com.nathanaelrota.cmmi.maven.requirements.RequirementClassLoader Maven / Gradle / Ivy
package com.nathanaelrota.cmmi.maven.requirements;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.maven.plugin.logging.Log;
import com.nathanaelrota.fs.FileFinder;
/**
* @author Nathanael ROTA
*/
public class RequirementClassLoader extends ClassLoader {
/**
* Maven Logger
*/
private Log logger = null;
/**
* Constant Definition for DOT
*/
public static final char DOT = '.';
/**
* @param log
* the log to set
*/
public void setLog(Log log) {
this.logger = log;
}
/**
* ctor
*/
public RequirementClassLoader(ClassLoader parent) {
super(parent);
}
/**
* load the classes from directory dir corresponding to pattern
* @param dir the dir
* @param pattern classes pattern
*/
public void loadClasses(String dir, String pattern) {
List classes = getClasses(pattern, dir);
boolean loadComplete = false;
do {
loadComplete = true;
for (String classfile : getClasses(pattern, dir)) {
try {
this.load(dir, classfile);
} catch (NoClassDefFoundError noClassDefFoundError) {
if (contains(classes, noClassDefFoundError.getMessage())) {
loadComplete = false;
}
}
}
} while (loadComplete == false);
}
/**
* test if a classe's list contains a specific class
* @param classes the list of class
* @param noClassDefFound the specific class
* @return true if the classes list contains the class
*/
private boolean contains(List classes, String noClassDefFound) {
String className = noClassDefFound.replace('\\', DOT).replace('/', DOT);
for (String clazz : classes) {
if (clazz.replace('\\', DOT).replace('/', DOT).startsWith(className)) {
debug("Class \"" + className + "\" has been found in Classes set");
return true;
}
}
debug("Class \"" + className + "\" has not been found in Classes set");
return false;
}
/**
* Visit the Test Case Class to update values field
*
* @param file
* the name of the Test Case Class
* @param directory
*/
private void load(String directory, String file) {
String className = file.replace('\\', DOT);
className = className.replace('/', DOT);
className = className.substring(0, file.length() - ".class".length());
try {
String path = directory + File.separator + file;
debug("Load Class: \"" + className + "\" from File: \"" + path + "\"");
byte[] classData = readClassData(path);
defineClass(className, classData, 0, classData.length);
} catch (NoClassDefFoundError noClassDefFoundError) {
error("NoClassDefFoundError during load of \"" + className + "\" NoClassDefFound " + noClassDefFoundError.getMessage());
throw noClassDefFoundError;
} catch (LinkageError linkageError) {
debug("LinkageError during load of \"" + className + "\"" + linkageError.getMessage());
}
}
/**
* reading utility
* @param path the file path
* @return the byte array containing the file
*/
private byte[] readClassData(String path) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
InputStream input = new FileInputStream(path);
int data = input.read();
while (data != -1) {
buffer.write(data);
data = input.read();
}
input.close();
} catch (IOException ioException) {
error("Error during load of \"" + path + "\" : IO Issue");
}
return buffer.toByteArray();
}
/**
* Dispatch debug log
*
* @param msg
* debug message
*/
protected void debug(String msg) {
if (logger != null) {
logger.debug(msg);
} else {
Logger.getLogger(RequirementClassLoader.class).debug(msg);
}
}
/**
* Dispatch error log
*
* @param msg
* error message
*/
protected void error(String msg) {
if (logger != null) {
logger.error(msg);
} else {
Logger.getLogger(RequirementClassLoader.class).error(msg);
}
}
/**
* get all the test cases from the rootDir
*
* @param pattern
* pattern of the tests filename
* @param rootDir
* directory where are the tests
*/
public static List getClasses(String pattern, String rootDir) {
FileFinder fileFinder = new FileFinder();
fileFinder.setPattern(pattern);
fileFinder.setRoot(rootDir);
fileFinder.find();
return fileFinder.getFiles();
}
/**
* convert filename to classname
* @param file the filename
* @return the classname
*/
public static String getClassName(String file) {
String className = file.replace('\\', DOT);
className = className.replace('/', DOT);
className = className.substring(0, file.length() - ".class".length());
return className;
}
}