use of org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo in project spring-roo by spring-projects.
the class JpaUnitTestMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final JpaUnitTestAnnotationValues annotationValues = new JpaUnitTestAnnotationValues(governorPhysicalTypeMetadata);
JavaType targetType = annotationValues.getTargetClass();
Validate.notNull(targetType, targetType.getSimpleTypeName().concat(" doesn't exist in the project."));
// Obtain target type child related entities
final ClassOrInterfaceTypeDetails cid = getTypeLocationService().getTypeDetails(targetType);
JpaEntityMetadata entityMetadata = getMetadataService().get(JpaEntityMetadata.createIdentifier(cid));
List<JavaType> relatedEntities = new ArrayList<JavaType>();
// Add the current entity first
relatedEntities.add(targetType);
Map<String, RelationInfo> relationInfos = entityMetadata.getRelationInfos();
for (RelationInfo relation : relationInfos.values()) {
// Get child entity type
JavaType childType = relation.childType;
if (!relatedEntities.contains(childType)) {
relatedEntities.add(childType);
}
}
// Get all entity factories for this entity and child related entities
Set<ClassOrInterfaceTypeDetails> entityFactories = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY_FACTORY);
Map<JavaType, JavaType> entityAndItsFactoryMap = new TreeMap<JavaType, JavaType>();
for (ClassOrInterfaceTypeDetails entityFactory : entityFactories) {
JavaType entity = (JavaType) entityFactory.getAnnotation(RooJavaType.ROO_JPA_ENTITY_FACTORY).getAttribute("entity").getValue();
if (entity != null && relatedEntities.contains(entity)) {
entityAndItsFactoryMap.put(entity, entityFactory.getType());
}
}
return new JpaUnitTestMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, relationInfos.values(), entityAndItsFactoryMap);
}
use of org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo in project spring-roo by spring-projects.
the class ServiceImplMetadata method builDeleteMethodBody.
/**
* Build method body which delegates on repository
*
* @param methodToBeImplemented
* @param isBatch
* @param isDelete
* @return
*/
private InvocableMemberBodyBuilder builDeleteMethodBody(final MethodMetadata methodToBeImplemented, boolean isBatch) {
// Generate body
final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
final JavaSymbolName param0 = methodToBeImplemented.getParameterNames().get(0);
final String entity = getNameOfJavaType(this.entity);
if (isBatch) {
// List<Entity> toDelete = repositoryField.FIND_ALL_METHOD(paramName);
bodyBuilder.appendFormalLine("%s<%s> toDelete = %s().%s(%s);", getNameOfJavaType(JavaType.LIST), entity, getAccessorMethod(repositoryFieldMetadata).getMethodName(), this.findAllIterableMethod.getMethodName(), param0);
bodyBuilder.appendFormalLine("%s().deleteInBatch(toDelete);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), methodToBeImplemented.getMethodName());
} else {
// Clear relations as child part
for (Pair<FieldMetadata, RelationInfo> item : childRelationsInfo) {
final RelationInfo info = item.getRight();
final FieldMetadata field = item.getLeft();
final JavaType childType = field.getFieldType().getBaseType();
String mappedByCapitalized = StringUtils.capitalize(info.mappedBy);
if (info.cardinality == Cardinality.ONE_TO_ONE) {
// Skip
} else if (info.cardinality == Cardinality.ONE_TO_MANY) {
// Clear bidirectional many-to-one child relationship with Customer
/*
if (customerOrder.getCustomer() != null) {
customerOrder.getCustomer().getOrders().remove(customerOrder);
}
*/
bodyBuilder.appendFormalLine("// Clear bidirectional many-to-one child relationship with %s", childType.getSimpleTypeName());
bodyBuilder.appendFormalLine("if (%s.get%s() != null) {", param0, mappedByCapitalized);
bodyBuilder.indent();
bodyBuilder.appendFormalLine("%s.get%s().get%s().remove(%s);", param0, mappedByCapitalized, info.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter(), param0);
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("");
} else {
// MANY_TO_MANY
String childTypeName = getNameOfJavaType(childType);
/*
// Clear bidirectional many-to-many child relationship with categories
for (Category category : product.getCategories()) {
category.getProducts().remove(product);
}
*/
bodyBuilder.appendFormalLine("// Clear bidirectional many-to-many child relationship with %s", childTypeName);
bodyBuilder.appendFormalLine("for (%s item : %s.get%s()) {", childTypeName, param0, mappedByCapitalized);
bodyBuilder.indent();
bodyBuilder.appendFormalLine("item.get%s().remove(%s);", info.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter(), param0);
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("");
}
}
// Clear relations as parent
for (RelationInfo info : entityMetadata.getRelationInfos().values()) {
if (info.cardinality == Cardinality.ONE_TO_ONE) {
/*
// Clear bidirectional one-to-one parent relationship with Address
customer.removeFromAddress();
*/
bodyBuilder.appendFormalLine("// Clear bidirectional one-to-one parent relationship with %s", info.childType.getSimpleTypeName());
bodyBuilder.appendFormalLine("%s.%s();", param0, info.removeMethod.getMethodName());
bodyBuilder.appendFormalLine("");
} else if (info.cardinality == Cardinality.ONE_TO_MANY) {
String childTypeName = getNameOfJavaType(info.childType);
/*
// Clear bidirectional one-to-many parent relationship with CustomerOrders
for (CustomerOrder order : customer.getOrders()) {
order.setCustomer(null);
}
*/
bodyBuilder.appendFormalLine("// Clear bidirectional one-to-many parent relationship with %s", childTypeName);
bodyBuilder.appendFormalLine("for (%s item : %s.get%s()) {", childTypeName, param0, info.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter());
bodyBuilder.indent();
bodyBuilder.appendFormalLine("item.set%s(null);", StringUtils.capitalize(info.mappedBy));
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("");
} else {
String childTypeName = getNameOfJavaType(info.childType);
// MANY_TO_MANY
/*
// Clear bidirectional many-to-many parent relationship with products
for (Product product : category.getProducts()) {
product.getCategories().remove(category);
}
*/
bodyBuilder.appendFormalLine("// Clear bidirectional many-to-many parent relationship with %s", childTypeName);
bodyBuilder.appendFormalLine("for (%s item : %s.get%s()) {", childTypeName, param0, info.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter());
bodyBuilder.indent();
bodyBuilder.appendFormalLine("item.get%s().remove(%s);", StringUtils.capitalize(info.mappedBy), param0);
bodyBuilder.indentRemove();
bodyBuilder.appendFormalLine("}");
bodyBuilder.appendFormalLine("");
}
}
bodyBuilder.appendFormalLine("%s().delete(%s);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), param0);
}
return bodyBuilder;
}
use of org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo in project spring-roo by spring-projects.
the class ServiceImplMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final ServiceImplAnnotationValues annotationValues = new ServiceImplAnnotationValues(governorPhysicalTypeMetadata);
// Getting service interface
JavaType serviceInterface = annotationValues.getService();
ClassOrInterfaceTypeDetails serviceInterfaceDetails = getTypeLocationService().getTypeDetails(serviceInterface);
final ServiceMetadata serviceMetadata = getServiceMetadata(metadataIdentificationString, serviceInterfaceDetails);
AnnotationMetadata serviceAnnotation = serviceInterfaceDetails.getAnnotation(RooJavaType.ROO_SERVICE);
Validate.notNull(serviceAnnotation, "ERROR: Provided service should be annotated with @RooService");
JavaType entity = (JavaType) serviceAnnotation.getAttribute("entity").getValue();
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
final String entityMetadataId = JpaEntityMetadata.createIdentifier(entityDetails.getType(), PhysicalTypeIdentifier.getPath(entityDetails.getDeclaredByMetadataId()));
final JpaEntityMetadata entityMetadata = (JpaEntityMetadata) getMetadataService().get(entityMetadataId);
// Add dependencies between modules
if (serviceMetadata != null) {
for (MethodMetadata method : serviceMetadata.getAllMethods()) {
List<JavaType> types = new ArrayList<JavaType>();
types.add(method.getReturnType());
types.addAll(method.getReturnType().getParameters());
for (AnnotatedJavaType parameter : method.getParameterTypes()) {
types.add(AnnotatedJavaType.convertFromAnnotatedJavaType(parameter));
types.addAll(AnnotatedJavaType.convertFromAnnotatedJavaType(parameter).getParameters());
}
for (JavaType parameter : types) {
getTypeLocationService().addModuleDependency(governorPhysicalTypeMetadata.getType().getModule(), parameter);
}
}
}
// Getting associated repository
ClassOrInterfaceTypeDetails repositoryDetails = getRepositoryJpaLocator().getRepository(entity);
final String repositoryMetadataId = RepositoryJpaMetadata.createIdentifier(repositoryDetails.getType(), PhysicalTypeIdentifier.getPath(repositoryDetails.getDeclaredByMetadataId()));
final RepositoryJpaMetadata repositoryMetadata = (RepositoryJpaMetadata) getMetadataService().get(repositoryMetadataId);
// Locate related services API types required by relations
Map<JavaType, ServiceMetadata> requiredServicesByEntity = new HashMap<JavaType, ServiceMetadata>();
ClassOrInterfaceTypeDetails relatedService;
for (RelationInfo info : entityMetadata.getRelationInfos().values()) {
if (info.cardinality != Cardinality.ONE_TO_ONE && !requiredServicesByEntity.containsKey(info.childType)) {
relatedService = getServiceLocator().getFirstService(info.childType);
if (relatedService != null) {
requiredServicesByEntity.put(info.childType, getServiceMetadata(metadataIdentificationString, relatedService));
}
}
}
// Get child relations info
List<Pair<FieldMetadata, RelationInfo>> childRelationsInfo = getJpaOperations().getFieldChildPartOfRelation(entityDetails);
return new ServiceImplMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, serviceInterface, repositoryDetails.getType(), repositoryMetadata, entity, entityMetadata, serviceMetadata, requiredServicesByEntity, childRelationsInfo);
}
use of org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo in project spring-roo by spring-projects.
the class ServiceMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final ServiceAnnotationValues annotationValues = new ServiceAnnotationValues(governorPhysicalTypeMetadata);
// Getting entity
JavaType entity = annotationValues.getEntity();
Validate.notNull(entity, "ERROR: You should specify a valid entity on @RooService annotation");
final JavaType identifierType = getPersistenceMemberLocator().getIdentifierType(entity);
Validate.notNull(identifierType, "ERROR: You should specify a valid entity on @RooService annotation");
final JpaEntityMetadata entityMetadata = getEntityMetadata(entity);
if (entityMetadata == null) {
return null;
}
registerDependency(entityMetadata.getId(), metadataIdentificationString);
// Getting associated repository
ClassOrInterfaceTypeDetails repositoryDetails = getRepositoryJpaLocator().getRepository(entity);
// Check if we have a valid repository
Validate.notNull(repositoryDetails, String.format("ERROR: You must generate some @RooJpaRepository for entity '%s' to be able to generate services", entity.getSimpleTypeName()));
// Get repository metadata
final String repositoryMetadataKey = RepositoryJpaMetadata.createIdentifier(repositoryDetails);
registerDependency(repositoryMetadataKey, metadataIdentificationString);
final RepositoryJpaMetadata repositoryMetadata = getMetadataService().get(repositoryMetadataKey);
List<MethodMetadata> finders = new ArrayList<MethodMetadata>();
List<MethodMetadata> countMethods = new ArrayList<MethodMetadata>();
if (repositoryMetadata == null) {
// Can't generate metadata yet
return null;
}
// Add dependencies between modules
for (MethodMetadata finder : repositoryMetadata.getFindersGenerated()) {
// Add to service finders list
finders.add(finder);
registerDependencyModulesOfFinder(governorPhysicalTypeMetadata, finder);
}
// Get count methods
countMethods.addAll(repositoryMetadata.getCountMethods());
// Get finders and its associated count method from repository metadata
Map<JavaSymbolName, MethodMetadata> repositoryFindersAndCounts = repositoryMetadata.getFinderMethodsAndCounts();
// Getting methods declared on related RepositoryJpaCustomMetadata
final JavaType customRepository = repositoryMetadata.getCustomRepository();
final ClassOrInterfaceTypeDetails customRepositoryDetails = getTypeLocationService().getTypeDetails(customRepository);
final String customRepositoryMetadataKey = RepositoryJpaCustomMetadata.createIdentifier(customRepositoryDetails);
final RepositoryJpaCustomMetadata repositoryCustomMetadata = getMetadataService().get(customRepositoryMetadataKey);
// Return null if repository dependency is not satisfied
if (repositoryCustomMetadata == null) {
return null;
}
// Get finders and its associated count method from custom repository metadata
Map<JavaSymbolName, MethodMetadata> repositoryCustomFindersAndCounts = repositoryCustomMetadata.getFinderMethodsAndCounts();
// Check if we have a valid custom repository
Validate.notNull(repositoryCustomMetadata, String.format("ERROR: Can't found a class @RooJpaRepositoryCustom for entity '%s' to be able to generate services", entity.getSimpleTypeName()));
registerDependency(customRepositoryMetadataKey, metadataIdentificationString);
final Map<FieldMetadata, MethodMetadata> countByReferencedFieldMethods = new HashMap<FieldMetadata, MethodMetadata>(repositoryMetadata.getCountMethodByReferencedFields());
// Add custom finders to finders list and add dependencies between modules
for (Pair<MethodMetadata, PartTree> finderInfo : repositoryCustomMetadata.getCustomFinderMethods()) {
// Add to service finders list
finders.add(finderInfo.getKey());
registerDependencyModulesOfFinder(governorPhysicalTypeMetadata, finderInfo.getKey());
}
// Add custom count methods to count method list
for (Pair<MethodMetadata, PartTree> countInfo : repositoryCustomMetadata.getCustomCountMethods()) {
countMethods.add(countInfo.getKey());
}
// Get related entities metadata
final Map<JavaType, JpaEntityMetadata> relatedEntities = new HashMap<JavaType, JpaEntityMetadata>();
// As parent
JavaType childEntity;
JpaEntityMetadata childEntityMetadata;
List<RelationInfo> relatedInfosWithServiceLayer = new ArrayList<RelationInfo>();
for (RelationInfo info : entityMetadata.getRelationInfos().values()) {
childEntity = info.fieldMetadata.getFieldType().getBaseType();
if (relatedEntities.containsKey(childEntity)) {
continue;
}
// No need to add relation methods if related entity has not service
ClassOrInterfaceTypeDetails childService = getServiceLocator().getFirstService(childEntity);
if (childService != null) {
relatedInfosWithServiceLayer.add(info);
childEntityMetadata = getEntityMetadata(childEntity);
if (childEntityMetadata == null) {
// We need child metadata. Return null waiting next metadata iteration
return null;
}
registerDependency(childEntityMetadata.getId(), metadataIdentificationString);
relatedEntities.put(childEntity, childEntityMetadata);
}
}
// As child
JavaType parentEntity;
JpaEntityMetadata parentEntityMetadata;
for (FieldMetadata fieldAsChild : entityMetadata.getRelationsAsChild().values()) {
parentEntity = fieldAsChild.getFieldType().getBaseType();
if (relatedEntities.containsKey(parentEntity)) {
continue;
}
parentEntityMetadata = getEntityMetadata(parentEntity);
if (parentEntityMetadata == null) {
// We need parent metadata. Return null waiting next metadata iteration
return null;
}
registerDependency(parentEntityMetadata.getId(), metadataIdentificationString);
relatedEntities.put(parentEntity, parentEntityMetadata);
}
return new ServiceMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, entity, identifierType, entityMetadata, repositoryMetadata, finders, repositoryCustomMetadata.getCurrentFindAllGlobalSearchMethod(), repositoryCustomMetadata.getCurrentFindAllByIdsInGlobalSearchMethod(), repositoryCustomMetadata.getReferencedFieldsFindAllMethods(), countByReferencedFieldMethods, countMethods, relatedEntities, repositoryFindersAndCounts, repositoryCustomFindersAndCounts, relatedInfosWithServiceLayer);
}
use of org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo in project spring-roo by spring-projects.
the class ControllerOperationsImpl method checkRelationField.
/**
* Find recursively if relation field is valid. Check that the fields are
* Set or List and check that the parents controllers exists
*/
private List<RelationInfo> checkRelationField(JpaEntityMetadata entityMetadata, String[] relationField, int level, ControllerMVCResponseService responseType, JavaPackage controllerPackage, String pathPrefix, JavaType masterEntity) {
List<RelationInfo> infos = new ArrayList<RelationInfo>();
RelationInfo info = entityMetadata.getRelationInfos().get(relationField[level]);
if (info == null) {
return null;
}
if (info.cardinality != Cardinality.ONE_TO_MANY && info.cardinality != Cardinality.MANY_TO_MANY) {
return null;
}
infos.add(info);
if (relationField.length > level + 1) {
List<String> currentPathList = new ArrayList<String>(level + 1);
for (int i = 0; i < relationField.length; i++) {
currentPathList.add(relationField[i]);
}
String currentPath = StringUtils.join(currentPathList, '.');
// try to find it
if (checkDetailControllerExists(masterEntity, responseType, controllerPackage, pathPrefix, currentPath)) {
JpaEntityMetadata childEntity = getMetadataService().get(JpaEntityMetadata.createIdentifier(getTypeLocationService().getTypeDetails(info.childType)));
List<RelationInfo> subPath = checkRelationField(childEntity, relationField, level + 1, responseType, controllerPackage, pathPrefix, masterEntity);
if (subPath == null) {
return null;
}
infos.addAll(subPath);
} else {
LOGGER.info(String.format("Details controller is required for %s befor can create %s", currentPath, StringUtils.join(Arrays.asList(relationField), ',')));
return null;
}
}
return infos;
}
Aggregations