container/profiles/src/main/java/org/mobicents/slee/container/deployment/profile/jpa/ConcreteProfileEntityGenerator.java
private Class<?> generateProfileAttributeArrayValueClass(CtClass concreteProfileEntityClass, String profileAttributeName, boolean unique) {
	
	  CtClass concreteArrayValueClass = null;
	  
	  try {
		  
		  // define the concrete profile attribute array value class name
		  String concreteArrayValueClassName = profileComponent.getProfileCmpInterfaceClass().getName() + "PEAAV_"+ClassGeneratorUtils.capitalize(profileAttributeName);   

		  // create javassist class
		  concreteArrayValueClass = ClassGeneratorUtils.createClass(concreteArrayValueClassName, new String[]{Serializable.class.getName()});

		  // set inheritance
		  ClassGeneratorUtils.createInheritanceLink(concreteArrayValueClass, ProfileEntityArrayAttributeValue.class.getName());

		  // annotate class with @Entity
		  ClassGeneratorUtils.addAnnotation( Entity.class.getName(), new LinkedHashMap<String, Object>(), concreteArrayValueClass );    

		  // generate a random table name
		  addTableAnnotationToPEAAV("SLEE_PEAAV_"+profileComponent.getProfileCmpInterfaceClass().getSimpleName() + "_" + Math.abs((long)profileComponent.getComponentID().hashCode()) + profileAttributeName,unique,concreteArrayValueClass);  
		  		  
		  // override @id
		  String getIdNameMethodSrc = "public long getId() { return super.getId(); }";
		  CtMethod getIdNameMethod = CtNewMethod.make(getIdNameMethodSrc, concreteArrayValueClass);
		  ClassGeneratorUtils.addAnnotation( Id.class.getName(), new LinkedHashMap<String, Object>(), getIdNameMethod);
		  ClassGeneratorUtils.addAnnotation( GeneratedValue.class.getName(), new LinkedHashMap<String, Object>(), getIdNameMethod);
		  concreteArrayValueClass.addMethod(getIdNameMethod);
		  
		  // override getter methods
		  String getSerializableMethodSrc = "public "+Serializable.class.getName()+" getSerializable() { return super.getSerializable(); }";
		  CtMethod getSerializableMethod = CtNewMethod.make(getSerializableMethodSrc, concreteArrayValueClass);
		  LinkedHashMap<String,Object> map = new LinkedHashMap<String, Object>();
		  map.put("name", "serializable");
		  map.put("length", 512);
		  //if (unique)map.put("unique", true);
		  ClassGeneratorUtils.addAnnotation(Column.class.getName(), map, getSerializableMethod);
		  concreteArrayValueClass.addMethod(getSerializableMethod);
		  String getStringMethodSrc = "public String getString() { return super.getString(); }";
		  CtMethod getStringMethod = CtNewMethod.make(getStringMethodSrc, concreteArrayValueClass);
		  map = new LinkedHashMap<String, Object>();
		  map.put("name", "string");
		  //if (unique)map.put("unique", true);
		  ClassGeneratorUtils.addAnnotation(Column.class.getName(), map, getStringMethod);
		  concreteArrayValueClass.addMethod(getStringMethod);

		  // FIXME add join columns here or in profile entity class to make
		  // the relation without a join table, atm if this is changed, the
		  // inserts on this table go with profile and table name as null %)
		  // THE PROFILENTITY FIELD IN AAV CLASS IS REQUIRED FOR THE RELATION WITH PROFILE ENTITY CLASS WITHOUT A JOIN TABLE
		  // add join column regarding the relation from array attr value to profile entity
		  CtField ctField = ClassGeneratorUtils.addField(concreteProfileEntityClass, "owner", concreteArrayValueClass);
		  ClassGeneratorUtils.generateSetter(ctField,null);
		  CtMethod getter = ClassGeneratorUtils.generateGetter(ctField,null);
		  //ClassGeneratorUtils.addAnnotation(ManyToOne.class.getName(), new LinkedHashMap<String, Object>(), getter);
		  // ----
		  ConstPool cp = getter.getMethodInfo().getConstPool();
		  AnnotationsAttribute attr = (AnnotationsAttribute) getter.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag);
		  if (attr == null) {
			  attr = new AnnotationsAttribute(cp,AnnotationsAttribute.visibleTag);
		  }
		  
		  Annotation manyToOne = new Annotation(ManyToOne.class.getName(), cp);
		  manyToOne.addMemberValue("optional", new BooleanMemberValue(false,cp));
		  attr.addAnnotation(manyToOne);
		  
		  Annotation joinColumns = new Annotation(JoinColumns.class.getName(), cp);
		  Annotation joinColumn1 = new Annotation(JoinColumn.class.getName(), cp);
		  joinColumn1.addMemberValue("name", new StringMemberValue("owner_tableName", cp));
		  joinColumn1.addMemberValue("referencedColumnName", new StringMemberValue("tableName", cp));
		  Annotation joinColumn2 = new Annotation(JoinColumn.class.getName(), cp);
		  joinColumn2.addMemberValue("name", new StringMemberValue("owner_profileName", cp));
		  joinColumn2.addMemberValue("referencedColumnName", new StringMemberValue("profileName", cp));
		  ArrayMemberValue joinColumnsMemberValue = new ArrayMemberValue(cp);
    	  joinColumnsMemberValue.setValue(new MemberValue[] { new AnnotationMemberValue(joinColumn1,cp), new AnnotationMemberValue(joinColumn2,cp)});
    	  joinColumns.addMemberValue("value", joinColumnsMemberValue);
    	  attr.addAnnotation(joinColumns);
    	  
    	  getter.getMethodInfo().addAttribute(attr);
		  
    	  // generate concrete setProfileEntity method
    	  String setProfileEntityMethodSrc = "public void setProfileEntity("+ProfileEntity.class.getName()+" profileEntity){ setOwner(("+concreteProfileEntityClass.getName()+")profileEntity); }";
    	  CtMethod setProfileEntityMethod = CtMethod.make(setProfileEntityMethodSrc, concreteArrayValueClass);
    	  concreteArrayValueClass.addMethod(setProfileEntityMethod);
    	      	  
		  // write and load the attr array value class
		  String deployDir = profileComponent.getDeploymentDir().getAbsolutePath();
		  if (logger.isDebugEnabled()) {
			  logger.debug( "Writing PROFILE ATTR ARRAY VALUE CONCRETE CLASS ( "+concreteArrayValueClass.getName()+" ) to: " + deployDir );
		  }
		   concreteArrayValueClass.writeFile( deployDir );
		  
		  return Thread.currentThread().getContextClassLoader().loadClass(concreteArrayValueClass.getName());      
	  }
	  catch (Throwable e) {
		  throw new SLEEException(e.getMessage(),e);
	  }
	  finally {
		  if (concreteArrayValueClass != null) {
			  concreteArrayValueClass.defrost();
		  }
	  }
  }
