com.caucho.loader.module.ArtifactManager Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.loader.module;
import java.net.URL;
import java.util.ArrayList;
import com.caucho.config.ConfigException;
import com.caucho.inject.Module;
import com.caucho.loader.EnvironmentApply;
import com.caucho.loader.EnvironmentClassLoader;
import com.caucho.util.L10N;
/**
* A jar artifact in the repository
*/
@Module
public class ArtifactManager
{
private static final L10N L = new L10N(ArtifactManager.class);
private EnvironmentClassLoader _loader;
private ArrayList _dependencyList
= new ArrayList();
private ArrayList _pendingList
= new ArrayList();
private ArrayList _artifactList
= new ArrayList();
private ArrayList _entryList
= new ArrayList();
private ArrayList _loaderList
= new ArrayList();
public ArtifactManager(EnvironmentClassLoader loader)
{
_loader = loader;
}
public void addDependency(ArtifactDependency dependency)
{
ArtifactRepository repository = ArtifactRepository.getCurrent();
if (repository == null) {
throw new ConfigException(L.l("Artifact dependency org='{0}', name='{1}' is not valid because no artifact repositories have been defined",
dependency.getOrg(),
dependency.getName()));
}
ArrayList artifactList = repository.resolve(dependency);
if (artifactList == null || artifactList.size() == 0) {
ArtifactDependency plainDependency
= new ArtifactDependency(dependency.getOrg(),
null,
dependency.getName(),
null);
artifactList = repository.resolve(plainDependency);
throw new ConfigException(L.l("Artifact dependency '{0}', org='{1}', version={2} does not match any jars in the repository. Available artifacts:{3}",
dependency.getName(),
dependency.getOrg(),
dependency.getVersion().toDebugString(),
toArtifactList(artifactList)));
}
_dependencyList.add(dependency);
_pendingList.add(dependency);
}
private String toArtifactList(ArrayList artifactList)
{
StringBuilder sb = new StringBuilder();
for (Artifact artifact : artifactList) {
sb.append("\n ").append(artifact.getName());
sb.append(", org=").append(artifact.getOrg());
if (artifact.getVersion() != null)
sb.append(", version=").append(artifact.getVersion().toDebugString());
}
return sb.toString();
}
public void start()
{
resolve();
}
public Class findImportClass(String name)
{
resolve();
for (int i = 0; i < _entryList.size(); i++) {
Entry entry = _entryList.get(i);
try {
Class cl = entry.getLoader().findClassImpl(name);
if (cl != null)
return cl;
} catch (ClassNotFoundException e) {
}
}
return null;
}
public URL getImportResource(String name)
{
resolve();
return null;
}
public void buildImportClassPath(ArrayList cp)
{
resolve();
for (Entry entry : _entryList) {
entry.getLoader().buildClassPathImpl(cp);
}
}
public void applyVisibleModules(EnvironmentApply apply)
{
resolve();
for (Entry entry : _entryList) {
apply.apply(entry.getLoader());
}
}
private void resolve()
{
synchronized (this) {
if (_pendingList.size() == 0)
return;
ArrayList pendingList
= new ArrayList(_pendingList);
ArtifactRepository repository = ArtifactRepository.getCurrent();
ArrayList newArtifactList = new ArrayList();
for (ArtifactDependency depend : pendingList) {
ArrayList artifacts
= repository.resolve(depend, _dependencyList);
Artifact artifact = artifacts.get(0);
_artifactList.add(artifact);
newArtifactList.add(artifact);
}
for (Artifact artifact : newArtifactList) {
ArrayList createList = new ArrayList();
ArtifactClassLoader loader
= createLoader(_loader.getParent(), artifact,
_artifactList, createList);
_entryList.add(new Entry(artifact, loader));
}
}
// XXX: timing
for (Entry entry : _entryList) {
entry.getLoader().start();
}
}
private ArtifactClassLoader createLoader(ClassLoader parent,
Artifact artifact,
ArrayList artifactList,
ArrayList createList)
{
if (createList.contains(artifact)) {
throw new ConfigException(L.l("Dependency loop detected at {0} while creating artifact {1}",
artifact,
createList.get(0)));
}
createList.add(artifact);
ArtifactRepository repository = ArtifactRepository.getCurrent();
ArrayList importList
= new ArrayList();
ArrayList subArtifactList
= new ArrayList();
ArrayList dependencies
= getArtifactDependencies(artifact);
for (ArtifactDependency depend : dependencies) {
ArrayList artifacts = repository.resolve(depend, dependencies);
if (artifacts.size() == 0) {
throw new ConfigException(L.l("Dependency org={0}, name={1} does not have any matching artifacts",
depend.getOrg(),
depend.getName()));
}
Artifact subArtifact = findArtifact(artifacts.get(0),
artifactList);
subArtifactList.add(subArtifact);
}
for (Artifact subArtifact : subArtifactList) {
importList.add(createLoader(parent, subArtifact,
subArtifactList, createList));
}
createList.remove(artifact);
ArtifactClassLoader loader = findLoader(artifact);
if (loader == null) {
loader = new ArtifactClassLoader(_loader.getParent(),
artifact,
importList);
_loaderList.add(loader);
}
return loader;
}
private ArrayList
getArtifactDependencies(Artifact artifact)
{
ArrayList dependencies
= new ArrayList();
ArtifactDependency parentDep = artifact.getParent();
if (parentDep != null) {
ArtifactRepository repository = ArtifactRepository.getCurrent();
ArrayList parentList = repository.resolve(parentDep);
if (parentList == null || parentList.size() == 0)
throw new ConfigException(L.l("maven parent {0} cannot be resolved",
parentDep));
Artifact parent = parentList.get(0);
dependencies.addAll(getArtifactDependencies(parent));
}
for (ArtifactDependency dep : artifact.getDependencies()) {
dependencies.add(dep);
}
return dependencies;
}
private Artifact findArtifact(Artifact newArtifact,
ArrayList artifactList)
{
for (Artifact artifact : artifactList) {
if (newArtifact.isSameArtifact(artifact))
return artifact;
}
return newArtifact;
}
private ArtifactClassLoader findLoader(Artifact artifact)
{
for (ArtifactClassLoader loader : _loaderList) {
if (loader.getArtifact().equals(artifact))
return loader;
}
return null;
}
@Override
public String toString()
{
return (getClass().getSimpleName() + "[" + _loader + "]");
}
static class Entry {
private Artifact _artifact;
private ArtifactClassLoader _loader;
Entry(Artifact artifact,
ArtifactClassLoader loader)
{
_artifact = artifact;
_loader = loader;
}
ArtifactClassLoader getLoader()
{
return _loader;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy