package org.springframework.roo.addon.layers.service.addon;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata;
import org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo;
import org.springframework.roo.addon.jpa.annotations.entity.JpaRelationType;
import org.springframework.roo.addon.layers.repository.jpa.addon.RepositoryJpaMetadata;
import org.springframework.roo.addon.layers.service.annotations.RooService;
import org.springframework.roo.classpath.PhysicalTypeIdentifier;
import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.details.FieldMetadata;
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.itd.AbstractItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.classpath.operations.Cardinality;
import org.springframework.roo.metadata.MetadataIdentificationUtils;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.model.SpringletsJavaType;
import org.springframework.roo.project.LogicalPath;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Metadata for {@link RooService}.
*
* @author Juan Carlos García
* @author Jose Manuel Vivó
* @author Sergio Clares
* @since 2.0
*/
public class ServiceMetadata extends AbstractItdTypeDetailsProvidingMetadataItem {
private static final String PROVIDES_TYPE_STRING = ServiceMetadata.class.getName();
private static final String PROVIDES_TYPE = MetadataIdentificationUtils
.create(PROVIDES_TYPE_STRING);
private final JavaType entity;
private final JavaType identifierType;
private final List<MethodMetadata> finders;
private final MethodMetadata findAllGlobalSearchMethod;
private final MethodMetadata findAllByIdsInGlobalSearchMethod;
private final List<MethodMetadata> transactionalDefinedMethod;
private final List<MethodMetadata> notTransactionalDefinedMethod;
private final Map<FieldMetadata, MethodMetadata> countByReferenceFieldDefinedMethod;
private final Map<FieldMetadata, MethodMetadata> referencedFieldsFindAllDefinedMethods;
private final List<MethodMetadata> customCountMethods;
private final JpaEntityMetadata entityMetadata;
private final RepositoryJpaMetadata repositoryMetadata;
private final MethodMetadata saveMethod;
private final MethodMetadata deleteMethod;
private final MethodMetadata saveBatchMethod;
private final MethodMetadata deleteBatchMethod;
private final MethodMetadata findOneMethod;
private final MethodMetadata findOneForUpdateMethod;
private final MethodMetadata findAllMethod;
private final MethodMetadata findAllIterableMethod;
private final MethodMetadata countMethod;
private final MethodMetadata findAllWithGlobalSearchMethod;
private final MethodMetadata findAllByIdsInWithGlobalSearchMethod;
private final Map<JavaType, JpaEntityMetadata> relatedEntitiesMetadata;
private final Set<MethodMetadata> allMethods;
private final Map<RelationInfo, MethodMetadata> addToRelationMethods;
private final Map<RelationInfo, MethodMetadata> removeFromRelationMethods;
private final Map<RelationInfo, MethodMetadata> setRelationMethods;
private final Map<JavaSymbolName, MethodMetadata> repositoryFindersAndCounts;
private final Map<JavaSymbolName, MethodMetadata> repositoryCustomFindersAndCounts;
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);
}
/**
* Constructor
*
* @param identifier the identifier for this item of metadata (required)
* @param aspectName the Java type of the ITD (required)
* @param governorPhysicalTypeMetadata the governor, which is expected to
* contain a {@link ClassOrInterfaceTypeDetails} (required)
* @param entity entity referenced on interface
* @param identifierType the type of the entity's identifier field
* (required)
* @param entityMetadata
* @param repositoryMetadata
* @param finders list of finders added to current entity
* @param findAllGlobalSearchMethod MethodMetadata with findAllGlobalSearch method
* @param referencedFieldsFindAllMethods
* @param countByReferencedFieldsMethods
* @param customCountMethods
* @param relatedEntities
*
*/
public ServiceMetadata(final String identifier, final JavaType aspectName,
final PhysicalTypeMetadata governorPhysicalTypeMetadata, final JavaType entity,
final JavaType identifierType, final JpaEntityMetadata entityMetadata,
RepositoryJpaMetadata repositoryMetadata, final List<MethodMetadata> finders,
final MethodMetadata findAllGlobalSearchMethod,
final MethodMetadata findAllByIdsInGlobalSearchMethod,
final Map<FieldMetadata, MethodMetadata> referencedFieldsFindAllMethods,
final Map<FieldMetadata, MethodMetadata> countByReferencedFieldsMethods,
final List<MethodMetadata> customCountMethods,
Map<JavaType, JpaEntityMetadata> relatedEntities,
Map<JavaSymbolName, MethodMetadata> repositoryFindersAndCounts,
Map<JavaSymbolName, MethodMetadata> repositoryCustomFindersAndCounts) {
super(identifier, aspectName, governorPhysicalTypeMetadata);
Validate.notNull(entity, "ERROR: Entity required to generate service interface");
Validate.notNull(identifierType,
"ERROR: Entity identifier type required to generate service interface");
this.entity = entity;
this.identifierType = identifierType;
this.entityMetadata = entityMetadata;
this.relatedEntitiesMetadata = relatedEntities;
this.repositoryMetadata = repositoryMetadata;
this.finders = finders;
this.findAllGlobalSearchMethod = findAllGlobalSearchMethod;
this.findAllByIdsInGlobalSearchMethod = findAllByIdsInGlobalSearchMethod;
this.repositoryFindersAndCounts = repositoryFindersAndCounts;
this.repositoryCustomFindersAndCounts = repositoryCustomFindersAndCounts;
Map<FieldMetadata, MethodMetadata> referencedFieldsFindAllDefinedMethods =
new HashMap<FieldMetadata, MethodMetadata>();
List<MethodMetadata> transactionalDefinedMethod = new ArrayList<MethodMetadata>();
List<MethodMetadata> notTransactionalDefinedMethod = new ArrayList<MethodMetadata>();
Map<FieldMetadata, MethodMetadata> countByReferenceFieldDefinedMethod =
new HashMap<FieldMetadata, MethodMetadata>();
this.customCountMethods = Collections.unmodifiableList(customCountMethods);
this.findOneMethod = getFindOneMethod();
notTransactionalDefinedMethod.add(findOneMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findOneMethod));
// ROO-3868: Extend from Springlets EntityResolver to use new entity view system
JavaType extendsType =
JavaType.wrapperOf(SpringletsJavaType.SPRINGLETS_ENTITY_RESOLVER, this.entity,
this.identifierType);
ensureGovernorExtends(extendsType);
// Generating persistent methods for modifiable entities
// (not reandOnly an no composition child)
if (entityMetadata.isReadOnly() || entityMetadata.isCompositionChild()) {
this.deleteMethod = null;
this.saveBatchMethod = null;
this.deleteBatchMethod = null;
} else {
// Add modification methods
this.deleteMethod = getDeleteMethod();
transactionalDefinedMethod.add(deleteMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(deleteMethod));
this.saveBatchMethod = getSaveBatchMethod();
transactionalDefinedMethod.add(saveBatchMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(saveBatchMethod));
this.deleteBatchMethod = getDeleteBatchMethod();
transactionalDefinedMethod.add(deleteBatchMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(deleteBatchMethod));
}
if (entityMetadata.isReadOnly()) {
this.saveMethod = null;
this.findOneForUpdateMethod = null;
} else {
this.saveMethod = getSaveMethod();
transactionalDefinedMethod.add(saveMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(saveMethod));
// Add findOneDetached method
this.findOneForUpdateMethod = getFindOneForUpdateMethod();
notTransactionalDefinedMethod.add(findOneForUpdateMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findOneForUpdateMethod));
}
// Add standard finders methods (if not composition child)
this.findAllIterableMethod = getFindAllIterableMethod();
notTransactionalDefinedMethod.add(findAllIterableMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findAllIterableMethod));
if (entityMetadata.isCompositionChild()) {
// No standard finder methods
this.findAllMethod = null;
this.countMethod = null;
this.findAllWithGlobalSearchMethod = null;
this.findAllByIdsInWithGlobalSearchMethod = null;
} else {
// Add standard finders methods
this.findAllMethod = getFindAllMethod();
notTransactionalDefinedMethod.add(findAllMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findAllMethod));
this.countMethod = getCountMethod();
notTransactionalDefinedMethod.add(countMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(countMethod));
// Generating findAll method that includes GlobalSearch parameter
this.findAllWithGlobalSearchMethod = getFindAllGlobalSearchMethod();
notTransactionalDefinedMethod.add(findAllWithGlobalSearchMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findAllWithGlobalSearchMethod));
// Generating findAllByIdsIn method
this.findAllByIdsInWithGlobalSearchMethod = getFindAllByIdsInGlobalSearchMethod();
notTransactionalDefinedMethod.add(findAllByIdsInWithGlobalSearchMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(findAllByIdsInWithGlobalSearchMethod));
}
// Add relation management methods
Map<RelationInfo, MethodMetadata> addToRelationMethodsTemp =
new TreeMap<RelationInfo, MethodMetadata>();
Map<RelationInfo, MethodMetadata> removeFromRelationMethodsTemp =
new TreeMap<RelationInfo, MethodMetadata>();
Map<RelationInfo, MethodMetadata> setRelationMethodsTemp =
new TreeMap<RelationInfo, MethodMetadata>();
MethodMetadata tmpMethod;
for (RelationInfo relationInfo : entityMetadata.getRelationInfos().values()) {
// Relations will be managed only for non readOnly entities
if (relationInfo.cardinality != Cardinality.ONE_TO_ONE && !entityMetadata.isReadOnly()) {
// addToRELATION
tmpMethod = getAddToRelationMethod(relationInfo);
addToRelationMethodsTemp.put(relationInfo, tmpMethod);
transactionalDefinedMethod.add(tmpMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(tmpMethod));
// removeFromRELATION
tmpMethod = getRemoveFromRelationMethod(relationInfo);
removeFromRelationMethodsTemp.put(relationInfo, tmpMethod);
transactionalDefinedMethod.add(tmpMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(tmpMethod));
if (relationInfo.type == JpaRelationType.AGGREGATION) {
// setRELATION
tmpMethod = getSetRelationMethod(relationInfo);
setRelationMethodsTemp.put(relationInfo, tmpMethod);
transactionalDefinedMethod.add(tmpMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(tmpMethod));
}
}
}
addToRelationMethods = Collections.unmodifiableMap(addToRelationMethodsTemp);
setRelationMethods = Collections.unmodifiableMap(setRelationMethodsTemp);
removeFromRelationMethods = Collections.unmodifiableMap(removeFromRelationMethodsTemp);
// ROO-3765: Prevent ITD regeneration applying the same sort to provided map. If this sort is not applied, maybe some
// method is not in the same order and ITD will be regenerated.
Map<FieldMetadata, MethodMetadata> referencedFieldsFindAllMethodsOrderedByFieldName =
new TreeMap<FieldMetadata, MethodMetadata>(FieldMetadata.COMPARATOR_BY_NAME);
referencedFieldsFindAllMethodsOrderedByFieldName.putAll(referencedFieldsFindAllMethods);
// Generating all findAll method for every referenced fields
for (Entry<FieldMetadata, MethodMetadata> findAllReferencedFieldMethod : referencedFieldsFindAllMethodsOrderedByFieldName
.entrySet()) {
MethodMetadata method =
getFindAllReferencedFieldMethod(findAllReferencedFieldMethod.getValue());
notTransactionalDefinedMethod.add(method);
referencedFieldsFindAllDefinedMethods.put(findAllReferencedFieldMethod.getKey(), method);
ensureGovernorHasMethod(new MethodMetadataBuilder(method));
}
// ROO-3765: Prevent ITD regeneration applying the same sort to provided map. If this sort is not applied, maybe some
// method is not in the same order and ITD will be regenerated.
Map<FieldMetadata, MethodMetadata> countByReferencedFieldsMethodsOrderedByFieldName =
new TreeMap<FieldMetadata, MethodMetadata>(FieldMetadata.COMPARATOR_BY_NAME);
countByReferencedFieldsMethodsOrderedByFieldName.putAll(countByReferencedFieldsMethods);
// Generating all countByReferencedField methods
if (countByReferencedFieldsMethods != null) {
for (Entry<FieldMetadata, MethodMetadata> countByReferencedFieldMethod : countByReferencedFieldsMethodsOrderedByFieldName
.entrySet()) {
MethodMetadata method =
getCountByReferencedFieldMethod(countByReferencedFieldMethod.getValue());
countByReferenceFieldDefinedMethod.put(countByReferencedFieldMethod.getKey(), method);
notTransactionalDefinedMethod.add(method);
ensureGovernorHasMethod(new MethodMetadataBuilder(method));
}
}
// Generating finders
for (MethodMetadata finder : finders) {
MethodMetadata finderMethod = getFinderMethod(finder);
notTransactionalDefinedMethod.add(finderMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(finderMethod));
}
// Generating count finder methods
for (MethodMetadata customCountMethod : customCountMethods) {
MethodMetadata customCountServiceMethod = getCustomCountMethod(customCountMethod);
if (!isAlreadyDefinedMethod(customCountMethod, countByReferencedFieldsMethods.values())) {
notTransactionalDefinedMethod.add(customCountServiceMethod);
ensureGovernorHasMethod(new MethodMetadataBuilder(customCountServiceMethod));
}
}
this.referencedFieldsFindAllDefinedMethods =
Collections.unmodifiableMap(referencedFieldsFindAllDefinedMethods);
this.transactionalDefinedMethod = Collections.unmodifiableList(transactionalDefinedMethod);
this.notTransactionalDefinedMethod =
Collections.unmodifiableList(notTransactionalDefinedMethod);
this.countByReferenceFieldDefinedMethod =
Collections.unmodifiableMap(countByReferencedFieldsMethods);
Set<MethodMetadata> allMethod = new TreeSet<MethodMetadata>(MethodMetadata.COMPARATOR_BY_NAME);
allMethod.addAll(notTransactionalDefinedMethod);
allMethod.addAll(transactionalDefinedMethod);
this.allMethods = Collections.unmodifiableSet(allMethod);
// Build the ITD
itdTypeDetails = builder.build();
}
private boolean isAlreadyDefinedMethod(MethodMetadata method, Collection<MethodMetadata> values) {
for (MethodMetadata value : values) {
if (method.matchSignature(value)) {
return true;
}
}
return false;
}
private MethodMetadata getRemoveFromRelationMethod(RelationInfo relationInfo) {
final MethodMetadata entityRemoveMethod = relationInfo.removeMethod;
// Define method name
JavaSymbolName methodName = entityRemoveMethod.getMethodName();
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
// add parent entity parameter
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(entity));
parameterNames.add(new JavaSymbolName(StringUtils.uncapitalize(entity.getSimpleTypeName())));
// Get related entity metadata
JpaEntityMetadata childEntityMetadata = relatedEntitiesMetadata.get(relationInfo.childType);
Validate.notNull(childEntityMetadata, "Can't get entity metadata for %s entity generating %s",
relationInfo.childType, aspectName);
if (relationInfo.cardinality != Cardinality.ONE_TO_ONE) {
// add child entity parameter
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType
.iterableOf(childEntityMetadata.getCurrentIndentifierField().getFieldType())));
parameterNames.add(entityRemoveMethod.getParameterNames().get(0));
}
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName, entity,
parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Generates "AddToRelation" Method for this service
* @param relationInfo
* @return
*/
private MethodMetadata getAddToRelationMethod(RelationInfo relationInfo) {
final MethodMetadata entityAddMethod = relationInfo.addMethod;
// Define method name
JavaSymbolName methodName = entityAddMethod.getMethodName();
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
// add parent entity parameter
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(entity));
parameterNames.add(new JavaSymbolName(StringUtils.uncapitalize(entity.getSimpleTypeName())));
// add child entity parameter
parameterNames.add(entityAddMethod.getParameterNames().get(0));
if (relationInfo.cardinality == Cardinality.ONE_TO_ONE) {
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(relationInfo.childType));
} else if (relationInfo.type == JpaRelationType.COMPOSITION) {
// Use objects
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType
.iterableOf(relationInfo.childType)));
} else {
// AGGREGATION: Use Child Pk: Get related entity metadata
JpaEntityMetadata childEntityMetadata = relatedEntitiesMetadata.get(relationInfo.childType);
Validate.notNull(childEntityMetadata,
"Can't get entity metadata for %s entity generating %s", relationInfo.childType,
aspectName);
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType
.iterableOf(childEntityMetadata.getCurrentIndentifierField().getFieldType())));
}
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName, entity,
parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Generates "setRelation" Method for this service
* @param relationInfo
* @return
*/
private MethodMetadata getSetRelationMethod(RelationInfo relationInfo) {
// Define method name
final JavaSymbolName methodName =
new JavaSymbolName("set"
+ relationInfo.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter());
// Define method parameter types
final List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
final List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
// add parent entity parameter
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(entity));
parameterNames.add(new JavaSymbolName(StringUtils.uncapitalize(entity.getSimpleTypeName())));
// add child entity parameter
parameterNames.add(relationInfo.fieldMetadata.getFieldName());
if (relationInfo.cardinality == Cardinality.ONE_TO_ONE) {
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(relationInfo.childType));
} else if (relationInfo.type == JpaRelationType.COMPOSITION) {
// Use objects
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType
.iterableOf(relationInfo.childType)));
} else {
// AGGREGATION: Use Child Pk: Get related entity metadata
JpaEntityMetadata childEntityMetadata = relatedEntitiesMetadata.get(relationInfo.childType);
Validate.notNull(childEntityMetadata,
"Can't get entity metadata for %s entity generating %s", relationInfo.childType,
aspectName);
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType
.iterableOf(childEntityMetadata.getCurrentIndentifierField().getFieldType())));
}
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName, entity,
parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "findAll" method. This method includes
* GlobalSearch parameters to be able to filter results.
*
* @return MethodMetadata
*/
private MethodMetadata getFindAllGlobalSearchMethod() {
// Define method name
JavaSymbolName methodName = this.findAllGlobalSearchMethod.getMethodName();
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = this.findAllGlobalSearchMethod.getParameterTypes();
// Define method parameter names
List<JavaSymbolName> parameterNames = this.findAllGlobalSearchMethod.getParameterNames();
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
this.findAllGlobalSearchMethod.getReturnType(), parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "findAll" method. This method includes
* GlobalSearch parameters to be able to filter results.
*
* @return MethodMetadata
*/
private MethodMetadata getFindAllByIdsInGlobalSearchMethod() {
// Define method name
JavaSymbolName methodName = this.findAllByIdsInGlobalSearchMethod.getMethodName();
// Define method parameter types
List<AnnotatedJavaType> parameterTypes =
this.findAllByIdsInGlobalSearchMethod.getParameterTypes();
// Define method parameter names
List<JavaSymbolName> parameterNames = this.findAllByIdsInGlobalSearchMethod.getParameterNames();
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
this.findAllByIdsInGlobalSearchMethod.getReturnType(), parameterTypes, parameterNames,
null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "findAll" method.
*
* @return MethodMetadataBuilder with public List <Entity> findAll();
* structure
*/
private MethodMetadata getFindAllMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("findAll");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
JavaType listEntityJavaType = JavaType.listOf(entity);
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
listEntityJavaType, parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "findAll" with iterable parameter.
*
* @return MethodMetadataBuilder with public List <Entity> findAll(Iterable
* <Long> ids) structure
*/
private MethodMetadata getFindAllIterableMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("findAll");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType.iterableOf(identifierType)));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(new JavaSymbolName("ids"));
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
JavaType listEntityJavaType = JavaType.listOf(entity);
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
listEntityJavaType, parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "findOne".
*
* @return MethodMetadataBuilder with public Entity findOne(Long id);
* structure
*/
private MethodMetadata getFindOneMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("findOne");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(identifierType));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(entityMetadata.getCurrentIndentifierField().getFieldName());
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName, entity,
parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Generates the "findOneForUpdate" method to be able to control
* concurrency in Entity updates.
*
* @return MethodMetadata with public Entity findOneForUpdate(T id);
* structure
*/
private MethodMetadata getFindOneForUpdateMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("findOneForUpdate");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(this.identifierType));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(this.entityMetadata.getCurrentIndentifierField().getFieldName());
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName, entity,
parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates method "count".
*
* @return MethodMetadataBuilder with public long count();
* structure
*/
private MethodMetadata getCountMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("count");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
JavaType.LONG_PRIMITIVE, parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates "save" method.
*
* @return MethodMetadataBuilder with public Entity save(Entity entity);
* structure
*/
private MethodMetadata getSaveMethod() {
// Define save method
JavaSymbolName methodName = new JavaSymbolName("save");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(this.entity));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(new JavaSymbolName("entity"));
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
this.entity, parameterTypes, parameterNames, null);
// Build a MethodMetadata instance
return methodBuilder.build();
}
/**
* Method that generates "delete" method.
*
* @return MethodMetadataBuilder with public void delete(Entity entity); structure
*/
private MethodMetadata getDeleteMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("delete");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(this.entity));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames
.add(new JavaSymbolName(StringUtils.uncapitalize(this.entity.getSimpleTypeName())));
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, null);
// Build a MethodMetadata instance
return methodBuilder.build();
}
/**
* Method that generates "save" batch method.
*
* @return MethodMetadataBuilder with public List<Entity> save(Iterable
* <Entity> entities); structure
*/
private MethodMetadata getSaveBatchMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("save");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType.iterableOf(entity)));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(new JavaSymbolName("entities"));
JavaType listEntityJavaType = JavaType.listOf(entity);
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
listEntityJavaType, parameterTypes, parameterNames, null);
// Build a MethodMetadata instance
return methodBuilder.build();
}
/**
* Method that generates "delete" batch method
*
* @return MethodMetadataBuilder with public void delete(Iterable
* <Long> ids); structure
*/
private MethodMetadata getDeleteBatchMethod() {
// Define method name
JavaSymbolName methodName = new JavaSymbolName("delete");
// Define method parameter types
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
parameterTypes.add(AnnotatedJavaType.convertFromJavaType(JavaType.iterableOf(identifierType)));
// Define method parameter names
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
parameterNames.add(new JavaSymbolName("ids"));
MethodMetadata existingMethod =
getGovernorMethod(methodName,
AnnotatedJavaType.convertFromAnnotatedJavaTypes(parameterTypes));
if (existingMethod != null) {
return existingMethod;
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT, methodName,
JavaType.VOID_PRIMITIVE, parameterTypes, parameterNames, null);
// Build a MethodMetadata instance
MethodMetadata methodMetadata = methodBuilder.build();
// delete method must be defined with @Transactional
//methodMetadata.setTransactional(true);
return methodMetadata;
}
/**
* Method that generates countByReferencedField method on current interface
*
* @param countMethod
* @return
*/
private MethodMetadata getCountByReferencedFieldMethod(MethodMetadata countMethod) {
// Define method parameter types and parameter names
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
List<AnnotatedJavaType> methodParamTypes = countMethod.getParameterTypes();
List<JavaSymbolName> methodParamNames = countMethod.getParameterNames();
for (int i = 0; i < countMethod.getParameterTypes().size(); i++) {
parameterTypes.add(methodParamTypes.get(i));
parameterNames.add(methodParamNames.get(i));
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT,
countMethod.getMethodName(), countMethod.getReturnType(), parameterTypes,
parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates findAll method for provided referenced fields on current interface
*
* @param countMethod
* @return
*/
private MethodMetadata getFindAllReferencedFieldMethod(MethodMetadata method) {
// Define method parameter types and parameter names
List<AnnotatedJavaType> parameterTypes = new ArrayList<AnnotatedJavaType>();
List<JavaSymbolName> parameterNames = new ArrayList<JavaSymbolName>();
List<AnnotatedJavaType> methodParamTypes = method.getParameterTypes();
List<JavaSymbolName> methodParamNames = method.getParameterNames();
for (int i = 0; i < method.getParameterTypes().size(); i++) {
parameterTypes.add(methodParamTypes.get(i));
parameterNames.add(methodParamNames.get(i));
}
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT,
method.getMethodName(), method.getReturnType(), parameterTypes, parameterNames, null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates finder method on current interface
*
* @param finderMethod
* @return
*/
private MethodMetadata getFinderMethod(MethodMetadata finderMethod) {
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT,
finderMethod.getMethodName(), finderMethod.getReturnType(),
finderMethod.getParameterTypes(), finderMethod.getParameterNames(), null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* Method that generates custom count method.
*
* @return MethodMetadata
*/
private MethodMetadata getCustomCountMethod(MethodMetadata customCountMethod) {
// Use the MethodMetadataBuilder for easy creation of MethodMetadata
MethodMetadataBuilder methodBuilder =
new MethodMetadataBuilder(getId(), Modifier.PUBLIC + Modifier.ABSTRACT,
customCountMethod.getMethodName(), customCountMethod.getReturnType(),
customCountMethod.getParameterTypes(), customCountMethod.getParameterNames(), null);
return methodBuilder.build(); // Build and return a MethodMetadata
// instance
}
/**
* This method returns all defined methods in service interface
* that aren transactional
*
* @return
*/
public List<MethodMetadata> getTransactionalDefinedMethods() {
return this.transactionalDefinedMethod;
}
/**
* This method returns all defined methods in service interface
* that aren't transactional
*
* @return
*/
public List<MethodMetadata> getNotTransactionalDefinedMethods() {
return this.notTransactionalDefinedMethod;
}
/**
* This method returns all defined count methods in
* service interface
*
* @return
*/
public Map<FieldMetadata, MethodMetadata> getCountByReferenceFieldDefinedMethod() {
return this.countByReferenceFieldDefinedMethod;
}
/**
* This method returns all defined findAll methods for referenced fields in
* service interface
*
* @return
*/
public Map<FieldMetadata, MethodMetadata> getReferencedFieldsFindAllDefinedMethods() {
return this.referencedFieldsFindAllDefinedMethods;
}
/**
* Return findAll method for a reference field.
*
* For example y this Service points to Pet
* getRefencedFieldFindAllDefineMethod("owner") will return
* the method "findPetsByOwner"
*
* @param fieldName
* @return
*/
public MethodMetadata getRefencedFieldFindAllDefinedMethod(String fieldName) {
for (Entry<FieldMetadata, MethodMetadata> entry : this.referencedFieldsFindAllDefinedMethods
.entrySet()) {
if (entry.getKey().getFieldName().getSymbolName().equals(fieldName)) {
return entry.getValue();
}
}
return null;
}
/**
* Return countBy method for a reference field.
*
* For example y this Service points to Pet
* getCountByReferenceFieldDefinedMethod("owner") will return
* the method "countByOwner"
*
* @param fieldName
* @return
*/
public MethodMetadata getCountByReferenceFieldDefinedMethod(String fieldName) {
for (Entry<FieldMetadata, MethodMetadata> entry : this.countByReferenceFieldDefinedMethod
.entrySet()) {
if (entry.getKey().getFieldName().getSymbolName().equals(fieldName)) {
return entry.getValue();
}
}
return null;
}
/**
* Method that returns the finder methos.
*
* @return a list of finder methods
*/
public List<MethodMetadata> getFinders() {
return finders;
}
/**
* Method that returns the count methods.
*
* @return a list of count methods
*/
public List<MethodMetadata> getCountMethods() {
return this.customCountMethods;
}
/**
* @return related repository
*/
public JavaType getRepositoryType() {
return RepositoryJpaMetadata.getJavaType(repositoryMetadata.getId());
}
/**
* @return method save(obj) method implemented in service
*/
public MethodMetadata getCurrentSaveMethod() {
return this.saveMethod;
}
/**
* @return method saveBatch(obj) implemented in service
*/
public MethodMetadata getCurrentSaveBatchMethod() {
return this.saveBatchMethod;
}
/**
* @return method deleteBatch(objs) implemented in service
*/
public MethodMetadata getCurrentDeleteBatchMethod() {
return this.deleteBatchMethod;
}
/**
* @return method delete(obj) implemented in service
*/
public MethodMetadata getCurrentDeleteMethod() {
return this.deleteMethod;
}
/**
* @return method findOne(id) implemented in service
*/
public MethodMetadata getCurrentFindOneMethod() {
return this.findOneMethod;
}
/**
* @return method findAll() implemented in service
*/
public MethodMetadata getCurrentFindAllMethod() {
return this.findAllMethod;
}
/**
* @return method findAll(Iterable) implemented in service
*/
public MethodMetadata getCurrentFindAllIterableMethod() {
return this.findAllIterableMethod;
}
/**
* @return method count() implemented in service
*/
public MethodMetadata getCurrentCountMethod() {
return this.countMethod;
}
/**
* @return method findAll(GlobalSearch, Pageable) implemented in service
*/
public MethodMetadata getCurrentFindAllWithGlobalSearchMethod() {
return this.findAllWithGlobalSearchMethod;
}
/**
* @return method findAllByIdsIn(List<?> ids, GlobalSearch, Pageable) implemented in service
*/
public MethodMetadata getCurrentFindAllByIdsInWithGlobalSearchMethod() {
return this.findAllByIdsInWithGlobalSearchMethod;
}
/**
* @return methods addToRelation generated in service
*/
public Map<RelationInfo, MethodMetadata> getAddToRelationMethods() {
return addToRelationMethods;
}
/**
* @return methods removeFromRelation generated in service
*/
public Map<RelationInfo, MethodMetadata> getRemoveFromRelationMethods() {
return removeFromRelationMethods;
}
/**
* @return methods setRelation generated in service
*/
public Map<RelationInfo, MethodMetadata> getSetRelationMethods() {
return setRelationMethods;
}
/**
* @return related entity
*/
public JavaType getEntity() {
return entity;
}
/**
* @return related entity identifier type
*/
public JavaType getIdType() {
return identifierType;
}
@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();
}
public Set<MethodMetadata> getAllMethods() {
return allMethods;
}
/**
* Obtains the finder methods and the associated counts
*
* @return
*/
public Map<JavaSymbolName, MethodMetadata> getRepositoryFindersAndCounts() {
return repositoryFindersAndCounts;
}
/**
* Obtains the finder methods and the associated counts
*
* @return
*/
public Map<JavaSymbolName, MethodMetadata> getRepositoryCustomFindersAndCounts() {
return repositoryCustomFindersAndCounts;
}
}