container/services/src/main/java/org/mobicents/slee/container/deployment/ConcreteSbbGenerator.java
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);
			}
			
			SbbAbstractClassDescriptor mSbbAbstractClass = sbbComponent.getDescriptor()
					.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());
				} 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.class.getName()) && !methods[i].getDeclaringClass().getName().equals(
										ActivityContextInterfaceExt.class.getName())) {
							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.isTraceEnabled()) {
	            logger.trace("Sbb Local Object interface :"
						+ sbbLocalInterfaceClass);
			}
			if (sbbLocalInterfaceClass != null
					&& !sbbLocalInterfaceClass.getName().equals(
					"javax.slee.SbbLocalObject")) {
				try {
					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);
				}

			}
			// 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 ?!? :)");
		}
	}
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);
			}
			
			SbbAbstractClassDescriptor mSbbAbstractClass = sbbComponent.getDescriptor()
					.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());
				} 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.class.getName()) && !methods[i].getDeclaringClass().getName().equals(
										ActivityContextInterfaceExt.class.getName())) {
							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.isTraceEnabled()) {
	            logger.trace("Sbb Local Object interface :"
						+ sbbLocalInterfaceClass);
			}
			if (sbbLocalInterfaceClass != null
					&& !sbbLocalInterfaceClass.getName().equals(
					"javax.slee.SbbLocalObject")) {
				try {
					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);
				}

			}
			// 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 ?!? :)");
		}
	}
Generate the concrete sbb Class

@return the concrete sbb class