| /* |
| * 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.axis2.maven2.aar; |
| |
| import org.apache.maven.artifact.Artifact; |
| import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.project.MavenProject; |
| import org.codehaus.plexus.util.DirectoryScanner; |
| import org.codehaus.plexus.util.FileUtils; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Set; |
| |
| |
| /** Abstract base class of all the mojos in the axis2-aar-maven-plugin. */ |
| public abstract class AbstractAarMojo |
| extends AbstractMojo { |
| |
| /** |
| * The projects base directory. |
| * |
| * @parameter property="project.basedir" |
| * @required |
| * @readonly |
| */ |
| protected File baseDir; |
| |
| /** |
| * The maven project. |
| * |
| * @parameter property="project" |
| * @required |
| * @readonly |
| */ |
| protected MavenProject project; |
| |
| /** |
| * The directory containing generated classes. |
| * |
| * @parameter default-value="${project.build.outputDirectory}" |
| * @required |
| */ |
| private File classesDirectory; |
| |
| /** |
| * The directory where the aar is built. |
| * |
| * @parameter default-value="${project.build.directory}/aar" |
| * @required |
| */ |
| protected File aarDirectory; |
| |
| /** |
| * The location of the services.xml file. If it is present in the META-INF directory in |
| * src/main/resources with that name then it will automatically be included. Otherwise this |
| * parameter must be set. |
| * |
| * @parameter default-value="src/main/resources/META-INF/services.xml" |
| */ |
| private File servicesXmlFile; |
| |
| /** |
| * The location of the WSDL file, if any. By default, no WSDL file is added and it is assumed, |
| * that Axis 2 will automatically generate a WSDL file. |
| * |
| * @parameter |
| */ |
| private File wsdlFile; |
| |
| /** |
| * Name, to which the wsdl file shall be mapped. By default, the name will be computed from the |
| * files path by removing the directory. |
| * |
| * @parameter default-value="service.wsdl" |
| */ |
| private String wsdlFileName; |
| |
| /** |
| * Additional file sets, which are being added to the archive. |
| * |
| * @parameter |
| */ |
| private FileSet[] fileSets; |
| |
| /** |
| * Whether the dependency jars should be included in the aar |
| * |
| * @parameter default-value="true" |
| */ |
| private boolean includeDependencies; |
| |
| /** |
| * Builds the exploded AAR file. |
| * |
| * @throws MojoExecutionException |
| */ |
| protected void buildExplodedAar() |
| throws MojoExecutionException { |
| getLog().debug("Exploding aar..."); |
| |
| aarDirectory.mkdirs(); |
| getLog().debug("Assembling aar " + project.getArtifactId() + " in " + aarDirectory); |
| |
| try { |
| final File metaInfDir = new File(aarDirectory, "META-INF"); |
| final File libDir = new File(aarDirectory, "lib"); |
| final File servicesFileTarget = new File(metaInfDir, "services.xml"); |
| boolean existsBeforeCopyingClasses = servicesFileTarget.exists(); |
| |
| String wsdlName = wsdlFileName; |
| if (wsdlName == null && wsdlFile != null) { |
| wsdlName = wsdlFile.getName(); |
| } |
| File wsdlFileTarget = null; |
| if (wsdlFile != null) { |
| wsdlFileTarget = new File(metaInfDir, wsdlFileName); |
| } |
| boolean wsdlExistsBeforeCopyingClasses = |
| wsdlFileTarget == null ? false : wsdlFileTarget.exists(); |
| |
| if (classesDirectory.exists() && (!classesDirectory.equals(aarDirectory))) { |
| FileUtils.copyDirectoryStructure(classesDirectory, aarDirectory); |
| } |
| |
| if (fileSets != null) { |
| for (int i = 0; i < fileSets.length; i++) { |
| FileSet fileSet = fileSets[i]; |
| copyFileSet(fileSet, aarDirectory); |
| } |
| } |
| |
| copyMetaInfFile(servicesXmlFile, servicesFileTarget, existsBeforeCopyingClasses, |
| "services.xml file"); |
| copyMetaInfFile(wsdlFile, wsdlFileTarget, wsdlExistsBeforeCopyingClasses, "WSDL file"); |
| |
| if (includeDependencies) { |
| Set<Artifact> artifacts = project.getArtifacts(); |
| |
| List<String> duplicates = findDuplicates(artifacts); |
| |
| for (Artifact artifact : artifacts) { |
| String targetFileName = getDefaultFinalName(artifact); |
| |
| getLog().debug("Processing: " + targetFileName); |
| |
| if (duplicates.contains(targetFileName)) { |
| getLog().debug("Duplicate found: " + targetFileName); |
| targetFileName = artifact.getGroupId() + "-" |
| + targetFileName; |
| getLog().debug("Renamed to: " + targetFileName); |
| } |
| |
| // TODO: utilise appropriate methods from project builder |
| ScopeArtifactFilter filter = new ScopeArtifactFilter( |
| Artifact.SCOPE_RUNTIME); |
| if (filter.include(artifact)) { |
| String type = artifact.getType(); |
| if ("jar".equals(type)) { |
| copyFileIfModified(artifact.getFile(), new File( |
| libDir, targetFileName)); |
| } |
| } |
| } |
| } |
| } |
| catch (IOException e) { |
| throw new MojoExecutionException("Could not explode aar...", e); |
| } |
| } |
| |
| /** |
| * Searches a set of artifacts for duplicate filenames and returns a list of duplicates. |
| * |
| * @param artifacts set of artifacts |
| * @return List of duplicated artifacts |
| */ |
| private List<String> findDuplicates(Set<Artifact> artifacts) { |
| List<String> duplicates = new ArrayList<String>(); |
| List<String> identifiers = new ArrayList<String>(); |
| for (Artifact artifact : artifacts) { |
| String candidate = getDefaultFinalName(artifact); |
| if (identifiers.contains(candidate)) { |
| duplicates.add(candidate); |
| } else { |
| identifiers.add(candidate); |
| } |
| } |
| return duplicates; |
| } |
| |
| /** |
| * Converts the filename of an artifact to artifactId-version.type format. |
| * |
| * @param artifact |
| * @return converted filename of the artifact |
| */ |
| private String getDefaultFinalName(Artifact artifact) { |
| return artifact.getArtifactId() + "-" + artifact.getVersion() + "." + |
| artifact.getArtifactHandler().getExtension(); |
| } |
| |
| /** |
| * Copy file from source to destination only if source timestamp is later than the destination |
| * timestamp. The directories up to <code>destination</code> will be created if they don't |
| * already exist. <code>destination</code> will be overwritten if it already exists. |
| * |
| * @param source An existing non-directory <code>File</code> to copy bytes from. |
| * @param destination A non-directory <code>File</code> to write bytes to (possibly |
| * overwriting). |
| * @throws IOException if <code>source</code> does not exist, |
| * <code>destination</code> cannot be written to, or an IO |
| * error occurs during copying. |
| * @throws java.io.FileNotFoundException if <code>destination</code> is a directory |
| * <p/> |
| * TO DO: Remove this method when Maven moves to |
| * plexus-utils version 1.4 |
| */ |
| private void copyFileIfModified(File source, File destination) |
| throws IOException { |
| // TO DO: Remove this method and use the method in WarFileUtils when Maven 2 changes |
| // to plexus-utils 1.2. |
| if (destination.lastModified() < source.lastModified()) { |
| FileUtils.copyFile(source.getCanonicalFile(), destination); |
| // preserve timestamp |
| destination.setLastModified(source.lastModified()); |
| } |
| } |
| |
| private void copyFileSet(FileSet fileSet, File targetDirectory) |
| throws IOException { |
| File dir = fileSet.getDirectory(); |
| if (dir == null) { |
| dir = baseDir; |
| } |
| File targetDir = targetDirectory; |
| if (fileSet.getOutputDirectory() != null) { |
| targetDir = new File(targetDir, fileSet.getOutputDirectory()); |
| } |
| if (targetDir.equals(dir)) { |
| return; |
| } |
| |
| DirectoryScanner ds = new DirectoryScanner(); |
| ds.setBasedir(dir); |
| if (!fileSet.isSkipDefaultExcludes()) { |
| ds.addDefaultExcludes(); |
| } |
| final String[] excludes = fileSet.getExcludes(); |
| if (excludes != null) { |
| ds.setExcludes(excludes); |
| } |
| final String[] includes = fileSet.getIncludes(); |
| if (includes != null) { |
| ds.setIncludes(includes); |
| } |
| ds.scan(); |
| String[] files = ds.getIncludedFiles(); |
| for (int i = 0; i < files.length; i++) { |
| File sourceFile = new File(dir, files[i]); |
| File targetFile = new File(targetDir, files[i]); |
| FileUtils.copyFile(sourceFile, targetFile); |
| } |
| } |
| |
| |
| private void copyMetaInfFile(final File pSource, final File pTarget, |
| final boolean pExistsBeforeCopying, |
| final String pDescription) |
| throws MojoExecutionException, IOException { |
| if (pSource != null && pTarget != null) { |
| if (!pSource.exists()) { |
| throw new MojoExecutionException( |
| "The configured " + pDescription + " could not be found at " |
| + pSource); |
| } |
| |
| if (!pExistsBeforeCopying && pTarget.exists()) { |
| getLog().warn("The configured " + pDescription + |
| " overwrites another file from the classpath."); |
| } |
| |
| FileUtils.copyFile(pSource, pTarget); |
| } |
| } |
| } |