use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class FinderOperationsImpl method installFinder.
public void installFinder(final JavaType entity, final JavaSymbolName finderName, JavaType formBean, JavaType returnType) {
Validate.notNull(entity, "ERROR: Entity type required to generate finder.");
Validate.notNull(finderName, "ERROR: Finder name required to generate finder.");
final String id = getTypeLocationService().getPhysicalTypeIdentifier(entity);
if (id == null) {
LOGGER.warning("Cannot locate source for '" + entity.getFullyQualifiedTypeName() + "'");
return;
}
// Check if provided entity is annotated with @RooJpaEntity
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
AnnotationMetadata entityAnnotation = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY);
Validate.notNull(entityAnnotation, "ERROR: Provided entity must be annotated with @RooJpaEntity");
// Getting repository that manages current entity
ClassOrInterfaceTypeDetails repository = getRepositoryJpaLocator().getRepository(entity);
// Entity must have a repository that manages it, if not, shows an error
Validate.notNull(repository, "ERROR: You must generate a repository to the provided entity before to add new finder. You could use 'repository jpa' commands.");
// Check if provided formBean contains the field names and types indicated as finder params
if (formBean != null) {
MemberDetails entityMemberDetails = getMemberDetailsScanner().getMemberDetails(this.getClass().getName(), getTypeLocationService().getTypeDetails(entity));
PartTree finderPartTree = new PartTree(finderName.getSymbolName(), entityMemberDetails);
checkDtoFieldsForFinder(getTypeLocationService().getTypeDetails(formBean), finderPartTree, repository.getType());
}
// Get repository annotation
AnnotationMetadata repositoryAnnotation = repository.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA);
AnnotationMetadataBuilder repositoryAnnotationBuilder = new AnnotationMetadataBuilder(repositoryAnnotation);
// Create list that will include finders to add
List<AnnotationAttributeValue<?>> finders = new ArrayList<AnnotationAttributeValue<?>>();
// Check if new finder name to be included already exists in @RooRepositoryJpa annotation
AnnotationAttributeValue<?> currentFinders = repositoryAnnotation.getAttribute("finders");
if (currentFinders != null) {
List<?> values = (List<?>) currentFinders.getValue();
Iterator<?> it = values.iterator();
while (it.hasNext()) {
NestedAnnotationAttributeValue finder = (NestedAnnotationAttributeValue) it.next();
if (finder.getValue() != null && finder.getValue().getAttribute("value") != null) {
if (finder.getValue().getAttribute("value").getValue().equals(finderName.getSymbolName())) {
LOGGER.log(Level.WARNING, String.format("ERROR: Finder '%s' already exists on entity '%s'", finderName.getSymbolName(), entity.getSimpleTypeName()));
return;
}
finders.add(finder);
}
}
}
// Create @RooFinder
AnnotationMetadataBuilder singleFinderAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_FINDER);
// Add finder attribute
singleFinderAnnotation.addStringAttribute("value", finderName.getSymbolName());
// Add returnType attribute
singleFinderAnnotation.addClassAttribute("returnType", returnType);
// Prevent errors validating if the return type contains a valid module
if (returnType.getModule() != null) {
getProjectOperations().addModuleDependency(repository.getName().getModule(), returnType.getModule());
}
// Add formBean attribute
if (formBean != null) {
singleFinderAnnotation.addClassAttribute("formBean", formBean);
getProjectOperations().addModuleDependency(repository.getName().getModule(), formBean.getModule());
}
NestedAnnotationAttributeValue newFinder = new NestedAnnotationAttributeValue(new JavaSymbolName("value"), singleFinderAnnotation.build());
// If not exists current finder, include it
finders.add(newFinder);
// Add finder list to currentFinders
ArrayAttributeValue<AnnotationAttributeValue<?>> newFinders = new ArrayAttributeValue<AnnotationAttributeValue<?>>(new JavaSymbolName("finders"), finders);
// Include finder name to finders attribute
repositoryAnnotationBuilder.addAttribute(newFinders);
// Update @RooRepositoryJpa annotation
final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(repository);
// Update annotation
cidBuilder.updateTypeAnnotation(repositoryAnnotationBuilder);
// Save changes on disk
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build());
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class RepositoryJpaLayerProvider method getMethodAdditions.
/**
* Returns the additions that the caller needs to make in order to invoke
* the given method
*
* @param callerMID the caller's metadata ID (required)
* @param method the method being called (required)
* @param repositoryType the type of repository being called
* @param parameterNames the parameter names used by the caller
* @return a non-<code>null</code> set of additions
*/
private MemberTypeAdditions getMethodAdditions(final String callerMID, final RepositoryJpaLayerMethod method, final JavaType repositoryType, final List<MethodParameter> parameters) {
// Create a builder to hold the repository field to be copied into the
// caller
final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(callerMID);
final AnnotationMetadataBuilder autowiredAnnotation = new AnnotationMetadataBuilder(AUTOWIRED);
final String repositoryFieldName = StringUtils.uncapitalize(repositoryType.getSimpleTypeName());
cidBuilder.addField(new FieldMetadataBuilder(callerMID, 0, Arrays.asList(autowiredAnnotation), new JavaSymbolName(repositoryFieldName), repositoryType));
// Create the additions to invoke the given method on this field
final String methodCall = repositoryFieldName + "." + method.getCall(parameters);
return new MemberTypeAdditions(cidBuilder, method.getName(), methodCall, false, parameters);
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class RepositoryJpaOperationsImpl method addRepositoryInterface.
/**
* Method that generates the repository interface. This method takes in mind
* if entity is defined as readOnly or not.
*
* @param interfaceType
* @param domainType
* @param entityDetails
* @param interfaceIdentifier
*/
private void addRepositoryInterface(JavaType interfaceType, JavaType domainType, ClassOrInterfaceTypeDetails entityDetails, String interfaceIdentifier, JavaType defaultReturnType) {
// Generates @RooJpaRepository annotation with referenced entity value
// and repository custom associated to this repository
final AnnotationMetadataBuilder interfaceAnnotationMetadata = new AnnotationMetadataBuilder(RooJavaType.ROO_REPOSITORY_JPA);
interfaceAnnotationMetadata.addAttribute(new ClassAttributeValue(new JavaSymbolName("entity"), domainType));
if (defaultReturnType != null) {
interfaceAnnotationMetadata.addAttribute(new ClassAttributeValue(new JavaSymbolName("defaultReturnType"), defaultReturnType));
// Add dependencies between modules
getProjectOperations().addModuleDependency(interfaceType.getModule(), defaultReturnType.getModule());
}
// Generating interface
final String interfaceMdId = PhysicalTypeIdentifier.createIdentifier(interfaceType, getPathResolver().getPath(interfaceIdentifier));
final ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(interfaceMdId, Modifier.PUBLIC, interfaceType, PhysicalTypeCategory.INTERFACE);
// Annotate repository interface
cidBuilder.addAnnotation(interfaceAnnotationMetadata.build());
// Save new repository on disk
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build());
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class RepositoryJpaOperationsImpl method addRepositoryConfigurationClass.
/**
* Checks for all the application modules in project and adds a repository
* configuration class, which uses the Springlets base repository class if
* none is already specified.
*/
private void addRepositoryConfigurationClass() {
Set<ClassOrInterfaceTypeDetails> applicationCids = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(SpringJavaType.SPRING_BOOT_APPLICATION);
for (ClassOrInterfaceTypeDetails applicationCid : applicationCids) {
// Obtain main application config class and its module
Pom module = getProjectOperations().getPomFromModuleName(applicationCid.getType().getModule());
// Create or update SpringDataJpaDetachableRepositoryConfiguration
JavaType repositoryConfigurationClass = new JavaType(String.format("%s.config.SpringDataJpaDetachableRepositoryConfiguration", getTypeLocationService().getTopLevelPackageForModule(module)), module.getModuleName());
Validate.notNull(repositoryConfigurationClass.getModule(), "ERROR: Module name is required to generate a valid JavaType");
// Checks if new service interface already exists.
final String repositoryConfigurationClassIdentifier = getPathResolver().getCanonicalPath(repositoryConfigurationClass.getModule(), Path.SRC_MAIN_JAVA, repositoryConfigurationClass);
final String mid = PhysicalTypeIdentifier.createIdentifier(repositoryConfigurationClass, getPathResolver().getPath(repositoryConfigurationClassIdentifier));
if (!getFileManager().exists(repositoryConfigurationClassIdentifier)) {
// Repository config class doesn't exist. Create class builder
final ClassOrInterfaceTypeDetailsBuilder typeBuilder = new ClassOrInterfaceTypeDetailsBuilder(mid, PUBLIC, repositoryConfigurationClass, PhysicalTypeCategory.CLASS);
// Add @RooJpaRepositoryConfiguration
AnnotationMetadataBuilder repositoryCondigurationAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_JPA_REPOSITORY_CONFIGURATION);
typeBuilder.addAnnotation(repositoryCondigurationAnnotation);
// Write new class disk
getTypeManagementService().createOrUpdateTypeOnDisk(typeBuilder.build());
}
}
}
use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder in project spring-roo by spring-projects.
the class RepositoryJpaTestCreator 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 Repository
ClassOrInterfaceTypeDetails cid = typeLocationService.getTypeDetails(type);
Validate.notNull(cid.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA), "Type must be a Roo JPA Repository type.");
// Get the repository managed entity
RepositoryJpaAnnotationValues repositoryAnnotationValues = new RepositoryJpaAnnotationValues(cid);
JavaType managedEntity = repositoryAnnotationValues.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 JPA repositories.");
Validate.isTrue(dodCreators.size() == 1, "More than 1 valid 'DataOnDemandCreatorProvider' found for JPA repositories. %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 @RooRepositoryJpaIntegrationTest to source file
AnnotationMetadataBuilder rooIntegrationTestAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_REPOSITORY_JPA_INTEGRATION_TEST);
rooIntegrationTestAnnotation.addClassAttribute("targetClass", type);
rooIntegrationTestAnnotation.addClassAttribute("dodConfigurationClass", creator.getDataOnDemandConfiguration());
rooIntegrationTestAnnotation.addClassAttribute("dodClass", creator.getDataOnDemand(managedEntity));
// 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());
}
Aggregations