use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class FieldCommands method checkFieldExists.
/**
* Checks if entity has already a field with the same name and throws an exception
* in that case.
*
* @param fieldName
* @param shellContext
* @param javaTypeDetails
*
* @deprecated this should be done by operation class (see JpaFieldCreatorProvider.checkFieldExists)
*/
private void checkFieldExists(final JavaSymbolName fieldName, ShellContext shellContext, final ClassOrInterfaceTypeDetails javaTypeDetails) {
MemberDetails memberDetails = memberDetailsScanner.getMemberDetails(this.getClass().getName(), javaTypeDetails);
List<FieldMetadata> fields = memberDetails.getFields();
for (FieldMetadata field : fields) {
if (field.getFieldName().equals(fieldName) && !shellContext.isForce()) {
throw new IllegalArgumentException(String.format("Field '%s' already exists and cannot be created. Try to use a " + "different field name on --fieldName parameter or use --force parameter to overwrite it.", fieldName));
}
}
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class JpaDataOnDemandCreator method createEntityFactory.
@Override
public JavaType createEntityFactory(JavaType currentEntity) {
Validate.notNull(currentEntity, "Entity to produce a data on demand provider for is required");
// Verify the requested entity actually exists as a class and is not
// abstract
final ClassOrInterfaceTypeDetails cid = getEntityDetails(currentEntity);
Validate.isTrue(cid.getPhysicalTypeCategory() == PhysicalTypeCategory.CLASS, "Type %s is not a class", currentEntity.getFullyQualifiedTypeName());
Validate.isTrue(!Modifier.isAbstract(cid.getModifier()), "Type %s is abstract", currentEntity.getFullyQualifiedTypeName());
// Check if the requested entity is a JPA @Entity
final MemberDetails memberDetails = memberDetailsScanner.getMemberDetails(JpaDataOnDemandCreator.class.getName(), cid);
final AnnotationMetadata entityAnnotation = memberDetails.getAnnotation(ENTITY);
Validate.isTrue(entityAnnotation != null, "Type %s must be a JPA entity type", currentEntity.getFullyQualifiedTypeName());
// Get related entities
List<JavaType> entities = getEntityAndRelatedEntitiesList(currentEntity);
// Get test Path for module
final LogicalPath path = LogicalPath.getInstance(Path.SRC_TEST_JAVA, currentEntity.getModule());
JavaType currentEntityFactory = null;
for (JavaType entity : entities) {
// Create the JavaType for the configuration class
JavaType factoryClass = new JavaType(String.format("%s.dod.%sFactory", entity.getPackage().getFullyQualifiedPackageName(), entity.getSimpleTypeName()), entity.getModule());
final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(factoryClass, path);
if (metadataService.get(declaredByMetadataId) != null) {
// The file already exists
continue;
}
// Create the CID builder
ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(declaredByMetadataId, Modifier.PUBLIC, factoryClass, PhysicalTypeCategory.CLASS);
// Add @RooEntityFactory annotation
AnnotationMetadataBuilder entityFactoryAnnotation = new AnnotationMetadataBuilder(RooJavaType.ROO_JPA_ENTITY_FACTORY);
entityFactoryAnnotation.addClassAttribute("entity", entity);
cidBuilder.addAnnotation(entityFactoryAnnotation);
// Write changes to disk
typeManagementService.createOrUpdateTypeOnDisk(cidBuilder.build());
// First entity is current entity
if (currentEntityFactory == null) {
currentEntityFactory = cidBuilder.getName();
}
}
return currentEntityFactory;
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class JpaDataOnDemandMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String dodMetadataId, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
if (layerService == null) {
layerService = getLayerService();
}
Validate.notNull(layerService, "LayerService is required");
// We need to parse the annotation, which we expect to be present
final JpaDataOnDemandAnnotationValues annotationValues = new JpaDataOnDemandAnnotationValues(governorPhysicalTypeMetadata);
final JavaType entity = annotationValues.getEntity();
if (!annotationValues.isAnnotationFound() || entity == null) {
return null;
}
// Remember that this entity JavaType matches up with this DOD's
// metadata identification string
// Start by clearing the previous association
final JavaType oldEntity = dodMidToEntityMap.get(dodMetadataId);
if (oldEntity != null) {
entityToDodMidMap.remove(oldEntity);
}
entityToDodMidMap.put(annotationValues.getEntity(), dodMetadataId);
dodMidToEntityMap.put(dodMetadataId, annotationValues.getEntity());
final JavaType identifierType = getPersistenceMemberLocator().getIdentifierType(entity);
if (identifierType == null) {
return null;
}
final MemberDetails memberDetails = getMemberDetails(entity);
if (memberDetails == null) {
return null;
}
// Get associated factory class (factory for current associated entity)
Set<ClassOrInterfaceTypeDetails> entityFactoryClasses = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY_FACTORY);
JpaEntityFactoryMetadata entityFactoryMetadata = null;
for (ClassOrInterfaceTypeDetails cid : entityFactoryClasses) {
if (((JavaType) cid.getAnnotation(RooJavaType.ROO_JPA_ENTITY_FACTORY).getAttribute("entity").getValue()).equals(entity)) {
String entityFactoryIdentifier = JpaEntityFactoryMetadata.createIdentifier(cid);
// Register dependency between EntityFactoryMetadata and DataOnDemandMetadata
registerDependency(entityFactoryIdentifier, dodMetadataId);
// Obtain related entity EntityFactoryMetadata
entityFactoryMetadata = getMetadataService().get(entityFactoryIdentifier);
break;
}
}
if (entityFactoryMetadata == null) {
return null;
}
// Register JpaDataOndDemandConfiguration as downstream dependency
Set<ClassOrInterfaceTypeDetails> dataOnDemandConfigurationClasses = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_DATA_ON_DEMAND_CONFIGURATION);
if (dataOnDemandConfigurationClasses.isEmpty()) {
return null;
}
ClassOrInterfaceTypeDetails jpaDataOnDemandConfigurationDetails = dataOnDemandConfigurationClasses.iterator().next();
String dodConfigurationId = JpaDataOnDemandConfigurationMetadata.createIdentifier(jpaDataOnDemandConfigurationDetails);
registerDependency(dodMetadataId, dodConfigurationId);
return new JpaDataOnDemandMetadata(dodMetadataId, aspectName, governorPhysicalTypeMetadata, annotationValues, entityFactoryMetadata);
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class JpaFieldCreatorProvider method createEmbeddedField.
@Override
public void createEmbeddedField(JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, boolean permitReservedWords, List<AnnotationMetadataBuilder> extraAnnotations) {
// Check if the requested entity is a JPA @Entity
final ClassOrInterfaceTypeDetails javaTypeDetails = typeLocationService.getTypeDetails(typeName);
Validate.notNull(javaTypeDetails, "The type specified, '%s', doesn't exist", typeName);
final String physicalTypeIdentifier = javaTypeDetails.getDeclaredByMetadataId();
final PhysicalTypeMetadata targetTypeMetadata = (PhysicalTypeMetadata) metadataService.get(physicalTypeIdentifier);
Validate.notNull(targetTypeMetadata, "The specified target '--class' does not exist or can not be found. Please create this type first.");
final PhysicalTypeDetails targetPtd = targetTypeMetadata.getMemberHoldingTypeDetails();
Validate.isInstanceOf(MemberHoldingTypeDetails.class, targetPtd);
final ClassOrInterfaceTypeDetails targetTypeCid = (ClassOrInterfaceTypeDetails) targetPtd;
final MemberDetails memberDetails = memberDetailsScanner.getMemberDetails(this.getClass().getName(), targetTypeCid);
Validate.isTrue(memberDetails.getAnnotation(ENTITY) != null || memberDetails.getAnnotation(PERSISTENT) != null, "The field embedded command is only applicable to JPA @Entity or Spring Data @Persistent target types.");
final EmbeddedField fieldDetails = new EmbeddedField(physicalTypeIdentifier, fieldType, fieldName);
if (extraAnnotations != null && !extraAnnotations.isEmpty()) {
fieldDetails.addAnnotations(extraAnnotations);
}
insertField(fieldDetails, permitReservedWords, false);
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class JpaFieldCreatorProvider method createCollectionField.
/**
* Implementation for {@link #createSetField(JavaType, JavaType, JavaSymbolName, Cardinality, Cascade[], boolean, Integer, Integer, JavaSymbolName, Fetch, String, String, String, String, String, String, boolean, Boolean, Boolean, boolean)}
* and
* {@link #createListField(ClassOrInterfaceTypeDetails, Cardinality, JavaType, JavaType, JavaSymbolName, Cascade, boolean, boolean, Integer, Integer, JavaSymbolName, Fetch, String, String, String, String, String, String, boolean, boolean)}
*
* @param typeName
* @param fieldType
* @param fieldName
* @param cardinality
* @param cascadeType
* @param notNull
* @param sizeMin
* @param sizeMax
* @param mappedBy
* @param fetch
* @param comment
* @param joinColumnName
* @param referencedColumnName
* @param joinTable
* @param joinColumns
* @param referencedColumns
* @param inverseJoinColumns
* @param inverseReferencedColumns
* @param permitReservedWords
* @param aggregation
* @param orphanRemoval
* @param isForce
* @param isList true generates List, false generates Set
* @param formatExpression
* @param formatMessage
*/
public void createCollectionField(JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, Cardinality cardinality, Cascade[] cascadeType, boolean notNull, Integer sizeMin, Integer sizeMax, JavaSymbolName mappedBy, Fetch fetch, String comment, String joinColumnName, String referencedColumnName, String joinTable, String joinColumns, String referencedColumns, String inverseJoinColumns, String inverseReferencedColumns, boolean permitReservedWords, Boolean aggregation, Boolean orphanRemoval, boolean isForce, boolean isList, String formatExpression, String formatMessage) {
// Check if property 'spring.roo.jpa.require.schema-object-name' is defined
// on
// project settings
String requiredSchemaObjectName = projectSettings.getProperty(SPRING_ROO_JPA_REQUIRE_SCHEMA_OBJECT_NAME);
// 'joinTable' or 'joinColumnName' is required if property is true
if (requiredSchemaObjectName != null && requiredSchemaObjectName.equals(TRUE) && joinTable == null && joinColumnName == null) {
throw new IllegalArgumentException("You must specify one of: 'joinTable' or 'joinColumnName'");
}
final ClassOrInterfaceTypeDetails childCid = typeLocationService.getTypeDetails(fieldType);
final ClassOrInterfaceTypeDetails parentCid = typeLocationService.getTypeDetails(typeName);
Validate.notNull(parentCid, "The type specified, '%s', doesn't exist", typeName);
Validate.notNull(childCid, "The specified target '--type' does not exist or can not be found. Please create this type first.", fieldType);
// Check if parent field exist
checkFieldExists(fieldName, isForce, parentCid, "fieldName");
// Check if the requested entity is a JPA @Entity
final MemberDetails childMemberDetails = memberDetailsScanner.getMemberDetails(this.getClass().getName(), childCid);
final AnnotationMetadata entityAnnotation = childMemberDetails.getAnnotation(ENTITY);
final AnnotationMetadata persistentAnnotation = childMemberDetails.getAnnotation(PERSISTENT);
boolean isEnumeration = false;
if (childCid.getPhysicalTypeCategory() == PhysicalTypeCategory.ENUMERATION) {
isEnumeration = true;
} else if (entityAnnotation != null || persistentAnnotation != null) {
// Target is JPA entity
} else {
throw new IllegalStateException("The field set command is only applicable to enum, JPA @Entity or Spring Data @Persistence elements");
}
if (isEnumeration) {
// Enumeration
createCollectionEnumeration(parentCid, fieldType, fieldName, permitReservedWords, sizeMin, sizeMax, comment, notNull, false);
} else {
if (mappedBy == null) {
// generate mappedBy name from uncapitalized parentClass name
if (cardinality == Cardinality.MANY_TO_MANY) {
// Get plural
mappedBy = new JavaSymbolName(StringUtils.uncapitalize(pluralService.getPlural(parentCid)));
} else {
mappedBy = new JavaSymbolName(StringUtils.uncapitalize(parentCid.getType().getSimpleTypeName()));
}
}
// Check that child 'mappedBy' field isn't equal to child type name uncapitalized
Validate.isTrue(!StringUtils.uncapitalize(fieldType.getSimpleTypeName()).equals(mappedBy.getSymbolName()), "Child entity field can not have the same name as the referenced entity ('%s') name in " + "lower camel case ('%s'). Please assign it other value using '--mappedBy' option.", fieldType.getSimpleTypeName(), mappedBy.getSymbolName());
if (fetch == null) {
fetch = Fetch.LAZY;
}
switch(cardinality) {
case ONE_TO_MANY:
createParentFieldOfToManyRelation(parentCid, childCid, fieldName, fieldType, Cardinality.ONE_TO_MANY, permitReservedWords, sizeMin, sizeMax, comment, notNull, mappedBy, fetch, aggregation, orphanRemoval, cascadeType, isList);
createChildFieldOfOneToManyRelation(childCid, typeName, permitReservedWords, mappedBy, fetch, joinColumnName, referencedColumnName, joinTable, joinColumns, referencedColumns, inverseJoinColumns, inverseReferencedColumns, formatExpression, formatMessage);
break;
case MANY_TO_MANY:
createParentFieldOfToManyRelation(parentCid, childCid, fieldName, fieldType, Cardinality.MANY_TO_MANY, permitReservedWords, sizeMin, sizeMax, comment, notNull, mappedBy, fetch, aggregation, orphanRemoval, cascadeType, isList);
createChildFieldOfManyToManyRelation(childCid, typeName, permitReservedWords, mappedBy, fetch, joinTable, joinColumns, referencedColumns, inverseJoinColumns, inverseReferencedColumns, isList);
break;
default:
throw new IllegalArgumentException("Cardinality must be ONE_TO_MANY or MANY_TO_MANY for the field set command");
}
// Add factory class for child entity if required
createChildEntityFactory(fieldType, typeName);
}
}
Aggregations