diff --git a/maven-plugin-plugin/pom.xml b/maven-plugin-plugin/pom.xml index b7d47a1..f8b1daf 100644 --- a/maven-plugin-plugin/pom.xml +++ b/maven-plugin-plugin/pom.xml @@ -20,7 +20,7 @@ --> - org.apache.maven.plugintools + org.apache.maven maven-plugin-tools 2.4-SNAPSHOT diff --git a/maven-plugin-tools-ant/integration-tests/basic/pom.xml b/maven-plugin-tools-ant/integration-tests/basic/pom.xml new file mode 100644 index 0000000..2edf184 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/basic/pom.xml @@ -0,0 +1,56 @@ + + + + + + 4.0.0 + org.apache.maven.ant.it + maven-ant-it-basic + Basic Ant-Mojo Integration Test + 1.0-SNAPSHOT + maven-plugin + Tests the simplest case of using an Ant script to drive a mojo. + + + + ant + ant + 1.6.5 + + + + + + + maven-plugin-plugin + + antBasic + + + + org.apache.maven + maven-plugin-tools-ant + 2.0.1 + + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.build.xml b/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.build.xml new file mode 100644 index 0000000..8ba12c1 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.build.xml @@ -0,0 +1,26 @@ + + + + + + + Hello, ${name}! + + \ No newline at end of file diff --git a/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.mojos.xml b/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.mojos.xml new file mode 100644 index 0000000..d945702 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/basic/src/main/scripts/test.mojos.xml @@ -0,0 +1,38 @@ + + + + + + + + test + test + + + name + ${name} + true + false + java.lang.String + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/referenceParameter/pom.xml b/maven-plugin-tools-ant/integration-tests/referenceParameter/pom.xml new file mode 100644 index 0000000..66f18a9 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/referenceParameter/pom.xml @@ -0,0 +1,61 @@ + + + + + + 4.0.0 + org.apache.maven.plugins + maven-ant-it-referenceParameter + Ant-Mojo Integration Test with non-String parameter + 1.0-SNAPSHOT + maven-plugin + Tests using an Ant script to drive a mojo where a parameter is not a String type. + + + + org.apache.maven + maven-script-ant + 2.0.2 + + + ant + ant + 1.6.5 + + + + + + + maven-plugin-plugin + + antWithRefs + + + + org.apache.maven + maven-plugin-tools-ant + 2.0.2 + + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/java/org/apache/maven/plugins/antWithRefs/ArtifactsTask.java b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/java/org/apache/maven/plugins/antWithRefs/ArtifactsTask.java new file mode 100644 index 0000000..8c8e20e --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/java/org/apache/maven/plugins/antWithRefs/ArtifactsTask.java @@ -0,0 +1,35 @@ +package org.apache.maven.plugins.antWithRefs; + +/* + * 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 org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class ArtifactsTask + extends Task +{ + + public void execute() + throws BuildException + { + log( String.valueOf( getProject().getReference( "artifacts" ) ) ); + } + +} diff --git a/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/resources/org/apache/maven/plugins/antWithRefs/antlib.xml b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/resources/org/apache/maven/plugins/antWithRefs/antlib.xml new file mode 100755 index 0000000..2fb4b4f --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/resources/org/apache/maven/plugins/antWithRefs/antlib.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.build.xml b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.build.xml new file mode 100644 index 0000000..72a61c9 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.build.xml @@ -0,0 +1,29 @@ + + + + + + + + + Project artifacts: + + + diff --git a/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.mojos.xml b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.mojos.xml new file mode 100644 index 0000000..aee2e02 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/referenceParameter/src/main/scripts/test.mojos.xml @@ -0,0 +1,39 @@ + + + + + + + + test + test + compile + + + artifacts + ${project.artifacts} + true + true + java.util.List + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/pom.xml b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/pom.xml new file mode 100644 index 0000000..c40883a --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/pom.xml @@ -0,0 +1,65 @@ + + + + + + 4.0.0 + + org.apache.maven.ant.it + simpleUsage-root + 1.0-SNAPSHOT + + simpleUsage-plugin + Simple Ant-Mojo + maven-plugin + Tests the simplest case of using an Ant script to drive a mojo. + + + + ant + ant + 1.6.5 + + + org.apache.maven + maven-script-ant + 2.0.1 + + + + + src/main/scripts + + + maven-plugin-plugin + + antSimpleUsage + + + + org.apache.maven + maven-plugin-tools-ant + 2.0.1 + + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.build.xml b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.build.xml new file mode 100644 index 0000000..8ba12c1 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.build.xml @@ -0,0 +1,26 @@ + + + + + + + Hello, ${name}! + + \ No newline at end of file diff --git a/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.mojos.xml b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.mojos.xml new file mode 100644 index 0000000..d945702 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/simpleUsage/plugin/src/main/scripts/test.mojos.xml @@ -0,0 +1,38 @@ + + + + + + + + test + test + + + name + ${name} + true + false + java.lang.String + + + + + diff --git a/maven-plugin-tools-ant/integration-tests/simpleUsage/pom.xml b/maven-plugin-tools-ant/integration-tests/simpleUsage/pom.xml new file mode 100644 index 0000000..cc51a4d --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/simpleUsage/pom.xml @@ -0,0 +1,44 @@ + + + + + + 4.0.0 + org.apache.maven.ant.it + simpleUsage-root + Simple-Usage Ant-Mojo Integration Test - Root + 1.0-SNAPSHOT + pom + Tests the simplest case of using an Ant script to drive a mojo. + + + + ant + ant + 1.6.5 + + + + + plugin + usage + + + diff --git a/maven-plugin-tools-ant/integration-tests/simpleUsage/usage/pom.xml b/maven-plugin-tools-ant/integration-tests/simpleUsage/usage/pom.xml new file mode 100644 index 0000000..9d648b6 --- /dev/null +++ b/maven-plugin-tools-ant/integration-tests/simpleUsage/usage/pom.xml @@ -0,0 +1,71 @@ + + + + + + 4.0.0 + + org.apache.maven.ant.it + simpleUsage-root + 1.0-SNAPSHOT + + simpleUsage-usage + Simple Ant-Mojo Usage Case + Tests the simplest case of using an Ant script to drive a mojo. + + + + ant + ant + 1.6.5 + + + + + + + org.apache.maven.ant.it + simpleUsage-plugin + 1.0-SNAPSHOT + + + org.codehaus.plexus + plexus-ant-factory + 1.0-alpha-1-SNAPSHOT + + + + + Hani + + + + + test + package + + test + + + + + + + diff --git a/maven-plugin-tools-ant/pom.xml b/maven-plugin-tools-ant/pom.xml new file mode 100755 index 0000000..b001457 --- /dev/null +++ b/maven-plugin-tools-ant/pom.xml @@ -0,0 +1,49 @@ + + + + + + + maven-plugin-tools + org.apache.maven + 2.4-SNAPSHOT + + 4.0.0 + maven-plugin-tools-ant + Maven Ant Plugin Tools + + + org.apache.maven + maven-plugin-tools-api + + + org.apache.maven + maven-plugin-descriptor + + + org.apache.maven + maven-plugin-tools-model + + + org.codehaus.plexus + plexus-utils + + + diff --git a/maven-plugin-tools-ant/src/main/java/org/apache/maven/tools/plugin/extractor/ant/AntMojoDescriptorExtractor.java b/maven-plugin-tools-ant/src/main/java/org/apache/maven/tools/plugin/extractor/ant/AntMojoDescriptorExtractor.java new file mode 100644 index 0000000..5cbbb63 --- /dev/null +++ b/maven-plugin-tools-ant/src/main/java/org/apache/maven/tools/plugin/extractor/ant/AntMojoDescriptorExtractor.java @@ -0,0 +1,168 @@ +package org.apache.maven.tools.plugin.extractor.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 org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.tools.model.PluginMetadataParseException; +import org.apache.maven.plugin.tools.model.PluginMetadataParser; +import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor; +import org.apache.maven.tools.plugin.extractor.ExtractionException; +import org.codehaus.plexus.util.StringUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class AntMojoDescriptorExtractor + extends AbstractScriptedMojoDescriptorExtractor +{ + + private static final String METADATA_FILE_EXTENSION = ".mojos.xml"; + + private static final String SCRIPT_FILE_EXTENSION = ".build.xml"; + + protected List extractMojoDescriptorsFromMetadata( Map metadataFilesKeyedByBasedir, + PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + List descriptors = new ArrayList(); + + PluginMetadataParser parser = new PluginMetadataParser(); + + for ( Iterator mapIterator = metadataFilesKeyedByBasedir.entrySet().iterator(); mapIterator.hasNext(); ) + { + Map.Entry entry = (Map.Entry) mapIterator.next(); + + String basedir = (String) entry.getKey(); + Set metadataFiles = (Set) entry.getValue(); + + for ( Iterator it = metadataFiles.iterator(); it.hasNext(); ) + { + File metadataFile = (File) it.next(); + + String basename = metadataFile.getName(); + basename = basename.substring( 0, basename.length() - METADATA_FILE_EXTENSION.length() ); + + File scriptFile = new File( metadataFile.getParentFile(), basename + SCRIPT_FILE_EXTENSION ); + + if ( !scriptFile.exists() ) + { + throw new InvalidPluginDescriptorException( + "Found orphaned plugin metadata file: " + metadataFile ); + } + + String relativePath = null; + + if ( basedir.endsWith( "/" ) ) + { + basedir = basedir.substring( 0, basedir.length() - 2 ); + } + + relativePath = scriptFile.getPath().substring( basedir.length() ); + + relativePath = relativePath.replace( '\\', '/' ); + + try + { + Set mojoDescriptors = parser.parseMojoDescriptors( metadataFile ); + + for ( Iterator discoveredMojoIterator = mojoDescriptors.iterator(); discoveredMojoIterator + .hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) discoveredMojoIterator.next(); + + Map paramMap = descriptor.getParameterMap(); + + if ( !paramMap.containsKey( "basedir" ) ) + { + Parameter param = new Parameter(); + param.setName( "basedir" ); + param.setAlias( "ant.basedir" ); + param.setExpression( "${antBasedir}" ); + param.setDefaultValue( "${basedir}" ); + param.setType( "java.io.File" ); + param.setDescription( "The base directory from which to execute the Ant script." ); + param.setEditable( true ); + param.setRequired( true ); + + descriptor.addParameter( param ); + } + + if ( !paramMap.containsKey( "antMessageLevel" ) ) + { + Parameter param = new Parameter(); + param.setName( "messageLevel" ); + param.setAlias( "ant.messageLevel" ); + param.setExpression( "${antMessageLevel}" ); + param.setDefaultValue( "info" ); + param.setType( "java.lang.String" ); + param.setDescription( "The message-level used to tune the verbosity of Ant logging." ); + param.setEditable( true ); + param.setRequired( false ); + + descriptor.addParameter( param ); + } + + String implementation = relativePath; + + String dImpl = descriptor.getImplementation(); + if ( StringUtils.isNotEmpty( dImpl ) ) + { + implementation = + relativePath + dImpl.substring( PluginMetadataParser.IMPL_BASE_PLACEHOLDER.length() ); + } + + descriptor.setImplementation( implementation ); + + descriptor.setLanguage( "ant-mojo" ); + descriptor.setComponentComposer( "map-oriented" ); + descriptor.setComponentConfigurator( "map-oriented" ); + + descriptor.setPluginDescriptor( pluginDescriptor ); + + descriptors.add( descriptor ); + } + } + catch ( PluginMetadataParseException e ) + { + throw new ExtractionException( "Error extracting mojo descriptor from script: " + metadataFile, e ); + } + } + } + + return descriptors; + } + + protected String getScriptFileExtension() + { + return SCRIPT_FILE_EXTENSION; + } + + protected String getMetadataFileExtension() + { + return METADATA_FILE_EXTENSION; + } +} diff --git a/maven-plugin-tools-ant/src/main/resources/META-INF/plexus/components.xml b/maven-plugin-tools-ant/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..d552b1e --- /dev/null +++ b/maven-plugin-tools-ant/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,36 @@ + + + + + + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + ant + org.apache.maven.tools.plugin.extractor.ant.AntMojoDescriptorExtractor + + + + \ No newline at end of file diff --git a/maven-plugin-tools-api/pom.xml b/maven-plugin-tools-api/pom.xml new file mode 100644 index 0000000..7709253 --- /dev/null +++ b/maven-plugin-tools-api/pom.xml @@ -0,0 +1,46 @@ + + + + + + + maven-plugin-tools + org.apache.maven + 2.4-SNAPSHOT + + 4.0.0 + maven-plugin-tools-api + Maven Plugin Tools APIs + + + org.apache.maven + maven-project + 2.0.4 + + + org.apache.maven + maven-plugin-descriptor + + + org.codehaus.plexus + plexus-utils + + + diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/AbstractScriptedMojoDescriptorExtractor.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/AbstractScriptedMojoDescriptorExtractor.java new file mode 100644 index 0000000..8c90d8d --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/AbstractScriptedMojoDescriptorExtractor.java @@ -0,0 +1,185 @@ +package org.apache.maven.tools.plugin.extractor; + +/* + * 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 org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.util.DirectoryScanner; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * @author jdcasey + */ +public abstract class AbstractScriptedMojoDescriptorExtractor + extends AbstractLogEnabled + implements MojoDescriptorExtractor +{ + public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + String metadataExtension = getMetadataFileExtension(); + String scriptExtension = getScriptFileExtension(); + + Map scriptFilesKeyedByBasedir = + gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), scriptExtension ); + + List mojoDescriptors; + if ( !StringUtils.isEmpty( metadataExtension ) ) + { + Map metadataFilesKeyedByBasedir = + gatherFilesByBasedir( project.getBasedir(), project.getScriptSourceRoots(), metadataExtension ); + + mojoDescriptors = extractMojoDescriptorsFromMetadata( metadataFilesKeyedByBasedir, pluginDescriptor ); + } + else + { + mojoDescriptors = extractMojoDescriptors( scriptFilesKeyedByBasedir, pluginDescriptor ); + } + + copyScriptsToOutputDirectory( scriptFilesKeyedByBasedir, project.getBuild().getOutputDirectory() ); + + return mojoDescriptors; + } + + protected void copyScriptsToOutputDirectory( Map scriptFilesKeyedByBasedir, String outputDirectory ) + throws ExtractionException + { + File outputDir = new File( outputDirectory ); + + if ( !outputDir.exists() ) + { + outputDir.mkdirs(); + } + + for ( Iterator it = scriptFilesKeyedByBasedir.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + + File sourceDir = new File( (String) entry.getKey() ); + + Set scripts = (Set) entry.getValue(); + + for ( Iterator scriptIterator = scripts.iterator(); scriptIterator.hasNext(); ) + { + File scriptFile = (File) scriptIterator.next(); + + String relativePath = scriptFile.getPath().substring( sourceDir.getPath().length() ); + + if ( relativePath.charAt( 0 ) == File.separatorChar ) + { + relativePath = relativePath.substring( 1 ); + } + + File outputFile = new File( outputDir, relativePath ).getAbsoluteFile(); + + if ( !outputFile.getParentFile().exists() ) + { + outputFile.getParentFile().mkdirs(); + } + + try + { + FileUtils.copyFile( scriptFile, outputFile ); + } + catch ( IOException e ) + { + throw new ExtractionException( + "Cannot copy script file: " + scriptFile + " to output: " + outputFile, e ); + } + } + } + } + + protected Map gatherFilesByBasedir( File basedir, List directories, String scriptFileExtension ) + { + Map sourcesByBasedir = new TreeMap(); + + for ( Iterator it = directories.iterator(); it.hasNext(); ) + { + Set sources = new HashSet(); + + String resourceDir = (String) it.next(); + + File dir = new File( basedir, resourceDir ).getAbsoluteFile(); + + resourceDir = dir.getPath(); + + if ( dir.exists() ) + { + DirectoryScanner scanner = new DirectoryScanner(); + + scanner.setBasedir( dir ); + scanner.addDefaultExcludes(); + scanner.setIncludes( new String[]{"**/*" + scriptFileExtension} ); + scanner.scan(); + + String[] relativePaths = scanner.getIncludedFiles(); + + for ( int i = 0; i < relativePaths.length; i++ ) + { + String relativePath = relativePaths[i]; + File scriptFile = new File( dir, relativePath ).getAbsoluteFile(); + + if ( scriptFile.isFile() && relativePath.endsWith( scriptFileExtension ) ) + { + sources.add( scriptFile ); + } + } + + sourcesByBasedir.put( resourceDir, sources ); + } + } + + return sourcesByBasedir; + } + + protected List extractMojoDescriptorsFromMetadata( Map metadataFilesKeyedByBasedir, + PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + return null; + } + + protected String getMetadataFileExtension() + { + return null; + } + + protected List extractMojoDescriptors( Map scriptFilesKeyedByBasedir, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + return null; + } + + protected abstract String getScriptFileExtension(); + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/ExtractionException.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/ExtractionException.java new file mode 100644 index 0000000..260bd94 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/ExtractionException.java @@ -0,0 +1,36 @@ +package org.apache.maven.tools.plugin.extractor; + +/* + * 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. + */ + +public class ExtractionException + extends Exception +{ + + public ExtractionException( String message, Throwable cause ) + { + super( message, cause ); + } + + public ExtractionException( String message ) + { + super( message ); + } + +} diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/MojoDescriptorExtractor.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/MojoDescriptorExtractor.java new file mode 100644 index 0000000..a8a2886 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/extractor/MojoDescriptorExtractor.java @@ -0,0 +1,37 @@ +package org.apache.maven.tools.plugin.extractor; + +/* + * 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 org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; + +import java.util.List; + +/** + * @author jdcasey + */ +public interface MojoDescriptorExtractor +{ + String ROLE = MojoDescriptorExtractor.class.getName(); + + List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException; +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/Generator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/Generator.java new file mode 100644 index 0000000..df3f028 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/Generator.java @@ -0,0 +1,35 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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 org.apache.maven.plugin.descriptor.PluginDescriptor; + +import java.io.File; +import java.io.IOException; + +/** + * @author Jason van Zyl + * @version $Id$ + */ +public interface Generator +{ + void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) + throws IOException; +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java new file mode 100644 index 0000000..1421e79 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java @@ -0,0 +1,452 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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 org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.descriptor.Requirement; +import org.apache.maven.tools.plugin.util.PluginUtils; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; +import org.codehaus.plexus.util.xml.XMLWriter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @todo add example usage tag that can be shown in the doco + * @todo need to add validation directives so that systems embedding maven2 can + * get validation directives to help users in IDEs. + */ +public class PluginDescriptorGenerator + implements Generator +{ + public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) + throws IOException + { + File f = new File( destinationDirectory, "plugin.xml" ); + + if ( !f.getParentFile().exists() ) + { + f.getParentFile().mkdirs(); + } + + FileWriter writer = null; + try + { + writer = new FileWriter( f ); + + XMLWriter w = new PrettyPrintXMLWriter( writer ); + + w.startElement( "plugin" ); + + element( w, "description", pluginDescriptor.getDescription() ); + + element( w, "groupId", pluginDescriptor.getGroupId() ); + + element( w, "artifactId", pluginDescriptor.getArtifactId() ); + + element( w, "version", pluginDescriptor.getVersion() ); + + element( w, "goalPrefix", pluginDescriptor.getGoalPrefix() ); + + element( w, "isolatedRealm", "" + pluginDescriptor.isIsolatedRealm() ); + + element( w, "inheritedByDefault", "" + pluginDescriptor.isInheritedByDefault() ); + + w.startElement( "mojos" ); + + if ( pluginDescriptor.getMojos() != null ) + { + for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) it.next(); + processMojoDescriptor( descriptor, w ); + } + } + + w.endElement(); + + PluginUtils.writeDependencies( w, pluginDescriptor ); + + w.endElement(); + + writer.flush(); + } + finally + { + IOUtil.close( writer ); + } + } + + protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w ) + { + w.startElement( "mojo" ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "goal" ); + + w.writeText( mojoDescriptor.getGoal() ); + + w.endElement(); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + String description = mojoDescriptor.getDescription(); + + if ( description != null ) + { + w.startElement( "description" ); + + w.writeText( mojoDescriptor.getDescription() ); + + w.endElement(); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + if ( mojoDescriptor.isDependencyResolutionRequired() != null ) + { + element( w, "requiresDependencyResolution", mojoDescriptor.isDependencyResolutionRequired() ); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "requiresDirectInvocation", "" + mojoDescriptor.isDirectInvocationOnly() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "requiresProject", "" + mojoDescriptor.isProjectRequired() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "requiresReports", "" + mojoDescriptor.isRequiresReports() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "aggregator", "" + mojoDescriptor.isAggregator() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "requiresOnline", "" + mojoDescriptor.isOnlineRequired() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + element( w, "inheritedByDefault", "" + mojoDescriptor.isInheritedByDefault() ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + if ( mojoDescriptor.getPhase() != null ) + { + element( w, "phase", mojoDescriptor.getPhase() ); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + if ( mojoDescriptor.getExecutePhase() != null ) + { + element( w, "executePhase", mojoDescriptor.getExecutePhase() ); + } + + if ( mojoDescriptor.getExecuteGoal() != null ) + { + element( w, "executeGoal", mojoDescriptor.getExecuteGoal() ); + } + + if ( mojoDescriptor.getExecuteLifecycle() != null ) + { + element( w, "executeLifecycle", mojoDescriptor.getExecuteLifecycle() ); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "implementation" ); + + w.writeText( mojoDescriptor.getImplementation() ); + + w.endElement(); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "language" ); + + w.writeText( mojoDescriptor.getLanguage() ); + + w.endElement(); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + if ( mojoDescriptor.getComponentConfigurator() != null ) + { + w.startElement( "configurator" ); + + w.writeText( mojoDescriptor.getComponentConfigurator() ); + + w.endElement(); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + if ( mojoDescriptor.getComponentComposer() != null ) + { + w.startElement( "composer" ); + + w.writeText( mojoDescriptor.getComponentComposer() ); + + w.endElement(); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "instantiationStrategy" ); + + w.writeText( mojoDescriptor.getInstantiationStrategy() ); + + w.endElement(); + + // ---------------------------------------------------------------------- + // Strategy for handling repeated reference to mojo in + // the calculated (decorated, resolved) execution stack + // ---------------------------------------------------------------------- + w.startElement( "executionStrategy" ); + + w.writeText( mojoDescriptor.getExecutionStrategy() ); + + w.endElement(); + + // ---------------------------------------------------------------------- + // Parameters + // ---------------------------------------------------------------------- + + List parameters = mojoDescriptor.getParameters(); + + w.startElement( "parameters" ); + + Map requirements = new HashMap(); + + Set configuration = new HashSet(); + + if ( parameters != null ) + { + for ( int j = 0; j < parameters.size(); j++ ) + { + Parameter parameter = (Parameter) parameters.get( j ); + + String expression = parameter.getExpression(); + + if ( StringUtils.isNotEmpty( expression ) && expression.startsWith( "${component." ) ) + { + // treat it as a component...a requirement, in other words. + + // remove "component." plus expression delimiters + String role = expression.substring( "${component.".length(), expression.length() - 1 ); + + String roleHint = null; + + int posRoleHintSeparator; + + if ( ( posRoleHintSeparator = role.indexOf( "#" ) ) > 0 ) + { + roleHint = role.substring( posRoleHintSeparator + 1 ); + + role = role.substring( 0, posRoleHintSeparator ); + } + + // TODO: remove deprecated expression + requirements.put( parameter.getName(), new Requirement( role, roleHint ) ); + } + else if ( parameter.getRequirement() != null ) + { + requirements.put( parameter.getName(), parameter.getRequirement() ); + } + else + { + // treat it as a normal parameter. + + w.startElement( "parameter" ); + + element( w, "name", parameter.getName() ); + + if ( parameter.getAlias() != null ) + { + element( w, "alias", parameter.getAlias() ); + } + + element( w, "type", parameter.getType() ); + + if ( parameter.getDeprecated() != null ) + { + element( w, "deprecated", parameter.getDeprecated() ); + } + + if ( parameter.getImplementation() != null ) + { + element( w, "implementation", parameter.getImplementation() ); + } + + element( w, "required", Boolean.toString( parameter.isRequired() ) ); + + element( w, "editable", Boolean.toString( parameter.isEditable() ) ); + + element( w, "description", parameter.getDescription() ); + + if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) || + StringUtils.isNotEmpty( parameter.getExpression() ) ) + { + configuration.add( parameter ); + } + + w.endElement(); + } + + } + } + + w.endElement(); + + // ---------------------------------------------------------------------- + // Coinfiguration + // ---------------------------------------------------------------------- + + if ( !configuration.isEmpty() ) + { + w.startElement( "configuration" ); + + for ( Iterator i = configuration.iterator(); i.hasNext(); ) + { + Parameter parameter = (Parameter) i.next(); + + w.startElement( parameter.getName() ); + + String type = parameter.getType(); + if ( type != null ) + { + w.addAttribute( "implementation", type ); + } + + if ( parameter.getDefaultValue() != null ) + { + w.addAttribute( "default-value", parameter.getDefaultValue() ); + } + + if ( parameter.getExpression() != null ) + { + w.writeText( parameter.getExpression() ); + } + + w.endElement(); + } + + w.endElement(); + } + + // ---------------------------------------------------------------------- + // Requirements + // ---------------------------------------------------------------------- + + if ( !requirements.isEmpty() ) + { + w.startElement( "requirements" ); + + for ( Iterator i = requirements.keySet().iterator(); i.hasNext(); ) + { + String key = (String) i.next(); + Requirement requirement = (Requirement) requirements.get( key ); + + w.startElement( "requirement" ); + + element( w, "role", requirement.getRole() ); + + if ( requirement.getRoleHint() != null ) + { + element( w, "role-hint", requirement.getRoleHint() ); + } + + element( w, "field-name", key ); + + w.endElement(); + } + + w.endElement(); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.endElement(); + } + + public void element( XMLWriter w, String name, String value ) + { + w.startElement( name ); + + if ( value == null ) + { + value = ""; + } + + w.writeText( value ); + + w.endElement(); + } +} diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java new file mode 100644 index 0000000..2d2bd7c --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java @@ -0,0 +1,430 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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 org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.XMLWriter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @todo add example usage tag that can be shown in the doco + */ +public class PluginXdocGenerator + implements Generator +{ + + public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) + throws IOException + { + for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) it.next(); + processMojoDescriptor( descriptor, destinationDirectory ); + } + } + + protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, File destinationDirectory ) + throws IOException + { + FileWriter writer = null; + try + { + writer = new FileWriter( new File( destinationDirectory, getMojoFilename( mojoDescriptor, "xml" ) ) ); + + writeBody( writer, mojoDescriptor ); + + writer.flush(); + } + finally + { + IOUtil.close( writer ); + } + } + + private String getMojoFilename( MojoDescriptor mojo, String ext ) + { + return mojo.getGoal() + "-mojo." + ext; + } + + private void writeBody( FileWriter writer, MojoDescriptor mojoDescriptor ) + { + XMLWriter w = new PrettyPrintXMLWriter( writer ); + + w.startElement( "document" ); + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "properties" ); + + w.startElement( "title" ); + + // TODO: need a friendly name for a plugin + w.writeText( mojoDescriptor.getPluginDescriptor().getArtifactId() + " - " + mojoDescriptor.getFullGoalName() ); + + w.endElement(); // title + + w.endElement(); // properties + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + w.startElement( "body" ); + + w.startElement( "section" ); + + w.addAttribute( "name", mojoDescriptor.getFullGoalName() ); + + w.startElement( "p" ); + + if ( mojoDescriptor.getDescription() != null ) + { + w.writeMarkup( mojoDescriptor.getDescription() ); + } + else + { + w.writeText( "No description." ); + } + + w.endElement(); // p + + writeGoalAttributes( mojoDescriptor, w ); + + writeGoalParameterTable( mojoDescriptor, w ); + + w.endElement(); // section + + w.endElement(); // body + + w.endElement(); // document + } + + private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w ) + { + w.startElement( "p" ); + w.writeMarkup( "Mojo Attributes:" ); + w.startElement( "ul" ); + + String value = mojoDescriptor.getDeprecated(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "This plugin goal has been deprecated: " + value + "" ); + w.endElement(); //li + } + + if ( mojoDescriptor.isProjectRequired() ) + { + w.startElement( "li" ); + w.writeMarkup( "Requires a Maven 2.0 project to execute." ); + w.endElement(); //li + } + + if ( mojoDescriptor.isAggregator() ) + { + w.startElement( "li" ); + w.writeMarkup( "Executes as an aggregator plugin." ); + w.endElement(); //li + } + + if ( mojoDescriptor.isDirectInvocationOnly() ) + { + w.startElement( "li" ); + w.writeMarkup( "Executes by direct invocation only." ); + w.endElement(); //li + } + + value = mojoDescriptor.isDependencyResolutionRequired(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "Requires dependency resolution of artifacts in scope: " + value + "" ); + w.endElement(); //li + } + + value = mojoDescriptor.getSince(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "Since version: " + value + "" ); + w.endElement(); //li + } + + value = mojoDescriptor.getPhase(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "Automatically executes within the lifecycle phase: " + value + "" ); + w.endElement(); //li + } + + value = mojoDescriptor.getExecutePhase(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( + "Invokes the execution of the lifecycle phase " + value + " prior to executing itself." ); + w.endElement(); //li + } + + value = mojoDescriptor.getExecuteGoal(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( + "Invokes the execution of this plugin's goal " + value + " prior to executing itself." ); + w.endElement(); //li + } + + value = mojoDescriptor.getExecuteLifecycle(); + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "Executes in its own lifecycle: " + value + "" ); + w.endElement(); //li + } + + if ( mojoDescriptor.isOnlineRequired() ) + { + w.startElement( "li" ); + w.writeMarkup( "Requires that mvn runs in online mode." ); + w.endElement(); //li + } + + if ( !mojoDescriptor.isInheritedByDefault() ) + { + w.startElement( "li" ); + w.writeMarkup( "Is NOT inherited by default in multi-project builds." ); + w.endElement(); //li + } + + w.endElement();//ul + w.endElement();//p + } + + private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w ) + { + List parameterList = mojoDescriptor.getParameters(); + + //remove components and read-only parameters + List list = filterParameters( parameterList ); + + if ( list != null && list.size() > 0 ) + { + writeParameterSummary( list, w ); + + writeParameterDetails( list, w ); + } + } + + private List filterParameters( List parameterList ) + { + List filtered = new ArrayList(); + + if ( parameterList != null ) + { + for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); ) + { + Parameter parameter = (Parameter) parameters.next(); + + if ( parameter.isEditable() ) + { + String expression = parameter.getExpression(); + + if ( expression == null || !expression.startsWith( "${component." ) ) + { + filtered.add( parameter ); + } + } + } + } + + return filtered; + } + + private void writeParameterDetails( List parameterList, XMLWriter w ) + { + w.startElement( "subsection" ); + w.addAttribute( "name", "Parameter Details" ); + + for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); ) + { + Parameter parameter = (Parameter) parameters.next(); + + w.startElement( "p" ); + w.writeMarkup( "" + parameter.getName() + "" ); + w.endElement(); //p + + String description = parameter.getDescription(); + if ( StringUtils.isEmpty( description ) ) + { + description = "No Description."; + } + w.startElement( "p" ); + w.writeMarkup( description ); + w.endElement(); //p + + w.startElement( "ul" ); + + writeDetail( "Deprecated", parameter.getDeprecated(), w ); + + writeDetail( "Type", parameter.getType(), w ); + + writeDetail( "Since", parameter.getSince(), w ); + + if ( parameter.isRequired() ) + { + writeDetail( "Required", "Yes", w ); + } + else + { + writeDetail( "Required", "No", w ); + } + + writeDetail( "Expression", parameter.getExpression(), w ); + + writeDetail( "Default", parameter.getDefaultValue(), w ); + + w.endElement();//ul + + if ( parameters.hasNext() ) + { + w.writeMarkup( "
" ); + } + } + + w.endElement(); + } + + private void writeDetail( String param, String value, XMLWriter w ) + { + if ( StringUtils.isNotEmpty( value ) ) + { + w.startElement( "li" ); + w.writeMarkup( "" + param + ": " ); + w.writeText( value ); + w.writeMarkup( "" ); + w.endElement(); //li + } + } + + private void writeParameterSummary( List parameterList, XMLWriter w ) + { + List requiredParams = getParametersByRequired( true, parameterList ); + if ( requiredParams.size() > 0 ) + { + writeParameterList( "Required Parameters", requiredParams, w ); + } + + List optionalParams = getParametersByRequired( false, parameterList ); + if ( optionalParams.size() > 0 ) + { + writeParameterList( "Optional Parameters", optionalParams, w ); + } + } + + private void writeParameterList( String title, List parameterList, XMLWriter w ) + { + w.startElement( "subsection" ); + w.addAttribute( "name", title ); + + w.startElement( "table" ); + + w.startElement( "tr" ); + w.startElement( "th" ); + w.writeText( "Name" ); + w.endElement();//th + w.startElement( "th" ); + w.writeText( "Type" ); + w.endElement();//th + w.startElement( "th" ); + w.writeText( "Description" ); + w.endElement();//th + w.endElement();//tr + + for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); ) + { + Parameter parameter = (Parameter) parameters.next(); + + w.startElement( "tr" ); + w.startElement( "td" ); + w.writeMarkup( "" + parameter.getName() + "" ); + w.endElement();//td + w.startElement( "td" ); + int index = parameter.getType().lastIndexOf( "." ); + w.writeMarkup( "" + parameter.getType().substring( index + 1 ) + "" ); + w.endElement();//td + w.startElement( "td" ); + String description = parameter.getDescription(); + if ( StringUtils.isEmpty( description ) ) + { + description = "No description."; + } + if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) + { + description = "Deprecated. " + description; + } + w.writeMarkup( description ); + + if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) ) + { + w.writeMarkup( " Default value is " ); + w.writeText( parameter.getDefaultValue() ); + w.writeMarkup( "." ); + } + w.endElement();//td + w.endElement(); //tr + } + + w.endElement();//table + w.endElement();//section + } + + private List getParametersByRequired( boolean required, List parameterList ) + { + List list = new ArrayList(); + + for ( Iterator parameters = parameterList.iterator(); parameters.hasNext(); ) + { + Parameter parameter = (Parameter) parameters.next(); + + if ( parameter.isRequired() == required ) + { + list.add( parameter ); + } + } + + return list; + } +} + + diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PrettyPrintXMLWriter.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PrettyPrintXMLWriter.java new file mode 100644 index 0000000..0d5e87f --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PrettyPrintXMLWriter.java @@ -0,0 +1,185 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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.PrintWriter; +import java.io.Writer; + +/** + * Copied from plexus-utils 1.3-SNAPSHOT as we can't upgrade it yet. + * This class can be removed when a newer version of plexus-utils is included with Maven + * + * @see org.codehaus.plexus.util.xml.PrettyPrintXMLWriter + */ +public class PrettyPrintXMLWriter + extends org.codehaus.plexus.util.xml.PrettyPrintXMLWriter +{ + + private static final String LS = System.getProperty( "line.separator" ); + + private PrintWriter writer; + + private String lineIndenter; + + private int depth; + + public PrettyPrintXMLWriter( PrintWriter writer, String lineIndenter ) + { + this( writer, lineIndenter, null, null ); + } + + public PrettyPrintXMLWriter( Writer writer, String lineIndenter ) + { + this( new PrintWriter( writer ), lineIndenter ); + } + + public PrettyPrintXMLWriter( PrintWriter writer ) + { + this( writer, null, null ); + } + + public PrettyPrintXMLWriter( Writer writer ) + { + this( new PrintWriter( writer ) ); + } + + public PrettyPrintXMLWriter( PrintWriter writer, String lineIndenter, String encoding, String doctype ) + { + super( writer, lineIndenter, encoding, doctype ); + + setWriter( writer ); + + setLineIndenter( lineIndenter ); + } + + public PrettyPrintXMLWriter( Writer writer, String lineIndenter, String encoding, String doctype ) + { + this( new PrintWriter( writer ), lineIndenter, encoding, doctype ); + } + + public PrettyPrintXMLWriter( PrintWriter writer, String encoding, String doctype ) + { + this( writer, " ", encoding, doctype ); + } + + public PrettyPrintXMLWriter( Writer writer, String encoding, String doctype ) + { + this( new PrintWriter( writer ), encoding, doctype ); + } + + /** + * Write a string to the underlying writer + * + * @param str + */ + private void write( String str ) + { + getWriter().write( str ); + } + + /** + * Get the string used as line indenter + * + * @return the line indenter + */ + protected String getLineIndenter() + { + return lineIndenter; + } + + /** + * Set the string used as line indenter + * + * @param lineIndenter + */ + protected void setLineIndenter( String lineIndenter ) + { + this.lineIndenter = lineIndenter; + } + + /** + * Write the end of line character (using system line separator) + * and start new line with indentation + */ + protected void endOfLine() + { + write( LS ); + + for ( int i = 0; i < getDepth(); i++ ) + { + write( getLineIndenter() ); + } + } + + /** + * Set the underlying writer + * + * @param writer + */ + protected void setWriter( PrintWriter writer ) + { + this.writer = writer; + } + + /** + * Get the underlying writer + * + * @return the underlying writer + */ + protected PrintWriter getWriter() + { + return writer; + } + + /** + * Set the current depth in the xml indentation + * + * @param depth + */ + protected void setDepth( int depth ) + { + this.depth = depth; + } + + /** + * Get the current depth in the xml indentation + * + * @return + */ + protected int getDepth() + { + return depth; + } + + public void startElement( String name ) + { + super.startElement( name ); + + setDepth( getDepth() + 1 ); + } + + public void endElement() + { + super.endElement(); + + setDepth( getDepth() - 1 ); + } + +} diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScanner.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScanner.java new file mode 100644 index 0000000..7ebabae --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScanner.java @@ -0,0 +1,151 @@ +package org.apache.maven.tools.plugin.scanner; + +/* + * 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 org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.ExtractionException; +import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; +import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.logging.console.ConsoleLogger; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author jdcasey + */ +public class DefaultMojoScanner + extends AbstractLogEnabled + implements MojoScanner +{ + + private Map mojoDescriptorExtractors; + + /** + * The names of the active extractors + */ + private Set/* */activeExtractors; + + public DefaultMojoScanner( Map extractors ) + { + this.mojoDescriptorExtractors = extractors; + + this.enableLogging( new ConsoleLogger( Logger.LEVEL_INFO, "standalone-scanner-logger" ) ); + } + + public DefaultMojoScanner() + { + } + + public void populatePluginDescriptor( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + Logger logger = getLogger(); + Set activeExtractors = getActiveExtractors(); + + logger.info( "Using " + activeExtractors.size() + " extractors." ); + + int numMojoDescriptors = 0; + + for ( Iterator it = activeExtractors.iterator(); it.hasNext(); ) + { + String language = (String) it.next(); + MojoDescriptorExtractor extractor = (MojoDescriptorExtractor) mojoDescriptorExtractors.get( language ); + + if ( extractor == null ) + { + throw new ExtractionException( "No extractor for language: " + language ); + } + + logger.info( "Applying extractor for language: " + language ); + + List extractorDescriptors = extractor.execute( project, pluginDescriptor ); + + logger.info( "Extractor for language: " + language + " found " + extractorDescriptors.size() + + " mojo descriptors." ); + numMojoDescriptors += extractorDescriptors.size(); + + for ( Iterator descriptorIt = extractorDescriptors.iterator(); descriptorIt.hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) descriptorIt.next(); + + logger.debug( "Adding mojo: " + descriptor + " to plugin descriptor." ); + + descriptor.setPluginDescriptor( pluginDescriptor ); + + pluginDescriptor.addMojo( descriptor ); + } + } + + if ( numMojoDescriptors == 0 ) + { + throw new InvalidPluginDescriptorException( "No mojo descriptors found in plugin." ); + } + } + + /** + * Gets the name of the active extractors. + * + * @return A Set containing the names of the active extractors. + */ + protected Set/* */getActiveExtractors() + { + Set/* */result = activeExtractors; + + if ( result == null ) + { + result = new HashSet/* */( mojoDescriptorExtractors.keySet() ); + } + + return result; + } + + /** + * @see org.apache.maven.tools.plugin.scanner.MojoScanner#setActiveExtractors(java.util.Set) + */ + public void setActiveExtractors( Set/* */extractors ) + { + if ( extractors == null ) + { + this.activeExtractors = null; + } + else + { + this.activeExtractors = new HashSet/* */(); + + for ( Iterator i = extractors.iterator(); i.hasNext(); ) + { + String extractor = (String) i.next(); + + if ( extractor != null && extractor.length() > 0 ) + { + this.activeExtractors.add( extractor ); + } + } + } + } +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/MojoScanner.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/MojoScanner.java new file mode 100644 index 0000000..491dfd8 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/scanner/MojoScanner.java @@ -0,0 +1,51 @@ +package org.apache.maven.tools.plugin.scanner; + +/* + * 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 org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.ExtractionException; + +import java.util.Set; + +/** + * @author jdcasey + */ +public interface MojoScanner +{ + String ROLE = MojoScanner.class.getName(); + + void populatePluginDescriptor( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException; + + + /** + * Sets the active extractors. + *

+ * Only the specified extractors will be used, all others will be skipped. + * + * @param extractors The names of the sctive extractors. If this parameter is null, + * all the scanner's extractors are considered active. Set entries that are + * null or empty ("") will be ignored. + */ + void setActiveExtractors( Set/* */extractors ); + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java new file mode 100644 index 0000000..9c9988e --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java @@ -0,0 +1,128 @@ +package org.apache.maven.tools.plugin.util; + +/* + * 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 org.apache.maven.model.Dependency; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.codehaus.plexus.component.repository.ComponentDependency; +import org.codehaus.plexus.util.DirectoryScanner; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.XMLWriter; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * @author jdcasey + */ +public final class PluginUtils +{ + + private PluginUtils() + { + } + + public static String[] findSources( String basedir, String include ) + { + return PluginUtils.findSources( basedir, include, null ); + } + + public static String[] findSources( String basedir, String include, String exclude ) + { + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir( basedir ); + scanner.setIncludes( new String[]{include} ); + if ( !StringUtils.isEmpty( exclude ) ) + { + // TODO: need default excludes in scanner + scanner.setExcludes( new String[]{exclude, "**/.svn/**"} ); + } + else + { + scanner.setExcludes( new String[]{"**/.svn/**"} ); + } + + scanner.scan(); + + return scanner.getIncludedFiles(); + } + + public static void writeDependencies( XMLWriter w, PluginDescriptor pluginDescriptor ) + { + + w.startElement( "dependencies" ); + + for ( Iterator it = pluginDescriptor.getDependencies().iterator(); it.hasNext(); ) + { + ComponentDependency dep = (ComponentDependency) it.next(); + + w.startElement( "dependency" ); + + PluginUtils.element( w, "groupId", dep.getGroupId() ); + + PluginUtils.element( w, "artifactId", dep.getArtifactId() ); + + PluginUtils.element( w, "type", dep.getType() ); + + PluginUtils.element( w, "version", dep.getVersion() ); + + w.endElement(); + } + + w.endElement(); + } + + public static List toComponentDependencies( List dependencies ) + { + List componentDeps = new LinkedList(); + + for ( Iterator it = dependencies.iterator(); it.hasNext(); ) + { + Dependency dependency = (Dependency) it.next(); + + ComponentDependency cd = new ComponentDependency(); + + cd.setArtifactId( dependency.getArtifactId() ); + cd.setGroupId( dependency.getGroupId() ); + cd.setVersion( dependency.getVersion() ); + cd.setType( dependency.getType() ); + + componentDeps.add( cd ); + } + + return componentDeps; + } + + private static void element( XMLWriter w, String name, String value ) + { + w.startElement( name ); + + if ( value == null ) + { + value = ""; + } + + w.writeText( value ); + + w.endElement(); + } + +} diff --git a/maven-plugin-tools-api/src/main/resources/META-INF/plexus/components.xml b/maven-plugin-tools-api/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..bea45db --- /dev/null +++ b/maven-plugin-tools-api/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,42 @@ + + + + + + + + org.apache.maven.tools.plugin.scanner.MojoScanner + org.apache.maven.tools.plugin.scanner.DefaultMojoScanner + per-lookup + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + mojoDescriptorExtractors + + + + + + \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/AbstractGeneratorTestCase.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/AbstractGeneratorTestCase.java new file mode 100644 index 0000000..b3b1d41 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/AbstractGeneratorTestCase.java @@ -0,0 +1,135 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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 junit.framework.TestCase; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.codehaus.plexus.component.repository.ComponentDependency; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Jason van Zyl + * @version $Id: AbstractGeneratorTestCase.java,v 1.1 2005/02/20 16:25:21 + * jdcasey Exp $ + */ +public abstract class AbstractGeneratorTestCase + extends TestCase +{ + protected Generator generator; + + protected String basedir; + + protected void setUp() + throws Exception + { + basedir = System.getProperty( "basedir" ); + } + + public void testGenerator() + throws Exception + { + setupGenerator(); + + MojoDescriptor mojoDescriptor = new MojoDescriptor(); + mojoDescriptor.setGoal( "testGoal" ); + mojoDescriptor.setImplementation( "org.apache.maven.tools.plugin.generator.TestMojo" ); + mojoDescriptor.setDependencyResolutionRequired( "compile" ); + + List params = new ArrayList(); + + Parameter param = new Parameter(); + param.setExpression( "${project.build.directory}" ); + param.setName( "dir" ); + param.setRequired( true ); + param.setType( "java.lang.String" ); + param.setDescription( "Test parameter description" ); + + params.add( param ); + + mojoDescriptor.setParameters( params ); + + PluginDescriptor pluginDescriptor = new PluginDescriptor(); + mojoDescriptor.setPluginDescriptor( pluginDescriptor ); + + pluginDescriptor.addMojo( mojoDescriptor ); + + pluginDescriptor.setArtifactId( "maven-unitTesting-plugin" ); + pluginDescriptor.setGoalPrefix( "test" ); + + ComponentDependency dependency = new ComponentDependency(); + dependency.setGroupId( "testGroup" ); + dependency.setArtifactId( "testArtifact" ); + dependency.setVersion( "0.0.0" ); + + pluginDescriptor.setDependencies( Collections.singletonList( dependency ) ); + + File destinationDirectory = new File( System.getProperty( "java.io.tmpdir" ), "testGenerator-outDir" ); + FileUtils.deleteDirectory( destinationDirectory ); + destinationDirectory.mkdir(); + + generator.execute( destinationDirectory, pluginDescriptor ); + + validate( destinationDirectory ); + + FileUtils.deleteDirectory( destinationDirectory ); + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + protected void setupGenerator() + throws Exception + { + String generatorClassName = getClass().getName(); + + generatorClassName = generatorClassName.substring( 0, generatorClassName.length() - 4 ); + + try + { + Class generatorClass = Thread.currentThread().getContextClassLoader().loadClass( generatorClassName ); + + generator = (Generator) generatorClass.newInstance(); + } + catch ( Exception e ) + { + throw new Exception( "Cannot find " + generatorClassName + + "! Make sure your test case is named in the form ${generatorClassName}Test " + + "or override the setupPlugin() method to instantiate the mojo yourself." ); + } + } + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + + protected void validate( File destinationDirectory ) + throws Exception + { + // empty + } +} diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGeneratorTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGeneratorTest.java new file mode 100644 index 0000000..9492fde --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGeneratorTest.java @@ -0,0 +1,129 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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 org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder; +import org.codehaus.plexus.component.repository.ComponentDependency; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.List; + +/** + * @author Jason van Zyl + * @version $Id: PluginDescriptorGeneratorTest.java,v 1.1.1.1 2004/08/09 + * 18:43:10 jvanzyl Exp $ + */ +public class PluginDescriptorGeneratorTest + extends AbstractGeneratorTestCase +{ + protected void validate( File destinationDirectory ) + throws Exception + { + PluginDescriptorBuilder pdb = new PluginDescriptorBuilder(); + + File pluginDescriptorFile = new File( destinationDirectory, "plugin.xml" ); + + String pd = readFile( pluginDescriptorFile ); + + PluginDescriptor pluginDescriptor = pdb.build( new StringReader( pd ) ); + + assertEquals( 1, pluginDescriptor.getMojos().size() ); + + MojoDescriptor mojoDescriptor = (MojoDescriptor) pluginDescriptor.getMojos().get( 0 ); + + checkMojo( mojoDescriptor ); + + // ---------------------------------------------------------------------- + // Dependencies + // ---------------------------------------------------------------------- + + List dependencies = pluginDescriptor.getDependencies(); + + checkDependency( "testGroup", "testArtifact", "0.0.0", (ComponentDependency) dependencies.get( 0 ) ); + + assertEquals( 1, dependencies.size() ); + + ComponentDependency dependency = (ComponentDependency) dependencies.get( 0 ); + assertEquals( "testGroup", dependency.getGroupId() ); + assertEquals( "testArtifact", dependency.getArtifactId() ); + assertEquals( "0.0.0", dependency.getVersion() ); + } + + private String readFile( File pluginDescriptorFile ) + throws IOException + { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter( sWriter ); + + BufferedReader reader = new BufferedReader( new FileReader( pluginDescriptorFile ) ); + + String line = null; + while ( ( line = reader.readLine() ) != null ) + { + pWriter.println( line ); + } + + reader.close(); + + return sWriter.toString(); + } + + private void checkMojo( MojoDescriptor mojoDescriptor ) + { + assertEquals( "test:testGoal", mojoDescriptor.getFullGoalName() ); + + assertEquals( "org.apache.maven.tools.plugin.generator.TestMojo", mojoDescriptor.getImplementation() ); + + // The following should be defaults + assertEquals( "per-lookup", mojoDescriptor.getInstantiationStrategy() ); + + assertNotNull( mojoDescriptor.isDependencyResolutionRequired() ); + + // check the parameter. + checkParameter( (Parameter) mojoDescriptor.getParameters().get( 0 ) ); + } + + private void checkParameter( Parameter parameter ) + { + assertEquals( "dir", parameter.getName() ); + assertEquals( String.class.getName(), parameter.getType() ); + assertTrue( parameter.isRequired() ); + } + + private void checkDependency( String groupId, String artifactId, String version, ComponentDependency dependency ) + { + assertNotNull( dependency ); + + assertEquals( groupId, dependency.getGroupId() ); + + assertEquals( artifactId, dependency.getArtifactId() ); + + assertEquals( version, dependency.getVersion() ); + } +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginXdocGeneratorTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginXdocGeneratorTest.java new file mode 100644 index 0000000..98dcbd5 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/generator/PluginXdocGeneratorTest.java @@ -0,0 +1,30 @@ +package org.apache.maven.tools.plugin.generator; + +/* + * 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. + */ + +/** + * @author Jason van Zyl + * @version $Id: PluginXdocGeneratorTest.java,v 1.1 2005/02/20 16:25:21 jdcasey + * Exp $ + */ +public class PluginXdocGeneratorTest + extends AbstractGeneratorTestCase +{ +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScannerTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScannerTest.java new file mode 100644 index 0000000..d3a31b5 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/DefaultMojoScannerTest.java @@ -0,0 +1,197 @@ +package org.apache.maven.tools.plugin.scanner; + +/* + * 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 junit.framework.TestCase; +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; +import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.ExtractionException; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author jdcasey + */ +public class DefaultMojoScannerTest + extends TestCase +{ + private Map extractors; + + private Build build; + + private Model model; + + private MojoScanner scanner; + + private MavenProject project; + + protected void setUp() + throws Exception + { + extractors = new HashMap(); + extractors.put( "one", new ScannerTestExtractor( "one" ) ); + extractors.put( "two", new ScannerTestExtractor( "two" ) ); + extractors.put( "three", new ScannerTestExtractor( "three" ) ); + + scanner = new DefaultMojoScanner( extractors ); + + build = new Build(); + build.setSourceDirectory( "testdir" ); + + model = new Model(); + model.setBuild( build ); + + project = new MavenProject( model ); + project.setFile( new File( "." ) ); + } + + public void testUnspecifiedExtractors() + throws Exception + { + PluginDescriptor pluginDescriptor = createPluginDescriptor(); + + scanner.populatePluginDescriptor( project, pluginDescriptor ); + + checkResult( pluginDescriptor, extractors.keySet() ); + } + + public void testSpecifiedExtractors() + throws Exception + { + Set activeExtractors = new HashSet(); + activeExtractors.add( "one" ); + activeExtractors.add( "" ); + activeExtractors.add( null ); + activeExtractors.add( "three" ); + + PluginDescriptor pluginDescriptor = createPluginDescriptor(); + + scanner.setActiveExtractors( activeExtractors ); + scanner.populatePluginDescriptor( project, pluginDescriptor ); + + checkResult( pluginDescriptor, Arrays.asList( new String[]{"one", "three"} ) ); + } + + public void testAllExtractorsThroughNull() + throws Exception + { + PluginDescriptor pluginDescriptor = createPluginDescriptor(); + + scanner.setActiveExtractors( null ); + scanner.populatePluginDescriptor( project, pluginDescriptor ); + + checkResult( pluginDescriptor, extractors.keySet() ); + } + + public void testNoExtractorsThroughEmptySet() + throws Exception + { + PluginDescriptor pluginDescriptor = createPluginDescriptor(); + + scanner.setActiveExtractors( Collections.EMPTY_SET ); + try + { + scanner.populatePluginDescriptor( project, pluginDescriptor ); + fail( "Expected exception" ); + } + catch (InvalidPluginDescriptorException e) + { + // Ok + } + + checkResult( pluginDescriptor, Collections.EMPTY_SET ); + } + + public void testUnknownExtractor() + throws Exception + { + Set activeExtractors = new HashSet(); + activeExtractors.add( "four" ); + + PluginDescriptor pluginDescriptor = createPluginDescriptor(); + + scanner.setActiveExtractors( activeExtractors ); + + try + { + scanner.populatePluginDescriptor( project, pluginDescriptor ); + fail( "No error for unknown extractor" ); + } + catch ( ExtractionException e ) + { + // Ok + } + + checkResult( pluginDescriptor, Collections.EMPTY_SET ); + } + + private PluginDescriptor createPluginDescriptor() + { + PluginDescriptor pluginDescriptor = new PluginDescriptor(); + pluginDescriptor.setGroupId( "groupId" ); + pluginDescriptor.setArtifactId( "artifactId" ); + pluginDescriptor.setVersion( "version" ); + pluginDescriptor.setGoalPrefix( "testId" ); + return pluginDescriptor; + } + + /** + * Checks if the {@link PluginDescriptor} contains exactly the {@link MojoDescriptor}s with the + * supplied goal names. + * + * @param pluginDescriptor The {@link PluginDescriptor} to check. + * @param expectedGoals The goal names of the {@link MojoDescriptor}s. + */ + protected void checkResult( PluginDescriptor pluginDescriptor, Collection expectedGoals ) + { + Set remainingGoals = new HashSet( expectedGoals ); + List descriptors = pluginDescriptor.getMojos(); + + if ( descriptors == null ) + { + // TODO Maybe getMojos should be more user frendly and not return null + descriptors = Collections.EMPTY_LIST; + } + + for ( Iterator i = descriptors.iterator(); i.hasNext(); ) + { + MojoDescriptor desc = (MojoDescriptor) i.next(); + assertEquals( pluginDescriptor, desc.getPluginDescriptor() ); + assertTrue( "Unexpected goal in PluginDescriptor: " + desc.getGoal(), + remainingGoals.remove( desc.getGoal() ) ); + } + + assertTrue( "Extpected goals missing from PluginDescriptor: " + remainingGoals, remainingGoals.size() == 0 ); + } + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/ScannerTestExtractor.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/ScannerTestExtractor.java new file mode 100644 index 0000000..58261ac --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/ScannerTestExtractor.java @@ -0,0 +1,52 @@ +package org.apache.maven.tools.plugin.scanner; + +/* + * 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 org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; + +import java.util.Collections; +import java.util.List; + +/** + * @author jdcasey + */ +public class ScannerTestExtractor + implements MojoDescriptorExtractor +{ + private final String goal; + + public ScannerTestExtractor( String goal ) + { + this.goal = goal; + } + + public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + { + MojoDescriptor desc = new MojoDescriptor(); + desc.setPluginDescriptor( pluginDescriptor ); + desc.setGoal( goal ); + + return Collections.singletonList( desc ); + } + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/TestExtractor.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/TestExtractor.java new file mode 100644 index 0000000..37c7670 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/scanner/TestExtractor.java @@ -0,0 +1,46 @@ +package org.apache.maven.tools.plugin.scanner; + +/* + * 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 org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; + +import java.util.Collections; +import java.util.List; + +/** + * @author jdcasey + */ +public class TestExtractor + implements MojoDescriptorExtractor +{ + + public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + { + MojoDescriptor desc = new MojoDescriptor(); + desc.setPluginDescriptor( pluginDescriptor ); + desc.setGoal( "testGoal" ); + + return Collections.singletonList( desc ); + } + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java new file mode 100644 index 0000000..b9e9ea2 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java @@ -0,0 +1,99 @@ +package org.apache.maven.tools.plugin.util; + +/* + * 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 junit.framework.TestCase; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.codehaus.plexus.component.repository.ComponentDependency; +import org.codehaus.plexus.util.xml.CompactXMLWriter; +import org.codehaus.plexus.util.xml.XMLWriter; + +import java.io.StringWriter; +import java.util.Collections; + +/** + * @author jdcasey + */ +public class PluginUtilsTest + extends TestCase +{ + + public void testShouldTrimArtifactIdToFindPluginId() + { + assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "maven-artifactId-plugin" ) ); + assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "maven-plugin-artifactId" ) ); + assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "artifactId-maven-plugin" ) ); + assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "artifactId" ) ); + assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "artifactId-plugin" ) ); + assertEquals( "plugin", PluginDescriptor.getGoalPrefixFromArtifactId( "maven-plugin-plugin" ) ); + } + + public void testShouldWriteDependencies() + throws Exception + { + ComponentDependency dependency = new ComponentDependency(); + dependency.setArtifactId( "testArtifactId" ); + dependency.setGroupId( "testGroupId" ); + dependency.setType( "pom" ); + dependency.setVersion( "0.0.0" ); + + PluginDescriptor descriptor = new PluginDescriptor(); + descriptor.setDependencies( Collections.singletonList( dependency ) ); + + StringWriter sWriter = new StringWriter(); + XMLWriter writer = new CompactXMLWriter( sWriter ); + + PluginUtils.writeDependencies( writer, descriptor ); + + String output = sWriter.toString(); + + String pattern = "" + "" + "testGroupId" + + "testArtifactId" + "pom" + "0.0.0" + + "" + ""; + + assertEquals( pattern, output ); + } + + public void testShouldFindTwoScriptsWhenNoExcludesAreGiven() + { + String testScript = "test.txt"; + + String basedir = TestUtils.dirname( testScript ); + + String includes = "**/*.txt"; + + String[] files = PluginUtils.findSources( basedir, includes ); + assertEquals( 2, files.length ); + } + + public void testShouldFindOneScriptsWhenAnExcludeIsGiven() + { + String testScript = "test.txt"; + + String basedir = TestUtils.dirname( testScript ); + + String includes = "**/*.txt"; + String excludes = "**/*Excludes.txt"; + + String[] files = PluginUtils.findSources( basedir, includes, excludes ); + assertEquals( 1, files.length ); + } + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/TestUtils.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/TestUtils.java new file mode 100644 index 0000000..fb3fde4 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/TestUtils.java @@ -0,0 +1,54 @@ +package org.apache.maven.tools.plugin.util; + +/* + * 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 junit.framework.TestCase; + +import java.net.URL; + +/** + * @author jdcasey + */ +public class TestUtils + extends TestCase +{ + + public void testDirnameFunction_METATEST() + { + String classname = getClass().getName().replace( '.', '/' ) + ".class"; + String basedir = TestUtils.dirname( classname ); + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + URL resource = cl.getResource( classname ); + + assertEquals( resource.getPath(), basedir + classname ); + } + + public static String dirname( String file ) + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + URL fileResource = cl.getResource( file ); + + String fullPath = fileResource.getPath(); + + return fullPath.substring( 0, fullPath.length() - file.length() ); + } + +} \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/resources/META-INF/plexus/scannerTestComponents.xml b/maven-plugin-tools-api/src/test/resources/META-INF/plexus/scannerTestComponents.xml new file mode 100644 index 0000000..d8ebcb1 --- /dev/null +++ b/maven-plugin-tools-api/src/test/resources/META-INF/plexus/scannerTestComponents.xml @@ -0,0 +1,41 @@ + + + + + + + org.apache.maven.tools.plugin.scanner.MojoScanner + org.apache.maven.tools.plugin.scanner.DefaultMojoScanner + per-lookup + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + mojoDescriptorExtractors + + + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + test + org.apache.maven.tools.plugin.scanner.TestExtractor + + + + \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/resources/test.txt b/maven-plugin-tools-api/src/test/resources/test.txt new file mode 100644 index 0000000..273c1a9 --- /dev/null +++ b/maven-plugin-tools-api/src/test/resources/test.txt @@ -0,0 +1 @@ +This is a test. \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/resources/testExcludes.txt b/maven-plugin-tools-api/src/test/resources/testExcludes.txt new file mode 100644 index 0000000..273c1a9 --- /dev/null +++ b/maven-plugin-tools-api/src/test/resources/testExcludes.txt @@ -0,0 +1 @@ +This is a test. \ No newline at end of file diff --git a/maven-plugin-tools-beanshell/pom.xml b/maven-plugin-tools-beanshell/pom.xml new file mode 100644 index 0000000..4bd82aa --- /dev/null +++ b/maven-plugin-tools-beanshell/pom.xml @@ -0,0 +1,46 @@ + + + + + + + maven-plugin-tools + org.apache.maven + 2.4-SNAPSHOT + + 4.0.0 + maven-plugin-tools-beanshell + Maven Plugin Tools for Beanshell + + + org.apache.maven + maven-plugin-tools-api + + + bsh + bsh + 1.3.0 + + + org.apache.maven + maven-plugin-descriptor + + + diff --git a/maven-plugin-tools-beanshell/src/main/java/org/apache/maven/tools/plugin/extractor/beanshell/BeanshellMojoDescriptorExtractor.java b/maven-plugin-tools-beanshell/src/main/java/org/apache/maven/tools/plugin/extractor/beanshell/BeanshellMojoDescriptorExtractor.java new file mode 100644 index 0000000..673d936 --- /dev/null +++ b/maven-plugin-tools-beanshell/src/main/java/org/apache/maven/tools/plugin/extractor/beanshell/BeanshellMojoDescriptorExtractor.java @@ -0,0 +1,115 @@ +package org.apache.maven.tools.plugin.extractor.beanshell; + +/* + * 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 bsh.EvalError; +import bsh.Interpreter; +import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.tools.plugin.extractor.AbstractScriptedMojoDescriptorExtractor; +import org.apache.maven.tools.plugin.extractor.ExtractionException; + +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @todo share constants + * @todo add example usage tag that can be shown in the doco + * @todo need to add validation directives so that systems embedding maven2 can + * get validation directives to help users in IDEs. + */ +public class BeanshellMojoDescriptorExtractor + extends AbstractScriptedMojoDescriptorExtractor +{ + private MojoDescriptor createMojoDescriptor( String basedir, String resource, PluginDescriptor pluginDescriptor ) + throws InvalidPluginDescriptorException + { + MojoDescriptor mojoDescriptor = new MojoDescriptor(); + mojoDescriptor.setPluginDescriptor( pluginDescriptor ); + + mojoDescriptor.setLanguage( "bsh" ); + mojoDescriptor.setComponentConfigurator( "bsh" ); + + mojoDescriptor.setImplementation( resource ); + + Interpreter interpreter = new Interpreter(); + + try + { + interpreter.set( "file", new File( basedir, resource ) ); + + interpreter.set( "mojoDescriptor", mojoDescriptor ); + + interpreter.eval( new InputStreamReader( getClass().getResourceAsStream( "/extractor.bsh" ) ) ); + } + catch ( EvalError evalError ) + { + throw new InvalidPluginDescriptorException( "Error scanning beanshell script", evalError ); + } + + return mojoDescriptor; + } + + protected String getScriptFileExtension() + { + return ".bsh"; + } + + protected List extractMojoDescriptors( Map scriptFilesKeyedByBasedir, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + List descriptors = new ArrayList(); + + for ( Iterator mapIterator = scriptFilesKeyedByBasedir.entrySet().iterator(); mapIterator.hasNext(); ) + { + Map.Entry entry = (Map.Entry) mapIterator.next(); + + String basedir = (String) entry.getKey(); + Set metadataFiles = (Set) entry.getValue(); + + for ( Iterator it = metadataFiles.iterator(); it.hasNext(); ) + { + File scriptFile = (File) it.next(); + + String relativePath = null; + + if ( basedir.endsWith( "/" ) ) + { + basedir = basedir.substring( 0, basedir.length() - 2 ); + } + + relativePath = scriptFile.getPath().substring( basedir.length() ); + + relativePath = relativePath.replace( '\\', '/' ); + + MojoDescriptor mojoDescriptor = createMojoDescriptor( basedir, relativePath, pluginDescriptor ); + descriptors.add( mojoDescriptor ); + } + } + + return descriptors; + } +} \ No newline at end of file diff --git a/maven-plugin-tools-beanshell/src/main/resources/META-INF/plexus/components.xml b/maven-plugin-tools-beanshell/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..e93baca --- /dev/null +++ b/maven-plugin-tools-beanshell/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,37 @@ + + + + + + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + bsh + org.apache.maven.tools.plugin.extractor.beanshell.BeanshellMojoDescriptorExtractor + + + + + \ No newline at end of file diff --git a/maven-plugin-tools-beanshell/src/main/resources/extractor.bsh b/maven-plugin-tools-beanshell/src/main/resources/extractor.bsh new file mode 100644 index 0000000..a512c06 --- /dev/null +++ b/maven-plugin-tools-beanshell/src/main/resources/extractor.bsh @@ -0,0 +1,216 @@ +import bsh.*; +import java.util.regex.Pattern; +import java.io.FileReader; +import org.codehaus.plexus.util.StringUtils; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; + +// only on start of line +this.tag = "\\r?\\n\\s*\\*?\\s*@(\\w+)"; +// zero width lookahead to next tag or end of comment +this.tagOrEndComment = "(?=" + tag + "|\\*/)"; +this.commentTextPattern = Pattern.compile( "(?s)/\\*\\*(.*?)" + tagOrEndComment ); +this.tagsPattern = Pattern.compile( "(?s)" + tag + "\\s*(.*?)" + tagOrEndComment ); +this.descriptionPattern = Pattern.compile( "(?s)\\r?\\n\\s*\\*" ); +this.typePattern = Pattern.compile( "type\\s*=\\s*\"(.*?)\"" ); +this.expressionPattern = Pattern.compile( "expression\\s*=\\s*\"(.*?)\"" ); +this.phasePattern = Pattern.compile( "phase\\s*=\\s*\"(.*?)\"" ); +this.goalPattern = Pattern.compile( "goal\\s*=\\s*\"(.*?)\"" ); +this.lifecyclePattern = Pattern.compile( "lifecycle\\s*=\\s*\"(.*?)\"" ); +this.rolePattern = Pattern.compile( "role\\s*=\\s*\"(.*?)\"" ); +this.roleHintPattern = Pattern.compile( "roleHint\\s*=\\s*\"(.*?)\"" ); + +setAccessibility( true ); + +createParameter( text, method ) +{ + if ( method.startsWith( "set" ) ) + { + this.name = StringUtils.uncapitalise( method.substring( 3 ) ); + this.desc = getDescription( text ); + this.tags = getTags( text ); + + this.parameter = new Parameter(); + parameter.setName( name ); + parameter.setDescription( desc ); + parameter.setRequired( tags.containsKey( "required" ) ); + parameter.setEditable( !tags.containsKey( "readonly" ) ); + this.deprecation = tags.get( "deprecated" ); + if ( deprecation != null ) + { + parameter.setDeprecated( deprecation ); + } + this.alias = tags.get( "alias" ); + if ( alias != null ) + { + parameter.setAlias( alias ); + } + this.value = tags.get( "parameter" ); + if ( value != null ) + { + m = typePattern.matcher( value ); + if ( m.find() ) + { + parameter.setType( m.group( 1 ) ); + } + else + { + parameter.setType( "java.lang.Object" ); + } + m = expressionPattern.matcher( value ); + if ( m.find() ) + { + parameter.setExpression( m.group( 1 ) ); + } + } + value = tags.get( "component" ); + if ( value != null ) + { + m = rolePattern.matcher( value ); + if ( m.find() ) + { + role = m.group( 1 ); + } + m = roleHintPattern.matcher( value ); + if ( m.find() ) + { + roleHint = m.group( 1 ); + } + else + { + roleHint = null; + } + parameter.setRequirement( new Requirement( role, roleHint ) ); + } + return parameter; + } + return null; +} + +getTags( text ) +{ + this.matcher = tagsPattern.matcher( text ); + this.tags = new HashMap(); + while ( matcher.find() ) + { + this.tagname = matcher.group( 1 ); + this.tagvalue = matcher.group( 2 ); + tags.put( tagname, tagvalue.trim() ); + } + return tags; +} + +getDescription( text ) +{ + this.matcher = commentTextPattern.matcher( text ); + if ( matcher.find() ) + { + this.input = matcher.group( 1 ); + return descriptionPattern.matcher( input ).replaceAll( "" ).trim(); + } + else + { + return ""; + } +} + +extract( file, mojoDescriptor ) +{ + this.parser = new Parser( new FileReader( file ) ); + parser.setRetainComments( true ); + + this.lastNode = null; + this.firstComment = null; + while ( !parser.Line() ) + { + this.node = parser.popNode(); + + if ( node instanceof BSHFormalComment && firstComment == null ) + { + firstComment = node; + } + + if ( node instanceof BSHMethodDeclaration ) + { + if ( lastNode instanceof BSHFormalComment ) + { + this.text = lastNode.text; + + this.method = node.name; + + this.parameter = createParameter( text, method ); + if ( parameter != null ) + { + if ( "${reports}".equals( parameter.getExpression() ) ) + { + mojoDescriptor.setRequiresReports( true ); + } + mojoDescriptor.addParameter( parameter ); + } + + if ( firstComment == lastNode ) + { + firstComment = null; + } + } + } + lastNode = node; + } + if ( firstComment != null ) + { + this.text = firstComment.text; + + mojoDescriptor.setDescription( getDescription( text ) ); + this.tags = getTags( text ); + mojoDescriptor.setGoal( tags.get( "goal" ) ); + mojoDescriptor.setPhase( tags.get( "phase" ) ); + this.value = tags.get( "requiresDependencyResolution" ); + // TODO: share with java extractor + if ( value == null || value.length() == 0 ) + { + value = "runtime"; + } + mojoDescriptor.setDependencyResolutionRequired( value ); + + mojoDescriptor.setProjectRequired( tags.containsKey( "requiresProject" ) ); + mojoDescriptor.setOnlineRequired( tags.containsKey( "requiresOnline" ) ); + + this.value = tags.get( "execute" ); + if ( value != null ) + { + m = phasePattern.matcher( value ); + if ( m.find() ) + { + mojoDescriptor.setExecutePhase( m.group( 1 ) ); + } + + m = goalPattern.matcher( value ); + if ( m.find() ) + { + mojoDescriptor.setExecuteGoal( m.group( 1 ) ); + } + + if ( mojoDescriptor.getExecutePhase() == null || mojoDescriptor.getExecuteGoal() == null ) + { + throw new InvalidPluginDescriptorException( "@execute must have a phase or goal" ); + } + + if ( mojoDescriptor.getExecutePhase() != null && mojoDescriptor.getExecuteGoal() != null ) + { + throw new InvalidPluginDescriptorException( "@execute must have only one of a phase or goal" ); + } + + m = lifecyclePattern.matcher( value ); + if ( m.find() ) + { + mojoDescriptor.setExecuteLifecycle( m.group( 1 ) ); + if ( mojoDescriptor.getExecuteGoal() != null ) + { + throw new InvalidPluginDescriptorException( "@execute lifecycle requires a phase instead of a goal" ); + } + } + } + } +} + +extract( file, mojoDescriptor ); diff --git a/maven-plugin-tools-java/pom.xml b/maven-plugin-tools-java/pom.xml new file mode 100644 index 0000000..c866941 --- /dev/null +++ b/maven-plugin-tools-java/pom.xml @@ -0,0 +1,46 @@ + + + + + + + maven-plugin-tools + org.apache.maven + 2.4-SNAPSHOT + + 4.0.0 + maven-plugin-tools-java + Maven Plugin Tools for Java + + + org.apache.maven + maven-plugin-tools-api + + + org.apache.maven + maven-plugin-descriptor + + + qdox + qdox + 1.6.1 + + + diff --git a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java new file mode 100644 index 0000000..a563abe --- /dev/null +++ b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java @@ -0,0 +1,582 @@ +package org.apache.maven.tools.plugin.extractor.java; + +/* + * 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 com.thoughtworks.qdox.JavaDocBuilder; +import com.thoughtworks.qdox.model.DocletTag; +import com.thoughtworks.qdox.model.JavaClass; +import com.thoughtworks.qdox.model.JavaField; +import com.thoughtworks.qdox.model.Type; + +import org.apache.maven.plugin.descriptor.InvalidParameterException; +import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.descriptor.Requirement; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; +import org.apache.maven.tools.plugin.extractor.ExtractionException; + +import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.util.StringUtils; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Extracts Mojo descriptors from Java sources. + * + * @todo add example usage tag that can be shown in the doco + * @todo need to add validation directives so that systems embedding maven2 can + * get validation directives to help users in IDEs. + */ +public class JavaMojoDescriptorExtractor + extends AbstractLogEnabled + implements MojoDescriptorExtractor +{ + public static final String MAVEN_PLUGIN_INSTANTIATION = "instantiationStrategy"; + + public static final String CONFIGURATOR = "configurator"; + + public static final String PARAMETER = "parameter"; + + public static final String PARAMETER_EXPRESSION = "expression"; + + public static final String PARAMETER_DEFAULT_VALUE = "default-value"; + + public static final String PARAMETER_ALIAS = "alias"; + + public static final String SINCE = "since"; + + /** + * This defines the default implementation in the case the parameter type is an interface. + */ + public static final String PARAMETER_IMPLEMENTATION = "implementation"; + + /** + * This indicates the base name of the bean properties used to read/write this parameter's value. + * So: + * + * @parameter property="project" + *

+ * Would say there is a getProject() method and a setProject(Project) method. Here the field + * name would not be the basis for the parameter's name. This mode of operation will allow the + * mojos to be usable as beans and will be the promoted form of use. + */ + public static final String PARAMETER_PROPERTY = "property"; + + public static final String REQUIRED = "required"; + + public static final String DEPRECATED = "deprecated"; + + public static final String READONLY = "readonly"; + + public static final String GOAL = "goal"; + + public static final String PHASE = "phase"; + + public static final String EXECUTE = "execute"; + + public static final String EXECUTE_LIFECYCLE = "lifecycle"; + + public static final String EXECUTE_PHASE = "phase"; + + public static final String EXECUTE_GOAL = "goal"; + + public static final String GOAL_DESCRIPTION = "description"; + + public static final String GOAL_REQUIRES_DEPENDENCY_RESOLUTION = "requiresDependencyResolution"; + + public static final String GOAL_REQUIRES_PROJECT = "requiresProject"; + + public static final String GOAL_REQUIRES_REPORTS = "requiresReports"; + + public static final String GOAL_IS_AGGREGATOR = "aggregator"; + + public static final String GOAL_REQUIRES_ONLINE = "requiresOnline"; + + public static final String GOAL_INHERIT_BY_DEFAULT = "inheritByDefault"; + + public static final String GOAL_MULTI_EXECUTION_STRATEGY = "attainAlways"; + + public static final String GOAL_REQUIRES_DIRECT_INVOCATION = "requiresDirectInvocation"; + + public static final String COMPONENT = "component"; + + public static final String COMPONENT_ROLE = "role"; + + public static final String COMPONENT_ROLEHINT = "roleHint"; + + protected void validateParameter( Parameter parameter, int i ) + throws InvalidParameterException + { + // TODO: remove when backward compatibility is no longer an issue. + String name = parameter.getName(); + + if ( name == null ) + { + throw new InvalidParameterException( "name", i ); + } + + // TODO: remove when backward compatibility is no longer an issue. + String type = parameter.getType(); + + if ( type == null ) + { + throw new InvalidParameterException( "type", i ); + } + + // TODO: remove when backward compatibility is no longer an issue. + String description = parameter.getDescription(); + + if ( description == null ) + { + throw new InvalidParameterException( "description", i ); + } + } + + // ---------------------------------------------------------------------- + // Mojo descriptor creation from @tags + // ---------------------------------------------------------------------- + + protected MojoDescriptor createMojoDescriptor( JavaClass javaClass ) + throws InvalidPluginDescriptorException + { + MojoDescriptor mojoDescriptor = new MojoDescriptor(); + + mojoDescriptor.setLanguage( "java" ); + + mojoDescriptor.setImplementation( javaClass.getFullyQualifiedName() ); + + mojoDescriptor.setDescription( javaClass.getComment() ); + + DocletTag tag = findInClassHierarchy( javaClass, MAVEN_PLUGIN_INSTANTIATION ); + + if ( tag != null ) + { + mojoDescriptor.setInstantiationStrategy( tag.getValue() ); + } + + tag = findInClassHierarchy( javaClass, GOAL_MULTI_EXECUTION_STRATEGY ); + + if ( tag != null ) + { + mojoDescriptor.setExecutionStrategy( MojoDescriptor.MULTI_PASS_EXEC_STRATEGY ); + } + else + { + mojoDescriptor.setExecutionStrategy( MojoDescriptor.SINGLE_PASS_EXEC_STRATEGY ); + } + + // ---------------------------------------------------------------------- + // Configurator hint + // ---------------------------------------------------------------------- + + DocletTag configurator = findInClassHierarchy( javaClass, CONFIGURATOR ); + + if ( configurator != null ) + { + mojoDescriptor.setComponentConfigurator( configurator.getValue() ); + } + + // ---------------------------------------------------------------------- + // Goal name + // ---------------------------------------------------------------------- + + DocletTag goal = findInClassHierarchy( javaClass, GOAL ); + + if ( goal != null ) + { + mojoDescriptor.setGoal( goal.getValue() ); + } + + // ---------------------------------------------------------------------- + // What version it was introduced in + // ---------------------------------------------------------------------- + + DocletTag since = findInClassHierarchy( javaClass, SINCE ); + + if ( since != null ) + { + mojoDescriptor.setSince( since.getValue() ); + } + + // ---------------------------------------------------------------------- + // Phase name + // ---------------------------------------------------------------------- + + DocletTag phase = findInClassHierarchy( javaClass, PHASE ); + + if ( phase != null ) + { + mojoDescriptor.setPhase( phase.getValue() ); + } + + // ---------------------------------------------------------------------- + // Additional phase to execute first + // ---------------------------------------------------------------------- + + DocletTag execute = findInClassHierarchy( javaClass, EXECUTE ); + + if ( execute != null ) + { + String executePhase = execute.getNamedParameter( EXECUTE_PHASE ); + String executeGoal = execute.getNamedParameter( EXECUTE_GOAL ); + + if ( executePhase == null && executeGoal == null ) + { + throw new InvalidPluginDescriptorException( "@execute tag requires a 'phase' or 'goal' parameter" ); + } + else if ( executePhase != null && executeGoal != null ) + { + throw new InvalidPluginDescriptorException( + "@execute tag can have only one of a 'phase' or 'goal' parameter" ); + } + mojoDescriptor.setExecutePhase( executePhase ); + mojoDescriptor.setExecuteGoal( executeGoal ); + + String lifecycle = execute.getNamedParameter( EXECUTE_LIFECYCLE ); + + if ( lifecycle != null ) + { + mojoDescriptor.setExecuteLifecycle( lifecycle ); + if ( mojoDescriptor.getExecuteGoal() != null ) + { + throw new InvalidPluginDescriptorException( + "@execute lifecycle requires a phase instead of a goal" ); + } + } + } + + // ---------------------------------------------------------------------- + // Dependency resolution flag + // ---------------------------------------------------------------------- + + DocletTag requiresDependencyResolution = findInClassHierarchy( javaClass, GOAL_REQUIRES_DEPENDENCY_RESOLUTION ); + + if ( requiresDependencyResolution != null ) + { + String value = requiresDependencyResolution.getValue(); + + if ( value == null || value.length() == 0 ) + { + value = "runtime"; + } + + mojoDescriptor.setDependencyResolutionRequired( value ); + } + + // ---------------------------------------------------------------------- + // Project flag + // ---------------------------------------------------------------------- + + boolean value = getBooleanTagValue( javaClass, GOAL_REQUIRES_PROJECT, mojoDescriptor.isProjectRequired() ); + mojoDescriptor.setProjectRequired( value ); + + // ---------------------------------------------------------------------- + // Aggregator flag + // ---------------------------------------------------------------------- + + DocletTag aggregator = findInClassHierarchy( javaClass, GOAL_IS_AGGREGATOR ); + + if ( aggregator != null ) + { + mojoDescriptor.setAggregator( true ); + } + + // ---------------------------------------------------------------------- + // requiresDirectInvocation flag + // ---------------------------------------------------------------------- + + value = + getBooleanTagValue( javaClass, GOAL_REQUIRES_DIRECT_INVOCATION, mojoDescriptor.isDirectInvocationOnly() ); + mojoDescriptor.setDirectInvocationOnly( value ); + + // ---------------------------------------------------------------------- + // Online flag + // ---------------------------------------------------------------------- + + value = getBooleanTagValue( javaClass, GOAL_REQUIRES_ONLINE, mojoDescriptor.isOnlineRequired() ); + mojoDescriptor.setOnlineRequired( value ); + + // ---------------------------------------------------------------------- + // inheritByDefault flag + // ---------------------------------------------------------------------- + + value = getBooleanTagValue( javaClass, GOAL_INHERIT_BY_DEFAULT, mojoDescriptor.isInheritedByDefault() ); + mojoDescriptor.setInheritedByDefault( value ); + + extractParameters( mojoDescriptor, javaClass ); + + return mojoDescriptor; + } + + private static boolean getBooleanTagValue( JavaClass javaClass, String tagName, boolean defaultValue ) + { + DocletTag requiresProject = findInClassHierarchy( javaClass, tagName ); + + if ( requiresProject != null ) + { + String requiresProjectValue = requiresProject.getValue(); + + if ( requiresProjectValue != null && requiresProjectValue.length() > 0 ) + { + defaultValue = Boolean.valueOf( requiresProjectValue ).booleanValue(); + } + } + return defaultValue; + } + + private static DocletTag findInClassHierarchy( JavaClass javaClass, String tagName ) + { + DocletTag tag = javaClass.getTagByName( tagName ); + + if ( tag == null ) + { + JavaClass superClass = javaClass.getSuperJavaClass(); + + if ( superClass != null ) + { + tag = findInClassHierarchy( superClass, tagName ); + } + } + + return tag; + } + + private void extractParameters( MojoDescriptor mojoDescriptor, JavaClass javaClass ) + throws InvalidPluginDescriptorException + { + // --------------------------------------------------------------------------------- + // We're resolving class-level, ancestor-class-field, local-class-field order here. + // --------------------------------------------------------------------------------- + + Map rawParams = extractFieldParameterTags( javaClass ); + + for ( Iterator it = rawParams.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry entry = (Map.Entry) it.next(); + + JavaField field = (JavaField) entry.getValue(); + + Type type = field.getType(); + + Parameter pd = new Parameter(); + + if ( !type.isArray() ) + { + pd.setType( type.getValue() ); + } + else + { + StringBuffer value = new StringBuffer( type.getValue() ); + + int remaining = type.getDimensions(); + + while ( remaining-- > 0 ) + { + value.append( "[]" ); + } + + pd.setType( value.toString() ); + } + + pd.setDescription( field.getComment() ); + + DocletTag componentTag = field.getTagByName( COMPONENT ); + + if ( componentTag != null ) + { + String role = componentTag.getNamedParameter( COMPONENT_ROLE ); + + if ( role == null ) + { + role = field.getType().toString(); + } + + String roleHint = componentTag.getNamedParameter( COMPONENT_ROLEHINT ); + + if ( roleHint == null ) + { + // support alternate syntax for better compatibility with the Plexus CDC. + roleHint = componentTag.getNamedParameter( "role-hint" ); + } + + pd.setRequirement( new Requirement( role, roleHint ) ); + + pd.setName( (String) entry.getKey() ); + } + else + { + DocletTag parameter = field.getTagByName( PARAMETER ); + + // ---------------------------------------------------------------------- + // We will look for a property name here first and use that if present + // i.e: + // + // @parameter property="project" + // + // Which will become the name used for the configuration element which + // will in turn will allow plexus to use the corresponding setter. + // ---------------------------------------------------------------------- + + String property = parameter.getNamedParameter( PARAMETER_PROPERTY ); + + if ( !StringUtils.isEmpty( property ) ) + { + pd.setName( property ); + } + else + { + pd.setName( (String) entry.getKey() ); + } + + pd.setRequired( field.getTagByName( REQUIRED ) != null ); + + pd.setEditable( field.getTagByName( READONLY ) == null ); + + DocletTag deprecationTag = field.getTagByName( DEPRECATED ); + + if ( deprecationTag != null ) + { + pd.setDeprecated( deprecationTag.getValue() ); + } + + DocletTag sinceTag = field.getTagByName( SINCE ); + if ( sinceTag != null ) + { + pd.setSince( sinceTag.getValue() ); + } + + String alias = parameter.getNamedParameter( PARAMETER_ALIAS ); + + if ( !StringUtils.isEmpty( alias ) ) + { + pd.setAlias( alias ); + } + + pd.setExpression( parameter.getNamedParameter( PARAMETER_EXPRESSION ) ); + + if ( "${reports}".equals( pd.getExpression() ) ) + { + mojoDescriptor.setRequiresReports( true ); + } + + pd.setDefaultValue( parameter.getNamedParameter( PARAMETER_DEFAULT_VALUE ) ); + + pd.setImplementation( parameter.getNamedParameter( PARAMETER_IMPLEMENTATION ) ); + } + + mojoDescriptor.addParameter( pd ); + } + } + + private Map extractFieldParameterTags( JavaClass javaClass ) + { + Map rawParams; + + // we have to add the parent fields first, so that they will be overwritten by the local fields if + // that actually happens... + JavaClass superClass = javaClass.getSuperJavaClass(); + + if ( superClass != null ) + { + rawParams = extractFieldParameterTags( superClass ); + } + else + { + rawParams = new TreeMap(); + } + + JavaField[] classFields = javaClass.getFields(); + + if ( classFields != null ) + { + for ( int i = 0; i < classFields.length; i++ ) + { + JavaField field = classFields[i]; + + if ( field.getTagByName( PARAMETER ) != null || field.getTagByName( COMPONENT ) != null ) + { + rawParams.put( field.getName(), field ); + } + } + } + return rawParams; + } + + public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + JavaClass[] javaClasses = discoverClasses( project ); + + List descriptors = new ArrayList(); + + for ( int i = 0; i < javaClasses.length; i++ ) + { + DocletTag tag = javaClasses[i].getTagByName( GOAL ); + + if ( tag != null ) + { + MojoDescriptor mojoDescriptor = createMojoDescriptor( javaClasses[i] ); + mojoDescriptor.setPluginDescriptor( pluginDescriptor ); + + // Validate the descriptor as best we can before allowing it to be processed. + validate( mojoDescriptor ); + + descriptors.add( mojoDescriptor ); + } + } + + return descriptors; + } + + protected JavaClass[] discoverClasses( final MavenProject project ) + throws ExtractionException + { + JavaDocBuilder builder = new JavaDocBuilder(); + + for ( Iterator i = project.getCompileSourceRoots().iterator(); i.hasNext(); ) + { + builder.addSourceTree( new File( (String) i.next() ) ); + } + + return builder.getClasses(); + } + + protected void validate( MojoDescriptor mojoDescriptor ) + throws InvalidParameterException + { + List parameters = mojoDescriptor.getParameters(); + + if ( parameters != null ) + { + for ( int j = 0; j < parameters.size(); j++ ) + { + validateParameter( (Parameter) parameters.get( j ), j ); + } + } + } +} diff --git a/maven-plugin-tools-java/src/main/resources/META-INF/plexus/components.xml b/maven-plugin-tools-java/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..6dbb2f1 --- /dev/null +++ b/maven-plugin-tools-java/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,36 @@ + + + + + + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + java + org.apache.maven.tools.plugin.extractor.java.JavaMojoDescriptorExtractor + + + + \ No newline at end of file diff --git a/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java b/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java new file mode 100644 index 0000000..731dcfe --- /dev/null +++ b/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java @@ -0,0 +1,121 @@ +package org.apache.maven.tools.plugin.extractor.java; + +/* + * 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 junit.framework.TestCase; +import org.apache.maven.model.Model; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; + +import java.io.File; +import java.net.URL; +import java.util.List; + +/** + * @author jdcasey + */ +public class JavaMojoDescriptorExtractorTest + extends TestCase +{ + + public void testShouldFindTwoMojoDescriptorsInTestSourceDirectory() + throws Exception + { + JavaMojoDescriptorExtractor extractor = new JavaMojoDescriptorExtractor(); + + File sourceFile = fileOf( "dir-flag.txt" ); + System.out.println( "found source file: " + sourceFile ); + + File dir = sourceFile.getParentFile(); + + Model model = new Model(); + model.setArtifactId( "maven-unitTesting-plugin" ); + + MavenProject project = new MavenProject( model ); + + project.setFile( new File( dir, "pom.xml" ) ); + project.addCompileSourceRoot( new File( dir, "source" ).getPath() ); + + PluginDescriptor pluginDescriptor = new PluginDescriptor(); + pluginDescriptor.setGoalPrefix( "test" ); + List results = extractor.execute( project, pluginDescriptor ); + assertEquals( "Extracted mojos", 2, results.size() ); + + for ( int i = 0; i < 2; i++ ) + { + MojoDescriptor mojoDescriptor = (MojoDescriptor) results.get( i ); + assertEquals( 1, mojoDescriptor.getParameters().size() ); + Parameter parameter = (Parameter) mojoDescriptor.getParameters().get( 0 ); + assertEquals( "project", parameter.getName() ); + assertEquals( "java.lang.String[]", parameter.getType() ); + } + } + + public void testShouldPropagateImplementationParameter() + throws Exception + { + JavaMojoDescriptorExtractor extractor = new JavaMojoDescriptorExtractor(); + + File sourceFile = fileOf( "dir-flag.txt" ); + System.out.println( "found source file: " + sourceFile ); + + File dir = sourceFile.getParentFile(); + + Model model = new Model(); + model.setArtifactId( "maven-unitTesting-plugin" ); + + MavenProject project = new MavenProject( model ); + + project.setFile( new File( dir, "pom.xml" ) ); + project.addCompileSourceRoot( new File( dir, "source2" ).getPath() ); + + PluginDescriptor pluginDescriptor = new PluginDescriptor(); + pluginDescriptor.setGoalPrefix( "test" ); + List results = extractor.execute( project, pluginDescriptor ); + assertEquals( 1, results.size() ); + + MojoDescriptor mojoDescriptor = (MojoDescriptor) results.get( 0 ); + + List parameters = mojoDescriptor.getParameters(); + + assertEquals( 1, parameters.size() ); + + Parameter parameter = (Parameter) parameters.get( 0 ); + + assertEquals( "Implementation parameter", "source2.sub.MyBla", parameter.getImplementation() ); + } + + private File fileOf( String classpathResource ) + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + URL resource = cl.getResource( classpathResource ); + + File result = null; + if ( resource != null ) + { + result = new File( resource.getPath() ); + } + + return result; + } + +} diff --git a/maven-plugin-tools-java/src/test/resources/dir-flag.txt b/maven-plugin-tools-java/src/test/resources/dir-flag.txt new file mode 100644 index 0000000..b47a682 --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/dir-flag.txt @@ -0,0 +1,10 @@ +This file is used by ClassLoader.getResource() to find the current path to the +test resources. Uses this code: + +URL resource = classloader.getResource("dir-flag.txt"); +File resourceFile = new File(resource.getPath()); +File testResourcesDir= resourceFile.getParentFile(); + +This way, the unit test can depend on a FileReader or somesuch, and still work +fine regardless of ${user.dir} as long as the classpath is right. Useful for +Eclipse... \ No newline at end of file diff --git a/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestOne.java b/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestOne.java new file mode 100644 index 0000000..52155ed --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestOne.java @@ -0,0 +1,48 @@ +package source; + +/* + * 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 org.apache.maven.plugin.AbstractMojo; + +/** + * Create an IDEA project file from a Maven project. + * + * @goal ideaOne + * @requiresDependencyResolution + */ +public class JavaExtractorTestOne + extends AbstractMojo +{ + /** + * Maven project used to generate IDEA project files. + * + * @parameter + * @required + */ + protected String[] project; + + public JavaExtractorTestOne() + { + } + + public void execute() + { + } +} diff --git a/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestTwo.java b/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestTwo.java new file mode 100644 index 0000000..665dc6c --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/source/JavaExtractorTestTwo.java @@ -0,0 +1,53 @@ +package source; + +/* + * 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 org.apache.maven.plugin.AbstractMojo; + +/** + * Create an IDEA project file from a Maven project. + * + * @goal ideaTwo + * @requiresDependencyResolution compile + */ +public class JavaExtractorTestTwo + extends AbstractMojo +{ + + /** + * Maven project used to generate IDEA project files. + * + * @parameter + * @required + */ + private String[] project; + + public JavaExtractorTestTwo() + { + } + + public void execute() + { + if ( getLog() != null ) + { + getLog().info( "projects: " + project ); + } + } +} diff --git a/maven-plugin-tools-java/src/test/resources/source2/Bla.java b/maven-plugin-tools-java/src/test/resources/source2/Bla.java new file mode 100644 index 0000000..83a14c0 --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/source2/Bla.java @@ -0,0 +1,24 @@ +package source2; + +/* + * 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. + */ + +public interface Bla +{ +} diff --git a/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java b/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java new file mode 100644 index 0000000..e0e6d89 --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java @@ -0,0 +1,50 @@ +package source2; + +/* + * 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 org.apache.maven.plugin.AbstractMojo; + +/** + * Tests the implementation argument of the parameter annotation. + * + * @goal ideaThree + * @requiresDependencyResolution compile + */ +public class JavaExtractorTestThree + extends AbstractMojo +{ + /** + * @parameter implementation=source2.sub.MyBla + * @required + */ + private Bla bla; + + public JavaExtractorTestThree() + { + } + + public void execute() + { + if ( getLog() != null ) + { + getLog().info( "bla: " + bla ); + } + } +} diff --git a/maven-plugin-tools-java/src/test/resources/source2/sub/MyBla.java b/maven-plugin-tools-java/src/test/resources/source2/sub/MyBla.java new file mode 100644 index 0000000..347f53b --- /dev/null +++ b/maven-plugin-tools-java/src/test/resources/source2/sub/MyBla.java @@ -0,0 +1,27 @@ +package source2.sub; + +/* + * 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 source2.Bla; + +public class MyBla + implements Bla +{ +} diff --git a/maven-plugin-tools-model/pom.xml b/maven-plugin-tools-model/pom.xml new file mode 100755 index 0000000..fce22bd --- /dev/null +++ b/maven-plugin-tools-model/pom.xml @@ -0,0 +1,67 @@ + + + + + + + maven-plugin-tools + org.apache.maven + 2.4-SNAPSHOT + + 4.0.0 + maven-plugin-tools-model + Maven Plugin Metadata Model + + + + org.codehaus.modello + modello-maven-plugin + 1.0-alpha-14 + + src/main/mdo/plugin-metadata.mdo + 1.0.0 + + + + + xpp3-reader + xpp3-writer + java + + + + + + + + + org.apache.maven + maven-plugin-descriptor + + + org.codehaus.plexus + plexus-utils + + + org.codehaus.plexus + plexus-container-default + + + diff --git a/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParseException.java b/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParseException.java new file mode 100644 index 0000000..e38dbbd --- /dev/null +++ b/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParseException.java @@ -0,0 +1,60 @@ +package org.apache.maven.plugin.tools.model; + +/* + * 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.File; + +public class PluginMetadataParseException + extends Exception +{ + + static final long serialVersionUID = 1; + + private final File metadataFile; + + private final String originalMessage; + + public PluginMetadataParseException( File metadataFile, String message, Throwable cause ) + { + super( "Error parsing file: " + metadataFile + ". Reason: " + message, cause ); + + this.metadataFile = metadataFile; + this.originalMessage = message; + } + + public PluginMetadataParseException( File metadataFile, String message ) + { + super( "Error parsing file: " + metadataFile + ". Reason: " + message ); + + this.metadataFile = metadataFile; + this.originalMessage = message; + } + + public File getMetadataFile() + { + return metadataFile; + } + + public String getOriginalMessage() + { + return originalMessage; + } + +} diff --git a/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParser.java b/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParser.java new file mode 100644 index 0000000..6b72ecd --- /dev/null +++ b/maven-plugin-tools-model/src/main/java/org/apache/maven/plugin/tools/model/PluginMetadataParser.java @@ -0,0 +1,183 @@ +package org.apache.maven.plugin.tools.model; + +/* + * 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 org.apache.maven.plugin.descriptor.DuplicateParameterException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.tools.model.io.xpp3.PluginMetadataXpp3Reader; +import org.codehaus.plexus.component.repository.ComponentRequirement; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class PluginMetadataParser +{ + public static final String IMPL_BASE_PLACEHOLDER = ""; + + public Set parseMojoDescriptors( File metadataFile ) + throws PluginMetadataParseException + { + Set descriptors = new HashSet(); + + Reader reader = null; + + try + { + reader = new FileReader( metadataFile ); + + PluginMetadataXpp3Reader metadataReader = new PluginMetadataXpp3Reader(); + + PluginMetadata pluginMetadata = metadataReader.read( reader ); + + List mojos = pluginMetadata.getMojos(); + + if ( mojos != null && !mojos.isEmpty() ) + { + for ( Iterator it = mojos.iterator(); it.hasNext(); ) + { + Mojo mojo = (Mojo) it.next(); + + MojoDescriptor descriptor = asDescriptor( metadataFile, mojo ); + + descriptors.add( descriptor ); + } + } + } + catch ( IOException e ) + { + throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e ); + } + catch ( XmlPullParserException e ) + { + throw new PluginMetadataParseException( metadataFile, "Cannot parse plugin metadata from file.", e ); + } + finally + { + IOUtil.close( reader ); + } + + return descriptors; + } + + private MojoDescriptor asDescriptor( File metadataFile, Mojo mojo ) + throws PluginMetadataParseException + { + MojoDescriptor descriptor = new MojoDescriptor(); + + descriptor.setImplementation( IMPL_BASE_PLACEHOLDER + ":" + mojo.getCall() ); + + descriptor.setGoal( mojo.getGoal() ); + descriptor.setPhase( mojo.getPhase() ); + descriptor.setDependencyResolutionRequired( mojo.getRequiresDependencyResolution() ); + descriptor.setAggregator( mojo.isAggregator() ); + descriptor.setInheritedByDefault( mojo.isInheritByDefault() ); + descriptor.setDirectInvocationOnly( mojo.isRequiresDirectInvocation() ); + descriptor.setOnlineRequired( mojo.isRequiresOnline() ); + descriptor.setProjectRequired( mojo.isRequiresProject() ); + descriptor.setRequiresReports( mojo.isRequiresReports() ); + descriptor.setDescription( mojo.getDescription() ); + descriptor.setDeprecated( mojo.getDeprecation() ); + + LifecycleExecution le = mojo.getExecution(); + if ( le != null ) + { + descriptor.setExecuteLifecycle( le.getLifecycle() ); + descriptor.setExecutePhase( le.getPhase() ); + } + + List parameters = mojo.getParameters(); + + if ( parameters != null && !parameters.isEmpty() ) + { + for ( Iterator it = parameters.iterator(); it.hasNext(); ) + { + org.apache.maven.plugin.tools.model.Parameter param = + (org.apache.maven.plugin.tools.model.Parameter) it.next(); + + Parameter dParam = new Parameter(); + dParam.setAlias( param.getAlias() ); + dParam.setDeprecated( param.getDeprecation() ); + dParam.setDescription( param.getDescription() ); + dParam.setEditable( !param.isReadonly() ); + dParam.setExpression( param.getExpression() ); + dParam.setDefaultValue( param.getDefaultValue() ); + + String property = param.getProperty(); + if ( StringUtils.isNotEmpty( property ) ) + { + dParam.setName( property ); + } + else + { + dParam.setName( param.getName() ); + } + + if ( StringUtils.isEmpty( dParam.getName() ) ) + { + throw new PluginMetadataParseException( metadataFile, "Mojo: \'" + mojo.getGoal() + + "\' has a parameter without either property or name attributes. Please specify one." ); + } + + dParam.setRequired( param.isRequired() ); + dParam.setType( param.getType() ); + + try + { + descriptor.addParameter( dParam ); + } + catch ( DuplicateParameterException e ) + { + throw new PluginMetadataParseException( metadataFile, + "Duplicate parameters detected for mojo: " + mojo.getGoal(), + e ); + } + } + } + + List components = mojo.getComponents(); + + if ( components != null && !components.isEmpty() ) + { + for ( Iterator it = components.iterator(); it.hasNext(); ) + { + Component component = (Component) it.next(); + + ComponentRequirement cr = new ComponentRequirement(); + cr.setRole( component.getRole() ); + cr.setRoleHint( component.getHint() ); + + descriptor.addRequirement( cr ); + } + } + + return descriptor; + } + +} diff --git a/maven-plugin-tools-model/src/main/mdo/plugin-metadata.mdo b/maven-plugin-tools-model/src/main/mdo/plugin-metadata.mdo new file mode 100644 index 0000000..8608fc9 --- /dev/null +++ b/maven-plugin-tools-model/src/main/mdo/plugin-metadata.mdo @@ -0,0 +1,342 @@ + + + + + plugin-metadata + PluginMetadata + + + + package + org.apache.maven.plugin.tools.model + + + + + PluginMetadata + 1.0.0 + Root element of a script-based mojo's plugin metadata bindings. + + + mojos + 1.0.0 + true + The list of mojos contained in the accompanying script. + + Mojo + * + + + + + + Mojo + 1.0.0 + Mojo descriptor definition. + + + 1.0.0 + goal + String + true + The name of the goal used to invoke this mojo. + + + 1.0.0 + phase + String + The phase to which this mojo should be bound by default. + + + 1.0.0 + aggregator + boolean + Whether this mojo operates as an aggregator when the reactor is run. That is, only runs once. + + + + 1.0.0 + requiresDependencyResolution + String + The scope of dependencies that this mojo requires to have resolved. + + + 1.0.0 + requiresProject + boolean + Whether this mojo requires a project instance in order to execute. + + + 1.0.0 + requiresReports + boolean + Whether this mojo requires a reports section in the POM. + + + 1.0.0 + requiresOnline + boolean + Whether this mojo requires online mode to operate normally. + + + 1.0.0 + inheritByDefault + boolean + Whether this mojo's configuration should propagate down the POM inheritance chain by default. + + + + 1.0.0 + requiresDirectInvocation + boolean + If true, this mojo can only be directly invoked (eg. specified directly on the command line). + + + + 1.0.0 + execution + Information about a sub-execution of the Maven lifecycle which should be processed. + + LifecycleExecution + + + + 1.0.0 + components + List of plexus components required by this mojo. + + Component + * + + + + 1.0.0 + parameters + List of parameters used by this mojo. + + Parameter + * + + + + description + 1.0.0 + The description for this parameter. + String + + + deprecation + 1.0.0 + A deprecation message for this mojo parameter. + String + + + 1.0.0 + call + String + The target/method within the script to call when this mojo executes. + + + + + LifecycleExecution + 1.0.0 + + + + lifecycle + 1.0.0 + String + The name of the overlay to apply to the sub-lifecycle before executing it. If specified, this + lifecycle overlay definition will be bundled with the plugin. + + + + phase + 1.0.0 + The phase in the sub-lifecycle. + String + + + goal + 1.0.0 + A goal, not attached to a lifecycle phase, which should be executed ahead of this mojo. + + String + + + + + Component + 1.0.0 + + + + role + 1.0.0 + The component role to lookup. + true + String + + + hint + 1.0.0 + String + The role-hint to lookup. + + + + + Parameter + 1.0.0 + + + + name + 1.0.0 + The parameter name + true + String + + + alias + 1.0.0 + String + An alternate name for the parameter. + + + property + 1.0.0 + String + The JavaBeans property name to use to configure the mojo with this parameter. + + + required + 1.0.0 + boolean + Whether this parameter is required. + + + readonly + 1.0.0 + boolean + + + + expression + 1.0.0 + String + + + + defaultValue + 1.0.0 + String + + + + type + 1.0.0 + String + true + + + + description + 1.0.0 + The description for this parameter. + String + + + deprecation + 1.0.0 + A deprecation message for this mojo parameter. + String + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1cde9ac --- /dev/null +++ b/pom.xml @@ -0,0 +1,150 @@ + + + + 4.0.0 + + maven-parent + org.apache.maven + 7 + ../pom/maven/pom.xml + + org.apache.maven + maven-plugin-tools + pom + Maven Plugin Tools + 2.4-SNAPSHOT + The Maven Plugin Tools contain the necessary tools to be able to produce Maven 2 Plugins in a variety of languages. + http://maven.apache.org/plugin-tools/ + + jira + http://jira.codehaus.org/browse/MPLUGIN + + 2004 + + scm:svn:http://svn.apache.org/repos/asf/maven/plugin-tools/trunk/ + scm:svn:https://svn.apache.org/repos/asf/maven/plugin-tools/trunk/ + http://svn.apache.org/viewcvs.cgi/maven/plugin-tools/trunk + + + + Maven User List + users-subscribe@maven.apache.org + users-unsubscribe@maven.apache.org + users@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-users + + http://www.mail-archive.com/users@maven.apache.org/ + http://www.nabble.com/Maven---Users-f178.html + + + + Maven Developer List + dev-subscribe@maven.apache.org + dev-unsubscribe@maven.apache.org + dev@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-dev + + + Maven Commits List + commits-subscribe@maven.apache.org + commits-unsubscribe@maven.apache.org + commits@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-dev + + + + Maven Announcements List + announce@maven.apache.org + announce-subscribe@maven.apache.org + announce-unsubscribe@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-announce/ + + + Maven Issues List + issues@maven.apache.org + issues-subscribe@maven.apache.org + issues-unsubscribe@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-issues/ + + + Maven Notifications List + notifications@maven.apache.org + notifications-subscribe@maven.apache.org + notifications-unsubscribe@maven.apache.org + http://mail-archives.apache.org/mod_mbox/maven-notifications/ + + + + + + + maven-release-plugin + + https://svn.apache.org/repos/asf/maven/plugin-tools/tags + + + + + + + maven-plugin-plugin + maven-plugin-tools-api + maven-plugin-tools-java + maven-plugin-tools-beanshell + maven-plugin-tools-model + maven-plugin-tools-ant + + + + + org.apache.maven + maven-plugin-tools-api + ${project.version} + + + org.apache.maven + maven-plugin-tools-model + ${project.version} + + + org.apache.maven + maven-plugin-tools-java + ${project.version} + + + org.apache.maven + maven-plugin-descriptor + 2.0.5 + + + org.codehaus.plexus + plexus-utils + 1.1 + + + org.codehaus.plexus + plexus-container-default + 1.0-alpha-9 + + + +