001    package org.codehaus.mojo.exec;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *     http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.File;
023    import java.util.List;
024    
025    import org.apache.maven.plugin.AbstractMojo;
026    import org.apache.maven.plugin.MojoExecutionException;
027    import org.apache.maven.project.MavenProject;
028    import org.codehaus.plexus.util.cli.CommandLineUtils;
029    
030    /**
031     * This class is used for unifying functionality between the 2 mojo exec plugins ('java' and 'exec'). It handles parsing
032     * the arguments and adding source/test folders.
033     * 
034     * @author Philippe Jacot (PJA)
035     * @author Jerome Lacoste
036     */
037    public abstract class AbstractExecMojo
038        extends AbstractMojo
039    {
040        /**
041         * The enclosing project.
042         * 
043         * @parameter expression="${project}"
044         * @required
045         * @readonly
046         */
047        protected MavenProject project;
048    
049        /**
050         * This folder is added to the list of those folders containing source to be compiled. Use this if your plugin
051         * generates source code.
052         * 
053         * @parameter expression="${sourceRoot}"
054         */
055        private File sourceRoot;
056    
057        /**
058         * This folder is added to the list of those folders containing source to be compiled for testing. Use this if your
059         * plugin generates test source code.
060         * 
061         * @parameter expression="${testSourceRoot}"
062         */
063        private File testSourceRoot;
064    
065        /**
066         * Arguments for the executed program
067         * 
068         * @parameter expression="${exec.args}"
069         */
070        private String commandlineArgs;
071    
072        /**
073         * Defines the scope of the classpath passed to the plugin. Set to compile,test,runtime or system depending on your
074         * needs. Since 1.1.2, the default value is 'runtime' instead of 'compile'.
075         * 
076         * @parameter expression="${exec.classpathScope}" default-value="runtime"
077         */
078        protected String classpathScope;
079    
080        /**
081         * Skip the execution.
082         * 
083         * @parameter expression="${skip}" default-value="false"
084         * @since 1.0.1
085         */
086        private boolean skip;
087    
088        /**
089         * Collects the project artifacts in the specified List and the project specific classpath (build output and build
090         * test output) Files in the specified List, depending on the plugin classpathScope value.
091         * 
092         * @param artifacts the list where to collect the scope specific artifacts
093         * @param theClasspathFiles the list where to collect the scope specific output directories
094         */
095        protected void collectProjectArtifactsAndClasspath( List artifacts, List theClasspathFiles )
096        {
097    
098            if ( "compile".equals( classpathScope ) )
099            {
100                artifacts.addAll( project.getCompileArtifacts() );
101                theClasspathFiles.add( new File( project.getBuild().getOutputDirectory() ) );
102            }
103            else if ( "test".equals( classpathScope ) )
104            {
105                artifacts.addAll( project.getTestArtifacts() );
106                theClasspathFiles.add( new File( project.getBuild().getTestOutputDirectory() ) );
107                theClasspathFiles.add( new File( project.getBuild().getOutputDirectory() ) );
108            }
109            else if ( "runtime".equals( classpathScope ) )
110            {
111                artifacts.addAll( project.getRuntimeArtifacts() );
112                theClasspathFiles.add( new File( project.getBuild().getOutputDirectory() ) );
113            }
114            else if ( "system".equals( classpathScope ) )
115            {
116                artifacts.addAll( project.getSystemArtifacts() );
117            }
118            else
119            {
120                throw new IllegalStateException( "Invalid classpath scope: " + classpathScope );
121            }
122    
123            getLog().debug( "Collected project artifacts " + artifacts );
124            getLog().debug( "Collected project classpath " + theClasspathFiles );
125        }
126    
127        /**
128         * Parses the argument string given by the user. Strings are recognized as everything between STRING_WRAPPER.
129         * PARAMETER_DELIMITER is ignored inside a string. STRING_WRAPPER and PARAMETER_DELIMITER can be escaped using
130         * ESCAPE_CHAR.
131         * 
132         * @return Array of String representing the arguments
133         * @throws MojoExecutionException for wrong formatted arguments
134         */
135        protected String[] parseCommandlineArgs()
136            throws MojoExecutionException
137        {
138            if ( commandlineArgs == null )
139            {
140                return null;
141            }
142            else
143            {
144                try
145                {
146                    return CommandLineUtils.translateCommandline( commandlineArgs );
147                }
148                catch ( Exception e )
149                {
150                    throw new MojoExecutionException( e.getMessage() );
151                }
152            }
153        }
154    
155        /**
156         * @return true of the mojo has command line arguments
157         */
158        protected boolean hasCommandlineArgs()
159        {
160            return ( commandlineArgs != null );
161        }
162    
163        /**
164         * Register compile and compile tests source roots if necessary
165         */
166        protected void registerSourceRoots()
167        {
168            if ( sourceRoot != null )
169            {
170                getLog().info( "Registering compile source root " + sourceRoot );
171                project.addCompileSourceRoot( sourceRoot.toString() );
172            }
173    
174            if ( testSourceRoot != null )
175            {
176                getLog().info( "Registering compile test source root " + testSourceRoot );
177                project.addTestCompileSourceRoot( testSourceRoot.toString() );
178            }
179        }
180    
181        /**
182         * Check if the execution should be skipped
183         * 
184         * @return true to skip
185         */
186        protected boolean isSkip()
187        {
188            return skip;
189        }
190    }