Index: addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenPathResolver.java =================================================================== --- addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenPathResolver.java (revision 184) +++ addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenPathResolver.java (working copy) @@ -23,6 +23,7 @@ pathInformation.add(new PathInformation(Path.SRC_TEST_RESOURCES, true, new File(root, "src/test/resources"))); pathInformation.add(new PathInformation(Path.SRC_MAIN_WEBAPP, false, new File(root, "src/main/webapp"))); pathInformation.add(new PathInformation(Path.ROOT, false, root)); + pathInformation.add(new PathInformation(Path.SPRING_CONFIG_ROOT,false, new File(root, "src/main/resources/META-INF/spring"))); init(); } Index: addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenProjectMetadataProvider.java =================================================================== --- addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenProjectMetadataProvider.java (revision 184) +++ addon-maven/src/main/java/org/springframework/roo/addon/maven/MavenProjectMetadataProvider.java (working copy) @@ -18,6 +18,7 @@ import org.springframework.roo.process.manager.MutableFile; import org.springframework.roo.project.Dependency; import org.springframework.roo.project.DependencyType; +import org.springframework.roo.project.Execution; import org.springframework.roo.project.Path; import org.springframework.roo.project.PathResolver; import org.springframework.roo.project.ProjectMetadata; @@ -108,8 +109,16 @@ Dependency d = new Dependency(dependency); dependencies.add(d); } + + // Build build plugin dependencies list + Set buildPluginDependencies = new HashSet(); + + for (Element plugin : XmlUtils.findElements("/project/build/plugins/plugin", rootElement)) { + Dependency d = new Dependency(plugin); + buildPluginDependencies.add(d); + } - return new ProjectMetadata(topLevelPackage, projectName, dependencies, pathResolver); + return new ProjectMetadata(topLevelPackage, projectName, dependencies, buildPluginDependencies, pathResolver); } public String getProvidesType() { @@ -180,13 +189,17 @@ } public void removeDependency(Dependency dependency) { - Assert.notNull(dependency, "Dependency to remove required"); + removeDependency(dependency,"/project/dependencies","/project/dependencies/dependency"); + } + + public void addBuildPluginDependency(Dependency dependency, Execution... executions) { + Assert.notNull(dependency, "Dependency to add required"); ProjectMetadata md = (ProjectMetadata) get(ProjectMetadata.getProjectIdentifier()); Assert.notNull(md, "Project metadata is not yet available, so dependency addition is unavailable"); - if (!md.isDependencyRegistered(dependency)) { + if (md.isDependencyRegistered(dependency)) { return; } - + MutableFile mutableFile = fileManager.updateFile(pom); Document document; @@ -197,19 +210,51 @@ } Element rootElement = (Element) document.getFirstChild(); - Element dependencies = XmlUtils.findFirstElement("/project/dependencies", rootElement); + Element plugins = XmlUtils.findFirstElement("/project/build/plugins", rootElement); + Assert.notNull(plugins, "Plugins unable to be found"); - for(Element candidate : XmlUtils.findElements("/project/dependencies/dependency", rootElement)) { - if (dependency.equals(new Dependency(candidate))) { - // Found it - dependencies.removeChild(candidate); - // We will not break the loop (even though we could theoretically), just in case it was declared in the POM more than once - } - } + Element pluginElement = document.createElement("plugin"); + Element groupId = document.createElement("groupId"); + Element artifactId = document.createElement("artifactId"); + Element version = document.createElement("version"); + + groupId.setTextContent(dependency.getGroupId().getFullyQualifiedPackageName()); + artifactId.setTextContent(dependency.getArtifactId().getSymbolName()); + version.setTextContent(dependency.getVersionId()); + + pluginElement.appendChild(groupId); + pluginElement.appendChild(artifactId); + pluginElement.appendChild(version); + + //add executions if they are defined + if (executions.length > 0) { + Element executionsElement = document.createElement("executions"); + for (Execution execution: executions) { + Element executionElement = document.createElement("execution"); + Element executionId = document.createElement("id"); + executionId.setTextContent(execution.getId()); + Element goalsElement = document.createElement("goals"); + for (String goal: execution.getGoals()) { + Element goalElement = document.createElement("goal"); + goalElement.setTextContent(goal); + goalsElement.appendChild(goalElement); + } + executionElement.appendChild(executionId); + executionElement.appendChild(goalsElement); + executionsElement.appendChild(executionElement); + } + pluginElement.appendChild(executionsElement); + } + + plugins.appendChild(pluginElement); - XmlUtils.writeXml(mutableFile.getOutputStream(), document); + XmlUtils.writeXml(mutableFile.getOutputStream(), document); } + public void removeBuildPluginDependency(Dependency dependency) { + removeDependency(dependency,"/project/build/plugins","/project/build/plugins/plugin"); + } + public void updateProjectType(ProjectType projectType) { Assert.notNull(projectType, "Project type required"); ProjectMetadata md = (ProjectMetadata) get(ProjectMetadata.getProjectIdentifier()); @@ -238,7 +283,6 @@ XmlUtils.writeXml(mutableFile.getOutputStream(), document); } - public void onFileEvent(FileEvent fileEvent) { Assert.notNull(fileEvent, "File event required"); @@ -256,4 +300,35 @@ } } + // remove an element identified by dependency, whenever it occurs at path + private void removeDependency(Dependency dependency, String containingPath, String path) { + Assert.notNull(dependency, "Dependency to remove required"); + ProjectMetadata md = (ProjectMetadata) get(ProjectMetadata.getProjectIdentifier()); + Assert.notNull(md, "Project metadata is not yet available, so dependency addition is unavailable"); + if (!md.isDependencyRegistered(dependency)) { + return; + } + + MutableFile mutableFile = fileManager.updateFile(pom); + + Document document; + try { + document = XmlUtils.getDocumentBuilder().parse(mutableFile.getInputStream()); + } catch (Exception ex) { + throw new IllegalStateException("Could not open POM '" + pom + "'", ex); + } + + Element rootElement = (Element) document.getFirstChild(); + Element dependencies = XmlUtils.findFirstElement(containingPath, rootElement); + + for(Element candidate : XmlUtils.findElements(path, rootElement)) { + if (dependency.equals(new Dependency(candidate))) { + // Found it + dependencies.removeChild(candidate); + // We will not break the loop (even though we could theoretically), just in case it was declared in the POM more than once + } + } + + XmlUtils.writeXml(mutableFile.getOutputStream(), document); + } } Index: addon-maven/src/main/java/org/springframework/roo/addon/maven/ApplicationContextOperations.java =================================================================== --- addon-maven/src/main/java/org/springframework/roo/addon/maven/ApplicationContextOperations.java (revision 184) +++ addon-maven/src/main/java/org/springframework/roo/addon/maven/ApplicationContextOperations.java (working copy) @@ -52,7 +52,7 @@ XmlUtils.findFirstElementByName("context:component-scan", rootElement).setAttribute("base-package", projectMetadata.getTopLevelPackage().getFullyQualifiedPackageName()); PathResolver pathResolver = projectMetadata.getPathResolver(); - MutableFile mutableFile = fileManager.createFile(pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml")); + MutableFile mutableFile = fileManager.createFile(pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml")); XmlUtils.writeXml(mutableFile.getOutputStream(), pom); fileManager.scanAll(); Index: addon-maven/src/main/resources/org/springframework/roo/addon/maven/applicationContext-template.xml =================================================================== --- addon-maven/src/main/resources/org/springframework/roo/addon/maven/applicationContext-template.xml (revision 184) +++ addon-maven/src/main/resources/org/springframework/roo/addon/maven/applicationContext-template.xml (working copy) @@ -10,7 +10,7 @@ http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> - + Index: addon-maven/src/main/resources/org/springframework/roo/addon/maven/pom-template.xml =================================================================== --- addon-maven/src/main/resources/org/springframework/roo/addon/maven/pom-template.xml (revision 184) +++ addon-maven/src/main/resources/org/springframework/roo/addon/maven/pom-template.xml (working copy) @@ -24,7 +24,38 @@ SpringSource Enterprise Bundle Repository - External Bundle Milestones http://repository.springsource.com/maven/bundles/milestone + + + + com.springsource.repository.bundles.snapshot + SpringSource Enterprise Bundle Repository - External Bundle Snapshots + http://repository.springsource.com/maven/bundles/snapshot + + + com.springsource.repository.bundles.external.snapshots + SpringSource Enterprise Bundle Repository - Third Party External Bundle Snapshots + http://private.repository.springsource.com.s3.amazonaws.com/maven/bundles/external + + + + + + com.springsource.repository.bundles.release + SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases + http://repository.springsource.com/maven/bundles/release + + + com.springsource.repository.bundles.external + SpringSource Enterprise Bundle Repository - External Bundle Releases + http://repository.springsource.com/maven/bundles/external + + + com.springsource.repository.bundles.milestone + SpringSource Enterprise Bundle Repository - External Bundle Milestones + http://repository.springsource.com/maven/bundles/milestone + + Index: addon-security/src/main/java/org/springframework/roo/addon/security/SecurityOperations.java =================================================================== --- addon-security/src/main/java/org/springframework/roo/addon/security/SecurityOperations.java (revision 184) +++ addon-security/src/main/java/org/springframework/roo/addon/security/SecurityOperations.java (working copy) @@ -62,7 +62,7 @@ projectOperations.dependencyUpdate(DEPENDENCY); // copy the template across - String destination = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-security.xml"); + String destination = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-security.xml"); if (!fileManager.exists(destination)) { try { FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), "applicationContext-security-template.xml"), fileManager.createFile(destination).getOutputStream()); Index: pom.xml =================================================================== --- pom.xml (revision 184) +++ pom.xml (working copy) @@ -10,39 +10,40 @@ annotations support - model + model shell shell-jline - metadata + metadata file-undo file-monitor file-monitor-polling project process-manager - classpath - classpath-javaparser - addon-maven - addon-plural - addon-propfiles - addon-beaninfo - addon-configurable - addon-email - addon-javabean - addon-jpa - addon-jms - addon-finder - addon-logging - addon-entity - addon-property-editor - addon-security - addon-tostring - addon-web-flow - addon-web-mvc-controller - addon-web-mvc-jsp - addon-web-menu - addon-web-selenium - addon-dod - addon-test + classpath + classpath-javaparser + addon-maven + addon-plural + addon-propfiles + addon-beaninfo + addon-configurable + addon-email + addon-javabean + addon-jpa + addon-jms + addon-finder + addon-logging + addon-entity + addon-property-editor + addon-security + addon-tostring + addon-web-flow + addon-web-mvc-controller + addon-web-mvc-jsp + addon-web-menu + addon-web-selenium + addon-dod + addon-test + addon-bundlor bootstrap Index: addon-web-mvc-controller/src/main/java/org/springframework/roo/addon/web/mvc/controller/WebMvcOperations.java =================================================================== --- addon-web-mvc-controller/src/main/java/org/springframework/roo/addon/web/mvc/controller/WebMvcOperations.java (revision 184) +++ addon-web-mvc-controller/src/main/java/org/springframework/roo/addon/web/mvc/controller/WebMvcOperations.java (working copy) @@ -213,7 +213,7 @@ // Verify the middle tier application context already exists PathResolver pathResolver = projectMetadata.getPathResolver(); - Assert.isTrue(fileManager.exists(pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml")), "Application context does not exist"); + Assert.isTrue(fileManager.exists(pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml")), "Application context does not exist"); String servletCtxFilename = "WEB-INF/" + projectMetadata.getProjectName() + "-servlet.xml"; if (fileManager.exists(pathResolver.getIdentifier(Path.SRC_MAIN_WEBAPP, servletCtxFilename))) { Index: addon-web-mvc-controller/src/main/resources/org/springframework/roo/addon/web/mvc/controller/web-template.xml =================================================================== --- addon-web-mvc-controller/src/main/resources/org/springframework/roo/addon/web/mvc/controller/web-template.xml (revision 184) +++ addon-web-mvc-controller/src/main/resources/org/springframework/roo/addon/web/mvc/controller/web-template.xml (working copy) @@ -11,7 +11,7 @@ contextConfigLocation - classpath*:applicationContext*.xml + classpath*:META-INF/spring/applicationContext*.xml Index: project/src/main/java/org/springframework/roo/project/ProjectMetadataProvider.java =================================================================== --- project/src/main/java/org/springframework/roo/project/ProjectMetadataProvider.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/ProjectMetadataProvider.java (working copy) @@ -37,8 +37,35 @@ */ public void removeDependency(Dependency dependency); + /** + * Attempts to add the specified build plugin dependency. If the dependency already exists + * according to {@link ProjectMetadata#isBuildPluginDependencyRegistered(Dependency)}, + * the method silently returns. Otherwise the dependency is added. + * + *

