/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
* Free SoftwareFoundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.ejb.cfg;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.inject.spi.AnnotatedMethod;
import com.caucho.config.ConfigException;
import com.caucho.config.reflect.AnnotatedMethodImpl;
import com.caucho.util.L10N;
/**
* Configuration for a method.
*/
public class EjbMethodPattern<X> {
private static L10N L = new L10N(EjbMethodPattern.class);
public final static int RESIN_DATABASE = 0;
public final static int RESIN_READ_ONLY = 1;
public final static int RESIN_ROW_LOCK = 2;
private EjbBean<X> _bean;
private String _location;
private MethodSignature _signature;
private int _resinIsolation = -1;
private int _jdbcIsolation = -1;
private boolean _queryLoadsBean = true;
private boolean _relationLoadsBean;
private String _query;
private String _queryLocation;
private TransactionAttributeType _transactionType = null;
private ArrayList<String> _roles;
/**
* Creates a new method.
*/
public EjbMethodPattern()
{
}
/**
* Creates a new method.
*
* @param entity the owning entity bean.
* @param signature the method signature.
*/
public EjbMethodPattern(EjbBean<X> bean, MethodSignature signature)
{
_bean = bean;
_signature = signature;
}
/**
* Sets the bean.
*/
public void setBean(EjbBean<X> bean)
{
_bean = bean;
}
/**
* Sets the config location.
*/
public void setLocation(String location)
{
_location = location;
}
/**
* Returns the config location.
*/
public String getLocation()
{
return _location;
}
/**
* Sets the method signature.
*/
public void setSignature(MethodSignature sig)
{
_signature = sig;
}
/**
* Returns the method signature.
*/
public MethodSignature getSignature()
{
return _signature;
}
/**
* Returns the method name.
*/
public String getName()
{
return _signature.getName();
}
/**
* Returns true if the method does not set any values.
*/
public boolean isReadOnly()
{
return _resinIsolation == RESIN_READ_ONLY;
}
/**
* Returns the Resin isolation.
*/
public int getResinIsolation()
{
return _resinIsolation;
}
/**
* Sets the Resin isolation.
*/
public void setResinIsolation(String isolation)
throws ConfigException
{
if (isolation.equals("read-only"))
_resinIsolation = RESIN_READ_ONLY;
else if (isolation.equals("database"))
_resinIsolation = RESIN_DATABASE;
else if (isolation.equals("row-locking"))
_resinIsolation = RESIN_ROW_LOCK;
else
throw new ConfigException(L.l("'{0}' is an unknown value for resin-isolation. Only 'read-only', 'database', and 'row-locking' are allowed.",
isolation));
}
/**
* Returns the JDBC isolation.
*/
public int getJDBCIsolation()
{
return _jdbcIsolation;
}
/**
* Sets the JDBC isolation.
*/
public void setJDBCIsolation(int isolation)
{
_jdbcIsolation = isolation;
}
/**
* Returns the method's query.
*/
public String getQuery()
{
return _query;
}
/**
* Sets the method's query.
*/
public void setQuery(String query)
{
_query = query;
}
/**
* Returns the query config location.
*/
public String getQueryLocation()
{
return _queryLocation;
}
/**
* Sets the query node.
*/
public void setQueryLocation(String location)
{
_queryLocation = location;
}
/**
* Returns the method's transaction type, e.g. Required.
*/
public TransactionAttributeType getTransactionType()
{
if (_transactionType != null)
return _transactionType;
else if (isReadOnly())
return TransactionAttributeType.SUPPORTS;
else
return TransactionAttributeType.REQUIRED;
}
public void setTransaction(TransactionAttributeType type)
throws ConfigException
{
_transactionType = type;
}
/**
* Sets the method's transaction type, e.g. Required
*/
public void setTransAttribute(String type)
throws ConfigException
{
if ("Required".equals(type))
_transactionType = TransactionAttributeType.REQUIRED;
else if ("RequiresNew".equals(type))
_transactionType = TransactionAttributeType.REQUIRES_NEW;
else if ("Mandatory".equals(type))
_transactionType = TransactionAttributeType.MANDATORY;
else if ("NotSupported".equals(type))
_transactionType = TransactionAttributeType.NOT_SUPPORTED;
else if ("Never".equals(type))
_transactionType = TransactionAttributeType.NEVER;
else if ("Supports".equals(type))
_transactionType = TransactionAttributeType.SUPPORTS;
else
throw new ConfigException(L.l("'{0}' is an unknown transaction type. The transaction types are:\n Required - creates a new transaction if none is active.\n RequiresNew - always creates a new transaction.\n Mandatory - requires an active transaction.\n NotSupported - suspends any active transaction.\n Never - forbids any active transaction.\n Supports - allows a transaction or no transaction.", type));
}
/**
* Returns true if the query method should load bean values.
*/
public boolean getQueryLoadsBean()
{
return _queryLoadsBean;
}
/**
* Set true if the query method should load bean values.
*/
public void setQueryLoadsBean(boolean loadBean)
{
_queryLoadsBean = loadBean;
}
/**
* Returns true if the relation method should load bean values.
*/
public boolean getRelationLoadsBean()
{
return _relationLoadsBean;
}
/**
* Set true if the relation method should load bean values.
*/
public void setRelationLoadsBean(boolean loadBean)
{
_relationLoadsBean = loadBean;
}
/**
* Returns the roles allowed for the method.
*/
public ArrayList<String> getRoles()
{
return _roles;
}
/**
* Set the roles allowed for the method.
*/
public void setRoles(ArrayList<String> roles)
{
_roles = roles;
}
/**
* Set the roles allowed for the method.
*/
public void setRoles(String []roles)
{
if (roles != null) {
if (_roles == null)
_roles = new ArrayList();
for (String role : roles) {
_roles.add(role);
}
}
}
/**
* Configures the bean with the override values
*/
public void configure(AnnotatedMethod<?> apiMethod)
{
if (_signature.isMatch(apiMethod.getJavaMember().getName(),
apiMethod.getJavaMember().getParameterTypes())) {
// configureSecurity(apiMethod);
configureXA(apiMethod);
}
}
public boolean isMatch(AnnotatedMethod<?> method)
{
return _signature.isMatch(method.getJavaMember().getName(),
method.getJavaMember().getParameterTypes());
}
private void configureXA(AnnotatedMethod<?> apiMethod)
{
if (_transactionType == null)
return;
Annotation ann = new TransactionAttribute() {
public Class annotationType() { return TransactionAttribute.class; }
public TransactionAttributeType value() { return _transactionType; }
};
((AnnotatedMethodImpl<?>) apiMethod).addAnnotation(ann);
// XXX: need to modify ...
// XaCallChain xa = bizMethod.getXa();
// xa.setTransactionType(_transactionType);
}
/*
private void configureSecurity(AspectGenerator bizMethod)
{
if (_roles == null)
return;
SecurityGenerator security = bizMethod.getSecurity();
// security.setRoles(_roles);
}
*/
/**
* Returns true if these are equivalent.
*/
public boolean equals(Object o)
{
if (! (o instanceof EjbMethodPattern<?>))
return false;
EjbMethodPattern<?> method = (EjbMethodPattern<?>) o;
return _signature.equals(method.getSignature());
}
@Override
public String toString()
{
if (_signature != null)
return getClass().getSimpleName() + "[" + _signature.getName() + "]";
else
return getClass().getSimpleName() + "[]";
}
}