private Class<?> generateProfileAttributeArrayValueClass(CtClass concreteProfileEntityClass, String profileAttributeName, boolean unique) {
	
	  CtClass concreteArrayValueClass = null;
	  
	  try {
		  
		  // define the concrete profile attribute array value class name
		  String concreteArrayValueClassName = profileComponent.getProfileCmpInterfaceClass().getName() + "PEAAV_"+ClassGeneratorUtils.capitalize(profileAttributeName);   

		  // create javassist class
		  concreteArrayValueClass = ClassGeneratorUtils.createClass(concreteArrayValueClassName, new String[]{Serializable.class.getName()});

		  // set inheritance
		  ClassGeneratorUtils.createInheritanceLink(concreteArrayValueClass, ProfileEntityArrayAttributeValue.class.getName());

		  // annotate class with @Entity
		  ClassGeneratorUtils.addAnnotation( Entity.class.getName(), new LinkedHashMap<String, Object>(), concreteArrayValueClass );    

		  // generate a random table name
		  addTableAnnotationToPEAAV("SLEE_PEAAV_"+profileComponent.getProfileCmpInterfaceClass().getSimpleName() + "_" + Math.abs((long)profileComponent.getComponentID().hashCode()) + profileAttributeName,unique,concreteArrayValueClass);  
		  		  
		  // override @id
		  String getIdNameMethodSrc = "public long getId() { return super.getId(); }";
		  CtMethod getIdNameMethod = CtNewMethod.make(getIdNameMethodSrc, concreteArrayValueClass);
		  ClassGeneratorUtils.addAnnotation( Id.class.getName(), new LinkedHashMap<String, Object>(), getIdNameMethod);
		  ClassGeneratorUtils.addAnnotation( GeneratedValue.class.getName(), new LinkedHashMap<String, Object>(), getIdNameMethod);
		  concreteArrayValueClass.addMethod(getIdNameMethod);
		  
		  // override getter methods
		  String getSerializableMethodSrc = "public "+Serializable.class.getName()+" getSerializable() { return super.getSerializable(); }";
		  CtMethod getSerializableMethod = CtNewMethod.make(getSerializableMethodSrc, concreteArrayValueClass);
		  LinkedHashMap<String,Object> map = new LinkedHashMap<String, Object>();
		  map.put("name", "serializable");
		  map.put("length", 512);
		  //if (unique)map.put("unique", true);
		  ClassGeneratorUtils.addAnnotation(Column.class.getName(), map, getSerializableMethod);
		  concreteArrayValueClass.addMethod(getSerializableMethod);
		  String getStringMethodSrc = "public String getString() { return super.getString(); }";
		  CtMethod getStringMethod = CtNewMethod.make(getStringMethodSrc, concreteArrayValueClass);
		  map = new LinkedHashMap<String, Object>();
		  map.put("name", "string");
		  //if (unique)map.put("unique", true);
		  ClassGeneratorUtils.addAnnotation(Column.class.getName(), map, getStringMethod);
		  concreteArrayValueClass.addMethod(getStringMethod);

		  // FIXME add join columns here or in profile entity class to make
		  // the relation without a join table, atm if this is changed, the
		  // inserts on this table go with profile and table name as null %)
		  // THE PROFILENTITY FIELD IN AAV CLASS IS REQUIRED FOR THE RELATION WITH PROFILE ENTITY CLASS WITHOUT A JOIN TABLE
		  // add join column regarding the relation from array attr value to profile entity
		  CtField ctField = ClassGeneratorUtils.addField(concreteProfileEntityClass, "owner", concreteArrayValueClass);
		  ClassGeneratorUtils.generateSetter(ctField,null);
		  CtMethod getter = ClassGeneratorUtils.generateGetter(ctField,null);
		  //ClassGeneratorUtils.addAnnotation(ManyToOne.class.getName(), new LinkedHashMap<String, Object>(), getter);
		  // ----
		  ConstPool cp = getter.getMethodInfo().getConstPool();
		  AnnotationsAttribute attr = (AnnotationsAttribute) getter.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag);
		  if (attr == null) {
			  attr = new AnnotationsAttribute(cp,AnnotationsAttribute.visibleTag);
		  }
		  
		  Annotation manyToOne = new Annotation(ManyToOne.class.getName(), cp);
		  manyToOne.addMemberValue("optional", new BooleanMemberValue(false,cp));
		  attr.addAnnotation(manyToOne);
		  
		  Annotation joinColumns = new Annotation(JoinColumns.class.getName(), cp);
		  Annotation joinColumn1 = new Annotation(JoinColumn.class.getName(), cp);
		  joinColumn1.addMemberValue("name", new StringMemberValue("owner_tableName", cp));
		  joinColumn1.addMemberValue("referencedColumnName", new StringMemberValue("tableName", cp));
		  Annotation joinColumn2 = new Annotation(JoinColumn.class.getName(), cp);
		  joinColumn2.addMemberValue("name", new StringMemberValue("owner_profileName", cp));
		  joinColumn2.addMemberValue("referencedColumnName", new StringMemberValue("profileName", cp));
		  ArrayMemberValue joinColumnsMemberValue = new ArrayMemberValue(cp);
    	  joinColumnsMemberValue.setValue(new MemberValue[] { new AnnotationMemberValue(joinColumn1,cp), new AnnotationMemberValue(joinColumn2,cp)});
    	  joinColumns.addMemberValue("value", joinColumnsMemberValue);
    	  attr.addAnnotation(joinColumns);
    	  
    	  getter.getMethodInfo().addAttribute(attr);
		  
    	  // generate concrete setProfileEntity method
    	  String setProfileEntityMethodSrc = "public void setProfileEntity("+ProfileEntity.class.getName()+" profileEntity){ setOwner(("+concreteProfileEntityClass.getName()+")profileEntity); }";
    	  CtMethod setProfileEntityMethod = CtMethod.make(setProfileEntityMethodSrc, concreteArrayValueClass);
    	  concreteArrayValueClass.addMethod(setProfileEntityMethod);
    	      	  
		  // write and load the attr array value class
		  String deployDir = profileComponent.getDeploymentDir().getAbsolutePath();
		  if (logger.isDebugEnabled()) {
			  logger.debug( "Writing PROFILE ATTR ARRAY VALUE CONCRETE CLASS ( "+concreteArrayValueClass.getName()+" ) to: " + deployDir );
		  }
		   concreteArrayValueClass.writeFile( deployDir );
		  
		  return Thread.currentThread().getContextClassLoader().loadClass(concreteArrayValueClass.getName());      
	  }
	  catch (Throwable e) {
		  throw new SLEEException(e.getMessage(),e);
	  }
	  finally {
		  if (concreteArrayValueClass != null) {
			  concreteArrayValueClass.defrost();
		  }
	  }
  }
private Class < ? > generateProfileAttributeArrayValueClass ( CtClass concreteProfileEntityClass , String profileAttributeName , boolean unique ) { CtClass concreteArrayValueClass = null ; try { // define the concrete profile attribute array value class name String concreteArrayValueClassName = profileComponent . getProfileCmpInterfaceClass ( ) . getName ( ) + "PEAAV_" + ClassGeneratorUtils . capitalize ( profileAttributeName ) ; // create javassist class concreteArrayValueClass = ClassGeneratorUtils . createClass ( concreteArrayValueClassName , new String [ ] { Serializable . class . getName ( ) } ) ; // set inheritance ClassGeneratorUtils . createInheritanceLink ( concreteArrayValueClass , ProfileEntityArrayAttributeValue . class . getName ( ) ) ; // annotate class with @Entity ClassGeneratorUtils . addAnnotation ( Entity . class . getName ( ) , new LinkedHashMap < String , Object > ( ) , concreteArrayValueClass ) ; // generate a random table name addTableAnnotationToPEAAV ( "SLEE_PEAAV_" + profileComponent . getProfileCmpInterfaceClass ( ) . getSimpleName ( ) + "_" + Math . abs ( ( long ) profileComponent . getComponentID ( ) . hashCode ( ) ) + profileAttributeName , unique , concreteArrayValueClass ) ; // override @id String getIdNameMethodSrc = "public long getId() { return super.getId(); }" ; CtMethod getIdNameMethod = CtNewMethod . make ( getIdNameMethodSrc , concreteArrayValueClass ) ; ClassGeneratorUtils . addAnnotation ( Id . class . getName ( ) , new LinkedHashMap < String , Object > ( ) , getIdNameMethod ) ; ClassGeneratorUtils . addAnnotation ( GeneratedValue . class . getName ( ) , new LinkedHashMap < String , Object > ( ) , getIdNameMethod ) ; concreteArrayValueClass . addMethod ( getIdNameMethod ) ; // override getter methods String getSerializableMethodSrc = "public " + Serializable . class . getName ( ) + " getSerializable() { return super.getSerializable(); }" ; CtMethod getSerializableMethod = CtNewMethod . make ( getSerializableMethodSrc , concreteArrayValueClass ) ; LinkedHashMap < String , Object > map = new LinkedHashMap < String , Object > ( ) ; map . put ( "name" , "serializable" ) ; map . put ( "length" , 512 ) ; //if (unique)map.put("unique", true); ClassGeneratorUtils . addAnnotation ( Column . class . getName ( ) , map , getSerializableMethod ) ; concreteArrayValueClass . addMethod ( getSerializableMethod ) ; String getStringMethodSrc = "public String getString() { return super.getString(); }" ; CtMethod getStringMethod = CtNewMethod . make ( getStringMethodSrc , concreteArrayValueClass ) ; map = new LinkedHashMap < String , Object > ( ) ; map . put ( "name" , "string" ) ; //if (unique)map.put("unique", true); ClassGeneratorUtils . addAnnotation ( Column . class . getName ( ) , map , getStringMethod ) ; concreteArrayValueClass . addMethod ( getStringMethod ) ; // FIXME add join columns here or in profile entity class to make // the relation without a join table, atm if this is changed, the // inserts on this table go with profile and table name as null %) // THE PROFILENTITY FIELD IN AAV CLASS IS REQUIRED FOR THE RELATION WITH PROFILE ENTITY CLASS WITHOUT A JOIN TABLE // add join column regarding the relation from array attr value to profile entity CtField ctField = ClassGeneratorUtils . addField ( concreteProfileEntityClass , "owner" , concreteArrayValueClass ) ; ClassGeneratorUtils . generateSetter ( ctField , null ) ; CtMethod getter = ClassGeneratorUtils . generateGetter ( ctField , null ) ; //ClassGeneratorUtils.addAnnotation(ManyToOne.class.getName(), new LinkedHashMap<String, Object>(), getter); // ---- ConstPool cp = getter . getMethodInfo ( ) . getConstPool ( ) ; AnnotationsAttribute attr = ( AnnotationsAttribute ) getter . getMethodInfo ( ) . getAttribute ( AnnotationsAttribute . visibleTag ) ; if ( attr == null ) { attr = new AnnotationsAttribute ( cp , AnnotationsAttribute . visibleTag ) ; } Annotation manyToOne = new Annotation ( ManyToOne . class . getName ( ) , cp ) ; manyToOne . addMemberValue ( "optional" , new BooleanMemberValue ( false , cp ) ) ; attr . addAnnotation ( manyToOne ) ; Annotation joinColumns = new Annotation ( JoinColumns . class . getName ( ) , cp ) ; Annotation joinColumn1 = new Annotation ( JoinColumn . class . getName ( ) , cp ) ; joinColumn1 . addMemberValue ( "name" , new StringMemberValue ( "owner_tableName" , cp ) ) ; joinColumn1 . addMemberValue ( "referencedColumnName" , new StringMemberValue ( "tableName" , cp ) ) ; Annotation joinColumn2 = new Annotation ( JoinColumn . class . getName ( ) , cp ) ; joinColumn2 . addMemberValue ( "name" , new StringMemberValue ( "owner_profileName" , cp ) ) ; joinColumn2 . addMemberValue ( "referencedColumnName" , new StringMemberValue ( "profileName" , cp ) ) ; ArrayMemberValue joinColumnsMemberValue = new ArrayMemberValue ( cp ) ; joinColumnsMemberValue . setValue ( new MemberValue [ ] { new AnnotationMemberValue ( joinColumn1 , cp ) , new AnnotationMemberValue ( joinColumn2 , cp ) } ) ; joinColumns . addMemberValue ( "value" , joinColumnsMemberValue ) ; attr . addAnnotation ( joinColumns ) ; getter . getMethodInfo ( ) . addAttribute ( attr ) ; // generate concrete setProfileEntity method String setProfileEntityMethodSrc = "public void setProfileEntity(" + ProfileEntity . class . getName ( ) + " profileEntity){ setOwner((" + concreteProfileEntityClass . getName ( ) + ")profileEntity); }" ; CtMethod setProfileEntityMethod = CtMethod . make ( setProfileEntityMethodSrc , concreteArrayValueClass ) ; concreteArrayValueClass . addMethod ( setProfileEntityMethod ) ; // write and load the attr array value class String deployDir = profileComponent . getDeploymentDir ( ) . getAbsolutePath ( ) ; if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Writing PROFILE ATTR ARRAY VALUE CONCRETE CLASS ( " + concreteArrayValueClass . getName ( ) + " ) to: " + deployDir ) ; } concreteArrayValueClass . writeFile ( deployDir ) ; return Thread . currentThread ( ) . getContextClassLoader ( ) . loadClass ( concreteArrayValueClass . getName ( ) ) ; } catch ( Throwable e ) { throw new SLEEException ( e . getMessage ( ) , e ) ; } finally { if ( concreteArrayValueClass != null ) { concreteArrayValueClass . defrost ( ) ; } } }
Generates a class that extends {@link ProfileEntityArrayAttributeValue} for a specific entity attribute of array type value
@param concreteProfileEntityClass
@param profileAttributeName
@return
Generates a class that extends {