org.liquibase.maven.plugins.MavenUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of liquibase-maven-plugin Show documentation
Show all versions of liquibase-maven-plugin Show documentation
A Maven plugin wraps up some of the functionality of Liquibase
// Version: $Id: $
// Copyright: Copyright(c) 2007 Trace Financial Limited
package org.liquibase.maven.plugins;
import liquibase.Scope;
import liquibase.exception.LiquibaseException;
import liquibase.license.*;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.liquibase.maven.property.PropertyElement;
import java.io.File;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
/**
* A Utilities class for Maven plugins.
*
* @author Peter Murray
*/
public class MavenUtils {
public static final String LOG_SEPARATOR =
"------------------------------------------------------------------------";
/**
* Obtains a {@link ClassLoader} that can load from the Maven project dependencies. If
* the dependencies have not be resolved (or there are none) then this will just end up
* delegating to the parent {@link ClassLoader} of this class.
*
* @return The ClassLoader that can load the resolved dependencies for the Maven
* project.
* @throws java.net.MalformedURLException If any of the dependencies cannot be resolved
* into a URL.
*/
public static ClassLoader getArtifactClassloader(MavenProject project,
boolean includeArtifact,
boolean includeTestOutputDirectory,
Class clazz,
Log log,
boolean verbose)
throws MalformedURLException {
if (verbose) {
log.info("Loading artifacts into URLClassLoader");
}
Set uris = new HashSet<>();
// Find project dependencies, including the transitive ones.
Set dependencies = project.getArtifacts();
if ((dependencies != null) && !dependencies.isEmpty()) {
for (Iterator it = dependencies.iterator(); it.hasNext(); ) {
addArtifact(uris, (Artifact) it.next(), log, verbose);
}
} else {
log.info("there are no resolved artifacts for the Maven project.");
}
// Include the artifact for the actual maven project if requested
if (includeArtifact) {
// If the actual artifact can be resolved, then use that, otherwise use the build
// directory as that should contain the files for this project that we will need to
// run against. It is possible that the build directly could be empty, but we cannot
// directly include the source and resources as the resources may require filtering
// to replace any placeholders in the resource files.
Artifact a = project.getArtifact();
if (a.getFile() != null) {
addArtifact(uris, a, log, verbose);
} else {
addFile(uris, new File(project.getBuild().getOutputDirectory()), log, verbose);
}
}
if (includeTestOutputDirectory) {
addFile(uris, new File(project.getBuild().getTestOutputDirectory()), log, verbose);
}
if (verbose) {
log.info(LOG_SEPARATOR);
}
List uriList = new ArrayList<>(uris);
URL[] urlArray = new URL[uris.size()];
for (int i = 0; i < uris.size(); i++) {
urlArray[i] = uriList.get(i).toURL();
}
return new URLClassLoader(urlArray, clazz.getClassLoader());
}
/**
* Adds the artifact file into the set of URLs so it can be used in a URLClassLoader.
*
* @param urls The set to add the artifact file URL to.
* @param artifact The Artifact to resolve the file for.
* @throws MalformedURLException If there is a problem creating the URL for the file.
*/
private static void addArtifact(Set urls,
Artifact artifact,
Log log,
boolean verbose)
throws MalformedURLException {
File f = artifact.getFile();
if (f == null) {
log.warn("Artifact with no actual file, '" + artifact.getGroupId()
+ ":" + artifact.getArtifactId() + "'");
} else {
addFile(urls, f, log, verbose);
}
// if (f != null) {
// URL fileURL = f.toURI().toURL();
// if (verbose) {
// log.info(" artifact: " + fileURL);
// }
// urls.add(fileURL);
// } else {
// log.warning("Artifact with no actual file, '" + artifact.getGroupId()
// + ":" + artifact.getArtifactId() + "'");
// }
}
private static void addFile(Set urls, File f, Log log, boolean verbose)
throws MalformedURLException {
if (f != null) {
URI fileUri = f.toURI();
if (verbose) {
log.info(" artifact: " + fileUri);
}
urls.add(fileUri);
}
}
/**
* Recursively searches for the field specified by the fieldName in the class and all
* the super classes until it either finds it, or runs out of parents.
*
* @param clazz The Class to start searching from.
* @param keyPropertyName The name of the field to retrieve.
* @return The {@link Field} identified by the field name.
* @throws NoSuchFieldException If the field was not found in the class or any of its
* super classes.
*/
public static Field getDeclaredField(Class> clazz, String keyPropertyName)
throws NoSuchFieldException {
Field f = getField(clazz, keyPropertyName);
if (f == null) {
// Try the parent class
Class> parent = clazz.getSuperclass();
if (parent != null) {
return getDeclaredField(parent, keyPropertyName);
} else {
throw new NoSuchFieldException("The field '" + keyPropertyName + "' could not be "
+ "found in the class of any of its parent "
+ "classes.");
}
} else {
return f;
}
}
private static Field getField(Class> clazz, String fieldName) {
Field[] fields = clazz.getDeclaredFields();
int i = 0;
while (i < fields.length) {
Field field = fields[i];
PropertyElement annotation = field.getAnnotation(PropertyElement.class);
if (annotation != null) {
if (annotation.key().equalsIgnoreCase(fieldName)) {
return field;
}
}
if (fields[i].getName().equalsIgnoreCase(fieldName)) {
return fields[i];
}
i++;
}
return null;
}
}