blob: de8ba817eca00ec0439216524dca47f5b5ead6e9 [file] [log] [blame]
package org.apache.maven.plugin.ant;
/*
* 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.
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.project.MavenProject;
import org.apache.xpath.XPathAPI;
import org.codehaus.plexus.util.PathTool;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.XMLWriter;
import org.codehaus.plexus.util.xml.XmlWriterUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Utility class for the <code>AntBuildWriter</code> class.
*
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @version $Id$
*/
public class AntBuildWriterUtil
{
/**
* @param compileSourceRoots
* @return not null list
*/
public static List removeEmptyCompileSourceRoots( List compileSourceRoots )
{
List newCompileSourceRootsList = new ArrayList();
if ( compileSourceRoots != null )
{
// copy as I may be modifying it
for ( Iterator i = compileSourceRoots.iterator(); i.hasNext(); )
{
String srcDir = (String) i.next();
if ( new File( srcDir ).exists() )
{
newCompileSourceRootsList.add( srcDir );
}
}
}
return newCompileSourceRootsList;
}
/**
* Convenience method to write <code>&lt;include/&gt;</code> and <code>&lt;exclude/&gt;</code>
*
* @param writer not null
* @param includes
* @param excludes
*/
public static void writeIncludesExcludes( XMLWriter writer, List includes, List excludes )
{
if ( includes != null )
{
for ( Iterator i = includes.iterator(); i.hasNext(); )
{
String include = (String) i.next();
writer.startElement( "include" );
writer.addAttribute( "name", include );
writer.endElement(); // include
}
}
if ( excludes != null )
{
for ( Iterator i = excludes.iterator(); i.hasNext(); )
{
String exclude = (String) i.next();
writer.startElement( "exclude" );
writer.addAttribute( "name", exclude );
writer.endElement(); // exclude
}
}
}
/**
* Write comments in the Ant build file header
*
* @param writer
*/
public static void writeHeader( XMLWriter writer )
{
writeAntVersionHeader( writer );
XmlWriterUtil.writeCommentLineBreak( writer );
XmlWriterUtil.writeComment( writer, StringUtils.repeat( "=", 21 ) + " - DO NOT EDIT THIS FILE! - "
+ StringUtils.repeat( "=", 21 ) );
XmlWriterUtil.writeCommentLineBreak( writer );
XmlWriterUtil.writeComment( writer, " " );
XmlWriterUtil.writeComment( writer, "Any modifications will be overwritten." );
XmlWriterUtil.writeComment( writer, " " );
DateFormat dateFormat = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, Locale.US );
XmlWriterUtil.writeComment( writer, "Generated by Maven Ant Plugin on "
+ dateFormat.format( new Date( System.currentTimeMillis() ) ) );
XmlWriterUtil.writeComment( writer, "See: http://maven.apache.org/plugins/maven-ant-plugin/" );
XmlWriterUtil.writeComment( writer, " " );
XmlWriterUtil.writeCommentLineBreak( writer );
XmlWriterUtil.writeLineBreak( writer );
}
/**
* Write comment for the Ant supported version
*
* @param writer
*/
public static void writeAntVersionHeader( XMLWriter writer )
{
XmlWriterUtil.writeCommentText( writer, "Ant build file (http://ant.apache.org/) for Ant 1.6.2 or above.", 0 );
}
/**
* Convenience method to write XML ant task
*
* @param writer not null
* @param project not null
* @param moduleSubPath not null
* @param tasks not null
*/
public static void writeAntTask( XMLWriter writer, MavenProject project, String moduleSubPath, String tasks )
{
writer.startElement( "ant" );
writer.addAttribute( "antfile", "build.xml" );
writer.addAttribute( "dir", toRelative( project.getBasedir(), moduleSubPath ) );
writer.addAttribute( "target", tasks );
writer.endElement(); // ant
}
/**
* Convenience method to write XML Ant javadoc task
*
* @param writer not null
* @param project not null
* @param wrapper not null
* @throws IOException if any
*/
public static void writeJavadocTask( XMLWriter writer, MavenProject project, ArtifactResolverWrapper wrapper )
throws IOException
{
List sources = new ArrayList();
for ( Iterator it = project.getCompileSourceRoots().iterator(); it.hasNext(); )
{
String source = (String) it.next();
if ( new File( source ).exists() )
{
sources.add( source );
}
}
// No sources
if ( sources.size() == 0 )
{
return;
}
writer.startElement( "javadoc" );
String sourcepath = getMavenJavadocPluginBasicOption( project, "sourcepath", null );
if ( sourcepath == null )
{
StringBuffer sb = new StringBuffer();
String[] compileSourceRoots = (String[]) sources.toArray( new String[0] );
for ( int i = 0; i < compileSourceRoots.length; i++ )
{
sb.append( "${maven.build.srcDir." ).append( i ).append( "}" );
if ( i < ( compileSourceRoots.length - 1 ) )
{
sb.append( File.pathSeparatorChar );
}
}
writer.addAttribute( "sourcepath", sb.toString() );
addWrapAttribute( writer, "javadoc", "packagenames", "*", 3 );
}
else
{
writer.addAttribute( "sourcepath", sourcepath );
}
addWrapAttribute( writer, "javadoc", "destdir",
getMavenJavadocPluginBasicOption( project, "destdir",
"${maven.reporting.outputDirectory}/apidocs" ), 3 );
addWrapAttribute( writer, "javadoc", "extdirs", getMavenJavadocPluginBasicOption( project, "extdirs", null ), 3 );
addWrapAttribute( writer, "javadoc", "overview", getMavenJavadocPluginBasicOption( project, "overview", null ),
3 );
addWrapAttribute( writer, "javadoc", "access",
getMavenJavadocPluginBasicOption( project, "show", "protected" ), 3 );
addWrapAttribute( writer, "javadoc", "old", getMavenJavadocPluginBasicOption( project, "old", "false" ), 3 );
addWrapAttribute( writer, "javadoc", "verbose",
getMavenJavadocPluginBasicOption( project, "verbose", "false" ), 3 );
addWrapAttribute( writer, "javadoc", "locale", getMavenJavadocPluginBasicOption( project, "locale", null ), 3 );
addWrapAttribute( writer, "javadoc", "encoding", getMavenJavadocPluginBasicOption( project, "encoding", null ),
3 );
addWrapAttribute( writer, "javadoc", "version", getMavenJavadocPluginBasicOption( project, "version", "true" ),
3 );
addWrapAttribute( writer, "javadoc", "use", getMavenJavadocPluginBasicOption( project, "use", "true" ), 3 );
addWrapAttribute( writer, "javadoc", "author", getMavenJavadocPluginBasicOption( project, "author", "true" ), 3 );
addWrapAttribute( writer, "javadoc", "splitindex", getMavenJavadocPluginBasicOption( project, "splitindex",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "windowtitle", getMavenJavadocPluginBasicOption( project, "windowtitle",
null ), 3 );
addWrapAttribute( writer, "javadoc", "nodeprecated", getMavenJavadocPluginBasicOption( project, "nodeprecated",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "nodeprecatedlist", getMavenJavadocPluginBasicOption( project,
"nodeprecatedlist",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "notree", getMavenJavadocPluginBasicOption( project, "notree", "false" ),
3 );
addWrapAttribute( writer, "javadoc", "noindex",
getMavenJavadocPluginBasicOption( project, "noindex", "false" ), 3 );
addWrapAttribute( writer, "javadoc", "nohelp", getMavenJavadocPluginBasicOption( project, "nohelp", "false" ),
3 );
addWrapAttribute( writer, "javadoc", "nonavbar",
getMavenJavadocPluginBasicOption( project, "nonavbar", "false" ), 3 );
addWrapAttribute( writer, "javadoc", "serialwarn", getMavenJavadocPluginBasicOption( project, "serialwarn",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "helpfile", getMavenJavadocPluginBasicOption( project, "helpfile", null ),
3 );
addWrapAttribute( writer, "javadoc", "stylesheetfile",
getMavenJavadocPluginBasicOption( project, "stylesheetfile", null ), 3 );
addWrapAttribute( writer, "javadoc", "charset", getMavenJavadocPluginBasicOption( project, "charset",
"ISO-8859-1" ), 3 );
addWrapAttribute( writer, "javadoc", "docencoding", getMavenJavadocPluginBasicOption( project, "docencoding",
null ), 3 );
addWrapAttribute( writer, "javadoc", "excludepackagenames",
getMavenJavadocPluginBasicOption( project, "excludepackagenames", null ), 3 );
addWrapAttribute( writer, "javadoc", "source", getMavenJavadocPluginBasicOption( project, "source", null ), 3 );
addWrapAttribute( writer, "javadoc", "linksource", getMavenJavadocPluginBasicOption( project, "linksource",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "breakiterator", getMavenJavadocPluginBasicOption( project,
"breakiterator",
"false" ), 3 );
addWrapAttribute( writer, "javadoc", "noqualifier", getMavenJavadocPluginBasicOption( project, "noqualifier",
null ), 3 );
// miscellaneous
addWrapAttribute( writer, "javadoc", "maxmemory",
getMavenJavadocPluginBasicOption( project, "maxmemory", null ), 3 );
addWrapAttribute( writer, "javadoc", "additionalparam", getMavenJavadocPluginBasicOption( project,
"additionalparam",
null ), 3 );
// Nested arg
String doctitle = getMavenJavadocPluginBasicOption( project, "doctitle", null );
if ( doctitle != null )
{
writer.startElement( "doctitle" );
writer.writeText( "<![CDATA[" + doctitle + "]]>" );
writer.endElement(); // doctitle
}
String header = getMavenJavadocPluginBasicOption( project, "header", null );
if ( header != null )
{
writer.startElement( "header" );
writer.writeText( "<![CDATA[" + header + "]]>" );
writer.endElement(); // header
}
String footer = getMavenJavadocPluginBasicOption( project, "footer", null );
if ( footer != null )
{
writer.startElement( "footer" );
writer.writeText( "<![CDATA[" + footer + "]]>" );
writer.endElement(); // footer
}
String bottom = getMavenJavadocPluginBasicOption( project, "bottom", null );
if ( bottom != null )
{
writer.startElement( "bottom" );
writer.writeText( "<![CDATA[" + bottom + "]]>" );
writer.endElement(); // bottom
}
Map[] links = getMavenJavadocPluginOptions( project, "links", null );
if ( links != null )
{
for ( int i = 0; i < links.length; i++ )
{
writer.startElement( "link" );
writer.addAttribute( "href", (String) links[i].get( "link" ) );
writer.endElement(); // link
}
}
Map[] offlineLinks = getMavenJavadocPluginOptions( project, "offlineLinks", null );
if ( offlineLinks != null )
{
for ( int i = 0; i < offlineLinks.length; i++ )
{
writer.startElement( "link" );
writer.addAttribute( "href", (String) offlineLinks[i].get( "url" ) );
addWrapAttribute( writer, "javadoc", "offline", "true", 4 );
writer.endElement(); // link
}
}
Map[] groups = getMavenJavadocPluginOptions( project, "groups", null );
if ( groups != null )
{
for ( int i = 0; i < groups.length; i++ )
{
Map group = (Map) groups[i].get( "group" );
writer.startElement( "group" );
writer.addAttribute( "title", (String) group.get( "title" ) );
addWrapAttribute( writer, "javadoc", "package", (String) group.get( "package" ), 4 );
writer.endElement(); // group
}
}
// TODO Handle docletArtifacts
String doclet = getMavenJavadocPluginBasicOption( project, "doclet", null );
if ( doclet != null )
{
String docletpath = getMavenJavadocPluginBasicOption( project, "docletpath", null );
if ( StringUtils.isNotEmpty( docletpath ) )
{
writer.startElement( "doclet" );
writer.addAttribute( "name", doclet );
addWrapAttribute( writer, "javadoc", "path", docletpath, 4 );
writer.endElement(); // doclet
}
else
{
Map docletArtifact = getMavenJavadocPluginOption( project, "docletArtifact", null );
String path = wrapper.getArtifactAbsolutePath( (String) docletArtifact.get( "groupId" ),
(String) docletArtifact.get( "artifactId" ),
(String) docletArtifact.get( "version" ) );
path = StringUtils.replace( path, wrapper.getLocalRepository().getBasedir(), "${maven.repo.local}" );
writer.startElement( "doclet" );
writer.addAttribute( "name", doclet );
addWrapAttribute( writer, "javadoc", "path", path, 4 );
writer.endElement(); // doclet
}
}
// TODO Handle taglets
String taglet = getMavenJavadocPluginBasicOption( project, "taglet", null );
if ( taglet != null )
{
String tagletpath = getMavenJavadocPluginBasicOption( project, "tagletpath", null );
if ( StringUtils.isNotEmpty( tagletpath ) )
{
writer.startElement( "taglet" );
writer.addAttribute( "name", taglet );
addWrapAttribute( writer, "javadoc", "path", tagletpath, 4 );
writer.endElement(); // taglet
}
else
{
Map tagletArtifact = getMavenJavadocPluginOption( project, "tagletArtifact", null );
String path = wrapper.getArtifactAbsolutePath( (String) tagletArtifact.get( "groupId" ),
(String) tagletArtifact.get( "artifactId" ),
(String) tagletArtifact.get( "version" ) );
path = StringUtils.replace( path, wrapper.getLocalRepository().getBasedir(), "${maven.repo.local}" );
writer.startElement( "taglet" );
writer.addAttribute( "name", taglet );
addWrapAttribute( writer, "javadoc", "path", path, 4 );
writer.endElement(); // taglet
}
}
Map[] tags = getMavenJavadocPluginOptions( project, "tags", null );
if ( tags != null )
{
for ( int i = 0; i < tags.length; i++ )
{
Map props = (Map) tags[i].get( "tag" );
writer.startElement( "tag" );
writer.addAttribute( "name", (String) props.get( "name" ) );
addWrapAttribute( writer, "javadoc", "scope", (String) props.get( "placement" ), 4 );
addWrapAttribute( writer, "javadoc", "description", (String) props.get( "head" ), 4 );
writer.endElement(); // tag
}
}
writer.endElement(); // javadoc
}
/**
* Convenience method to write XML Ant jar task
*
* @param writer not null
* @param project not null
* @throws IOException if any
*/
public static void writeJarTask( XMLWriter writer, MavenProject project )
throws IOException
{
writer.startElement( "jar" );
writer.addAttribute( "jarfile", "${maven.build.dir}/${maven.build.finalName}.jar" );
addWrapAttribute( writer, "jar", "compress",
getMavenJarPluginBasicOption( project, "archive//compress", "true" ), 3 );
addWrapAttribute( writer, "jar", "index", getMavenJarPluginBasicOption( project, "archive//index", "false" ), 3 );
if ( getMavenJarPluginBasicOption( project, "archive//manifestFile", null ) != null )
{
addWrapAttribute( writer, "jar", "manifest", getMavenJarPluginBasicOption( project,
"archive//manifestFile", null ),
3 );
}
addWrapAttribute( writer, "jar", "basedir", "${maven.build.outputDir}", 3 );
addWrapAttribute( writer, "jar", "excludes", "**/package.html", 3 );
if ( getMavenPluginOption( project, "maven-jar-plugin", "archive//manifest", null ) != null )
{
writer.startElement( "manifest" );
writer.startElement( "attribute" );
writer.addAttribute( "name", "Main-Class" );
addWrapAttribute( writer, "attribute", "value",
getMavenJarPluginBasicOption( project, "archive//manifest//mainClass", null ), 5 );
writer.endElement(); // attribute
writer.endElement(); // manifest
}
writer.endElement(); // jar
}
/**
* Convenience method to write XML Ant ear task
*
* @param writer not null
* @param project not null
* @param artifactResolverWrapper not null
* @throws IOException if any
*/
public static void writeEarTask( XMLWriter writer, MavenProject project,
ArtifactResolverWrapper artifactResolverWrapper )
throws IOException
{
writeCopyLib( writer, project, artifactResolverWrapper, "${maven.build.dir}/${maven.build.finalName}" );
writer.startElement( "ear" );
writer.addAttribute( "destfile", "${maven.build.dir}/${maven.build.finalName}.ear" );
addWrapAttribute( writer, "ear", "basedir", "${maven.build.dir}/${maven.build.finalName}", 3 );
addWrapAttribute( writer, "ear", "compress",
getMavenEarPluginBasicOption( project, "archive//compress", "true" ), 3 );
addWrapAttribute( writer, "ear", "includes ", getMavenEarPluginBasicOption( project, "includes", null ), 3 );
addWrapAttribute( writer, "ear", "excludes", getMavenEarPluginBasicOption( project, "excludes", null ), 3 );
if ( getMavenEarPluginBasicOption( project, "applicationXml", null ) != null )
{
addWrapAttribute( writer, "ear", "appxml", getMavenEarPluginBasicOption( project, "applicationXml", null ),
3 );
}
else
{
// Generated appxml
addWrapAttribute( writer, "ear", "appxml", "${maven.build.dir}/application.xml", 3 );
}
if ( getMavenEarPluginBasicOption( project, "manifestFile", null ) != null )
{
addWrapAttribute( writer, "ear", "manifest", getMavenEarPluginBasicOption( project, "manifestFile", null ),
3 );
}
writer.endElement(); // ear
}
/**
* Convenience method to write XML Ant war task
*
* @param writer not null
* @param project not null
* @param artifactResolverWrapper not null
* @throws IOException if any
*/
public static void writeWarTask( XMLWriter writer, MavenProject project,
ArtifactResolverWrapper artifactResolverWrapper )
throws IOException
{
String webXml =
getMavenWarPluginBasicOption( project, "webXml", "${basedir}/src/main/webapp/WEB-INF/web.xml" );
if ( webXml.startsWith( "${basedir}/" ) )
{
webXml = webXml.substring( "${basedir}/".length() );
}
writeCopyLib( writer, project, artifactResolverWrapper, "${maven.build.dir}/${maven.build.finalName}/WEB-INF/lib" );
writer.startElement( "war" );
writer.addAttribute( "destfile", "${maven.build.dir}/${maven.build.finalName}.war" );
addWrapAttribute( writer, "war", "compress",
getMavenWarPluginBasicOption( project, "archive//compress", "true" ), 3 );
addWrapAttribute( writer, "war", "webxml", webXml, 3 );
if ( getMavenWarPluginBasicOption( project, "manifestFile", null ) != null )
{
addWrapAttribute( writer, "war", "manifest", getMavenWarPluginBasicOption( project, "manifestFile", null ),
3 );
}
writer.startElement( "lib" );
writer.addAttribute( "dir", "${maven.build.dir}/${maven.build.finalName}/WEB-INF/lib" );
writer.endElement(); // lib
writer.startElement( "classes" );
writer.addAttribute( "dir", "${maven.build.outputDir}" );
writer.endElement(); // classes
writer.startElement( "fileset" );
writer.addAttribute( "dir", "src/main/webapp" );
addWrapAttribute( writer, "fileset", "excludes", "WEB-INF/web.xml", 4 );
writer.endElement(); // fileset
writer.endElement(); // war
}
/**
* Convenience method to wrap long element tags for a given attribute.
*
* @param writer not null
* @param tag not null
* @param name not null
* @param value not null
* @param indent positive value
*/
public static void addWrapAttribute( XMLWriter writer, String tag, String name, String value, int indent )
{
if ( StringUtils.isEmpty( value ) )
{
return;
}
if ( indent < 0 )
{
writer.addAttribute( name, value );
}
else
{
writer.addAttribute( "\n"
+ StringUtils.repeat( " ", ( StringUtils.isEmpty( tag ) ? 0 : tag.length() ) + indent
* XmlWriterUtil.DEFAULT_INDENTATION_SIZE ) + name, value );
}
}
/**
* @param mavenProject not null
* @return true if project packaging equals <code>pom</code>
*/
public static boolean isPomPackaging( MavenProject mavenProject )
{
return "pom".equals( mavenProject.getPackaging() );
}
/**
* @param mavenProject
* @return true if project packaging equals one of several packaging types
* including <code>jar</code>, <code>maven-plugin</code>, <code>ejb</code>, or
* <code>bundle</code>
*/
public static boolean isJarPackaging( MavenProject mavenProject )
{
return "jar".equals( mavenProject.getPackaging() )
|| isEjbPackaging( mavenProject )
|| isMavenPluginPackaging( mavenProject )
|| isBundlePackaging( mavenProject )
;
}
/**
* @param mavenProject
* @return true if project packaging equals <code>bundle</code>
*/
public static boolean isBundlePackaging( MavenProject mavenProject )
{
return "bundle".equals( mavenProject.getPackaging() );
}
/**
* @param mavenProject
* @return true if project packaging equals <code>ejb</code>
*/
public static boolean isEjbPackaging( MavenProject mavenProject )
{
return "ejb".equals( mavenProject.getPackaging() );
}
/**
* @param mavenProject
* @return true if project packaging equals <code>maven-plugin</code>
*/
public static boolean isMavenPluginPackaging( MavenProject mavenProject )
{
return "maven-plugin".equals( mavenProject.getPackaging() );
}
/**
* @param mavenProject
* @return true if project packaging equals <code>ear</code>
*/
public static boolean isEarPackaging( MavenProject mavenProject )
{
return "ear".equals( mavenProject.getPackaging() );
}
/**
* @param mavenProject not null
* @return true if project packaging equals <code>war</code>
*/
public static boolean isWarPackaging( MavenProject mavenProject )
{
return "war".equals( mavenProject.getPackaging() );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-compiler-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenCompilerPluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-compiler-plugin", optionName, defaultValue );
}
/**
* Return the map of <code>optionName</code> value defined in a project for the "maven-compiler-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the map for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static Map getMavenCompilerPluginOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOption( project, "maven-compiler-plugin", optionName, defaultValue );
}
/**
* Return an array of map of <code>optionName</code> value defined in a project for the "maven-compiler-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the array of option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static Map[] getMavenCompilerPluginOptions( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOptions( project, "maven-compiler-plugin", optionName, defaultValue );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-surefire-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenSurefirePluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-surefire-plugin", optionName, defaultValue );
}
/**
* Return the map of <code>optionName</code> value defined in a project for the "maven-surefire-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the map for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static Map getMavenSurefirePluginOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOption( project, "maven-surefire-plugin", optionName, defaultValue );
}
/**
* Return an array of map of <code>optionName</code> value defined in a project for the "maven-surefire-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the array of option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static Map[] getMavenSurefirePluginOptions( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOptions( project, "maven-surefire-plugin", optionName, defaultValue );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-javadoc-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenJavadocPluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-javadoc-plugin", optionName, defaultValue );
}
/**
* Return a map of <code>optionName</code> value defined in a project for the "maven-javadoc-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the map for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static Map getMavenJavadocPluginOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOption( project, "maven-javadoc-plugin", optionName, defaultValue );
}
/**
* Return an array of map of <code>optionName</code> value defined in a project for the "maven-javadoc-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return an array of option name. Could be null if not found.
* @throws IOException if any
*/
public static Map[] getMavenJavadocPluginOptions( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginOptions( project, "maven-javadoc-plugin", optionName, defaultValue );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-jar-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenJarPluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-jar-plugin", optionName, defaultValue );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-ear-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenEarPluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-ear-plugin", optionName, defaultValue );
}
/**
* Return the <code>optionName</code> value defined in a project for the "maven-war-plugin" plugin.
*
* @param project not null
* @param optionName the option name wanted
* @param defaultValue a default value
* @return the value for the option name or the default value. Could be null if not found.
* @throws IOException if any
*/
public static String getMavenWarPluginBasicOption( MavenProject project, String optionName, String defaultValue )
throws IOException
{
return getMavenPluginBasicOption( project, "maven-war-plugin", optionName, defaultValue );
}
// ----------------------------------------------------------------------
// Convenience methods
// ----------------------------------------------------------------------
/**
* Return the value for the option <code>optionName</code> defined in a project with the given
* <code>artifactId</code> plugin.
* <br/>
* Example:
* <table>
* <tr>
* <td>Configuration</td>
* <td>Result</td>
* </tr>
* <tr>
* <td><pre>&lt;option&gt;value&lt;/option&gt;</pre></td>
* <td><pre>value</pre></td>
* </tr>
* </table>
*
* @param project not null
* @param pluginArtifactId not null
* @param optionName an <code>Xpath</code> expression from the plugin <code>&lt;configuration/&gt;</code>
* @param defaultValue could be null
* @return the value for the option name or null if not found
* @throws IOException if any
*/
private static String getMavenPluginBasicOption( MavenProject project, String pluginArtifactId, String optionName,
String defaultValue )
throws IOException
{
return (String) getMavenPluginConfigurationsImpl( project, pluginArtifactId, optionName, defaultValue )
.get( optionName );
}
/**
* Return a Map for the option <code>optionName</code> defined in a project with the given
* <code>artifactId</code> plugin.
* <br/>
* Example:
* <table>
* <tr>
* <td>Configuration</td>
* <td>Result</td>
* </tr>
* <tr>
* <td><pre>
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* </pre></td>
* <td><pre>{param1=value1, param2=value2}<pre></td>
* </tr>
* </table>
*
* @param project not null
* @param pluginArtifactId not null
* @param optionName an <code>Xpath</code> expression from the plugin <code>&lt;configuration/&gt;</code>
* @param defaultValue could be null
* @return the value for the option name or null if not found
* @throws IOException if any
*/
private static Map getMavenPluginOption( MavenProject project, String pluginArtifactId, String optionName,
String defaultValue )
throws IOException
{
return (Map) getMavenPluginConfigurationsImpl( project, pluginArtifactId, optionName, defaultValue )
.get( optionName );
}
/**
* Return an array of Map for the option <code>optionName</code> defined in a project with the given
* <code>artifactId</code> plugin.
* <br/>
* Example:
* <table>
* <tr>
* <td>Configuration</td>
* <td>Result</td>
* </tr>
* <tr>
* <td><pre>
* &lt;options&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;/options&gt;
* </pre></td>
* <td><pre>[{option=[{param1=value1, param2=value2}]}, {option=[{param1=value1, param2=value2}]<pre></td>
* </tr>
* </table>
*
* @param project not null
* @param pluginArtifactId not null
* @param optionName an <code>Xpath</code> expression from the plugin <code>&lt;configuration/&gt;</code>
* @param defaultValue could be null
* @return the value for the option name or null if not found
* @throws IOException if any
*/
private static Map[] getMavenPluginOptions( MavenProject project, String pluginArtifactId, String optionName,
String defaultValue )
throws IOException
{
return (Map[]) getMavenPluginConfigurationsImpl( project, pluginArtifactId, optionName, defaultValue )
.get( optionName );
}
/**
* Return a Map for the option <code>optionName</code> defined in a project with the given
* <code>artifactId</code> plugin.
* <br/>
* Example:
* <table>
* <tr>
* <td>Configuration</td>
* <td>Result</td>
* </tr>
* <tr>
* <td><pre>&lt;option&gt;value&lt;/option&gt;</pre></td>
* <td><pre>{option=value}</pre></td>
* </tr>
* <tr>
* <td><pre>
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* </pre></td>
* <td><pre>{option={param1=value1, param2=value2}}<pre></td>
* </tr>
* <tr>
* <td><pre>
* &lt;options&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;/options&gt;
* </pre></td>
* <td><pre>{options=[{option=[{param1=value1, param2=value2}]}, {option=[{param1=value1, param2=value2}]}]<pre></td>
* </tr>
* </table>
*
* @param project not null
* @param pluginArtifactId not null
* @param optionName an <code>Xpath</code> expression from the plugin <code>&lt;configuration/&gt;</code>
* @param defaultValue could be null
* @return a map with the options found
* @throws IOException if any
*/
private static Map getMavenPluginConfigurationsImpl( MavenProject project, String pluginArtifactId,
String optionName, String defaultValue )
throws IOException
{
List plugins = new ArrayList();
for ( Iterator it = project.getModel().getReporting().getPlugins().iterator(); it.hasNext(); )
{
plugins.add( it.next() );
}
for ( Iterator it = project.getModel().getBuild().getPlugins().iterator(); it.hasNext(); )
{
plugins.add( it.next() );
}
if ( project.getBuild().getPluginManagement() != null )
{
for ( Iterator it = project.getBuild().getPluginManagement().getPlugins().iterator(); it.hasNext(); )
{
plugins.add( it.next() );
}
}
for ( Iterator it = plugins.iterator(); it.hasNext(); )
{
Object next = it.next();
Object pluginConf = null;
if ( next instanceof Plugin )
{
Plugin plugin = (Plugin) next;
// using out-of-box Maven plugins
if ( !( ( plugin.getGroupId().equals( "org.apache.maven.plugins" ) ) && ( plugin.getArtifactId()
.equals( pluginArtifactId ) ) ) )
{
continue;
}
pluginConf = plugin.getConfiguration();
}
if ( next instanceof ReportPlugin )
{
ReportPlugin reportPlugin = (ReportPlugin) next;
// using out-of-box Maven plugins
if ( !( ( reportPlugin.getGroupId().equals( "org.apache.maven.plugins" ) ) && ( reportPlugin
.getArtifactId().equals( pluginArtifactId ) ) ) )
{
continue;
}
pluginConf = reportPlugin.getConfiguration();
}
if ( pluginConf == null )
{
continue;
}
try
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse( new ByteArrayInputStream( pluginConf.toString().getBytes( "UTF-8" ) ) );
NodeList nodeList = XPathAPI.eval( doc, "//configuration/" + optionName ).nodelist();
if ( nodeList.getLength() > 0 )
{
Node optionNode = nodeList.item( 0 );
if ( isList( optionNode ) )
{
/*
* <optionNames>
* <optionName>
* <param1>value1</param1>
* <param2>value2</param2>
* </optionName>
* </optionNames>
*/
Map options = new HashMap();
List optionNames = new ArrayList();
NodeList childs = optionNode.getChildNodes();
for ( int i = 0; i < childs.getLength(); i++ )
{
Node child = childs.item( i );
if ( child.getNodeType() == Node.ELEMENT_NODE )
{
Map option = new HashMap();
if ( isElementContent( child ) )
{
Map properties = new HashMap();
NodeList childs2 = child.getChildNodes();
if ( childs2.getLength() > 0 )
{
for ( int j = 0; j < childs2.getLength(); j++ )
{
Node child2 = childs2.item( j );
if ( child2.getNodeType() == Node.ELEMENT_NODE )
{
properties.put( child2.getNodeName(), getTextContent( child2 ) );
}
}
option.put( child.getNodeName(), properties );
}
}
else
{
option.put( child.getNodeName(), getTextContent( child ) );
}
optionNames.add( option );
}
}
options.put( optionName, optionNames.toArray( new Map[0] ) );
return options;
}
if ( isElementContent( optionNode ) )
{
/*
* <optionName>
* <param1>value1</param1>
* <param2>value2</param2>
* </optionName>
*/
Map option = new HashMap();
NodeList childs = optionNode.getChildNodes();
if ( childs.getLength() > 1 )
{
Map parameters = new HashMap();
for ( int i = 0; i < childs.getLength(); i++ )
{
Node child = childs.item( i );
if ( child.getNodeType() == Node.ELEMENT_NODE )
{
parameters.put( child.getNodeName(), getTextContent( child ) );
}
}
option.put( optionName, parameters );
}
return option;
}
else
{
/*
* <optionName>value1</optionName>
*/
Map option = new HashMap();
option.put( optionName, getTextContent( optionNode ) );
return option;
}
}
}
catch ( Exception e )
{
throw new IOException( "Exception occured: " + e.getMessage() );
}
}
Map properties = new HashMap();
properties.put( optionName, defaultValue );
return properties;
}
/**
* Write copy tasks in an outputDir for EAR and WAR targets for project depencies without
* <code>provided</code> or <code>test</code> as scope
*
* @param writer not null
* @param project not null
* @param artifactResolverWrapper not null
* @param outputDir not null
*/
private static void writeCopyLib( XMLWriter writer, MavenProject project,
ArtifactResolverWrapper artifactResolverWrapper, String outputDir )
{
writer.startElement( "mkdir" );
writer.addAttribute( "dir", outputDir );
writer.endElement(); // mkdir
if ( project.getArtifacts() != null )
{
for ( Iterator i = project.getArtifacts().iterator(); i.hasNext(); )
{
Artifact artifact = (Artifact) i.next();
if ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() )
|| Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
{
String path = artifactResolverWrapper.getLocalArtifactPath( artifact );
if ( !new File( path ).isAbsolute() )
{
path = "${maven.repo.local}/" + path;
}
writer.startElement( "copy" );
writer.addAttribute( "file", path );
addWrapAttribute( writer, "copy", "todir", outputDir, 3 );
writer.endElement(); // copy
}
}
}
}
/**
* Check if a given <code>node</code> is a list of nodes or not.
* <br/>
* For instance, the node <code>options</code> is a list of <code>option</code> in the following case:
*<pre>
* &lt;options&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;option&gt;
* &lt;param1&gt;value1&lt;/param1&gt;
* &lt;param2&gt;value2&lt;/param2&gt;
* &lt;/option&gt;
* &lt;/options&gt;
* </pre>
*
* @param node a given node, may be <code>null</code>.
* @return true if the node is a list, false otherwise.
*/
private static boolean isList( Node node )
{
if ( node == null )
{
return false;
}
NodeList children = node.getChildNodes();
boolean isList = false;
String lastNodeName = null;
for ( int i = 0; i < children.getLength(); i++ )
{
Node child = children.item( i );
if ( child.getNodeType() == Node.ELEMENT_NODE )
{
isList = isList || ( child.getNodeName().equals( lastNodeName ) );
lastNodeName = child.getNodeName();
}
}
if ( StringUtils.isNotEmpty( lastNodeName ) )
{
isList = isList || lastNodeName.equals( getSingularForm( node.getNodeName() ) );
}
return isList;
}
/**
* Checks whether the specified node has element content or consists only of character data.
*
* @param node The node to test, may be <code>null</code>.
* @return <code>true</code> if any child node is an element, <code>false</code> otherwise.
*/
private static boolean isElementContent( Node node )
{
if ( node == null )
{
return false;
}
NodeList children = node.getChildNodes();
for ( int i = 0; i < children.getLength(); i++ )
{
Node child = children.item( i );
if ( child.getNodeType() == Node.ELEMENT_NODE )
{
return true;
}
}
return false;
}
/**
* Gets the text content of the specified node.
*
* @param node The node whose text contents should be retrieved, may be <code>null</code>.
* @return The text content of the node, can be empty but never <code>null</code>.
*/
private static String getTextContent( Node node )
{
StringBuffer buffer = new StringBuffer();
if ( node != null )
{
NodeList children = node.getChildNodes();
for ( int i = 0; i < children.getLength(); i++ )
{
Node child = children.item( i );
if ( child.getNodeType() == Node.TEXT_NODE || child.getNodeType() == Node.CDATA_SECTION_NODE )
{
buffer.append( child.getNodeValue() );
}
}
}
return buffer.toString();
}
/**
* Gets the singular form of the specified (English) plural form. For example:
*
* <pre>
* properties -&gt; property
* branches -&gt; branch
* reports -&gt; report
* </pre>
*
* @param pluralForm The plural form for which to derive the singular form, may be <code>null</code>.
* @return The corresponding singular form or an empty string if the input string was not recognized as a plural
* form.
*/
static String getSingularForm( String pluralForm )
{
String singularForm = "";
if ( StringUtils.isNotEmpty( pluralForm ) )
{
if ( pluralForm.endsWith( "ies" ) )
{
singularForm = pluralForm.substring( 0, pluralForm.length() - 3 ) + 'y';
}
else if ( pluralForm.endsWith( "ches" ) )
{
singularForm = pluralForm.substring( 0, pluralForm.length() - 2 );
}
else if ( pluralForm.endsWith( "s" ) && pluralForm.length() > 1 )
{
singularForm = pluralForm.substring( 0, pluralForm.length() - 1 );
}
}
return singularForm;
}
/**
* Relativizes the specified path against the given base directory (if possible). If the specified path is a
* subdirectory of the base directory, the base directory prefix will be chopped off. If the specified path is equal
* to the base directory, the path "." is returned. Otherwise, the path is returned as is. Examples:
* <table border="1">
* <tr>
* <td>basedir</td>
* <td>path</td>
* <td>result</td>
* </tr>
* <tr>
* <td>/home</td>
* <td>/home/dir</td>
* <td>dir</td>
* </tr>
* <tr>
* <td>/home</td>
* <td>/home/dir/</td>
* <td>dir/</td>
* </tr>
* <tr>
* <td>/home</td>
* <td>/home</td>
* <td>.</td>
* </tr>
* <tr>
* <td>/home</td>
* <td>/home/</td>
* <td>./</td>
* </tr>
* <tr>
* <td>/home</td>
* <td>dir</td>
* <td>dir</td>
* </tr>
* </table>
* The returned path will always use the forward slash ('/') as the file separator regardless of the current
* platform. Also, the result path will have a trailing slash if the input path has a trailing file separator.
*
* @param basedir The base directory to relativize the path against, must not be <code>null</code>.
* @param path The path to relativize, must not be <code>null</code>.
* @return The relativized path, never <code>null</code>.
*/
static String toRelative( File basedir, String path )
{
String result = null;
if ( new File( path ).isAbsolute() )
{
String pathNormalized = path.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
result = PathTool.getRelativeFilePath( basedir.getAbsolutePath(), pathNormalized );
}
if ( result == null )
{
result = path;
}
result = result.replace( '\\', '/' );
if ( result.length() <= 0 || "/".equals( result ) )
{
result = '.' + result;
}
return result;
}
}