/***************************************************
* *
* Mobicents: The Open Source JSLEE Platform *
* *
* Distributable under LGPL license. *
* See terms of license at gnu.org. *
* *
***************************************************/
package org.mobicents.slee.container.deployment;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javax.slee.EventTypeID;
import javax.slee.SLEEException;
import javax.slee.Sbb;
import javax.slee.SbbLocalObject;
import javax.slee.management.DeploymentException;
import org.apache.log4j.Logger;
import org.mobicents.slee.container.component.SbbComponent;
import org.mobicents.slee.container.component.deployment.ClassPool;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MEventEntry;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MGetChildRelationMethod;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MGetProfileCMPMethod;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MSbbAbstractClass;
import org.mobicents.slee.container.component.deployment.jaxb.descriptors.sbb.MSbbCMPField;
import org.mobicents.slee.container.component.sbb.AbstractSbbClassInfo;
import org.mobicents.slee.runtime.activity.ActivityContextInterfaceImpl;
import org.mobicents.slee.runtime.sbb.SbbAbstractMethodHandler;
import org.mobicents.slee.runtime.sbb.SbbConcrete;
import org.mobicents.slee.runtime.sbb.SbbLocalObjectImpl;
import org.mobicents.slee.runtime.sbb.SbbObjectState;
import org.mobicents.slee.runtime.sbbentity.SbbEntity;
/**
* Class generating the sbb concrete class from a sbb abstract class provided by
* a sbb developer
*
*
* @author DERUELLE Jean <a
* href="mailto:jean.deruelle@gmail.com">jean.deruelle@gmail.com </a>
* @author M. Ranganathan
* @author Ivelin Ivanov
* @author Stefano Gamma
* @author Eduardo Martins (v2)
*
*/
public class ConcreteSbbGenerator {
/**
* the sbb component
*/
private final SbbComponent sbbComponent;
/**
* the sbb abstract class used to generate the concrete class
*/
private CtClass sbbAbstractClass = null;
/**
* the sbb concrete class to generate
*/
private CtClass sbbConcreteClass = null;
/**
* Logger to logg information
*/
private static Logger logger = null;
/**
* the sbb abstract methods used to generate the concrete class methods
*/
private Map abstractMethods = null;
/**
* Generator of the concrete activity context interface in case the sbb
* developer specified a narrow method in th descriptor
*/
private ConcreteActivityContextInterfaceGenerator concreteActivityContextInterfaceGenerator = null;
/**
* Pool to generate or read classes with javassist
*/
private ClassPool pool = null;
private Map superClassesAbstractMethods;
/**
* The path where classes will reside
*/
private final String deployDir;
static {
logger = Logger.getLogger(ConcreteSbbGenerator.class);
}
/**
* Constructor
*/
public ConcreteSbbGenerator(SbbComponent sbbComponent) {
this.sbbComponent = sbbComponent;
this.deployDir = sbbComponent.getDeploymentDir().getAbsolutePath();
;
this.pool = sbbComponent.getClassPool();
}
/**
* Generate the concrete sbb Class
*
* @return the concrete sbb class
*/
public void generateConcreteSbb() throws DeploymentException {
String sbbAbstractClassName = sbbComponent.getAbstractSbbClass()
.getName();
String sbbConcreteClassName = ConcreteClassGeneratorUtils
.getSbbConcreteClassName(sbbAbstractClassName);
sbbConcreteClass = pool.makeClass(sbbConcreteClassName);
try {
try {
sbbAbstractClass = pool.get(sbbAbstractClassName);
} catch (NotFoundException nfe) {
throw new DeploymentException(nfe.getMessage(), nfe);
}
generateAbstractSbbClassInfo();
try {
ConcreteClassGeneratorUtils.createInterfaceLinks(
sbbConcreteClass, new CtClass[] { pool
.get(SbbConcrete.class.getName()) });
} catch (NotFoundException nfe) {
throw new DeploymentException(nfe.getMessage(), nfe);
}
ConcreteClassGeneratorUtils.createInheritanceLink(sbbConcreteClass,
sbbAbstractClass);
abstractMethods = ClassUtils
.getAbstractMethodsFromClass(sbbAbstractClass);
superClassesAbstractMethods = ClassUtils
.getSuperClassesAbstractMethodsFromClass(sbbAbstractClass);
try {
createFields(new CtClass[] {
pool.get(SbbEntity.class.getName()),
pool.get(SbbObjectState.class.getName()) });
CtClass[] parameters = new CtClass[] { pool.get(SbbEntity.class
.getName()) };
createSbbEntityGetterAndSetter(sbbConcreteClass);
createDefaultUsageParameterGetter(sbbConcreteClass);
createNamedUsageParameterGetter(sbbConcreteClass);
createDefaultConstructor();
createConstructorWithParameter(parameters);
} catch (NotFoundException nfe) {
logger.error("Constructor With Parameter not created");
throw new DeploymentException("Constructor not created.", nfe);
}
MSbbAbstractClass mSbbAbstractClass = sbbComponent.getDescriptor()
.getSbbClasses().getSbbAbstractClass();
createCMPAccessors(mSbbAbstractClass.getCmpFields());
createGetChildRelationsMethod(mSbbAbstractClass
.getChildRelationMethods().values());
createGetProfileCMPMethods(mSbbAbstractClass.getProfileCMPMethods()
.values());
createFireEventMethods(sbbComponent.getDescriptor()
.getEventEntries().values());
// GetUsageParametersMethod[] usageParameters=
// sbbDeploymentDescriptor.getUsageParametersMethods();
// if the activity context interface has been defined in the
// descriptor
// file
// then generates the concrete class of the activity context
// interface
// and implements the narrow method
if (sbbComponent.getDescriptor()
.getSbbActivityContextInterface() != null) {
Class activityContextInterfaceClass = null;
try {
activityContextInterfaceClass = Thread.currentThread()
.getContextClassLoader().loadClass(
sbbComponent.getDescriptor()
.getSbbActivityContextInterface().getInterfaceName());
} catch (ClassNotFoundException e2) {
String s = "Error creating constructor - class not found";
logger.error(s, e2);
throw new DeploymentException(s, e2);
}
// Check the activity context interface for illegal method
// names.
Method[] methods = activityContextInterfaceClass.getMethods();
ArrayList<String> allSetters = new ArrayList<String>();
ArrayList<String> missingSetters = new ArrayList<String>();
if (methods != null) {
for (int i = 0; i < methods.length; i++) {
if (!methods[i].getDeclaringClass().getName().equals(
"javax.slee.ActivityContextInterface")) {
String methodName = methods[i].getName();
// setters should have a single parameter and should
// return void type.
if (methodName.startsWith("set")) {
Class[] args = methods[i].getParameterTypes();
// setter should only have one argument
if (args.length != 1)
throw new DeploymentException(
"Setter method '"
+ methodName
+ "' should only have one argument.");
// setter return type should be void
Class returnClass = methods[i].getReturnType();
if (!returnClass.equals(Void.TYPE))
throw new DeploymentException(
"Setter method '"
+ methodName
+ "' return type should be void.");
allSetters.add(methodName);
} else if (methodName.startsWith("get")) {
Class[] args = methods[i].getParameterTypes();
// getter should have no parameters.
if (args != null && args.length != 0)
throw new DeploymentException(
"Getter method '"
+ methodName
+ "' should have no parameters.");
// getter return type should not be void
if (methods[i].getReturnType()
.equals(Void.TYPE))
throw new DeploymentException(
"Getter method '"
+ methodName
+ "' return type cannot be void.");
String setterName = methodName.replaceFirst(
"get", "set");
try {
activityContextInterfaceClass.getMethod(
setterName, methods[i]
.getReturnType());
} catch (NoSuchMethodException nsme) {
missingSetters.add(setterName);
}
} else {
throw new DeploymentException(
"Invalid method '"
+ methodName
+ "' in SBB Activity Context Interface.");
}
}
}
// Check if the missing setters aren't defined with
// different arg
for (String setter : missingSetters)
if (allSetters.contains(setter))
throw new DeploymentException(
"Getter argument type and"
+ " setter return type for attribute '"
+ setter.replaceFirst("set", "")
.toLowerCase()
+ "' must be the same.");
}
/*
* CtMethod[] abstractClassMethods =
* sbbAbstractClass.getDeclaredMethods();
*
* for ( int i = 0; i < abstractClassMethods.length; i ++ ) {
* CtMethod ctMethod = abstractClassMethods[i]; if ( !
* Modifier.isAbstract(ctMethod.getModifiers())) {
* this.createMethodWrapper(sbbConcreteClass,ctMethod); } }
*/
// check if the concrete class has already been generated.
// if that the case, the guess is that the concrete class is a
// safe
// one
// and so it is not generated again
// avoid also problems of class already loaded from the class
// loader
//
CtClass activityContextInterface = null;
try {
activityContextInterface = pool
.get(activityContextInterfaceClass.getName());
createField(activityContextInterface,
"sbbActivityContextInterface");
this
.createSetActivityContextInterfaceMethod(activityContextInterface);
ConcreteActivityContextInterfaceGenerator concreteActivityContextInterfaceGenerator = new ConcreteActivityContextInterfaceGenerator(
activityContextInterfaceClass.getName(), deployDir,
pool);
Class concreteActivityContextInterfaceClass = concreteActivityContextInterfaceGenerator
.generateActivityContextInterfaceConcreteClass();
createGetSbbActivityContextInterfaceMethod(
activityContextInterface,
concreteActivityContextInterfaceClass);
// set the concrete activity context interface class in
// the
// descriptor
if (logger.isDebugEnabled()) {
logger.debug("SETTING ACI concrete class "
+ concreteActivityContextInterfaceClass
+ " in " + sbbComponent);
}
sbbComponent
.setActivityContextInterfaceConcreteClass(concreteActivityContextInterfaceClass);
} catch (NotFoundException nfe) {
logger
.error("Narrow Activity context interface method and "
+ "activity context interface concrete class not created");
throw new DeploymentException(nfe.getMessage(), nfe);
} finally {
/*
* if (activityContextInterface != null) {
* activityContextInterface.detach(); }
*/
}
}
// if the sbb local object has been defined in the descriptor file
// then generates the concrete class of the sbb local object
// and implements the narrow method
Class sbbLocalInterfaceClass = sbbComponent
.getSbbLocalInterfaceClass();
if (logger.isDebugEnabled()) {
logger.debug("Sbb Local Object interface :"
+ sbbLocalInterfaceClass);
}
if (sbbLocalInterfaceClass != null
&& !sbbLocalInterfaceClass.getName().equals(
"javax.slee.SbbLocalObject")) {
// check if the concrete class has already been generated.
// if that the case, the guess is that the concrete class is a
// safe
// one
// and so it is not generated again
// avoid also problems of class already loaded from the class
// loader
if (true /*
* !SbbDeployer.concreteClassesGenerated
* .contains(sbbAbstractClassName)
*/) {
try {
CtClass sbbLocalInterface = pool
.get(sbbLocalInterfaceClass.getName());
ConcreteSbbLocalObjectGenerator concreteSbbLocalObjectGenerator = new ConcreteSbbLocalObjectGenerator(
sbbLocalInterfaceClass.getName(),
sbbAbstractClassName, this.deployDir, pool);
Class concreteSbbLocalObjectClass = concreteSbbLocalObjectGenerator
.generateSbbLocalObjectConcreteClass();
// set the sbb Local object class in the descriptor
sbbComponent
.setSbbLocalInterfaceConcreteClass(concreteSbbLocalObjectClass);
} catch (NotFoundException nfe) {
String s = "sbb Local Object concrete class not created for interface "
+ sbbLocalInterfaceClass.getName();
throw new DeploymentException(s, nfe);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug(sbbLocalInterfaceClass.getName()
+ " concrete class already "
+ "generated. No generated a second time.");
}
}
}
// if there is no interface defined in the descriptor for sbb local
// object
// then the slee implementation is taken
else {
try {
sbbComponent
.setSbbLocalInterfaceClass(SbbLocalObject.class);
sbbComponent
.setSbbLocalInterfaceConcreteClass(SbbLocalObjectImpl.class);
} catch (Exception e) {
throw new DeploymentException(e.getMessage(), e);
}
}
try {
sbbConcreteClass.writeFile(deployDir);
// @@2.4+ -> 3.4+
// pool.writeFile(sbbConcreteClassName, deployPath);
if (logger.isDebugEnabled()) {
logger.debug("Concrete Class " + sbbConcreteClassName
+ " generated in the following path " + deployDir);
}
} catch (Exception e) {
String s = "Error generating concrete class";
throw new DeploymentException(s, e);
}
Class clazz = null;
try {
clazz = Thread.currentThread().getContextClassLoader()
.loadClass(sbbConcreteClassName);
} catch (ClassNotFoundException e1) {
String s = "What the heck?! Could not find generated class. Is it under the chair?";
throw new DeploymentException(s, e1);
}
// set the concrete class in the descriptor
sbbComponent.setConcreteSbbClass(clazz);
} finally {
if (sbbConcreteClass != null) {
sbbConcreteClass.defrost();
}
}
// uh uh
if (sbbComponent.getConcreteSbbClass() == null) {
throw new DeploymentException(
"concrete sbb class generation failed and I don't know why, bug bug ?!? :)");
}
}
/**
* Generates info that indicates if a method from {@link Sbb} interface
* should be invoked or not, in runtime.
*/
private void generateAbstractSbbClassInfo() {
CtClass sbbClass = null;
try {
sbbClass = pool.get(Sbb.class.getName());
} catch (NotFoundException e) {
throw new SLEEException(e.getMessage(), e);
}
AbstractSbbClassInfo abstractSbbClassInfo = new AbstractSbbClassInfo();
for (CtMethod sbbClassMethod : sbbClass.getDeclaredMethods()) {
for (CtMethod sbbAbstractClassMethod : sbbAbstractClass
.getMethods()) {
if (sbbAbstractClassMethod.getName().equals(
sbbClassMethod.getName())
&& sbbAbstractClassMethod.getSignature().equals(
sbbClassMethod.getSignature())) {
// match, save info
abstractSbbClassInfo.setInvokeInfo(sbbAbstractClassMethod
.getMethodInfo().getName(), !sbbAbstractClassMethod
.isEmpty());
break;
}
}
}
sbbComponent.setAbstractSbbClassInfo(abstractSbbClassInfo);
}
/**
* @param class1
* @param string
*/
private void createField(CtClass parameter, String parameterName) {
// TODO Auto-generated method stub
try {
CtField ctField = new CtField(parameter, parameterName,
sbbConcreteClass);
ctField.setModifiers(Modifier.PRIVATE);
sbbConcreteClass.addField(ctField);
} catch (CannotCompileException cce) {
cce.printStackTrace();
}
}
/**
* Creates a constructor with parameters <BR>
* For every parameter a field of the same class is created in the concrete
* class And each field is gonna be initialized with the corresponding
* parameter
*
* @param parameters
* the parameters of the constructor to add
* @throws DeploymentException
*/
protected void createConstructorWithParameter(CtClass[] parameters)
throws DeploymentException {
CtConstructor constructorWithParameter = new CtConstructor(parameters,
sbbConcreteClass);
String constructorBody = "{" + "this();";
/*
* for (int i = 0; i < parameters.length; i++) { String parameterName =
* parameters[i].getName(); parameterName =
* parameterName.substring(parameterName .lastIndexOf(".") + 1); String
* firstCharLowerCase = parameterName.substring(0, 1) .toLowerCase();
* parameterName = firstCharLowerCase.concat(parameterName
* .substring(1));
*
* int paramNumber = i + 1; constructorBody += parameterName + "=$" +
* paramNumber + ";"; }
*/
constructorBody += "this.setSbbEntity($1);";
constructorBody += "}";
try {
sbbConcreteClass.addConstructor(constructorWithParameter);
constructorWithParameter.setBody(constructorBody);
if (logger.isDebugEnabled()) {
logger.debug("ConstructorWithParameter created");
}
} catch (CannotCompileException e) {
throw new DeploymentException(e.getMessage(), e);
}
}
private void createFields(CtClass[] parameters) throws DeploymentException {
for (int i = 0; i < parameters.length; i++) {
String parameterName = parameters[i].getName();
parameterName = parameterName.substring(parameterName
.lastIndexOf(".") + 1);
String firstCharLowerCase = parameterName.substring(0, 1)
.toLowerCase();
parameterName = firstCharLowerCase.concat(parameterName
.substring(1));
try {
CtField ctField = new CtField(parameters[i], parameterName,
sbbConcreteClass);
ctField.setModifiers(Modifier.PRIVATE);
sbbConcreteClass.addField(ctField);
} catch (CannotCompileException e) {
throw new DeploymentException(e.getMessage(), e);
}
}
}
/**
* Create a default constructor on the Sbb Concrete Class
*
* @throws DeploymentException
*/
protected void createDefaultConstructor() throws DeploymentException {
CtConstructor defaultConstructor = new CtConstructor(null,
sbbConcreteClass);
// We need a "do nothing" constructor because the
// convergence name creation method may need to actually
// create the object instance to run the method that
// creates the convergence name.
String constructorBody = "{ }";
try {
defaultConstructor.setBody(constructorBody);
sbbConcreteClass.addConstructor(defaultConstructor);
logger.debug("DefaultConstructor created");
} catch (CannotCompileException e) {
throw new DeploymentException(e.getMessage(), e);
}
}
/**
* Create a default usage parameter getter and setter.
*
* @param sbbConcrete
* @throws DeploymentException
*/
private void createDefaultUsageParameterGetter(CtClass sbbConcrete)
throws DeploymentException {
String methodName = "getDefaultSbbUsageParameterSet";
CtMethod method = (CtMethod) abstractMethods.get(methodName);
if (method == null) {
method = (CtMethod) superClassesAbstractMethods.get(methodName);
}
if (method != null) {
try {
// copy method from abstract to concrete class
CtMethod concreteMethod = CtNewMethod.copy(method,
sbbConcreteClass, null);
// create the method body
String concreteMethodBody = "{ return ($r)"
+ SbbAbstractMethodHandler.class.getName()
+ ".getDefaultSbbUsageParameterSet(sbbEntity); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + methodName
+ " , body = " + concreteMethodBody);
}
concreteMethod.setBody(concreteMethodBody);
sbbConcreteClass.addMethod(concreteMethod);
} catch (CannotCompileException cce) {
throw new SLEEException("Cannot compile method "
+ method.getName(), cce);
}
}
}
/**
* Create a named usage parameter getter.
*
* @param sbbConcrete
* @throws DeploymentException
*/
private void createNamedUsageParameterGetter(CtClass sbbConcrete)
throws DeploymentException {
String methodName = "getSbbUsageParameterSet";
CtMethod method = (CtMethod) abstractMethods.get(methodName);
if (method == null) {
method = (CtMethod) superClassesAbstractMethods.get(methodName);
}
if (method != null) {
try {
// copy method from abstract to concrete class
CtMethod concreteMethod = CtNewMethod.copy(method,
sbbConcreteClass, null);
// create the method body
String concreteMethodBody = "{ return ($r)"
+ SbbAbstractMethodHandler.class.getName()
+ ".getSbbUsageParameterSet(sbbEntity,$1); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + methodName
+ " , body = " + concreteMethodBody);
}
concreteMethod.setBody(concreteMethodBody);
sbbConcreteClass.addMethod(concreteMethod);
} catch (CannotCompileException cce) {
throw new SLEEException("Cannot compile method "
+ method.getName(), cce);
}
}
}
/**
* Create a method to retrive the entity from the SbbObject.
*
* @param cmpAccessors
* @throws DeploymentException
*/
private void createSbbEntityGetterAndSetter(CtClass sbbConcrete)
throws DeploymentException {
try {
CtClass sbbEntityClass = pool.get(SbbEntity.class.getName());
CtMethod getSbbEntity = CtNewMethod
.make("public " + SbbEntity.class.getName()
+ " getSbbEntity() { return this.sbbEntity; }",
sbbConcrete);
getSbbEntity.setModifiers(Modifier.PUBLIC);
sbbConcrete.addMethod(getSbbEntity);
CtMethod setSbbEntity = CtNewMethod.make(
"public void setSbbEntity ( " + SbbEntity.class.getName()
+ " sbbEntity )" + "{"
+ "this.sbbEntity = sbbEntity;" + "}", sbbConcrete);
setSbbEntity.setModifiers(Modifier.PUBLIC);
sbbConcrete.addMethod(setSbbEntity);
} catch (Exception e) {
throw new DeploymentException(e.getMessage(), e);
}
}
/**
* Create the cmp field setters and getters
*
* @param cmps
* the description of the cmp fields
* @throws DeploymentException
*/
protected void createCMPAccessors(Collection<MSbbCMPField> cmps)
throws DeploymentException {
for (MSbbCMPField cmp : cmps) {
String fieldName = cmp.getCmpFieldName();
// Set the first char of the accessor to UpperCase to follow the
// javabean requirements
fieldName = fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
String getterMethodName = "get" + fieldName;
CtMethod getterMethod = (CtMethod) abstractMethods
.get(getterMethodName);
if (getterMethod == null) {
getterMethod = (CtMethod) this.superClassesAbstractMethods
.get(getterMethodName);
}
if (getterMethod == null) {
throw new SLEEException("can't find abstract method "
+ getterMethodName);
}
try {
// copy method from abstract to concrete class
CtMethod concreteGetterMethod = CtNewMethod.copy(getterMethod,
sbbConcreteClass, null);
// create the method body
String concreteGetterMethodBody = "{ return ($r)"
+ SbbAbstractMethodHandler.class.getName()
+ ".getCMPField(sbbEntity,\"" + cmp.getCmpFieldName()
+ "\","+concreteGetterMethod.getReturnType().getName()+".class); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + getterMethodName
+ " , body = " + concreteGetterMethodBody);
}
concreteGetterMethod.setBody(concreteGetterMethodBody);
sbbConcreteClass.addMethod(concreteGetterMethod);
} catch (Exception cce) {
throw new SLEEException("Cannot compile method "
+ getterMethod.getName(), cce);
}
String setterMethodName = "set" + fieldName;
CtMethod setterMethod = (CtMethod) abstractMethods
.get(setterMethodName);
if (setterMethod == null) {
setterMethod = (CtMethod) this.superClassesAbstractMethods
.get(setterMethodName);
}
if (setterMethod == null) {
throw new SLEEException("can't find abstract method "
+ setterMethodName);
}
try {
// copy method from abstract to concrete class
CtMethod concreteSetterMethod = CtNewMethod.copy(setterMethod,
sbbConcreteClass, null);
// create the method body
String concreteSetterMethodBody = "{ "
+ SbbAbstractMethodHandler.class.getName()
+ ".setCMPField(sbbEntity,\"" + cmp.getCmpFieldName()
+ "\",$1); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + setterMethodName
+ " , body = " + concreteSetterMethodBody);
}
concreteSetterMethod.setBody(concreteSetterMethodBody);
sbbConcreteClass.addMethod(concreteSetterMethod);
} catch (CannotCompileException cce) {
throw new SLEEException("Cannot compile method "
+ getterMethod.getName(), cce);
}
}
}
private String getEventTypeIDInstantionString(MEventEntry mEventEntry) {
String eventTypeIDClassName = EventTypeID.class.getName();
return eventTypeIDClassName + " eventTypeID = new "
+ eventTypeIDClassName + "(\""
+ mEventEntry.getEventReference().getEventTypeName() + "\",\""
+ mEventEntry.getEventReference().getEventTypeVendor()
+ "\",\""
+ mEventEntry.getEventReference().getEventTypeVersion()
+ "\");";
}
/**
* Create the implementation of the fire event methods
*
* @param firedEvents
* the set of fire event
*/
protected void createFireEventMethods(Collection<MEventEntry> mEventEntries) {
if (mEventEntries == null)
return;
for (MEventEntry mEventEntry : mEventEntries) {
if (mEventEntry.isFired()) {
String methodName = "fire" + mEventEntry.getEventName();
CtMethod method = (CtMethod) abstractMethods.get(methodName);
if (method == null) {
method = (CtMethod) superClassesAbstractMethods
.get(methodName);
}
if (method != null) {
try {
// copy method from abstract to concrete class
CtMethod concreteMethod = CtNewMethod.copy(method,
sbbConcreteClass, null);
String eventTypeIDClassName = EventTypeID.class
.getName();
// create the method body
String concreteMethodBody = "{";
concreteMethodBody += getEventTypeIDInstantionString(mEventEntry);
concreteMethodBody += SbbAbstractMethodHandler.class
.getName()
+ ".fireEvent(sbbEntity,eventTypeID";
for (int i = 0; i < method.getParameterTypes().length; i++) {
concreteMethodBody += ",$" + (i + 1);
}
concreteMethodBody += ");}";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + methodName
+ " , body = " + concreteMethodBody);
}
concreteMethod.setBody(concreteMethodBody);
sbbConcreteClass.addMethod(concreteMethod);
} catch (Exception e) {
throw new SLEEException("Cannot compile method "
+ method.getName(), e);
}
}
}
}
}
/**
* Create the get child relation method (this method redirects the call to a
* child relation interceptor)
*
* @param childRelations
* the childRelations method to add to the concrete class
*/
protected void createGetChildRelationsMethod(
Collection<MGetChildRelationMethod> childRelations) {
if (childRelations == null)
return;
for (MGetChildRelationMethod childRelation : childRelations) {
String methodName = childRelation.getChildRelationMethodName();
CtMethod method = (CtMethod) abstractMethods.get(methodName);
if (method == null) {
method = (CtMethod) superClassesAbstractMethods.get(methodName);
}
if (method != null) {
try {
// copy method from abstract to concrete class
CtMethod concreteMethod = CtNewMethod.copy(method,
sbbConcreteClass, null);
// create the method body
String concreteMethodBody = "{ return "
+ SbbAbstractMethodHandler.class.getName()
+ ".getChildRelation(sbbEntity,\"" + methodName
+ "\"); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + methodName
+ " , body = " + concreteMethodBody);
}
concreteMethod.setBody(concreteMethodBody);
sbbConcreteClass.addMethod(concreteMethod);
} catch (CannotCompileException cce) {
throw new SLEEException("Cannot compile method "
+ method.getName(), cce);
}
}
}
}
/**
* Create the get profile CMP method (this method redirects the call to a
* profile cmp interceptor)
*
* @param cmpProfiles
* the CMP Profiles method to add to the concrete class
*/
protected void createGetProfileCMPMethods(
Collection<MGetProfileCMPMethod> cmpProfiles) {
if (cmpProfiles == null) {
if (logger.isDebugEnabled()) {
logger
.debug("no CMP Profile method implementation to generate.");
}
return;
}
for (MGetProfileCMPMethod cmpProfile : cmpProfiles) {
String methodName = cmpProfile.getProfileCmpMethodName();
CtMethod method = (CtMethod) abstractMethods.get(methodName);
if (method == null)
method = (CtMethod) superClassesAbstractMethods.get(methodName);
if (method != null)
try {
// copy method from abstract to concrete class
CtMethod concreteMethod = CtNewMethod.copy(method,
sbbConcreteClass, null);
// create the method body
String concreteMethodBody = "{ return "
+ SbbAbstractMethodHandler.class.getName()
+ ".getProfileCMPMethod(sbbEntity,\"" + methodName
+ "\",$1); }";
if (logger.isDebugEnabled()) {
logger.debug("Generated method " + methodName
+ " , body = " + concreteMethodBody);
}
concreteMethod.setBody(concreteMethodBody);
sbbConcreteClass.addMethod(concreteMethod);
} catch (CannotCompileException cce) {
throw new SLEEException("Cannot compile method "
+ method.getName(), cce);
}
}
}
protected void createSetActivityContextInterfaceMethod(
CtClass activityContextInterface) throws DeploymentException {
String methodToAdd = "public void sbbSetActivityContextInterface( Object aci ) {"
+ "this.sbbActivityContextInterface = ("
+ activityContextInterface.getName() + ") aci ; } ";
CtMethod methodTest;
try {
methodTest = CtNewMethod.make(methodToAdd, sbbConcreteClass);
sbbConcreteClass.addMethod(methodTest);
logger.debug("Method " + methodToAdd + " added");
} catch (CannotCompileException e) {
throw new DeploymentException(e.getMessage(), e);
}
}
/**
* Create the narrow method to get the activity context interface
*
* @param activityContextInterface
* the activity context interface return type of the narrow
* method
* @param concreteActivityContextInterfaceClass
* @throws DeploymentException
*/
protected void createGetSbbActivityContextInterfaceMethod(
CtClass activityContextInterface,
Class concreteActivityContextInterfaceClass)
throws DeploymentException {
String methodToAdd = "public "
+ activityContextInterface.getName()
+ " asSbbActivityContextInterface(javax.slee.ActivityContextInterface aci) {"
+ "if(aci==null)"
+ " throw new "
+ IllegalStateException.class.getName()
+ "(\"Passed argument can not be of null value.\");"
+ " if(sbbEntity == null || sbbEntity.getSbbObject().getState() != "
+ SbbObjectState.class.getName() + ".READY) { throw new "
+ IllegalStateException.class.getName()
+ "(\"Cannot call asSbbActivityContextInterface\"); } "
+ "else if ( aci instanceof "
+ concreteActivityContextInterfaceClass.getName()
+ ") return aci;" + "else return new "
+ concreteActivityContextInterfaceClass.getName() + " ( ("+ActivityContextInterfaceImpl.class.getName()+") $1, "
+ "sbbEntity.getSbbComponent());" + "}";
CtMethod methodTest;
try {
methodTest = CtNewMethod.make(methodToAdd, sbbConcreteClass);
sbbConcreteClass.addMethod(methodTest);
if (logger.isDebugEnabled()) {
logger.debug("Method " + methodToAdd + " added");
}
} catch (CannotCompileException e) {
throw new DeploymentException(e.getMessage(), e);
}
}
/**
*
* @param usageParameters
*/
/*
* protected void createSbbUsageParameterInterface(
* GetUsageParametersMethod[] usageParameters){ }
*/
}