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