use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class WebFinderCommands method getEntityValues.
@CliOptionAutocompleteIndicator(param = "entity", command = "web mvc finder", help = "--entity parameter should be completed with classes annotated with @RooJpaEntity.")
public List<String> getEntityValues(ShellContext context) {
// Get current value of class
String currentText = context.getParameters().get("entity");
// Create results to return
List<String> results = new ArrayList<String>();
for (JavaType entity : getTypeLocationService().findTypesWithAnnotation(RooJavaType.ROO_JPA_ENTITY)) {
ClassOrInterfaceTypeDetails repository = repositoryJpaLocator.getFirstRepository(entity);
if (repository == null) {
continue;
}
AnnotationMetadata repositoryAnnotation = repository.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA);
if (repositoryAnnotation.getAttribute("finders") == null) {
continue;
}
String name = replaceTopLevelPackageString(entity, currentText);
if (!results.contains(name)) {
results.add(name);
}
}
if (results.isEmpty()) {
results.add("");
}
return results;
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class JspViewManager method addCommonAttributes.
private void addCommonAttributes(final FieldMetadata field, final Element fieldElement) {
AnnotationMetadata annotationMetadata;
if (field.getFieldType().equals(INT_OBJECT) || field.getFieldType().getFullyQualifiedTypeName().equals(int.class.getName()) || field.getFieldType().equals(SHORT_OBJECT) || field.getFieldType().getFullyQualifiedTypeName().equals(short.class.getName()) || field.getFieldType().equals(LONG_OBJECT) || field.getFieldType().getFullyQualifiedTypeName().equals(long.class.getName()) || field.getFieldType().equals(BIG_INTEGER)) {
fieldElement.setAttribute("validationMessageCode", "field_invalid_integer");
} else if (isEmailField(field)) {
fieldElement.setAttribute("validationMessageCode", "field_invalid_email");
} else if (field.getFieldType().equals(DOUBLE_OBJECT) || field.getFieldType().getFullyQualifiedTypeName().equals(double.class.getName()) || field.getFieldType().equals(FLOAT_OBJECT) || field.getFieldType().getFullyQualifiedTypeName().equals(float.class.getName()) || field.getFieldType().equals(BIG_DECIMAL)) {
fieldElement.setAttribute("validationMessageCode", "field_invalid_number");
}
if ("field:input".equals(fieldElement.getTagName()) && null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), MIN))) {
final AnnotationAttributeValue<?> min = annotationMetadata.getAttribute(VALUE);
if (min != null) {
fieldElement.setAttribute("min", min.getValue().toString());
fieldElement.setAttribute("required", "true");
}
}
if ("field:input".equals(fieldElement.getTagName()) && null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), MAX)) && !"field:textarea".equals(fieldElement.getTagName())) {
final AnnotationAttributeValue<?> maxA = annotationMetadata.getAttribute(VALUE);
if (maxA != null) {
fieldElement.setAttribute("max", maxA.getValue().toString());
}
}
if ("field:input".equals(fieldElement.getTagName()) && null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), DECIMAL_MIN)) && !"field:textarea".equals(fieldElement.getTagName())) {
final AnnotationAttributeValue<?> decimalMin = annotationMetadata.getAttribute(VALUE);
if (decimalMin != null) {
fieldElement.setAttribute("decimalMin", decimalMin.getValue().toString());
fieldElement.setAttribute("required", "true");
}
}
if ("field:input".equals(fieldElement.getTagName()) && null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), DECIMAL_MAX))) {
final AnnotationAttributeValue<?> decimalMax = annotationMetadata.getAttribute(VALUE);
if (decimalMax != null) {
fieldElement.setAttribute("decimalMax", decimalMax.getValue().toString());
}
}
if (null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), PATTERN))) {
final AnnotationAttributeValue<?> regexp = annotationMetadata.getAttribute(new JavaSymbolName("regexp"));
if (regexp != null) {
fieldElement.setAttribute("validationRegex", regexp.getValue().toString());
}
}
if ("field:input".equals(fieldElement.getTagName()) && null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), SIZE))) {
final AnnotationAttributeValue<?> max = annotationMetadata.getAttribute(new JavaSymbolName("max"));
if (max != null) {
fieldElement.setAttribute("max", max.getValue().toString());
}
final AnnotationAttributeValue<?> min = annotationMetadata.getAttribute(new JavaSymbolName("min"));
if (min != null) {
fieldElement.setAttribute("min", min.getValue().toString());
fieldElement.setAttribute("required", "true");
}
}
if (null != (annotationMetadata = MemberFindingUtils.getAnnotationOfType(field.getAnnotations(), NOT_NULL))) {
final String tagName = fieldElement.getTagName();
if (tagName.endsWith("textarea") || tagName.endsWith("input") || tagName.endsWith("datetime") || tagName.endsWith("textarea") || tagName.endsWith("select") || tagName.endsWith("reference")) {
fieldElement.setAttribute("required", "true");
}
}
if (field.getCustomData().keySet().contains(CustomDataKeys.COLUMN_FIELD)) {
@SuppressWarnings("unchecked") final Map<String, Object> values = (Map<String, Object>) field.getCustomData().get(CustomDataKeys.COLUMN_FIELD);
if (values.keySet().contains("nullable") && (Boolean) values.get("nullable") == false) {
fieldElement.setAttribute("required", "true");
}
}
// Disable form binding for nested fields (mainly PKs)
if (field.getFieldName().getSymbolName().contains(".")) {
fieldElement.setAttribute("disableFormBinding", "true");
}
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class RepositoryJpaCustomImplMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final RepositoryJpaCustomImplAnnotationValues annotationValues = new RepositoryJpaCustomImplAnnotationValues(governorPhysicalTypeMetadata);
// Getting repository custom
JavaType repositoryCustom = annotationValues.getRepository();
// Validate that contains repository interface
Validate.notNull(repositoryCustom, "ERROR: You need to specify interface repository to be implemented.");
ClassOrInterfaceTypeDetails repositoryDetails = getTypeLocationService().getTypeDetails(repositoryCustom);
AnnotationMetadata repositoryCustomAnnotation = repositoryDetails.getAnnotation(ROO_REPOSITORY_JPA_CUSTOM);
Validate.notNull(repositoryCustomAnnotation, "ERROR: Repository interface should be annotated with @RooJpaRepositoryCustom");
AnnotationAttributeValue<JavaType> entityAttribute = repositoryCustomAnnotation.getAttribute("entity");
Validate.notNull(entityAttribute, "ERROR: Repository interface should be contain an entity on @RooJpaRepositoryCustom annotation");
JavaType entity = entityAttribute.getValue();
RepositoryJpaMetadata repositoryMetadata = getRepositoryJpaLocator().getRepositoryMetadata(entity);
if (repositoryMetadata == null) {
// Can't generate it jet
return null;
}
// Register downstream dependency for RepositoryJpaCustomImplMetadata to update projection
// finders implementations
String repositoryCustomMetadataKey = RepositoryJpaCustomMetadata.createIdentifier(repositoryDetails);
registerDependency(repositoryCustomMetadataKey, metadataIdentificationString);
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
// Check if default return type is a Projection
JavaType returnType = repositoryMetadata.getDefaultReturnType();
ClassOrInterfaceTypeDetails returnTypeDetails = getTypeLocationService().getTypeDetails(returnType);
AnnotationMetadata entityProjectionAnnotation = returnTypeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
boolean returnTypeIsProjection = entityProjectionAnnotation != null;
// Get projection constructor fields from @RooEntityProjection and add it to a Map with
// domain type's variable names
Map<JavaType, List<Pair<String, String>>> typesFieldMaps = new LinkedHashMap<JavaType, List<Pair<String, String>>>();
Map<JavaType, Boolean> typesAreProjections = new HashMap<JavaType, Boolean>();
if (returnTypeIsProjection) {
buildFieldNamesMap(entity, returnType, entityProjectionAnnotation, typesFieldMaps);
typesAreProjections.put(returnType, true);
}
final RepositoryJpaCustomMetadata repositoryCustomMetadata = getMetadataService().get(repositoryCustomMetadataKey);
// Prevent empty metadata
if (repositoryCustomMetadata == null) {
return null;
}
// Getting java bean metadata
final String javaBeanMetadataKey = JavaBeanMetadata.createIdentifier(entityDetails);
// Getting jpa entity metadata
final String jpaEntityMetadataKey = JpaEntityMetadata.createIdentifier(entityDetails);
JpaEntityMetadata entityMetadata = getMetadataService().get(jpaEntityMetadataKey);
// Create dependency between repository and java bean annotation
registerDependency(javaBeanMetadataKey, metadataIdentificationString);
// Create dependency between repository and jpa entity annotation
registerDependency(jpaEntityMetadataKey, metadataIdentificationString);
// Getting entity properties
MemberDetails entityMemberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), entityDetails);
// Getting valid fields to construct the findAll query
List<FieldMetadata> validFields = new ArrayList<FieldMetadata>();
loadValidFields(entityMemberDetails, entityMetadata, validFields);
// Getting all necessary information about referencedFields
Map<FieldMetadata, MethodMetadata> referencedFieldsMethods = repositoryCustomMetadata.getReferencedFieldsFindAllMethods();
Map<FieldMetadata, String> referencedFieldsIdentifierNames = new HashMap<FieldMetadata, String>();
List<Pair<MethodMetadata, PartTree>> customFinderMethods = repositoryCustomMetadata.getCustomFinderMethods();
List<Pair<MethodMetadata, PartTree>> customCountMethods = repositoryCustomMetadata.getCustomCountMethods();
if (customCountMethods == null) {
customCountMethods = new ArrayList<Pair<MethodMetadata, PartTree>>();
}
for (Entry<FieldMetadata, MethodMetadata> referencedFields : referencedFieldsMethods.entrySet()) {
// Get identifier field name in path format
String fieldPathName = String.format("%s.%s", StringUtils.uncapitalize(entity.getSimpleTypeName()), referencedFields.getKey().getFieldName().getSymbolNameUnCapitalisedFirstLetter());
// Put keys and values in map
referencedFieldsIdentifierNames.put(referencedFields.getKey(), fieldPathName);
}
// Add valid entity fields to mappings
Map<JavaType, Map<String, FieldMetadata>> typesFieldsMetadataMap = new HashMap<JavaType, Map<String, FieldMetadata>>();
Map<String, FieldMetadata> entityFieldMetadata = new LinkedHashMap<String, FieldMetadata>();
List<Pair<String, String>> entityFieldMappings = new ArrayList<Pair<String, String>>();
typesAreProjections.put(entity, false);
for (FieldMetadata field : validFields) {
entityFieldMetadata.put(field.getFieldName().getSymbolName(), field);
entityFieldMappings.add(Pair.of(field.getFieldName().getSymbolName(), StringUtils.uncapitalize(entity.getSimpleTypeName()).concat(".").concat(field.getFieldName().getSymbolName())));
}
typesFieldsMetadataMap.put(entity, entityFieldMetadata);
typesFieldMaps.put(entity, entityFieldMappings);
// Make a list with all domain types, excepting entities
List<JavaType> domainTypes = new ArrayList<JavaType>();
domainTypes.add(returnType);
for (Pair<MethodMetadata, PartTree> methodInfo : customFinderMethods) {
// Get finder return type from first parameter of method return type (Page)
JavaType finderReturnType = getDomainTypeOfFinderMethod(methodInfo.getKey());
domainTypes.add(finderReturnType);
// If type is a DTO, add finder fields to mappings
JavaType parameterType = methodInfo.getKey().getParameterTypes().get(0).getJavaType();
typesAreProjections.put(parameterType, false);
}
// Add typesFieldMaps for each projection finder and check for id fields
for (JavaType type : domainTypes) {
// Check if projection fields has been added already
if (typesFieldMaps.containsKey(type)) {
continue;
}
// Build Map with FieldMetadata of each projection
ClassOrInterfaceTypeDetails typeDetails = getTypeLocationService().getTypeDetails(type);
if (typeDetails == null) {
LOGGER.warning("Detail not found for type: " + type);
continue;
}
List<FieldMetadata> typeFieldList = getMemberDetailsScanner().getMemberDetails(this.getClass().getName(), typeDetails).getFields();
Map<String, FieldMetadata> fieldMetadataMap = new LinkedHashMap<String, FieldMetadata>();
for (FieldMetadata field : typeFieldList) {
fieldMetadataMap.put(field.getFieldName().getSymbolName(), field);
}
typesFieldsMetadataMap.put(type, fieldMetadataMap);
AnnotationMetadata projectionAnnotation = typeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
if (projectionAnnotation != null) {
typesAreProjections.put(type, true);
// Type is a Projection
JavaType associatedEntity = (JavaType) projectionAnnotation.getAttribute("entity").getValue();
// Add fields to typesFieldMaps
buildFieldNamesMap(associatedEntity, type, projectionAnnotation, typesFieldMaps);
}
}
return new RepositoryJpaCustomImplMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, entity, entityMetadata, entityMetadata.getCurrentIndentifierField(), validFields, repositoryCustomMetadata.getCurrentFindAllGlobalSearchMethod(), repositoryCustomMetadata.getCurrentFindAllByIdsInGlobalSearchMethod(), repositoryCustomMetadata.getDefaultReturnType(), referencedFieldsMethods, referencedFieldsIdentifierNames, typesFieldMaps, customFinderMethods, customCountMethods, typesFieldsMetadataMap, typesAreProjections);
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class RepositoryJpaOperationsImpl method addRepository.
@Override
public void addRepository(JavaType interfaceType, final JavaType domainType, JavaType defaultReturnType, boolean failOnComposition) {
Validate.notNull(domainType, "ERROR: You must specify a valid Entity. ");
if (getProjectOperations().isMultimoduleProject()) {
Validate.notNull(interfaceType, "ERROR: You must specify an interface repository type on multimodule projects.");
Validate.notNull(interfaceType.getModule(), "ERROR: interfaceType module is required on multimodule projects.");
} else if (interfaceType == null) {
interfaceType = new JavaType(String.format("%s.repository.%sRepository", getProjectOperations().getFocusedTopLevelPackage(), domainType.getSimpleTypeName()), "");
}
// Check if entity provided type is annotated with @RooJpaEntity
ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(domainType);
AnnotationMetadata entityAnnotation = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY);
// Show an error indicating that entity should be annotated with
// @RooJpaEntity
Validate.notNull(entityAnnotation, "ERROR: Provided entity should be annotated with @RooJpaEntity");
if (!shouldGenerateRepository(entityDetails)) {
if (failOnComposition) {
throw new IllegalArgumentException("%s is child part of a composition relation. Can't create repository (entity should be handle in parent part)");
} else {
// Nothing to do: silently exit
return;
}
}
if (defaultReturnType != null) {
ClassOrInterfaceTypeDetails defaultReturnTypeDetails = getTypeLocationService().getTypeDetails(defaultReturnType);
AnnotationMetadata defaultReturnTypeAnnotation = defaultReturnTypeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
// Show an error indicating that defaultReturnType should be annotated with
// @RooEntityProjection
Validate.notNull(defaultReturnTypeAnnotation, "ERROR: Provided defaultReturnType should be annotated with @RooEntityProjection");
}
// Check if the new interface to be created already exists
final String interfaceIdentifier = getPathResolver().getCanonicalPath(interfaceType.getModule(), Path.SRC_MAIN_JAVA, interfaceType);
if (getFileManager().exists(interfaceIdentifier)) {
// Type already exists - return.
LOGGER.log(Level.INFO, String.format("INFO: The repository '%s' already exists.", interfaceType.getSimpleTypeName()));
return;
}
// Check if already exists a repository that manage current entity
// Only one repository per entity is allowed
Set<ClassOrInterfaceTypeDetails> existingRepositories = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_REPOSITORY_JPA);
for (ClassOrInterfaceTypeDetails existingRepository : existingRepositories) {
AnnotationAttributeValue<Object> relatedEntity = existingRepository.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA).getAttribute("entity");
if (relatedEntity.getValue().equals(domainType)) {
LOGGER.log(Level.INFO, String.format("INFO: Already exists a repository associated to the entity '%s'. Only one repository per entity is allowed.", domainType.getSimpleTypeName()));
return;
}
}
// Add Springlets base repository class
addRepositoryConfigurationClass();
// Check if current entity is defined as "readOnly".
AnnotationAttributeValue<Boolean> readOnlyAttr = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY).getAttribute("readOnly");
boolean readOnly = readOnlyAttr != null && readOnlyAttr.getValue() ? true : false;
if (readOnly) {
// If is readOnly entity, generates common ReadOnlyRepository interface
generateReadOnlyRepository(interfaceType.getPackage());
}
// Generates repository interface
addRepositoryInterface(interfaceType, domainType, entityDetails, interfaceIdentifier, defaultReturnType);
// By default, generate RepositoryCustom interface and its
// implementation that allow developers to include its dynamic queries
// using QueryDSL
addRepositoryCustom(domainType, interfaceType, interfaceType.getPackage());
// Add dependencies between modules
getProjectOperations().addModuleDependency(interfaceType.getModule(), domainType.getModule());
// Add dependencies and plugins
generateConfiguration(interfaceType, domainType);
}
use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.
the class RepositoryJpaOperationsImpl method generateRepositoryCustomImpl.
/**
* Method that generates RepositoryCustom implementation on current package.
* If this RepositoryCustom implementation already exists in this or other
* package, will not be generated.
*
* @param interfaceType
* @param repository
* @param entity
* @return JavaType with existing or new RepositoryCustom implementation
*/
private JavaType generateRepositoryCustomImpl(JavaType interfaceType, JavaType repository, JavaType entity) {
// Getting RepositoryCustomImpl JavaType
JavaType implType = new JavaType(repository.getFullyQualifiedTypeName().concat("Impl"), repository.getModule());
// Check if new class exists yet
final String implIdentifier = getPathResolver().getCanonicalPath(implType.getModule(), Path.SRC_MAIN_JAVA, implType);
if (getFileManager().exists(implIdentifier)) {
// Type already exists - return
return implType;
}
// Check if already exists some class annotated with
// @RooJpaRepositoryCustomImpl
// that implements the same repositoryCustom interface.
Set<JavaType> repositoriesCustomImpl = getTypeLocationService().findTypesWithAnnotation(RooJavaType.ROO_REPOSITORY_JPA_CUSTOM_IMPL);
if (!repositoriesCustomImpl.isEmpty()) {
Iterator<JavaType> it = repositoriesCustomImpl.iterator();
while (it.hasNext()) {
JavaType repositoryCustom = it.next();
ClassOrInterfaceTypeDetails repositoryDetails = getTypeLocationService().getTypeDetails(repositoryCustom);
AnnotationMetadata annotation = repositoryDetails.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA_CUSTOM_IMPL);
AnnotationAttributeValue<JavaType> repositoryType = annotation.getAttribute("repository");
if (repositoryType.getValue().equals(interfaceType)) {
return repositoryType.getValue();
}
}
}
// If not, continue creating new RepositoryCustomImpl
InputStream inputStream = null;
try {
// Use defined template
inputStream = FileUtils.getInputStream(getClass(), "RepositoryCustomImpl-template._java");
String input = IOUtils.toString(inputStream);
// Replacing package
input = input.replace("__PACKAGE__", implType.getPackage().getFullyQualifiedPackageName());
// Replacing entity import
input = input.replace("__ENTITY_IMPORT__", entity.getFullyQualifiedTypeName());
// Replacing interface .class
input = input.replace("__REPOSITORY_CUSTOM_INTERFACE__", interfaceType.getSimpleTypeName());
// Replacing class name
input = input.replaceAll("__REPOSITORY_CUSTOM_IMPL__", implType.getSimpleTypeName());
// Replacing entity name
input = input.replace("__ENTITY_NAME__", entity.getSimpleTypeName());
// Creating RepositoryCustomImpl class
getFileManager().createOrUpdateTextFileIfRequired(implIdentifier, input, false);
} catch (final IOException e) {
throw new IllegalStateException(String.format("Unable to create '%s'", implIdentifier), e);
} finally {
IOUtils.closeQuietly(inputStream);
}
return implType;
}
Aggregations