package net.sourceforge.javautil.classloader.impl.maven;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import net.sourceforge.javautil.classloader.boot.EntryPointClassPackage;
import net.sourceforge.javautil.classloader.boot.EntryPoint;
import net.sourceforge.javautil.classloader.boot.EntryPointConfiguration;
import net.sourceforge.javautil.classloader.boot.EntryPointSettings;
import net.sourceforge.javautil.classloader.boot.IEntryPointType;
import net.sourceforge.javautil.classloader.boot.IEntryPointType.TargetType;
import net.sourceforge.javautil.classloader.impl.ClassContext;
import net.sourceforge.javautil.classloader.impl.StandardClassLoaderHeiarchy;
import net.sourceforge.javautil.classloader.resolver.IClassPackage;
import net.sourceforge.javautil.classloader.resolver.ClassPackageContext;
import net.sourceforge.javautil.classloader.resolver.IClassPackageReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageResolver;
import net.sourceforge.javautil.classloader.resolver.IClassDependencyPool;
import net.sourceforge.javautil.classloader.resolver.IClassDependencyPool.PoolScope;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageReferenceImpl;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageResolverImpl;
import net.sourceforge.javautil.classloader.resolver.impl.ClassDependencyPoolImpl;
import net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryClassLoader;
import net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryLocalPackage;
import net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryLocalProject;
import net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryUtil;
import net.sourceforge.javautil.classloader.resolver.impl.maven.ProjectObjectModel;
import net.sourceforge.javautil.classloader.source.ClassSource;
import net.sourceforge.javautil.classloader.source.CompositeClassSource;
import net.sourceforge.javautil.classloader.source.LibDirectoryClassSource;
import net.sourceforge.javautil.classloader.util.ClassPackageUtil;
import net.sourceforge.javautil.common.VirtualArtifactUtil;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.impl.SystemDirectory;
import net.sourceforge.javautil.common.io.impl.SystemFile;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
/**
* The entry point for maven based applications needing maven dependency libraries loaded
* before the application starts.<br/><br/>
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: MavenEntryPoint.java 2745 2011-02-05 04:23:36Z ponderator $
*/
public class MavenEntryPoint extends EntryPointClassPackage implements IEntryPointType {
protected IClassPackageResolver resolver;
protected IClassDependencyPool pool;
public MavenEntryPoint () {}
public MavenEntryPoint(EntryPoint entryPoint, EntryPointSettings settings) {
super(entryPoint, settings);
}
public TargetType getTargetType() {
return TargetType.Bootstrapper;
}
public boolean canBoot() {
return this.locatePOMDescriptor() != null;
}
/**
* Will detect pom.xml specified by {@link #getPackageDescriptor()}, and load {@link EntryPoint#getAdditionalClassSources()}.
* It will also load all maven project directories specified by {@link #getProjectDirectory()}.
*/
public void main(EntryPointConfiguration config) throws Throwable {
ClassContext context = null;
ClassSource cs = config.getPoint().getAdditionalClassSources();
// Load project directories
String mp = this.getProjectDirectory();
if (mp == null) mp = "../";
this.resolver = MavenRepositoryUtil.createStandardResolver();
String[] mps = mp.split(";");
for (String mpd : mps) {
((ClassPackageResolverImpl)this.resolver).addLocalRepository(new MavenRepositoryLocalProject( new SystemDirectory(mpd) ));
}
((ClassPackageResolverImpl)this.resolver).addLocalRepository(new MavenRepositoryClassLoader());
context = cs != null ?
new ClassContext(new StandardClassLoaderHeiarchy(), cs) :
new ClassContext(new StandardClassLoaderHeiarchy());
Thread.currentThread().setContextClassLoader(context);
// Check for a specified or default pom.xml file
IVirtualFile pomFile = this.locatePOMDescriptor();
if (pomFile != null && pomFile.isExists()) {
ProjectObjectModel pom = ProjectObjectModel.parse(resolver, pomFile);
ProjectObjectModel resolved = (ProjectObjectModel) resolver.getDescriptor(pom);
if (resolved != null) {
pom = resolved;
} else {
log.info("Unresolvable pom.xml used for bootstrapping: " + pom);
}
MavenRepositoryUtil.addProjectMainTarget(context.getNonPackageSources(), pom, pomFile.getOwner());
context.setPool(pool = MavenRepositoryUtil.createFrom(resolver, pom, pom.getDependencies()));
Thread.currentThread().setContextClassLoader(context);
} else {
log.warn("Could not find: " + pomFile.getPath().toString("/"));
}
new ClassPackageContext(resolver, context.getPool()).setGlobal();
config.getPoint().setupDefaultURLStreamHandlerFactory(context);
if (log.isDebug()) {
log.debug("Non Package Sources");
for (ClassSource src : context.getNonPackageSources().getAllNonCompositeSources()) {
log.debug(" --> " + src);
}
log.debug("Package Sources");
for (IClassPackage pkg : context.getPool().getPackages(true)) {
log.debug(" --> " + pkg.getDescriptor());
}
this.log.debug("BOOTING MAVEN: " + config.getMainClass() + ": " + System.currentTimeMillis());
}
config.registerExecuted(this);
// Load the main class and invoke it
this.settings.refresh();
if (config.getMainClass() != null)
config.getPoint().boot(ClassCache.getFor(context.loadClass(config.getMainClass())), this);
}
/**
* @return The located pom.xml file, or null if it could not be located
*/
public IVirtualFile locatePOMDescriptor () {
String pomFileName = this.getPackageDescriptor() != null ? this.getPackageDescriptor() : "pom.xml";
IVirtualFile pomFile = VirtualArtifactUtil.getResource(pomFileName);
return pomFile != null && pomFile.isExists() ? pomFile : null;
}
public IClassDependencyPool getDependencyPool() { return pool; }
public IClassPackageResolver getEntryResolver () { return this.resolver; }
}