
org.bitbucket.bradleysmithllc.etlunit.launcher.BootStrapper Maven / Gradle / Ivy
The newest version!
package org.bitbucket.bradleysmithllc.etlunit.launcher;
/*
* #%L
* etlunit-application-assembly
* %%
* Copyright (C) 2010 - 2023 bradleysmithllc
* %%
* 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.
* #L%
*/
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultModelBuilder;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectModelResolver;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RequestTrace;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.transport.wagon.WagonTransporterFactory;
import java.io.*;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
/**
* Hello world!
*/
public class BootStrapper {
private static Pair> effectiveProject = null;
static Pair> effectiveProject() throws Exception {
if (effectiveProject == null) {
File pomFile = pomFile();
if (!pomFile.exists()) {
throw new IllegalStateException("No maven project detected");
}
effectiveProject = resolveProjectDependencies(pomFile);
}
return effectiveProject;
}
public static ClassLoader contextClassLoader() throws Exception {
File localDirectory = localDirectory();
List finalURLList = new ArrayList<>();
// prepend the classes and test-classes directories to catch intermediate classes and resources
addIfExists(mavenBuildDirectory(localDirectory, "test-classes"), finalURLList);
addIfExists(mavenBuildDirectory(localDirectory, "classes"), finalURLList);
addIfExists(mavenSrcTestDirectory(localDirectory, "resources"), finalURLList);
addIfExists(mavenSrcMainDirectory(localDirectory, "resources"), finalURLList);
finalURLList.addAll(effectiveProject().getRight());
// write this log in the target folder
File logFile = mavenBuildDirectory(localDirectory, "BootStrapper.classloader.log");
// write out a debug log as well as creating a classpath for other modules
StringBuilder classpathBuilder = new StringBuilder();
FileWriter fw = new FileWriter(logFile);
BufferedWriter writer = new BufferedWriter(fw);
writer.write("URL ClassLoader components:\n");
List classloaderURLList = new ArrayList<>();
for (File file : finalURLList) {
classloaderURLList.add(file.toURL());
if (classpathBuilder.length() > 0) {
classpathBuilder.append(File.pathSeparator);
}
classpathBuilder.append(file.getCanonicalPath());
writer.write(file.getCanonicalPath());
writer.write("\n");
}
writer.write("\n\nInternal classpath:\n\n\n");
String str = classpathBuilder.toString();
writer.write(str);
writer.flush();
writer.close();
fw.close();
System.setProperty("etlunit.maven.plugin.classpath", str);
// create classloader
ClassLoader urlClassLoader = new DelegatingClassLoader(classloaderURLList.toArray(new URL[classloaderURLList.size()]));
Thread.currentThread().setContextClassLoader(urlClassLoader);
return urlClassLoader;
}
private static void addIfExists(File directory, List finalURLList) throws MalformedURLException {
if (directory.exists()) {
finalURLList.add(directory);
}
}
private static File pomFile() {
File pom = new File(localDirectory(), "pom.xml");
if (!pom.exists()) {
throw new IllegalStateException("Not a maven project");
}
return pom;
}
private static File localDirectory() {
return new File(System.getProperty("user.dir"));
}
private static File mavenSrcDirectory(File localDirectory) {
return new File(localDirectory, "src");
}
private static File mavenSrcMainDirectory(File localDirectory) {
return new File(mavenSrcDirectory(localDirectory), "main");
}
private static File mavenSrcTestDirectory(File localDirectory) {
return new File(mavenSrcDirectory(localDirectory), "test");
}
private static File mavenSrcMainDirectory(File localDirectory, String resources) {
return new File(mavenSrcMainDirectory(localDirectory), resources);
}
private static File mavenSrcTestDirectory(File localDirectory, String resources) {
return new File(mavenSrcTestDirectory(localDirectory), resources);
}
private static File mavenBuildDirectory(File base) {
return new File(base, "target");
}
private static File mavenBuildDirectory(File base, String classes) {
return new File(mavenBuildDirectory(base), classes);
}
public static MavenProject loadProject(File pomFile) throws Exception {
MavenProject ret = null;
MavenXpp3Reader mavenReader = new MavenXpp3Reader();
if (pomFile != null && pomFile.exists()) {
FileReader reader = null;
try {
reader = new FileReader(pomFile);
Model model = mavenReader.read(reader);
model.setPomFile(pomFile);
ret = new MavenProject(model);
} finally {
reader.close();
}
}
return ret;
}
public static void main(String... argv) throws Exception {
File localDirectory = localDirectory();
File pomFile = pomFile();
ClassLoader cll = contextClassLoader();
Class cl = cll.loadClass("org.bitbucket.bradleysmithllc.etlunit.jline_cli.EtlUnitJLineCLI");
Method method = cl.getDeclaredMethod("main", String[].class);
// let the launcher do it's work
method.invoke(null, new Object [] {argv});
}
public static Pair> resolveProjectDependencies(File pomFile) throws Exception {
DefaultServiceLocator locator = serviceLocator();
RepositorySystem system = locator.getService(RepositorySystem.class);
DefaultRepositorySystemSession
session = MavenRepositorySystemUtils.newSession();
File localRepoDir = new File(System.getProperty("user.home"), ".m2/repository");
localRepoDir.mkdirs();
LocalRepository localRepo = new LocalRepository(localRepoDir);
session.setLocalRepositoryManager(
system.newLocalRepositoryManager(session, localRepo));
RequestTrace requestTrace = new RequestTrace(null);
RemoteRepositoryManager
remoteRepositoryManager =
locator.getService(RemoteRepositoryManager.class);
List repos =
Arrays.asList(new RemoteRepository.Builder("central", "default",
"https://repo.maven.apache.org/maven2/").build());
DefaultRepositorySystem repositorySystem =
new DefaultRepositorySystem();
repositorySystem.initService(locator);
ModelResolver modelResolver =
new ProjectModelResolver(session, requestTrace,
repositorySystem, remoteRepositoryManager, repos,
ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT,
null);
DefaultModelBuildingRequest modelBuildingRequest =
new DefaultModelBuildingRequest();
modelBuildingRequest.setPomFile(pomFile);
modelBuildingRequest.setModelResolver(modelResolver);
DefaultModelBuilder
modelBuilder = new DefaultModelBuilderFactory().newInstance();
Model effectiveModel = modelBuilder.build(
modelBuildingRequest).getEffectiveModel();
List dependencies = new ArrayList<>();
// verify that etlunit-jline is in the path, otherwise this project is not usable
List effectiveModelDependencies = effectiveModel.getDependencies();
for (Dependency dependency : effectiveModelDependencies) {
// Set the coordinates of the artifact to download
Artifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), "jar", dependency.getVersion());
long start = System.currentTimeMillis();
AetherTransitiveDependencies.resolve(artifact, dependencies);
long stop = System.currentTimeMillis();
System.out.println((stop - start) + "ms to resolve");
}
Set artifactSet = new HashSet<>();
for (Artifact artifact : dependencies) {
artifactSet.add(artifact.getGroupId() + ":" + artifact.getArtifactId());
}
if (!artifactSet.contains("org.bitbucket.bradleysmithllc.etlunit:etlunit-jline-cli")) {
System.out.println("This project is not built with the org.bitbucket.bradleysmithllc.etlunit:etlunit-jline-cli dependency. It cannot be used with this interface");
System.exit(-1);
}
// this is the unfiltered list. Make a single list of the max version for each dependency
Map artifactVersions = new HashMap<>();
for (Artifact artifact : dependencies) {
String id = artifact.getGroupId() + "." + artifact.getArtifactId();
if (!artifactVersions.containsKey(id)) {
artifactVersions.put(id, artifact);
} else {
DefaultArtifactVersion thisVersion = new DefaultArtifactVersion(artifact.getVersion());
Artifact lastArtifact = artifactVersions.get(id);
DefaultArtifactVersion lastVersion = new DefaultArtifactVersion(lastArtifact.getVersion());
if (thisVersion.compareTo(lastVersion) > 0) {
artifactVersions.put(id, artifact);
}
}
}
List artifacts = new ArrayList<>(artifactVersions.values());
Collections.sort(artifacts, Comparator.comparing(art -> (art.getGroupId() + "." + art.getArtifactId())));
List urlList = new ArrayList<>();
for (Artifact artifact : artifacts) {
urlList.add(artifact.getFile());
}
File localCache = mavenBuildDirectory(pomFile.getParentFile(), "effectivePom.xml");
localCache.getParentFile().mkdirs();
FileWriter fw = new FileWriter(localCache);
BufferedWriter bw = new BufferedWriter(fw);
new MavenXpp3Writer().write(bw, effectiveModel);
bw.flush();
bw.close();
return ImmutablePair.of(effectiveModel, urlList);
}
private static DefaultServiceLocator serviceLocator() {
DefaultServiceLocator locator =
MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class,
BasicRepositoryConnectorFactory.class);
locator.addService(
TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class,
HttpTransporterFactory.class);
locator.addService(TransporterFactory.class,
WagonTransporterFactory.class);
return locator;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy