package org.springframework.roo.addon.javabean.addon;
import static org.springframework.roo.model.GoogleJavaType.GAE_DATASTORE_KEY;
import static org.springframework.roo.model.GoogleJavaType.GAE_DATASTORE_KEY_FACTORY;
import static org.springframework.roo.model.JavaType.LONG_OBJECT;
import static org.springframework.roo.model.JdkJavaType.ARRAY_LIST;
import static org.springframework.roo.model.JdkJavaType.HASH_SET;
import static org.springframework.roo.model.JdkJavaType.LIST;
import static org.springframework.roo.model.JdkJavaType.SET;
import static org.springframework.roo.model.JpaJavaType.MANY_TO_MANY;
import static org.springframework.roo.model.JpaJavaType.MANY_TO_ONE;
import static org.springframework.roo.model.JpaJavaType.ONE_TO_MANY;
import static org.springframework.roo.model.JpaJavaType.ONE_TO_ONE;
import static org.springframework.roo.model.JpaJavaType.TRANSIENT;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.roo.addon.javabean.annotations.RooJavaBean;
import org.springframework.roo.classpath.PhysicalTypeIdentifier;
import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.BeanInfoUtils;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.details.DeclaredFieldAnnotationDetails;
import org.springframework.roo.classpath.details.FieldMetadata;
import org.springframework.roo.classpath.details.FieldMetadataBuilder;
import org.springframework.roo.classpath.details.MethodMetadata;
import org.springframework.roo.classpath.details.MethodMetadataBuilder;
import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadata;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder;
import org.springframework.roo.classpath.scanner.MemberDetails;
import org.springframework.roo.classpath.scanner.MemberDetailsScanner;
import org.springframework.roo.metadata.MetadataIdentificationUtils;
import org.springframework.roo.model.DataType;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.project.LogicalPath;
/**
* Metadata for {@link RooJavaBean}.
*
* @author Ben Alex
* @author Alan Stewart
* @since 1.0
*/
public class JavaBeanMetadata extends AbstractItdTypeDetailsProvidingMetadataItem {
private static final String PROVIDES_TYPE_STRING = JavaBeanMetadata.class.getName();
private static final String PROVIDES_TYPE = MetadataIdentificationUtils
.create(PROVIDES_TYPE_STRING);
public static String createIdentifier(final JavaType javaType, final LogicalPath path) {
return PhysicalTypeIdentifierNamingUtils.createIdentifier(PROVIDES_TYPE_STRING, javaType, path);
}
public static String createIdentifier(ClassOrInterfaceTypeDetails details) {
final LogicalPath logicalPath =
PhysicalTypeIdentifier.getPath(details.getDeclaredByMetadataId());
return createIdentifier(details.getType(), logicalPath);
}
public static JavaType getJavaType(final String metadataIdentificationString) {
return PhysicalTypeIdentifierNamingUtils.getJavaType(PROVIDES_TYPE_STRING,
metadataIdentificationString);
}
public static String getMetadataIdentiferType() {
return PROVIDES_TYPE;
}
public static LogicalPath getPath(final String metadataIdentificationString) {
return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING,
metadataIdentificationString);
}
public static boolean isValid(final String metadataIdentificationString) {
return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING,
metadataIdentificationString);
}
private JavaBeanAnnotationValues annotationValues;
private Map<FieldMetadata, JavaSymbolName> declaredFields;
private List<? extends MethodMetadata> interfaceMethods;
private MemberDetailsScanner memberDetailsScanner;
private Map<JavaSymbolName, MethodMetadata> accesorMethods;
private Map<JavaSymbolName, MethodMetadata> mutatorMethods;
/**
* Constructor
*
* @param identifier
* the ID of the metadata to create (must be a valid ID)
* @param aspectName
* the name of the ITD to be created (required)
* @param governorPhysicalTypeMetadata
* the governor (required)
* @param annotationValues
* the values of the {@link RooJavaBean} annotation (required)
* @param declaredFields
* the fields declared in the governor (required, can be empty)
* @param memberDetailsScanner
* the memberDetailsScanner used to get declared methods
*/
public JavaBeanMetadata(final String identifier, final JavaType aspectName,
final PhysicalTypeMetadata governorPhysicalTypeMetadata,
final JavaBeanAnnotationValues annotationValues,
final Map<FieldMetadata, JavaSymbolName> declaredFields,
List<? extends MethodMetadata> interfaceMethods, MemberDetailsScanner memberDetailsScanner) {
super(identifier, aspectName, governorPhysicalTypeMetadata);
Validate.isTrue(isValid(identifier),
"Metadata identification string '%s' does not appear to be a valid", identifier);
Validate.notNull(annotationValues, "Annotation values required");
Validate.notNull(declaredFields, "Declared fields required");
if (!isValid()) {
return;
}
if (declaredFields.isEmpty()) {
return; // N.B. the MD is still valid, just empty
}
this.annotationValues = annotationValues;
this.declaredFields = declaredFields;
this.interfaceMethods = interfaceMethods;
this.memberDetailsScanner = memberDetailsScanner;
this.accesorMethods = new HashMap<JavaSymbolName, MethodMetadata>();
this.mutatorMethods = new HashMap<JavaSymbolName, MethodMetadata>();
// Add getters and setters
for (final Entry<FieldMetadata, JavaSymbolName> entry : declaredFields.entrySet()) {
final FieldMetadata field = entry.getKey();
final MethodMetadataBuilder accessorMethod = getDeclaredGetter(field);
final MethodMetadataBuilder mutatorMethod = getDeclaredSetter(field);
// Check to see if GAE is interested
if (entry.getValue() != null) {
JavaSymbolName hiddenIdFieldName;
if (field.getFieldType().isCommonCollectionType()) {
hiddenIdFieldName =
governorTypeDetails.getUniqueFieldName(field.getFieldName().getSymbolName() + "Keys");
builder.getImportRegistrationResolver().addImport(GAE_DATASTORE_KEY_FACTORY);
builder.addField(getMultipleEntityIdField(hiddenIdFieldName));
} else {
hiddenIdFieldName =
governorTypeDetails.getUniqueFieldName(field.getFieldName().getSymbolName() + "Id");
builder.addField(getSingularEntityIdField(hiddenIdFieldName));
}
processGaeAnnotations(field);
accessorMethod.setBodyBuilder(getGaeAccessorBody(field, hiddenIdFieldName));
mutatorMethod.setBodyBuilder(getGaeMutatorBody(field, hiddenIdFieldName));
}
// Add to mutators and accesors list and build
if (accessorMethod != null) {
this.accesorMethods.put(field.getFieldName(), accessorMethod.build());
builder.addMethod(accessorMethod);
}
if (mutatorMethod != null) {
this.mutatorMethods.put(field.getFieldName(), mutatorMethod.build());
builder.addMethod(mutatorMethod);
}
}
// Implements interface methods if exists
if (interfaceMethods != null) {
for (MethodMetadata interfaceMethod : interfaceMethods) {
MethodMetadataBuilder methodBuilder = getInterfaceMethod(interfaceMethod);
// ROO-3584: JavaBean implementing Interface defining getters and setters
// ROO-3585: If interface method already exists on type is not necessary
// to add on ITD. Method builder will be NULL.
if (methodBuilder != null && !checkIfInterfaceMethodWasImplemented(methodBuilder)) {
builder.addMethod(methodBuilder);
}
}
}
// Create a representation of the desired output ITD
itdTypeDetails = builder.build();
}
/**
* Obtains the specific accessor method that is either contained within the
* normal Java compilation unit or will be introduced by this add-on via an
* ITD.
*
* @param field
* that already exists on the type either directly or via
* introduction (required; must be declared by this type to be
* located)
* @return the method corresponding to an accessor, or null if not found
*/
private MethodMetadataBuilder getDeclaredGetter(final FieldMetadata field) {
Validate.notNull(field, "Field required");
// Compute the mutator method name
final JavaSymbolName methodName = BeanInfoUtils.getAccessorMethodName(field);
// See if the type itself declared the accessor
if (governorHasMethod(methodName)) {
return null;
}
// Decide whether we need to produce the accessor method (see ROO-619
// for reason we allow a getter for a final field)
if (annotationValues.isGettersByDefault() && !Modifier.isTransient(field.getModifier())
&& !Modifier.isStatic(field.getModifier())) {
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine("return this." + field.getFieldName().getSymbolName() + ";");
return new MethodMetadataBuilder(getId(), Modifier.PUBLIC, methodName, field.getFieldType(),
bodyBuilder);
}
return null;
}
/**
* Obtains the specific mutator method that is either contained within the
* normal Java compilation unit or will be introduced by this add-on via an
* ITD.
*
* @param field
* that already exists on the type either directly or via
* introduction (required; must be declared by this type to be
* located)
* @return the method corresponding to a mutator, or null if not found
*/
private MethodMetadataBuilder getDeclaredSetter(final FieldMetadata field) {
Validate.notNull(field, "Field required");
// Compute the mutator method name
final JavaSymbolName methodName = BeanInfoUtils.getMutatorMethodName(field);
// Compute the mutator method parameters
final JavaType parameterType = field.getFieldType();
// See if the type itself declared the mutator
if (governorHasMethod(methodName, parameterType)) {
return null;
}
// Compute the mutator method parameter names
final List<JavaSymbolName> parameterNames = Arrays.asList(field.getFieldName());
// Decide whether we need to produce the mutator method (disallowed for
// final fields as per ROO-36)
if (annotationValues.isSettersByDefault() && !Modifier.isTransient(field.getModifier())
&& !Modifier.isStatic(field.getModifier()) && !Modifier.isFinal(field.getModifier())) {
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine("this." + field.getFieldName().getSymbolName() + " = "
+ field.getFieldName().getSymbolName() + ";");
return new MethodMetadataBuilder(getId(), Modifier.PUBLIC, methodName,
JavaType.VOID_PRIMITIVE, AnnotatedJavaType.convertFromJavaTypes(parameterType),
parameterNames, bodyBuilder);
}
return null;
}
/**
* Obtains a valid MethodMetadataBuilder with necessary configuration
*
* @param method
* @return MethodMetadataBuilder
*/
private MethodMetadataBuilder getInterfaceMethod(final MethodMetadata method) {
// Compute the method name
final JavaSymbolName methodName = method.getMethodName();
// See if the type itself declared the accessor
if (governorHasMethod(methodName)) {
return null;
}
// Getting return type
JavaType returnType = method.getReturnType();
// Generating body
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
// If return type is not primitive, return null
if (returnType.isPrimitive()) {
JavaType baseType = returnType.getBaseType();
if (baseType.equals(JavaType.BOOLEAN_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return false;");
} else if (baseType.equals(JavaType.BYTE_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0;");
} else if (baseType.equals(JavaType.SHORT_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0;");
} else if (baseType.equals(JavaType.INT_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0;");
} else if (baseType.equals(JavaType.LONG_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0;");
} else if (baseType.equals(JavaType.FLOAT_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0;");
} else if (baseType.equals(JavaType.DOUBLE_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return 0.00;");
} else if (baseType.equals(JavaType.CHAR_PRIMITIVE)) {
bodyBuilder.appendFormalLine("return '\0';");
}
} else {
bodyBuilder.appendFormalLine("return null;");
}
return new MethodMetadataBuilder(getId(), Modifier.PUBLIC, methodName, returnType, bodyBuilder);
}
private InvocableMemberBodyBuilder getEntityCollectionAccessorBody(final FieldMetadata field,
final JavaSymbolName entityIdsFieldName) {
final String entityCollectionName = field.getFieldName().getSymbolName();
final String entityIdsName = entityIdsFieldName.getSymbolName();
final String localEnitiesName = "local" + StringUtils.capitalize(entityCollectionName);
final JavaType collectionElementType = field.getFieldType().getParameters().get(0);
final String simpleCollectionElementTypeName = collectionElementType.getSimpleTypeName();
JavaType collectionType = field.getFieldType();
builder.getImportRegistrationResolver().addImport(collectionType);
final String collectionName =
field.getFieldType().getNameIncludingTypeParameters()
.replace(field.getFieldType().getPackage().getFullyQualifiedPackageName() + ".", "");
String instantiableCollection = collectionName;
// GAE only supports java.util.List and java.util.Set collections and we
// need a concrete implementation of either.
if (collectionType.getFullyQualifiedTypeName().equals(LIST.getFullyQualifiedTypeName())) {
collectionType =
new JavaType(ARRAY_LIST.getFullyQualifiedTypeName(), 0, DataType.TYPE, null,
collectionType.getParameters());
instantiableCollection =
collectionType.getNameIncludingTypeParameters().replace(
collectionType.getPackage().getFullyQualifiedPackageName() + ".", "");
} else if (collectionType.getFullyQualifiedTypeName().equals(SET.getFullyQualifiedTypeName())) {
collectionType =
new JavaType(HASH_SET.getFullyQualifiedTypeName(), 0, DataType.TYPE, null,
collectionType.getParameters());
instantiableCollection =
collectionType.getNameIncludingTypeParameters().replace(
collectionType.getPackage().getFullyQualifiedPackageName() + ".", "");
}
builder.getImportRegistrationResolver().addImport(collectionType);
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine(collectionName + " " + localEnitiesName + " = new "
+ instantiableCollection + "();");
bodyBuilder.appendFormalLine("for (Key key : " + entityIdsName + ") {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine(simpleCollectionElementTypeName + " entity = "
+ simpleCollectionElementTypeName + ".find" + simpleCollectionElementTypeName
+ "(key.getId());");
bodyBuilder.appendFormalLine("if (entity != null) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine(localEnitiesName + ".add(entity);");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("this." + entityCollectionName + " = " + localEnitiesName + ";");
bodyBuilder.appendFormalLine("return " + localEnitiesName + ";");
return bodyBuilder;
}
private InvocableMemberBodyBuilder getEntityCollectionMutatorBody(final FieldMetadata field,
final JavaSymbolName entityIdsFieldName) {
final String entityCollectionName = field.getFieldName().getSymbolName();
final String entityIdsName = entityIdsFieldName.getSymbolName();
final JavaType collectionElementType = field.getFieldType().getParameters().get(0);
final String localEnitiesName = "local" + StringUtils.capitalize(entityCollectionName);
JavaType collectionType = field.getFieldType();
builder.getImportRegistrationResolver().addImport(collectionType);
final String collectionName =
field.getFieldType().getNameIncludingTypeParameters()
.replace(field.getFieldType().getPackage().getFullyQualifiedPackageName() + ".", "");
String instantiableCollection = collectionName;
if (collectionType.getFullyQualifiedTypeName().equals(LIST.getFullyQualifiedTypeName())) {
collectionType =
new JavaType(ARRAY_LIST.getFullyQualifiedTypeName(), 0, DataType.TYPE, null,
collectionType.getParameters());
instantiableCollection =
collectionType.getNameIncludingTypeParameters().replace(
collectionType.getPackage().getFullyQualifiedPackageName() + ".", "");
} else if (collectionType.getFullyQualifiedTypeName().equals(SET.getFullyQualifiedTypeName())) {
collectionType =
new JavaType(HASH_SET.getFullyQualifiedTypeName(), 0, DataType.TYPE, null,
collectionType.getParameters());
instantiableCollection =
collectionType.getNameIncludingTypeParameters().replace(
collectionType.getPackage().getFullyQualifiedPackageName() + ".", "");
}
builder.getImportRegistrationResolver().addImports(collectionType, LIST, ARRAY_LIST);
final String identifierMethodName = getIdentifierMethodName(field).getSymbolName();
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine(collectionName + " " + localEnitiesName + " = new "
+ instantiableCollection + "();");
bodyBuilder.appendFormalLine("List<Long> longIds = new ArrayList<Long>();");
bodyBuilder.appendFormalLine("for (Key key : " + entityIdsName + ") {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("if (!longIds.contains(key.getId())) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("longIds.add(key.getId());");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("for (" + collectionElementType.getSimpleTypeName() + " entity : "
+ entityCollectionName + ") {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("if (!longIds.contains(entity." + identifierMethodName + "())) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("longIds.add(entity." + identifierMethodName + "());");
bodyBuilder.appendFormalLine(entityIdsName + ".add(KeyFactory.createKey("
+ collectionElementType.getSimpleTypeName() + ".class.getName(), entity."
+ identifierMethodName + "()));");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine(localEnitiesName + ".add(entity);");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("this." + entityCollectionName + " = " + localEnitiesName + ";");
return bodyBuilder;
}
private InvocableMemberBodyBuilder getGaeAccessorBody(final FieldMetadata field,
final JavaSymbolName hiddenIdFieldName) {
return field.getFieldType().isCommonCollectionType() ? getEntityCollectionAccessorBody(field,
hiddenIdFieldName) : getSingularEntityAccessor(field, hiddenIdFieldName);
}
private InvocableMemberBodyBuilder getGaeMutatorBody(final FieldMetadata field,
final JavaSymbolName hiddenIdFieldName) {
return field.getFieldType().isCommonCollectionType() ? getEntityCollectionMutatorBody(field,
hiddenIdFieldName) : getSingularEntityMutator(field, hiddenIdFieldName);
}
private InvocableMemberBodyBuilder getInterfaceMethodBody(JavaType returnType) {
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine("// Interface Implementation");
bodyBuilder.appendFormalLine("return 0;");
return bodyBuilder;
}
private JavaSymbolName getIdentifierMethodName(final FieldMetadata field) {
final JavaSymbolName identifierAccessorMethodName = declaredFields.get(field);
return identifierAccessorMethodName != null ? identifierAccessorMethodName
: new JavaSymbolName("getId");
}
private FieldMetadataBuilder getMultipleEntityIdField(final JavaSymbolName fieldName) {
builder.getImportRegistrationResolver().addImport(HASH_SET);
return new FieldMetadataBuilder(getId(), Modifier.PRIVATE, fieldName, new JavaType(
SET.getFullyQualifiedTypeName(), 0, DataType.TYPE, null,
Collections.singletonList(GAE_DATASTORE_KEY)), "new HashSet<Key>()");
}
private InvocableMemberBodyBuilder getSingularEntityAccessor(final FieldMetadata field,
final JavaSymbolName hiddenIdFieldName) {
final String entityName = field.getFieldName().getSymbolName();
final String entityIdName = hiddenIdFieldName.getSymbolName();
final String simpleFieldTypeName = field.getFieldType().getSimpleTypeName();
final String identifierMethodName = getIdentifierMethodName(field).getSymbolName();
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine("if (this." + entityIdName + " != null) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("if (this." + entityName + " == null || this." + entityName + "."
+ identifierMethodName + "() != this." + entityIdName + ") {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("this." + entityName + " = " + simpleFieldTypeName + ".find"
+ simpleFieldTypeName + "(this." + entityIdName + ");");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("} else {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("this." + entityName + " = null;");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("return this." + entityName + ";");
return bodyBuilder;
}
private FieldMetadataBuilder getSingularEntityIdField(final JavaSymbolName fieldName) {
return new FieldMetadataBuilder(getId(), Modifier.PRIVATE, fieldName, LONG_OBJECT, null);
}
private InvocableMemberBodyBuilder getSingularEntityMutator(final FieldMetadata field,
final JavaSymbolName hiddenIdFieldName) {
final String entityName = field.getFieldName().getSymbolName();
final String entityIdName = hiddenIdFieldName.getSymbolName();
final String identifierMethodName = getIdentifierMethodName(field).getSymbolName();
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
bodyBuilder.appendFormalLine("if (" + entityName + " != null) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("if (" + entityName + "." + identifierMethodName
+ " () == null) {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine(entityName + ".persist();");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("this." + entityIdName + " = " + entityName + "."
+ identifierMethodName + "();");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("} else {");
bodyBuilder.indent();
bodyBuilder.appendFormalLine("this." + entityIdName + " = null;");
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("this." + entityName + " = " + entityName + ";");
return bodyBuilder;
}
private void processGaeAnnotations(final FieldMetadata field) {
for (final AnnotationMetadata annotation : field.getAnnotations()) {
if (annotation.getAnnotationType().equals(ONE_TO_ONE)
|| annotation.getAnnotationType().equals(MANY_TO_ONE)
|| annotation.getAnnotationType().equals(ONE_TO_MANY)
|| annotation.getAnnotationType().equals(MANY_TO_MANY)) {
builder.addFieldAnnotation(new DeclaredFieldAnnotationDetails(field,
new AnnotationMetadataBuilder(annotation.getAnnotationType()).build(), true));
builder.addFieldAnnotation(new DeclaredFieldAnnotationDetails(field,
new AnnotationMetadataBuilder(TRANSIENT).build()));
break;
}
}
}
/**
* To check if current method was implemented on all Java classes or ITds
* associated to this entity class.
* If method was implemented, is not necessary to add again.
*
* @param methodBuilder
* @return
*/
private boolean checkIfInterfaceMethodWasImplemented(MethodMetadataBuilder methodBuilder) {
// ROO-3584: Obtain current declared methods
List<MethodMetadataBuilder> declaredMethods = builder.getDeclaredMethods();
for (MethodMetadataBuilder method : declaredMethods) {
// If current method equals to interface method, return false
if (method.getMethodName().equals(methodBuilder.getMethodName())) {
return true;
}
}
// ROO-3587: Obtain ALL declared methods from Java classes and ITDs.
MemberDetails memberDetails =
memberDetailsScanner.getMemberDetails(getClass().getName(), governorTypeDetails);
List<MethodMetadata> allMethods = memberDetails.getMethods();
for (MethodMetadata method : allMethods) {
// If current method equals to interface method, return false
if (method.getMethodName().equals(methodBuilder.getMethodName())) {
return true;
}
}
return false;
}
/**
* Returns a list with the mutator methods of the class requesting the metadata
*
* @return List<MethodMetadata> with mutator methods of the class
*/
public List<MethodMetadata> getMutatorMethods() {
return (List<MethodMetadata>) this.mutatorMethods.values();
}
/**
* Returns the mutator method related with the provided field
*
* @return MethodMetadata with the mutator method of the field
*/
public MethodMetadata getMutatorMethod(FieldMetadata field) {
return mutatorMethods.get(field.getFieldName());
}
/**
* Returns a list with the accesor methods of the class requesting the metadata
*
* @return List<MethodMetadata> with accesor methods of the class
*/
public List<MethodMetadata> getAccesorMethods() {
return (List<MethodMetadata>) this.accesorMethods.values();
}
/**
* Returns the accesor method related with the provided field
*
* @return MethodMetadata with the accesor method of the field
*/
public MethodMetadata getAccesorMethod(FieldMetadata field) {
return accesorMethods.get(field.getFieldName());
}
@Override
public String toString() {
final ToStringBuilder builder = new ToStringBuilder(this);
builder.append("identifier", getId());
builder.append("valid", valid);
builder.append("aspectName", aspectName);
builder.append("destinationType", destination);
builder.append("governor", governorPhysicalTypeMetadata.getId());
builder.append("itdTypeDetails", itdTypeDetails);
return builder.toString();
}
}