Skip to content

Commit

Permalink
Cleaned up MavenResourceAccessor
Browse files Browse the repository at this point in the history
  • Loading branch information
nvoxland committed Sep 15, 2022
1 parent 73063b3 commit e19b281
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 161 deletions.
@@ -0,0 +1,4 @@
package liquibase.integration;

public class AbstractIntegration {
}
Expand Up @@ -159,17 +159,18 @@ protected void printSettings(String indent) {

@Override
protected ResourceAccessor getResourceAccessor(ClassLoader cl) {
List<ResourceAccessor> resourceAccessors = new ArrayList<ResourceAccessor>();
resourceAccessors.add(new MavenResourceAccessor(cl));
resourceAccessors.add(new FileSystemResourceAccessor(project.getBasedir()));
resourceAccessors.add(new ClassLoaderResourceAccessor(getClass().getClassLoader()));

if (changeLogDirectory != null) {
calculateChangeLogDirectoryAbsolutePath();
resourceAccessors.add(new FileSystemResourceAccessor(new File(changeLogDirectory)));
}

return new SearchPathResourceAccessor(searchPath, resourceAccessors.toArray(new ResourceAccessor[0]));
// List<ResourceAccessor> resourceAccessors = new ArrayList<ResourceAccessor>();
// resourceAccessors.add(new MavenResourceAccessor(cl));
// resourceAccessors.add(new FileSystemResourceAccessor(project.getBasedir()));
// resourceAccessors.add(new ClassLoaderResourceAccessor(getClass().getClassLoader()));
//
// if (changeLogDirectory != null) {
// calculateChangeLogDirectoryAbsolutePath();
// resourceAccessors.add(new FileSystemResourceAccessor(new File(changeLogDirectory)));
// }
//
// return new SearchPathResourceAccessor(searchPath, resourceAccessors.toArray(new ResourceAccessor[0]));
return null;
}

@Override
Expand Down
Expand Up @@ -893,16 +893,17 @@ private static InputStream handlePropertyFileInputStream(String propertyFile) th
}

protected ClassLoader getMavenArtifactClassLoader() throws MojoExecutionException {
try {
return MavenUtils.getArtifactClassloader(project,
includeArtifact,
includeTestOutputDirectory,
getClass(),
getLog(),
verbose);
} catch (MalformedURLException e) {
throw new MojoExecutionException("Failed to create artifact classloader", e);
}
return null;
// try {
// return MavenUtils.getArtifactClassloader(project,
// includeArtifact,
// includeTestOutputDirectory,
// getClass(),
// getLog(),
// verbose);
// } catch (MalformedURLException e) {
// throw new MojoExecutionException("Failed to create artifact classloader", e);
// }
}

