package org.codehaus.mojo.macker; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.logging.SystemStreamLog; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer; /** * Forking to invoke the Macker tool. Based on * <code>org.codehaus.mojo.cobertura.tasks.AbstractTask</code>. * This uses the Shell from CommandLine for forking. In Windows XP this has * a max of 8kb command line arguments. So we have to use a command file. * @author <a href="http://www.code-cop.org/">Peter Kofler</a> */ public class ForkedMacker implements Macker { private static final String COMMAND_CLASS = CommandLineFile.class.getName(); private static final String TASK_CLASS = "net.innig.macker.Macker"; private List/*<String>*/options = new ArrayList/*<String>*/(); private List/*<String>*/rules = new ArrayList/*<String>*/(); private List/*<String>*/classes = new ArrayList/*<String>*/(); private Log log = new SystemStreamLog(); private String maxmem; private List/*<Artifact>*/pluginClasspathList = Collections.EMPTY_LIST; private boolean quiet; private String createClasspath() throws MojoExecutionException { StringBuffer cpBuffer = new StringBuffer(); for ( Iterator it = pluginClasspathList.iterator(); it.hasNext(); ) { Artifact artifact = (Artifact) it.next(); try { cpBuffer.append( artifact.getFile().getCanonicalPath() ); if ( it.hasNext() ) { cpBuffer.append( File.pathSeparator ); } } catch ( IOException e ) { throw new MojoExecutionException( "Error while creating the canonical path for '" + artifact.getFile() + "'.", e ); } } return cpBuffer.toString(); } private Commandline createCommandLine() throws MojoExecutionException { // Commandline cl = new Commandline(); // cl.setExecutable( "java" ); // cl.createArg().setValue( "-cp" ); // cl.createArg().setValue( createClasspath() ); // if ( maxmem != null ) // { // cl.createArg().setValue( "-Xmx" + maxmem ); // } // cl.createArg().setValue( commandClass ); List/*<String>*/jvmArguments = new ArrayList/*<String>*/(); jvmArguments.add( "-cp" ); jvmArguments.add( createClasspath() ); if ( maxmem != null ) { jvmArguments.add( "-Xmx" + maxmem ); } Commandline cl = new Commandline( new JavaShell( jvmArguments ) ); cl.setExecutable( COMMAND_CLASS ); cl.createArg().setValue( TASK_CLASS ); try { CommandLineBuilder builder = new CommandLineBuilder( "macker" ); for ( Iterator/*<String>*/it = options.iterator(); it.hasNext(); ) { builder.addArg( (String) it.next() ); } for ( Iterator/*<String>*/it = rules.iterator(); it.hasNext(); ) { builder.addArg( (String) it.next() ); } for ( Iterator/*<String>*/it = classes.iterator(); it.hasNext(); ) { builder.addArg( (String) it.next() ); } builder.saveArgs(); String commandsFile = builder.getCommandLineFile(); cl.createArg().setValue( commandsFile ); } catch ( IOException e ) { throw new MojoExecutionException( "Unable to create CommandsFile.", e ); } return cl; } private int executeJava() throws MojoExecutionException { Commandline cl = createCommandLine(); StringStreamConsumer stdout = new StringStreamConsumer(); StringStreamConsumer stderr = new StringStreamConsumer(); if ( quiet ) { StringStreamConsumer nullConsumer = new StringStreamConsumer() { public void consumeLine( String s ) { } }; stdout = nullConsumer; stderr = nullConsumer; } log.debug( "Working Directory: " + cl.getWorkingDirectory() ); log.debug( "Executing command line:" ); log.debug( cl.toString() ); int exitCode; try { exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr ); } catch ( CommandLineException e ) { throw new MojoExecutionException( "Unable to execute Macker.", e ); } log.debug( "exit code: " + exitCode ); String output = stdout.getOutput(); if ( output.trim().length() > 0 ) { log.debug( "--------------------" ); log.debug( " Standard output from the Macker task:" ); log.debug( "--------------------" ); log.info( output ); log.debug( "--------------------" ); } String stream = stderr.getOutput(); if ( stream.trim().length() > 0 ) { log.debug( "--------------------" ); log.debug( " Standard error from the Macker task:" ); log.debug( "--------------------" ); log.error( stderr.getOutput() ); log.debug( "--------------------" ); } return exitCode; } public void check() throws MojoExecutionException, MojoFailureException { int returnCode = executeJava(); switch ( returnCode ) { case 0: log.debug( "All checks passed." ); break; case 2: log.debug( "Macker check failed." ); throw new MojoFailureException( "MackerIsMadException during Macker execution" ); default: log.error( "Macker check had errors. See messages above." ); throw new MojoExecutionException( "Error during Macker execution" ); } } public void setLog( Log log ) { this.log = log; } public void setMaxmem( String maxmem ) { this.maxmem = maxmem; } public void setPluginClasspathList( List/*<Artifact>*/pluginClasspathList ) { this.pluginClasspathList = Collections.unmodifiableList( pluginClasspathList ); } public void setQuiet( boolean quiet ) { this.quiet = quiet; } public void addClass( File clazz ) throws IOException { classes.add( clazz.getCanonicalPath() ); } public void addRulesFile( File rule ) throws IOException { // -r, --rulesfile <rules.xml> rules.add( "-r" ); rules.add( rule.getCanonicalPath() ); } public void setAngerThreshold( String anger ) { // --anger <threshold> options.add( "--anger" ); options.add( anger ); } public void setPrintMaxMessages( int maxMsg ) { // --print-max <max-messages> options.add( "--print-max" ); options.add( "" + maxMsg ); } public void setPrintThreshold( String print ) { // --print <threshold> options.add( "--print" ); options.add( print ); } public void setVariable( String name, String value ) { // -D, --define <var>=<value> options.add( "-D" ); options.add( name + "=" + value ); } public void setVerbose( boolean verbose ) { if ( verbose ) { // -v, --verbose options.add( "-v" ); } } public void setXmlReportFile( File report ) throws IOException { // -o, --output <report.xml> options.add( "-o" ); options.add( report.getCanonicalPath() ); } }