use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class PushInOperationsImpl method pushInMethod.
/**
* Makes push-in of a method defined on a provided class
*
* @param klass
* class to make the push-in operation
* @param weiteOnDisk
* indicates if pushed elements should be writed on .java file
*
* @return list of objects with all the pushed elements.
*/
public List<Object> pushInMethod(JavaType klass, MethodMetadata method, boolean writeOnDisk) {
List<Object> pushedElements = new ArrayList<Object>();
// Check if current klass exists
Validate.notNull(klass, "ERROR: You must specify a valid class to continue with push-in action");
// Getting class details
ClassOrInterfaceTypeDetails classDetails = getTypeLocationService().getTypeDetails(klass);
Validate.notNull(klass, "ERROR: You must specify a valid class to continue with push-in action");
Validate.notNull(method, "ERROR: You must provide a valid method");
// Getting member details
MemberDetails memberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), classDetails);
// Check if the provided class is a test to be able to select valid
// class path
Path path = classDetails.getAnnotation(RooJavaType.ROO_JPA_UNIT_TEST) == null ? Path.SRC_MAIN_JAVA : Path.SRC_TEST_JAVA;
// Getting current class .java file metadata ID
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(klass, getPathResolver().getPath(klass.getModule(), path));
// Getting detailsBuilder
ClassOrInterfaceTypeDetailsBuilder detailsBuilder = new ClassOrInterfaceTypeDetailsBuilder(classDetails);
// Avoid AspectJ error when push-in from *RepositoryImpl classes
AnnotationMetadata rooRepositoryCustomImplAnnotation = classDetails.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA_CUSTOM_IMPL);
JavaType relatedRepositoryCustom = null;
if (rooRepositoryCustomImplAnnotation != null) {
AnnotationAttributeValue<Object> attribute = rooRepositoryCustomImplAnnotation.getAttribute("repository");
Validate.notNull(attribute, "Unable to find 'repository' attribute of @RooJpaRepositoryCustomImpl on '%s'", classDetails.getType().getSimpleTypeName());
relatedRepositoryCustom = (JavaType) attribute.getValue();
}
// Getting all details
for (final MemberHoldingTypeDetails memberHoldingTypeDetails : memberDetails.getDetails()) {
// Avoid AspectJ error when push-in from *RepositoryImpl classes
if (rooRepositoryCustomImplAnnotation != null && memberHoldingTypeDetails.getImplementsTypes().contains(relatedRepositoryCustom)) {
detailsBuilder.addImplementsType(relatedRepositoryCustom);
pushedElements.add(relatedRepositoryCustom);
}
// this .java file
if (!memberHoldingTypeDetails.getType().equals(classDetails.getType())) {
continue;
}
// Getting all declared methods (including declared on ITDs
// and .java files)
List<MethodMetadata> allDeclaredMethods = memberHoldingTypeDetails.getMethods();
// Checking if is necessary to make push-in for all declared methods
for (MethodMetadata declaredMethod : allDeclaredMethods) {
// If method exists on .aj file, add it!
if (!method.getDeclaredByMetadataId().equals(declaredByMetadataId) && declaredMethod.equals(method)) {
// Add method to .java file
MethodMetadata newMethod = getNewMethod(declaredByMetadataId, method);
detailsBuilder.addMethod(newMethod);
// Save changes to be pushed
pushedElements.add(newMethod);
}
}
// Getting all imports registered on .aj file to move to .java file
Set<ImportMetadata> allRegisteredImports = memberHoldingTypeDetails.getImports();
detailsBuilder.addImports(allRegisteredImports);
// Save imports to be pushed only if some method has been pushed
if (!pushedElements.isEmpty()) {
pushedElements.addAll(allRegisteredImports);
}
}
// Updating .java file if write on disdk
if (writeOnDisk) {
getTypeManagementService().createOrUpdateTypeOnDisk(detailsBuilder.build());
}
return pushedElements;
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class PluralMetadata method getPlural.
/**
* @param field the field to obtain plural details for (required)
* @return a guaranteed plural, computed via an annotation or Inflector
* (never returns null or an empty string)
*/
public String getPlural(final FieldMetadata field) {
Validate.notNull(field, "Field required");
// Obtain the plural from the cache, if available
final String symbolName = field.getFieldName().getSymbolName();
if (cache != null && cache.containsKey(symbolName)) {
return cache.get(symbolName);
}
// We need to build the plural
String thePlural = "";
final AnnotationMetadata annotation = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), ROO_PLURAL);
if (annotation != null) {
// Use the plural the user defined via the annotation
final AnnotationAttributeValue<?> attribute = annotation.getAttribute(new JavaSymbolName("value"));
if (attribute != null) {
thePlural = attribute.getValue().toString();
}
}
if ("".equals(thePlural)) {
// Manually compute the plural, as the user did not provided one
thePlural = getInflectorPlural(symbolName, Locale.ENGLISH);
}
if (cache == null) {
// Create the cache (we defer this in case there is no field plural
// retrieval ever required for this instance)
cache = new HashMap<String, String>();
}
// Populate the cache for next time
cache.put(symbolName, thePlural);
return thePlural;
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class ControllerOperationsImpl method createOrUpdateControllerForEntity.
@Override
public void createOrUpdateControllerForEntity(JavaType entity, ControllerMVCResponseService responseType, JavaPackage controllerPackage, String pathPrefix) {
// Getting entity details to obtain information about it
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
AnnotationMetadata entityAnnotation = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY);
if (entityAnnotation == null) {
LOGGER.log(Level.INFO, String.format("ERROR: The provided class %s is not a valid entity. It should be annotated with @RooEntity", entity.getSimpleTypeName()));
return;
}
JpaEntityMetadata entityMetadata = getMetadataService().get(JpaEntityMetadata.createIdentifier(entityDetails));
if (entityMetadata.isCompositionChild()) {
// Don't generate Controller for composition Child entities
LOGGER.log(Level.INFO, String.format("INFO: The provided class %s is composition child part of a relationship. No controller is needed as it's managed form parent controller", entity.getSimpleTypeName()));
return;
}
// Getting related service
JavaType service = null;
ClassOrInterfaceTypeDetails serviceDetails = getServiceLocator().getService(entity);
if (serviceDetails == null) {
// Is necessary at least one service to generate controller
LOGGER.log(Level.INFO, String.format("ERROR: You must generate a service to '%s' entity before to generate a new controller.", entity.getFullyQualifiedTypeName()));
return;
}
service = serviceDetails.getName();
Collection<ClassOrInterfaceTypeDetails> controllers = getControllerLocator().getControllers(entity);
// Check controllersPackage value
if (controllerPackage == null) {
controllerPackage = getDefaultControllerPackage();
if (controllerPackage == null) {
return;
}
}
ControllerAnnotationValues values;
for (ClassOrInterfaceTypeDetails existingController : controllers) {
values = new ControllerAnnotationValues(existingController);
if ((values.getType() == ControllerType.COLLECTION || values.getType() == ControllerType.ITEM)) {
if (StringUtils.equals(values.getPathPrefix(), pathPrefix) && existingController.getAnnotation(responseType.getAnnotation()) != null) {
LOGGER.log(Level.INFO, String.format("ERROR: Already exists a controller associated to entity '%s' with the " + "pathPrefix '%s' for this responseType. Specify different one " + "using --pathPrefix or --responseType parameter.", entity.getSimpleTypeName(), pathPrefix));
return;
}
}
}
// Generate Collection controller JavaType
String entityPluralCapitalized = StringUtils.capitalize(getPluralService().getPlural(entity));
JavaType collectionController = new JavaType(String.format("%s.%sCollection%sController", controllerPackage.getFullyQualifiedPackageName(), entityPluralCapitalized, responseType.getControllerNameModifier()), controllerPackage.getModule());
ClassOrInterfaceTypeDetails collectionControllerDetails = getTypeLocationService().getTypeDetails(collectionController);
if (collectionControllerDetails == null) {
List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
annotations.add(getRooControllerAnnotation(entity, pathPrefix, ControllerType.COLLECTION));
// Add responseType annotation. Don't use responseTypeService
// annotate to
// prevent multiple
// updates of the .java file. Annotate operation will be used during
// controller update.
annotations.add(new AnnotationMetadataBuilder(responseType.getAnnotation()));
final LogicalPath controllerPath = getPathResolver().getPath(collectionController.getModule(), Path.SRC_MAIN_JAVA);
final String resourceIdentifier = getTypeLocationService().getPhysicalTypeCanonicalPath(collectionController, controllerPath);
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(collectionController, getPathResolver().getPath(resourceIdentifier));
ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId, Modifier.PUBLIC, collectionController, PhysicalTypeCategory.CLASS);
cidBuilder.setAnnotations(annotations);
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build());
// Create LinkFactory class
if (responseType.getName().equals("THYMELEAF")) {
createLinkFactoryClass(cidBuilder.getName());
}
} else {
LOGGER.log(Level.INFO, String.format("ERROR: The controller %s already exists.", collectionController.getFullyQualifiedTypeName()));
return;
}
// Same operation to itemController
// Generate Item Controller JavaType
JavaType itemController = new JavaType(String.format("%s.%sItem%sController", controllerPackage.getFullyQualifiedPackageName(), entityPluralCapitalized, responseType.getControllerNameModifier()), controllerPackage.getModule());
ClassOrInterfaceTypeDetails itemControllerDetails = getTypeLocationService().getTypeDetails(itemController);
if (itemControllerDetails == null) {
List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>();
annotations = new ArrayList<AnnotationMetadataBuilder>();
annotations.add(getRooControllerAnnotation(entity, pathPrefix, ControllerType.ITEM));
// Add responseType annotation. Don't use responseTypeService
// annotate to
// prevent multiple
// updates of the .java file. Annotate operation will be used during
// controller update.
annotations.add(new AnnotationMetadataBuilder(responseType.getAnnotation()));
final LogicalPath controllerPathItem = getPathResolver().getPath(itemController.getModule(), Path.SRC_MAIN_JAVA);
final String resourceIdentifierItem = getTypeLocationService().getPhysicalTypeCanonicalPath(itemController, controllerPathItem);
final String declaredByMetadataIdItem = PhysicalTypeIdentifier.createIdentifier(itemController, getPathResolver().getPath(resourceIdentifierItem));
ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataIdItem, Modifier.PUBLIC, itemController, PhysicalTypeCategory.CLASS);
cidBuilder.setAnnotations(annotations);
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build());
// Create LinkFactory class
if (responseType.getName().equals("THYMELEAF")) {
createLinkFactoryClass(cidBuilder.getName());
}
} else {
LOGGER.log(Level.INFO, String.format("ERROR: The controller %s already exists.", collectionController.getFullyQualifiedTypeName()));
return;
}
// Check if requires Deserializer
if (responseType.requiresJsonDeserializer()) {
createJsonDeserializersIfDontExists(entity, itemController.getModule(), controllerPackage);
}
if (responseType.requiresJsonMixin()) {
createJsonMixinIfDontExists(entity, entityMetadata, itemController.getModule(), controllerPackage);
}
// Check multimodule project
if (getProjectOperations().isMultimoduleProject()) {
getProjectOperations().addModuleDependency(collectionController.getModule(), service.getModule());
getProjectOperations().addModuleDependency(itemController.getModule(), service.getModule());
}
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class ControllerOperationsImpl method createOrUpdateDetailControllerForEntity.
@Override
public void createOrUpdateDetailControllerForEntity(JavaType entity, String relationField, ControllerMVCResponseService responseType, JavaPackage controllerPackage, String viewsList) {
// Getting entity details to obtain information about it
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
AnnotationMetadata entityAnnotation = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY);
if (entityAnnotation == null) {
LOGGER.log(Level.INFO, String.format("ERROR: The provided class %s is not a valid entity. It should be annotated with @RooJpaEntity", entity.getSimpleTypeName()));
return;
}
// Check controllersPackage value
if (controllerPackage == null) {
controllerPackage = getDefaultControllerPackage();
if (controllerPackage == null) {
return;
}
}
boolean existsBasicControllers = false;
String pathPrefixController = "";
Collection<ClassOrInterfaceTypeDetails> itemControllers = getControllerLocator().getControllers(entity, ControllerType.ITEM);
for (ClassOrInterfaceTypeDetails existingController : itemControllers) {
if (existingController.getType().getPackage().equals(controllerPackage)) {
ControllerAnnotationValues values = new ControllerAnnotationValues(existingController);
AnnotationMetadata responseTypeAnnotation = existingController.getAnnotation(responseType.getAnnotation());
if (responseTypeAnnotation != null) {
pathPrefixController = values.getPathPrefix();
existsBasicControllers = true;
break;
}
}
}
if (!existsBasicControllers) {
LOGGER.log(Level.INFO, String.format("INFO: Doesn't exist parent controller in the package %s with the response type %s for the entity %s. Please, use 'web mvc controller' command to create them.", controllerPackage, responseType.getName(), entity.getSimpleTypeName()));
return;
}
JpaEntityMetadata entityMetadata = getMetadataService().get(JpaEntityMetadata.createIdentifier(entityDetails));
List<Pair<String, List<RelationInfoExtended>>> relationsToAdd = new ArrayList<Pair<String, List<RelationInfoExtended>>>();
if (StringUtils.isNotBlank(relationField)) {
// Check field received as parameter
List<RelationInfoExtended> infos = getRelationInfoFor(entityMetadata, relationField);
// TODO support multilevel detail (TO BE ANALIZED)
if (infos.size() > 1) {
LOGGER.log(Level.INFO, "ERROR: multi-level details not supported.");
return;
}
StringBuilder sbuilder = new StringBuilder();
for (int i = 0; i < infos.size(); i++) {
RelationInfoExtended info = infos.get(i);
sbuilder.append(info.fieldName);
if (!(info.cardinality == Cardinality.ONE_TO_MANY || info.cardinality == Cardinality.MANY_TO_MANY)) {
LOGGER.log(Level.INFO, String.format("ERROR: %s.%s is not a one-to-many or many-to-many relationships.", info.entityType.getFullyQualifiedTypeName(), info.fieldName));
return;
}
// Check than previous level details has been created before
if (i < infos.size() - 2) {
if (!checkDetailControllerExists(entity, responseType, controllerPackage, pathPrefixController, sbuilder.toString())) {
LOGGER.log(Level.INFO, String.format("ERROR: Detail controller for entity %s and detail field %s must be created before generate %s controller.", entity, sbuilder.toString(), relationField));
return;
}
}
}
relationsToAdd.add(Pair.of(relationField, infos));
} else {
for (RelationInfo info : entityMetadata.getRelationInfos().values()) {
if (info.cardinality == Cardinality.ONE_TO_MANY || info.cardinality == Cardinality.MANY_TO_MANY) {
// Check that is not already generated controller
if (!checkDetailControllerExists(entity, responseType, controllerPackage, pathPrefixController, info.fieldName)) {
relationsToAdd.add(Pair.of(info.fieldName, getRelationInfoFor(entityMetadata, info.fieldName)));
}
}
}
}
if (relationsToAdd.isEmpty()) {
LOGGER.log(Level.INFO, String.format("INFO: none relation found to generate detail controllers for entity '%s'.", entity.getSimpleTypeName()));
return;
}
for (Pair<String, List<RelationInfoExtended>> relation : relationsToAdd) {
boolean generated = createDetailClass(relation.getLeft(), entity, responseType, controllerPackage, pathPrefixController, viewsList);
RelationInfo lastRelation = relation.getRight().get(relation.getRight().size() - 1);
if (generated && lastRelation.type == JpaRelationType.COMPOSITION) {
createDetailsItemClass(relation.getLeft(), entity, responseType, controllerPackage, pathPrefixController, viewsList);
}
}
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class ControllerOperationsImpl method getAllMethodsToPublish.
/**
* Get all the methods that can be published from the service or the
* controller established by parameter
*
* @param currentService
* Service from which obtain methods
* @param currentController
* Controller from which obtain methods
* @return methods names list
*/
public List<String> getAllMethodsToPublish(String currentService, String currentController) {
// Generating all possible values
List<String> serviceMethodsToPublish = new ArrayList<String>();
List<ClassOrInterfaceTypeDetails> servicesToPublish = new ArrayList<ClassOrInterfaceTypeDetails>();
if (StringUtils.isEmpty(currentService)) {
// Get controllers
Collection<ClassOrInterfaceTypeDetails> controllers = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_CONTROLLER);
for (ClassOrInterfaceTypeDetails controller : controllers) {
String name = getClasspathOperations().replaceTopLevelPackageString(controller, currentController);
if (currentController.equals(name)) {
// Get the entity associated
AnnotationMetadata controllerAnnotation = controller.getAnnotation(RooJavaType.ROO_CONTROLLER);
JavaType entity = (JavaType) controllerAnnotation.getAttribute("entity").getValue();
// Search the service related with the entity
Set<ClassOrInterfaceTypeDetails> services = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_SERVICE);
Iterator<ClassOrInterfaceTypeDetails> itServices = services.iterator();
while (itServices.hasNext()) {
ClassOrInterfaceTypeDetails existingService = itServices.next();
AnnotationAttributeValue<Object> entityAttr = existingService.getAnnotation(RooJavaType.ROO_SERVICE).getAttribute("entity");
if (entityAttr != null && entityAttr.getValue().equals(entity)) {
servicesToPublish.add(existingService);
}
}
break;
}
}
} else {
// Get the services
Set<ClassOrInterfaceTypeDetails> services = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_SERVICE);
for (ClassOrInterfaceTypeDetails service : services) {
String name = getClasspathOperations().replaceTopLevelPackageString(service, currentService);
if (currentService.equals(name)) {
servicesToPublish.add(service);
break;
}
}
}
for (ClassOrInterfaceTypeDetails serviceToPublish : servicesToPublish) {
// Getting service metadata
final ServiceMetadata serviceMetadata = getMetadataService().get(ServiceMetadata.createIdentifier(serviceToPublish));
// Get all methods generated by Roo
List<MethodMetadata> methodsImplementedByRoo = new ArrayList<MethodMetadata>();
methodsImplementedByRoo.addAll(serviceMetadata.getNotTransactionalDefinedMethods());
methodsImplementedByRoo.addAll(serviceMetadata.getTransactionalDefinedMethods());
// Get all methods and compare them with the generated by Roo
List<MethodMetadata> methods = serviceToPublish.getMethods();
boolean notGeneratedByRoo;
for (MethodMetadata method : methods) {
notGeneratedByRoo = true;
Iterator<MethodMetadata> iterMethodsImplRoo = methodsImplementedByRoo.iterator();
while (iterMethodsImplRoo.hasNext() && notGeneratedByRoo) {
MethodMetadata methodImplementedByRoo = iterMethodsImplRoo.next();
// If name is equals check the parameters
if (method.getMethodName().equals(methodImplementedByRoo.getMethodName())) {
// order
if (method.getParameterTypes().size() == methodImplementedByRoo.getParameterTypes().size()) {
Iterator<AnnotatedJavaType> iterParameterTypesMethodRoo = methodImplementedByRoo.getParameterTypes().iterator();
boolean allParametersAreEquals = true;
for (AnnotatedJavaType parameterType : method.getParameterTypes()) {
AnnotatedJavaType parameterTypeMethodRoo = iterParameterTypesMethodRoo.next();
if (!parameterType.getJavaType().equals(parameterTypeMethodRoo.getJavaType())) {
allParametersAreEquals = false;
break;
}
}
if (allParametersAreEquals) {
notGeneratedByRoo = false;
}
}
}
}
// If is not generated by Roo add to list of the elements
if (notGeneratedByRoo) {
StringBuffer methodNameBuffer = new StringBuffer("");
if (StringUtils.isEmpty(currentService)) {
methodNameBuffer.append(getClasspathOperations().replaceTopLevelPackage(serviceToPublish)).append(".");
}
methodNameBuffer.append(method.getMethodName().getSymbolName());
List<AnnotatedJavaType> parameterTypes = method.getParameterTypes();
methodNameBuffer = methodNameBuffer.append("(");
for (int i = 0; i < parameterTypes.size(); i++) {
String paramType = parameterTypes.get(i).getJavaType().getSimpleTypeName();
methodNameBuffer = methodNameBuffer.append(paramType).append(",");
}
String methodName;
if (!parameterTypes.isEmpty()) {
methodName = methodNameBuffer.toString().substring(0, methodNameBuffer.toString().length() - 1).concat(")");
} else {
methodName = methodNameBuffer.append(")").toString();
}
serviceMethodsToPublish.add(methodName);
}
}
}
return serviceMethodsToPublish;
}
Aggregations