org.jboss.byteman.contrib.rulecheck.RuleCheckMojo Maven / Gradle / Ivy
package org.jboss.byteman.contrib.rulecheck;
/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
* @authors Amos Feng
*/
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.jboss.byteman.check.RuleCheck;
import org.jboss.byteman.check.RuleCheckResult;
import java.io.File;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
/**
* Check the byteman script rule
*
*/
@Mojo( name = "rulecheck", defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class RuleCheckMojo extends AbstractMojo
{
@Component
private MavenProject project;
@Component
private PluginDescriptor descriptor;
/**
* Location of the script.
*/
@Parameter( defaultValue = "${project.build.testOutputDirectory}", property = "scriptDir", required = true )
private File scriptDir;
/**
* Packages to lookup non-package qualified class names
*/
@Parameter( property = "packages")
private String[] packages;
/**
* Fail build when rule check returns error
*/
@Parameter(defaultValue = "true", property = "failOnError")
private boolean failOnError;
/**
* Fail build when rule check has warnings
*/
@Parameter(defaultValue = "true", property = "failOnWarning")
private boolean failOnWarning;
/**
* Expect count of warning messages
*/
@Parameter(defaultValue = "0", property = "expectWarnings")
private int expectWarnings;
/*
* Skip the checking
*/
@Parameter(defaultValue = "false", property = "skip")
private boolean skip;
/**
* include specified script files
*/
@Parameter(property = "includes")
private String[] includes;
/**
* exclude specified script files
*/
@Parameter(property = "excludes")
private String[] excludes;
/**
* additional class path
*/
@Parameter(property = "additionalClassPath")
private String additionalClassPath;
/**
* env settings
*/
@Parameter(property = "systemProperties")
private Properties systemProperties;
/**
* verbose
*/
@Parameter(defaultValue = "false" , property = "verbose")
boolean verbose;
public void execute() throws MojoExecutionException {
List scripts;
if(skip) {
getLog().info("Checking byteman scripts are skipped");
return;
}
for (String key : systemProperties.stringPropertyNames()) {
if (!key.matches("[-A-Za-z0-9_$.]+")) {
throw new MojoExecutionException("invalid system property " + key);
}
String value = systemProperties.getProperty(key);
System.setProperty(key, value);
}
try {
if(verbose) {
getLog().info("find byteman script in " + scriptDir);
}
StringBuffer includebuf = new StringBuffer();
for(int i = 0; i < includes.length; i++) {
includebuf.append(includes[i]);
if(i != includes.length - 1) includebuf.append(",");
}
StringBuffer excludebuf = new StringBuffer();
for(int i = 0; i < excludes.length; i++) {
excludebuf.append(excludes[i]);
if(i != excludes.length - 1) excludebuf.append(",");
}
scripts = FileUtils.getFiles(scriptDir, includebuf.toString(), excludebuf.toString());
} catch (Exception e) {
getLog().debug("Can not find " + scriptDir);
return;
}
if(scripts.size() == 0) {
getLog().info("No byteman script in " + scriptDir);
return;
} else {
int n = scripts.size();
getLog().info("Found " + n + " scripts:");
for (int i = 0; i < n; i++) {
getLog().info(" " + i + ": " + scripts.get(i));
}
}
List classpathElements;
try {
classpathElements = project.getCompileClasspathElements();
classpathElements.addAll(project.getRuntimeClasspathElements());
classpathElements.add(project.getBuild().getOutputDirectory() );
classpathElements.add(project.getBuild().getTestOutputDirectory() );
if(additionalClassPath != null) {
String[] cps = (additionalClassPath.split(";"));
for(int i = 0; i < cps.length; i++) {
File file = new File(cps[i]);
String path = null;
if(file.isAbsolute()) {
path = cps[i];
} else {
path = project.getBasedir() + File.separator + cps[i];
}
classpathElements.add(path);
if(verbose) {
getLog().info("add addional classpath " + path);
}
}
}
ClassRealm realm = descriptor.getClassRealm();
for (String element : classpathElements)
{
File elementFile = new File(element);
if(verbose) {
getLog().info(element);
} else {
getLog().debug(element);
}
realm.addURL(elementFile.toURI().toURL());
}
} catch (DependencyResolutionRequiredException e) {
getLog().warn(e);
} catch (MalformedURLException e) {
getLog().warn(e);
}
RuleCheck checker = new RuleCheck();
for(File script : scripts) {
if(verbose) {
getLog().info("add script " + script);
}else {
getLog().debug("add script " + script);
}
checker.addRuleFile(script.getAbsolutePath());
}
for(int i = 0; i < packages.length; i++) {
checker.addPackage(packages[i]);
if(verbose) {
getLog().info("add package " + packages[i]);
}else {
getLog().debug("add package " + packages[i]);
}
}
getLog().info("Checking " + scripts.size() + " byteman scripts in " + scriptDir);
checker.checkRules();
RuleCheckResult result= checker.getResult();
if(result.hasWarning()) {
List warns = result.getWarningMessages();
warns.addAll(result.getTypeWarningMessages());
for(String warn : warns) {
getLog().warn(warn);
}
int totalWarnCount = warns.size();
if(failOnWarning && expectWarnings != totalWarnCount) {
throw new MojoExecutionException("check byteman script rules failed with " + totalWarnCount +
" warnings. You may config failOnWarning with false or expectWarnings with " + totalWarnCount);
}
}
if(result.hasError()) {
int totalErrorCount = result.getErrorCount() + result.getParseErrorCount() + result.getTypeErrorCount();
getLog().error("Checking byteman script rules failed with " + totalErrorCount + " errors");
List errors = result.getErrorMessages();
errors.addAll(result.getParseErrorMessages());
errors.addAll(result.getTypeErrorMessages());
for(String error : errors) {
getLog().error(error);
}
if(failOnError) {
throw new MojoExecutionException("check byteman script rules failed with " + totalErrorCount + " errors");
}
}
}
}