View Javadoc

1   /*
2    * Copyright (c) 2007, Ounce Labs, Inc.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *     * Redistributions of source code must retain the above copyright
8    *       notice, this list of conditions and the following disclaimer.
9    *     * Redistributions in binary form must reproduce the above copyright
10   *       notice, this list of conditions and the following disclaimer in the
11   *       documentation and/or other materials provided with the distribution.
12   *     * Neither the name of the <organization> nor the
13   *       names of its contributors may be used to endorse or promote products
14   *       derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS PROVIDED BY OUNCE LABS, INC. ``AS IS'' AND ANY
17   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL OUNCE LABS, INC. BE LIABLE FOR ANY
20   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package org.codehaus.mojo.ounce;
28  
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  import org.apache.maven.artifact.Artifact;
34  import org.apache.maven.artifact.DependencyResolutionRequiredException;
35  import org.apache.maven.artifact.repository.ArtifactRepository;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugin.MojoFailureException;
38  import org.codehaus.mojo.ounce.core.OunceCore;
39  import org.codehaus.mojo.ounce.core.OunceCoreException;
40  import org.codehaus.mojo.ounce.utils.Utils;
41  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
42  
43  /**
44   * This mojo generates an Ounce project file. It does not fork the build like the "project" mojo and is instead intended
45   * to be bound in a pom for automatic execution. If you would rather have the project generated on demand via the
46   * command line, use the project goal instead.
47   * 
48   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
49   * @requiresDependencyResolution test
50   * @goal project-only
51   * @phase package
52   */
53  public class ProjectOnlyMojo
54      extends AbstractOunceMojo
55  {
56  
57      public static final String PATH_SEPARATOR = ";";
58  
59      public static final String M2_REPO = "M2_REPO";
60  
61      /**
62       * The scope of the classpath used to analyze this project. <br/> Valid choices are: compile, test, runtime, or
63       * system. If includeTestSources is true, then the classpathScope reverts to test. Otherwise, the default is
64       * compile.
65       * 
66       * @parameter default-value="compile" expression="${ounce.classpathScope}";
67       */
68      private String classpathScope;
69  
70      /**
71       * JDK configuration known to Ounce Core.
72       * 
73       * @parameter expression="${ounce.jdkName}"
74       */
75      private String jdkName;
76      
77      /**
78       * Options to pass to the javac compiler.
79       * 
80       * @parameter expression="${ounce.javaCompilerOptions}"
81       */
82      private String javaCompilerOptions;
83  
84      /**
85       * If TestSources should be included in the compilable sources. If set, adds project.getTestSourceRoot() to the path
86       * and defaults the classpathScope to test.
87       * 
88       * @parameter expression="${ounce.includeTestSources}" default-value="false"
89       */
90      protected boolean includeTestSources;
91  
92      /**
93       * Whether the plugin should use the Ounce Automation Server to create any necessary variables (such as M2_REPO).
94       * Requires that the Ounce Automation Server be installed.
95       * 
96       * @parameter expression="${ounce.createVariables}" default-value="true"
97       */
98      protected boolean createVariables;
99  
100     /**
101      * The location of the Ounce client installation directory. Required if ounceauto is not on the path.
102      * 
103      * @parameter expression="${ounce.installDir}"
104      */
105     String installDir;
106 
107     /**
108      * The location of the web context root, if needed.
109      * 
110      * @parameter expression="${project.build.directory}/${project.build.finalName}"
111      */
112     private String webappDirectory;
113     
114     /**
115      * Whether to analyze the framework for a Struts application
116      * 
117      * @parameter expression="${ounce.analyzeStrutsFramework}" default-value="false"
118      */
119     private boolean analyzeStrutsFramework;
120     
121     /**
122      * Whether to import Struts validation routines
123      * 
124      * @parameter expression="${ounce.importStrutsValidation}" default-value="false"
125      */
126     private boolean importStrutsValidation;
127 
128     /**
129      * Location of the local repository.
130      * 
131      * @parameter expression="${localRepository}"
132      * @readonly
133      * @required
134      */
135     protected ArtifactRepository local;
136 
137     /*
138      * (non-Javadoc)
139      * 
140      * @see org.apache.maven.plugin.Mojo#execute()
141      */
142     public void execute()
143         throws MojoExecutionException, MojoFailureException
144     {
145         if ( project.getPackaging() != "pom" || !skipPoms )
146         {
147             try
148             {
149             	
150                 String classPath = buildClasspath();
151                 List sourceRoots = getSourceRoots();
152 
153                 String projectRoot = getProjectRoot();
154 
155                 // make all paths relative
156 
157                 webappDirectory = Utils.convertToRelativePath( webappDirectory, projectRoot, "" );
158 
159                 // remove project root from the
160                 // classpath
161                 classPath = Utils.convertToRelativePath( classPath, projectRoot, "" );
162 
163                 // remove repo from the classpath
164                 classPath = Utils.convertToRelativePath( classPath, local.getBasedir(), ProjectOnlyMojo.M2_REPO );
165 
166                 classPath = Utils.convertToVariablePath( classPath, pathVariableMap );
167 
168                 sourceRoots = Utils.convertToRelativePaths( sourceRoots, projectRoot, "" );
169 
170                 projectRoot = ".";
171 
172                 OunceCore core = getCore();
173 
174                 core.createProject( getProjectRoot(), name, projectRoot, sourceRoots, webappDirectory, classPath,
175                                     jdkName, javaCompilerOptions, project.getPackaging(), this.options, 
176                                     analyzeStrutsFramework, importStrutsValidation, this.getLog() );
177 
178                 if ( createVariables )
179                 {
180                     if ( pathVariableMap == null )
181                     {
182                         pathVariableMap = new HashMap();
183                     }
184                     if ( pathVariableMap.get( ProjectOnlyMojo.M2_REPO ) == null )
185                     {
186                         pathVariableMap.put( ProjectOnlyMojo.M2_REPO, local.getBasedir() );
187                     }
188                     core.createPathVariables( pathVariableMap, installDir, this.getLog() );
189                 }
190             }
191             catch ( ComponentLookupException e )
192             {
193                 throw new MojoExecutionException( "Unable to lookup the core interface for hint: " + coreHint, e );
194             }
195             catch ( OunceCoreException e )
196             {
197                 throw new MojoExecutionException( "Nested Ouncecore exception: " + e.getLocalizedMessage(), e );
198             }
199         }
200         else
201         {
202             getLog().info( "Skipping Pom project." );
203         }
204     }
205 
206     /**
207      * This method gets the source roots from the project. Overrides the ProjectOnly:getSourceRoots() method because we
208      * don't have an executed project because the build wasn't forked.
209      * 
210      * @return List of source roots.
211      */
212     protected List getSourceRoots()
213     {
214         List sourceRoots = project.getCompileSourceRoots();
215 
216         if ( this.includeTestSources )
217         {
218             sourceRoots.addAll( project.getTestCompileSourceRoots() );
219         }
220         return sourceRoots;
221     }
222 
223     /**
224      * Gets the classpath elements and returns a properly formatted classpath.
225      * 
226      * @return
227      * @throws MojoExecutionException
228      */
229     protected String buildClasspath()
230         throws MojoExecutionException
231     {
232 
233         List classpathElements = getClasspathElements();
234 
235         StringBuffer sb = new StringBuffer();
236         Iterator i = classpathElements.iterator();
237 
238         if ( i.hasNext() )
239         {
240             // first one, no separator needed
241             sb.append( Utils.convertToUnixStylePath( (String) i.next() ) );
242 
243             // separate the rest of them with pathSeparator
244             while ( i.hasNext() )
245             {
246                 sb.append( ProjectOnlyMojo.PATH_SEPARATOR );
247                 sb.append( Utils.convertToUnixStylePath( (String) i.next() ) );
248             }
249         }
250 
251         return sb.toString();
252 
253     }
254 
255     /**
256      * Gets the properly scoped classpathElements from the Maven Project
257      * 
258      * @return List of classpath strings.
259      * @throws MojoExecutionException
260      */
261     protected List getClasspathElements()
262         throws MojoExecutionException
263     {
264         List classpathElements = null;
265 
266         try
267         {
268             // checking if test sources are included. If so,
269             // then we want the classpath to be test
270             // (includes everything)
271             if ( Artifact.SCOPE_TEST.equalsIgnoreCase( this.classpathScope ) || this.includeTestSources )
272             {
273                 classpathElements = project.getTestClasspathElements();
274             }
275             else if ( Artifact.SCOPE_COMPILE.equalsIgnoreCase( this.classpathScope ) )
276             {
277                 classpathElements = project.getCompileClasspathElements();
278             }
279             else if ( Artifact.SCOPE_RUNTIME.equalsIgnoreCase( this.classpathScope ) )
280             {
281                 classpathElements = project.getRuntimeClasspathElements();
282             }
283             else if ( Artifact.SCOPE_SYSTEM.equalsIgnoreCase( this.classpathScope ) )
284             {
285                 classpathElements = project.getSystemClasspathElements();
286             }
287             else
288             {
289                 throw new MojoExecutionException( "Invalid classpathScope: " + this.classpathScope +
290                     " valid values are: compile, test, runtime, system." );
291             }
292         }
293         catch ( DependencyResolutionRequiredException e )
294         {
295             throw new MojoExecutionException( e.getLocalizedMessage(), e );
296         }
297 
298         return classpathElements;
299     }
300 
301     /**
302      * @return the classpathScope
303      */
304     protected String getClasspathScope()
305     {
306         return this.classpathScope;
307     }
308 
309     /**
310      * @param theClasspathScope the classpathScope to set
311      */
312     protected void setClasspathScope( String theClasspathScope )
313     {
314         this.classpathScope = theClasspathScope;
315     }
316 
317     /**
318      * @return the jdkName
319      */
320     protected String getJdkName()
321     {
322         return this.jdkName;
323     }
324 
325     /**
326      * @param theJdkName the jdkName to set
327      */
328     protected void setJdkName( String theJdkName )
329     {
330         this.jdkName = theJdkName;
331     }
332     
333     /**
334      * @return the includeTestSources
335      */
336     protected boolean isIncludeTestSources()
337     {
338         return this.includeTestSources;
339     }
340 
341     /**
342      * @param theIncludeTestSources the includeTestSources to set
343      */
344     protected void setIncludeTestSources( boolean theIncludeTestSources )
345     {
346         this.includeTestSources = theIncludeTestSources;
347     }
348 
349     /**
350      * @return the java compiler options
351      */
352     protected String getJavaCompilerOptions()
353     {
354         return javaCompilerOptions;
355     }
356 
357     /**
358      * @param theJavaCompilerOptions the java compiler options
359      */
360     protected void setJavaCompilerOptions( String theJavaCompilerOptions )
361     {
362         this.javaCompilerOptions = theJavaCompilerOptions;
363     }
364 
365     /**
366      * @return the webappDirectory
367      */
368     protected String getWebappDirectory()
369     {
370         return this.webappDirectory;
371     }
372 
373     /**
374      * @param theWebappDirectory the webappDirectory to set
375      */
376     protected void setWebappDirectory( String theWebappDirectory )
377     {
378         this.webappDirectory = theWebappDirectory;
379     }
380     
381     /**
382      * @return whether to analyze Struts framework
383      */
384     protected boolean getAnalyzeStrutsFramework() {
385     	return this.analyzeStrutsFramework;
386     }
387     
388     /**
389      * @param toAnalyzeStrutsFramework whether to analyze Struts Framework
390      */
391     protected void setAnalyzeStrutsFramework(boolean analyzeStrutsFramework) {
392     	this.analyzeStrutsFramework = analyzeStrutsFramework;
393     }
394     
395     /**
396      * @return whether to import Struts validation
397      */
398     protected boolean getImportStrutsValidation() {
399     	return this.importStrutsValidation;
400     }
401     
402     /**
403      * @param importStrutsValidation whether to import Struts validation 
404      */ 
405     protected void setImportStrutsValidation(boolean importStrutsValidation) {
406     	this.importStrutsValidation = importStrutsValidation;
407     }
408     
409     /**
410      * @return the local
411      */
412     public ArtifactRepository getLocal()
413     {
414         return this.local;
415     }
416 
417     /**
418      * @param theLocal the local to set
419      */
420     public void setLocal( ArtifactRepository theLocal )
421     {
422         this.local = theLocal;
423     }
424 
425 }