/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.tuscany.sca.tools.ant.generator.plugin; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.model.FileSet; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Settings; import org.codehaus.plexus.util.xml.Xpp3Dom; /** * A Maven plugin that generates an Ant build.xml file for Tuscany SCA samples. * * Build dependencies and additional build steps like WSDL2Java for example are * automatically determined from the pom.xml file describing the module's Maven build. * * @version $Rev$ $Date$ * @goal generate * @phase generate-sources * @requiresDependencyResolution test * @description Generate Ant build script for an SCA project */ public class AntGeneratorMojo extends AbstractMojo { /** * The project to generate an Ant build for. * * @parameter expression="${project}" * @required */ private MavenProject project; /** * Used for resolving artifacts * * @component */ private ArtifactResolver resolver; /** * Factory for creating artifact objects * * @component */ private ArtifactFactory factory; /** * The local repository where the artifacts are located * * @parameter expression="${localRepository}" * @required */ private ArtifactRepository localRepository; /** * The remote repositories where artifacts are located * * @parameter expression="${project.remoteArtifactRepositories}" */ private List remoteRepositories; /** * The current user system settings for use in Maven. * * @parameter expression="${settings}" * @required * @readonly */ private Settings settings; /** * The main class name. * @parameter */ private String mainClass; /** * If set true then only the dependency file is created. The dependency * file can then be included in a hand generated build.xml file * @parameter */ private Boolean buildDependencyFileOnly; /** * The build.xml file to generate. * @parameter expression="${basedir}/build.xml" */ private String buildFile; /** * The build-dependency.xml file to generate. * @parameter expression="${basedir}/build-dependency.xml" */ private String buildDependencyFile; /** * The path to the root dir so that build.xml files can be generated at any level * in the distribution hierarchy * @parameter expression="../.." */ private String pathToRootDir; /** * Additional run targets and corresponding class names * @parameter */ private Map runTargets; /** * Set this to true if test source needs to be compiled * @parameter */ private boolean testSource; /** * Additional jar files to be produced * @parameter */ private List jarFiles; public void execute() throws MojoExecutionException { if ((buildDependencyFileOnly != null) && (buildDependencyFileOnly == true)){ generateBuildDependencyFile(); } else { generateBuildFile(); } } /** * Generate Ant build dependency XML file */ private void generateBuildDependencyFile() throws MojoExecutionException { getLog().info("Generating " + buildDependencyFile); // Open the target build-dependency.xml file File targetFile = new File(buildDependencyFile); PrintWriter pw; try { pw = new PrintWriter(new FileOutputStream(targetFile)); } catch (FileNotFoundException e) { throw new MojoExecutionException(e.toString()); } // Generate the Apache license header generateLicenseHeader(pw); // Generate Ant filesets representing the build dependencies generateBuildDependencies(pw); pw.close(); } /** * Generate Ant build XML file */ private void generateBuildFile() throws MojoExecutionException { getLog().info("Generating " + buildFile); // Open the target build.xml file File targetFile = new File(buildFile); PrintWriter pw; try { pw = new PrintWriter(new FileOutputStream(targetFile)); } catch (FileNotFoundException e) { throw new MojoExecutionException(e.toString()); } // Determine the project packaging String packaging = project.getPackaging().toLowerCase(); // Generate the Apache license header generateLicenseHeader(pw); pw.println(""); pw.println(); // Generate the compile target int base = project.getBasedir().toString().length() + 1; pw.println(" "); pw.println(" "); // Generate any pre-compilation tasks generatePreCompileTasks(pw); // Generate the compile task pw.println(" "); for (String source: (List)project.getCompileSourceRoots()) { if (source.length() > base) { source = source.substring(base); } else { source = "."; } pw.println(" "); } pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); for (FileSet resource: (List)project.getResources()) { String source = resource.getDirectory(); if (source.length() > base) { source = source.substring(base); if (source.equals(".")){ pw.println(" "); } else { pw.println(" "); } } else { if (project.getResources().size() > 1) { break; } pw.println(" "); source = "."; } } pw.println(" "); // Compile test source using code cut and pasted from above if (testSource) { pw.println(" "); pw.println(" "); for (String source: (List)project.getTestCompileSourceRoots()) { if (source.length() > base) { source = source.substring(base); } else { source = "."; } pw.println(" "); } pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); for (FileSet resource: (List)project.getTestResources()) { String source = resource.getDirectory(); if (source.length() > base) { source = source.substring(base); if (source.equals(".")){ pw.println(" "); } else { pw.println(" "); } } else { if (project.getTestResources().size() > 1) { break; } pw.println(" "); source = "."; } } pw.println(" "); } // Build a JAR if (packaging.equals("jar")) { pw.println(" "); pw.println(" "); if (mainClass != null) { pw.println(" "); } pw.println(" "); pw.println(" "); } else if (packaging.equals("war")) { // Build a WAR pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); } // Build additional JARs if (jarFiles != null) { for (JarFile jarFile: jarFiles) { pw.println(" "); if (jarFile.getFilesets() != null) { for (String fileset: jarFile.getFilesets()) { pw.println(" "); } } pw.println(" "); } } // Finish the compile target pw.println(" "); pw.println(); // Generate a package target alongside the compile target // Tuscany SCA samples use "package" as the target for webapps pw.println(" "); pw.println(); // Generate the run target if (mainClass != null) { pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(); } // Generate other run targets if (runTargets != null) { for (Map.Entry element: runTargets.entrySet()) { pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(); } } // Generate the clean target pw.println(" "); pw.println(" "); pw.println(" "); pw.println(); // Generate Ant filesets representing the build dependencies generateBuildDependencies(pw); pw.println(""); pw.close(); } /** * Generate Ant filesets representing the build dependencies. * @param pw PrintWriter to write to */ private void generateBuildDependencies(PrintWriter pw) { // Determine the module dependencies List tuscanyModules = new ArrayList(); List otherModules = new ArrayList(); for (Artifact artifact: (List)project.getRuntimeArtifacts()) { if (artifact.getGroupId().startsWith("org.apache.tuscany.sca")) { tuscanyModules.add(artifact.getFile().getName()); } else { otherModules.add(artifact.getFile().getName()); } } // Sort lists of modules, making output deterministic Collections.sort(tuscanyModules); Collections.sort(otherModules); // Generate filesets for the tuscany and 3rd party dependencies pw.println(" "); for (String name: tuscanyModules) { pw.println(" "); } pw.println(" "); pw.println(" "); for (String name: otherModules) { pw.println(" "); } pw.println(" "); pw.println(); } /** * Extract plugin execution configurations out of the Maven model. This handles * nested configurations with a base configuration and a collection of nested * configuration elements, for example: * * * * x.wsdl * * * y.wsdl * * * true * * * @param execution Maven plugin execution model * @return a list of maps containing the plugin configuration key value pairs */ private static List> pluginConfigurations(PluginExecution execution) { List> configurations = new ArrayList>(); Map topConfiguration = new HashMap(); Xpp3Dom dom = (Xpp3Dom)execution.getConfiguration(); for (Xpp3Dom element: dom.getChildren()) { if (element.getChildCount() != 0) { // Handle nested configuration element, create a child configuration // for each for (Xpp3Dom childConfigurationElement: element.getChildren()) { Map childConfiguration = new HashMap(); for (Xpp3Dom childElement: childConfigurationElement.getChildren()) { childConfiguration.put(childElement.getName(), childElement.getValue()); } configurations.add(childConfiguration); } } else { // Handle top level key value pair element topConfiguration.put(element.getName(), element.getValue()); } } // Return the top configuration or the child configurations merged // with the top one if (configurations.isEmpty()) { configurations.add(topConfiguration); } else { for (Map configuration: configurations) { configuration.putAll(topConfiguration); } } return configurations; } /** * Generate Ant tasks for the pre-compilation generation plugins * used in the Maven module. * @param pw PrintWriter to write to * @return list of directories containing generated source to compile */ private void generatePreCompileTasks(PrintWriter pw) { String baseDir = project.getBasedir().getAbsolutePath() + '/'; List plugins = (List)project.getBuildPlugins(); for (Plugin plugin: plugins) { // Generate Ant task equivalent to the Tuscany SDO plugin if ("org.apache.tuscany.sdo".equals(plugin.getGroupId()) && "tuscany-sdo-plugin".equals(plugin.getArtifactId())) { for (PluginExecution execution: (List)plugin.getExecutions()) { for (Map configuration: pluginConfigurations(execution)) { pw.println(" "); // Generate the various code generation options for (Map.Entry element: configuration.entrySet()) { String key = element.getKey(); String value = element.getValue(); if (key.equals("schemaNamespace")) { pw.println(" "); pw.println(" "); } if (key.equals("javaPackage")) { pw.println(" "); pw.println(" "); } if (key.equals("prefix")) { pw.println(" "); pw.println(" "); } if (key.equals("noInterfaces") && "true".equals(value)) { pw.println(" "); } if (key.equals("noNotification") && "true".equals(value)) { pw.println(" "); } if (key.equals("noContainer") && "true".equals(value)) { pw.println(" "); } if (key.equals("noUnsettable") && "true".equals(value)) { pw.println(" "); } } // Generate target directory parameter String targetDirectory = configuration.get("targetDirectory"); if (targetDirectory == null) { targetDirectory = "target/sdo-source"; } else if (targetDirectory.startsWith(baseDir)) { targetDirectory = targetDirectory.substring(baseDir.length()); } pw.println(" "); pw.println(" "); // Generate schema file parameter String schemaFile = configuration.get("schemaFile"); if (schemaFile == null) { schemaFile = configuration.get("fileName"); } if (schemaFile != null) { if (schemaFile.startsWith(baseDir)) { schemaFile = schemaFile.substring(baseDir.length()); } pw.println(" "); } pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); } } } // Generate Ant task equivalent to the Tuscany WSDL2Java plugin else if ("org.apache.tuscany.sca".equals(plugin.getGroupId()) && "tuscany-maven-wsdl2java".equals(plugin.getArtifactId())) { for (PluginExecution execution: (List)plugin.getExecutions()) { for (Map configuration: pluginConfigurations(execution)) { pw.println(" "); // Generate the various code generation options for (Map.Entry element: configuration.entrySet()) { String key = element.getKey(); String value = element.getValue(); if (key.equals("javaPackage")) { pw.println(" "); pw.println(" "); } } // Generate target directory parameter String targetDirectory = configuration.get("targetDirectory"); if (targetDirectory == null) { targetDirectory = "target/wsdl2java-source"; } else if (targetDirectory.startsWith(baseDir)) { targetDirectory = targetDirectory.substring(baseDir.length()); } pw.println(" "); pw.println(" "); // Generate WSDL file parameter String wsdlFile = configuration.get("wsdlFile"); if (wsdlFile == null) { wsdlFile = configuration.get("fileName"); } if (wsdlFile != null) { if (wsdlFile.startsWith(baseDir)) { wsdlFile = wsdlFile.substring(baseDir.length()); } pw.println(" "); } pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); } } } } } /** * Generate license header. * * @param pw PrintWriter to write to */ private void generateLicenseHeader(PrintWriter pw) { pw.println(""); pw.println(); } }