use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class ExceptionsOperationsImpl method addHandlersAnnotations.
/**
* Generates {@link RooExceptionHandlers} and {@link RooExceptionHandler} annotations
* and adds or updates it on specified class.
*
* @param exception
* @param targetClass
* @param errorView
*/
private void addHandlersAnnotations(JavaType exception, JavaType targetClass, String errorView) {
Validate.notNull(targetClass, "Target class is required to add @RooExceptionHandlers annotation");
// Create @RooExceptionHandler Annotation
final AnnotationMetadataBuilder exceptionHandlerAnnotationBuilder = new AnnotationMetadataBuilder(RooJavaType.ROO_EXCEPTION_HANDLER);
final List<AnnotationAttributeValue<?>> exceptionHandlerAnnotationAttributes = new ArrayList<AnnotationAttributeValue<?>>();
exceptionHandlerAnnotationAttributes.add(new ClassAttributeValue(new JavaSymbolName(EXCEPTION), exception));
if (errorView != null) {
exceptionHandlerAnnotationAttributes.add(new StringAttributeValue(new JavaSymbolName(ERROR_VIEW), errorView));
}
exceptionHandlerAnnotationBuilder.setAttributes(exceptionHandlerAnnotationAttributes);
// Check if container annotation already exists
ClassOrInterfaceTypeDetails typeDetails = typeLocationService.getTypeDetails(targetClass);
ClassOrInterfaceTypeDetailsBuilder typeDetailsBuilder = new ClassOrInterfaceTypeDetailsBuilder(typeDetails);
AnnotationMetadata exceptionHandlersAnnotation = typeDetails.getAnnotation(RooJavaType.ROO_EXCEPTION_HANDLERS);
AnnotationMetadataBuilder exceptionHandlersAnnotationBuilder = null;
if (exceptionHandlersAnnotation != null) {
exceptionHandlersAnnotationBuilder = new AnnotationMetadataBuilder(exceptionHandlersAnnotation);
} else {
exceptionHandlersAnnotationBuilder = new AnnotationMetadataBuilder(RooJavaType.ROO_EXCEPTION_HANDLERS);
}
Validate.notNull(exceptionHandlersAnnotationBuilder);
// Add @RooExceptionHandler annotation into @RooExceptionHandlers
final List<NestedAnnotationAttributeValue> exceptionHandlersArrayValues = new ArrayList<NestedAnnotationAttributeValue>();
exceptionHandlersArrayValues.add(new NestedAnnotationAttributeValue(new JavaSymbolName(VALUE), exceptionHandlerAnnotationBuilder.build()));
final List<AnnotationAttributeValue<?>> attributeValues = new ArrayList<AnnotationAttributeValue<?>>();
attributeValues.add(new ArrayAttributeValue<NestedAnnotationAttributeValue>(new JavaSymbolName(VALUE), exceptionHandlersArrayValues));
if (exceptionHandlersAnnotation == null) {
// Add new @RooExceptionHandlers annotation with given values
exceptionHandlersAnnotationBuilder.setAttributes(attributeValues);
typeDetailsBuilder.addAnnotation(exceptionHandlersAnnotationBuilder.build());
} else {
// Get current annotation values from @RooExceptionHandlers annotation
AnnotationAttributeValue<?> currentHandlers = exceptionHandlersAnnotation.getAttribute(VALUE);
if (currentHandlers != null) {
List<?> values = (List<?>) currentHandlers.getValue();
Iterator<?> it = values.iterator();
while (it.hasNext()) {
NestedAnnotationAttributeValue handler = (NestedAnnotationAttributeValue) it.next();
if (handler.getValue() != null) {
// Check if there is a @RooExceptionHandlers with same 'exception' value
if (exceptionHandlerAnnotationBuilder.build().getAttribute(EXCEPTION).getValue().equals(handler.getValue().getAttribute(EXCEPTION).getValue())) {
LOGGER.warning(String.format("There is already a handler for exception %s in class %s", exception.getSimpleTypeName(), targetClass.getSimpleTypeName()));
return;
}
exceptionHandlersArrayValues.add(handler);
}
}
}
// Add found values
attributeValues.add(new ArrayAttributeValue<NestedAnnotationAttributeValue>(new JavaSymbolName(VALUE), exceptionHandlersArrayValues));
exceptionHandlersAnnotationBuilder.setAttributes(attributeValues);
// Update annotation
typeDetailsBuilder.updateTypeAnnotation(exceptionHandlersAnnotationBuilder.build());
}
// Write to disk
getTypeManagementService().createOrUpdateTypeOnDisk(typeDetailsBuilder.build());
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class PushInOperationsImpl method pushInClass.
/**
* Makes push-in of all items 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
* @param force
* if some operation will produce several changes, this parameter
* should be true.
*
* @return list of objects with all the pushed elements.
*/
public List<Object> pushInClass(JavaType klass, boolean writeOnDisk, boolean force) {
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");
// String builder where changes will be registered
StringBuilder changesToApply = new StringBuilder();
// Getting member details
MemberDetails memberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), classDetails);
List<MemberHoldingTypeDetails> memberHoldingTypes = memberDetails.getDetails();
// Return if the class has not associated ITD's
if (memberHoldingTypes.size() == 1 && memberHoldingTypes.get(0).getPhysicalTypeCategory() != PhysicalTypeCategory.ITD) {
return pushedElements;
}
// 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);
// Getting all details
for (final MemberHoldingTypeDetails memberHoldingTypeDetails : memberDetails.getDetails()) {
// 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 method : allDeclaredMethods) {
// If method exists on .aj file, add it!
if (method.getDeclaredByMetadataId().split("\\?").length > 1 && method.getDeclaredByMetadataId().split("\\?")[1].equals(klass.getFullyQualifiedTypeName()) && !method.getDeclaredByMetadataId().equals(declaredByMetadataId)) {
// Add method to .java file
MethodMetadata newMethod = getNewMethod(declaredByMetadataId, method);
detailsBuilder.addMethod(newMethod);
// Save changes on pushed elements list
pushedElements.add(newMethod);
changesToApply.append(String.format("Method '%s' will be pushed on '%s.java' class. \n", method.getMethodName(), klass.getSimpleTypeName()));
}
}
// Getting all declared fields (including declared on ITDs
// and .java files)
List<? extends FieldMetadata> allDeclaredFields = memberHoldingTypeDetails.getDeclaredFields();
// Checking if is necessary to make push-in for all declared fields
for (FieldMetadata field : allDeclaredFields) {
// If field exists on .aj file, add it!
if (field.getDeclaredByMetadataId().split("\\?").length > 1 && field.getDeclaredByMetadataId().split("\\?")[1].equals(klass.getFullyQualifiedTypeName()) && !field.getDeclaredByMetadataId().equals(declaredByMetadataId)) {
// Add field to .java file
FieldMetadata newField = getNewField(declaredByMetadataId, field);
detailsBuilder.addField(newField);
// Save changes on pushed elements list
pushedElements.add(newField);
changesToApply.append(String.format("Field '%s' will be pushed on '%s.java' class. \n", field.getFieldName(), klass.getSimpleTypeName()));
}
}
// Getting all declared constructors (including declared on ITDs and
// .java files)
List<? extends ConstructorMetadata> allDeclaredConstructors = memberHoldingTypeDetails.getDeclaredConstructors();
// constructors
for (ConstructorMetadata constructor : allDeclaredConstructors) {
// Check if current constructor exists on .java file
classDetails = getTypeLocationService().getTypeDetails(detailsBuilder.build().getType());
List<JavaType> parameterTypes = new ArrayList<JavaType>();
for (AnnotatedJavaType type : constructor.getParameterTypes()) {
parameterTypes.add(type.getJavaType());
}
ConstructorMetadata javaDeclaredConstructor = classDetails.getDeclaredConstructor(parameterTypes);
// If not exists, add it!
if (javaDeclaredConstructor == null) {
// Add constructor to .java file
detailsBuilder.addConstructor(constructor);
// Save changes on pushed elements list
pushedElements.add(constructor);
String constructorParametersNames = "";
for (JavaSymbolName paramName : constructor.getParameterNames()) {
constructorParametersNames = constructorParametersNames.concat(paramName.getSymbolName()).concat(", ");
changesToApply.append(String.format("Constructor with parameters '%s' will be pushed on '%s.java' class. \n", constructorParametersNames.substring(0, constructorParametersNames.length() - 2), klass.getSimpleTypeName()));
}
}
}
// Getting all declared annotations (including declared on ITDs
// and .java files)
List<AnnotationMetadata> allDeclaredAnnotations = memberHoldingTypeDetails.getAnnotations();
for (AnnotationMetadata annotation : allDeclaredAnnotations) {
// Check if current annotation exists on .java file
classDetails = getTypeLocationService().getTypeDetails(detailsBuilder.build().getType());
List<AnnotationMetadata> javaDeclaredAnnotations = classDetails.getAnnotations();
boolean annotationExists = false;
for (AnnotationMetadata javaAnnotation : javaDeclaredAnnotations) {
if (javaAnnotation.getAnnotationType().getFullyQualifiedTypeName().equals(annotation.getAnnotationType().getFullyQualifiedTypeName())) {
annotationExists = true;
}
}
// If not exists, add it!
if (!annotationExists) {
// Add annotation to .java file
detailsBuilder.addAnnotation(annotation);
// Save changes on pushed elements list
pushedElements.add(annotation);
changesToApply.append(String.format("Annotation '%s' will be pushed on '%s.java' class. \n", annotation.getAnnotationType().getSimpleTypeName(), klass.getSimpleTypeName()));
}
}
// Getting all extends registered on .aj file to move to .java file
List<JavaType> allExtendsTypes = memberHoldingTypeDetails.getExtendsTypes();
for (JavaType extendsType : allExtendsTypes) {
// If extends exists on .aj file, add it!
if (!detailsBuilder.getExtendsTypes().contains(extendsType)) {
detailsBuilder.addExtendsTypes(extendsType);
// Save changes on pushed elements list
pushedElements.add(extendsType);
changesToApply.append(String.format("Extends type '%s' will be pushed on '%s.java' class. \n", extendsType.getSimpleTypeName(), klass.getSimpleTypeName()));
}
}
// Getting all implements registered on .aj file to move to .java
// file
List<JavaType> allImplementsTypes = memberHoldingTypeDetails.getImplementsTypes();
for (JavaType implementsType : allImplementsTypes) {
if (!detailsBuilder.getImplementsTypes().contains(implementsType)) {
detailsBuilder.addImplementsType(implementsType);
// Save changes on pushed elements list
pushedElements.add(implementsType);
changesToApply.append(String.format("Implements type '%s' will be pushed on '%s.java' class. \n", implementsType.getSimpleTypeName(), klass.getSimpleTypeName()));
}
}
// Getting all imports registered on .aj file to move to .java file
Set<ImportMetadata> allRegisteredImports = memberHoldingTypeDetails.getImports();
detailsBuilder.addImports(allRegisteredImports);
// Save changes on pushed elements list
pushedElements.add(allRegisteredImports);
}
// Updating .java file
if (!force) {
// Show message to be able to know which changes will be applied
if (changesToApply.length() > 0) {
LOGGER.log(Level.INFO, changesToApply.toString());
}
} else if (writeOnDisk) {
getTypeManagementService().createOrUpdateTypeOnDisk(detailsBuilder.build());
}
return pushedElements;
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class JsonControllerTestCreator method createIntegrationTest.
@Override
public void createIntegrationTest(JavaType type, Pom module) {
Validate.notNull(type, "Class to produce an integration test class for is required");
// Check if provided JavaType is a JSON Controller
ClassOrInterfaceTypeDetails cid = typeLocationService.getTypeDetails(type);
Validate.notNull(cid.getAnnotation(RooJavaType.ROO_CONTROLLER), "Type must be a Roo controller.");
Validate.notNull(cid.getAnnotation(RooJavaType.ROO_JSON), "Type must be a Roo JSON controller.");
// Add springlets-boot-starter-test dependency
projectOperations.addProperty("", SPRINGLETS_VERSION_PROPERTY);
projectOperations.addDependency(module.getModuleName(), SPRINGLETS_BOOT_STARTER_TEST_DEPENDENCY);
// Get the controller managed entity
ControllerAnnotationValues controllerAnnotationValues = new ControllerAnnotationValues(cid);
JavaType managedEntity = controllerAnnotationValues.getEntity();
// Workaround to get a JavaType with not null module when recovering it
// from a ClassAttributeValue
managedEntity = new JavaType(managedEntity.getFullyQualifiedTypeName(), managedEntity.getArray(), managedEntity.getDataType(), managedEntity.getArgName(), managedEntity.getParameters(), typeLocationService.getTypeDetails(managedEntity).getType().getModule());
// Create Data On Demand artifacts for managed entity
List<DataOnDemandCreatorProvider> dodCreators = getValidDataOnDemandCreatorsForType(managedEntity);
Validate.isTrue(!dodCreators.isEmpty(), "Couldn't find any 'DataOnDemandCreatorProvider' for JSON controllers.");
Validate.isTrue(dodCreators.size() == 1, "More than 1 valid 'DataOnDemandCreatorProvider' found for JSON controllers. %s can't decide which one to use.", this.getClass().getName());
DataOnDemandCreatorProvider creator = dodCreators.get(0);
creator.createDataOnDemand(managedEntity);
// Add module dependency with test-jar dependency
if (projectOperations.isMultimoduleProject()) {
String managedEntityModuleName = managedEntity.getModule();
Pom managedEntityModule = projectOperations.getPomFromModuleName(managedEntityModuleName);
projectOperations.addDependency(module.getModuleName(), new Dependency(managedEntityModule.getGroupId(), managedEntityModule.getArtifactId(), "${project.version}", DependencyType.valueOfTypeCode("test-jar"), DependencyScope.TEST), true, true);
}
// Create integration test class
final JavaType name = new JavaType(type + "IT", module.getModuleName());
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(name, Path.SRC_TEST_JAVA.getModulePathId(module.getModuleName()));
if (metadataService.get(declaredByMetadataId) != null) {
// The file already exists
return;
}
// Add @RooJsonControllerIntegrationTest to source file
AnnotationMetadataBuilder rooIntegrationTestAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_JSON_CONTROLLER_INTEGRATION_TEST);
rooIntegrationTestAnnotation.addClassAttribute("targetClass", type);
// Create integration test class
final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId, Modifier.PUBLIC, name, PhysicalTypeCategory.CLASS);
cidBuilder.addAnnotation(rooIntegrationTestAnnotation);
// Write changes to disk
typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class JpaTestCreator method createUnitTest.
@Override
public void createUnitTest(final JavaType entity) {
Validate.notNull(entity, "Class to produce an unit test class for is required");
// Check if provided JavaType is a Repository
ClassOrInterfaceTypeDetails cid = typeLocationService.getTypeDetails(entity);
Validate.notNull(cid.getAnnotation(RooJavaType.ROO_JPA_ENTITY), "Type must be a Roo JPA Entity type.");
// Create JPA DataOnDemand artifacts
List<DataOnDemandCreatorProvider> dodCreators = getValidDataOnDemandCreatorsForType(entity);
for (DataOnDemandCreatorProvider dodCreator : dodCreators) {
dodCreator.createDataOnDemand(entity);
}
final JavaType name = new JavaType(entity + "Test", entity.getModule());
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(name, Path.SRC_TEST_JAVA.getModulePathId(entity.getModule()));
if (metadataService.get(declaredByMetadataId) != null) {
// The file already exists
return;
}
// Add @RooUnitTest to source file
AnnotationMetadataBuilder rooUnitTestAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_JPA_UNIT_TEST);
rooUnitTestAnnotation.addClassAttribute("targetClass", entity);
final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId, Modifier.PUBLIC, name, PhysicalTypeCategory.CLASS);
cidBuilder.addAnnotation(rooUnitTestAnnotation);
typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class JpaDataOnDemandCreator method createDataOnDemandConfiguration.
@Override
public JavaType createDataOnDemandConfiguration(String moduleName) {
// Check if alreafy exists
JavaType dodConfig = getDataOnDemandConfiguration();
if (dodConfig != null) {
return dodConfig;
}
// Add spring-boot-test dependency with test scope
projectOperations.addDependency(moduleName, SPRING_BOOT_TEST_DEPENDENCY);
// Get Pom
final Pom module = projectOperations.getPomFromModuleName(moduleName);
// Get test Path for module
final LogicalPath path = LogicalPath.getInstance(Path.SRC_TEST_JAVA, moduleName);
// Create the JavaType for the configuration class
JavaType dodConfigurationClass = new JavaType(String.format("%s.dod.DataOnDemandConfiguration", typeLocationService.getTopLevelPackageForModule(module), moduleName));
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(dodConfigurationClass, path);
if (metadataService.get(declaredByMetadataId) != null) {
// The file already exists
return new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId).getName();
}
// Create the CID builder
ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId, Modifier.PUBLIC, dodConfigurationClass, PhysicalTypeCategory.CLASS);
cidBuilder.addAnnotation(new AnnotationMetadataBuilder(RooJavaType.ROO_JPA_DATA_ON_DEMAND_CONFIGURATION));
// Write changes to disk
final ClassOrInterfaceTypeDetails configDodCid = cidBuilder.build();
typeManagementService.createOrUpdateTypeOnDisk(configDodCid);
return configDodCid.getName();
}
Aggregations