use of org.springframework.roo.classpath.details.FieldMetadata in project spring-roo by spring-projects.
the class RepositoryJpaCustomImplMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final RepositoryJpaCustomImplAnnotationValues annotationValues = new RepositoryJpaCustomImplAnnotationValues(governorPhysicalTypeMetadata);
// Getting repository custom
JavaType repositoryCustom = annotationValues.getRepository();
// Validate that contains repository interface
Validate.notNull(repositoryCustom, "ERROR: You need to specify interface repository to be implemented.");
ClassOrInterfaceTypeDetails repositoryDetails = getTypeLocationService().getTypeDetails(repositoryCustom);
AnnotationMetadata repositoryCustomAnnotation = repositoryDetails.getAnnotation(ROO_REPOSITORY_JPA_CUSTOM);
Validate.notNull(repositoryCustomAnnotation, "ERROR: Repository interface should be annotated with @RooJpaRepositoryCustom");
AnnotationAttributeValue<JavaType> entityAttribute = repositoryCustomAnnotation.getAttribute("entity");
Validate.notNull(entityAttribute, "ERROR: Repository interface should be contain an entity on @RooJpaRepositoryCustom annotation");
JavaType entity = entityAttribute.getValue();
RepositoryJpaMetadata repositoryMetadata = getRepositoryJpaLocator().getRepositoryMetadata(entity);
if (repositoryMetadata == null) {
// Can't generate it jet
return null;
}
// Register downstream dependency for RepositoryJpaCustomImplMetadata to update projection
// finders implementations
String repositoryCustomMetadataKey = RepositoryJpaCustomMetadata.createIdentifier(repositoryDetails);
registerDependency(repositoryCustomMetadataKey, metadataIdentificationString);
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
// Check if default return type is a Projection
JavaType returnType = repositoryMetadata.getDefaultReturnType();
ClassOrInterfaceTypeDetails returnTypeDetails = getTypeLocationService().getTypeDetails(returnType);
AnnotationMetadata entityProjectionAnnotation = returnTypeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
boolean returnTypeIsProjection = entityProjectionAnnotation != null;
// Get projection constructor fields from @RooEntityProjection and add it to a Map with
// domain type's variable names
Map<JavaType, List<Pair<String, String>>> typesFieldMaps = new LinkedHashMap<JavaType, List<Pair<String, String>>>();
Map<JavaType, Boolean> typesAreProjections = new HashMap<JavaType, Boolean>();
if (returnTypeIsProjection) {
buildFieldNamesMap(entity, returnType, entityProjectionAnnotation, typesFieldMaps);
typesAreProjections.put(returnType, true);
}
final RepositoryJpaCustomMetadata repositoryCustomMetadata = getMetadataService().get(repositoryCustomMetadataKey);
// Prevent empty metadata
if (repositoryCustomMetadata == null) {
return null;
}
// Getting java bean metadata
final String javaBeanMetadataKey = JavaBeanMetadata.createIdentifier(entityDetails);
// Getting jpa entity metadata
final String jpaEntityMetadataKey = JpaEntityMetadata.createIdentifier(entityDetails);
JpaEntityMetadata entityMetadata = getMetadataService().get(jpaEntityMetadataKey);
// Create dependency between repository and java bean annotation
registerDependency(javaBeanMetadataKey, metadataIdentificationString);
// Create dependency between repository and jpa entity annotation
registerDependency(jpaEntityMetadataKey, metadataIdentificationString);
// Getting entity properties
MemberDetails entityMemberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), entityDetails);
// Getting valid fields to construct the findAll query
List<FieldMetadata> validFields = new ArrayList<FieldMetadata>();
loadValidFields(entityMemberDetails, entityMetadata, validFields);
// Getting all necessary information about referencedFields
Map<FieldMetadata, MethodMetadata> referencedFieldsMethods = repositoryCustomMetadata.getReferencedFieldsFindAllMethods();
Map<FieldMetadata, String> referencedFieldsIdentifierNames = new HashMap<FieldMetadata, String>();
List<Pair<MethodMetadata, PartTree>> customFinderMethods = repositoryCustomMetadata.getCustomFinderMethods();
List<Pair<MethodMetadata, PartTree>> customCountMethods = repositoryCustomMetadata.getCustomCountMethods();
if (customCountMethods == null) {
customCountMethods = new ArrayList<Pair<MethodMetadata, PartTree>>();
}
for (Entry<FieldMetadata, MethodMetadata> referencedFields : referencedFieldsMethods.entrySet()) {
// Get identifier field name in path format
String fieldPathName = String.format("%s.%s", StringUtils.uncapitalize(entity.getSimpleTypeName()), referencedFields.getKey().getFieldName().getSymbolNameUnCapitalisedFirstLetter());
// Put keys and values in map
referencedFieldsIdentifierNames.put(referencedFields.getKey(), fieldPathName);
}
// Add valid entity fields to mappings
Map<JavaType, Map<String, FieldMetadata>> typesFieldsMetadataMap = new HashMap<JavaType, Map<String, FieldMetadata>>();
Map<String, FieldMetadata> entityFieldMetadata = new LinkedHashMap<String, FieldMetadata>();
List<Pair<String, String>> entityFieldMappings = new ArrayList<Pair<String, String>>();
typesAreProjections.put(entity, false);
for (FieldMetadata field : validFields) {
entityFieldMetadata.put(field.getFieldName().getSymbolName(), field);
entityFieldMappings.add(Pair.of(field.getFieldName().getSymbolName(), StringUtils.uncapitalize(entity.getSimpleTypeName()).concat(".").concat(field.getFieldName().getSymbolName())));
}
typesFieldsMetadataMap.put(entity, entityFieldMetadata);
typesFieldMaps.put(entity, entityFieldMappings);
// Make a list with all domain types, excepting entities
List<JavaType> domainTypes = new ArrayList<JavaType>();
domainTypes.add(returnType);
for (Pair<MethodMetadata, PartTree> methodInfo : customFinderMethods) {
// Get finder return type from first parameter of method return type (Page)
JavaType finderReturnType = getDomainTypeOfFinderMethod(methodInfo.getKey());
domainTypes.add(finderReturnType);
// If type is a DTO, add finder fields to mappings
JavaType parameterType = methodInfo.getKey().getParameterTypes().get(0).getJavaType();
typesAreProjections.put(parameterType, false);
}
// Add typesFieldMaps for each projection finder and check for id fields
for (JavaType type : domainTypes) {
// Check if projection fields has been added already
if (typesFieldMaps.containsKey(type)) {
continue;
}
// Build Map with FieldMetadata of each projection
ClassOrInterfaceTypeDetails typeDetails = getTypeLocationService().getTypeDetails(type);
if (typeDetails == null) {
LOGGER.warning("Detail not found for type: " + type);
continue;
}
List<FieldMetadata> typeFieldList = getMemberDetailsScanner().getMemberDetails(this.getClass().getName(), typeDetails).getFields();
Map<String, FieldMetadata> fieldMetadataMap = new LinkedHashMap<String, FieldMetadata>();
for (FieldMetadata field : typeFieldList) {
fieldMetadataMap.put(field.getFieldName().getSymbolName(), field);
}
typesFieldsMetadataMap.put(type, fieldMetadataMap);
AnnotationMetadata projectionAnnotation = typeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
if (projectionAnnotation != null) {
typesAreProjections.put(type, true);
// Type is a Projection
JavaType associatedEntity = (JavaType) projectionAnnotation.getAttribute("entity").getValue();
// Add fields to typesFieldMaps
buildFieldNamesMap(associatedEntity, type, projectionAnnotation, typesFieldMaps);
}
}
return new RepositoryJpaCustomImplMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, entity, entityMetadata, entityMetadata.getCurrentIndentifierField(), validFields, repositoryCustomMetadata.getCurrentFindAllGlobalSearchMethod(), repositoryCustomMetadata.getCurrentFindAllByIdsInGlobalSearchMethod(), repositoryCustomMetadata.getDefaultReturnType(), referencedFieldsMethods, referencedFieldsIdentifierNames, typesFieldMaps, customFinderMethods, customCountMethods, typesFieldsMetadataMap, typesAreProjections);
}
use of org.springframework.roo.classpath.details.FieldMetadata in project spring-roo by spring-projects.
the class RepositoryJpaMetadataProviderImpl method checkDtoFieldsForFinder.
/**
* Validates that all dto fields matches with parameters on finder of a repository
*
* @param formBeanDetails
* @param finder
* @param repository
*/
private void checkDtoFieldsForFinder(ClassOrInterfaceTypeDetails formBeanDetails, PartTree finder, JavaType repository) {
final JavaType dtoType = formBeanDetails.getName();
final String finderName = finder.getOriginalQuery();
FieldMetadata paramField, dtoField;
JavaType paramType, dtoFieldType;
for (FinderParameter param : finder.getParameters()) {
paramField = param.getPath().peek();
dtoField = formBeanDetails.getField(paramField.getFieldName());
Validate.notNull(dtoField, "Field '%s' not found on DTO %s for finder '%s' of %s", paramField.getFieldName(), dtoType, finderName, repository);
paramType = paramField.getFieldType().getBaseType();
dtoFieldType = dtoField.getFieldType().getBaseType();
Validate.isTrue(paramType.equals(dtoFieldType), "Type missmatch for field '%s' on DTO %s for finder '%s' of %s: excepted %s and got %s", dtoField.getFieldName(), dtoType, finderName, repository, paramType, dtoFieldType);
}
}
use of org.springframework.roo.classpath.details.FieldMetadata in project spring-roo by spring-projects.
the class ServiceImplMetadata method getSetRelation.
private MethodMetadata getSetRelation(MethodMetadata methodToBeImplemented, RelationInfo relationInfo) {
InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
// Prepare constants
final JavaSymbolName param0 = methodToBeImplemented.getParameterNames().get(0);
final JavaType childType = relationInfo.childType;
final FieldMetadata childServideField = requiredServiceFieldByEntity.get(childType);
final String childTypeNameJavaType = getNameOfJavaType(childType);
final JavaSymbolName param1 = methodToBeImplemented.getParameterNames().get(1);
final String saveMethod = serviceMetadata.getCurrentSaveMethod().getMethodName().getSymbolName();
String childListVariable = "items";
// List<{childType}> {parentFieldName} =
// {childService}.findAll({param1});
bodyBuilder.appendFormalLine("%s<%s> %s = %s().findAll(%s);", getNameOfJavaType(JavaType.LIST), childTypeNameJavaType, childListVariable, getAccessorMethod(childServideField).getMethodName(), param1);
// Set<{childType}> currents = {param0}.get{rel.property}();
bodyBuilder.appendFormalLine("%s currents = %s.get%s();", getNameOfJavaType(relationInfo.fieldMetadata.getFieldType()), param0, relationInfo.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter());
// Set<{childType}> toRemove = new
// HashSet<{childType}>({parentFieldName});
bodyBuilder.appendFormalLine("%s<%s> toRemove = new %s<%s>();", getNameOfJavaType(JavaType.SET), childTypeNameJavaType, getNameOfJavaType(JdkJavaType.HASH_SET), childTypeNameJavaType);
// for (Iterator<{childType}> iterator = current.iterator();
// iterator.hasNext();) {
bodyBuilder.appendFormalLine("for (%s<%s> iterator = currents.iterator(); iterator.hasNext();) {", getNameOfJavaType(JavaType.ITERATOR), childTypeNameJavaType);
bodyBuilder.indent();
final String itemName = "next".concat(StringUtils.capitalize(childType.getSimpleTypeName()));
// {childType} {itemName} = iterator.next();
bodyBuilder.appendFormalLine("%s %s = iterator.next();", childTypeNameJavaType, itemName);
// if ({childListVariable}.contains({itemName})) {
bodyBuilder.appendFormalLine("if (%s.contains(%s)) {", childListVariable, itemName);
bodyBuilder.indent();
// {childListVariable}.remove({itemName});
bodyBuilder.appendFormalLine("%s.remove(%s);", childListVariable, itemName);
bodyBuilder.indentRemove();
// } else {
bodyBuilder.appendFormalLine("} else {");
bodyBuilder.indent();
// toRemove.add(product);
bodyBuilder.appendFormalLine("toRemove.add(%s);", itemName);
bodyBuilder.indentRemove();
// }
bodyBuilder.appendFormalLine("}");
// }
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
// {param0}.{removeFromMethod}(toRemove);
bodyBuilder.appendFormalLine("%s.%s(toRemove);", param0, relationInfo.removeMethod.getMethodName());
// {param0}.{addToMethod}({childListVariable);
bodyBuilder.appendFormalLine("%s.%s(%s);", param0, relationInfo.addMethod.getMethodName(), childListVariable);
// Concurrency control
if (this.entityMetadata.getCurrentVersionField() != null) {
// // Force the version update of the parent side to know that the parent has changed
bodyBuilder.appendFormalLine("// Force the version update of the parent side to know that the parent has changed");
// // because it has new books assigned
bodyBuilder.appendFormalLine("// because it has new books assigned");
// {param0}.setVersion({param0}.getVersion() + 1);
bodyBuilder.appendFormalLine("%s.setVersion(%s.getVersion() + 1);", param0, param0);
}
// return {repoField}.{saveMethod}({param0});
bodyBuilder.appendFormalLine("return %s().%s(%s);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), saveMethod, param0);
return getMethod(methodToBeImplemented, true, bodyBuilder);
}
use of org.springframework.roo.classpath.details.FieldMetadata in project spring-roo by spring-projects.
the class ServiceImplMetadata method getMethodAddRemoveRel.
private MethodMetadata getMethodAddRemoveRel(MethodMetadata methodToBeImplemented, RelationInfo relationInfo, MethodMetadata operationMethod) {
InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
// Prepare constants
final String operation = operationMethod.getMethodName().getSymbolName();
final JavaSymbolName param0 = methodToBeImplemented.getParameterNames().get(0);
final JavaType childType = relationInfo.childType;
final FieldMetadata childServideField = requiredServiceFieldByEntity.get(childType);
final String parentFieldName = relationInfo.fieldName;
final JavaSymbolName param1 = methodToBeImplemented.getParameterNames().get(1);
final JavaType param1TypeWrapped = methodToBeImplemented.getParameterTypes().get(1).getJavaType().getParameters().get(0);
final String saveMethod = serviceMetadata.getCurrentSaveMethod().getMethodName().getSymbolName();
String childListVariable;
if (childType.equals(param1TypeWrapped)) {
childListVariable = param1.getSymbolName();
} else {
// List<{childType}> {parentFieldName} =
// {childService}.findAll({param1});
bodyBuilder.appendFormalLine("%s<%s> %s = %s().findAll(%s);", getNameOfJavaType(JavaType.LIST), getNameOfJavaType(childType), parentFieldName, getAccessorMethod(childServideField).getMethodName(), param1);
childListVariable = parentFieldName;
}
// {param0}.{operation}({childListVariable});
bodyBuilder.appendFormalLine("%s.%s(%s);", param0, operation, childListVariable);
// return {repoField}.{saveMethod}({param0});
bodyBuilder.appendFormalLine("return %s().%s(%s);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), saveMethod, param0);
return getMethod(methodToBeImplemented, true, bodyBuilder);
}
use of org.springframework.roo.classpath.details.FieldMetadata in project spring-roo by spring-projects.
the class Predicate method getOptions.
/**
* Returns the different queries that can be build based on the current predicate expressions.
* The options are joined to the current query expression.
*
* @param query that represents the subject information
* @return
*/
public List<String> getOptions(String subject) {
List<String> options = new ArrayList<String>();
OrPart lastOr = null;
Part lastAnd = null;
// Extract the last condition
if (!nodes.isEmpty()) {
lastOr = nodes.get(nodes.size() - 1);
lastAnd = lastOr.getChildren().isEmpty() ? null : lastOr.getChildren().get(lastOr.getChildren().size() - 1);
}
// Builds the current query by joining the subject expression with the predicate information
subject = subject.concat(toString());
// Check if last condition has a property
if (lastAnd == null || !lastAnd.hasProperty()) {
// If options are added after Or, OrderBy keyword is added. It makes possible transform an Or into an OrderBy expression
if (subject.endsWith("Or")) {
options.add(StringUtils.removeEnd(subject, "Or").concat(ORDER_BY));
}
// Show all fields with correct format
for (FieldMetadata field : fields) {
options.add(subject.concat(StringUtils.capitalize(field.getFieldName().toString())));
}
} else {
// Once a property is defined, the query is complete and no more information is necessary but optional
options.add(subject.concat(""));
// Once a property is defined, OrderBy option can be added
options.add(subject.concat(ORDER_BY));
// AlwaysIgnoreCase option ends search criteria definition.
if (!alwaysIgnoreCase) {
options.add(subject.concat("AllIgnoreCase"));
options.add(subject.concat("AllIgnoringCase"));
options.add(subject.concat("And"));
options.add(subject.concat("Or"));
if (!lastAnd.hasOperator()) {
// If condition does not have an operator, optionally, it can be included
List<String> types = lastAnd.getSupportedOperators();
for (String type : types) {
options.add(subject.concat(type));
}
} else if (lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS) {
// If the condition has an operator, but it also acts as prefix of other operators, they are included
List<String> types = lastAnd.getSupportedOperatorsByPrefix(lastAnd.getOperator());
for (String type : types) {
if (StringUtils.isNotBlank(type)) {
options.add(subject.concat(type));
}
}
}
// IgnoreCase option is available only for string properties
if (lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS && lastAnd.getProperty().getKey().peek().getFieldType().equals(JavaType.STRING)) {
options.add(subject.concat("IgnoreCase"));
options.add(subject.concat("IgnoringCase"));
}
// If the property condition is a reference to other entity, the related entity fields are shown
if (!lastAnd.hasOperator() && lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS) {
List<FieldMetadata> fields = currentPartTreeInstance.getValidProperties(lastAnd.getProperty().getLeft().peek().getFieldType());
if (fields != null) {
for (FieldMetadata field : fields) {
options.add(subject.concat(StringUtils.capitalize(field.getFieldName().toString())));
}
}
}
}
}
return options;
}
Aggregations