package org.springframework.roo.project; import static org.springframework.roo.shell.OptionContexts.UPDATE; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; import org.springframework.roo.project.maven.Pom; import org.springframework.roo.project.packaging.JarPackaging; import org.springframework.roo.project.packaging.PackagingProvider; import org.springframework.roo.project.packaging.PackagingProviderRegistry; import org.springframework.roo.shell.CliAvailabilityIndicator; import org.springframework.roo.shell.CliCommand; import org.springframework.roo.shell.CliOption; import org.springframework.roo.shell.CliOptionAutocompleteIndicator; import org.springframework.roo.shell.CommandMarker; import org.springframework.roo.shell.ShellContext; import org.springframework.roo.support.logging.HandlerUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Logger; /** * Shell commands for {@link MavenOperations} and also to launch native mvn * commands. * * @author Ben Alex * @since 1.0 */ @Component @Service public class MavenCommands implements CommandMarker { protected final static Logger LOGGER = HandlerUtils.getLogger(MavenCommands.class); // ------------ OSGi component attributes ---------------- private BundleContext context; private static final String DEPENDENCY_ADD_COMMAND = "dependency add"; private static final String DEPENDENCY_REMOVE_COMMAND = "dependency remove"; private static final String MODULE_CREATE_COMMAND = "module create"; private static final String MODULE_FOCUS_COMMAND = "module focus"; private static final String PERFORM_ASSEMBLY_COMMAND = "perform assembly"; private static final String PERFORM_CLEAN_COMMAND = "perform clean"; private static final String PERFORM_COMMAND_COMMAND = "perform command"; private static final String PERFORM_ECLIPSE_COMMAND = "perform eclipse"; private static final String PERFORM_PACKAGE_COMMAND = "perform package"; private static final String PERFORM_TESTS_COMMAND = "perform tests"; private static final String REPOSITORY_ADD_COMMAND = "maven repository add"; private static final String REPOSITORY_REMOVE_COMMAND = "maven repository remove"; private MavenOperations mavenOperations; private ProjectOperations projectOperations; @Reference PackagingProviderRegistry packagingProviderRegistry; protected void activate(final ComponentContext cContext) { context = cContext.getBundleContext(); } /* @CliCommand(value = DEPENDENCY_ADD_COMMAND, help = "Adds a new dependency to the Maven project object model (POM)") */ public void addDependency( @CliOption(key = "groupId", mandatory = true, help = "The group ID of the dependency") final String groupId, @CliOption(key = "artifactId", mandatory = true, help = "The artifact ID of the dependency") final String artifactId, @CliOption(key = "version", mandatory = true, help = "The version of the dependency") final String version, @CliOption(key = "classifier", help = "The classifier of the dependency") final String classifier, @CliOption(key = "scope", help = "The scope of the dependency") final DependencyScope scope) { getMavenOperations().addDependency(getMavenOperations().getFocusedModuleName(), groupId, artifactId, version, scope, classifier); } /* @CliCommand(value = REPOSITORY_ADD_COMMAND, help = "Adds a new repository to the Maven project object model (POM)") */ public void addRepository(@CliOption(key = "id", mandatory = true, help = "The ID of the repository") final String id, @CliOption(key = "name", mandatory = false, help = "The name of the repository") final String name, @CliOption( key = "url", mandatory = true, help = "The URL of the repository") final String url) { getMavenOperations().addRepository(getMavenOperations().getFocusedModuleName(), new Repository(id, name, url)); } @CliOptionAutocompleteIndicator(command = MODULE_CREATE_COMMAND, param = "packaging", help = "--packaging select one of the available Maven packaging values") public List<String> returnPomModules(ShellContext shellContext) { List<String> allPossibleValues = new ArrayList<String>(); Collection<PackagingProvider> allPackagingProviders = packagingProviderRegistry.getAllPackagingProviders(); for (final PackagingProvider packagingProvider : allPackagingProviders) { // ROO-3801 Can't create POM children if (!"pom".equals(packagingProvider.getId())) { allPossibleValues.add(packagingProvider.getId().toUpperCase()); } } return allPossibleValues; } @CliCommand(value = MODULE_CREATE_COMMAND, help = "Creates a new Maven module in current *multimodule* project.") public void createModule(@CliOption(key = "moduleName", mandatory = true, help = "The name of the module to create.") final String moduleName, @CliOption( key = "packaging", help = "The Maven packaging of this module." + "Possible values are: `BUNDLE`, `EAR`, `ESA`, `JAR` and `WAR`." + "Default if option not present: `JAR` (equals to 'jar').", unspecifiedDefaultValue = JarPackaging.NAME) final PackagingProvider packaging, @CliOption( key = "artifactId", help = "The artifact ID of this module." + "Default if option not present: `--moduleName` value.") final String artifactId) { getMavenOperations().createModule(moduleName, packaging, artifactId); } @CliCommand(value = MODULE_FOCUS_COMMAND, help = "Changes Roo Shell focus to a different project " + "module, when in a multimodule project.") public void focusModule( @CliOption(key = "moduleName", mandatory = true, optionContext = UPDATE, help = "The module name to focus on." + "Possible values are: any of the project module names (`~` for root module).") final Pom module) { getMavenOperations().setModule(module); } @CliAvailabilityIndicator({DEPENDENCY_ADD_COMMAND, DEPENDENCY_REMOVE_COMMAND}) public boolean isDependencyModificationAllowed() { return getMavenOperations().isFocusedProjectAvailable(); } @CliAvailabilityIndicator({REPOSITORY_ADD_COMMAND, REPOSITORY_REMOVE_COMMAND}) public boolean isRepositoryModificationAllowed() { return getMavenOperations().isFocusedProjectAvailable(); } @CliAvailabilityIndicator(MODULE_CREATE_COMMAND) public boolean isModuleCreationAllowed() { return getMavenOperations().isModuleCreationAllowed(); } @CliAvailabilityIndicator(MODULE_FOCUS_COMMAND) public boolean isModuleFocusAllowed() { return getMavenOperations().isModuleFocusAllowed(); } @CliAvailabilityIndicator({PERFORM_PACKAGE_COMMAND, PERFORM_ECLIPSE_COMMAND, PERFORM_TESTS_COMMAND, PERFORM_CLEAN_COMMAND, PERFORM_ASSEMBLY_COMMAND, PERFORM_COMMAND_COMMAND}) public boolean isPerformCommandAllowed() { return getMavenOperations().isFocusedProjectAvailable(); } /* @CliCommand(value = {PERFORM_COMMAND_COMMAND}, help = "Executes a user-specified Maven command") */ public void mvn(@CliOption(key = "mavenCommand", mandatory = true, help = "User-specified Maven command (eg test:test)") final String command) throws IOException { getMavenOperations().executeMvnCommand(command); } /* @CliCommand(value = DEPENDENCY_REMOVE_COMMAND, help = "Removes an existing dependency from the Maven project object model (POM)") */ public void removeDependency( @CliOption(key = "groupId", mandatory = true, help = "The group ID of the dependency") final String groupId, @CliOption(key = "artifactId", mandatory = true, help = "The artifact ID of the dependency") final String artifactId, @CliOption(key = "version", mandatory = true, help = "The version of the dependency") final String version, @CliOption(key = "classifier", help = "The classifier of the dependency") final String classifier) { getMavenOperations().removeDependency(getMavenOperations().getFocusedModuleName(), groupId, artifactId, version, classifier); } /* @CliCommand(value = REPOSITORY_REMOVE_COMMAND, help = "Removes an existing repository from the Maven project object model (POM)") */ public void removeRepository(@CliOption(key = "id", mandatory = true, help = "The ID of the repository") final String id, @CliOption(key = "url", mandatory = true, help = "The URL of the repository") final String url) { getMavenOperations().removeRepository(getMavenOperations().getFocusedModuleName(), new Repository(id, null, url)); } /* @CliCommand(value = {PERFORM_ASSEMBLY_COMMAND}, help = "Executes the assembly goal via Maven") */ public void runAssembly() throws IOException { mvn("assembly:assembly"); } /* @CliCommand(value = {PERFORM_CLEAN_COMMAND}, help = "Executes a full clean (including Eclipse files) via Maven") */ public void runClean() throws IOException { mvn("clean"); } /* @CliCommand( value = {PERFORM_ECLIPSE_COMMAND}, help = "Sets up Eclipse configuration via Maven (only necessary if you have not installed the m2eclipse plugin in Eclipse)") */ public void runEclipse() throws IOException { mvn("eclipse:clean eclipse:eclipse"); } /* @CliCommand(value = {PERFORM_PACKAGE_COMMAND}, help = "Packages the application using Maven, but does not execute any tests") */ public void runPackage() throws IOException { mvn("-DskipTests=true package"); } /* @CliCommand(value = {PERFORM_TESTS_COMMAND}, help = "Executes the tests via Maven") */ public void runTest() throws IOException { mvn("test"); } public MavenOperations getMavenOperations() { if (mavenOperations == null) { // Get all Services implement MavenOperations interface try { ServiceReference<?>[] references = this.context.getAllServiceReferences(MavenOperations.class.getName(), null); for (ServiceReference<?> ref : references) { return (MavenOperations) this.context.getService(ref); } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load MavenOperations on MavenCommands."); return null; } } else { return mavenOperations; } } 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) { projectOperations = (ProjectOperations) this.context.getService(ref); return projectOperations; } return null; } catch (InvalidSyntaxException e) { LOGGER.warning("Cannot load ProjectOperations on MavenCommands."); return null; } } else { return projectOperations; } } }