package org.springframework.roo.classpath.details; import static org.springframework.roo.classpath.customdata.CustomDataKeys.LAYER_TYPE; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.commons.lang3.Validate; import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType; import org.springframework.roo.classpath.details.annotations.AnnotationMetadata; import org.springframework.roo.model.CustomData; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; import org.springframework.roo.support.util.CollectionUtils; /** * Convenient superclass for {@link MemberHoldingTypeDetails} implementations. * * @author Andrew Swan * @since 1.2.0 */ public abstract class AbstractMemberHoldingTypeDetails extends AbstractIdentifiableAnnotatedJavaStructureProvider implements MemberHoldingTypeDetails { /** * Constructor * * @param customData * @param declaredByMetadataId * @param modifier * @param annotations */ protected AbstractMemberHoldingTypeDetails(final CustomData customData, final String declaredByMetadataId, final int modifier, final Collection<AnnotationMetadata> annotations) { super(customData, declaredByMetadataId, modifier, annotations); } public ConstructorMetadata getDeclaredConstructor(final List<JavaType> parameters) { final Collection<JavaType> parameterList = CollectionUtils.populate(new ArrayList<JavaType>(), parameters); for (final ConstructorMetadata constructor : getDeclaredConstructors()) { if (parameterList.equals(AnnotatedJavaType.convertFromAnnotatedJavaTypes(constructor .getParameterTypes()))) { return constructor; } } return null; } public FieldMetadata getDeclaredField(final JavaSymbolName fieldName) { for (final FieldMetadata field : getDeclaredFields()) { if (field.getFieldName().equals(fieldName)) { return field; } } return null; } public ClassOrInterfaceTypeDetails getDeclaredInnerType(final JavaType typeName) { Validate.notNull(typeName, "Name of inner type required"); for (final ClassOrInterfaceTypeDetails cid : getDeclaredInnerTypes()) { if (cid.getName().getSimpleTypeName().equals(typeName.getSimpleTypeName())) { return cid; } } return null; } public FieldMetadata getField(final JavaSymbolName fieldName) { Validate.notNull(fieldName, "Field name required"); MemberHoldingTypeDetails current = this; while (current != null) { final FieldMetadata result = current.getDeclaredField(fieldName); if (result != null) { return result; } if (current instanceof ClassOrInterfaceTypeDetails) { current = ((ClassOrInterfaceTypeDetails) current).getSuperclass(); } else { current = null; } } return null; } public List<FieldMetadata> getFieldsWithAnnotation(final JavaType annotation) { Validate.notNull(annotation, "Annotation required"); final List<FieldMetadata> result = new ArrayList<FieldMetadata>(); MemberHoldingTypeDetails current = this; while (current != null) { for (final FieldMetadata field : current.getDeclaredFields()) { if (MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), annotation) != null) { // Found the annotation on this field result.add(field); } } if (current instanceof ClassOrInterfaceTypeDetails) { current = ((ClassOrInterfaceTypeDetails) current).getSuperclass(); } else { current = null; } } return result; } @SuppressWarnings("unchecked") public List<JavaType> getLayerEntities() { final Object entities = getCustomData().get(LAYER_TYPE); if (entities == null) { return Collections.emptyList(); } return (List<JavaType>) entities; } public MethodMetadata getMethod(final JavaSymbolName methodName) { Validate.notNull(methodName, "Method name required"); MemberHoldingTypeDetails current = this; while (current != null) { final MethodMetadata result = MemberFindingUtils.getDeclaredMethod(current, methodName); if (result != null) { return result; } if (current instanceof ClassOrInterfaceTypeDetails) { current = ((ClassOrInterfaceTypeDetails) current).getSuperclass(); } else { current = null; } } return null; } public MethodMetadata getMethod(final JavaSymbolName methodName, List<JavaType> parameters) { Validate.notNull(methodName, "Method name required"); if (parameters == null) { parameters = new ArrayList<JavaType>(); } MemberHoldingTypeDetails current = this; while (current != null) { final MethodMetadata result = MemberFindingUtils.getDeclaredMethod(current, methodName, parameters); if (result != null) { return result; } if (current instanceof ClassOrInterfaceTypeDetails) { current = ((ClassOrInterfaceTypeDetails) current).getSuperclass(); } else { current = null; } } return null; } public List<MethodMetadata> getMethods() { final List<MethodMetadata> result = new ArrayList<MethodMetadata>(); MemberHoldingTypeDetails current = this; while (current != null) { for (final MethodMetadata method : current.getDeclaredMethods()) { result.add(method); } if (current instanceof ClassOrInterfaceTypeDetails) { current = ((ClassOrInterfaceTypeDetails) current).getSuperclass(); } else { current = null; } } return result; } public JavaSymbolName getUniqueFieldName(final String proposedName) { Validate.notBlank(proposedName, "Proposed field name is required"); String candidateName = proposedName; while (getField(new JavaSymbolName(candidateName)) != null) { // The proposed field name is taken; differentiate it candidateName += "_"; } // We've derived a unique name return new JavaSymbolName(candidateName); } public boolean implementsType(final JavaType interfaceType) { return getImplementsTypes().contains(interfaceType); } }