View Javadoc

1   package org.codehaus.mojo.macker;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugin.MojoFailureException;
25  import org.apache.maven.plugin.logging.Log;
26  import org.apache.maven.plugin.logging.SystemStreamLog;
27  
28  import java.io.File;
29  import java.io.IOException;
30  import java.util.ArrayList;
31  import java.util.Collections;
32  import java.util.Iterator;
33  import java.util.List;
34  
35  import org.codehaus.plexus.util.cli.CommandLineException;
36  import org.codehaus.plexus.util.cli.CommandLineUtils;
37  import org.codehaus.plexus.util.cli.Commandline;
38  import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer;
39  
40  /**
41   * Forking to invoke the Macker tool.  Based on
42   * <code>org.codehaus.mojo.cobertura.tasks.AbstractTask</code>.
43   * This uses the Shell from CommandLine for forking. In Windows XP this has
44   * a max of 8kb command line arguments.  So we have to use a command file.
45   * @author <a href="http://www.code-cop.org/">Peter Kofler</a>
46   */
47  public class ForkedMacker
48      implements Macker
49  {
50      private static final String COMMAND_CLASS = CommandLineFile.class.getName();
51      private static final String TASK_CLASS = "net.innig.macker.Macker";
52  
53      private List/*<String>*/options = new ArrayList/*<String>*/();
54      private List/*<String>*/rules = new ArrayList/*<String>*/();
55      private List/*<String>*/classes = new ArrayList/*<String>*/();
56      private Log log = new SystemStreamLog();
57      private String maxmem;
58      private List/*<Artifact>*/pluginClasspathList = Collections.EMPTY_LIST;
59      private boolean quiet;
60  
61      private String createClasspath()
62          throws MojoExecutionException
63      {
64          StringBuffer cpBuffer = new StringBuffer();
65          for ( Iterator it = pluginClasspathList.iterator(); it.hasNext(); )
66          {
67              Artifact artifact = (Artifact) it.next();
68              try
69              {
70                  cpBuffer.append( artifact.getFile().getCanonicalPath() );
71                  if ( it.hasNext() )
72                  {
73                      cpBuffer.append( File.pathSeparator );
74                  }
75              }
76              catch ( IOException e )
77              {
78                  throw new MojoExecutionException( "Error while creating the canonical path for '" + artifact.getFile()
79                          + "'.", e );
80              }
81          }
82  
83          return cpBuffer.toString();
84      }
85  
86      private Commandline createCommandLine()
87          throws MojoExecutionException
88      {
89          // Commandline cl = new Commandline();
90          // cl.setExecutable( "java" );
91          // cl.createArg().setValue( "-cp" );
92          // cl.createArg().setValue( createClasspath() );
93          // if ( maxmem != null )
94          // {
95          //     cl.createArg().setValue( "-Xmx" + maxmem );
96          // }
97          // cl.createArg().setValue( commandClass );
98          List/*<String>*/jvmArguments = new ArrayList/*<String>*/();
99          jvmArguments.add( "-cp" );
100         jvmArguments.add( createClasspath() );
101         if ( maxmem != null )
102         {
103             jvmArguments.add( "-Xmx" + maxmem );
104         }
105         Commandline cl = new Commandline( new JavaShell( jvmArguments ) );
106         cl.setExecutable( COMMAND_CLASS );
107 
108         cl.createArg().setValue( TASK_CLASS );
109         try
110         {
111             CommandLineBuilder builder = new CommandLineBuilder( "macker" );
112             for ( Iterator/*<String>*/it = options.iterator(); it.hasNext(); )
113             {
114                 builder.addArg( (String) it.next() );
115             }
116             for ( Iterator/*<String>*/it = rules.iterator(); it.hasNext(); )
117             {
118                 builder.addArg( (String) it.next() );
119             }
120             for ( Iterator/*<String>*/it = classes.iterator(); it.hasNext(); )
121             {
122                 builder.addArg( (String) it.next() );
123             }
124             builder.saveArgs();
125             String commandsFile =  builder.getCommandLineFile();
126             cl.createArg().setValue( commandsFile );
127         }
128         catch ( IOException e )
129         {
130             throw new MojoExecutionException( "Unable to create CommandsFile.", e );
131         }
132         return cl;
133     }
134 
135     private int executeJava()
136         throws MojoExecutionException
137     {
138         Commandline cl = createCommandLine();
139 
140         StringStreamConsumer stdout = new StringStreamConsumer();
141         StringStreamConsumer stderr = new StringStreamConsumer();
142         if ( quiet )
143         {
144             StringStreamConsumer nullConsumer = new StringStreamConsumer()
145             {
146                 public void consumeLine( String s )
147                 {
148                 }
149             };
150             stdout = nullConsumer;
151             stderr = nullConsumer;
152         }
153         log.debug( "Working Directory: " + cl.getWorkingDirectory() );
154         log.debug( "Executing command line:" );
155         log.debug( cl.toString() );
156 
157         int exitCode;
158         try
159         {
160             exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
161         }
162         catch ( CommandLineException e )
163         {
164             throw new MojoExecutionException( "Unable to execute Macker.", e );
165         }
166         log.debug( "exit code: " + exitCode );
167 
168         String output = stdout.getOutput();
169         if ( output.trim().length() > 0 )
170         {
171             log.debug( "--------------------" );
172             log.debug( " Standard output from the Macker task:" );
173             log.debug( "--------------------" );
174             log.info( output );
175             log.debug( "--------------------" );
176         }
177         String stream = stderr.getOutput();
178         if ( stream.trim().length() > 0 )
179         {
180             log.debug( "--------------------" );
181             log.debug( " Standard error from the Macker task:" );
182             log.debug( "--------------------" );
183             log.error( stderr.getOutput() );
184             log.debug( "--------------------" );
185         }
186         return exitCode;
187     }
188 
189     public void check()
190         throws MojoExecutionException, MojoFailureException
191     {
192         int returnCode = executeJava();
193         switch ( returnCode )
194         {
195         case 0:
196             log.debug( "All checks passed." );
197             break;
198         case 2:
199             log.debug( "Macker check failed." );
200             throw new MojoFailureException( "MackerIsMadException during Macker execution" );
201         default:
202             log.error( "Macker check had errors. See messages above." );
203             throw new MojoExecutionException( "Error during Macker execution" );
204         }
205     }
206 
207     public void setLog( Log log )
208     {
209         this.log = log;
210     }
211 
212     public void setMaxmem( String maxmem )
213     {
214         this.maxmem = maxmem;
215     }
216 
217     public void setPluginClasspathList( List/*<Artifact>*/pluginClasspathList )
218     {
219         this.pluginClasspathList = Collections.unmodifiableList( pluginClasspathList );
220     }
221 
222     public void setQuiet( boolean quiet )
223     {
224         this.quiet = quiet;
225     }
226 
227     public void addClass( File clazz )
228         throws IOException
229     {
230         classes.add( clazz.getCanonicalPath() );
231     }
232 
233     public void addRulesFile( File rule )
234         throws IOException
235     {
236         // -r, --rulesfile <rules.xml>
237         rules.add( "-r" );
238         rules.add( rule.getCanonicalPath() );
239     }
240 
241     public void setAngerThreshold( String anger )
242     {
243         // --anger <threshold>
244         options.add( "--anger" );
245         options.add( anger );
246     }
247 
248     public void setPrintMaxMessages( int maxMsg )
249     {
250         // --print-max <max-messages>
251         options.add( "--print-max" );
252         options.add( "" + maxMsg );
253     }
254 
255     public void setPrintThreshold( String print )
256     {
257         // --print <threshold>
258         options.add( "--print" );
259         options.add( print );
260     }
261 
262     public void setVariable( String name, String value )
263     {
264         // -D, --define <var>=<value>
265         options.add( "-D" );
266         options.add( name + "=" + value );
267     }
268 
269     public void setVerbose( boolean verbose )
270     {
271         if ( verbose )
272         {
273             // -v, --verbose
274             options.add( "-v" );
275         }
276     }
277 
278     public void setXmlReportFile( File report )
279         throws IOException
280     {
281         // -o, --output <report.xml>
282         options.add( "-o" );
283         options.add( report.getCanonicalPath() );
284     }
285 }