use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class ToStringMetadataProviderImpl method getMetadata.
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
final ToStringAnnotationValues annotationValues = new ToStringAnnotationValues(governorPhysicalTypeMetadata);
if (!annotationValues.isAnnotationFound()) {
return null;
}
final MemberDetails memberDetails = getMemberDetails(governorPhysicalTypeMetadata);
if (memberDetails == null || memberDetails.getFields().isEmpty()) {
return null;
}
AnnotationMetadata javaBeanAnnotation = memberDetails.getAnnotation(ROO_JAVA_BEAN);
if (javaBeanAnnotation != null) {
// Return an empty metadata as @RooJavaBean do the work
return new ToStringMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, new ArrayList<FieldMetadata>(), true);
}
// Exclude fields which are in superclass
List<FieldMetadata> toStringFields = getToStringFields(governorPhysicalTypeMetadata, memberDetails.getFields());
return new ToStringMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, toStringFields, false);
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class SeleniumOperationsImpl method generateTest.
/**
* Creates a new Selenium testcase
*
* @param controller the JavaType of the controller under test (required)
* @param name the name of the test case (optional)
* @param serverURL the URL of the Selenium server (optional)
*/
@Override
public void generateTest(final JavaType controller, String name, String serverURL) {
Validate.notNull(controller, "Controller type required");
final ClassOrInterfaceTypeDetails controllerTypeDetails = typeLocationService.getTypeDetails(controller);
Validate.notNull(controllerTypeDetails, "Class or interface type details for type '%s' could not be resolved", controller);
final LogicalPath path = PhysicalTypeIdentifier.getPath(controllerTypeDetails.getDeclaredByMetadataId());
final String webScaffoldMetadataIdentifier = WebScaffoldMetadata.createIdentifier(controller, path);
final WebScaffoldMetadata webScaffoldMetadata = (WebScaffoldMetadata) metadataService.get(webScaffoldMetadataIdentifier);
Validate.notNull(webScaffoldMetadata, "Web controller '%s' does not appear to be an automatic, scaffolded controller", controller.getFullyQualifiedTypeName());
// allow the creation of new instances for the form backing object
if (!webScaffoldMetadata.getAnnotationValues().isCreate()) {
LOGGER.warning("The controller you specified does not allow the creation of new instances of the form backing object. No Selenium tests created.");
return;
}
if (!serverURL.endsWith("/")) {
serverURL = serverURL + "/";
}
final JavaType formBackingType = webScaffoldMetadata.getAnnotationValues().getFormBackingObject();
final String relativeTestFilePath = "selenium/test-" + formBackingType.getSimpleTypeName().toLowerCase() + ".xhtml";
final String seleniumPath = pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, relativeTestFilePath);
final InputStream templateInputStream = FileUtils.getInputStream(getClass(), "selenium-template.xhtml");
Validate.notNull(templateInputStream, "Could not acquire selenium.xhtml template");
final Document document = XmlUtils.readXml(templateInputStream);
final Element root = (Element) document.getLastChild();
if (root == null || !"html".equals(root.getNodeName())) {
throw new IllegalArgumentException("Could not parse selenium test case template file!");
}
name = name != null ? name : "Selenium test for " + controller.getSimpleTypeName();
XmlUtils.findRequiredElement("/html/head/title", root).setTextContent(name);
XmlUtils.findRequiredElement("/html/body/table/thead/tr/td", root).setTextContent(name);
final Element tbody = XmlUtils.findRequiredElement("/html/body/table/tbody", root);
tbody.appendChild(openCommand(document, serverURL + projectOperations.getProjectName(projectOperations.getFocusedModuleName()) + "/" + webScaffoldMetadata.getAnnotationValues().getPath() + "?form"));
final ClassOrInterfaceTypeDetails formBackingTypeDetails = typeLocationService.getTypeDetails(formBackingType);
Validate.notNull(formBackingType, "Class or interface type details for type '%s' could not be resolved", formBackingType);
final MemberDetails memberDetails = memberDetailsScanner.getMemberDetails(getClass().getName(), formBackingTypeDetails);
// Add composite PK identifier fields if needed
for (final FieldMetadata field : persistenceMemberLocator.getEmbeddedIdentifierFields(formBackingType)) {
final JavaType fieldType = field.getFieldType();
if (!fieldType.isCommonCollectionType() && !isSpecialType(fieldType)) {
final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(field);
final String fieldName = field.getFieldName().getSymbolName();
fieldBuilder.setFieldName(new JavaSymbolName(fieldName + "." + fieldName));
tbody.appendChild(typeCommand(document, fieldBuilder.build()));
}
}
// Add all other fields
final List<FieldMetadata> fields = webMetadataService.getScaffoldEligibleFieldMetadata(formBackingType, memberDetails, null);
for (final FieldMetadata field : fields) {
final JavaType fieldType = field.getFieldType();
if (!fieldType.isCommonCollectionType() && !isSpecialType(fieldType)) {
tbody.appendChild(typeCommand(document, field));
}
}
tbody.appendChild(clickAndWaitCommand(document, "//input[@id = 'proceed']"));
// Add verifications for all other fields
for (final FieldMetadata field : fields) {
final JavaType fieldType = field.getFieldType();
if (!fieldType.isCommonCollectionType() && !isSpecialType(fieldType)) {
tbody.appendChild(verifyTextCommand(document, formBackingType, field));
}
}
fileManager.createOrUpdateTextFileIfRequired(seleniumPath, XmlUtils.nodeToString(document), false);
manageTestSuite(relativeTestFilePath, name, serverURL);
// Install selenium-maven-plugin
installMavenPlugin();
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class WsOperationsImpl method annotateRelatedFieldsIfNeeded.
/**
* This method annotates the provided class with @RooJaxbEntity. If this class extends
* other classes, and that classes annotates other classes, etc.
* this method will annotate them.
*
* @param entityDetails
*/
private void annotateRelatedFieldsIfNeeded(ClassOrInterfaceTypeDetails entityDetails) {
// Getting details of the provided entity
MemberDetails memberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), entityDetails);
// Getting all its fields
for (FieldMetadata entityField : memberDetails.getFields()) {
// If is a relation field, should be annotated
if (entityField.getAnnotation(JpaJavaType.ONE_TO_ONE) != null || entityField.getAnnotation(JpaJavaType.ONE_TO_MANY) != null || entityField.getAnnotation(JpaJavaType.MANY_TO_ONE) != null || entityField.getAnnotation(JpaJavaType.MANY_TO_MANY) != null) {
// Getting details of the annotated field
JavaType fieldType = entityField.getFieldType();
if (fieldType.isCommonCollectionType()) {
fieldType = fieldType.getBaseType();
}
ClassOrInterfaceTypeDetails fieldDetails = getTypeLocationService().getTypeDetails(fieldType);
// If is a valid entity
if (fieldDetails != null && fieldDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY) != null) {
// Delegates in annotateClassIfNeeded to annotate the related class field
annotateClassIfNeeded(fieldDetails);
}
}
}
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class WsOperationsImpl method addSEI.
@Override
public void addSEI(JavaType service, JavaType sei, JavaType endpointClass, JavaType configClass, String profile, boolean force) {
Validate.notNull(service, "ERROR: Provide a valid service");
Validate.notNull(sei, "ERROR: Provide a valid sei");
// Check if provided service exists
ClassOrInterfaceTypeDetails serviceTypeDetails = getTypeLocationService().getTypeDetails(service);
Validate.notNull(serviceTypeDetails, "ERROR: Provide an existing service");
// Check if provided service is annotated with @RooService
AnnotationMetadata serviceAnnotation = serviceTypeDetails.getAnnotation(RooJavaType.ROO_SERVICE);
Validate.notNull(serviceAnnotation, "ERROR: Provide a valid service annotated with @RooService");
// Check if provided service has a related entity
AnnotationAttributeValue<JavaType> entityAttr = serviceAnnotation.getAttribute("entity");
Validate.notNull(entityAttr, "ERROR: The provided service is annotated with @RooService but doesn't " + "contains the 'entity' attribute");
JavaType relatedEntity = entityAttr.getValue();
Validate.notNull(relatedEntity, "ERROR: The provided service is annotated with @RooService but doesn't " + "contains a valid entity in the 'entity' attribute");
// Check if provided SEI is located in an application module
if (!isLocatedInApplicationModule(sei) && !force) {
LOGGER.log(Level.INFO, "ERROR: The provided SEI is not located in an application module.");
return;
}
// Check if the configClass is located in an application module
if (configClass != null && !isLocatedInApplicationModule(configClass) && !force) {
LOGGER.log(Level.INFO, "ERROR: The provided config class is not located in an application module.");
return;
}
// new one inside the provided SEI module using the provided SEI name and 'Endpoint' suffix.
if (endpointClass == null) {
endpointClass = new JavaType(String.format("%sEndpoint", sei.getFullyQualifiedTypeName()), sei.getModule());
}
// new one inside the provided SEI module using the provided SEI name and 'Configuration' suffix
if (configClass == null) {
configClass = new JavaType(String.format("%sConfiguration", sei.getFullyQualifiedTypeName()), sei.getModule());
}
// Check if provided configClass exists or should be generated
boolean isNewConfigClass = false;
ClassOrInterfaceTypeDetails configClassDetails = getTypeLocationService().getTypeDetails(configClass);
if (configClassDetails == null) {
isNewConfigClass = true;
}
// If it have it, it should match with the provided one the provided one
if (!isNewConfigClass) {
MemberDetails configClassMemberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), configClassDetails);
AnnotationMetadata configurationAnnotation = configClassMemberDetails.getAnnotation(SpringJavaType.CONFIGURATION);
if (configurationAnnotation == null) {
LOGGER.log(Level.INFO, "ERROR: The provided class is not annotated with @Configuration so is not possible to include Web Service client configuration on it." + "Specify other configuration class that contains @Configuration annotation or specify a not existing class to generate it.");
return;
}
if (StringUtils.isNotEmpty(profile)) {
AnnotationMetadata profileAnnotation = configClassMemberDetails.getAnnotation(SpringJavaType.PROFILE);
if (profileAnnotation != null) {
String profiles = (String) profileAnnotation.getAttribute("value").getValue();
String[] definedProfiles = profiles.split(",");
boolean profileExists = false;
for (String definedProfile : definedProfiles) {
if (definedProfile.equals(profile)) {
profileExists = true;
}
}
if (!profileExists) {
LOGGER.log(Level.INFO, "ERROR: The provided configuration class doesn't work in the provided profile. " + "Use a different configuration class or use a different profile.");
return;
}
}
}
}
// Check if some the provided classes that should be generated already exists
if (getTypeLocationService().getTypeDetails(sei) != null) {
LOGGER.log(Level.INFO, "ERROR: The provided SEI already exists. Specify a different one using" + " --sei parameter.");
return;
}
if (getTypeLocationService().getTypeDetails(endpointClass) != null) {
LOGGER.log(Level.INFO, "ERROR: The provided Endpoint class already exists. Specify a different one using" + " --class parameter.");
return;
}
// Include necessary dependencies
includeDependenciesAndPluginsForSei(sei.getModule());
// Include the necessary properties using the provided profile
getApplicationConfigService().addProperty(sei.getModule(), "cxf.path", "/services", profile, true);
getApplicationConfigService().addProperty(sei.getModule(), "cxf.servlet.load-on-startup", "-1", profile, true);
// Generate the new SEI
final String seiIdentifier = getPathResolver().getCanonicalPath(sei.getModule(), Path.SRC_MAIN_JAVA, sei);
final String midSEI = PhysicalTypeIdentifier.createIdentifier(sei, getPathResolver().getPath(seiIdentifier));
ClassOrInterfaceTypeDetailsBuilder cidBuilderSEI = new ClassOrInterfaceTypeDetailsBuilder(midSEI, Modifier.PUBLIC, sei, PhysicalTypeCategory.INTERFACE);
// Create new @RooWsEndpoint annotation
AnnotationMetadataBuilder seiAnnotation = new AnnotationMetadataBuilder(new JavaType(RooSei.class));
// Including service parameter to @RooSei annotation
seiAnnotation.addClassAttribute("service", service);
// Include new @RooSei annotation
cidBuilderSEI.addAnnotation(seiAnnotation);
// Write SEI class on disk
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilderSEI.build());
// Generate the new Endpoint
final String endpointIdentifier = getPathResolver().getCanonicalPath(endpointClass.getModule(), Path.SRC_MAIN_JAVA, endpointClass);
final String midEndpoint = PhysicalTypeIdentifier.createIdentifier(endpointClass, getPathResolver().getPath(endpointIdentifier));
ClassOrInterfaceTypeDetailsBuilder cidBuilderEndpoint = new ClassOrInterfaceTypeDetailsBuilder(midEndpoint, Modifier.PUBLIC, endpointClass, PhysicalTypeCategory.CLASS);
// Create new @RooSeiImpl annotation
AnnotationMetadataBuilder endpointAnnotation = new AnnotationMetadataBuilder(new JavaType(RooSeiImpl.class));
// Include sei parameter to @RooSeiImpl annotation
endpointAnnotation.addClassAttribute("sei", sei);
// Include new @RooSeiImpl annotation
cidBuilderEndpoint.addAnnotation(endpointAnnotation);
// Include implements
cidBuilderEndpoint.addImplementsType(sei);
// Write endpoint class on disk
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilderEndpoint.build());
// If configuration class exists, check if is already annotated and update it.
// If not exists, create a new one
ClassOrInterfaceTypeDetailsBuilder cidBuilderConfig = null;
if (!isNewConfigClass) {
// Obtain builder from the existing class
cidBuilderConfig = new ClassOrInterfaceTypeDetailsBuilder(configClassDetails);
// Check if already have @RooWsEndpoints annotation
AnnotationMetadataBuilder wsEndpointsAnnotation = cidBuilderConfig.getDeclaredTypeAnnotation(RooJavaType.ROO_WS_ENDPOINTS);
if (wsEndpointsAnnotation != null) {
// Update the existing one
AnnotationAttributeValue<?> existingEndPoints = wsEndpointsAnnotation.build().getAttribute("endpoints");
List<?> values = (List<?>) existingEndPoints.getValue();
if (values != null) {
// Check if the provided endpoint exists yet in this config class
Iterator<?> it = values.iterator();
boolean alreadyManaged = false;
while (it.hasNext()) {
ClassAttributeValue existingEndPointAttr = (ClassAttributeValue) it.next();
JavaType existingEndPoint = existingEndPointAttr.getValue();
if (existingEndPoint.getFullyQualifiedTypeName().equals(endpointClass.getFullyQualifiedTypeName())) {
alreadyManaged = true;
}
}
// If endpoint already exists, show an error indicating that this endpoint is already managed
if (alreadyManaged) {
LOGGER.log(Level.INFO, "ERROR: The provided endpoint is already defined in the provided configuration class. " + "Specify some different configuration class.");
return;
} else {
// Update existing annotation with the new endPoint
Iterator<?> iterator = values.iterator();
List<AnnotationAttributeValue<?>> endpoints = new ArrayList<AnnotationAttributeValue<?>>();
while (iterator.hasNext()) {
ClassAttributeValue existingEndPoint = (ClassAttributeValue) iterator.next();
endpoints.add(existingEndPoint);
}
// Create @RooWsEndpoints annotation
ClassAttributeValue newEndpoint = new ClassAttributeValue(new JavaSymbolName("value"), endpointClass);
endpoints.add(newEndpoint);
ArrayAttributeValue<AnnotationAttributeValue<?>> newEndpoints = new ArrayAttributeValue<AnnotationAttributeValue<?>>(new JavaSymbolName("endpoints"), endpoints);
wsEndpointsAnnotation.addAttribute(newEndpoints);
}
}
} else {
// If not exists, add it with the new elements
wsEndpointsAnnotation = new AnnotationMetadataBuilder(new JavaType(RooWsEndpoints.class));
// Generate new list of endpoints
List<AnnotationAttributeValue<?>> endpoints = new ArrayList<AnnotationAttributeValue<?>>();
ClassAttributeValue newEndpoint = new ClassAttributeValue(new JavaSymbolName("value"), endpointClass);
endpoints.add(newEndpoint);
ArrayAttributeValue<AnnotationAttributeValue<?>> newEndpoints = new ArrayAttributeValue<AnnotationAttributeValue<?>>(new JavaSymbolName("endpoints"), endpoints);
wsEndpointsAnnotation.addAttribute(newEndpoints);
// Check if is necessary to include profile attribute
if (StringUtils.isNotEmpty(profile)) {
wsEndpointsAnnotation.addStringAttribute("profile", profile);
}
// Include new @RooWsEndpoints annotation
cidBuilderConfig.addAnnotation(wsEndpointsAnnotation);
}
} else {
// Create the specified configuration class and annotate it with necessary information
final String configClassIdentifier = getPathResolver().getCanonicalPath(configClass.getModule(), Path.SRC_MAIN_JAVA, configClass);
final String mid = PhysicalTypeIdentifier.createIdentifier(configClass, getPathResolver().getPath(configClassIdentifier));
cidBuilderConfig = new ClassOrInterfaceTypeDetailsBuilder(mid, Modifier.PUBLIC, configClass, PhysicalTypeCategory.CLASS);
// Create new @RooWsEndpoints annotation and include the new endpoint
// as endpoints attribute
List<AnnotationAttributeValue<?>> endpoints = new ArrayList<AnnotationAttributeValue<?>>();
ClassAttributeValue endPointAttributeValue = new ClassAttributeValue(new JavaSymbolName("value"), endpointClass);
endpoints.add(endPointAttributeValue);
ArrayAttributeValue<AnnotationAttributeValue<?>> newEndpoints = new ArrayAttributeValue<AnnotationAttributeValue<?>>(new JavaSymbolName("endpoints"), endpoints);
AnnotationMetadataBuilder wsEndpointsAnnotation = new AnnotationMetadataBuilder(new JavaType(RooWsEndpoints.class));
wsEndpointsAnnotation.addAttribute(newEndpoints);
// Include new @RooWsEndpoints annotation
cidBuilderConfig.addAnnotation(wsEndpointsAnnotation);
// doesn't exists yet, because we're generating a new @Configuration class
if (StringUtils.isNotEmpty(profile)) {
wsEndpointsAnnotation.addStringAttribute("profile", profile);
}
}
// Write config class on disk
getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilderConfig.build());
// After create the SEI and the Endpoint, is necessary to annotate related entity with
// some JAX-B annotations if has not been annotated before
/*ClassOrInterfaceTypeDetails entityDetails =
getTypeLocationService().getTypeDetails(relatedEntity);
if (entityDetails != null) {
// Annotate the entity with @RooJaxbEntity. If this entity has a super class or that
// super class has another super class, etc. is necessary to annotate it too.
annotateClassIfNeeded(entityDetails);
// Also, is necessary to annotate @OneToMany, @ManyToOne and @ManyToMany fields detected in
// this class and in the super classes.
annotateRelatedFieldsIfNeeded(entityDetails);
}*/
// Provisional changes to annotate all entities
Set<ClassOrInterfaceTypeDetails> allEntities = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY);
for (ClassOrInterfaceTypeDetails entity : allEntities) {
// Annotate the entity with @RooJaxbEntity. If this entity has a super class or that
// super class has another super class, etc. is necessary to annotate it too.
annotateClassIfNeeded(entity);
// Also, is necessary to annotate @OneToMany, @ManyToOne and @ManyToMany fields detected in
// this class and in the super classes.
annotateRelatedFieldsIfNeeded(entity);
}
}
use of org.springframework.roo.classpath.scanner.MemberDetails in project spring-roo by spring-projects.
the class DefaultPhysicalTypeMetadataProvider method get.
public MetadataItem get(final String metadataIdentificationString) {
if (fileManager == null) {
fileManager = getFileManager();
}
Validate.notNull(fileManager, "FileManager is required");
if (metadataDependencyRegistry == null) {
metadataDependencyRegistry = getMetadataDependencyRegistry();
}
Validate.notNull(metadataDependencyRegistry, "MetadataDependencyRegistry is required");
if (projectOperations == null) {
projectOperations = getProjectOperations();
}
Validate.notNull(projectOperations, "ProjectOperations is required");
if (typeLocationService == null) {
typeLocationService = getTypeLocationService();
}
Validate.notNull(typeLocationService, "TypeLocationService is required");
if (typeParsingService == null) {
typeParsingService = getTypeParsingService();
}
Validate.notNull(typeParsingService, "TypeParsingService is required");
Validate.isTrue(PhysicalTypeIdentifier.isValid(metadataIdentificationString), "Metadata id '%s' is not valid for this metadata provider", metadataIdentificationString);
final String canonicalPath = typeLocationService.getPhysicalTypeCanonicalPath(metadataIdentificationString);
if (StringUtils.isBlank(canonicalPath)) {
return null;
}
metadataDependencyRegistry.deregisterDependencies(metadataIdentificationString);
if (!fileManager.exists(canonicalPath)) {
// that was found but could not be parsed
return null;
}
final JavaType javaType = PhysicalTypeIdentifier.getJavaType(metadataIdentificationString);
final ClassOrInterfaceTypeDetails typeDetails = typeParsingService.getTypeAtLocation(canonicalPath, metadataIdentificationString, javaType);
if (typeDetails == null) {
return null;
}
final PhysicalTypeMetadata result = new DefaultPhysicalTypeMetadata(metadataIdentificationString, canonicalPath, typeDetails);
final ClassOrInterfaceTypeDetails details = result.getMemberHoldingTypeDetails();
if (details != null && details.getPhysicalTypeCategory() == PhysicalTypeCategory.CLASS && details.getExtendsTypes().size() == 1) {
// This is a class, and it extends another class
if (details.getSuperclass() != null) {
// We have a dependency on the superclass, and there is metadata
// available for the superclass
// We won't implement the full MetadataNotificationListener
// here, but rely on MetadataService's fallback
// (which is to evict from cache and call get again given
// JavaParserMetadataProvider doesn't implement
// MetadataNotificationListener, then notify everyone we've
// changed)
final String superclassId = details.getSuperclass().getDeclaredByMetadataId();
metadataDependencyRegistry.registerDependency(superclassId, result.getId());
} else {
// type change, in the hope we discover our parent someday
for (final LogicalPath sourcePath : projectOperations.getPathResolver().getSourcePaths()) {
final String possibleSuperclass = PhysicalTypeIdentifier.createIdentifier(details.getExtendsTypes().get(0), sourcePath);
metadataDependencyRegistry.registerDependency(possibleSuperclass, result.getId());
}
}
}
MemberDetails memberDetails = new MemberDetailsBuilder(Arrays.asList(details)).build();
// Loop until such time as we complete a full loop where no changes are
// made to the result
boolean additionalLoopRequired = true;
while (additionalLoopRequired) {
additionalLoopRequired = false;
for (final MemberDetailsDecorator decorator : decorators) {
final MemberDetails newResult = decorator.decorateTypes(DefaultPhysicalTypeMetadataProvider.class.getName(), memberDetails);
Validate.isTrue(newResult != null, "Decorator '%s' returned an illegal result", decorator.getClass().getName());
if (!newResult.equals(memberDetails)) {
additionalLoopRequired = true;
memberDetails = newResult;
}
}
}
return new DefaultPhysicalTypeMetadata(metadataIdentificationString, canonicalPath, (ClassOrInterfaceTypeDetails) memberDetails.getDetails().get(0));
}
Aggregations