View Javadoc
1   /*
2    * #%L
3    * Mojo's Maven plugin for Cobertura
4    * %%
5    * Copyright (C) 2005 - 2013 Codehaus
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package org.codehaus.mojo.cobertura.tasks;
21  
22  import org.apache.commons.lang.SystemUtils;
23  import org.apache.maven.artifact.Artifact;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugin.logging.Log;
27  import org.apache.maven.plugin.logging.SystemStreamLog;
28  import org.codehaus.plexus.util.FileUtils;
29  import org.codehaus.plexus.util.cli.CommandLineException;
30  import org.codehaus.plexus.util.cli.CommandLineUtils;
31  import org.codehaus.plexus.util.cli.Commandline;
32  
33  import java.io.File;
34  import java.io.IOException;
35  import java.net.MalformedURLException;
36  import java.net.URL;
37  import java.util.Collections;
38  import java.util.Iterator;
39  import java.util.List;
40  
41  /**
42   * Base Abstract Class for all of the Tasks.
43   *
44   * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
45   */
46  public abstract class AbstractTask
47  {
48      /**
49       * The shared command line args.
50       */
51      protected CommandLineArguments cmdLineArgs;
52  
53      private Log log;
54  
55      private String maxmem;
56  
57      private List<Artifact> pluginClasspathList;
58  
59      private String taskClass;
60  
61      private boolean quiet;
62  
63      /**
64       * Initialize AbstractTask.
65       *
66       * @param taskClassname the classname for the task.
67       */
68      protected AbstractTask( String taskClassname )
69      {
70          taskClass = taskClassname;
71          cmdLineArgs = new CommandLineArguments();
72          maxmem = "64m";
73      }
74  
75      /**
76       * Setter for <code>quiet</code>.
77       *
78       * @param quiet The quiet to set.
79       */
80      public void setQuiet( boolean quiet )
81      {
82          this.quiet = quiet;
83      }
84  
85      /**
86       * Getter for <code>quiet</code>.
87       *
88       * @return Returns the quiet.
89       */
90      public boolean isQuiet()
91      {
92          return quiet;
93      }
94  
95      /**
96       * Using the <code>${project.compileClasspathElements}</code> and the <code>${plugin.artifacts}</code>, create
97       * a classpath string that is suitable to be used from a forked cobertura process.
98       *
99       * @return the classpath string
100      * @throws MojoExecutionException if the pluginArtifacts cannot be properly resolved to a full system path.
101      */
102     public String createClasspath()
103         throws MojoExecutionException
104     {
105 
106         StringBuffer cpBuffer = new StringBuffer();
107 
108         for ( Iterator<Artifact> it = pluginClasspathList.iterator(); it.hasNext(); )
109         {
110             Artifact artifact = it.next();
111 
112             try
113             {
114                 cpBuffer.append( File.pathSeparator ).append( artifact.getFile().getCanonicalPath() );
115             }
116             catch ( IOException e )
117             {
118                 throw new MojoExecutionException(
119                     "Error while creating the canonical path for '" + artifact.getFile() + "'.", e );
120             }
121         }
122 
123         return cpBuffer.toString();
124     }
125 
126     private String getLog4jConfigFile()
127     {
128         String resourceName = "cobertura-plugin/log4j-info.properties";
129         if ( getLog().isDebugEnabled() )
130         {
131             resourceName = "cobertura-plugin/log4j-debug.properties";
132         }
133         if ( quiet )
134         {
135             resourceName = "cobertura-plugin/log4j-error.properties";
136         }
137 
138         String path = null;
139         try
140         {
141             File log4jconfigFile = File.createTempFile( "log4j", "config.properties" );
142             URL log4jurl = this.getClass().getClassLoader().getResource( resourceName );
143             FileUtils.copyURLToFile( log4jurl, log4jconfigFile );
144             log4jconfigFile.deleteOnExit();
145             path = log4jconfigFile.toURL().toExternalForm();
146         }
147         catch ( MalformedURLException e )
148         {
149             // ignore
150         }
151         catch ( IOException e )
152         {
153             // ignore
154         }
155         return path;
156     }
157 
158     /**
159      * Run the task.
160      *
161      * @throws MojoExecutionException for a full-out execution problem.
162      * @throws MojoFailureException   for an anticipated failure.
163      */
164     public abstract void execute()
165         throws MojoExecutionException, MojoFailureException;
166 
167     /**
168      * Run a jvm to execute something.
169      *
170      * @return the exit code.
171      * @throws MojoExecutionException for an error launching the jvm.
172      */
173     protected int executeJava()
174         throws MojoExecutionException
175     {
176         Commandline cl = new Commandline();
177         File java = new File( SystemUtils.getJavaHome(), "bin/java" );
178         cl.setExecutable( java.getAbsolutePath() );
179         cl.addEnvironment( "CLASSPATH", createClasspath() );
180 
181         String log4jConfig = getLog4jConfigFile();
182         if ( log4jConfig != null )
183         {
184             cl.createArg().setValue( "-Dlog4j.configuration=" + log4jConfig );
185         }
186 
187         cl.createArg().setValue( "-Xmx" + maxmem );
188 
189         cl.createArg().setValue( taskClass );
190 
191         if ( cmdLineArgs.useCommandsFile() )
192         {
193             String commandsFile;
194             try
195             {
196                 commandsFile = cmdLineArgs.getCommandsFile();
197             }
198             catch ( IOException e )
199             {
200                 throw new MojoExecutionException( "Unable to obtain CommandsFile location.", e );
201             }
202             if ( FileUtils.fileExists( commandsFile ) )
203             {
204                 cl.createArg().setValue( "--commandsfile" );
205                 cl.createArg().setValue( commandsFile );
206             }
207             else
208             {
209                 throw new MojoExecutionException( "CommandsFile doesn't exist: " + commandsFile );
210             }
211         }
212         else
213         {
214             Iterator<String> it = cmdLineArgs.iterator();
215             while ( it.hasNext() )
216             {
217                 cl.createArg().setValue( it.next() );
218             }
219         }
220 
221         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
222 
223         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
224 
225         if ( quiet )
226         {
227             CommandLineUtils.StringStreamConsumer nullConsumer = new CommandLineUtils.StringStreamConsumer()
228             {
229                 public void consumeLine( String line )
230                 {
231                     // swallow
232                 }
233             };
234             stdout = nullConsumer;
235             stderr = nullConsumer;
236         }
237 
238         getLog().debug( "Working Directory: " + cl.getWorkingDirectory() );
239         try
240         {
241             String[] environmentVariables = cl.getEnvironmentVariables();
242             for ( String environmentVariable : environmentVariables )
243             {
244                 getLog().debug( "Environment variable: " + environmentVariable );
245             }
246         }
247         catch( CommandLineException e ) {
248             // Ignore
249         }
250         getLog().debug( "Executing command line:" );
251         getLog().debug( cl.toString() );
252 
253         int exitCode;
254         try
255         {
256             exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
257         }
258         catch ( CommandLineException e )
259         {
260             throw new MojoExecutionException( "Unable to execute Cobertura.", e );
261         }
262 
263         getLog().debug( "exit code: " + exitCode );
264 
265         String output = stdout.getOutput();
266 
267         if ( output.trim().length() > 0 )
268         {
269             getLog().debug( "--------------------" );
270             getLog().debug( " Standard output from the Cobertura task:" );
271             getLog().debug( "--------------------" );
272             getLog().info( output );
273             getLog().debug( "--------------------" );
274         }
275 
276         String stream = stderr.getOutput();
277 
278         if ( stream.trim().length() > 0 )
279         {
280             getLog().debug( "--------------------" );
281             getLog().debug( " Standard error from the Cobertura task:" );
282             getLog().debug( "--------------------" );
283             getLog().error( stderr.getOutput() );
284             getLog().debug( "--------------------" );
285         }
286 
287         return exitCode;
288     }
289 
290     /**
291      * Return the command line args.
292      *
293      * @return the command line args.
294      */
295     public CommandLineArguments getCmdLineArgs()
296     {
297         return cmdLineArgs;
298     }
299 
300     /**
301      * @return a log object.
302      */
303     public Log getLog()
304     {
305         if ( log == null )
306         {
307             log = new SystemStreamLog();
308         }
309 
310         return log;
311     }
312 
313     /**
314      * @return the configured -Xmx option.
315      */
316     public String getMaxmem()
317     {
318         return maxmem;
319     }
320 
321     /**
322      * @return Returns the pluginClasspathList.
323      */
324     public List<Artifact> getPluginClasspathList()
325     {
326         return pluginClasspathList;
327     }
328 
329     /**
330      * Set the entire command line args.
331      *
332      * @param cmdLineArgs new args.
333      */
334     public void setCmdLineArgs( CommandLineArguments cmdLineArgs )
335     {
336         this.cmdLineArgs = cmdLineArgs;
337     }
338 
339     /**
340      * Set the logger.
341      *
342      * @param log the new logger.
343      */
344     public void setLog( Log log )
345     {
346         this.log = log;
347     }
348 
349     /**
350      * Set the -Xmx value for the jvm.
351      *
352      * @param maxmem the memory size.
353      */
354     public void setMaxmem( String maxmem )
355     {
356         this.maxmem = maxmem;
357     }
358 
359     /**
360      * @param pluginClasspathList The pluginClasspathList to set.
361      */
362     public void setPluginClasspathList( List<Artifact> pluginClasspathList )
363     {
364         this.pluginClasspathList = Collections.unmodifiableList( pluginClasspathList );
365     }
366 }