+ * An exception is thrown if this method is called before there is {@link ProjectMetadata} + * available, or if the on-disk representation cannot be modified for any reason. + * + * @param dependency to add (required) + * @param execution specifications for build plugin (optional) + */ + public void addBuildPluginDependency(Dependency dependency,Execution... executions); /** + * Attempts to remove the specified build plugin dependency. If the dependency does not + * exist according to {@link ProjectMetadata#isBuildPluginDependencyRegistered(Dependency)}, + * the method silently returns. Otherwise the located dependency is removed. + * + *

+ * An exception is thrown if this method is called before there is {@link ProjectMetadata} + * available, or if the on-disk representation cannot be modified for any reason. + * + * @param dependency to remove (required) + */ + public void removeBuildPluginDependency(Dependency dependency); + + + /** * Attempts to update the project packaging type as defined via {@link ProjectType}. If the * project packaging is not defined it will create a new definition. * Index: project/src/main/java/org/springframework/roo/project/Execution.java =================================================================== --- project/src/main/java/org/springframework/roo/project/Execution.java (revision 0) +++ project/src/main/java/org/springframework/roo/project/Execution.java (revision 0) @@ -0,0 +1,31 @@ +package org.springframework.roo.project; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.springframework.roo.support.util.Assert; + +/** + * Immutable representation of an execution specification for a (maven) build plugin + * + * @author Adrian Colyer + * @since 1.0 + * + */ +public final class Execution { + private final String id; + private final List goals; + + public Execution(String id, String... goals) { + Assert.notNull(id, "execution id must be specified"); + Assert.notEmpty(goals, "at least one goal must be specified"); + this.id = id; + this.goals = Collections.unmodifiableList(Arrays.asList(goals)); + } + + public String getId() { return this.id; } + + public List getGoals() { return this.goals; } + +} Index: project/src/main/java/org/springframework/roo/project/ProjectMetadata.java =================================================================== --- project/src/main/java/org/springframework/roo/project/ProjectMetadata.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/ProjectMetadata.java (working copy) @@ -37,17 +37,20 @@ private JavaPackage topLevelPackage; private String projectName; private Set dependencies; + private Set buildPluginDependencies; private PathResolver pathResolver; - public ProjectMetadata(JavaPackage topLevelPackage, String projectName, Set dependencies, PathResolver pathResolver) { + public ProjectMetadata(JavaPackage topLevelPackage, String projectName, Set dependencies, Set buildPluginDependencies, PathResolver pathResolver) { super(PROJECT_IDENTIFIER); Assert.notNull(topLevelPackage, "Top level package required"); Assert.notNull(projectName, "Project name required"); Assert.notNull(dependencies, "Dependencies required"); + Assert.notNull(buildPluginDependencies, "Build plugin dependencies required"); Assert.notNull(pathResolver, "Path resolver required"); this.topLevelPackage = topLevelPackage; this.projectName = projectName; this.dependencies = dependencies; + this.buildPluginDependencies = buildPluginDependencies; this.pathResolver = pathResolver; } @@ -65,6 +68,18 @@ Assert.notNull(dependency, "Dependency to check is required"); return dependencies.contains(dependency); } + + /** + * Convenience method for determining whether a particular build plugin dependency + * is registered. + * + * @param dependency to check (required) + * @return whether the build plugin dependency is currently registered or not + */ + public boolean isBuildPluginDependencyRegistered(Dependency dependency) { + Assert.notNull(dependency, "Dependency to check is required"); + return buildPluginDependencies.contains(dependency); + } public JavaPackage getTopLevelPackage() { return topLevelPackage; @@ -104,6 +119,34 @@ return result; } + /** + * @return an unmodifiable collection of the build plugin dependencies (never null, but + * may be empty). + */ + public Set getBuildPluginDependencies() { + return Collections.unmodifiableSet(buildPluginDependencies); + } + + /** + * Locates any build plugin dependencies which match the presented dependency, excluding the version number. + * This is useful for upgrade use cases, where it is necessary to locate any build plugin dependencies with + * the same group, artifact and type identifications so that they can be removed. + * + * @param dependency to locate (required; note the version number is ignored in comparisons) + * @return any matching dependencies (never returns null, but may return an empty {@link Set}) + */ + public Set getBuildPluginDependenciesExcludingVersion(Dependency dependency) { + Assert.notNull(dependency, "Dependency to locate is required"); + Set result = new HashSet(); + for (Dependency d : buildPluginDependencies) { + if (dependency.getArtifactId().equals(d.getArtifactId()) && dependency.getGroupId().equals(d.getGroupId()) && dependency.getType().equals(d.getType())) { + result.add(d); + } + } + return result; + } + + public final String toString() { ToStringCreator tsc = new ToStringCreator(this); tsc.append("identifier", getId()); @@ -111,6 +154,7 @@ tsc.append("topLevelPackage", topLevelPackage); tsc.append("projectName", projectName); tsc.append("dependencies", dependencies); + tsc.append("buildPluginDependencies", buildPluginDependencies); tsc.append("pathResolver", pathResolver); return tsc.toString(); } Index: project/src/main/java/org/springframework/roo/project/ProjectOperations.java =================================================================== --- project/src/main/java/org/springframework/roo/project/ProjectOperations.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/ProjectOperations.java (working copy) @@ -9,6 +9,7 @@ * Provides common project operations. Should be subclassed by a project-specific operations subclass. * * @author Ben Alex + * @author Adrian Colyer * @since 1.0 * */ @@ -54,9 +55,9 @@ * Provides a convenient way for third parties to instruct end users how to use the CLI to remove an unwanted * dependency from their projects without requiring the user to manually edit a pom.xml or write an add-on. * - * @param groupId to add (required) - * @param artifactId to add (required) - * @param versionId to add (requireD) + * @param groupId to remove (required) + * @param artifactId to remove (required) + * @param versionId to remove (requireD) */ public final void removeDependency(JavaPackage groupId, JavaSymbolName artifactId, String version) { Assert.isTrue(isDependencyModificationAllowed(), "Dependency modification prohibited at this time"); @@ -100,4 +101,76 @@ projectMetadataProvider.updateProjectType(projectType); } + + /** + * Allows addition of a build plugin to the POM. + * + *

+ * Provides a convenient way for third parties to instruct end users how to use the CLI to add + * a new build capability to their projects without requiring the user to manually edit a pom.xml or write an add-on. + * + * @param groupId to add (required) + * @param artifactId to add (required) + * @param versionId to add (requireD) + * @param executions to execute when the project is built (optional) + */ + public final void addPluginDependency( + JavaPackage groupId, JavaSymbolName artifactId, String version, + Execution... executions) { + Assert.isTrue(isDependencyModificationAllowed(), "Dependency modification prohibited at this time"); + Assert.notNull(groupId, "Group ID required"); + Assert.notNull(artifactId, "Artifact ID required"); + Assert.hasText(version, "Version required"); + Dependency dependency = new Dependency(groupId, artifactId, version, DependencyType.JAR); + projectMetadataProvider.addBuildPluginDependency(dependency,executions); + } + + /** + * Allows remove of an existing build plugin from the POM. + * + *

+ * Provides a convenient way for third parties to instruct end users how to use the CLI to remove an unwanted + * build plugin from their projects without requiring the user to manually edit a pom.xml or write an add-on. + * + * @param groupId to remove (required) + * @param artifactId to remove (required) + * @param versionId to remove (requireD) + */ + public final void removeBuildPlugin(JavaPackage groupId, JavaSymbolName artifactId, String version) { + Assert.isTrue(isDependencyModificationAllowed(), "Dependency modification prohibited at this time"); + Assert.notNull(groupId, "Group ID required"); + Assert.notNull(artifactId, "Artifact ID required"); + Assert.hasText(version, "Version required"); + Dependency dependency = new Dependency(groupId, artifactId, version, DependencyType.JAR); + projectMetadataProvider.removeBuildPluginDependency(dependency); + } + + /** + * Verifies if the specified build plugin is present. If it is present, silently returns. If it is not + * present, removes any build plugin which matches {@link ProjectMetadata#getBuildPluginsExcludingVersion(Dependency)}. + * Always adds the presented dependency. + * + * @param dependency build plugin to add (required) + * @param executions to be executed when project is built (optional) + */ + public void buildPluginUpdate(Dependency buildPluginDependency, Execution... executions) { + Assert.isTrue(isDependencyModificationAllowed(), "Dependency modification prohibited at this time"); + Assert.notNull(buildPluginDependency, "Dependency required"); + ProjectMetadata projectMetadata = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier()); + Assert.notNull(projectMetadata, "Project metadata unavailable"); + + if (projectMetadata.isBuildPluginDependencyRegistered(buildPluginDependency)) { + // Already exists, so just quit + return; + } + + // Delete any existing dependencies with a different version + for (Dependency existing : projectMetadata.getBuildPluginDependenciesExcludingVersion(buildPluginDependency)) { + projectMetadataProvider.removeBuildPluginDependency(existing); + } + + // Add the dependency + projectMetadataProvider.addBuildPluginDependency(buildPluginDependency,executions); + } + } Index: project/src/main/java/org/springframework/roo/project/Path.java =================================================================== --- project/src/main/java/org/springframework/roo/project/Path.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/Path.java (working copy) @@ -26,6 +26,7 @@ public static final Path SRC_TEST_RESOURCES = new Path("SRC_TEST_RESOURCES"); public static final Path SRC_MAIN_WEBAPP = new Path("SRC_MAIN_WEBAPP"); public static final Path ROOT = new Path("ROOT"); + public static final Path SPRING_CONFIG_ROOT = new Path("SPRING_CONFIG_ROOT"); private String name; Index: project/src/main/java/org/springframework/roo/project/Dependency.java =================================================================== --- project/src/main/java/org/springframework/roo/project/Dependency.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/Dependency.java (working copy) @@ -94,7 +94,14 @@ if(dependency.hasChildNodes()) { this.groupId = new JavaPackage(dependency.getElementsByTagName("groupId").item(0).getTextContent()); this.artifactId = new JavaSymbolName(dependency.getElementsByTagName("artifactId").item(0).getTextContent()); - this.versionId = dependency.getElementsByTagName("version").item(0).getTextContent(); + + NodeList versionElements = dependency.getElementsByTagName("version"); + if (versionElements.getLength() > 0) { + this.versionId = dependency.getElementsByTagName("version").item(0).getTextContent(); + } + else { + this.versionId = ""; + } //parsing for exclusions NodeList exclusionList = dependency.getElementsByTagName("exclusions"); Index: project/src/main/java/org/springframework/roo/project/PathResolver.java =================================================================== --- project/src/main/java/org/springframework/roo/project/PathResolver.java (revision 184) +++ project/src/main/java/org/springframework/roo/project/PathResolver.java (working copy) @@ -112,6 +112,7 @@ *

  • {@link Path#SRC_TEST_JAVA}
  • *
  • {@link Path#SRC_TEST_RESOURCES}
  • *
  • {@link Path#ROOT}
  • + *
  • {@link Path#SPRING_CONFIG_ROOT}
  • * * * @return all supported paths (never null and never empty) Index: addon-logging/src/main/java/org/springframework/roo/addon/logging/LoggingOperations.java =================================================================== --- addon-logging/src/main/java/org/springframework/roo/addon/logging/LoggingOperations.java (revision 184) +++ addon-logging/src/main/java/org/springframework/roo/addon/logging/LoggingOperations.java (working copy) @@ -54,7 +54,7 @@ } private void setupProperties(LogLevel logLevel, LoggerPackage loggerPackage) { - String filePath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "log4j.properties"); + String filePath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "log4j.properties"); MutableFile log4jMutableFile = null; Properties props = new Properties(); Index: addon-jms/src/main/java/org/springframework/roo/addon/jms/JmsOperations.java =================================================================== --- addon-jms/src/main/java/org/springframework/roo/addon/jms/JmsOperations.java (revision 184) +++ addon-jms/src/main/java/org/springframework/roo/addon/jms/JmsOperations.java (working copy) @@ -80,12 +80,12 @@ } public boolean isManageJmsAvailable() { - return fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-jms.xml")); + return fileManager.exists(getPathResolver().getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-jms.xml")); } public void installJms(JmsProvider jmsProvider, String name, JmsDestinationType destinationType) { Assert.notNull(jmsProvider, "Jms provider required"); - String jmsContextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-jms.xml"); + String jmsContextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-jms.xml"); MutableFile jmsContextMutableFile = null; Document appCtx; @@ -94,7 +94,7 @@ jmsContextMutableFile = fileManager.updateFile(jmsContextPath); appCtx = XmlUtils.getDocumentBuilder().parse(jmsContextMutableFile.getInputStream()); } else { - FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), "applicationContext-jms-template.xml"), fileManager.createFile(pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-jms.xml")).getOutputStream()); + FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), "applicationContext-jms-template.xml"), fileManager.createFile(pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-jms.xml")).getOutputStream()); jmsContextMutableFile = fileManager.updateFile(jmsContextPath); appCtx = XmlUtils.getDocumentBuilder().parse(jmsContextMutableFile.getInputStream()); } @@ -195,7 +195,7 @@ physicalTypeMetadataProvider.createPhysicalType(toCreate); - String jmsContextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-jms.xml"); + String jmsContextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-jms.xml"); MutableFile jmsContextMutableFile = null; Document appCtx; Index: bootstrap/pom.xml =================================================================== --- bootstrap/pom.xml (revision 184) +++ bootstrap/pom.xml (working copy) @@ -237,6 +237,12 @@
    org.springframework.roo + org.springframework.roo.addon.bundlor + ${roo.version} + provided + + + org.springframework.roo org.springframework.roo.classpath ${roo.version} provided @@ -291,5 +297,6 @@ com.springsource.slf4j.juli 1.5.6 + Index: classpath/src/main/java/org/springframework/roo/classpath/converters/PathConverter.java =================================================================== --- classpath/src/main/java/org/springframework/roo/classpath/converters/PathConverter.java (revision 184) +++ classpath/src/main/java/org/springframework/roo/classpath/converters/PathConverter.java (working copy) @@ -28,6 +28,7 @@ legalValues.add(Path.SRC_MAIN_WEBAPP.getName()); legalValues.add(Path.SRC_TEST_JAVA.getName()); legalValues.add(Path.SRC_TEST_RESOURCES.getName()); + legalValues.add(Path.SPRING_CONFIG_ROOT.getName()); } // TODO: Allow context to limit to source paths only, limit to resource paths only Property changes on: addon-bundlor ___________________________________________________________________ Name: svn:ignore + .* target Index: addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/ManifestTemplate.java =================================================================== --- addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/ManifestTemplate.java (revision 0) +++ addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/ManifestTemplate.java (revision 0) @@ -0,0 +1,223 @@ +package org.springframework.roo.addon.bundlor; + +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.springframework.roo.process.manager.FileManager; + +import com.springsource.util.osgi.manifest.BundleManifest; +import com.springsource.util.osgi.manifest.BundleManifestFactory; +import com.springsource.util.osgi.manifest.parse.ParserLogger; +import com.springsource.util.parser.manifest.ManifestContents; +import com.springsource.util.parser.manifest.ManifestParser; +import com.springsource.util.parser.manifest.ManifestProblem; +import com.springsource.util.parser.manifest.RecoveringManifestParser; + +/** + * Utility class for modifying template.mf files + * Defensively coded to encapsulate and log all errors that may occur + * while manipulating the manifest. + * + * @author Adrian Colyer + * @since 1.0 + * + */ +public class ManifestTemplate { + + final static Logger logger = Logger.getLogger(ManifestTemplate.class.getName()); + + private static final String EXCLUDED_EXPORTS = "Excluded-Exports"; + private static final String IMPORT_TEMPLATE = "Import-Template"; + private static final String EXPORT_TEMPLATE = "Export-Template"; + private static final String IMPORT_PACKAGE = "Import-Package"; + + private BundleManifest mf = null; + private boolean manifestOK = true; + private FileManager fileManager; + private String templateMfPath; + private JDKLoggerParserLogger parserLogger = new JDKLoggerParserLogger(); + + + public ManifestTemplate(FileManager fileManager, String pathToTemplateMfFile) { + this.fileManager = fileManager; + this.templateMfPath = pathToTemplateMfFile; + ManifestParser parser = new RecoveringManifestParser(); + try { + ManifestContents manifestContent = parser.parse(new FileReader(pathToTemplateMfFile)); + if (parser.foundProblems()) { + manifestOK = false; + logParsingErrors(parser.getProblems()); + } + else { + mf = BundleManifestFactory.createBundleManifest(manifestContent, parserLogger); + if (parserLogger.hasReportedErrors()) { + logger.log(Level.SEVERE,"Could not process template.mf file, bundlor command aborted"); + manifestOK = false; + mf = null; + } + } + } + catch (Exception ex) { + mf = null; + manifestOK = false; + logger.log(Level.SEVERE, "Could not process template.mf file, bundlor command aborted", ex); + } + } + + + public ManifestTemplate addExcludeExport(String packagePattern) { + if (manifestOK) { + // current header value + String excludeExportHeader = mf.getHeader(EXCLUDED_EXPORTS); + if (null == excludeExportHeader) { excludeExportHeader = ""; } + excludeExportHeader = excludeExportHeader.trim(); + + // add new exclusion + if (excludeExportHeader.length() != 0) { + excludeExportHeader += ", "; + } + excludeExportHeader += packagePattern; + + // save it back + mf.setHeader(EXCLUDED_EXPORTS, excludeExportHeader); + + if (parserLogger.hasReportedErrors()) { + logger.log(Level.SEVERE, "bundlor command aborted due to ill-formed manifest header"); + } + } + + return this; + } + + public ManifestTemplate addExportTemplate(String packagePattern, String version) { + if (manifestOK) { + // current header value + String exportTemplateHeader = mf.getHeader(EXPORT_TEMPLATE); + if (null == exportTemplateHeader) { exportTemplateHeader = ""; } + exportTemplateHeader = exportTemplateHeader.trim(); + + // add new export + if (exportTemplateHeader.length() != 0) { + exportTemplateHeader += ", "; + } + exportTemplateHeader += (packagePattern + ";version=\"" + version + "\""); + + // save it back + mf.setHeader(EXPORT_TEMPLATE, exportTemplateHeader); + + if (parserLogger.hasReportedErrors()) { + logger.log(Level.SEVERE, "bundlor command aborted due to ill-formed manifest header"); + } + } + + return this; + } + + public ManifestTemplate addImportTemplate(String packagePattern, String versionRange, + boolean optional) { + if (manifestOK) { + // current header value + String importTemplateHeader = mf.getHeader(IMPORT_TEMPLATE); + if (null == importTemplateHeader) { importTemplateHeader = ""; } + importTemplateHeader = importTemplateHeader.trim(); + + // add new import + if (importTemplateHeader.length() != 0) { + importTemplateHeader += ", "; + } + importTemplateHeader += (packagePattern + ";version=\"" + versionRange + "\""); + if (optional) { + importTemplateHeader += ";resolution:=optional"; + } + + // save it back + mf.setHeader(IMPORT_TEMPLATE, importTemplateHeader); + + if (parserLogger.hasReportedErrors()) { + logger.log(Level.SEVERE, "bundlor command aborted due to ill-formed manifest header"); + } + } + + return this; + + } + + public ManifestTemplate addImportPackage(String packageName, String versionRange, + boolean optional) { + if (manifestOK) { + // current header value + String importPackageHeader = mf.getHeader(IMPORT_PACKAGE); + if (null == importPackageHeader) { importPackageHeader = ""; } + importPackageHeader = importPackageHeader.trim(); + + // add new import + if (importPackageHeader.length() != 0) { + importPackageHeader += ", "; + } + importPackageHeader += (packageName + ";version=\"" + versionRange + "\""); + if (optional) { + importPackageHeader += ";resolution:=optional"; + } + + // save it back + mf.setHeader(IMPORT_PACKAGE, importPackageHeader); + + if (parserLogger.hasReportedErrors()) { + logger.log(Level.SEVERE, "bundlor command aborted due to ill-formed manifest header"); + } + } + return this; + + } + + public void writeOut() { + if (manifestOK) { + try { + mf.write(new OutputStreamWriter( + fileManager.updateFile(templateMfPath).getOutputStream())); + } catch (IOException e) { + logger.log(Level.SEVERE, "Unable to write template.mf contents, bundlor command aborted", e); + } + } + } + + private void logParsingErrors(List problems) { + StringBuffer problemText = new StringBuffer(); + for (ManifestProblem problem : problems) { + problemText.append(problem.toStringWithContext()); + problemText.append("\n"); + } + logger.log(Level.SEVERE,"Problems found parsing template.mf, bundlor command aborted: " + + problemText.toString()); + } + + /* helper class to route parsing messages through the regular + * ManifestTemplate logger + */ + private static class JDKLoggerParserLogger implements ParserLogger { + + private boolean hasReportedErrors = false; + + public boolean hasReportedErrors() { + return hasReportedErrors; + } + + public String[] errorReports() { + return new String[0]; + } + + public void outputErrorMsg(Exception re, String item) { + hasReportedErrors = true; + ManifestTemplate.logger.log( + Level.WARNING, + "Error parsing template.mf: " + item, + re); + } + + } + +} Index: addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorCommands.java =================================================================== --- addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorCommands.java (revision 0) +++ addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorCommands.java (revision 0) @@ -0,0 +1,105 @@ +package org.springframework.roo.addon.bundlor; + +import org.springframework.roo.shell.CliAvailabilityIndicator; +import org.springframework.roo.shell.CliCommand; +import org.springframework.roo.shell.CliOption; +import org.springframework.roo.shell.CommandMarker; +import org.springframework.roo.support.lifecycle.ScopeDevelopment; +import org.springframework.roo.support.util.Assert; + +/** + * Commands for the Bundlor add-on to be used by the Roo shell + * + * @author Adrian Colyer + * @since 1.0 + * + */ +@ScopeDevelopment +public class BundlorCommands implements CommandMarker { + + private final BundlorOperations bundlorOperations; + + public BundlorCommands(BundlorOperations bundlorOperations) { + Assert.notNull(bundlorOperations, "bundlor operations required"); + this.bundlorOperations = bundlorOperations; + } + + // install bundlor + + @CliAvailabilityIndicator("install bundlor") + public boolean isInstallBundlorAvailable() { + return bundlorOperations.isInstallBundlorAvailable(); + } + + @CliCommand(value="install bundlor", + help="automatically create and manage an OSGi manifest for this project using Bundlor") + public void installBundlor( + @CliOption(key={"bundleName"},mandatory=false,help="Human readable name for the bundle") String bundleName) + { + bundlorOperations.installBundlor(bundleName); + } + + // template management + + @CliAvailabilityIndicator( + {"bundlor non-exported packages", + "bundlor version package exports", + "bundlor configure imports", + "bundlor add explicit import", + "bundlor show template"}) + public boolean isTemplateManagementAvailable() { + return bundlorOperations.isTemplateManagementAvailable(); + } + + + @CliCommand(value="bundlor non-exported packages", + help="specify packages that should not be exported by the bundle") + public void bundlorMakePrivate( + @CliOption(key="packagePattern",mandatory=true,help="package name with optional .* postfix") + String packagePattern) { + bundlorOperations.excludeFromExport(packagePattern); + } + + @CliCommand(value="bundlor version package exports", + help="specify version to export individual packages at (defaults to bundle version)") + public void bundlorVersionExports( + @CliOption(key="packagePattern",mandatory=true,help="package name with optional .* postfix") + String packagePattern, + @CliOption(key="version",mandatory=true,help="version to export package at") + String version) { + bundlorOperations.versionExports(packagePattern, version); + } + + @CliCommand(value="bundlor configure imports", + help="specify version range for package imports, and whether they are optional") + public void bundlorConfigureImports( + @CliOption(key="packagePattern",mandatory=true,help="package name with optional .* postfix") + String packagePattern, + @CliOption(key="fromVersion",mandatory=true,help="minimum version to accept") + String fromVersion, + @CliOption(key="toVersion",mandatory=true,help="version range ceiling, use INF for infinity") + String toVersion, + @CliOption(key="inclusiveUpperBound",mandatory=false,specifiedDefaultValue="true",unspecifiedDefaultValue="false",help="should upper version be inclusive (default = exclusive)") + boolean inclusiveUpperBound, + @CliOption(key="optional",mandatory=false,specifiedDefaultValue="true",unspecifiedDefaultValue="false",help="treat package import as optional (default = mandatory)") + boolean optional) { + bundlorOperations.configureImports(packagePattern, fromVersion, toVersion, inclusiveUpperBound, optional); + } + + @CliCommand(value="bundlor add explicit import", + help="Add an explicit import for a dependency Bundlor cannot detect") + public void bundlorAddImport( + @CliOption(key="package",mandatory=true,help="package to import") + String packageName, + @CliOption(key="fromVersion",mandatory=true,help="minimum version to accept") + String fromVersion, + @CliOption(key="toVersion",mandatory=true,help="version range ceiling, use INF for infinity") + String toVersion, + @CliOption(key="inclusiveUpperBound",mandatory=false,specifiedDefaultValue="true",unspecifiedDefaultValue="false",help="should upper version be inclusive (default = exclusive)") + boolean inclusiveUpperBound, + @CliOption(key="optional",mandatory=false,specifiedDefaultValue="true",unspecifiedDefaultValue="false",help="treat package import as optional (default = mandatory)") + boolean optional) { + bundlorOperations.addExplicitImport(packageName, fromVersion, toVersion, inclusiveUpperBound, optional); + } + +} Index: addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorOperations.java =================================================================== --- addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorOperations.java (revision 0) +++ addon-bundlor/src/main/java/org/springframework/roo/addon/bundlor/BundlorOperations.java (revision 0) @@ -0,0 +1,140 @@ +package org.springframework.roo.addon.bundlor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.logging.Logger; + +import org.springframework.roo.metadata.MetadataService; +import org.springframework.roo.process.manager.FileManager; +import org.springframework.roo.project.Dependency; +import org.springframework.roo.project.Execution; +import org.springframework.roo.project.Path; +import org.springframework.roo.project.PathResolver; +import org.springframework.roo.project.ProjectMetadata; +import org.springframework.roo.project.ProjectOperations; +import org.springframework.roo.support.lifecycle.ScopeDevelopment; +import org.springframework.roo.support.util.Assert; +import org.springframework.roo.support.util.FileCopyUtils; +import org.springframework.roo.support.util.TemplateUtils; + +/** + * Provides Bundlor installation and manifest management services. + * + * @author Adrian Colyer + * @since 1.0 + * + */ +@ScopeDevelopment +public class BundlorOperations { + + private static final Dependency PLUGIN_DEPENDENCY = new Dependency("com.springsource.bundlor", "com.springsource.bundlor.maven", "1.0.0.M5"); + private static final String INFINITY="INF"; + + Logger logger = Logger.getLogger(BundlorOperations.class.getName()); + + private FileManager fileManager; + private PathResolver pathResolver; + private MetadataService metadataService; + private ProjectOperations projectOperations; + + public BundlorOperations(FileManager fileManager, PathResolver pathResolver, MetadataService metadataService, ProjectOperations projectOperations) { + Assert.notNull(fileManager, "File manager required"); + Assert.notNull(pathResolver, "Path resolver required"); + Assert.notNull(metadataService, "Metadata service required"); + Assert.notNull(projectOperations, "Project operations required"); + this.fileManager = fileManager; + this.pathResolver = pathResolver; + this.metadataService = metadataService; + this.projectOperations = projectOperations; + } + + public boolean isInstallBundlorAvailable() { + ProjectMetadata project = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier()); + if (project == null) { + return false; + } + // only permit installation if they don't already have some version of Bundlor installed + return project.getBuildPluginDependenciesExcludingVersion(PLUGIN_DEPENDENCY).isEmpty(); + } + + public void installBundlor(String bundleName) { + projectOperations.buildPluginUpdate(PLUGIN_DEPENDENCY,new Execution("bundlor","transform")); + + // copy the template across + String destination = pathResolver.getIdentifier(Path.ROOT, "template.mf"); + if (!fileManager.exists(destination)) { + writeTemplateFile(destination,bundleName); + } + + } + + public boolean isTemplateManagementAvailable() { + String template = pathResolver.getIdentifier(Path.ROOT, "template.mf"); + return (new File(template).exists()); + } + + private void writeTemplateFile(String destination,String bundleName) { + try { + ProjectMetadata project = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier()); + String mfFile = FileCopyUtils.copyToString(new InputStreamReader(TemplateUtils.getTemplate(getClass(), "template.mf"))); + mfFile = mfFile.replaceAll("#topLevelPackage#", project.getTopLevelPackage().toString()); + String bundleNameReplacement = project.getProjectName(); + if (null != bundleName) { + bundleNameReplacement = bundleName; + } + mfFile = mfFile.replaceAll("#bundleName#",bundleNameReplacement); + FileCopyUtils.copy(mfFile,new OutputStreamWriter(fileManager.createFile(destination).getOutputStream())); + } catch (IOException ioe) { + throw new IllegalStateException(ioe); + } + } + + public void excludeFromExport(String packagePattern) { + getManifestTemplate() + .addExcludeExport(packagePattern) + .writeOut(); + } + + public void versionExports(String packagePattern, String version) { + getManifestTemplate() + .addExportTemplate(packagePattern,version) + .writeOut(); + } + + public void configureImports(String packagePattern, String fromVersion, String toVersion, boolean inclusiveUpper, boolean optional) { + String versionRange = makeVersionRange(fromVersion,toVersion,inclusiveUpper); + getManifestTemplate() + .addImportTemplate(packagePattern,versionRange,optional) + .writeOut(); + } + + public void addExplicitImport(String packageName, String fromVersion, String toVersion, boolean inclusiveUpper, boolean optional) { + String versionRange = makeVersionRange(fromVersion,toVersion,inclusiveUpper); + getManifestTemplate() + .addImportPackage(packageName,versionRange,optional) + .writeOut(); + } + + private ManifestTemplate getManifestTemplate() { + return new ManifestTemplate(fileManager,pathResolver.getIdentifier(Path.ROOT, "template.mf")); + } + + private String makeVersionRange(String fromVersion, String toVersion, boolean inclusiveUpper) { + if (fromVersion.equals(toVersion)) { + // always use inclusive upper + return "[" + fromVersion + "," + toVersion + "]"; + } + else { + if (INFINITY.equals(toVersion)) { + return fromVersion; + } + else { + return "[" + fromVersion + "," + toVersion + + (inclusiveUpper? "]" : ")"); + } + } + } + +} Index: addon-bundlor/src/main/resources/org/springframework/roo/addon/bundlor/template.mf =================================================================== --- addon-bundlor/src/main/resources/org/springframework/roo/addon/bundlor/template.mf (revision 0) +++ addon-bundlor/src/main/resources/org/springframework/roo/addon/bundlor/template.mf (revision 0) @@ -0,0 +1,25 @@ +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: #topLevelPackage# +Bundle-Name: #bundleName# +Bundle-Version: 0.1.0.BUILD-SNAPSHOT +Bundle-Classpath: .,META-INF/spring +Excluded-Exports: *.internal.* +Import-Template: org.tuckey.web.filters.urlrewrite.*;version="[3.1.0,3.2.0)", + org.springframework.web.*;version="${spring.version:spring}", + org.springframework.stereotype.*;version="${spring.version:spring}", + org.springframework.beans.*;version="${spring.version:spring}", + org.springframework.context.*;version="${spring.version:spring}", + org.springframework.orm.*;version="${spring.version:spring}", + org.springframework.transaction.*;version="${spring.version:spring}", + org.springframework.jms.*;version="${spring.version:spring}", + org.springframework.ui.*;version="${spring.version:spring}", + org.springframework.validation.*;version="${spring.version:spring}", + org.apache.commons.dbcp.*;version="[1.2.2.osgi,1.2.2.osgi]", + javax.persistence.*;version="[1.0.0,1.1.0)", + javax.validation.*;version="[1.0.0,1.1.0)", + org.hibernate.ejb.*;version="[3.3.2.GA,3.3.3)", + org.aspectj.*;version="${aspectj.version:[=.=.=.=,=.+1.0)}", + org.springframework.js.*;version="[2.0.7,2.1.0)" +Version-Patterns: + spring;pattern="[=.=.=,=.+1.0)", + hibernate;pattern="[=.=.=.=,=.=.+1)" Index: addon-bundlor/pom.xml =================================================================== --- addon-bundlor/pom.xml (revision 0) +++ addon-bundlor/pom.xml (revision 0) @@ -0,0 +1,62 @@ + + + 4.0.0 + + org.springframework.roo + org.springframework.roo.parent + 1.0.0.RC1 + + org.springframework.roo.addon.bundlor + jar + Spring Roo - Addon - Bundlor + + + com.springsource.util + com.springsource.util.parser.manifest + 2.0.0.BUILD-20090602.153631-43 + + + com.springsource.util + com.springsource.util.osgi + 2.0.0.BUILD-20090602.153654-43 + + + + + org.springframework.roo + org.springframework.roo.shell + ${roo.version} + provided + + + org.springframework.roo + org.springframework.roo.process.manager + ${roo.version} + provided + + + org.springframework.roo + org.springframework.roo.project + ${roo.version} + provided + + + org.springframework.roo + org.springframework.roo.metadata + ${roo.version} + provided + + + org.springframework.roo + org.springframework.roo.support + ${roo.version} + provided + + + org.springframework.roo + org.springframework.roo.model + ${roo.version} + provided + + + Index: addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaCommands.java =================================================================== --- addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaCommands.java (revision 184) +++ addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaCommands.java (working copy) @@ -56,17 +56,17 @@ @CliCommand(value="database properties", help="Shows database configuration details") public SortedSet databaseProperties() { - return propFileOperations.getPropertyKeys(Path.SRC_MAIN_RESOURCES, "database.properties", true); + return propFileOperations.getPropertyKeys(Path.SPRING_CONFIG_ROOT, "database.properties", true); } @CliCommand(value="database set", help="Changes a particular database property") public void databaseSet(@CliOption(key="key", mandatory=true, help="The property key that should be changed") String key, @CliOption(key="value", mandatory=true, help="The new vale for this property key") String value) { - propFileOperations.changeProperty(Path.SRC_MAIN_RESOURCES, "database.properties", key, value); + propFileOperations.changeProperty(Path.SPRING_CONFIG_ROOT, "database.properties", key, value); } @CliCommand(value="database remove", help="Removes a particular database property") public void databaseRemove(@CliOption(key={"","key"}, mandatory=true, help="The property key that should be removed") String key) { - propFileOperations.removeProperty(Path.SRC_MAIN_RESOURCES, "database.properties", key); + propFileOperations.removeProperty(Path.SPRING_CONFIG_ROOT, "database.properties", key); } /** Index: addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaOperations.java =================================================================== --- addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaOperations.java (revision 184) +++ addon-jpa/src/main/java/org/springframework/roo/addon/jpa/JpaOperations.java (working copy) @@ -77,7 +77,7 @@ } private void updateApplicationContext(JdbcDatabase database, String jndi) { - String contextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml"); + String contextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml"); MutableFile contextMutableFile = null; Document appCtx; @@ -153,7 +153,7 @@ } private void updateDatabaseProperties(JdbcDatabase database) { - String databasePath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "database.properties"); + String databasePath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "database.properties"); MutableFile databaseMutableFile = null; Properties props = new Properties(); Index: addon-test/src/main/java/org/springframework/roo/addon/test/IntegrationTestMetadata.java =================================================================== --- addon-test/src/main/java/org/springframework/roo/addon/test/IntegrationTestMetadata.java (revision 184) +++ addon-test/src/main/java/org/springframework/roo/addon/test/IntegrationTestMetadata.java (working copy) @@ -112,7 +112,7 @@ // Add an @ContextConfiguration("classpath:/applicationContext.xml") annotation to the type, if the user did not define it on the governor directly if (MemberFindingUtils.getAnnotationOfType(governorTypeDetails.getTypeAnnotations(), new JavaType("org.springframework.test.context.ContextConfiguration")) == null) { List> ctxCfg = new ArrayList>(); - ctxCfg.add(new StringAttributeValue(new JavaSymbolName("locations"), "classpath:/applicationContext.xml")); + ctxCfg.add(new StringAttributeValue(new JavaSymbolName("locations"), "classpath:/META-INF/spring/applicationContext.xml")); builder.addTypeAnnotation(new DefaultAnnotationMetadata(new JavaType("org.springframework.test.context.ContextConfiguration"), ctxCfg)); } Index: addon-web-flow/src/main/java/org/springframework/roo/addon/web/flow/WebFlowOperations.java =================================================================== --- addon-web-flow/src/main/java/org/springframework/roo/addon/web/flow/WebFlowOperations.java (revision 184) +++ addon-web-flow/src/main/java/org/springframework/roo/addon/web/flow/WebFlowOperations.java (working copy) @@ -63,11 +63,11 @@ } public boolean isInstallWebFlowAvailable() { - return getPathResolver() != null && !fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-webflow.xml")); + return getPathResolver() != null && !fileManager.exists(getPathResolver().getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-webflow.xml")); } public boolean isManageWebFlowAvailable() { - return fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-webflow.xml")); + return fileManager.exists(getPathResolver().getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-webflow.xml")); } /** @@ -86,7 +86,7 @@ //install Web flow config ProjectMetadata projectMetadata = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier()); - String flowContextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-webflow.xml"); + String flowContextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-webflow.xml"); MutableFile webflowContextMutableFile = null; Document appCtx; @@ -95,7 +95,7 @@ webflowContextMutableFile = fileManager.updateFile(flowContextPath); appCtx = XmlUtils.getDocumentBuilder().parse(webflowContextMutableFile.getInputStream()); } else { - FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), "applicationContext-webflow-template.xml"), fileManager.createFile(pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext-webflow.xml")).getOutputStream()); + FileCopyUtils.copy(TemplateUtils.getTemplate(getClass(), "applicationContext-webflow-template.xml"), fileManager.createFile(pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext-webflow.xml")).getOutputStream()); webflowContextMutableFile = fileManager.updateFile(flowContextPath); appCtx = XmlUtils.getDocumentBuilder().parse(webflowContextMutableFile.getInputStream()); } Index: addon-email/src/main/java/org/springframework/roo/addon/email/MailOperations.java =================================================================== --- addon-email/src/main/java/org/springframework/roo/addon/email/MailOperations.java (revision 184) +++ addon-email/src/main/java/org/springframework/roo/addon/email/MailOperations.java (working copy) @@ -71,13 +71,13 @@ } public boolean isManageEmailAvailable() { - return fileManager.exists(getPathResolver().getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml")); + return fileManager.exists(getPathResolver().getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml")); } public void installEmail(String hostServer, MailProtocol protocol, String port, String encoding, String username, String password) { Assert.hasText(hostServer, "Host server name required"); - String emailPropsPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "email.properties"); + String emailPropsPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "email.properties"); MutableFile databaseMutableFile = null; Properties props = new Properties(); @@ -94,7 +94,7 @@ throw new IllegalStateException(ioe); } - String contextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml"); + String contextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml"); MutableFile contextMutableFile = null; Document appCtx = null; @@ -202,7 +202,7 @@ public void configureTemplateMessage(String from, String subject) { - String emailPropsPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "email.properties"); + String emailPropsPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "email.properties"); MutableFile databaseMutableFile = null; Properties props = new Properties(); @@ -219,7 +219,7 @@ throw new IllegalStateException(ioe); } - String contextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml"); + String contextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml"); MutableFile contextMutableFile = null; Document appCtx = null; @@ -302,7 +302,7 @@ mutableTypeDetails.addField(fieldMetadata); - String contextPath = pathResolver.getIdentifier(Path.SRC_MAIN_RESOURCES, "applicationContext.xml"); + String contextPath = pathResolver.getIdentifier(Path.SPRING_CONFIG_ROOT, "applicationContext.xml"); MutableFile contextMutableFile = null; Document appCtx = null;