/**
Expand All @@ -926,9 +927,10 @@ protected ClassLoader getClassLoaderIncludingProjectClasspath() throws MojoExecu
}

protected ResourceAccessor getResourceAccessor(ClassLoader cl) {
ResourceAccessor mFO = new MavenResourceAccessor(cl);
ResourceAccessor fsFO = new FileSystemResourceAccessor(project.getBasedir());
return new SearchPathResourceAccessor(searchPath, mFO, fsFO);
// ResourceAccessor mFO = new MavenResourceAccessor(cl);
// ResourceAccessor fsFO = new FileSystemResourceAccessor(project.getBasedir());
// return new SearchPathResourceAccessor(searchPath, mFO, fsFO);
return null;
}

/**
Expand Down
Expand Up @@ -3,16 +3,13 @@
import liquibase.Scope;
import liquibase.command.CommandDefinition;
import liquibase.command.CommandFactory;
import liquibase.command.CommandResults;
import liquibase.command.CommandScope;
import liquibase.integration.commandline.Main;
import liquibase.util.StringUtil;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.MapOrientedComponent;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
Expand All @@ -26,45 +23,28 @@
import java.util.Map;
import java.util.Properties;

public class LiquibaseCommandMojo extends AbstractMojo implements MapOrientedComponent {
public class LiquibaseMojo extends AbstractMojo implements MapOrientedComponent {

private String goal;
private Map<String, Object> configuration;
private ClassLoader classloader;
// private List<Parameter> goalParameters;
private MavenProject project;
private MojoExecution mojoExecution;

public LiquibaseCommandMojo() {
public LiquibaseMojo() {
}

@Override
public void addComponentRequirement(ComponentRequirement componentRequirement, Object o) throws ComponentConfigurationException {
System.out.println("Add compp");
//TODO: How does this get used?
}

@Override
public void setComponentConfiguration(Map<?, ?> map) throws ComponentConfigurationException {
MojoExecution mojoExecution = (MojoExecution) map.get("mojoExecution");
MavenProject project = (MavenProject) map.get("project");

this.goal = mojoExecution.getGoal();

public void setComponentConfiguration(Map<?, ?> config) throws ComponentConfigurationException {
this.mojoExecution = (MojoExecution) config.get("mojoExecution");
this.project = (MavenProject) config.get("project");

try {
List classpathElements = project.getCompileClasspathElements();
classpathElements.add(project.getBuild().getOutputDirectory());
URL urls[] = new URL[classpathElements.size()];
for (int i = 0; i < classpathElements.size(); ++i) {
urls[i] = new File((String) classpathElements.get(i)).toURI().toURL();
}
this.classloader = new URLClassLoader(urls, MavenUtils.getArtifactClassloader(project,
true,
true,
getClass(),
getLog(),
false));

this.configuration = new HashMap<>();
for (Map.Entry entry : map.entrySet()) {
for (Map.Entry<?, ?> entry : config.entrySet()) {
Object value = entry.getValue();
if (value == null) {
continue;
Expand All @@ -75,7 +55,7 @@ public void setComponentConfiguration(Map<?, ?> map) throws ComponentConfigurati
this.configuration.put(String.valueOf(entry.getKey()), entry.getValue());
}

Properties userProperties = ((MavenSession) map.get("session")).getUserProperties();
Properties userProperties = ((MavenSession) config.get("session")).getUserProperties();
for (Map.Entry<Object, Object> entry : userProperties.entrySet()) {
this.configuration.put(String.valueOf(entry.getKey()), entry.getValue());
}
Expand All @@ -86,10 +66,9 @@ public void setComponentConfiguration(Map<?, ?> map) throws ComponentConfigurati

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
// System.out.println("EXECUTE COMMAND MOJO!!!"+goal);
// System.out.println(StringUtil.join(configuration, ","));
Main.runningFromNewCli = true;

String goal = mojoExecution.getGoal();
try {
CommandScope commandScope = new CommandScope(goal);

Expand All @@ -103,7 +82,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}

Map<String, Object> scopeValues = new HashMap<>();
scopeValues.put(Scope.Attr.resourceAccessor.name(), new MavenResourceAccessor(classloader));
scopeValues.put(Scope.Attr.resourceAccessor.name(), new MavenResourceAccessor(project));
Scope.child(scopeValues, () -> {
commandScope.execute();
});
Expand Down
@@ -1,19 +1,61 @@
package org.liquibase.maven.plugins;

import liquibase.Scope;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.CompositeResourceAccessor;
import liquibase.resource.FileSystemResourceAccessor;
import liquibase.resource.InputStreamList;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

import static sun.awt.FontConfiguration.verbose;

/**
* Extension of {@link liquibase.resource.ClassLoaderResourceAccessor} for Maven which will use a default or user specified {@link ClassLoader} to load files/resources.
*/
public class MavenResourceAccessor extends ClassLoaderResourceAccessor {
public class MavenResourceAccessor extends CompositeResourceAccessor {

public MavenResourceAccessor(MavenProject project) throws DependencyResolutionRequiredException {
for (String element : project.getCompileClasspathElements()) {
this.addResourceAccessor(new FileSystemResourceAccessor(new File(element)));
}

Set<Artifact> dependencies = project.getArtifacts();
if (dependencies != null) {
for (Artifact artifact : dependencies) {
this.addResourceAccessor(new FileSystemResourceAccessor(artifact.getFile()));
}
} else {
Scope.getCurrentScope().getLog(getClass()).fine("No artifacts for the Maven project to add to the searchPath");
}

// 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.
File projectArtifactFile = project.getArtifact().getFile();
if (projectArtifactFile == null) {
this.addResourceAccessor(new FileSystemResourceAccessor(new File(project.getBuild().getOutputDirectory())));
} else {
this.addResourceAccessor(new FileSystemResourceAccessor(projectArtifactFile));
}

public MavenResourceAccessor(ClassLoader classLoader) {
super(classLoader);
//TODO if (includeTestOutputDirectory) {
this.addResourceAccessor(new FileSystemResourceAccessor(new File(project.getBuild().getTestOutputDirectory())));
// }
}

@Override
Expand Down
Expand Up @@ -28,107 +28,6 @@ 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<URI> 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<URI> 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<URI> 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<URI> 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
Expand Down

0 comments on commit e19b281

Please sign in to comment.