package org.codehaus.mojo.javancss;
/*
* 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 java.io.File;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
/**
* Check the build if for any Method with a ccn greater than a limit in the source code. Fails the build if told so.
*
* @author <a href="jeanlaurentATgmail.com">Jean-Laurent de Morlhon</a>
* @version $Id$
* @goal check
* @phase verify
* @execute goal="report"
*/
public class NcssViolationCheckMojo
extends AbstractMojo
{
/**
* Specifies the location of the source files to be used.
*
* @parameter expression="${project.build.sourceDirectory}"
* @required
* @readonly
*/
private File sourceDirectory;
/**
* Specifies the directory where the XML report will be generated.
*
* @parameter default-value="${project.build.directory}"
* @required
*/
// FIXME : same variable, same value in NCSSReportMojo...
private File xmlOutputDirectory;
/**
* Whether to fail the build if the validation check fails.
*
* @parameter default-value="true"
* @required
*/
private boolean failOnViolation;
/**
* Name of the file holding the xml file generated by JavaNCSS
*
* @parameter default-value="javancss-raw-report.xml"
* @required
*/
// FIXME : same variable, same value in NCSSReportMojo...
private String tempFileName;
/**
* CCN Limit, any code with a ccn greater than this number will generate a violation
*
* @parameter default-value="10"
* @required
*/
private int ccnLimit;
/**
* ncss Limit, any code with a ncss greater than this number will generate a violation
*
* @parameter default-value="100"
* @required
*/
private int ncssLimit;
public void execute()
throws MojoExecutionException, MojoFailureException
{
if ( sourceDirectory == null || !sourceDirectory.exists() )
{
return;
}
Set ccnViolation = new HashSet();
Set ncssViolation = new HashSet();
List methodList = loadDocument().selectNodes( "//javancss/functions/function" );
// Count ccn & ncss violations
Iterator nodeIterator = methodList.iterator();
while ( nodeIterator.hasNext() )
{
Node node = (Node) nodeIterator.next();
// count ccn violation
int ccn = new Integer( node.valueOf( "ccn" ) ).intValue();
if ( ccn > ccnLimit )
{
ccnViolation.add( node.valueOf( "name" ) );
}
// count ncss violation
int ncss = new Integer( node.valueOf( "ncss" ) ).intValue();
if ( ncss > ncssLimit )
{
ncssViolation.add( node.valueOf( "name" ) );
}
}
// crappy....
reportViolation( "ccn", ccnViolation, ccnLimit );
reportViolation( "ncss", ncssViolation, ncssLimit );
}
private Document loadDocument()
throws MojoFailureException
{
// FIXME: Building of File is strangely equivalent to method buildOutputFileName of NcssReportGenerator class...
File ncssXmlFile = new File( xmlOutputDirectory, tempFileName );
try
{
return new SAXReader().read( ncssXmlFile );
}
catch ( DocumentException de )
{
throw new MojoFailureException( "Can't read javancss xml output file : " + ncssXmlFile );
}
}
private void reportViolation( String statName, Set violationSet, int limit )
throws MojoFailureException
{
getLog().debug( statName + " Violation = " + violationSet.size() );
if ( violationSet.size() > 0 )
{
String violationString =
"Your code has " + violationSet.size() + " method(s) with a " + statName + " greater than " + limit;
getLog().warn( violationString );
Iterator iterator = violationSet.iterator();
while ( iterator.hasNext() )
{
getLog().warn( " " + (String) iterator.next() );
}
if ( failOnViolation )
{
throw new MojoFailureException( violationString );
}
}
}
}