/** * Retrieves text files from the classloader and displays them on-screen. * * <p>Respects normal Roo conventions such as all resources should appear under the same package as * the bundle itself etc. * * @author Ben Alex * @since 1.1.1 */ public abstract class MessageDisplayUtils { private static Logger LOGGER = HandlerUtils.getLogger(MessageDisplayUtils.class); /** * Same as {@link #displayFile(String, Class, boolean)} except it passes false as the final * argument. * * @param fileName the simple filename (required) * @param owner the class which owns the file (required) */ public static void displayFile(final String fileName, final Class<?> owner) { displayFile(fileName, owner, false); } /** * Displays the requested file via the LOGGER API. * * <p>Each file must available from the classloader of the "owner". It must also be in the same * package as the class of the "owner". So if the owner is com.foo.Bar, and the file is called * "hello.txt", the file must appear in the same bundle as com.foo.Bar and be available from the * resource path "/com/foo/Hello.txt". * * @param fileName the simple filename (required) * @param owner the class which owns the file (required) * @param important if true, it will display with a higher importance color where possible */ public static void displayFile( final String fileName, final Class<?> owner, final boolean important) { final Level level = important ? Level.SEVERE : Level.FINE; final String owningPackage = owner.getPackage().getName().replace('.', '/'); final String fullResourceName = "/" + owningPackage + "/" + fileName; final InputStream inputStream = owner.getClassLoader().getResourceAsStream(fullResourceName); if (inputStream == null) { throw new IllegalStateException("Could not locate '" + fileName + "'"); } try { final String message = FileCopyUtils.copyToString(new InputStreamReader(new BufferedInputStream(inputStream))); LOGGER.log(level, message); } catch (final Exception e) { throw new IllegalStateException(e); } finally { IOUtils.closeQuietly(inputStream); } } }
/** * Implementation of operations this add-on offers. * * @since 1.1 */ @Component // Use these Apache Felix annotations to register your commands class in the Roo // container @Service public class EnversOperationsImpl extends AbstractOperations implements EnversOperations { private static Logger LOG = HandlerUtils.getLogger(EnversCommands.class); /** * Use ProjectOperations to install new dependencies, plugins, properties, etc into the project * configuration */ @Reference private ProjectOperations projectOperations; /** Use PathResolver to get paths for copying files */ @Reference private PathResolver pathResolver; /** * Use TypeLocationService to find types which are annotated with a given annotation in the * project */ @Reference private TypeLocationService typeLocationService; /** Use TypeManagementService to change types */ @Reference private TypeManagementService typeManagementService; @Reference private MetadataService metadataService; /** {@inheritDoc} */ public boolean isCommandAvailable() { // Check if a project has been created return projectOperations.isFocusedProjectAvailable(); } /** {@inheritDoc} */ public void annotateType(final JavaType type, final JavaPackage javaPackage) { // TODO check for existing controller // Use Roo's Assert type for null checks Validate.notNull(type, "Java type required"); Validate.notNull(javaPackage, "Java package required, web mvc all command package required"); // Obtain ClassOrInterfaceTypeDetails for this java type ClassOrInterfaceTypeDetails entityDetails = typeLocationService.getTypeDetails(type); // Test if the annotation already exists on the target type if (entityDetails != null && MemberFindingUtils.getAnnotationOfType( entityDetails.getAnnotations(), new JavaType(RooEnvers.class.getName())) == null) { ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder = new ClassOrInterfaceTypeDetailsBuilder(entityDetails); // Create JavaType instance for the add-ons trigger annotation JavaType rooEnvers = new JavaType(RooEnvers.class.getName()); // Create Annotation metadata AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(rooEnvers); // Add annotation to target type classOrInterfaceTypeDetailsBuilder.addAnnotation(annotationBuilder.build()); // Save changes to disk typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build()); } // Get details for existing controller JavaType typeController = new JavaType( javaPackage.getFullyQualifiedPackageName() + "." + type.getSimpleTypeName() + "Controller"); ClassOrInterfaceTypeDetails typeControllerDetails = typeLocationService.getTypeDetails(typeController); // Add annotation @RooEnversController to existing controller ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder = new ClassOrInterfaceTypeDetailsBuilder(typeControllerDetails); JavaType rooEnversController = new JavaType("de.eightbitboy.roo.envers.controller.RooEnversController"); final List<AnnotationAttributeValue<?>> rooEnversControllerAttributes = new ArrayList<AnnotationAttributeValue<?>>(); rooEnversControllerAttributes.add(new ClassAttributeValue(new JavaSymbolName("type"), type)); AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(rooEnversController, rooEnversControllerAttributes); classOrInterfaceTypeDetailsBuilder.addAnnotation(annotationBuilder.build()); typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build()); } public void addViews(final JavaType type) { String targetPath = pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/views/"); EnversViewManager viewManager = new EnversViewManager(type, targetPath); viewManager.addViews(); } /** {@inheritDoc} */ public void setup() { // Install the add-on Google code repository needed to get the annotation // projectOperations.addRepository("", new Repository("Envers Roo add-on repository", "Envers // Roo add-on repository", "https://roo-envers.googlecode.com/svn/repo")); List<Dependency> dependencies = new ArrayList<Dependency>(); // Install the dependency on the add-on jar // TODO move this to configuration.xml ? dependencies.add( new Dependency( "de.eightbitboy.roo.envers", "de.eightbitboy.roo.envers", "0.1.0", DependencyType.JAR, DependencyScope.PROVIDED)); // Install dependencies defined in external XML file for (Element dependencyElement : XmlUtils.findElements( "/configuration/batch/dependencies/dependency", XmlUtils.getConfiguration(getClass()))) { dependencies.add(new Dependency(dependencyElement)); } // Add all new dependencies to pom.xml projectOperations.addDependencies("", dependencies); // Modify tags to create views for entity revisions this.modifyTags(); // TODO use modified tags for audited entities only } private void modifyTags() { // TODO modify tags instead of overwriting them!!! String targetPath = pathResolver.getFocusedIdentifier(Path.SRC_MAIN_WEBAPP, "/WEB-INF/tags/form/fields"); LOG.info("disabled copying of tags"); // copyDirectoryContents("tags/*.*", targetPath, true); } }
/** * Implementation of {@link MailOperationsImpl}. * * @author Stefan Schmidt * @since 1.0 */ @Component @Service public class MailOperationsImpl implements MailOperations { // Constants private static final int PRIVATE_TRANSIENT = Modifier.PRIVATE | Modifier.TRANSIENT; private static final AnnotatedJavaType STRING = new AnnotatedJavaType(JavaType.STRING); private static final String LOCAL_MESSAGE_VARIABLE = "mailMessage"; private static final String SPRING_TASK_NS = "http://www.springframework.org/schema/task"; private static final String SPRING_TASK_XSD = "http://www.springframework.org/schema/task/spring-task-3.0.xsd"; private static final String TEMPLATE_MESSAGE_FIELD = "templateMessage"; private static final Logger log = HandlerUtils.getLogger(MailOperationsImpl.class); // Fields @Reference private FileManager fileManager; @Reference private ProjectOperations projectOperations; @Reference private PropFileOperations propFileOperations; @Reference private TypeManagementService typeManagementService; @Reference private TypeLocationService typeLocationService; public boolean isInstallEmailAvailable() { return projectOperations.isProjectAvailable(); } public boolean isManageEmailAvailable() { return projectOperations.isProjectAvailable() && fileManager.exists(getApplicationContextPath()); } /** * Returns the canonical path of the user project's applicationContext.xml file. * * @return a non-blank path */ private String getApplicationContextPath() { return projectOperations .getPathResolver() .getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml"); } public void installEmail( final String hostServer, final MailProtocol protocol, final String port, final String encoding, final String username, final String password) { Assert.hasText(hostServer, "Host server name required"); final String contextPath = getApplicationContextPath(); final Document document = XmlUtils.readXml(fileManager.getInputStream(contextPath)); final Element root = document.getDocumentElement(); boolean installDependencies = true; final Map<String, String> props = new HashMap<String, String>(); Element mailBean = XmlUtils.findFirstElement( "/beans/bean[@class = 'org.springframework.mail.javamail.JavaMailSenderImpl']", root); if (mailBean != null) { root.removeChild(mailBean); installDependencies = false; } mailBean = document.createElement("bean"); mailBean.setAttribute("class", "org.springframework.mail.javamail.JavaMailSenderImpl"); mailBean.setAttribute("id", "mailSender"); final Element property = document.createElement("property"); property.setAttribute("name", "host"); property.setAttribute("value", "${email.host}"); mailBean.appendChild(property); root.appendChild(mailBean); props.put("email.host", hostServer); if (protocol != null) { final Element pElement = document.createElement("property"); pElement.setAttribute("value", "${email.protocol}"); pElement.setAttribute("name", "protocol"); mailBean.appendChild(pElement); props.put("email.protocol", protocol.getProtocol()); } if (StringUtils.hasText(port)) { final Element pElement = document.createElement("property"); pElement.setAttribute("name", "port"); pElement.setAttribute("value", "${email.port}"); mailBean.appendChild(pElement); props.put("email.port", port); } if (StringUtils.hasText(encoding)) { final Element pElement = document.createElement("property"); pElement.setAttribute("name", "defaultEncoding"); pElement.setAttribute("value", "${email.encoding}"); mailBean.appendChild(pElement); props.put("email.encoding", encoding); } if (StringUtils.hasText(username)) { final Element pElement = document.createElement("property"); pElement.setAttribute("name", "username"); pElement.setAttribute("value", "${email.username}"); mailBean.appendChild(pElement); props.put("email.username", username); } if (StringUtils.hasText(password)) { final Element pElement = document.createElement("property"); pElement.setAttribute("name", "password"); pElement.setAttribute("value", "${email.password}"); mailBean.appendChild(pElement); props.put("email.password", password); if (SMTP.equals(protocol)) { final Element javaMailProperties = document.createElement("property"); javaMailProperties.setAttribute("name", "javaMailProperties"); final Element securityProps = document.createElement("props"); javaMailProperties.appendChild(securityProps); final Element prop = document.createElement("prop"); prop.setAttribute("key", "mail.smtp.auth"); prop.setTextContent("true"); securityProps.appendChild(prop); final Element prop2 = document.createElement("prop"); prop2.setAttribute("key", "mail.smtp.starttls.enable"); prop2.setTextContent("true"); securityProps.appendChild(prop2); mailBean.appendChild(javaMailProperties); } } DomUtils.removeTextNodes(root); fileManager.createOrUpdateTextFileIfRequired( contextPath, XmlUtils.nodeToString(document), false); if (installDependencies) { updateConfiguration(); } propFileOperations.addProperties( Path.SPRING_CONFIG_ROOT, "email.properties", props, true, true); } public void configureTemplateMessage(final String from, final String subject) { final String contextPath = getApplicationContextPath(); final Document document = XmlUtils.readXml(fileManager.getInputStream(contextPath)); final Element root = document.getDocumentElement(); final Map<String, String> props = new HashMap<String, String>(); if (StringUtils.hasText(from) || StringUtils.hasText(subject)) { Element smmBean = getSimpleMailMessageBean(root); if (smmBean == null) { smmBean = document.createElement("bean"); smmBean.setAttribute("class", "org.springframework.mail.SimpleMailMessage"); smmBean.setAttribute("id", "templateMessage"); } if (StringUtils.hasText(from)) { Element smmProperty = XmlUtils.findFirstElement("//property[@name='from']", smmBean); if (smmProperty != null) { smmBean.removeChild(smmProperty); } smmProperty = document.createElement("property"); smmProperty.setAttribute("value", "${email.from}"); smmProperty.setAttribute("name", "from"); smmBean.appendChild(smmProperty); props.put("email.from", from); } if (StringUtils.hasText(subject)) { Element smmProperty = XmlUtils.findFirstElement("//property[@name='subject']", smmBean); if (smmProperty != null) { smmBean.removeChild(smmProperty); } smmProperty = document.createElement("property"); smmProperty.setAttribute("value", "${email.subject}"); smmProperty.setAttribute("name", "subject"); smmBean.appendChild(smmProperty); props.put("email.subject", subject); } root.appendChild(smmBean); DomUtils.removeTextNodes(root); fileManager.createOrUpdateTextFileIfRequired( contextPath, XmlUtils.nodeToString(document), false); } if (props.size() > 0) { propFileOperations.addProperties( Path.SPRING_CONFIG_ROOT, "email.properties", props, true, true); } } /** * Finds the SimpleMailMessage bean in the Spring XML file with the given root element * * @param root * @return <code>null</code> if there is no such bean */ private Element getSimpleMailMessageBean(final Element root) { return XmlUtils.findFirstElement( "/beans/bean[@class = 'org.springframework.mail.SimpleMailMessage']", root); } public void injectEmailTemplate( final JavaType targetType, final JavaSymbolName fieldName, final boolean async) { Assert.notNull(targetType, "Java type required"); Assert.notNull(fieldName, "Field name required"); final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); annotations.add(new AnnotationMetadataBuilder(AUTOWIRED)); // Obtain the physical type and its mutable class details final String declaredByMetadataId = PhysicalTypeIdentifier.createIdentifier(targetType); ClassOrInterfaceTypeDetails existing = typeLocationService.findClassOrInterface(targetType); if (existing == null) { log.warning( "Aborting: Unable to find metadata for target type '" + targetType.getFullyQualifiedTypeName() + "'"); return; } final ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder = new ClassOrInterfaceTypeDetailsBuilder(existing); // Add the MailSender field final FieldMetadataBuilder mailSenderFieldBuilder = new FieldMetadataBuilder( declaredByMetadataId, PRIVATE_TRANSIENT, annotations, fieldName, MAIL_SENDER); classOrInterfaceTypeDetailsBuilder.addField(mailSenderFieldBuilder.build()); // Add the "sendMessage" method classOrInterfaceTypeDetailsBuilder.addMethod( getSendMethod(fieldName, async, declaredByMetadataId, classOrInterfaceTypeDetailsBuilder)); typeManagementService.createOrUpdateTypeOnDisk(classOrInterfaceTypeDetailsBuilder.build()); } /** * Generates the "send email" method to be added to the domain type * * @param mailSenderName the name of the MailSender field (required) * @param async whether to send the email asynchronously * @param targetClassMID the MID of the class to receive the method * @param mutableTypeDetails the type to which the method is being added (required) * @return a non-<code>null</code> method */ private MethodMetadata getSendMethod( final JavaSymbolName mailSenderName, final boolean async, final String targetClassMID, final ClassOrInterfaceTypeDetailsBuilder classOrInterfaceTypeDetailsBuilder) { final String contextPath = getApplicationContextPath(); final Document document = XmlUtils.readXml(fileManager.getInputStream(contextPath)); final Element root = document.getDocumentElement(); // Make a builder for the created method's body final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); // Collect the types and names of the created method's parameters final PairList<AnnotatedJavaType, JavaSymbolName> parameters = new PairList<AnnotatedJavaType, JavaSymbolName>(); if (getSimpleMailMessageBean(root) == null) { // There's no SimpleMailMessage bean; use a local variable bodyBuilder.appendFormalLine( "org.springframework.mail.SimpleMailMessage " + LOCAL_MESSAGE_VARIABLE + " = new org.springframework.mail.SimpleMailMessage();"); // Set the from address parameters.add(STRING, new JavaSymbolName("mailFrom")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setFrom(mailFrom);"); // Set the subject parameters.add(STRING, new JavaSymbolName("subject")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setSubject(subject);"); } else { // A SimpleMailMessage bean exists; auto-wire it into the entity and use it as a template final List<AnnotationMetadataBuilder> smmAnnotations = Arrays.asList(new AnnotationMetadataBuilder(AUTOWIRED)); final FieldMetadataBuilder smmFieldBuilder = new FieldMetadataBuilder( targetClassMID, PRIVATE_TRANSIENT, smmAnnotations, new JavaSymbolName(TEMPLATE_MESSAGE_FIELD), SIMPLE_MAIL_MESSAGE); classOrInterfaceTypeDetailsBuilder.addField(smmFieldBuilder.build()); // Use the injected bean as a template (for thread safety) bodyBuilder.appendFormalLine( "org.springframework.mail.SimpleMailMessage " + LOCAL_MESSAGE_VARIABLE + " = new org.springframework.mail.SimpleMailMessage(" + TEMPLATE_MESSAGE_FIELD + ");"); } // Set the to address parameters.add(STRING, new JavaSymbolName("mailTo")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setTo(mailTo);"); // Set the message body parameters.add(STRING, new JavaSymbolName("message")); bodyBuilder.appendFormalLine(LOCAL_MESSAGE_VARIABLE + ".setText(message);"); bodyBuilder.newLine(); bodyBuilder.appendFormalLine(mailSenderName + ".send(" + LOCAL_MESSAGE_VARIABLE + ");"); final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( targetClassMID, Modifier.PUBLIC, new JavaSymbolName("sendMessage"), JavaType.VOID_PRIMITIVE, parameters.getKeys(), parameters.getValues(), bodyBuilder); if (async) { if (DomUtils.findFirstElementByName("task:annotation-driven", root) == null) { // Add asynchronous email support to the application if (!StringUtils.hasText(root.getAttribute("xmlns:task"))) { // Add the "task" namespace to the Spring config file root.setAttribute("xmlns:task", SPRING_TASK_NS); root.setAttribute( "xsi:schemaLocation", root.getAttribute("xsi:schemaLocation") + " " + SPRING_TASK_NS + " " + SPRING_TASK_XSD); } root.appendChild( new XmlElementBuilder("task:annotation-driven", document) .addAttribute("executor", "asyncExecutor") .addAttribute("mode", "aspectj") .build()); root.appendChild( new XmlElementBuilder("task:executor", document) .addAttribute("id", "asyncExecutor") .addAttribute("pool-size", "${executor.poolSize}") .build()); // Write out the new Spring config file fileManager.createOrUpdateTextFileIfRequired( contextPath, XmlUtils.nodeToString(document), false); // Update the email properties file propFileOperations.addPropertyIfNotExists( Path.SPRING_CONFIG_ROOT, "email.properties", "executor.poolSize", "10", true); } methodBuilder.addAnnotation(new AnnotationMetadataBuilder(ASYNC)); } return methodBuilder.build(); } private void updateConfiguration() { final Element configuration = XmlUtils.getConfiguration(getClass()); final List<Dependency> dependencies = new ArrayList<Dependency>(); final List<Element> emailDependencies = XmlUtils.findElements("/configuration/email/dependencies/dependency", configuration); for (final Element dependencyElement : emailDependencies) { dependencies.add(new Dependency(dependencyElement)); } projectOperations.addDependencies(dependencies); } }
/** * Implementation of {@link I18nOperations}. * * @author Sergio Clares * @author Juan Carlos García * @since 2.0 */ @Component @Service public class I18nOperationsImpl implements I18nOperations { private static final Logger LOGGER = HandlerUtils.getLogger(I18nOperationsImpl.class); // ------------ OSGi component attributes ---------------- private BundleContext context; private ServiceInstaceManager serviceInstaceManager = new ServiceInstaceManager(); protected void activate(final ComponentContext context) { this.context = context.getBundleContext(); serviceInstaceManager.activate(this.context); } @Override public boolean isInstallLanguageCommandAvailable() { return getProjectOperations().isFeatureInstalled(FeatureNames.MVC); } @Override public void installLanguage(final I18n language, final boolean useAsDefault, final Pom module) { // Check if provided module match with application modules features Validate.isTrue( getTypeLocationService().hasModuleFeature(module, ModuleFeatureName.APPLICATION), "ERROR: Provided module doesn't match with application modules features. " + "Execute this operation again and provide a valid application module."); Validate.notNull(language, "ERROR: You should provide a valid language code."); if (language.getLocale() == null) { LOGGER.warning("ERROR: Provided language is not valid."); return; } final LogicalPath resourcesPath = LogicalPath.getInstance(Path.SRC_MAIN_RESOURCES, module.getModuleName()); final String targetDirectory = getPathResolver().getIdentifier(resourcesPath, ""); // Getting message.properties file String messageBundle = ""; if (language.getLocale().equals(Locale.ENGLISH)) { messageBundle = targetDirectory + "messages.properties"; } else { messageBundle = targetDirectory .concat("messages_") .concat(language.getLocale().getLanguage().concat(".properties")); } if (!getFileManager().exists(messageBundle)) { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = language.getMessageBundle(); outputStream = getFileManager().createFile(messageBundle).getOutputStream(); IOUtils.copy(inputStream, outputStream); } catch (final Exception e) { throw new IllegalStateException( "Encountered an error during copying of message bundle MVC JSP addon.", e); } finally { IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(outputStream); } } // Install flag final String flagGraphic = targetDirectory .concat("static/public/img/") .concat(language.getLocale().getLanguage()) .concat(".png"); if (!getFileManager().exists(flagGraphic)) { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = language.getFlagGraphic(); outputStream = getFileManager().createFile(flagGraphic).getOutputStream(); IOUtils.copy(inputStream, outputStream); } catch (final Exception e) { throw new IllegalStateException( "Encountered an error during copying of flag graphic for MVC JSP addon.", e); } finally { IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(outputStream); } } // Update @WebMvcConfiguration annotation defining defaultLanguage // attribute if (useAsDefault) { // Obtain all existing configuration classes annotated with // @RooWebMvcConfiguration Set<ClassOrInterfaceTypeDetails> configurationClasses = getTypeLocationService() .findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_WEB_MVC_CONFIGURATION); for (ClassOrInterfaceTypeDetails configurationClass : configurationClasses) { // If configuration class is located in the provided module if (configurationClass.getType().getModule().equals(module.getModuleName())) { ClassOrInterfaceTypeDetailsBuilder cidBuilder = new ClassOrInterfaceTypeDetailsBuilder(configurationClass); AnnotationMetadataBuilder annotation = cidBuilder.getDeclaredTypeAnnotation(RooJavaType.ROO_WEB_MVC_CONFIGURATION); annotation.addStringAttribute("defaultLanguage", language.getLocale().getLanguage()); // Update configuration class getTypeManagementService().createOrUpdateTypeOnDisk(cidBuilder.build()); } } LOGGER.log( Level.INFO, String.format( "INFO: Default language of your project has been changed to %s.", language.getLanguage())); } // Get all controllers and update its message bundles Set<ClassOrInterfaceTypeDetails> controllers = getTypeLocationService() .findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_CONTROLLER); for (ClassOrInterfaceTypeDetails controller : controllers) { getMetadataService().evictAndGet(ControllerMetadata.createIdentifier(controller)); } // Add application property getApplicationConfigService() .addProperty( module.getModuleName(), "spring.messages.fallback-to-system-locale", "false", "", true); } /** * Add labels to all installed languages * * @param moduleName * @param labels */ @Override public void addOrUpdateLabels(String moduleName, final Map<String, String> labels) { final LogicalPath resourcesPath = LogicalPath.getInstance(Path.SRC_MAIN_RESOURCES, moduleName); final String targetDirectory = getPathResolver().getIdentifier(resourcesPath, ""); Set<I18n> supportedLanguages = getI18nSupport().getSupportedLanguages(); for (I18n i18n : supportedLanguages) { String messageBundle = String.format("messages_%s.properties", i18n.getLocale().getLanguage()); String bundlePath = String.format( "%s%s%s", targetDirectory, AntPathMatcher.DEFAULT_PATH_SEPARATOR, messageBundle); if (getFileManager().exists(bundlePath)) { getPropFilesManager().addProperties(resourcesPath, messageBundle, labels, true, false); } } // Allways update english message bundles getPropFilesManager().addProperties(resourcesPath, "messages.properties", labels, true, false); } /** * Return a list of installed languages in the provided application module. * * @param moduleName the module name to search for installed languages. * @return a list with the available languages. */ @Override public List<I18n> getInstalledLanguages(String moduleName) { final LogicalPath resourcesPath = LogicalPath.getInstance(Path.SRC_MAIN_RESOURCES, moduleName); final String targetDirectory = getPathResolver().getIdentifier(resourcesPath, ""); // Create list for installed languages List<I18n> installedLanguages = new ArrayList<I18n>(); // Get all available languages Set<I18n> supportedLanguages = getI18nSupport().getSupportedLanguages(); for (I18n i18n : supportedLanguages) { String messageBundle = String.format("messages_%s.properties", i18n.getLocale().getLanguage()); String bundlePath = String.format( "%s%s%s", targetDirectory, AntPathMatcher.DEFAULT_PATH_SEPARATOR, messageBundle); if (getFileManager().exists(bundlePath)) { installedLanguages.add(i18n); } } // Always add English language as default installedLanguages.add(new EnglishLanguage()); return Collections.unmodifiableList(installedLanguages); } /** * This method gets all implementations of ControllerMVCResponseService interface to be able to * locate all ControllerMVCResponseService. Uses param installed to obtain only the installed or * not installed response types. * * @param installed indicates if returned responseType should be installed or not. * @return Map with responseTypes identifier and the ControllerMVCResponseService implementation */ private List<ControllerMVCResponseService> getControllerMVCResponseTypes(boolean installed) { List<ControllerMVCResponseService> responseTypes = new ArrayList<ControllerMVCResponseService>(); try { ServiceReference<?>[] references = this.context.getAllServiceReferences(ControllerMVCResponseService.class.getName(), null); for (ServiceReference<?> ref : references) { ControllerMVCResponseService responseTypeService = (ControllerMVCResponseService) this.context.getService(ref); boolean isAbleToInstall = false; for (Pom module : getProjectOperations().getPoms()) { if (responseTypeService.isInstalledInModule(module.getModuleName()) == installed) { isAbleToInstall = true; break; } } if (isAbleToInstall) { responseTypes.add(responseTypeService); } } return responseTypes; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load ControllerMVCResponseService on I18nOperationsImpl."); return null; } } // Get OSGi services private TypeLocationService getTypeLocationService() { return serviceInstaceManager.getServiceInstance(this, TypeLocationService.class); } private I18nSupport getI18nSupport() { return serviceInstaceManager.getServiceInstance(this, I18nSupport.class); } private PathResolver getPathResolver() { return serviceInstaceManager.getServiceInstance(this, PathResolver.class); } private FileManager getFileManager() { return serviceInstaceManager.getServiceInstance(this, FileManager.class); } private ProjectOperations getProjectOperations() { return serviceInstaceManager.getServiceInstance(this, ProjectOperations.class); } private PropFilesManagerService getPropFilesManager() { return serviceInstaceManager.getServiceInstance(this, PropFilesManagerService.class); } public ApplicationConfigService getApplicationConfigService() { return serviceInstaceManager.getServiceInstance(this, ApplicationConfigService.class); } public MetadataService getMetadataService() { return serviceInstaceManager.getServiceInstance(this, MetadataService.class); } public TypeManagementService getTypeManagementService() { return serviceInstaceManager.getServiceInstance(this, TypeManagementService.class); } public PluralService getPluralService() { return serviceInstaceManager.getServiceInstance(this, PluralService.class); } }
@Component @Service public class AndroidProjectOperationsImpl implements AndroidProjectOperations { private static final Logger LOGGER = HandlerUtils.getLogger(AndroidProjectOperationsImpl.class); private static final DocumentBuilderFactory FACTORY; static { FACTORY = DocumentBuilderFactory.newInstance(); FACTORY.setNamespaceAware(true); } private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android"; private static final String XML_EXTENSION = ".xml"; private static final String WIDGET_PACKAGE = "android.widget"; private static final String ID_PREFIX = "@+id/"; private static final String STRINGS = "strings"; public static DocumentBuilder newDocumentBuilder() { try { return FACTORY.newDocumentBuilder(); } catch (final ParserConfigurationException e) { throw new IllegalStateException(e); } } @Reference TypeLocationService typeLocationService; @Reference TypeManagementService typeManagementService; @Reference ProjectOperations projectOperations; @Reference JpaOperations jpaOperations; @Reference FileManager fileManager; @Reference PathResolver pathResolver; @Reference AndroidTypeService androidTypeService; @Reference MetadataService metadataService; @Override public boolean isActivityAvailable() { return projectOperations.isFocusedProjectAvailable(); } @Override public boolean isViewAvailable() { return projectOperations.isFocusedProjectAvailable() && typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(ROO_ACTIVITY).size() > 0; } @Override public void layout( final String name, final Dimension height, final Dimension width, final Orientation orientation) { final Document document = newDocumentBuilder().newDocument(); final Element layoutElem = document.createElement("LinearLayout"); layoutElem.setAttribute("xmlns:android", ANDROID_NS); layoutElem.setAttribute("android:layout_height", height.value()); layoutElem.setAttribute("android:layout_width", width.value()); layoutElem.setAttribute("android:orientation", orientation.value()); document.appendChild(layoutElem); final String layoutPath = pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + name + XML_EXTENSION); if (fileManager.exists(layoutPath)) { LOGGER.severe("Layout '" + name + "' already exists"); return; } final MutableFile file = fileManager.createFile(layoutPath); final OutputStream output = file.getOutputStream(); XmlUtils.writeFormattedXml(output, document); try { output.close(); } catch (IOException e) { LOGGER.severe("Error closing stream: " + e.getMessage()); return; } // fileManager.createOrUpdateTextFileIfRequired(layoutPath, // XmlUtils.nodeToString(document), true); } @Override public void activity( final JavaType name, final String layout, final boolean main, final boolean noTitle, final boolean fullscreen) { if (noTitle) { Validate.isTrue(fullscreen == false, "Options 'noTitle' and 'fullscreen' are mutex"); } if (fullscreen) { Validate.isTrue(noTitle == false, "Options 'noTitle' and 'fullscreen' are mutex"); } if (!StringUtils.isEmpty(layout)) { final String layoutPath = pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION); if (!fileManager.exists(layoutPath)) { LOGGER.info("Layout '" + layout + "' does not exist"); layout(layout, Dimension.FILL_PARENT, Dimension.FILL_PARENT, Orientation.VERTICAL); } } final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); final AnnotationMetadataBuilder activityAnnotationBuilder = new AnnotationMetadataBuilder(ROO_ACTIVITY); if (!StringUtils.isEmpty(layout)) { activityAnnotationBuilder.addStringAttribute("value", layout); } if (noTitle) { activityAnnotationBuilder.addBooleanAttribute(RooActivity.NO_TITLE_ATTRIBUTE, noTitle); } if (fullscreen) { activityAnnotationBuilder.addBooleanAttribute(RooActivity.FULLSCREEN_ATTRIBUTE, fullscreen); } annotations.add(activityAnnotationBuilder); jpaOperations.newEntity(name, false, ANDROID_ACTIVITY, annotations); androidTypeService.addActvity( projectOperations.getFocusedModuleName(), name.getFullyQualifiedTypeName(), main); } @Override public void view( final JavaType type, final String viewName, final String identifier, final JavaSymbolName fieldName, final Dimension height, final Dimension width) { final ClassOrInterfaceTypeDetails typeDetails = typeLocationService.getTypeDetails(type); Validate.notNull(typeDetails, "The type specified, '" + type + "'doesn't exist"); final JavaType viewType = new JavaType(viewName.contains(".") ? viewName : WIDGET_PACKAGE + "." + viewName); final String layout = RequestFactoryUtils.getStringAnnotationValue(typeDetails, ROO_ACTIVITY, "value", ""); if (!StringUtils.isEmpty(layout)) { final DocumentBuilder builder = newDocumentBuilder(); final String layoutPath = pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION); InputStream inputStream = null; Document document = null; try { inputStream = fileManager.getInputStream(layoutPath); document = builder.parse(inputStream); } catch (final Exception e) { LOGGER.severe("Error reading layout XML: " + e.getMessage()); } finally { IOUtils.closeQuietly(inputStream); } if (document != null) { final Element root = document.getDocumentElement(); final Element viewElem = document.createElement(viewType.getSimpleTypeName()); final String id = StringUtils.isEmpty(identifier) ? fieldName.getSymbolName() : identifier; viewElem.setAttribute("android:id", ID_PREFIX + id); viewElem.setAttribute("android:layout_height", height.value()); viewElem.setAttribute("android:layout_width", width.value()); root.appendChild(viewElem); fileManager.createOrUpdateTextFileIfRequired( layoutPath, XmlUtils.nodeToString(document), true); } } final String physicalTypeIdentifier = typeDetails.getDeclaredByMetadataId(); final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); final AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(ROO_VIEW); if (!StringUtils.isEmpty(identifier)) { annotationBuilder.addStringAttribute("value", identifier); } annotations.add(annotationBuilder); final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(physicalTypeIdentifier, 0, annotations, fieldName, viewType); typeManagementService.addField(fieldBuilder.build()); } @Override public void resourceString( final JavaType type, final String name, final JavaSymbolName fieldName, final String value) { final ClassOrInterfaceTypeDetails typeDetails = typeLocationService.getTypeDetails(type); Validate.notNull(typeDetails, "The type specified, '" + type + "' doesn't exist"); final DocumentBuilder builder = newDocumentBuilder(); final String valuesPath = pathResolver.getFocusedIdentifier(Path.ROOT, VALUES_PATH + SEP + STRINGS + XML_EXTENSION); InputStream inputStream = null; Document document = null; try { inputStream = fileManager.getInputStream(valuesPath); document = builder.parse(inputStream); } catch (final Exception e) { LOGGER.severe("Error reading resource XML: " + e.getMessage()); } finally { IOUtils.closeQuietly(inputStream); } if (document != null) { final Element root = document.getDocumentElement(); final Element stringElem = XmlUtils.createTextElement(document, "string", value); final String id = StringUtils.isEmpty(name) ? fieldName.getSymbolName() : name; stringElem.setAttribute("name", id); root.appendChild(stringElem); fileManager.createOrUpdateTextFileIfRequired( valuesPath, XmlUtils.nodeToString(document), true); } final String physicalTypeIdentifier = typeDetails.getDeclaredByMetadataId(); final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); final AnnotationMetadataBuilder annotationBuilder = new AnnotationMetadataBuilder(ROO_STRING); if (!StringUtils.isEmpty(name)) { annotationBuilder.addStringAttribute("value", name); } annotations.add(annotationBuilder); final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(physicalTypeIdentifier, 0, annotations, fieldName, STRING); typeManagementService.addField(fieldBuilder.build()); } @Override public void systemService( final JavaType type, JavaSymbolName fieldName, final SystemService service, final boolean addPermissions) { final ClassOrInterfaceTypeDetails typeDetails = typeLocationService.getTypeDetails(type); Validate.notNull(typeDetails, "The type specified, '" + type + "' doesn't exist"); if (fieldName == null) { fieldName = new JavaSymbolName( StringUtils.uncapitalize(service.getServiceType().getSimpleTypeName())); } final String physicalTypeIdentifier = typeDetails.getDeclaredByMetadataId(); final List<AnnotationMetadataBuilder> annotations = Arrays.asList(new AnnotationMetadataBuilder(ROO_SYSTEM_SERVICE)); final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder( physicalTypeIdentifier, 0, annotations, fieldName, service.getServiceType()); typeManagementService.addField(fieldBuilder.build()); if (addPermissions) { final String moduleName = projectOperations.getFocusedModuleName(); for (Permission permission : service.getPermissions()) { androidTypeService.addPermission(moduleName, permission.permissionName()); } } } @Override public void permission(final Permission permission) { Validate.notNull(permission, "Permission type may not be null"); final String moduleName = projectOperations.getFocusedModuleName(); androidTypeService.addPermission(moduleName, permission.permissionName()); } @Override public void fragment(final JavaType name, final String layout, final boolean support) { if (!StringUtils.isEmpty(layout)) { final String layoutPath = pathResolver.getFocusedIdentifier(Path.ROOT, LAYOUT_PATH + SEP + layout + XML_EXTENSION); if (!fileManager.exists(layoutPath)) { LOGGER.info("Layout '" + layout + "' does not exist"); layout(layout, Dimension.FILL_PARENT, Dimension.FILL_PARENT, Orientation.VERTICAL); } } final List<AnnotationMetadataBuilder> annotations = new ArrayList<AnnotationMetadataBuilder>(); final AnnotationMetadataBuilder activityAnnotationBuilder = new AnnotationMetadataBuilder(ROO_FRAGMENT); if (!StringUtils.isEmpty(layout)) { activityAnnotationBuilder.addStringAttribute("value", layout); } annotations.add(activityAnnotationBuilder); jpaOperations.newEntity( name, false, support ? ANDROID_SUPPORT_FRAGMENT : ANDROID_FRAGMENT, annotations); } @Override public void dependency(final AndroidProjectDependency dependency) { final String moduleName = projectOperations.getFocusedModuleName(); final Element configuration = XmlUtils.getConfiguration(getClass()); for (final Element propertyElement : XmlUtils.findElements( "/configuration/" + dependency.getTag() + "/properties/property", configuration)) { final Property property = new Property(propertyElement); projectOperations.addProperty(moduleName, property); } final List<AndroidDependency> dependencies = new ArrayList<AndroidDependency>(); for (final Element dependencyElement : XmlUtils.findElements( "/configuration/" + dependency.getTag() + "/dependencies/dependency", configuration)) { dependencies.add(new AndroidDependency(dependencyElement)); } projectOperations.removeDependencies(moduleName, dependencies); metadataService.evict(ProjectMetadata.getProjectIdentifier(moduleName)); androidTypeService.addDependencies(moduleName, dependencies); } }
/** * Provides field creation operations support for DTO classes by implementing FieldCreatorProvider. * * @author Sergio Clares * @since 2.0 */ @Component @Service public class DtoFieldCreatorProvider implements FieldCreatorProvider { protected static final Logger LOGGER = HandlerUtils.getLogger(FieldCommands.class); // ------------ OSGi component attributes ----------------// private BundleContext context; @Reference private TypeLocationService typeLocationService; @Reference private MemberDetailsScanner memberDetailsScanner; @Reference private ProjectOperations projectOperations; @Reference private TypeManagementService typeManagementService; private Converter<JavaType> javaTypeConverter; protected void activate(final ComponentContext context) { this.context = context.getBundleContext(); } protected void deactivate(final ComponentContext context) { this.context = null; } @Override public boolean isValid(JavaType javaType) { ClassOrInterfaceTypeDetails cid = typeLocationService.getTypeDetails(javaType); if (cid.getAnnotation(RooJavaType.ROO_DTO) != null) { return true; } return false; } @Override public boolean isFieldManagementAvailable() { Set<ClassOrInterfaceTypeDetails> dtoClasses = typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_DTO); if (!dtoClasses.isEmpty()) { return true; } return false; } @Override public boolean isFieldEmbeddedAvailable() { return false; } @Override public boolean isFieldReferenceAvailable() { return false; } @Override public boolean isFieldCollectionAvailable() { return false; } @Override public boolean isColumnMandatoryForFieldBoolean(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldBoolean(ShellContext shellContext) { return false; } @Override public boolean isTransientVisibleForFieldBoolean(ShellContext shellContext) { return false; } @Override public boolean isAssertFalseVisibleForFieldBoolean(ShellContext shellContext) { String param = shellContext.getParameters().get("assertTrue"); if (param != null) { return false; } return true; } @Override public boolean isAssertTrueVisibleForFieldBoolean(ShellContext shellContext) { String param = shellContext.getParameters().get("assertFalse"); if (param != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldDate(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldDate(ShellContext shellContext) { return false; } @Override public boolean isPersistenceTypeVisibleForFieldDate(ShellContext shellContext) { return false; } @Override public boolean isTransientVisibleForFieldDate(ShellContext shellContext) { return false; } @Override public boolean isFutureVisibleForFieldDate(ShellContext shellContext) { String past = shellContext.getParameters().get("past"); if (past != null) { return false; } return true; } @Override public boolean isPastVisibleForFieldDate(ShellContext shellContext) { String past = shellContext.getParameters().get("future"); if (past != null) { return false; } return true; } @Override public boolean areDateAndTimeFormatVisibleForFieldDate(ShellContext shellContext) { String dateTimeFormatPattern = shellContext.getParameters().get("dateTimeFormatPattern"); if (dateTimeFormatPattern != null) { return false; } return true; } @Override public boolean isDateTimeFormatPatternVisibleForFieldDate(ShellContext shellContext) { String dateFormat = shellContext.getParameters().get("dateFormat"); String timeFormat = shellContext.getParameters().get("timeFormat"); if (dateFormat == null && timeFormat == null) { return true; } return false; } @Override public boolean isNotNullVisibleForFieldDate(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldDate(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldEnum(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldEnum(ShellContext shellContext) { return false; } @Override public boolean isEnumTypeVisibleForFieldEnum(ShellContext shellContext) { return false; } @Override public boolean isTransientVisibleForFieldEnum(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldEnum(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldEnum(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldNumber(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldNumber(ShellContext shellContext) { return false; } @Override public boolean isUniqueVisibleForFieldNumber(ShellContext shellContext) { return false; } @Override public boolean isTransientVisibleForFieldNumber(ShellContext shellContext) { return false; } @Override public boolean isNullRequiredVisibleForFieldNumber(ShellContext shellContext) { // Check if `notNull`is specified String notNullParam = shellContext.getParameters().get("notNull"); if (notNullParam != null) { return false; } // Check if type is primitive String typeValue = shellContext.getParameters().get("type"); if (StringUtils.isNotBlank(typeValue)) { JavaType numberType = getJavaTypeConverter().convertFromText(typeValue, JavaType.class, "java-number"); if (numberType.isPrimitive()) { return false; } } return true; } @Override public boolean isNotNullVisibleForFieldNumber(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldReference(ShellContext shellContext) { return false; } @Override public boolean isJoinColumnNameVisibleForFieldReference(ShellContext shellContext) { return false; } @Override public boolean isReferencedColumnNameVisibleForFieldReference(ShellContext shellContext) { return false; } @Override public boolean isFetchVisibleForFieldReference(ShellContext shellContext) { return false; } @Override public boolean isCascadeTypeVisibleForFieldReference(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldReference(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldReference(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isJoinTableMandatoryForFieldSet(ShellContext shellContext) { return false; } @Override public boolean areJoinTableParamsVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isMappedByVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isCardinalityVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isFetchVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isJoinTableVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean areOptionalParametersVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean areJoinTableParamsMandatoryForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isJoinColumnNameMandatoryForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isJoinColumnNameVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isReferencedColumnNameVisibleForFieldSet(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldSet(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldSet(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isJoinColumnNameMandatoryForFieldList(ShellContext shellContext) { return false; } @Override public boolean isJoinColumnNameVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isReferencedColumnNameVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean areOptionalParametersVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean areJoinTableParamsVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isJoinTableMandatoryForFieldList(ShellContext shellContext) { return false; } @Override public boolean areJoinTableParamsMandatoryForFieldList(ShellContext shellContext) { return false; } @Override public boolean isMappedByVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isCardinalityVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isFetchVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isJoinTableVisibleForFieldList(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldList(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldList(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldString(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldString(ShellContext shellContext) { return false; } @Override public boolean isUniqueVisibleForFieldString(ShellContext shellContext) { return false; } @Override public boolean isTransientVisibleForFieldString(ShellContext shellContext) { return false; } @Override public boolean isLobVisibleForFieldString(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldString(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldString(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isColumnMandatoryForFieldFile(ShellContext shellContext) { return false; } @Override public boolean isColumnVisibleForFieldFile(ShellContext shellContext) { return false; } public boolean isColumnMandatoryForFieldOther(ShellContext shellContext) { return false; } public boolean isColumnVisibleForFieldOther(ShellContext shellContext) { return false; } public boolean isTransientVisibleForFieldOther(ShellContext shellContext) { return false; } @Override public boolean isNotNullVisibleForFieldOther(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("nullRequired"); if (antagonistParam != null) { return false; } return true; } @Override public boolean isNullRequiredVisibleForFieldOther(ShellContext shellContext) { String antagonistParam = shellContext.getParameters().get("notNull"); if (antagonistParam != null) { return false; } return true; } @Override public void createBooleanField( ClassOrInterfaceTypeDetails javaTypeDetails, boolean primitive, JavaSymbolName fieldName, boolean notNull, boolean assertFalse, boolean assertTrue, String column, String comment, String value, boolean permitReservedWords, boolean transientModifier) { createBooleanField( javaTypeDetails, primitive, fieldName, notNull, assertFalse, assertTrue, column, comment, value, permitReservedWords, transientModifier, null); } @Override public void createBooleanField( ClassOrInterfaceTypeDetails javaTypeDetails, boolean primitive, JavaSymbolName fieldName, boolean notNull, boolean assertFalse, boolean assertTrue, String column, String comment, String value, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = javaTypeDetails.getDeclaredByMetadataId(); final BooleanField fieldDetails = new BooleanField( physicalTypeIdentifier, primitive ? JavaType.BOOLEAN_PRIMITIVE : JavaType.BOOLEAN_OBJECT, fieldName); fieldDetails.setNotNull(notNull); fieldDetails.setAssertFalse(assertFalse); fieldDetails.setAssertTrue(assertTrue); if (column != null) { fieldDetails.setColumn(column); } if (comment != null) { fieldDetails.setComment(comment); } if (value != null) { fieldDetails.setValue(value); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } @Override public void createDateField( ClassOrInterfaceTypeDetails javaTypeDetails, JavaType fieldType, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, boolean future, boolean past, DateFieldPersistenceType persistenceType, String column, String comment, DateTime dateFormat, DateTime timeFormat, String pattern, String value, boolean permitReservedWords, boolean transientModifier) { createDateField( javaTypeDetails, fieldType, fieldName, notNull, nullRequired, future, past, persistenceType, column, comment, dateFormat, timeFormat, pattern, value, permitReservedWords, transientModifier, null); } @Override public void createDateField( ClassOrInterfaceTypeDetails javaTypeDetails, JavaType fieldType, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, boolean future, boolean past, DateFieldPersistenceType persistenceType, String column, String comment, DateTime dateFormat, DateTime timeFormat, String pattern, String value, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = javaTypeDetails.getDeclaredByMetadataId(); final DateField fieldDetails = new DateField(physicalTypeIdentifier, fieldType, fieldName); fieldDetails.setNotNull(notNull); fieldDetails.setNullRequired(nullRequired); fieldDetails.setFuture(future); fieldDetails.setPast(past); if (JdkJavaType.isDateField(fieldType)) { fieldDetails.setPersistenceType(persistenceType); } if (column != null) { fieldDetails.setColumn(column); } if (comment != null) { fieldDetails.setComment(comment); } if (dateFormat != null) { fieldDetails.setDateFormat(dateFormat); } if (timeFormat != null) { fieldDetails.setTimeFormat(timeFormat); } if (pattern != null) { fieldDetails.setPattern(pattern); } if (value != null) { fieldDetails.setValue(value); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } @Override public void createEmbeddedField( JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, boolean permitReservedWords) { createEmbeddedField(typeName, fieldType, fieldName, permitReservedWords, null); } @Override public void createEmbeddedField( JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, boolean permitReservedWords, List<AnnotationMetadataBuilder> extraAnnotations) { throw new IllegalArgumentException( "'field embedded' command is not available for DTO classes."); } @Override public void createEnumField( ClassOrInterfaceTypeDetails cid, JavaType fieldType, JavaSymbolName fieldName, String column, boolean notNull, boolean nullRequired, EnumType enumType, String comment, boolean permitReservedWords, boolean transientModifier) { createEnumField( cid, fieldType, fieldName, column, notNull, nullRequired, enumType, comment, permitReservedWords, transientModifier, null); } @Override public void createEnumField( ClassOrInterfaceTypeDetails cid, JavaType fieldType, JavaSymbolName fieldName, String column, boolean notNull, boolean nullRequired, EnumType enumType, String comment, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = cid.getDeclaredByMetadataId(); final EnumField fieldDetails = new EnumField(physicalTypeIdentifier, fieldType, fieldName); if (column != null) { fieldDetails.setColumn(column); } fieldDetails.setNotNull(notNull); fieldDetails.setNullRequired(nullRequired); if (enumType != null) { fieldDetails.setEnumType(enumType); } if (comment != null) { fieldDetails.setComment(comment); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } @Override public void createNumericField( ClassOrInterfaceTypeDetails javaTypeDetails, JavaType fieldType, boolean primitive, Set<String> legalNumericPrimitives, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String decimalMin, String decimalMax, Integer digitsInteger, Integer digitsFraction, Long min, Long max, String column, String comment, boolean unique, String value, boolean permitReservedWords, boolean transientModifier) { createNumericField( javaTypeDetails, fieldType, primitive, legalNumericPrimitives, fieldName, notNull, nullRequired, decimalMin, decimalMax, digitsInteger, digitsFraction, min, max, column, comment, unique, value, permitReservedWords, transientModifier, null); } @Override public void createNumericField( ClassOrInterfaceTypeDetails javaTypeDetails, JavaType fieldType, boolean primitive, Set<String> legalNumericPrimitives, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String decimalMin, String decimalMax, Integer digitsInteger, Integer digitsFraction, Long min, Long max, String column, String comment, boolean unique, String value, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = javaTypeDetails.getDeclaredByMetadataId(); if (primitive && legalNumericPrimitives.contains(fieldType.getFullyQualifiedTypeName())) { fieldType = new JavaType(fieldType.getFullyQualifiedTypeName(), 0, DataType.PRIMITIVE, null, null); } final NumericField fieldDetails = new NumericField(physicalTypeIdentifier, fieldType, fieldName); fieldDetails.setNotNull(notNull); fieldDetails.setNullRequired(nullRequired); if (decimalMin != null) { fieldDetails.setDecimalMin(decimalMin); } if (decimalMax != null) { fieldDetails.setDecimalMax(decimalMax); } if (digitsInteger != null) { fieldDetails.setDigitsInteger(digitsInteger); } if (digitsFraction != null) { fieldDetails.setDigitsFraction(digitsFraction); } if (min != null) { fieldDetails.setMin(min); } if (max != null) { fieldDetails.setMax(max); } if (column != null) { fieldDetails.setColumn(column); } if (comment != null) { fieldDetails.setComment(comment); } if (unique) { fieldDetails.setUnique(true); } if (value != null) { fieldDetails.setValue(value); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } Validate.isTrue( fieldDetails.isDigitsSetCorrectly(), "Must specify both --digitsInteger and --digitsFractional for @Digits to be added"); insertField(fieldDetails, permitReservedWords, false); } @Override public void createReferenceField( JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, boolean aggregation, JavaSymbolName mappedBy, Cascade[] cascadeType, boolean notNull, String joinColumnName, String referencedColumnName, Fetch fetch, String comment, boolean permitReservedWords, Boolean orphanRemoval, boolean isForce) { throw new IllegalArgumentException( "'field reference' command is not available for DTO classes."); } @Override public void createSetField( JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, Cardinality cardinality, Cascade[] cascadeType, boolean notNull, Integer sizeMin, Integer sizeMax, JavaSymbolName mappedBy, Fetch fetch, String comment, String joinColumn, String referencedColumn, String joinTable, String joinColumns, String referencedColumns, String inverseJoinColumns, String inverseReferencedColumns, boolean permitReservedWords, Boolean aggregation, Boolean orphanRemoval, boolean isForce) { throw new IllegalArgumentException("'field set' command is not available for DTO classes."); } @Override public void createListField( JavaType typeName, JavaType fieldType, JavaSymbolName fieldName, Cardinality cardinality, Cascade[] cascadeType, boolean notNull, Integer sizeMin, Integer sizeMax, JavaSymbolName mappedBy, Fetch fetch, String comment, String joinColumn, String referencedColumn, String joinTable, String joinColumns, String referencedColumns, String inverseJoinColumns, String inverseReferencedColumns, boolean permitReservedWords, Boolean aggregation, Boolean orphanRemoval, boolean isForce) { throw new IllegalArgumentException("'field list' command is not available for DTO classes."); } @Override public void createStringField( ClassOrInterfaceTypeDetails cid, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String decimalMin, String decimalMax, Integer sizeMin, Integer sizeMax, String regexp, String column, String comment, boolean unique, String value, boolean lob, boolean permitReservedWords, boolean transientModifier) { createStringField( cid, fieldName, notNull, nullRequired, decimalMin, decimalMax, sizeMin, sizeMax, regexp, column, comment, unique, value, lob, permitReservedWords, transientModifier, null); } @Override public void createStringField( ClassOrInterfaceTypeDetails cid, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String decimalMin, String decimalMax, Integer sizeMin, Integer sizeMax, String regexp, String column, String comment, boolean unique, String value, boolean lob, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = cid.getDeclaredByMetadataId(); final StringField fieldDetails = new StringField(physicalTypeIdentifier, fieldName); fieldDetails.setNotNull(notNull); fieldDetails.setNullRequired(nullRequired); if (decimalMin != null) { fieldDetails.setDecimalMin(decimalMin); } if (decimalMax != null) { fieldDetails.setDecimalMax(decimalMax); } if (sizeMin != null) { fieldDetails.setSizeMin(sizeMin); } if (sizeMax != null) { fieldDetails.setSizeMax(sizeMax); } if (regexp != null) { fieldDetails.setRegexp(regexp.replace("\\", "\\\\")); } if (column != null) { fieldDetails.setColumn(column); } if (comment != null) { fieldDetails.setComment(comment); } if (unique) { fieldDetails.setUnique(true); } if (value != null) { fieldDetails.setValue(value); } if (lob) { fieldDetails .getInitedAnnotations() .add(new AnnotationMetadataBuilder("javax.persistence.Lob")); // ROO-3722: Add LAZY load in @Lob fields using @Basic AnnotationMetadataBuilder basicAnnotation = new AnnotationMetadataBuilder("javax.persistence.Basic"); basicAnnotation.addEnumAttribute( "fetch", new EnumDetails(new JavaType("javax.persistence.FetchType"), new JavaSymbolName("LAZY"))); fieldDetails.getInitedAnnotations().add(basicAnnotation); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } @Override public void createFileField( ClassOrInterfaceTypeDetails cid, JavaSymbolName fieldName, UploadedFileContentType contentType, boolean autoUpload, boolean notNull, String column, boolean permitReservedWords) { createFileField( cid, fieldName, contentType, autoUpload, notNull, column, permitReservedWords, null); } @Override public void createFileField( ClassOrInterfaceTypeDetails cid, JavaSymbolName fieldName, UploadedFileContentType contentType, boolean autoUpload, boolean notNull, String column, boolean permitReservedWords, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = cid.getDeclaredByMetadataId(); final UploadedFileField fieldDetails = new UploadedFileField(physicalTypeIdentifier, fieldName, contentType); fieldDetails.setAutoUpload(autoUpload); fieldDetails.setNotNull(notNull); if (column != null) { fieldDetails.setColumn(column); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } @Override public void createOtherField( ClassOrInterfaceTypeDetails cid, JavaType fieldType, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String comment, String column, boolean permitReservedWords, boolean transientModifier) { createOtherField( cid, fieldType, fieldName, notNull, nullRequired, comment, column, permitReservedWords, transientModifier, null); } @Override public void createOtherField( ClassOrInterfaceTypeDetails cid, JavaType fieldType, JavaSymbolName fieldName, boolean notNull, boolean nullRequired, String comment, String column, boolean permitReservedWords, boolean transientModifier, List<AnnotationMetadataBuilder> extraAnnotations) { final String physicalTypeIdentifier = cid.getDeclaredByMetadataId(); final FieldDetails fieldDetails = new FieldDetails(physicalTypeIdentifier, fieldType, fieldName); fieldDetails.setNotNull(notNull); fieldDetails.setNullRequired(nullRequired); if (comment != null) { fieldDetails.setComment(comment); } if (column != null) { fieldDetails.setColumn(column); } if (extraAnnotations != null && !extraAnnotations.isEmpty()) { fieldDetails.addAnnotations(extraAnnotations); } insertField(fieldDetails, permitReservedWords, false); } public void insertField( final FieldDetails fieldDetails, final boolean permitReservedWords, final boolean transientModifier) { String module = null; if (!permitReservedWords) { ReservedWords.verifyReservedWordsNotPresent(fieldDetails.getFieldName()); if (fieldDetails.getColumn() != null) { ReservedWords.verifyReservedWordsNotPresent(fieldDetails.getColumn()); } } final List<AnnotationMetadataBuilder> annotations = fieldDetails.getInitedAnnotations(); fieldDetails.decorateAnnotationsList(annotations); fieldDetails.setAnnotations(annotations); if (fieldDetails.getFieldType() != null) { module = fieldDetails.getFieldType().getModule(); } fieldDetails.setModifiers(Modifier.PRIVATE); String initializer = null; if (fieldDetails instanceof CollectionField) { final CollectionField collectionField = (CollectionField) fieldDetails; module = collectionField.getGenericParameterTypeName().getModule(); initializer = "new " + collectionField.getInitializer() + "()"; } else if (fieldDetails instanceof DateField && fieldDetails.getFieldName().getSymbolName().equals("created")) { initializer = "new Date()"; } // Format the passed-in comment (if given) formatFieldComment(fieldDetails); final FieldMetadataBuilder fieldBuilder = new FieldMetadataBuilder(fieldDetails); fieldBuilder.setFieldInitializer(initializer); typeManagementService.addField(fieldBuilder.build()); if (module != null) { projectOperations.addModuleDependency(module); } } public void formatFieldComment(FieldDetails fieldDetails) { // If a comment was defined, we need to format it if (fieldDetails.getComment() != null) { // First replace all "" with the proper escape sequence \" String unescapedMultiLineComment = fieldDetails.getComment().replaceAll("\"\"", "\\\\\""); // Then unescape all characters unescapedMultiLineComment = StringEscapeUtils.unescapeJava(unescapedMultiLineComment); CommentFormatter commentFormatter = new CommentFormatter(); String javadocComment = commentFormatter.formatStringAsJavadoc(unescapedMultiLineComment); fieldDetails.setComment(commentFormatter.format(javadocComment, 1)); } } @Override public List<String> getFieldSetTypeAllPossibleValues(ShellContext shellContext) { // Get current value of class String currentText = shellContext.getParameters().get("type"); List<String> allPossibleValues = new ArrayList<String>(); // Getting all existing entities Set<ClassOrInterfaceTypeDetails> entitiesInProject = typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY); for (ClassOrInterfaceTypeDetails entity : entitiesInProject) { String name = replaceTopLevelPackageString(entity, currentText); if (!allPossibleValues.contains(name)) { allPossibleValues.add(name); } } // Getting all existing dtos Set<ClassOrInterfaceTypeDetails> dtosInProject = typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_DTO); for (ClassOrInterfaceTypeDetails dto : dtosInProject) { String name = replaceTopLevelPackageString(dto, currentText); if (!allPossibleValues.contains(name)) { allPossibleValues.add(name); } } return allPossibleValues; } @Override public List<String> getFieldListTypeAllPossibleValues(ShellContext shellContext) { // Get current value of class String currentText = shellContext.getParameters().get("type"); List<String> allPossibleValues = new ArrayList<String>(); // Getting all existing entities Set<ClassOrInterfaceTypeDetails> entitiesInProject = typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY); for (ClassOrInterfaceTypeDetails entity : entitiesInProject) { String name = replaceTopLevelPackageString(entity, currentText); if (!allPossibleValues.contains(name)) { allPossibleValues.add(name); } } // Getting all existing dtos Set<ClassOrInterfaceTypeDetails> dtosInProject = typeLocationService.findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_DTO); for (ClassOrInterfaceTypeDetails dto : dtosInProject) { String name = replaceTopLevelPackageString(dto, currentText); if (!allPossibleValues.contains(name)) { allPossibleValues.add(name); } } return allPossibleValues; } @Override public List<String> getFieldEmbeddedAllPossibleValues(ShellContext shellContext) { // field embedded not used for DTO's return new ArrayList<String>(); } /** * Replaces a JavaType fullyQualifiedName for a shorter name using '~' for TopLevelPackage * * @param cid ClassOrInterfaceTypeDetails of a JavaType * @param currentText String current text for option value * @return the String representing a JavaType with its name shortened */ private String replaceTopLevelPackageString(ClassOrInterfaceTypeDetails cid, String currentText) { String javaTypeFullyQualilfiedName = cid.getType().getFullyQualifiedTypeName(); String javaTypeString = ""; String topLevelPackageString = ""; // Add module value to topLevelPackage when necessary if (StringUtils.isNotBlank(cid.getType().getModule()) && !cid.getType().getModule().equals(projectOperations.getFocusedModuleName())) { // Target module is not focused javaTypeString = cid.getType().getModule().concat(LogicalPath.MODULE_PATH_SEPARATOR); topLevelPackageString = projectOperations .getTopLevelPackage(cid.getType().getModule()) .getFullyQualifiedPackageName(); } else if (StringUtils.isNotBlank(cid.getType().getModule()) && cid.getType().getModule().equals(projectOperations.getFocusedModuleName()) && (currentText.startsWith(cid.getType().getModule()) || cid.getType().getModule().startsWith(currentText)) && StringUtils.isNotBlank(currentText)) { // Target module is focused but user wrote it javaTypeString = cid.getType().getModule().concat(LogicalPath.MODULE_PATH_SEPARATOR); topLevelPackageString = projectOperations .getTopLevelPackage(cid.getType().getModule()) .getFullyQualifiedPackageName(); } else { // Not multimodule project topLevelPackageString = projectOperations.getFocusedTopLevelPackage().getFullyQualifiedPackageName(); } // Autocomplete with abbreviate or full qualified mode String auxString = javaTypeString.concat( StringUtils.replace(javaTypeFullyQualilfiedName, topLevelPackageString, "~")); if ((StringUtils.isBlank(currentText) || auxString.startsWith(currentText)) && StringUtils.contains(javaTypeFullyQualilfiedName, topLevelPackageString)) { // Value is for autocomplete only or user wrote abbreviate value javaTypeString = auxString; } else { // Value could be for autocomplete or for validation javaTypeString = String.format("%s%s", javaTypeString, javaTypeFullyQualilfiedName); } return javaTypeString; } @SuppressWarnings("unchecked") public Converter<JavaType> getJavaTypeConverter() { if (javaTypeConverter == null) { // Get all Services implement JavaTypeConverter interface try { ServiceReference<?>[] references = this.context.getAllServiceReferences(Converter.class.getName(), null); for (ServiceReference<?> ref : references) { Converter<?> converter = (Converter<?>) this.context.getService(ref); if (converter.supports(JavaType.class, PROJECT)) { javaTypeConverter = (Converter<JavaType>) converter; return javaTypeConverter; } } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("ERROR: Cannot load JavaTypeConverter on JpaFieldCreatorProvider."); return null; } } else { return javaTypeConverter; } } }
/** * Implementation of {@link MavenOperations}. * * @author Ben Alex * @author Alan Stewart * @since 1.0 */ @Component @Service public class MavenOperationsImpl extends AbstractProjectOperations implements MavenOperations { // Constants private static final Logger LOGGER = HandlerUtils.getLogger(MavenOperationsImpl.class); // Fields @Reference private FileManager fileManager; @Reference private ProcessManager processManager; public boolean isCreateProjectAvailable() { return !isProjectAvailable(); } public String getProjectRoot() { return pathResolver.getRoot(Path.ROOT); } public void createProject( final JavaPackage topLevelPackage, final String projectName, final Integer majorJavaVersion, final GAV parentPom, final PackagingType packagingType) { Assert.isTrue(isCreateProjectAvailable(), "Project creation is unavailable at this time"); final String javaVersion = getJavaVersion(majorJavaVersion); packagingType.createArtifacts(topLevelPackage, projectName, javaVersion, parentPom); } /** * Returns the project's target Java version in POM format * * @param majorJavaVersion the major version provided by the user; can be <code>null</code> to * auto-detect it * @return a non-blank string */ private final String getJavaVersion(final Integer majorJavaVersion) { if (majorJavaVersion != null && majorJavaVersion >= 5 && majorJavaVersion <= 7) { return "1." + majorJavaVersion; } // No valid version given; detect the major Java version to use final String ver = System.getProperty("java.version"); if (ver.contains("1.7.")) { return "1.7"; } if (ver.contains("1.6.")) { return "1.6"; } // To be running Roo they must be on Java 5 or above return "1.5"; } public void executeMvnCommand(final String extra) throws IOException { final File root = new File(getProjectRoot()); Assert.isTrue( root.isDirectory() && root.exists(), "Project root does not currently exist as a directory ('" + root.getCanonicalPath() + "')"); final String cmd = (File.separatorChar == '\\' ? "mvn.bat " : "mvn ") + extra; final Process p = Runtime.getRuntime().exec(cmd, null, root); // Ensure separate threads are used for logging, as per ROO-652 final LoggingInputStream input = new LoggingInputStream(p.getInputStream(), processManager); final LoggingInputStream errors = new LoggingInputStream(p.getErrorStream(), processManager); p.getOutputStream() .close(); // Close OutputStream to avoid blocking by Maven commands that expect input, as // per ROO-2034 input.start(); errors.start(); try { if (p.waitFor() != 0) { LOGGER.warning("The command '" + cmd + "' did not complete successfully"); } } catch (final InterruptedException e) { throw new IllegalStateException(e); } } private static class LoggingInputStream extends Thread { // Fields private final BufferedReader reader; private final ProcessManager processManager; /** * Constructor * * @param inputStream * @param processManager */ public LoggingInputStream(final InputStream inputStream, final ProcessManager processManager) { this.reader = new BufferedReader(new InputStreamReader(inputStream)); this.processManager = processManager; } @Override public void run() { ActiveProcessManager.setActiveProcessManager(processManager); String line; try { while ((line = reader.readLine()) != null) { if (line.startsWith("[ERROR]")) { LOGGER.severe(line); } else if (line.startsWith("[WARNING]")) { LOGGER.warning(line); } else { LOGGER.info(line); } } } catch (final IOException e) { if (e.getMessage().contains("No such file or directory") || // For *nix/Mac e.getMessage().contains("CreateProcess error=2")) { // For Windows LOGGER.severe( "Could not locate Maven executable; please ensure mvn command is in your path"); } } finally { IOUtils.closeQuietly(reader); ActiveProcessManager.clearActiveProcessManager(); } } } public boolean isCreateModuleAvailable() { // TODO Waiting on JTT's work for ROO-120 to find out if the currently focussed module is // POM-packaged return false; } public void createModule( final JavaPackage topLevelPackage, final String name, final GAV parent, final PackagingType packagingType) { Assert.isTrue(isCreateModuleAvailable(), "Cannot create modules at this time"); final String moduleName = StringUtils.defaultIfEmpty(name, topLevelPackage.getLastElement()); final GAV module = new GAV(topLevelPackage.getFullyQualifiedPackageName(), moduleName, parent.getVersion()); final ProjectMetadata project = getProjectMetadata(); // TODO create or update "modules" element of parent module's POM // Create the new module's directory, named by its artifactId (Maven standard practice) fileManager.createDirectory(moduleName); // Focus the new module so that artifacts created below go to the correct path(s) focus(module); packagingType.createArtifacts(topLevelPackage, name, "${java.version}", parent); } public void focus(final GAV module) { Assert.notNull(module, "Specify the module to focus on"); throw new UnsupportedOperationException( "Module focussing not implemented yet"); // TODO by JTT for ROO-120 } }
/** * @author Juan Carlos García * @since 2.0 */ public class EntitiesServlet extends HttpServlet { private BundleContext context; private static final Logger LOGGER = HandlerUtils.getLogger(EntitiesServlet.class); private Shell shell; private TypeLocationService typeLocationService; private ProjectOperations projectOperations; public EntitiesServlet(BundleContext bContext) { this.context = bContext; } public void init() throws ServletException {} /** * Method to handle GET method request of /entities service * * @param request * @param response */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Set response content type response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); String method = request.getPathInfo(); if (method == null || method.equals("/")) { getAllEntities(out); } else { // Removing URL / from entity name getEntityDetails(method.substring(1), out); } } /** * Method to handle POST request of /entities service * * @param request * @param response */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Set response content type response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); // Getting params String entityName = request.getParameter("entityName").trim(); String extendsType = request.getParameter("extends"); String isAbstract = request.getParameter("isAbstract"); // Execute entity command // TODO: Replace with JPA command String entityCommand = "entity jpa --class " + entityName; // Adding abstract if needed if (isAbstract != null) { entityCommand = entityCommand.concat(" --abstract ").concat(isAbstract); } // Adding extends if needed if (extendsType != null && !"".equals(extendsType)) { entityCommand = entityCommand.concat(" --extends ").concat(extendsType); } boolean status = getShell().executeCommand(entityCommand); String message = "Created entity '" + entityName + "'!"; if (!status) { message = "Error creating entity."; } // Returning JSON ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json = ow.writeValueAsString(new Status(status, message)); out.println(json); } public void destroy() { // do nothing. } /** * Method to obtain all created entities on current project * * @param out */ private void getAllEntities(PrintWriter out) throws ServletException, IOException { List<Entity> allEntities = new ArrayList<Entity>(); // Getting all entities Set<ClassOrInterfaceTypeDetails> entities = getTypeLocationService() .findClassesOrInterfaceDetailsWithAnnotation(new JavaType(RooJavaBean.class)); Iterator<ClassOrInterfaceTypeDetails> it = entities.iterator(); while (it.hasNext()) { // Getting entity ClassOrInterfaceTypeDetails entity = it.next(); // Entity Name String entityName = entity.getName().getFullyQualifiedTypeName(); String topLevelPackage = getProjectOperations().getFocusedTopLevelPackage().toString(); // Replacing topLevelPackage with ~ entityName = entityName.replace(topLevelPackage, "~"); List<Field> entityFields = new ArrayList<Field>(); for (FieldMetadata field : entity.getDeclaredFields()) { // Getting fields values String fieldName = field.getFieldName().getSymbolName(); String fieldType = field.getFieldType().getSimpleTypeName(); // Getting referenced class String referencedClass = ""; if (field.getFieldType().getSimpleTypeName().equals("Set") || field.getFieldType().getSimpleTypeName().equals("List")) { referencedClass = field.getFieldType().getParameters().get(0).getSimpleTypeName(); } else { AnnotationMetadata manyToOneAnnotation = field.getAnnotation(new JavaType("javax.persistence.ManyToOne")); if (manyToOneAnnotation != null) { referencedClass = field.getFieldType().getFullyQualifiedTypeName(); referencedClass = referencedClass.replace(topLevelPackage, "~"); fieldType = "Reference"; } } // Creating entityField Object Field entityField = new Field(fieldName, fieldType, referencedClass); // Adding field to entity entityFields.add(entityField); } // Checking if current entity is abstract boolean isAbstractEntity = entity.isAbstract(); // Adding extends type List<String> extendsTypes = new ArrayList<String>(); for (JavaType extendsType : entity.getExtendsTypes()) { extendsTypes.add(extendsType.getFullyQualifiedTypeName().replace(topLevelPackage, "~")); } // Creating Entity Object allEntities.add(new Entity(entityName, extendsTypes, isAbstractEntity, entityFields)); } // Returning JSON ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json = ow.writeValueAsString(allEntities); out.println(json); } /** * Method to obtain details of some entity * * @param out */ private void getEntityDetails(String entityName, PrintWriter out) throws ServletException, IOException { List<Entity> allEntities = new ArrayList<Entity>(); // Getting all entities Set<ClassOrInterfaceTypeDetails> entities = getTypeLocationService() .findClassesOrInterfaceDetailsWithAnnotation(new JavaType(RooJavaBean.class)); Iterator<ClassOrInterfaceTypeDetails> it = entities.iterator(); while (it.hasNext()) { // Getting entity ClassOrInterfaceTypeDetails entity = it.next(); // Entity Name String currentEntityName = entity.getName().getFullyQualifiedTypeName(); String topLevelPackage = getProjectOperations().getFocusedTopLevelPackage().toString(); // Replacing topLevelPackage with ~ currentEntityName = currentEntityName.replace(topLevelPackage, "~"); // Getting info only about selected entity if (entityName.equals(currentEntityName)) { List<Field> entityFields = new ArrayList<Field>(); for (FieldMetadata field : entity.getDeclaredFields()) { // Getting fields values String fieldName = field.getFieldName().getSymbolName(); String fieldType = field.getFieldType().getSimpleTypeName(); // Getting referenced class String referencedClass = ""; if (field.getFieldType().getSimpleTypeName().equals("Set") || field.getFieldType().getSimpleTypeName().equals("List")) { referencedClass = field.getFieldType().getParameters().get(0).getSimpleTypeName(); } else { AnnotationMetadata manyToOneAnnotation = field.getAnnotation(new JavaType("javax.persistence.ManyToOne")); if (manyToOneAnnotation != null) { referencedClass = field.getFieldType().getFullyQualifiedTypeName(); referencedClass = referencedClass.replace(topLevelPackage, "~"); fieldType = "Reference"; } } // Creating entityField Object Field entityField = new Field(fieldName, fieldType, referencedClass); // Adding field to entity entityFields.add(entityField); } // Checking if current entity is abstract boolean isAbstractEntity = entity.isAbstract(); // Adding extends type List<String> extendsTypes = new ArrayList<String>(); for (JavaType extendsType : entity.getExtendsTypes()) { extendsTypes.add(extendsType.getFullyQualifiedTypeName().replace(topLevelPackage, "~")); } // Creating Entity Object allEntities.add( new Entity(currentEntityName, extendsTypes, isAbstractEntity, entityFields)); } } // Returning JSON ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json = ow.writeValueAsString(allEntities); out.println(json); } /** * Method to get TypeLocationService Service implementation * * @return */ public TypeLocationService getTypeLocationService() { if (typeLocationService == null) { // Get all TypeLocationService implement Shell interface try { ServiceReference<?>[] references = context.getAllServiceReferences(TypeLocationService.class.getName(), null); for (ServiceReference<?> ref : references) { typeLocationService = (TypeLocationService) context.getService(ref); return typeLocationService; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load TypeLocationService on ProjectConfigurationController."); return null; } } else { return typeLocationService; } } /** * Method to get Shell Service implementation * * @return */ public Shell getShell() { if (shell == null) { // Get all Services implement Shell interface try { ServiceReference<?>[] references = context.getAllServiceReferences(Shell.class.getName(), null); for (ServiceReference<?> ref : references) { shell = (Shell) context.getService(ref); return shell; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load Shell on ProjectConfigurationController."); return null; } } else { return shell; } } /** * Method to get ProjectOperations Service implementation * * @return */ public ProjectOperations getProjectOperations() { if (projectOperations == null) { // Get all Services implement ProjectOperations interface try { ServiceReference<?>[] references = this.context.getAllServiceReferences(ProjectOperations.class.getName(), null); for (ServiceReference<?> ref : references) { return (ProjectOperations) this.context.getService(ref); } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load ProjectOperations on EntitiesController."); return null; } } else { return projectOperations; } } }