use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder 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.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class ServiceOperationsImpl method createServiceInterface.
/**
* Method that creates the service interface
*
* @param domainType
* @param interfaceType
*/
private void createServiceInterface(final JavaType domainType, final JavaType interfaceType) {
Validate.notNull(interfaceType.getModule(), "JavaType %s does not have a module", domainType);
// Checks if new service interface already exists.
final String interfaceIdentifier = pathResolver.getCanonicalPath(interfaceType.getModule(), Path.SRC_MAIN_JAVA, interfaceType);
if (fileManager.exists(interfaceIdentifier)) {
// Type already exists - nothing to do
return;
}
// Validate that user provides a valid entity
Validate.notNull(domainType, "ERROR: Domain type required to generate service");
ClassOrInterfaceTypeDetails entityDetails = typeLocationService.getTypeDetails(domainType);
Validate.notNull(entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY), "ERROR: Provided entity should be annotated with @RooJpaEntity");
// Generating @RooService annotation
final AnnotationMetadataBuilder interfaceAnnotationMetadata = new AnnotationMetadataBuilder(ROO_SERVICE);
interfaceAnnotationMetadata.addAttribute(new ClassAttributeValue(new JavaSymbolName("entity"), domainType));
// Creating interface builder
final String interfaceMid = PhysicalTypeIdentifier.createIdentifier(interfaceType, pathResolver.getPath(interfaceIdentifier));
final ClassOrInterfaceTypeDetailsBuilder interfaceTypeBuilder = new ClassOrInterfaceTypeDetailsBuilder(interfaceMid, PUBLIC, interfaceType, PhysicalTypeCategory.INTERFACE);
// Adding @RooService annotation to current interface
interfaceTypeBuilder.addAnnotation(interfaceAnnotationMetadata.build());
// Write service interface on disk
typeManagementService.createOrUpdateTypeOnDisk(interfaceTypeBuilder.build());
// Add dependencies between modules
projectOperations.addModuleDependency(interfaceType.getModule(), domainType.getModule());
// Add springlets-data-commons dependency
projectOperations.addDependency(interfaceType.getModule(), new Dependency("io.springlets", "springlets-data-commons", null));
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder 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.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class ControllerOperationsImpl method setup.
/**
* This operation will setup Spring MVC on generated project.
*
* @param module
* Pom module where Spring MVC should be included
* @param usesDefaultModule
* boolean that indicates if the setup command is using the
* default application module
*/
@Override
public void setup(Pom module, boolean usesDefaultModule) {
// If provided module is null, use the focused one
if (module == null) {
module = getProjectOperations().getFocusedModule();
}
// Checks that provided module matches with Application properties
// modules
Validate.isTrue(getTypeLocationService().hasModuleFeature(module, ModuleFeatureName.APPLICATION), "ERROR: You are trying to install Spring MVC inside module that doesn't match with APPLICATION modules features. " + "Use --module parameter to specify a valid APPLICATION module where install Spring MVC.");
// message
if (isInstalledInModule(module.getModuleName())) {
String message = "";
if (usesDefaultModule) {
message = String.format("the default module '%s'.", module.getModuleName());
} else {
message = String.format("the provided module '%s'.", module.getModuleName());
}
LOGGER.log(Level.INFO, String.format("INFO: Spring MVC is already installed in %s", message));
return;
}
// Add Spring MVC dependency
getProjectOperations().addDependency(module.getModuleName(), new Dependency("org.springframework.boot", "spring-boot-starter-web", null));
// Add DateTime dependency
getProjectOperations().addDependency(module.getModuleName(), new Dependency("joda-time", "joda-time", null));
// Add TracEE dependency and property
getProjectOperations().addProperty("", TRACEE_PROPERTY);
getProjectOperations().addDependency(module.getModuleName(), TRACEE_SPRINGMVC);
// Include Springlets Starter project dependencies and properties
getProjectOperations().addProperty("", SPRINGLETS_VERSION_PROPERTY);
getProjectOperations().addDependency(module.getModuleName(), SPRINGLETS_WEB_STARTER);
// Create WebMvcConfiguration.java class
JavaType webMvcConfiguration = new JavaType(String.format("%s.config.WebMvcConfiguration", getTypeLocationService().getTopLevelPackageForModule(module)), module.getModuleName());
Validate.notNull(webMvcConfiguration.getModule(), "ERROR: Module name is required to generate a valid JavaType");
// Checks if new service interface already exists.
final String webMvcConfigurationIdentifier = getPathResolver().getCanonicalPath(webMvcConfiguration.getModule(), Path.SRC_MAIN_JAVA, webMvcConfiguration);
if (!getFileManager().exists(webMvcConfigurationIdentifier)) {
// Creating class builder
final String mid = PhysicalTypeIdentifier.createIdentifier(webMvcConfiguration, getPathResolver().getPath(webMvcConfigurationIdentifier));
final ClassOrInterfaceTypeDetailsBuilder typeBuilder = new ClassOrInterfaceTypeDetailsBuilder(mid, PUBLIC, webMvcConfiguration, PhysicalTypeCategory.CLASS);
// Generating @RooWebMvcConfiguration annotation
final AnnotationMetadataBuilder annotationMetadata = new AnnotationMetadataBuilder(RooJavaType.ROO_WEB_MVC_CONFIGURATION);
typeBuilder.addAnnotation(annotationMetadata.build());
// Write new class disk
getTypeManagementService().createOrUpdateTypeOnDisk(typeBuilder.build());
}
// Create JSON configuration class
createDomainModelModule(module);
// Adding spring.jackson.serialization.indent-output property
getApplicationConfigService().addProperty(module.getModuleName(), "spring.jackson.serialization.indent-output", "true", "dev", true);
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class WebFinderOperationsImpl method createOrUpdateSearchControllerForEntity.
@Override
public void createOrUpdateSearchControllerForEntity(JavaType entity, List<String> queryMethods, ControllerMVCResponseService responseType, JavaPackage controllerPackage, String pathPrefix) {
Validate.notNull(entity, "Entity type required");
Validate.notNull(responseType, "Response type required");
Validate.notNull(controllerPackage, "Package required");
Validate.notNull(typeLocationService.getTypeDetails(entity).getAnnotation(RooJavaType.ROO_JPA_ENTITY), "The provided JavaType %s must be annotated with @RooJpaEntity", entity.getSimpleTypeName());
// Check if module has an application class
controllerPackage = checkAndUseApplicationModule(controllerPackage);
// Check if entity has any associated repository
final ClassOrInterfaceTypeDetails relatedRepositoryDetails = repositoryJpaLocator.getRepository(entity);
Validate.notNull(relatedRepositoryDetails, "Entity %s doesn't have an associated repository. You " + "need at least an associated repository with finders to publish them to the web layer." + "Please, create one associated repository with 'repository jpa' command.", entity);
// Get repository finder methods
RepositoryJpaMetadata repositoryMetadata = repositoryJpaLocator.getRepositoryMetadata(entity);
// Get finders in @RooRepositoryJpa
// List<String> entityFinders = repositoryMetadata.getDeclaredFinderNames();
List<String> entityFinders = getFindersWhichCanBePublish(repositoryMetadata, responseType);
// Check if specified finder methods exists in associated repository
for (String finder : queryMethods) {
if (!entityFinders.contains(finder)) {
LOGGER.log(Level.INFO, String.format("ERROR: Provided finder '%s' doesn't exists on the repository '%s' " + "related to entity '%s'", finder, relatedRepositoryDetails.getType().getSimpleTypeName(), entity.getSimpleTypeName()));
return;
}
}
// Check if entity has any associated service
JavaType relatedService = null;
ClassOrInterfaceTypeDetails service = serviceLocator.getService(entity);
if (service == null) {
LOGGER.log(Level.INFO, String.format("Entity %s doesn't have associated services, " + "necessary to create controllers. Please, create one associated service with " + "'service' command before publish finders to web layer.", entity.getSimpleTypeName()));
return;
}
relatedService = service.getType();
// Seek for search type controllers related to entity
Collection<ClassOrInterfaceTypeDetails> entitySearchControllers = controllerLocator.getControllers(entity, ControllerType.SEARCH, responseType.getAnnotation());
// Check if any of the search controllers have the same pathPrefix.
// If so, and controllerPackage is as well the same, update the controller.
ClassOrInterfaceTypeDetails controllerToUpdateOrCreate = null;
for (ClassOrInterfaceTypeDetails entitySearchController : entitySearchControllers) {
ControllerAnnotationValues controllerValues = new ControllerAnnotationValues(entitySearchController);
if (StringUtils.equals(pathPrefix, controllerValues.getPathPrefix())) {
if (controllerPackage.equals(entitySearchController.getType().getPackage())) {
// The controller exists, so choose it for updating.
controllerToUpdateOrCreate = entitySearchController;
break;
} else {
// A related controller already exists for the same entity, with the same 'pathPrefix',
// but in a different package.
LOGGER.log(Level.INFO, String.format("ERROR: Already exists a controller associated " + "to entity '%s' with the pathPrefix '%s', in a different package. Specify " + "a different pathPrefix to create a new one, or the same 'package' and " + "'pathPrefix' to update the existing controller.", entity.getSimpleTypeName(), pathPrefix));
return;
}
} else if (entitySearchController.getType().getPackage().equals(controllerPackage)) {
// A related controller already exists for the same entity, in the same package
LOGGER.log(Level.INFO, String.format("ERROR: Already exists a controller associated to entity '%s' in the " + "same package '%s', with different 'pathPrefix'. Specify a different 'pathPrefix' " + "and a different package that the existing one to create a new one, or the same " + "'package' and 'pathPrefix' to update the existing controller.", entity.getSimpleTypeName(), controllerPackage.getFullyQualifiedPackageName()));
return;
}
}
// Update or create the search controller
ClassOrInterfaceTypeDetailsBuilder controllerBuilder = null;
if (controllerToUpdateOrCreate == null) {
// Create controller builder for a new file
controllerBuilder = buildNewSearchController(entity, queryMethods, responseType, controllerPackage, pathPrefix);
} else {
// Controller already exists, so create builder with it
controllerBuilder = new ClassOrInterfaceTypeDetailsBuilder(controllerToUpdateOrCreate);
// Update existing controller
boolean findersAdded = updateExistingSearchController(queryMethods, controllerToUpdateOrCreate, controllerBuilder);
// Check if response type is already added
AnnotationMetadata responseTypeAnnotation = controllerToUpdateOrCreate.getAnnotation(responseType.getAnnotation());
if (responseTypeAnnotation != null) {
if (!findersAdded) {
// Controller already had same response type annotation and same finders added
LOGGER.log(Level.WARNING, String.format("Controller %s already has specified finders and specified response type.", controllerToUpdateOrCreate.getType().getFullyQualifiedTypeName()));
return;
}
} else {
// Add annotation for the new response type
controllerBuilder.addAnnotation(new AnnotationMetadataBuilder(responseType.getAnnotation()));
}
}
// Add dependencies between modules if required
addModuleDependencies(entity, relatedRepositoryDetails, relatedService, controllerBuilder.build());
// Write changes to disk
typeManagementService.createOrUpdateTypeOnDisk(controllerBuilder.build());
// Create LinkFactory class for the search controler
controllerOperations.createLinkFactoryClass(controllerBuilder.getName());
}
Aggregations