emptySet());
/**
* Construct a new instance with the given parent class loader, which must be a concurrent class loader, or {@code null}
* to create a root concurrent class loader.
*
* @param parent the parent class loader
*/
protected ConcurrentClassLoader(final ConcurrentClassLoader parent) {
super(parent == null ? ConcurrentClassLoader.class.getClassLoader() : parent);
if (JDK7_PLUS) {
if (getClassLoadingLock("$TEST$") == this) {
throw new Error("Cannot instantiate non-parallel subclass");
}
}
}
/**
* Construct a new instance, using our class loader as the parent.
*/
protected ConcurrentClassLoader() {
super(ConcurrentClassLoader.class.getClassLoader());
if (JDK7_PLUS) {
if (getClassLoadingLock("$TEST$") == this) {
throw new Error("Cannot instantiate non-parallel subclass");
}
}
}
/**
* Loads the class with the specified binary name. Equivalent to calling {@link #loadClass(String, boolean) loadClass(className, false)}.
*
* @param className The binary name of the class
* @return the resulting {@code Class} instance
* @throws ClassNotFoundException if the class was not found
*/
@Override
public final Class> loadClass(final String className) throws ClassNotFoundException {
return performLoadClass(className, false, false);
}
/**
* Loads the class with the specified binary name.
*
* @param className The binary name of the class
* @param resolve {@code true} if the class should be linked after loading
* @return the resulting {@code Class} instance
*/
@Override
public final Class> loadClass(final String className, boolean resolve) throws ClassNotFoundException {
return performLoadClass(className, false, resolve);
}
/**
* Same as {@link #loadClass(String)}, except only exported classes will be considered.
*
* @param className the class name
* @return the class
* @throws ClassNotFoundException if the class isn't found
*/
public final Class> loadExportedClass(final String className) throws ClassNotFoundException {
return performLoadClass(className, true, false);
}
/**
* Same as {@link #loadClass(String,boolean)}, except only exported classes will be considered.
*
* @param className the class name
* @param resolve {@code true} if the class should be linked after loading
* @return the class
* @throws ClassNotFoundException if the class isn't found
*/
public final Class> loadExportedClass(final String className, boolean resolve) throws ClassNotFoundException {
return performLoadClass(className, true, resolve);
}
/**
* Find a class, possibly delegating to other loader(s). This method should never synchronize across a
* delegation method call of any sort. The default implementation always throws {@code ClassNotFoundException}.
*
* If a class is to be defined by this method, it should be done via one of the atomic {@code defineOrLoadClass}
* methods rather than {@code defineClass()} in order to avoid spurious exceptions.
*
* @param className the class name
* @param exportsOnly {@code true} if only exported classes should be considered
* @param resolve {@code true} if the class should be linked after loading
* @return the class
* @throws ClassNotFoundException if the class is not found
*/
protected Class> findClass(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
throw new ClassNotFoundException(className);
}
/**
* Atomically define or load the named class. If the class is already defined, the existing class is returned.
*
* @param className the class name to define or load
* @param bytes the bytes to use to define the class
* @param off the offset into the byte array at which the class bytes begin
* @param len the number of bytes in the class
* @return the class
*/
protected final Class> defineOrLoadClass(final String className, final byte[] bytes, int off, int len) {
try {
final Class> definedClass = defineClass(className, bytes, off, len);
return definedClass;
} catch (LinkageError e) {
final Class> loadedClass = findLoadedClass(className);
if (loadedClass != null) {
return loadedClass;
}
throw e;
}
}
/**
* Atomically define or load the named class. If the class is already defined, the existing class is returned.
*
* @param className the class name to define or load
* @param bytes the bytes to use to define the class
* @param off the offset into the byte array at which the class bytes begin
* @param len the number of bytes in the class
* @param protectionDomain the protection domain for the defined class
* @return the class
*/
protected final Class> defineOrLoadClass(final String className, final byte[] bytes, int off, int len, ProtectionDomain protectionDomain) {
try {
final Class> definedClass = defineClass(className, bytes, off, len, protectionDomain);
return definedClass;
} catch (LinkageError e) {
final Class> loadedClass = findLoadedClass(className);
if (loadedClass != null) {
return loadedClass;
}
throw e;
}
}
/**
* Implementation of {@link ClassLoader#findClass(String)}.
*
* @param className the class name
* @return the result of {@code findClass(className, false, false)}
*/
protected final Class> findClass(final String className) throws ClassNotFoundException {
return findClass(className, false, false);
}
/**
* Finds the resource with the given name. The name of a resource is a {@code '/'}-separated path name that
* identifies the resource. If the resource name starts with {@code "java/"} then the parent class loader is used.
* Otherwise, this method delegates to {@link #findResource(String, boolean)}.
*
* @param name the name of the resource
* @return the resource URL, or {@code null} if no such resource exists or the invoker does not have adequate
* permission to access it
*/
public final URL getResource(final String name) {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
// Whatever loads jboss-modules.jar should have it's classes accessible.
// This could even be the bootclasspath, in which case CL is null, and we prefer the system CL
return definingLoader != null ? definingLoader.getResource(name) : ClassLoader.getSystemResource(name);
}
}
return findResource(name, false);
}
/**
* Finds all available resources with the given name.
*
* @see #getResource(String)
*
* @param name the resource name
* @return an enumeration over all the resource URLs; if no resources could be found, the enumeration will be empty
* @throws IOException if an I/O error occurs
*/
public final Enumeration getResources(final String name) throws IOException {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
return definingLoader != null ? definingLoader.getResources(name) : ClassLoader.getSystemResources(name);
}
}
return findResources(name, false);
}
/**
* Find the resource with the given name and exported status.
*
* @see #getResource(String)
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource URL
*/
protected URL findResource(final String name, final boolean exportsOnly) {
return null;
}
/**
* Never used. {@link ClassLoader#getResource(String)} and related methods can cause a loop condition
* when this method is implemented; use {@link #findResource(String, boolean)} instead.
*
* @param name ignored
* @return {@code null} always
*/
protected final URL findResource(final String name) {
// Always return null so that we don't go into a loop from super.getResource*().
return null;
}
/**
* Finds the resources with the given name and exported status.
*
* @see #getResources(String)
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource enumeration
* @throws IOException if an I/O error occurs
*/
protected Enumeration findResources(final String name, final boolean exportsOnly) throws IOException {
return EMPTY_ENUMERATION;
}
/**
* Never used. {@link ClassLoader#getResources(String)} and related methods can cause a loop condition
* when this method is implemented; use {@link #findResources(String, boolean)} instead. By default, returns
* an empty enumeration.
*
* @param name ignored
* @return an empty enumeration
*/
protected final Enumeration findResources(final String name) {
return EMPTY_ENUMERATION;
}
/**
* Finds the resource with the given name and exported status, returning the resource content as a stream.
*
* @param name the resource name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @return the resource stream, or {@code null} if the resource is not found
*/
protected InputStream findResourceAsStream(final String name, final boolean exportsOnly) {
final URL url = findResource(name, exportsOnly);
try {
return url == null ? null : url.openStream();
} catch (IOException e) {
return null;
}
}
/**
* Returns an input stream for reading the specified resource. If the resource starts with {@code "java/"}, then
* this method delegates to the parent class loader. Otherwise, this method delegates to {@link #findResourceAsStream(String, boolean)}.
*
* @param name the resource name
* @return the resource stream, or {@code null} if the resource is not found
*/
public final InputStream getResourceAsStream(final String name) {
for (String s : Module.systemPaths) {
if (name.startsWith(s)) {
return definingLoader != null ? definingLoader.getResourceAsStream(name) : ClassLoader.getSystemResourceAsStream(name);
}
}
return findResourceAsStream(name, false);
}
// Private members
/**
* Perform a class load operation. If the class is in the package or a subpackage of a package in the system packages list,
* the parent class loader is used to load the class. Otherwise, this method checks to see if the class loader
* object is locked; if so, it unlocks it and submits the request to the class loader thread. Otherwise, it will
* load the class itself by delegating to {@link #findClass(String, boolean, boolean)}.
*
* @param className the class name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @param resolve {@code true} to resolve the loaded class
* @return the class returned by {@link #findClass(String, boolean, boolean)}
* @throws ClassNotFoundException if {@link #findClass(String, boolean, boolean)} throws this exception
*/
private Class> performLoadClass(String className, boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
if (className == null) {
throw new IllegalArgumentException("name is null");
}
for (String s : Module.systemPackages) {
if (className.startsWith(s)) {
return definingLoader != null ? definingLoader.loadClass(className) : findSystemClass(className);
}
}
return performLoadClassChecked(className, exportsOnly, resolve);
}
/**
* Perform a class load operation. This method checks to see if the class loader object is locked; if so, it
* unlocks it and submits the request to the class loader thread. Otherwise, it will load the class itself by
* delegating to {@link #findClass(String, boolean, boolean)}.
*
* If the {@code jboss.modules.unsafe-locks} system property is set to {@code true}, then rather than using the
* class loading thread, the lock is forcibly broken and the load retried.
*
* @param className the class name
* @param exportsOnly {@code true} to consider only exported resources or {@code false} to consider all resources
* @param resolve {@code true} to resolve the loaded class
* @return the class returned by {@link #findClass(String, boolean, boolean)}
* @throws ClassNotFoundException if {@link #findClass(String, boolean, boolean)} throws this exception
*/
private Class> performLoadClassChecked(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
if (SAFE_JDK) {
return performLoadClassUnchecked(className, exportsOnly, resolve);
} else if (Thread.holdsLock(this)) {
if (LOCKLESS) {
final Unsafe unsafe = UnsafeHolder.UNSAFE;
unsafe.monitorExit(this);
try {
return performLoadClassChecked(className, exportsOnly, resolve);
} finally {
unsafe.monitorEnter(this);
}
}
if (Thread.currentThread() != LoaderThreadHolder.LOADER_THREAD) {
// Only the classloader thread may take this lock; use a condition to relinquish it
final LoadRequest req = new LoadRequest(className, resolve, exportsOnly, this, AccessController.getContext());
final Queue queue = LoaderThreadHolder.REQUEST_QUEUE;
synchronized (queue) {
queue.add(req);
queue.notify();
}
boolean intr = false;
try {
while (!req.done) try {
wait();
} catch (InterruptedException e) {
intr = true;
}
} finally {
if (intr) Thread.currentThread().interrupt();
}
final Class> result = req.result;
if (result == null) {
final String message = req.message;
throw new ClassNotFoundException(message == null ? className : message);
}
return result;
}
}
// no deadlock risk! Either the lock isn't held, or we're inside the class loader thread.
return performLoadClassUnchecked(className, exportsOnly, resolve);
}
private Class> performLoadClassUnchecked(final String className, final boolean exportsOnly, final boolean resolve) throws ClassNotFoundException {
if (className.charAt(0) == '[') {
// Use Class.forName to load the array type
final Class> array = Class.forName(className, false, this);
if (resolve) {
resolveClass(array);
}
return array;
}
return findClass(className, exportsOnly, resolve);
}
private final UnlockedReadHashMap packages = new UnlockedReadHashMap(64);
/**
* Load a package which is visible to this class loader.
*
* @param name the package name
* @return the package, or {@code null} if no such package is visible to this class loader
*/
protected final Package getPackage(final String name) {
final String packageName = name + ".";
for (String s : Module.systemPackages) {
if (packageName.startsWith(s)) {
return Package.getPackage(name);
}
}
if (GET_PACKAGE_SUPPRESSOR.get() == Boolean.TRUE) {
return null;
}
return getPackageByName(name);
}
/**
* Perform the actual work to load a package which is visible to this class loader. By default, uses a simple
* parent-first delegation strategy.
*
* @param name the package name
* @return the package, or {@code null} if no such package is visible to this class loader
*/
protected Package getPackageByName(final String name) {
final Package parentPackage = super.getPackage(name);
return parentPackage == null ? findLoadedPackage(name) : parentPackage;
}
/**
* Get all defined packages which are visible to this class loader.
*
* @return the packages
*/
protected Package[] getPackages() {
ArrayList list = new ArrayList();
list.addAll(packages.values());
list.addAll(Arrays.asList(super.getPackages()));
return list.toArray(new Package[list.size()]);
}
/**
* Load a package from this class loader only.
*
* @param name the package name
* @return the package or {@code null} if no such package is defined by this class loader
*/
protected final Package findLoadedPackage(final String name) {
return packages.get(name);
}
/**
* Defines a package by name in this ConcurrentClassLoader. If the package was already defined, the
* existing package is returned instead.
*
* @param name the package name
* @param specTitle the specification title
* @param specVersion the specification version
* @param specVendor the specification vendor
* @param implTitle the implementation title
* @param implVersion the implementation version
* @param implVendor the implementation vendor
* @param sealBase if not {@code null}, then this package is sealed with respect to the given code source URL
*
* @return the newly defined package, or the existing one if one was already defined
*/
protected Package definePackage(final String name, final String specTitle, final String specVersion, final String specVendor, final String implTitle, final String implVersion, final String implVendor, final URL sealBase) throws IllegalArgumentException {
ThreadLocal suppressor = GET_PACKAGE_SUPPRESSOR;
suppressor.set(Boolean.TRUE);
try {
Package existing = packages.get(name);
if (existing != null) {
return existing;
}
Package pkg = super.definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
existing = packages.putIfAbsent(name, pkg);
return existing != null ? existing : pkg;
} finally {
suppressor.remove();
}
}
static final class LoaderThreadHolder {
static final Thread LOADER_THREAD;
static final Queue REQUEST_QUEUE = new ArrayDeque();
static {
Thread thr = new LoaderThread();
thr.setName("ClassLoader Thread");
// This thread will always run as long as the VM is alive.
thr.setDaemon(true);
thr.start();
LOADER_THREAD = thr;
}
private LoaderThreadHolder() {
}
}
static class LoadRequest {
private final String className;
private final boolean resolve;
private final ConcurrentClassLoader requester;
private final AccessControlContext context;
Class> result;
String message;
private boolean exportsOnly;
boolean done;
LoadRequest(final String className, final boolean resolve, final boolean exportsOnly, final ConcurrentClassLoader requester, final AccessControlContext context) {
this.className = className;
this.resolve = resolve;
this.exportsOnly = exportsOnly;
this.requester = requester;
this.context = context;
}
}
static class LoaderThread extends Thread {
@Override
public void interrupt() {
// no interruption
}
@Override
public void run() {
final Queue queue = LoaderThreadHolder.REQUEST_QUEUE;
for (; ;) {
try {
LoadRequest request;
synchronized (queue) {
while ((request = queue.poll()) == null) {
queue.wait();
}
}
final ConcurrentClassLoader loader = request.requester;
Class> result = null;
synchronized (loader) {
try {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
final LoadRequest localRequest = request;
result = AccessController.doPrivileged(new PrivilegedExceptionAction>() {
public Class> run() throws ClassNotFoundException {
return loader.performLoadClassChecked(localRequest.className, localRequest.exportsOnly, localRequest.resolve);
}
}, request.context);
} else try {
result = loader.performLoadClassChecked(request.className, request.exportsOnly, request.resolve);
} catch (ClassNotFoundException e) {
request.message = e.getMessage();
}
} finally {
// no matter what, the requester MUST be notified
request.result = result;
request.done = true;
loader.notifyAll();
}
}
} catch (Throwable t) {
// ignore
}
}
}
}
private static final class UnsafeHolder {
static Unsafe UNSAFE;
static {
try {
final Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
UNSAFE = (Unsafe) field.get(null);
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (NoSuchFieldException e) {
throw new NoSuchFieldError(e.getMessage());
}
}
private UnsafeHolder() {
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DefaultBootModuleLoaderHolder.java 0000664 0000000 0000000 00000004543 12572057235 0032075 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
final class DefaultBootModuleLoaderHolder {
static final ModuleLoader INSTANCE;
private DefaultBootModuleLoaderHolder() {
}
static {
INSTANCE = AccessController.doPrivileged(new PrivilegedAction() {
public ModuleLoader run() {
final String loaderClass = System.getProperty("boot.module.loader", LocalModuleLoader.class.getName());
try {
return Class.forName(loaderClass, true, DefaultBootModuleLoaderHolder.class.getClassLoader()).asSubclass(ModuleLoader.class).getConstructor().newInstance();
} catch (InstantiationException e) {
throw new InstantiationError(e.getMessage());
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InvocationTargetException e) {
try {
throw e.getCause();
} catch (RuntimeException cause) {
throw cause;
} catch (Error cause) {
throw cause;
} catch (Throwable t) {
throw new Error(t);
}
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.getMessage());
}
}
});
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Dependency.java 0000664 0000000 0000000 00000007514 12572057235 0026311 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency item.
*
* @author John Bailey
* @author David M. Lloyd
*/
abstract class Dependency {
private final PathFilter exportFilter;
private final PathFilter importFilter;
private final PathFilter resourceExportFilter;
private final PathFilter resourceImportFilter;
private final ClassFilter classExportFilter;
private final ClassFilter classImportFilter;
Dependency(final PathFilter exportFilter, final PathFilter importFilter) {
this(exportFilter, importFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll());
}
protected Dependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter) {
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
this.exportFilter = exportFilter;
this.importFilter = importFilter;
this.resourceExportFilter = resourceExportFilter;
this.resourceImportFilter = resourceImportFilter;
this.classExportFilter = classExportFilter;
this.classImportFilter = classImportFilter;
}
/**
* Get the export filter for this dependency. This filter determines what imported paths are re-exported by this
* dependency. All exported paths must also satisfy the import filter.
*
* @return the export filter
*/
final PathFilter getExportFilter() {
return exportFilter;
}
/**
* Get the import filter for this dependency. This filter determines what exported paths are imported from the
* dependency to the dependent.
*
* @return the import filter
*/
final PathFilter getImportFilter() {
return importFilter;
}
final PathFilter getResourceExportFilter() {
return resourceExportFilter;
}
final PathFilter getResourceImportFilter() {
return resourceImportFilter;
}
final ClassFilter getClassExportFilter() {
return classExportFilter;
}
final ClassFilter getClassImportFilter() {
return classImportFilter;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DependencySpec.java 0000664 0000000 0000000 00000053231 12572057235 0027121 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency specification that represents a single dependency for a module. The dependency can be on a local loader
* or another module, or on the target module's local loader.
*
* @apiviz.exclude
*
* @author David M. Lloyd
* @author John Bailey
* @author Jason T. Greene
*/
public abstract class DependencySpec {
final PathFilter importFilter;
final PathFilter exportFilter;
final PathFilter resourceImportFilter;
final PathFilter resourceExportFilter;
final ClassFilter classImportFilter;
final ClassFilter classExportFilter;
/**
* Get the dependency import filter.
*
* @return the import filter
*/
public PathFilter getImportFilter() {
return importFilter;
}
/**
* Get the dependency export filter.
*
* @return the export filter
*/
public PathFilter getExportFilter() {
return exportFilter;
}
/**
* Get the dependency resource import filter.
*
* @return the import filter
*/
public PathFilter getResourceImportFilter() {
return resourceImportFilter;
}
/**
* Get the dependency resource export filter.
*
* @return the export filter
*/
public PathFilter getResourceExportFilter() {
return resourceExportFilter;
}
/**
* Get the dependency class import filter.
*
* @return the class import filter
*/
public ClassFilter getClassImportFilter() {
return classImportFilter;
}
/**
* Get the dependency class export filter.
*
* @return the class export filter
*/
public ClassFilter getClassExportFilter() {
return classExportFilter;
}
DependencySpec(final PathFilter importFilter, final PathFilter exportFilter) {
this(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll());
}
DependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) {
this.importFilter = importFilter;
this.exportFilter = exportFilter;
this.resourceImportFilter = resourceImportFilter;
this.resourceExportFilter = resourceExportFilter;
this.classImportFilter = classImportFilter;
this.classExportFilter = classExportFilter;
}
abstract Dependency getDependency(final Module module);
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources.
*
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec() {
return createLocalDependencySpec(PathFilters.acceptAll(), PathFilters.acceptAll());
}
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter) {
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
return new DependencySpec(importFilter, exportFilter) {
Dependency getDependency(final Module module) {
return new ModuleClassLoaderDependency(exportFilter, importFilter, module.getClassLoaderPrivate());
}
public String toString() {
return "dependency on local resources";
}
};
}
/**
* Create a dependency on the current module's local resources. You should have at least one such dependency
* on any module which has its own resources.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter) {
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
return new DependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter) {
Dependency getDependency(final Module module) {
return new ModuleClassLoaderDependency(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter, module.getClassLoaderPrivate());
}
public String toString() {
return "dependency on filtered local resources";
}
};
}
/**
* Create a system dependency.
*
* @param loaderPaths the set of paths to use from the system class loader
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final Set loaderPaths) {
return createLocalDependencySpec(ClassLoaderLocalLoader.SYSTEM, loaderPaths);
}
/**
* Create a system dependency.
*
* @param loaderPaths the set of paths to use from the system class loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final Set loaderPaths, boolean export) {
return createLocalDependencySpec(ClassLoaderLocalLoader.SYSTEM, loaderPaths, export);
}
/**
* Create a system dependency.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param loaderPaths the set of paths to use from the system class loader
* @return the dependency spec
*/
public static DependencySpec createSystemDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final Set loaderPaths) {
return createLocalDependencySpec(importFilter, exportFilter, ClassLoaderLocalLoader.SYSTEM, loaderPaths);
}
/**
* Create a dependency on the given class loader.
*
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @return the dependency spec
*/
public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths) {
return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths);
}
/**
* Create a dependency on the given class loader.
*
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*/
public static DependencySpec createClassLoaderDependencySpec(final ClassLoader classLoader, final Set loaderPaths, boolean export) {
return createLocalDependencySpec(new ClassLoaderLocalLoader(classLoader), loaderPaths, export);
}
/**
* Create a dependency on the given class loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param classLoader the class loader
* @param loaderPaths the set of paths to use from this class loader
* @return the dependency spec
*/
public static DependencySpec createClassLoaderDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ClassLoader classLoader, final Set loaderPaths) {
return createLocalDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), new ClassLoaderLocalLoader(classLoader), loaderPaths);
}
/**
* Create a dependency on the given local loader.
*
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths) {
return createLocalDependencySpec(PathFilters.acceptAll(), PathFilters.rejectAll(), localLoader, loaderPaths);
}
/**
* Create a dependency on the given local loader.
*
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final LocalLoader localLoader, final Set loaderPaths, boolean export) {
return createLocalDependencySpec(PathFilters.acceptAll(), export ? PathFilters.getDefaultImportFilter() : PathFilters.rejectAll(), localLoader, loaderPaths);
}
/**
* Create a dependency on the given local loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final LocalLoader localLoader, final Set loaderPaths) {
return createLocalDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), localLoader, loaderPaths);
}
/**
* Create a dependency on the given local loader.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @param localLoader the local loader
* @param loaderPaths the set of paths that is exposed by the local loader
* @return the dependency spec
*/
public static DependencySpec createLocalDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final LocalLoader localLoader, final Set loaderPaths) {
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
if (localLoader == null) {
throw new IllegalArgumentException("localLoader is null");
}
if (loaderPaths == null) {
throw new IllegalArgumentException("loaderPaths is null");
}
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
return new DependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter) {
Dependency getDependency(final Module module) {
return new LocalDependency(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter, localLoader, loaderPaths);
}
public String toString() {
return "dependency on local loader " + localLoader;
}
};
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier) {
return createModuleDependencySpec(identifier, false);
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @param export {@code true} if the dependency should be exported by default
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export) {
return createModuleDependencySpec(identifier, export, false);
}
/**
* Create a dependency on the given module.
*
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final ModuleIdentifier identifier, final boolean export, final boolean optional) {
return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), null, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export) {
return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), moduleLoader, identifier, false);
}
/**
* Create a dependency on the given module.
*
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param export {@code true} if this is a fully re-exported dependency, {@code false} if it should not be exported
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean export, final boolean optional) {
return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), export ? PathFilters.acceptAll() : PathFilters.rejectAll(), moduleLoader, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), exportFilter, null, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(PathFilters.getDefaultImportFilter(), exportFilter, moduleLoader, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
return createModuleDependencySpec(importFilter, exportFilter, PathFilters.acceptAll(), PathFilters.acceptAll(), ClassFilters.acceptAll(), ClassFilters.acceptAll(), moduleLoader, identifier, optional);
}
/**
* Create a dependency on the given module.
*
* @param importFilter the import filter to apply
* @param exportFilter the export filter to apply
* @param resourceImportFilter the resource import filter to apply
* @param resourceExportFilter the resource export filter to apply
* @param classImportFilter the class import filter to apply
* @param classExportFilter the class export filter to apply
* @param moduleLoader the specific module loader from which the module should be acquired
* @param identifier the module identifier
* @param optional {@code true} if the dependency is optional, {@code false} if it is mandatory
* @return the dependency spec
*/
public static DependencySpec createModuleDependencySpec(final PathFilter importFilter, final PathFilter exportFilter, final PathFilter resourceImportFilter, final PathFilter resourceExportFilter, final ClassFilter classImportFilter, final ClassFilter classExportFilter, final ModuleLoader moduleLoader, final ModuleIdentifier identifier, final boolean optional) {
if (importFilter == null) {
throw new IllegalArgumentException("importFilter is null");
}
if (exportFilter == null) {
throw new IllegalArgumentException("exportFilter is null");
}
if (identifier == null) {
throw new IllegalArgumentException("identifier is null");
}
if (classImportFilter == null) {
throw new IllegalArgumentException("classImportFilter is null");
}
if (classExportFilter == null) {
throw new IllegalArgumentException("classExportFilter is null");
}
if (resourceImportFilter == null) {
throw new IllegalArgumentException("resourceImportFilter is null");
}
if (resourceExportFilter == null) {
throw new IllegalArgumentException("resourceExportFilter is null");
}
return new ModuleDependencySpec(importFilter, exportFilter, resourceImportFilter, resourceExportFilter, classImportFilter, classExportFilter, moduleLoader, identifier, optional);
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/DependencyTreeViewer.java 0000664 0000000 0000000 00000012173 12572057235 0030310 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A dependency tree viewer utility. Prints out the dependency tree for a module.
*/
public final class DependencyTreeViewer {
private static O[] filtered(Class oType, I... inputs) {
final I[] newArray = Arrays.copyOf(inputs, inputs.length);
int o = 0;
for (int i = 0; i < inputs.length; i ++) {
if (oType.getComponentType().isInstance(inputs[i])) {
newArray[o++] = (O) inputs[i];
}
}
return Arrays.copyOf(newArray, o, oType);
}
private static void print(PrintWriter out, String prefix, ModuleSpec spec, FastCopyHashSet visited, File... roots) {
if (spec instanceof AliasModuleSpec) {
final AliasModuleSpec aliasModuleSpec = (AliasModuleSpec) spec;
out.print(" -> ");
final ModuleIdentifier aliasTarget = aliasModuleSpec.getAliasTarget();
out.println(aliasTarget);
if (visited.add(aliasTarget)) {
try {
final ModuleSpec moduleSpec = LocalModuleFinder.parseModuleXmlFile(aliasTarget, null, roots);
print(out, prefix, moduleSpec, visited);
} catch (IOException e) {
out.println(e);
} catch (ModuleLoadException e) {
out.println(e);
}
}
} else if (spec instanceof ConcreteModuleSpec) {
out.println();
final ConcreteModuleSpec concreteModuleSpec = (ConcreteModuleSpec) spec;
final DependencySpec[] dependencies = filtered(ModuleDependencySpec[].class, concreteModuleSpec.getDependencies());
for (int i = 0, dependenciesLength = dependencies.length; i < dependenciesLength; i++) {
print(out, prefix, dependencies[i], visited, i == dependenciesLength - 1, roots);
}
} else {
out.println();
}
}
private static void print(PrintWriter out, String prefix, DependencySpec spec, FastCopyHashSet visited, final boolean last, final File... roots) {
if (spec instanceof ModuleDependencySpec) {
final ModuleDependencySpec moduleDependencySpec = (ModuleDependencySpec) spec;
final ModuleIdentifier identifier = moduleDependencySpec.getIdentifier();
out.print(prefix);
out.print(last ? '└' : '├');
out.print('─');
out.print(' ');
out.print(identifier);
if (moduleDependencySpec.isOptional()) {
out.print(" (optional)");
}
final PathFilter exportFilter = moduleDependencySpec.getExportFilter();
if (! exportFilter.equals(PathFilters.rejectAll())) {
out.print(" (exported)");
}
if (visited.add(identifier)) {
print(out, prefix + (last ? " " : "│ "), identifier, visited, roots);
} else {
out.println();
}
}
}
private static void print(PrintWriter out, String prefix, ModuleIdentifier identifier, FastCopyHashSet visited, final File... roots) {
final ModuleSpec moduleSpec;
try {
moduleSpec = LocalModuleFinder.parseModuleXmlFile(identifier, null, roots);
if (moduleSpec == null) {
out.println(" (not found)");
} else {
print(out, prefix, moduleSpec, visited, roots);
}
} catch (IOException e) {
out.print(" (");
out.print(e);
out.println(")");
} catch (ModuleLoadException e) {
out.print(" (");
out.print(e);
out.println(")");
}
}
/**
* Print the dependency tree for the given module with the given module root list.
*
* @param out the output stream to use
* @param identifier the identifier of the module to examine
* @param roots the module roots to search
*/
public static void print(PrintWriter out, ModuleIdentifier identifier, final File... roots) {
out.print(identifier);
print(out, "", identifier, new FastCopyHashSet(), roots);
out.flush();
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FastCopyHashSet.java 0000664 0000000 0000000 00000037313 12572057235 0027243 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* A HashSet that is optimized for fast shallow copies. If the copy-ctor is
* passed another FastCopyHashSet, or clone is called on this set, the shallow
* copy can be performed using little more than a single array copy. In order to
* accomplish this, immutable objects must be used internally, so update
* operations result in slightly more object churn than HashSet
.
*
* Note: It is very important to use a smaller load factor than you normally
* would for HashSet, since the implementation is open-addressed with linear
* probing. With a 50% load-factor a get is expected to return in only 2 probes.
* However, a 90% load-factor is expected to return in around 50 probes.
*
* @author Jason T. Greene
* @author David M. Lloyd
*/
class FastCopyHashSet extends AbstractSet implements Set, Cloneable, Serializable {
/**
* Serialization ID
*/
private static final long serialVersionUID = 10929568968762L;
/**
* Same default as HashMap, must be a power of 2
*/
private static final int DEFAULT_CAPACITY = 64;
/**
* MAX_INT - 1
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 50%
*/
private static final float DEFAULT_LOAD_FACTOR = 0x0.5p0f;
/**
* The open-addressed table
*/
private transient E[] table;
/**
* The current number of key-value pairs
*/
private transient int size;
/**
* The next resize
*/
private transient int threshold;
/**
* The user defined load factor which defines when to resize
*/
private final float loadFactor;
/**
* Counter used to detect changes made outside of an iterator
*/
private transient int modCount;
/**
* Accumulated hash code
*/
private transient int hashCode;
public FastCopyHashSet(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Can not have a negative size table!");
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (!(loadFactor > 0F && loadFactor <= 1F))
throw new IllegalArgumentException("Load factor must be greater than 0 and less than or equal to 1");
this.loadFactor = loadFactor;
init(initialCapacity, loadFactor);
}
public FastCopyHashSet(Set extends E> set) {
if (set instanceof FastCopyHashSet) {
FastCopyHashSet extends E> fast = (FastCopyHashSet extends E>) set;
table = fast.table.clone();
loadFactor = fast.loadFactor;
size = fast.size;
threshold = fast.threshold;
hashCode = fast.hashCode;
} else {
loadFactor = DEFAULT_LOAD_FACTOR;
init(set.size(), loadFactor);
addAll(set);
}
}
@SuppressWarnings("unchecked")
private void init(int initialCapacity, float loadFactor) {
int c = 1;
while (c < initialCapacity) c <<= 1;
threshold = (int) (c * loadFactor);
// Include the load factor when sizing the table for the first time
if (initialCapacity > threshold && c < MAXIMUM_CAPACITY) {
c <<= 1;
threshold = (int) (c * loadFactor);
}
table = (E[]) new Object[c];
}
public FastCopyHashSet(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public FastCopyHashSet() {
this(DEFAULT_CAPACITY);
}
private int nextIndex(int index, int length) {
index = (index >= length - 1) ? 0 : index + 1;
return index;
}
private static int index(int hashCode, int length) {
return hashCode & (length - 1);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object key) {
if (key == null) {
return false;
}
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
for (int start = index; ;) {
E e = table[index];
if (e == null)
return false;
if (key.equals(e))
return true;
index = nextIndex(index, length);
if (index == start) // Full table
return false;
}
}
public boolean add(E key) {
if (key == null) {
throw new IllegalArgumentException("key is null");
}
E[] table = this.table;
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
boolean f = false;
for (int start = index; ;) {
E e = table[index];
if (e == null)
break;
if (! f) {
f= true;
}
if (key.equals(e)) {
return false;
}
index = nextIndex(index, length);
if (index == start)
throw new IllegalStateException("Table is full!");
}
modCount++;
table[index] = key;
hashCode += key.hashCode();
if (++size >= threshold)
resize(length);
return true;
}
@SuppressWarnings("unchecked")
private void resize(int from) {
int newLength = from << 1;
// Can't get any bigger
if (newLength > MAXIMUM_CAPACITY || newLength <= from)
return;
E[] newTable = (E[]) new Object[newLength];
E[] old = table;
for (E e : old) {
if (e == null)
continue;
int index = index(e.hashCode(), newLength);
while (newTable[index] != null)
index = nextIndex(index, newLength);
newTable[index] = e;
}
threshold = (int) (loadFactor * newLength);
table = newTable;
}
public boolean addAll(Collection extends E> set) {
int size = set.size();
if (size == 0)
return false;
boolean changed = false;
for (E e : set) {
if (add(e)) {
changed = true;
}
}
return changed;
}
public boolean remove(Object key) {
E[] table = this.table;
int length = table.length;
int hash = key.hashCode();
int start = index(hash, length);
for (int index = start; ;) {
E e = table[index];
if (e == null)
return false;
if (key.equals(e)) {
table[index] = null;
hashCode -= hash;
relocate(index);
modCount++;
size--;
return true;
}
index = nextIndex(index, length);
if (index == start)
return false;
}
}
private void relocate(int start) {
E[] table = this.table;
int length = table.length;
int current = nextIndex(start, length);
for (; ;) {
E e = table[current];
if (e == null)
return;
// A Doug Lea variant of Knuth's Section 6.4 Algorithm R.
// This provides a non-recursive method of relocating
// entries to their optimal positions once a gap is created.
int prefer = index(e.hashCode(), length);
if ((current < prefer && (prefer <= start || start <= current))
|| (prefer <= start && start <= current)) {
table[start] = e;
table[current] = null;
start = current;
}
current = nextIndex(current, length);
}
}
public void clear() {
modCount++;
E[] table = this.table;
for (int i = 0; i < table.length; i++)
table[i] = null;
size = hashCode = 0;
}
@SuppressWarnings("unchecked")
public FastCopyHashSet clone() {
try {
FastCopyHashSet clone = (FastCopyHashSet) super.clone();
clone.table = table.clone();
return clone;
}
catch (CloneNotSupportedException e) {
// should never happen
throw new IllegalStateException(e);
}
}
public Iterator iterator() {
return new KeyIterator();
}
public void printDebugStats() {
int optimal = 0;
int total = 0;
int totalSkew = 0;
int maxSkew = 0;
for (int i = 0; i < table.length; i++) {
E e = table[i];
if (e != null) {
total++;
int target = index(e.hashCode(), table.length);
if (i == target)
optimal++;
else {
int skew = Math.abs(i - target);
if (skew > maxSkew) maxSkew = skew;
totalSkew += skew;
}
}
}
System.out.println(" Size: " + size);
System.out.println(" Real Size: " + total);
System.out.println(" Optimal: " + optimal + " (" + (float) optimal * 100 / total + "%)");
System.out.println(" Average Distance: " + ((float) totalSkew / (total - optimal)));
System.out.println(" Max Distance: " + maxSkew);
}
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
int size = s.readInt();
init(size, loadFactor);
for (int i = 0; i < size; i++) {
E key = (E) s.readObject();
putForCreate(key);
}
this.size = size;
}
@SuppressWarnings("unchecked")
private void putForCreate(E key) {
E[] table = this.table;
int hash = key.hashCode();
int length = table.length;
int index = index(hash, length);
E e = table[index];
while (e != null) {
index = nextIndex(index, length);
e = table[index];
}
table[index] = key;
}
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeInt(size);
for (E e : table) {
if (e != null) {
s.writeObject(e);
}
}
}
public boolean containsAll(final Collection> c) {
final E[] table = this.table;
for (E e : table) {
if (e != null) {
if (! c.contains(e)) {
return false;
}
}
}
return true;
}
@SuppressWarnings("NonFinalFieldReferenceInEquals")
public boolean equals(final Object o) {
if (o == this)
return true;
if (! (o instanceof Set))
return false;
if (o instanceof FastCopyHashSet) {
final FastCopyHashSet> set = (FastCopyHashSet>) o;
if (hashCode != set.hashCode) {
return false;
}
if (table.length == set.table.length) {
return Arrays.equals(table, set.table);
}
}
Set> set = (Set>) o;
if (set.size() != size())
return false;
try {
return containsAll(set);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
@SuppressWarnings("NonFinalFieldReferencedInHashCode")
public int hashCode() {
return hashCode;
}
public Object[] getRawArray() {
return table;
}
private class KeyIterator implements Iterator {
private int next = 0;
private int expectedCount = modCount;
private int current = -1;
private boolean hasNext;
private E[] table = FastCopyHashSet.this.table;
public E next() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
if (!hasNext && !hasNext())
throw new NoSuchElementException();
current = next++;
hasNext = false;
return table[current];
}
public boolean hasNext() {
if (hasNext == true)
return true;
E[] table = this.table;
for (int i = next; i < table.length; i++) {
if (table[i] != null) {
next = i;
return hasNext = true;
}
}
next = table.length;
return false;
}
@SuppressWarnings("unchecked")
public void remove() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
int current = this.current;
int delete = current;
if (current == -1)
throw new IllegalStateException();
// Invalidate current (prevents multiple remove)
this.current = -1;
// Start were we relocate
next = delete;
E[] table = this.table;
if (table != FastCopyHashSet.this.table) {
FastCopyHashSet.this.remove(table[delete]);
table[delete] = null;
expectedCount = modCount;
return;
}
int length = table.length;
int i = delete;
table[delete] = null;
size--;
for (; ;) {
i = nextIndex(i, length);
E e = table[i];
if (e == null)
break;
int prefer = index(e.hashCode(), length);
if ((i < prefer && (prefer <= delete || delete <= i))
|| (prefer <= delete && delete <= i)) {
// Snapshot the unseen portion of the table if we have
// to relocate an entry that was already seen by this iterator
if (i < current && current <= delete && table == FastCopyHashSet.this.table) {
int remaining = length - current;
E[] newTable = (E[]) new Object[remaining];
System.arraycopy(table, current, newTable, 0, remaining);
// Replace iterator's table.
// Leave table local var pointing to the real table
this.table = newTable;
next = 0;
}
// Do the swap on the real table
table[delete] = e;
table[i] = null;
delete = i;
}
}
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FileEntryResource.java 0000664 0000000 0000000 00000006043 12572057235 0027640 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import static java.security.AccessController.doPrivileged;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
/**
* A file entry resource.
*
* @author David M. Lloyd
*/
final class FileEntryResource implements Resource {
private final String name;
private final File file;
private final URL url;
private final AccessControlContext context;
FileEntryResource(final String name, final File file, final URL url, final AccessControlContext context) {
this.name = name;
this.file = file;
this.url = url;
this.context = context;
}
public long getSize() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
return doPrivileged(new PrivilegedAction() {
public Long run() {
return Long.valueOf(file.length());
}
}, context).longValue();
} else {
return file.length();
}
}
public String getName() {
return name;
}
public URL getURL() {
return url;
}
public InputStream openStream() throws IOException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
return doPrivileged(new PrivilegedExceptionAction() {
public FileInputStream run() throws IOException {
return new FileInputStream(file);
}
}, context);
} catch (PrivilegedActionException e) {
try {
throw e.getException();
} catch (RuntimeException e1) {
throw e1;
} catch (IOException e1) {
throw e1;
} catch (Exception e1) {
throw new UndeclaredThrowableException(e1);
}
}
} else {
return new FileInputStream(file);
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FileResourceLoader.java 0000664 0000000 0000000 00000032166 12572057235 0027752 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import static java.security.AccessController.doPrivileged;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.jar.Manifest;
/**
*
* @author David M. Lloyd
*/
final class FileResourceLoader extends NativeLibraryResourceLoader implements IterableResourceLoader {
private final String rootName;
private final Manifest manifest;
private final CodeSource codeSource;
private final AccessControlContext context;
FileResourceLoader(final String rootName, final File root, final AccessControlContext context) {
super(root);
if (root == null) {
throw new IllegalArgumentException("root is null");
}
if (rootName == null) {
throw new IllegalArgumentException("rootName is null");
}
if (context == null) {
throw new IllegalArgumentException("context is null");
}
this.rootName = rootName;
final File manifestFile = new File(root, "META-INF" + File.separatorChar + "MANIFEST.MF");
manifest = readManifestFile(manifestFile);
final URL rootUrl;
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
rootUrl = doPrivileged(new PrivilegedAction() {
public URL run() {
try {
return root.getAbsoluteFile().toURI().toURL();
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
}
}
}, context);
} else try {
rootUrl = root.getAbsoluteFile().toURI().toURL();
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
}
this.context = context;
codeSource = new CodeSource(rootUrl, (CodeSigner[])null);
}
private static Manifest readManifestFile(final File manifestFile) {
try {
return manifestFile.exists() ? new Manifest(new FileInputStream(manifestFile)) : null;
} catch (IOException e) {
return null;
}
}
public String getRootName() {
return rootName;
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
return doPrivileged(new PrivilegedExceptionAction() {
public ClassSpec run() throws IOException {
return doGetClassSpec(fileName);
}
}, context);
} catch (PrivilegedActionException e) {
try {
throw e.getException();
} catch (IOException e1) {
throw e1;
} catch (RuntimeException e1) {
throw e1;
} catch (Exception e1) {
throw new UndeclaredThrowableException(e1);
}
}
} else {
return doGetClassSpec(fileName);
}
}
private ClassSpec doGetClassSpec(final String fileName) throws IOException {
final File file = new File(getRoot(), fileName);
if (! file.exists()) {
return null;
}
final long size = file.length();
final ClassSpec spec = new ClassSpec();
spec.setCodeSource(codeSource);
final InputStream is = new FileInputStream(file);
try {
if (size <= (long) Integer.MAX_VALUE) {
final int castSize = (int) size;
byte[] bytes = new byte[castSize];
int a = 0, res;
while ((res = is.read(bytes, a, castSize - a)) > 0) {
a += res;
}
// done
is.close();
spec.setBytes(bytes);
return spec;
} else {
throw new IOException("Resource is too large to be a valid class file");
}
} finally {
StreamUtil.safeClose(is);
}
}
public PackageSpec getPackageSpec(final String name) throws IOException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
try {
return doPrivileged(new PrivilegedExceptionAction() {
public PackageSpec run() throws IOException {
return getPackageSpec(name, manifest, getRoot().toURI().toURL());
}
}, context);
} catch (PrivilegedActionException e) {
try {
throw e.getException();
} catch (IOException e1) {
throw e1;
} catch (RuntimeException e1) {
throw e1;
} catch (Exception e1) {
throw new UndeclaredThrowableException(e1);
}
}
} else {
return getPackageSpec(name, manifest, getRoot().toURI().toURL());
}
}
public Resource getResource(final String name) {
final String canonPath = PathUtils.canonicalize(PathUtils.relativize(name));
final File file = new File(getRoot(), canonPath);
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
return doPrivileged(new PrivilegedAction() {
public Resource run() {
if (!file.exists()) {
return null;
} else {
try {
return new FileEntryResource(canonPath, file, file.toURI().toURL(), context);
} catch (MalformedURLException e) {
return null;
}
}
}
}, context);
} else if (! file.exists()) {
return null;
} else {
try {
return new FileEntryResource(canonPath, file, file.toURI().toURL(), context);
} catch (MalformedURLException e) {
return null;
}
}
}
class Itr implements Iterator {
private final String base;
private final String[] names;
private final boolean recursive;
private int i = 0;
private Itr nested;
private Resource next;
Itr(final String base, final String[] names, final boolean recursive) {
assert PathUtils.isRelative(base);
assert names != null && names.length > 0;
this.base = base;
this.names = names;
this.recursive = recursive;
}
public boolean hasNext() {
final String[] names = this.names;
if (next != null) {
return true;
}
final String base = this.base;
while (i < names.length) {
final String current = names[i];
final String full = base.isEmpty() ? current : base + "/" + current;
final File file = new File(getRoot(), full);
if (recursive && nested == null) {
final String[] children = file.list();
if (children != null && children.length > 0) {
nested = new Itr(full, children, recursive);
}
}
if (nested != null) {
if (nested.hasNext()) {
next = nested.next();
return true;
}
nested = null;
}
i++;
if (file.isFile()) {
try {
next = new FileEntryResource(full, file, file.toURI().toURL(), context);
return true;
} catch (MalformedURLException ignored) {
}
}
}
return false;
}
public Resource next() {
if (! hasNext()) {
throw new NoSuchElementException();
}
try {
return next;
} finally {
next = null;
}
}
public void remove() {
}
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
final String canonPath = PathUtils.canonicalize(PathUtils.relativize(startPath));
final File start = new File(getRoot(), canonPath);
final String[] children = start.list();
if (children == null || children.length == 0) {
return Collections.emptySet().iterator();
}
return new Itr(canonPath, children, recursive);
}
public Collection getPaths() {
final List index = new ArrayList();
final File indexFile = new File(getRoot().getPath() + ".index");
if (ResourceLoaders.USE_INDEXES) {
// First check for an index file
if (indexFile.exists()) {
try {
final BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(indexFile)));
try {
String s;
while ((s = r.readLine()) != null) {
index.add(s.trim());
}
return index;
} finally {
// if exception is thrown, undo index creation
r.close();
}
} catch (IOException e) {
index.clear();
}
}
}
// Manually build index, starting with the root path
index.add("");
buildIndex(index, getRoot(), "");
if (ResourceLoaders.WRITE_INDEXES) {
// Now try to write it
boolean ok = false;
try {
final FileOutputStream fos = new FileOutputStream(indexFile);
try {
final OutputStreamWriter osw = new OutputStreamWriter(fos);
try {
final BufferedWriter writer = new BufferedWriter(osw);
try {
for (String name : index) {
writer.write(name);
writer.write('\n');
}
writer.close();
osw.close();
fos.close();
ok = true;
} finally {
StreamUtil.safeClose(writer);
}
} finally {
StreamUtil.safeClose(osw);
}
} finally {
StreamUtil.safeClose(fos);
}
} catch (IOException e) {
// failed, ignore
} finally {
if (! ok) {
// well, we tried...
indexFile.delete();
}
}
}
return index;
}
private void buildIndex(final List index, final File root, final String pathBase) {
File[] files = root.listFiles();
if (files != null) for (File file : files) {
if (file.isDirectory()) {
index.add(pathBase + file.getName());
buildIndex(index, file, pathBase + file.getName() + "/");
}
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredIterableLocalLoader.java 0000664 0000000 0000000 00000004307 12572057235 0031540 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* @author David M. Lloyd
*/
class FilteredIterableLocalLoader implements IterableLocalLoader {
private final ClassFilter classFilter;
private final IterableLocalLoader originalLoader;
private final PathFilter resourcePathFilter;
FilteredIterableLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) {
this.classFilter = classFilter;
this.originalLoader = originalLoader;
this.resourcePathFilter = resourcePathFilter;
}
public Class> loadClassLocal(final String name, final boolean resolve) {
return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null;
}
public Package loadPackageLocal(final String name) {
return originalLoader.loadPackageLocal(name);
}
public List loadResourceLocal(final String name) {
return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList();
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
return PathFilters.filtered(resourcePathFilter, originalLoader.iterateResources(startPath, recursive));
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredIterableResourceLoader.java 0000664 0000000 0000000 00000004677 12572057235 0032307 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
final class FilteredIterableResourceLoader implements IterableResourceLoader {
private final PathFilter filter;
private final IterableResourceLoader loader;
FilteredIterableResourceLoader(final PathFilter filter, final IterableResourceLoader loader) {
this.filter = filter;
this.loader = loader;
}
public String getRootName() {
return loader.getRootName();
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName));
return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null;
}
public PackageSpec getPackageSpec(final String name) throws IOException {
return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Resource getResource(final String name) {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name));
return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null;
}
public String getLibrary(final String name) {
return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Collection getPaths() {
return loader.getPaths();
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
return PathFilters.filtered(filter, loader.iterateResources(PathUtils.relativize(PathUtils.canonicalize(startPath)), recursive));
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredLocalLoader.java 0000664 0000000 0000000 00000003576 12572057235 0030077 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.List;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
/**
* @author David M. Lloyd
*/
class FilteredLocalLoader implements LocalLoader {
private final ClassFilter classFilter;
private final LocalLoader originalLoader;
private final PathFilter resourcePathFilter;
FilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) {
this.classFilter = classFilter;
this.originalLoader = originalLoader;
this.resourcePathFilter = resourcePathFilter;
}
public Class> loadClassLocal(final String name, final boolean resolve) {
return classFilter.accept(name) ? originalLoader.loadClassLocal(name, resolve) : null;
}
public Package loadPackageLocal(final String name) {
return originalLoader.loadPackageLocal(name);
}
public List loadResourceLocal(final String name) {
return resourcePathFilter.accept(name) ? originalLoader.loadResourceLocal(name) : Collections.emptyList();
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/FilteredResourceLoader.java 0000664 0000000 0000000 00000004134 12572057235 0030623 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.util.Collection;
import org.jboss.modules.filter.PathFilter;
final class FilteredResourceLoader implements ResourceLoader {
private final PathFilter filter;
private final ResourceLoader loader;
FilteredResourceLoader(final PathFilter filter, final ResourceLoader loader) {
this.filter = filter;
this.loader = loader;
}
public String getRootName() {
return loader.getRootName();
}
public ClassSpec getClassSpec(final String fileName) throws IOException {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(fileName));
return filter.accept(canonicalFileName) ? loader.getClassSpec(canonicalFileName) : null;
}
public PackageSpec getPackageSpec(final String name) throws IOException {
return loader.getPackageSpec(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Resource getResource(final String name) {
final String canonicalFileName = PathUtils.canonicalize(PathUtils.relativize(name));
return filter.accept(canonicalFileName) ? loader.getResource(canonicalFileName) : null;
}
public String getLibrary(final String name) {
return loader.getLibrary(PathUtils.canonicalize(PathUtils.relativize(name)));
}
public Collection getPaths() {
return loader.getPaths();
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IdentityHashSet.java 0000664 0000000 0000000 00000040032 12572057235 0027274 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* An identity based hash set. A number of properties apply to this set. It
* compares only using object identity, it supports null entries, it allocates
* little more than a single object array, and it can be copied quickly. If the
* copy-ctor is passed another IdentityHashSet, or clone is called on this set,
* the shallow copy can be performed using little more than a single array copy.
*
* Note: It is very important to use a smaller load factor than you normally
* would for HashSet, since the implementation is open-addressed with linear
* probing. With a 50% load-factor a get is expected to return in only 2 probes.
* However, a 90% load-factor is expected to return in around 50 probes.
*
* @author Jason T. Greene
*/
class IdentityHashSet extends AbstractSet implements Set, Cloneable, Serializable {
/**
* Serialization ID
*/
private static final long serialVersionUID = 10929568968762L;
/**
* Same default as HashMap, must be a power of 2
*/
private static final int DEFAULT_CAPACITY = 8;
/**
* MAX_INT - 1
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 67%, just like IdentityHashMap
*/
private static final float DEFAULT_LOAD_FACTOR = 0.67f;
/**
* The open-addressed table
*/
private transient Object[] table;
/**
* The current number of key-value pairs
*/
private transient int size;
/**
* The next resize
*/
private transient int threshold;
/**
* The user defined load factor which defines when to resize
*/
private final float loadFactor;
/**
* Counter used to detect changes made outside of an iterator
*/
private transient int modCount;
public IdentityHashSet(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Can not have a negative size table!");
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (!(loadFactor > 0F && loadFactor <= 1F))
throw new IllegalArgumentException("Load factor must be greater than 0 and less than or equal to 1");
this.loadFactor = loadFactor;
init(initialCapacity, loadFactor);
}
@SuppressWarnings("unchecked")
public IdentityHashSet(Set extends E> set) {
if (set instanceof IdentityHashSet) {
IdentityHashSet extends E> fast = (IdentityHashSet extends E>) set;
table = fast.table.clone();
loadFactor = fast.loadFactor;
size = fast.size;
threshold = fast.threshold;
} else {
loadFactor = DEFAULT_LOAD_FACTOR;
init(set.size(), loadFactor);
addAll(set);
}
}
private void init(int initialCapacity, float loadFactor) {
int c = 1;
for (; c < initialCapacity; c <<= 1);
threshold = (int) (c * loadFactor);
// Include the load factor when sizing the table for the first time
if (initialCapacity > threshold && c < MAXIMUM_CAPACITY) {
c <<= 1;
threshold = (int) (c * loadFactor);
}
table = new Object[c];
}
public IdentityHashSet(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public IdentityHashSet() {
this(DEFAULT_CAPACITY);
}
// The normal bit spreader...
private static int hash(Object o) {
int h = System.identityHashCode(o);
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
private int nextIndex(int index, int length) {
index = (index >= length - 1) ? 0 : index + 1;
return index;
}
private static int index(int hashCode, int length) {
return hashCode & (length - 1);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object entry) {
if (entry == null) return false;
int hash = hash(entry);
int length = table.length;
int index = index(hash, length);
for (int start = index;;) {
Object e = table[index];
if (e == null)
return false;
if (entry == e)
return true;
index = nextIndex(index, length);
if (index == start) // Full table
return false;
}
}
public boolean add(E entry) {
if (entry == null) {
throw new NullPointerException("entry is null");
}
Object[] table = this.table;
int hash = hash(entry);
int length = table.length;
int index = index(hash, length);
for (int start = index;;) {
Object e = table[index];
if (e == null)
break;
if (e == entry)
return false;
index = nextIndex(index, length);
if (index == start)
throw new IllegalStateException("Table is full!");
}
modCount++;
table[index] = entry;
if (++size >= threshold)
resize(length);
return true;
}
private void resize(int from) {
int newLength = from << 1;
// Can't get any bigger
if (newLength > MAXIMUM_CAPACITY || newLength <= from)
return;
Object[] newTable = new Object[newLength];
Object[] old = table;
for (Object e : old) {
if (e == null)
continue;
int index = index(hash(e), newLength);
while (newTable[index] != null)
index = nextIndex(index, newLength);
newTable[index] = e;
}
threshold = (int) (loadFactor * newLength);
table = newTable;
}
@SuppressWarnings({ "unchecked" })
public boolean addAll(Collection extends E> collection) {
int size = collection.size();
if (size == 0)
return false;
if (size > threshold) {
if (size > MAXIMUM_CAPACITY)
size = MAXIMUM_CAPACITY;
int length = table.length;
for (; length < size; length <<= 1);
resize(length);
}
boolean state = false;
if (collection instanceof IdentityHashSet) {
for (E e : ((E[]) (((IdentityHashSet>) collection).table)))
if (e != null) state |= add(e);
} else {
for (E e : collection)
state |= add(e);
}
return state;
}
public boolean remove(Object o) {
if (o == null) return false;
Object[] table = this.table;
int length = table.length;
int hash = hash(o);
int start = index(hash, length);
for (int index = start;;) {
Object e = table[index];
if (e == null)
return false;
if (e == o) {
table[index] = null;
relocate(index);
modCount++;
size--;
return true;
}
index = nextIndex(index, length);
if (index == start)
return false;
}
}
private void relocate(int start) {
Object[] table = this.table;
int length = table.length;
int current = nextIndex(start, length);
for (;;) {
Object e = table[current];
if (e == null)
return;
// A Doug Lea variant of Knuth's Section 6.4 Algorithm R.
// This provides a non-recursive method of relocating
// entries to their optimal positions once a gap is created.
int prefer = index(hash(e), length);
if ((current < prefer && (prefer <= start || start <= current)) || (prefer <= start && start <= current)) {
table[start] = e;
table[current] = null;
start = current;
}
current = nextIndex(current, length);
}
}
public void clear() {
modCount++;
Object[] table = this.table;
for (int i = 0; i < table.length; i++)
table[i] = null;
size = 0;
}
@SuppressWarnings("unchecked")
public IdentityHashSet clone() {
try {
IdentityHashSet clone = (IdentityHashSet) super.clone();
clone.table = table.clone();
return clone;
} catch (CloneNotSupportedException e) {
// should never happen
throw new IllegalStateException(e);
}
}
/**
* Advanced method that returns a copy of the internal table. The resulting
* array will contain nulls at random places that must be skipped. In
* addition, it will not operate correctly if a null was inserted into the
* set. Use at your own risk....
*
* @return an array containing elements in this set along with randomly
* placed nulls,
*/
@SuppressWarnings({ "unchecked" })
public E[] toScatteredArray(E[] dummy) {
final E[] ret = (E[]) Array.newInstance(dummy.getClass().getComponentType(), table.length);
System.arraycopy((E[])table, 0, ret, 0, ret.length);
return ret;
}
/**
* Warning: this will crap out if the set contains a {@code null}.
*
* @param target the target to write to
* @param offs the offset into the target
* @param len the length to write
* @return the target array
*/
@SuppressWarnings({ "unchecked" })
public E[] toArray(final E[] target, final int offs, final int len) {
assert len <= size;
final E[] table = (E[]) this.table;
E e;
final int last = offs + len;
for (int i = offs, j = 0; i < last; j ++) {
e = table[j];
if (e != null) {
target[i++] = e;
}
}
return target;
}
public void printDebugStats() {
int optimal = 0;
int total = 0;
int totalSkew = 0;
int maxSkew = 0;
for (int i = 0; i < table.length; i++) {
Object e = table[i];
if (e != null) {
total++;
int target = index(hash(e), table.length);
if (i == target)
optimal++;
else {
int skew = Math.abs(i - target);
if (skew > maxSkew)
maxSkew = skew;
totalSkew += skew;
}
}
}
System.out.println(" Size: " + size);
System.out.println(" Real Size: " + total);
System.out.println(" Optimal: " + optimal + " (" + (float) optimal * 100 / total + "%)");
System.out.println(" Average Distance: " + ((float) totalSkew / (total - optimal)));
System.out.println(" Max Distance: " + maxSkew);
}
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
int size = s.readInt();
init(size, loadFactor);
for (int i = 0; i < size; i++) {
putForCreate((E) s.readObject());
}
this.size = size;
}
private void putForCreate(E entry) {
Object[] table = this.table;
int hash = hash(entry);
int length = table.length;
int index = index(hash, length);
Object e = table[index];
while (e != null) {
index = nextIndex(index, length);
e = table[index];
}
table[index] = entry;
}
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeInt(size);
for (Object e : table) {
if (e != null) {
s.writeObject(e);
}
}
}
@Override
public Iterator iterator() {
return new IdentityHashSetIterator();
}
private class IdentityHashSetIterator implements Iterator {
private int next = 0;
private int expectedCount = modCount;
private int current = -1;
private boolean hasNext;
Object table[] = IdentityHashSet.this.table;
public boolean hasNext() {
if (hasNext == true)
return true;
Object table[] = this.table;
for (int i = next; i < table.length; i++) {
if (table[i] != null) {
next = i;
return hasNext = true;
}
}
next = table.length;
return false;
}
@SuppressWarnings("unchecked")
public E next() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
if (!hasNext && !hasNext())
throw new NoSuchElementException();
current = next++;
hasNext = false;
return (E) table[current];
}
public void remove() {
if (modCount != expectedCount)
throw new ConcurrentModificationException();
int current = this.current;
int delete = current;
if (current == -1)
throw new IllegalStateException();
// Invalidate current (prevents multiple remove)
this.current = -1;
// Start were we relocate
next = delete;
Object[] table = this.table;
if (table != IdentityHashSet.this.table) {
IdentityHashSet.this.remove(table[delete]);
table[delete] = null;
expectedCount = modCount;
return;
}
int length = table.length;
int i = delete;
table[delete] = null;
size--;
for (;;) {
i = nextIndex(i, length);
Object e = table[i];
if (e == null)
break;
int prefer = index(hash(e), length);
if ((i < prefer && (prefer <= delete || delete <= i)) || (prefer <= delete && delete <= i)) {
// Snapshot the unseen portion of the table if we have
// to relocate an entry that was already seen by this
// iterator
if (i < current && current <= delete && table == IdentityHashSet.this.table) {
int remaining = length - current;
Object[] newTable = new Object[remaining];
System.arraycopy(table, current, newTable, 0, remaining);
// Replace iterator's table.
// Leave table local var pointing to the real table
this.table = newTable;
next = 0;
}
// Do the swap on the real table
table[delete] = e;
table[i] = null;
delete = i;
}
}
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableLocalLoader.java 0000664 0000000 0000000 00000003101 12572057235 0030050 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Iterator;
/**
* A local loader which can enumerate its contents.
*
* @author David M. Lloyd
*/
public interface IterableLocalLoader extends LocalLoader {
/**
* Enumerate all the resources under the given path. The given path name is relative to the root
* of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed.
* If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}.
*
* @param startPath the path to search under
* @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path
* @return the resource iterator (possibly empty)
*/
Iterator iterateResources(String startPath, boolean recursive);
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableModuleFinder.java 0000664 0000000 0000000 00000002627 12572057235 0030260 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Iterator;
/**
* A module finder which is iterable.
*
* @author David M. Lloyd
*/
public interface IterableModuleFinder extends ModuleFinder {
/**
* Iterate the modules which can be located via this module finder.
*
* @param baseIdentifier the identifier to start with, or {@code null} to iterate all modules
* @param recursive {@code true} to find recursively nested modules, {@code false} to only find immediately nested modules
* @return an iterator for the modules in this module finder
*/
Iterator iterateModules(ModuleIdentifier baseIdentifier, boolean recursive);
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/IterableResourceLoader.java 0000664 0000000 0000000 00000003131 12572057235 0030610 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Iterator;
/**
* A resource loader which has the ability to enumerate its contents.
*
* @author David M. Lloyd
*/
public interface IterableResourceLoader extends ResourceLoader {
/**
* Enumerate all the resources under the given path. The given path name is relative to the root
* of the resource loader. If the path "escapes" the root via {@code ..}, such segments will be consumed.
* If the path is absolute, it will be converted to a relative path by dropping the leading {@code /}.
*
* @param startPath the path to search under
* @param recursive {@code true} to recursively descend into subdirectories, {@code false} to only read this path
* @return the resource iterator (possibly empty)
*/
Iterator iterateResources(String startPath, boolean recursive);
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JDKPaths.java 0000664 0000000 0000000 00000011326 12572057235 0025637 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.security.AccessController;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* A utility class which maintains the set of JDK paths. Makes certain assumptions about the disposition of the
* class loader used to load JBoss Modules; thus this class should only be used when booted up via the "-jar" or "-cp"
* switches.
*
* @author David M. Lloyd
*/
final class JDKPaths {
static final Set JDK;
static {
final Set pathSet = new FastCopyHashSet(1024);
final Set jarSet = new FastCopyHashSet(1024);
final String sunBootClassPath = AccessController.doPrivileged(new PropertyReadAction("sun.boot.class.path"));
final String javaClassPath = AccessController.doPrivileged(new PropertyReadAction("java.class.path"));
processClassPathItem(sunBootClassPath, jarSet, pathSet);
processClassPathItem(javaClassPath, jarSet, pathSet);
pathSet.add("org/jboss/modules");
pathSet.add("org/jboss/modules/filter");
pathSet.add("org/jboss/modules/log");
pathSet.add("org/jboss/modules/management");
pathSet.add("org/jboss/modules/ref");
JDK = Collections.unmodifiableSet(pathSet);
}
private JDKPaths() {
}
private static void processClassPathItem(final String classPath, final Set jarSet, final Set pathSet) {
if (classPath == null) return;
int s = 0, e;
do {
e = classPath.indexOf(File.pathSeparatorChar, s);
String item = e == -1 ? classPath.substring(s) : classPath.substring(s, e);
if (! jarSet.contains(item)) {
final File file = new File(item);
if (file.isDirectory()) {
processDirectory0(pathSet, file);
} else {
try {
processJar(pathSet, file);
} catch (IOException ex) {
// ignore
}
}
}
s = e + 1;
} while (e != -1);
}
static void processJar(final Set pathSet, final File file) throws IOException {
final ZipFile zipFile = new ZipFile(file);
try {
final Enumeration extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
final String name = entry.getName();
final int lastSlash = name.lastIndexOf('/');
if (lastSlash != -1) {
pathSet.add(name.substring(0, lastSlash));
}
}
zipFile.close();
} finally {
StreamUtil.safeClose(zipFile);
}
}
static void processDirectory0(final Set pathSet, final File file) {
for (File entry : file.listFiles()) {
if (entry.isDirectory()) {
processDirectory1(pathSet, entry, file.getPath());
} else {
final String parent = entry.getParent();
if (parent != null) pathSet.add(parent);
}
}
}
static void processDirectory1(final Set pathSet, final File file, final String pathBase) {
for (File entry : file.listFiles()) {
if (entry.isDirectory()) {
processDirectory1(pathSet, entry, pathBase);
} else {
String packagePath = entry.getParent();
if (packagePath != null) {
packagePath = packagePath.substring(pathBase.length()).replace('\\', '/');;
if(packagePath.startsWith("/")) {
packagePath = packagePath.substring(1);
}
pathSet.add(packagePath);
}
}
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarEntryResource.java 0000664 0000000 0000000 00000003203 12572057235 0027470 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
*
* @author David M. Lloyd
*/
final class JarEntryResource implements Resource {
private final JarFile jarFile;
private final JarEntry entry;
private final URL resourceURL;
JarEntryResource(final JarFile jarFile, final JarEntry entry, final URL resourceURL) {
this.jarFile = jarFile;
this.entry = entry;
this.resourceURL = resourceURL;
}
public String getName() {
return entry.getName();
}
public URL getURL() {
return resourceURL;
}
public InputStream openStream() throws IOException {
return jarFile.getInputStream(entry);
}
public long getSize() {
final long size = entry.getSize();
return size == -1 ? 0 : size;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarFileResourceLoader.java 0000664 0000000 0000000 00000044156 12572057235 0030411 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
*
* @author David M. Lloyd
* @author Thomas.Diesler@jboss.com
*/
final class JarFileResourceLoader extends AbstractResourceLoader implements IterableResourceLoader {
private static final String INDEX_FILE = "META-INF/PATHS.LIST";
private final JarFile jarFile;
private final String rootName;
private final URL rootUrl;
private final String relativePath;
private final File fileOfJar;
// protected by {@code this}
private final Map codeSources = new HashMap<>();
JarFileResourceLoader(final String rootName, final JarFile jarFile) {
this(rootName, jarFile, null);
}
JarFileResourceLoader(final String rootName, final JarFile jarFile, final String relativePath) {
if (jarFile == null) {
throw new IllegalArgumentException("jarFile is null");
}
if (rootName == null) {
throw new IllegalArgumentException("rootName is null");
}
fileOfJar = new File(jarFile.getName());
this.jarFile = jarFile;
this.rootName = rootName;
final String realPath = relativePath == null ? null : PathUtils.canonicalize(relativePath);
this.relativePath = realPath;
try {
rootUrl = getJarURI(fileOfJar.toURI(), realPath).toURL();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid root file specified", e);
}
}
private static URI getJarURI(final URI original, final String nestedPath) throws URISyntaxException {
final StringBuilder b = new StringBuilder();
b.append("file:");
assert original.getScheme().equals("file");
final String path = original.getPath();
assert path != null;
final String host = original.getHost();
if (host != null) {
final String userInfo = original.getRawUserInfo();
b.append("//");
if (userInfo != null) {
b.append(userInfo).append('@');
}
b.append(host);
}
b.append(path).append("!/");
if (nestedPath != null) {
b.append(nestedPath);
}
return new URI("jar", b.toString(), null);
}
public String getRootName() {
return rootName;
}
public synchronized ClassSpec getClassSpec(final String fileName) throws IOException {
final ClassSpec spec = new ClassSpec();
final JarEntry entry = getJarEntry(fileName);
if (entry == null) {
// no such entry
return null;
}
final long size = entry.getSize();
final InputStream is = jarFile.getInputStream(entry);
try {
if (size == -1) {
// size unknown
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] buf = new byte[16384];
int res;
while ((res = is.read(buf)) > 0) {
baos.write(buf, 0, res);
}
// done
CodeSource codeSource = createCodeSource(entry);
baos.close();
is.close();
spec.setBytes(baos.toByteArray());
spec.setCodeSource(codeSource);
return spec;
} else if (size <= (long) Integer.MAX_VALUE) {
final int castSize = (int) size;
byte[] bytes = new byte[castSize];
int a = 0, res;
while ((res = is.read(bytes, a, castSize - a)) > 0) {
a += res;
}
// consume remainder so that cert check doesn't fail in case of wonky JARs
while (is.read() != -1);
// done
CodeSource codeSource = createCodeSource(entry);
is.close();
spec.setBytes(bytes);
spec.setCodeSource(codeSource);
return spec;
} else {
throw new IOException("Resource is too large to be a valid class file");
}
} finally {
StreamUtil.safeClose(is);
}
}
// this MUST only be called after the input stream is fully read (see MODULES-201)
private CodeSource createCodeSource(final JarEntry entry) {
final CodeSigner[] entryCodeSigners = entry.getCodeSigners();
final CodeSigners codeSigners = entryCodeSigners == null || entryCodeSigners.length == 0 ? EMPTY_CODE_SIGNERS : new CodeSigners(entryCodeSigners);
CodeSource codeSource = codeSources.get(codeSigners);
if (codeSource == null) {
codeSources.put(codeSigners, codeSource = new CodeSource(rootUrl, entryCodeSigners));
}
return codeSource;
}
private JarEntry getJarEntry(final String fileName) {
return relativePath == null ? jarFile.getJarEntry(fileName) : jarFile.getJarEntry(relativePath + "/" + fileName);
}
public PackageSpec getPackageSpec(final String name) throws IOException {
final Manifest manifest;
if (relativePath == null) {
manifest = jarFile.getManifest();
} else {
JarEntry jarEntry = getJarEntry("META-INF/MANIFEST.MF");
if (jarEntry == null) {
manifest = null;
} else {
InputStream inputStream = jarFile.getInputStream(jarEntry);
try {
manifest = new Manifest(inputStream);
} finally {
StreamUtil.safeClose(inputStream);
}
}
}
return getPackageSpec(name, manifest, rootUrl);
}
public String getLibrary(final String name) {
// JARs cannot have libraries in them
return null;
}
public Resource getResource(String name) {
try {
final JarFile jarFile = this.jarFile;
name = PathUtils.canonicalize(PathUtils.relativize(name));
final JarEntry entry = getJarEntry(name);
if (entry == null) {
return null;
}
final URI uri;
try {
File absoluteFile = new File(jarFile.getName()).getAbsoluteFile();
String path = absoluteFile.getPath();
path = PathUtils.canonicalize(path);
if (File.separatorChar != '/') {
// optimizes away on platforms with /
path = path.replace(File.separatorChar, '/');
}
if (PathUtils.isRelative(path)) {
// should not be possible, but the JDK thinks this might happen sometimes..?
path = "/" + path;
}
if (path.startsWith("//")) {
// UNC path URIs have loads of leading slashes
path = "//" + path;
}
uri = new URI("file", null, path, null);
} catch (URISyntaxException x) {
throw new IllegalStateException(x);
}
return new JarEntryResource(jarFile, entry, new URL(null, getJarURI(uri, entry.getName()).toString(), (URLStreamHandler) null));
} catch (MalformedURLException e) {
// must be invalid...? (todo: check this out)
return null;
} catch (URISyntaxException e) {
// must be invalid...? (todo: check this out)
return null;
}
}
public Iterator iterateResources(final String startPath, final boolean recursive) {
final JarFile jarFile = this.jarFile;
final String startName = PathUtils.canonicalize(PathUtils.relativize(startPath));
final Enumeration entries = jarFile.entries();
return new Iterator() {
private Resource next;
public boolean hasNext() {
while (next == null) {
if (! entries.hasMoreElements()) {
return false;
}
final JarEntry entry = entries.nextElement();
final String name = entry.getName();
if ((recursive ? PathUtils.isChild(startName, name) : PathUtils.isDirectChild(startName, name))) {
if (!entry.isDirectory()) {
try {
next = new JarEntryResource(jarFile, entry, getJarURI(new File(jarFile.getName()).toURI(), entry.getName()).toURL());
} catch (Exception ignored) {
}
}
}
}
return true;
}
public Resource next() {
if (! hasNext()) {
throw new NoSuchElementException();
}
try {
return next;
} finally {
next = null;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Collection getPaths() {
final Collection index = new HashSet();
index.add("");
String relativePath = this.relativePath;
// First check for an external index
final JarFile jarFile = this.jarFile;
final String jarFileName = jarFile.getName();
final long jarModified = fileOfJar.lastModified();
final File indexFile = new File(jarFileName + ".index");
if (ResourceLoaders.USE_INDEXES) {
if (indexFile.exists()) {
final long indexModified = indexFile.lastModified();
if (indexModified != 0L && jarModified != 0L && indexModified >= jarModified) try {
return readIndex(new FileInputStream(indexFile), index, relativePath);
} catch (IOException e) {
index.clear();
}
}
}
// Next check for an internal index
JarEntry listEntry = jarFile.getJarEntry(INDEX_FILE);
if (listEntry != null) {
try {
return readIndex(jarFile.getInputStream(listEntry), index, relativePath);
} catch (IOException e) {
index.clear();
}
}
// Next just read the JAR
extractJarPaths(jarFile, relativePath, index);
if (ResourceLoaders.WRITE_INDEXES && relativePath == null) {
writeExternalIndex(indexFile, index);
}
return index;
}
static void extractJarPaths(final JarFile jarFile, String relativePath,
final Collection index) {
index.add("");
final Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry jarEntry = entries.nextElement();
final String name = jarEntry.getName();
final int idx = name.lastIndexOf('/');
if (idx == -1) continue;
final String path = name.substring(0, idx);
if (path.length() == 0 || path.endsWith("/")) {
// invalid name, just skip...
continue;
}
if (relativePath == null) {
index.add(path);
} else {
if (path.startsWith(relativePath + "/")) {
index.add(path.substring(relativePath.length() + 1));
}
}
}
}
static void writeExternalIndex(final File indexFile,
final Collection index) {
// Now try to write it
boolean ok = false;
try {
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexFile)));
try {
for (String name : index) {
writer.write(name);
writer.write('\n');
}
writer.close();
ok = true;
} finally {
StreamUtil.safeClose(writer);
}
} catch (IOException e) {
// failed, ignore
} finally {
if (! ok) {
// well, we tried...
indexFile.delete();
}
}
}
static Collection readIndex(final InputStream stream, final Collection index, final String relativePath) throws IOException {
final BufferedReader r = new BufferedReader(new InputStreamReader(stream));
try {
String s;
while ((s = r.readLine()) != null) {
String name = s.trim();
if (relativePath == null) {
index.add(name);
} else {
if (name.startsWith(relativePath + "/")) {
index.add(name.substring(relativePath.length() + 1));
}
}
}
return index;
} finally {
// if exception is thrown, undo index creation
r.close();
}
}
static void addInternalIndex(File file, boolean modify) throws IOException {
final JarFile oldJarFile = new JarFile(file, false);
try {
final Collection index = new TreeSet();
final File outputFile;
outputFile = new File(file.getAbsolutePath().replace(".jar", "-indexed.jar"));
final ZipOutputStream zo = new ZipOutputStream(new FileOutputStream(outputFile));
try {
Enumeration entries = oldJarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
// copy data, unless we're replacing the index
if (!entry.getName().equals(INDEX_FILE)) {
final JarEntry clone = (JarEntry) entry.clone();
// Compression level and format can vary across implementations
if (clone.getMethod() != ZipEntry.STORED)
clone.setCompressedSize(-1);
zo.putNextEntry(clone);
StreamUtil.copy(oldJarFile.getInputStream(entry), zo);
}
// add to the index
final String name = entry.getName();
final int idx = name.lastIndexOf('/');
if (idx == -1) continue;
final String path = name.substring(0, idx);
if (path.length() == 0 || path.endsWith("/")) {
// invalid name, just skip...
continue;
}
index.add(path);
}
// write index
zo.putNextEntry(new ZipEntry(INDEX_FILE));
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zo));
try {
for (String name : index) {
writer.write(name);
writer.write('\n');
}
writer.close();
} finally {
StreamUtil.safeClose(writer);
}
zo.close();
oldJarFile.close();
if (modify) {
file.delete();
if (!outputFile.renameTo(file)) {
throw new IOException("failed to rename " + outputFile.getAbsolutePath() + " to " + file.getAbsolutePath());
}
}
} finally {
StreamUtil.safeClose(zo);
}
} finally {
StreamUtil.safeClose(oldJarFile);
}
}
private static final CodeSigners EMPTY_CODE_SIGNERS = new CodeSigners(new CodeSigner[0]);
static final class CodeSigners {
private final CodeSigner[] codeSigners;
private final int hashCode;
public CodeSigners(final CodeSigner[] codeSigners) {
this.codeSigners = codeSigners;
hashCode = Arrays.hashCode(codeSigners);
}
public boolean equals(final Object obj) {
return obj instanceof CodeSigners && equals((CodeSigners) obj);
}
private boolean equals(final CodeSigners other) {
return Arrays.equals(codeSigners, other.codeSigners);
}
public int hashCode() {
return hashCode;
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarModuleFinder.java 0000775 0000000 0000000 00000016234 12572057235 0027247 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.jboss.modules.filter.MultiplePathFilterBuilder;
import org.jboss.modules.filter.PathFilters;
/**
* A module finder which uses a JAR file as a module repository.
*
* @author David M. Lloyd
*/
public final class JarModuleFinder implements ModuleFinder {
private final ModuleIdentifier myIdentifier;
private final JarFile jarFile;
private final AccessControlContext context;
/**
* Construct a new instance.
*
* @param myIdentifier the identifier to use for the JAR itself
* @param jarFile the JAR file to encapsulate
*/
public JarModuleFinder(final ModuleIdentifier myIdentifier, final JarFile jarFile) {
this.myIdentifier = myIdentifier;
this.jarFile = jarFile;
context = AccessController.getContext();
}
public ModuleSpec findModule(final ModuleIdentifier identifier, final ModuleLoader delegateLoader) throws ModuleLoadException {
if (identifier.equals(myIdentifier)) {
// special root JAR module
Manifest manifest;
try {
manifest = jarFile.getManifest();
} catch (IOException e) {
throw new ModuleLoadException("Failed to load MANIFEST from JAR", e);
}
ModuleSpec.Builder builder = ModuleSpec.build(identifier);
Attributes mainAttributes = manifest.getMainAttributes();
String mainClass = mainAttributes.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
builder.setMainClass(mainClass);
}
String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
String dependencies = mainAttributes.getValue("Dependencies");
MultiplePathFilterBuilder pathFilterBuilder = PathFilters.multiplePathFilterBuilder(true);
pathFilterBuilder.addFilter(PathFilters.is("modules"), false);
pathFilterBuilder.addFilter(PathFilters.isChildOf("modules"), false);
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader("", jarFile), pathFilterBuilder.create()));
String[] classPathEntries = classPath == null ? JarModuleLoader.NO_STRINGS : classPath.split("\\s+");
for (String entry : classPathEntries) {
if (! entry.isEmpty()) {
if (entry.startsWith("../") || entry.startsWith("./") || entry.startsWith("/") || entry.contains("/../")) {
// invalid
continue;
}
if (entry.endsWith("/")) {
// directory reference
File root = new File(jarFile.getName(), entry);
FileResourceLoader resourceLoader = new FileResourceLoader(entry, root, context);
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(resourceLoader));
} else {
// assume a JAR
File root = new File(jarFile.getName(), entry);
JarFile childJarFile;
try {
childJarFile = new JarFile(root, true);
} catch (IOException e) {
// ignore and continue
continue;
}
builder.addResourceRoot(ResourceLoaderSpec.createResourceLoaderSpec(new JarFileResourceLoader(entry, childJarFile)));
}
}
}
String[] dependencyEntries = dependencies == null ? JarModuleLoader.NO_STRINGS : dependencies.split("\\s*,\\s*");
for (String dependencyEntry : dependencyEntries) {
boolean optional = false;
boolean export = false;
dependencyEntry = dependencyEntry.trim();
if (! dependencyEntry.isEmpty()) {
String[] fields = dependencyEntry.split("\\s+");
if (fields.length < 1) {
continue;
}
String moduleName = fields[0];
for (int i = 1; i < fields.length; i++) {
String field = fields[i];
if (field.equals("optional")) {
optional = true;
} else if (field.equals("export")) {
export = true;
}
// else ignored
}
builder.addDependency(DependencySpec.createModuleDependencySpec(ModuleIdentifier.fromString(moduleName), export, optional));
}
}
builder.addDependency(DependencySpec.createSystemDependencySpec(JDKPaths.JDK));
builder.addDependency(DependencySpec.createLocalDependencySpec());
return builder.create();
} else {
String namePath = identifier.getName().replace('.', '/');
String basePath = "modules/" + namePath + "/" + identifier.getSlot();
JarEntry moduleXmlEntry = jarFile.getJarEntry(basePath + "/module.xml");
if (moduleXmlEntry == null) {
return null;
}
ModuleSpec moduleSpec;
try {
InputStream inputStream = jarFile.getInputStream(moduleXmlEntry);
try {
moduleSpec = ModuleXmlParser.parseModuleXml(new ModuleXmlParser.ResourceRootFactory() {
public ResourceLoader createResourceLoader(final String rootPath, final String loaderPath, final String loaderName) throws IOException {
return new JarFileResourceLoader(loaderName, jarFile, loaderPath);
}
}, basePath, inputStream, moduleXmlEntry.getName(), delegateLoader, identifier);
} finally {
StreamUtil.safeClose(inputStream);
}
} catch (IOException e) {
throw new ModuleLoadException("Failed to read module.xml file", e);
}
return moduleSpec;
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/JarModuleLoader.java 0000664 0000000 0000000 00000004310 12572057235 0027233 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.util.jar.JarFile;
/**
* @author David M. Lloyd
*/
final class JarModuleLoader extends ModuleLoader {
static final String[] NO_STRINGS = new String[0];
private final ModuleLoader delegate;
private final JarFile jarFile;
private final ModuleIdentifier myIdentifier;
JarModuleLoader(final ModuleLoader delegate, final JarFile jarFile) {
super(new ModuleFinder[] { new JarModuleFinder(simpleNameOf(jarFile), jarFile) });
this.delegate = delegate;
this.jarFile = jarFile;
myIdentifier = simpleNameOf(jarFile);
}
private static ModuleIdentifier simpleNameOf(JarFile jarFile) {
String jarName = jarFile.getName();
String simpleJarName = jarName.substring(jarName.lastIndexOf(File.separatorChar) + 1);
return ModuleIdentifier.create(simpleJarName);
}
protected Module preloadModule(final ModuleIdentifier identifier) throws ModuleLoadException {
if (identifier.equals(myIdentifier)) {
return loadModuleLocal(identifier);
} else {
Module module = loadModuleLocal(identifier);
if (module == null) {
return preloadModule(identifier, delegate);
} else {
return module;
}
}
}
ModuleIdentifier getMyIdentifier() {
return myIdentifier;
}
public String toString() {
return "JAR module loader";
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LayeredModulePathFactory.java 0000664 0000000 0000000 00000022136 12572057235 0031130 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
/**
* Provides a module path that includes entries for any "layer" and "add-on" directory structures found
* within the regular items in the provided module path.
*
* @author Brian Stansberry (c) 2012 Red Hat Inc.
*/
class LayeredModulePathFactory {
/**
* Inspects each element in the given {@code modulePath} to see if it includes a {@code layers.conf} file
* and/or a standard directory structure with child directories {@code system/layers} and, optionally,
* {@code system/add-ons}. If so, the layers identified in {@code layers.conf} are added to the module path
*
* @param modulePath the filesystem locations that make up the standard module path, each of which is to be
* checked for the presence of layers and add-ons
*
* @return a new module path, including any layers and add-ons, if found
*/
static File[] resolveLayeredModulePath(File... modulePath) {
boolean foundLayers = false;
List layeredPath = new ArrayList();
for (File file : modulePath) {
// Always add the root, as the user may place modules directly in it
layeredPath.add(file);
LayersConfig layersConfig = getLayersConfig(file);
File layersDir = new File(file, layersConfig.getLayersPath());
if (!layersDir.exists()) {
if (layersConfig.isConfigured()) {
// Bad config from user
throw new IllegalStateException("No layers directory found at " + layersDir);
}
// else this isn't a root that has layers and add-ons
continue;
}
boolean validLayers = true;
List layerFiles = new ArrayList();
for (String layerName : layersConfig.getLayers()) {
File layer = new File(layersDir, layerName);
if (!layer.exists()) {
if (layersConfig.isConfigured()) {
// Bad config from user
throw new IllegalStateException(String.format("Cannot find layer %s under directory %s", layerName, layersDir));
}
// else this isn't a standard layers and add-ons structure
validLayers = false;
break;
}
loadOverlays(layer, layerFiles);
}
if (validLayers) {
foundLayers = true;
layeredPath.addAll(layerFiles);
// Now add-ons
File[] addOns = new File(file, layersConfig.getAddOnsPath()).listFiles();
if (addOns != null) {
for (File addOn : addOns) {
if (addOn.isDirectory()) {
loadOverlays(addOn, layeredPath);
}
}
}
}
}
return foundLayers ? layeredPath.toArray(new File[layeredPath.size()]) : modulePath;
}
private static LayersConfig getLayersConfig(File repoRoot) {
File layersList = new File(repoRoot, "layers.conf");
if (!layersList.exists()) {
return new LayersConfig();
}
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(layersList), "UTF-8");
Properties props = new Properties();
props.load(reader);
return new LayersConfig(props);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
StreamUtil.safeClose(reader);
}
}
private static class LayersConfig {
private static final String DEFAULT_LAYERS_PATH = "system/layers";
private static final String DEFAULT_ADD_ONS_PATH = "system/add-ons";
private final boolean configured;
private final String layersPath;
private final String addOnsPath;
private final List layers;
private LayersConfig() {
configured = false;
layersPath = DEFAULT_LAYERS_PATH;
addOnsPath = DEFAULT_ADD_ONS_PATH;
layers = Collections.singletonList("base");
}
private LayersConfig(Properties properties) {
configured = true;
// Possible future enhancement; probably better to use an xml file
// layersPath = properties.getProperty("layers.path", DEFAULT_LAYERS_PATH);
// addOnsPath = properties.getProperty("add-ons.path", DEFAULT_ADD_ONS_PATH);
// boolean excludeBase = Boolean.valueOf(properties.getProperty("exclude.base.layer", "false"));
layersPath = DEFAULT_LAYERS_PATH;
addOnsPath = DEFAULT_ADD_ONS_PATH;
boolean excludeBase = false;
String layersProp = (String) properties.get("layers");
if (layersProp == null || (layersProp = layersProp.trim()).length() == 0) {
if (excludeBase) {
layers = Collections.emptyList();
} else {
layers = Collections.singletonList("base");
}
} else {
String[] layerNames = layersProp.split(",");
layers = new ArrayList();
boolean hasBase = false;
for (String layerName : layerNames) {
if ("base".equals(layerName)) {
hasBase = true;
}
layers.add(layerName);
}
if (!hasBase && !excludeBase) {
layers.add("base");
}
}
}
boolean isConfigured() {
return configured;
}
String getLayersPath() {
return layersPath;
}
String getAddOnsPath() {
return addOnsPath;
}
List getLayers() {
return layers;
}
}
private static final String OVERLAYS = ".overlays";
/**
* Load the overlays for each layer.
*
* @param layeringRoot the layer root
* @param path the module path
*/
static void loadOverlays(final File layeringRoot, final List path) {
final File overlays = new File(layeringRoot, OVERLAYS);
if (overlays.exists()) {
final File refs = new File(overlays, OVERLAYS);
if (refs.exists()) {
try {
for (final String overlay : readRefs(refs)) {
final File root = new File(overlays, overlay);
path.add(root);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
path.add(layeringRoot);
}
public static List readRefs(final File file) throws IOException {
if(! file.exists()) {
return Collections.emptyList();
}
final InputStream is = new FileInputStream(file);
try {
return readRefs(is);
} finally {
if (is != null) try {
is.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
static List readRefs(final InputStream is) throws IOException {
final List refs = new ArrayList();
final StringBuffer buffer = new StringBuffer();
do {
if(buffer.length() > 0) {
final String ref = buffer.toString().trim();
if(ref.length() > 0) {
refs.add(ref);
}
}
} while(readLine(is, buffer));
return refs;
}
static boolean readLine(InputStream is, StringBuffer buffer) throws IOException {
buffer.setLength(0);
int c;
for(;;) {
c = is.read();
switch(c) {
case '\t':
case '\r':
break;
case -1: return false;
case '\n': return true;
default: buffer.append((char) c);
}
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Linkage.java 0000664 0000000 0000000 00000004570 12572057235 0025604 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* The linkage state of a module.
*
* @author David M. Lloyd
*/
final class Linkage {
private static final Dependency[] NO_DEPENDENCIES = new Dependency[0];
private static final DependencySpec[] NO_DEPENDENCY_SPECS = new DependencySpec[0];
enum State {
NEW,
UNLINKED,
LINKING,
LINKED,
;
}
private final DependencySpec[] dependencySpecs;
private final Dependency[] dependencies;
private final State state;
private final Map> allPaths;
Linkage(final State state) {
this(NO_DEPENDENCY_SPECS, NO_DEPENDENCIES, state, Collections.>emptyMap());
}
Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state) {
this(dependencySpecs, dependencies, state, Collections.>emptyMap());
}
Linkage(final DependencySpec[] dependencySpecs, final Dependency[] dependencies, final State state, final Map> allPaths) {
this.dependencySpecs = dependencySpecs;
this.dependencies = dependencies;
this.state = state;
this.allPaths = allPaths;
}
Map> getPaths() {
return allPaths;
}
State getState() {
return state;
}
Dependency[] getDependencies() {
return dependencies;
}
DependencySpec[] getDependencySpecs() {
return dependencySpecs;
}
static final Linkage NONE = new Linkage(State.NEW);
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalDependency.java 0000664 0000000 0000000 00000003340 12572057235 0027255 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.Set;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.PathFilter;
/**
* @author David M. Lloyd
*/
final class LocalDependency extends Dependency {
private final LocalLoader localLoader;
private final Set paths;
LocalDependency(final PathFilter exportFilter, final PathFilter importFilter, final PathFilter resourceExportFilter, final PathFilter resourceImportFilter, final ClassFilter classExportFilter, final ClassFilter classImportFilter, final LocalLoader localLoader, final Set paths) {
super(exportFilter, importFilter, resourceExportFilter, resourceImportFilter, classExportFilter, classImportFilter);
this.localLoader = localLoader;
this.paths = paths;
}
LocalLoader getLocalLoader() {
return localLoader;
}
Set getPaths() {
return paths;
}
public String toString() {
return "dependency on " + localLoader;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalLoader.java 0000664 0000000 0000000 00000004112 12572057235 0026403 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.util.List;
/**
* A loader which implements the local part of a module.
*
* Thread safety warning! The loader must never call into a class loader (or any other object) which may
* take locks and subsequently delegate to a module class loader. This will cause deadlocks and other hard-to-debug
* concurrency problems.
*
* @author David M. Lloyd
*/
public interface LocalLoader {
/**
* Load a class which is locally defined by this loader.
*
* @param name the class name
* @param resolve {@code true} to resolve the class
* @return the class, or {@code null} if there is no local class with this name
*/
Class> loadClassLocal(String name, boolean resolve);
/**
* Load a package which is locally defined by this loader.
*
* @param name the package name
* @return the package, or {@code null} if there is no local package with this name
*/
Package loadPackageLocal(String name);
/**
* Load a resource which is locally defined by this loader. The given name is a path separated
* by "{@code /}" characters.
*
* @param name the resource path
* @return the resource or resources, or an empty list if there is no local resource with this name
*/
List loadResourceLocal(String name);
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalLoaders.java 0000664 0000000 0000000 00000007744 12572057235 0026604 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* Static factory methods for various types of local loaders.
*
* @apiviz.exclude
*
* @author David M. Lloyd
*/
public final class LocalLoaders {
private LocalLoaders() {
}
/**
* Create a filtered local loader.
*
* @param pathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createPathFilteredLocalLoader(final PathFilter pathFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param pathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterablePathFilteredLocalLoader(final PathFilter pathFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(ClassFilters.acceptAll(), pathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createClassFilteredLocalLoader(final ClassFilter classFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterableClassFilteredLocalLoader(final ClassFilter classFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(classFilter, PathFilters.acceptAll(), originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param resourcePathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static LocalLoader createFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final LocalLoader originalLoader) {
return new FilteredLocalLoader(classFilter, resourcePathFilter, originalLoader);
}
/**
* Create a filtered local loader.
*
* @param classFilter the class filter to apply to classes
* @param resourcePathFilter the path filter to apply to resources
* @param originalLoader the original loader
* @return the filtered loader
*/
public static IterableLocalLoader createIterableFilteredLocalLoader(final ClassFilter classFilter, final PathFilter resourcePathFilter, final IterableLocalLoader originalLoader) {
return new FilteredIterableLocalLoader(classFilter, resourcePathFilter, originalLoader);
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalModuleFinder.java 0000664 0000000 0000000 00000022125 12572057235 0027556 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
import static java.security.AccessController.doPrivileged;
import static java.security.AccessController.getContext;
/**
* A module finder which locates module specifications which are stored in a local module
* repository on the filesystem, which uses {@code module.xml} descriptors.
*
* @author David M. Lloyd
*/
public final class LocalModuleFinder implements ModuleFinder {
private static final File[] NO_FILES = new File[0];
private final File[] repoRoots;
private final PathFilter pathFilter;
private final AccessControlContext accessControlContext;
private LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter, final boolean cloneRoots) {
this.repoRoots = cloneRoots && repoRoots.length > 0 ? repoRoots.clone() : repoRoots;
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
for (File repoRoot : this.repoRoots) {
if (repoRoot == null) sm.checkPermission(new FilePermission(new File(repoRoot, "-").getPath(), "read"));
}
}
this.pathFilter = pathFilter;
this.accessControlContext = AccessController.getContext();
}
/**
* Construct a new instance.
*
* @param repoRoots the repository roots to use
* @param pathFilter the path filter to use
*/
public LocalModuleFinder(final File[] repoRoots, final PathFilter pathFilter) {
this(repoRoots, pathFilter, true);
}
/**
* Construct a new instance.
*
* @param repoRoots the repository roots to use
*/
public LocalModuleFinder(final File[] repoRoots) {
this(repoRoots, PathFilters.acceptAll());
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*
* This is equivalent to a call to {@link LocalModuleFinder#LocalModuleFinder(boolean) LocalModuleFinder(true)}.
*
*/
public LocalModuleFinder() {
this(true);
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*
* @param supportLayersAndAddOns {@code true} if the identified module repository roots should be checked for
* an internal structure of child "layer" and "add-on" directories that may also
* be treated as module roots lower in precedence than the parent root. Any "layers"
* subdirectories whose names are specified in a {@code layers.conf} file found in
* the module repository root will be added in the precedence of order specified
* in the {@code layers.conf} file; all "add-on" subdirectories will be added at
* a lower precedence than all "layers" and with no guaranteed precedence order
* between them. If {@code false} no check for "layer" and "add-on" directories
* will be performed.
*
*/
public LocalModuleFinder(boolean supportLayersAndAddOns) {
this(getRepoRoots(supportLayersAndAddOns), PathFilters.acceptAll(), false);
}
static File[] getRepoRoots(final boolean supportLayersAndAddOns) {
return supportLayersAndAddOns ? LayeredModulePathFactory.resolveLayeredModulePath(getModulePathFiles()) : getModulePathFiles();
}
private static File[] getModulePathFiles() {
return getFiles(System.getProperty("module.path", System.getenv("JAVA_MODULEPATH")), 0, 0);
}
private static File[] getFiles(final String modulePath, final int stringIdx, final int arrayIdx) {
if (modulePath == null) return NO_FILES;
final int i = modulePath.indexOf(File.pathSeparatorChar, stringIdx);
final File[] files;
if (i == -1) {
files = new File[arrayIdx + 1];
files[arrayIdx] = new File(modulePath.substring(stringIdx)).getAbsoluteFile();
} else {
files = getFiles(modulePath, i + 1, arrayIdx + 1);
files[arrayIdx] = new File(modulePath.substring(stringIdx, i)).getAbsoluteFile();
}
return files;
}
private static String toPathString(ModuleIdentifier moduleIdentifier) {
final StringBuilder builder = new StringBuilder(40);
builder.append(moduleIdentifier.getName().replace('.', File.separatorChar));
builder.append(File.separatorChar).append(moduleIdentifier.getSlot());
builder.append(File.separatorChar);
return builder.toString();
}
public ModuleSpec findModule(final ModuleIdentifier identifier, final ModuleLoader delegateLoader) throws ModuleLoadException {
final String child = toPathString(identifier);
if (pathFilter.accept(child)) {
try {
return doPrivileged(new PrivilegedExceptionAction() {
public ModuleSpec run() throws Exception {
for (File root : repoRoots) {
final File file = new File(root, child);
final File moduleXml = new File(file, "module.xml");
if (moduleXml.exists()) {
final ModuleSpec spec = ModuleXmlParser.parseModuleXml(delegateLoader, identifier, file, moduleXml, accessControlContext);
if (spec == null) break;
return spec;
}
}
return null;
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
try {
throw e.getException();
} catch (RuntimeException e1) {
throw e1;
} catch (ModuleLoadException e1) {
throw e1;
} catch (Error e1) {
throw e1;
} catch (Exception e1) {
throw new UndeclaredThrowableException(e1);
}
}
}
return null;
}
/**
* Parse a {@code module.xml} file and return the corresponding module specification.
*
* @param identifier the identifier to load
* @param delegateLoader the delegate module loader to use for module specifications
* @param roots the repository root paths to search
* @return the module specification
* @throws IOException if reading the module file failed
* @throws ModuleLoadException if creating the module specification failed (e.g. due to a parse error)
*/
public static ModuleSpec parseModuleXmlFile(final ModuleIdentifier identifier, final ModuleLoader delegateLoader, final File... roots) throws IOException, ModuleLoadException {
final String child = toPathString(identifier);
for (File root : roots) {
final File file = new File(root, child);
final File moduleXml = new File(file, "module.xml");
if (moduleXml.exists()) {
final ModuleSpec spec = ModuleXmlParser.parseModuleXml(delegateLoader, identifier, file, moduleXml, getContext());
if (spec == null) break;
return spec;
}
}
return null;
}
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("local module finder @").append(Integer.toHexString(hashCode())).append(" (roots: ");
final int repoRootsLength = repoRoots.length;
for (int i = 0; i < repoRootsLength; i++) {
final File root = repoRoots[i];
b.append(root);
if (i != repoRootsLength - 1) {
b.append(',');
}
}
b.append(')');
return b.toString();
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/LocalModuleLoader.java 0000664 0000000 0000000 00000004327 12572057235 0027561 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.File;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
/**
* A local filesystem-backed module loader.
*
* @author John Bailey
* @author David M. Lloyd
*/
public final class LocalModuleLoader extends ModuleLoader {
/**
* Construct a new instance.
*
* @param repoRoots the array of repository roots to look for modules
*/
public LocalModuleLoader(final File[] repoRoots) {
this(repoRoots, PathFilters.acceptAll());
}
/**
* Construct a new instance.
*
* @param repoRoots the array of repository roots to look for modules
* @param pathFilter the path filter to apply to roots
*/
public LocalModuleLoader(final File[] repoRoots, final PathFilter pathFilter) {
super(new ModuleFinder[] { new LocalModuleFinder(repoRoots, pathFilter)});
}
/**
* Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable
* to get the list of module repository roots.
*/
public LocalModuleLoader() {
super(new ModuleFinder[] { new LocalModuleFinder() });
}
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("local module loader @").append(Integer.toHexString(hashCode())).append(" (finder: ").append(getFinders()[0]).append(')');
return b.toString();
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Main.java 0000664 0000000 0000000 00000061407 12572057235 0025120 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import __redirected.__JAXPRedirected;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.security.Policy;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.logging.LogManager;
import java.util.jar.Manifest;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jboss.modules.log.JDKModuleLogger;
import static java.security.AccessController.doPrivileged;
import static org.jboss.modules.SecurityActions.setContextClassLoader;
/**
* The main entry point of JBoss Modules when run as a JAR on the command line.
*
* @author David M. Lloyd
* @author Jason T. Greene
* @apiviz.exclude
*/
public final class Main {
static {
// Force initialization at the earliest possible point
@SuppressWarnings("unused")
long start = StartTimeHolder.START_TIME;
}
private static final String[] NO_STRINGS = new String[0];
private Main() {
}
private static void usage() {
System.out.println("Usage: java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -jar [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -cp [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] -class [args...]");
System.out.println(" java [-jvmoptions...] -jar " + getJarName() + ".jar -addindex [-modify] ");
System.out.println("where is a valid module specification string");
System.out.println("and options include:");
System.out.println(" -help Display this message");
System.out.println(" -mp, -modulepath ");
System.out.println(" A list of directories, separated by '" + File.pathSeparator + "', where modules may be located");
System.out.println(" If not specified, the value of the \"module.path\" system property is used");
System.out.println(" -class Specify that the final argument is a");
System.out.println(" class to load from the class path; not compatible with -jar");
System.out.println(" -cp,-classpath ");
System.out.println(" A search path for class files; implies -class");
System.out.println(" -dep,-dependencies [,,...]");
System.out.println(" A list of module dependencies to add to the class path;");
System.out.println(" requires -class or -cp");
System.out.println(" -deptree Print the dependency tree of the given module instead of running it");
System.out.println(" -jar Specify that the final argument is the name of a");
System.out.println(" JAR file to run as a module; not compatible with -class");
System.out.println(" -jaxpmodule ");
System.out.println(" The default JAXP implementation to use of the JDK");
System.out.println(" -secmgr Run with a security manager installed; not compatible with -secmgrmodule");
System.out.println(" -secmgrmodule ");
System.out.println(" Run with a security manager module; not compatible with -secmgr");
System.out.println(" -addindex Specify that the final argument is a");
System.out.println(" jar to create an index for");
System.out.println(" -modify Modify the indexes jar in-place");
System.out.println(" -version Print version and exit\n");
}
/**
* Run JBoss Modules.
*
* @param args the command-line arguments
*
* @throws Throwable if an error occurs
*/
public static void main(String[] args) throws Throwable {
final int argsLen = args.length;
String deps = null;
String[] moduleArgs = NO_STRINGS;
String modulePath = null;
String classpath = null;
boolean jar = false;
boolean classpathDefined = false;
boolean classDefined = false;
boolean depTree = false;
String nameArgument = null;
ModuleIdentifier jaxpModuleIdentifier = null;
boolean defaultSecMgr = false;
String secMgrModule = null;
boolean addIndex = false;
boolean modifyInPlace = false;
for (int i = 0, argsLength = argsLen; i < argsLength; i++) {
final String arg = args[i];
try {
if (arg.charAt(0) == '-') {
// it's an option
if ("-version".equals(arg)) {
System.out.println("JBoss Modules version " + getVersionString());
return;
} else if ("-help".equals(arg)) {
usage();
return;
} else if ("-addindex".equals(arg)) {
addIndex = true;
} else if ("-modify".equals(arg)) {
modifyInPlace = true;
} else if ("-modulepath".equals(arg) || "-mp".equals(arg)) {
if (modulePath != null) {
System.err.println("Module path may only be specified once");
System.exit(1);
}
modulePath = args[++i];
System.setProperty("module.path", modulePath);
} else if ("-config".equals(arg)) {
System.err.println("Config files are no longer supported. Use the -mp option instead");
System.exit(1);
} else if ("-deptree".equals(arg)) {
if (depTree) {
System.err.println("-deptree may only be specified once");
System.exit(1);
}
if (jar) {
System.err.println("-deptree may not be specified with -jar");
System.exit(1);
}
if (classDefined) {
System.err.println("-deptree may not be specified with -class");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-deptree may not be specified with -classpath");
System.exit(1);
}
depTree = true;
} else if ("-jaxpmodule".equals(arg)) {
jaxpModuleIdentifier = ModuleIdentifier.fromString(args[++i]);
} else if ("-jar".equals(arg)) {
if (jar) {
System.err.println("-jar flag may only be specified once");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-cp/-classpath may not be specified with -jar");
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -jar");
System.exit(1);
}
jar = true;
} else if ("-cp".equals(arg) || "-classpath".equals(arg)) {
if (classpathDefined) {
System.err.println("-cp or -classpath may only be specified once.");
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be specified with -cp/classpath");
System.exit(1);
}
if (jar) {
System.err.println("-cp/-classpath may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -classpath");
System.exit(1);
}
classpathDefined = true;
classpath = args[++i];
doPrivileged(new PropertyWriteAction("java.class.path", classpath));
} else if ("-dep".equals(arg) || "-dependencies".equals(arg)) {
if (deps != null) {
System.err.println("-dep or -dependencies may only be specified once.");
System.exit(1);
}
deps = args[++i];
} else if ("-class".equals(arg)) {
if (classDefined) {
System.err.println("-class flag may only be specified once");
System.exit(1);
}
if (classpathDefined) {
System.err.println("-class may not be specified with -cp/classpath");
System.exit(1);
}
if (jar) {
System.err.println("-class may not be specified with -jar");
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be specified with -class");
System.exit(1);
}
classDefined = true;
} else if ("-logmodule".equals(arg)) {
System.err.println("WARNING: -logmodule is deprecated. Please use the system property 'java.util.logging.manager' or the 'java.util.logging.LogManager' service loader.");
i++;
} else if ("-secmgr".equals(arg)) {
if (defaultSecMgr) {
System.err.println("-secmgr may only be specified once");
System.exit(1);
}
if (secMgrModule != null) {
System.err.println("-secmgr may not be specified when -secmgrmodule is given");
System.exit(1);
}
defaultSecMgr = true;
} else if ("-secmgrmodule".equals(arg)) {
if (secMgrModule != null) {
System.err.println("-secmgrmodule may only be specified once");
System.exit(1);
}
if (defaultSecMgr) {
System.err.println("-secmgrmodule may not be specified when -secmgr is given");
System.exit(1);
}
secMgrModule = args[++i];
} else {
System.err.printf("Invalid option '%s'\n", arg);
usage();
System.exit(1);
}
} else {
// it's the module specification
nameArgument = arg;
int cnt = argsLen - i - 1;
moduleArgs = new String[cnt];
System.arraycopy(args, i + 1, moduleArgs, 0, cnt);
break;
}
} catch (IndexOutOfBoundsException e) {
System.err.printf("Argument expected for option %s\n", arg);
usage();
System.exit(1);
}
}
if (modifyInPlace && ! addIndex) {
System.err.println("-modify requires -addindex");
usage();
System.exit(1);
}
if (addIndex) {
if (nameArgument == null) {
System.err.println("-addindex requires a target JAR name");
usage();
System.exit(1);
}
if (modulePath != null) {
System.err.println("-mp may not be used with -addindex");
usage();
System.exit(1);
}
if (jaxpModuleIdentifier != null) {
System.err.println("-jaxpModuleIdentifier may not be used with -addindex");
usage();
System.exit(1);
}
if (classpathDefined) {
System.err.println("-cp or -classpath may not be used with -addindex");
usage();
System.exit(1);
}
if (classDefined) {
System.err.println("-class may not be used with -addindex");
usage();
System.exit(1);
}
if (jar) {
System.err.println("-jar may not be used with -addindex");
usage();
System.exit(1);
}
if (deps != null) {
System.err.println("-deps may not be used with -addindex");
usage();
System.exit(1);
}
if (defaultSecMgr) {
System.err.println("-secmgr may not be used with -addindex");
usage();
System.exit(1);
}
if (secMgrModule != null) {
System.err.println("-secmgrmodule may not be used with -addindex");
usage();
System.exit(1);
}
if (depTree) {
System.err.println("-deptree may not be used with -addindex");
usage();
System.exit(1);
}
JarFileResourceLoader.addInternalIndex(new File(nameArgument), modifyInPlace);
return;
}
if (deps != null && ! classDefined && ! classpathDefined) {
System.err.println("-deps may only be specified when -cp/-classpath or -class is in use");
System.exit(1);
}
// run the module
if (nameArgument == null) {
if (classDefined || classpathDefined) {
System.err.println("No class name specified");
} else if (jar) {
System.err.println("No JAR specified");
} else {
System.err.println("No module specified");
}
usage();
System.exit(1);
}
if (depTree) {
DependencyTreeViewer.print(new PrintWriter(System.out), ModuleIdentifier.fromString(nameArgument), LocalModuleFinder.getRepoRoots(true));
System.exit(0);
}
final ModuleLoader loader;
final ModuleLoader environmentLoader;
environmentLoader = DefaultBootModuleLoaderHolder.INSTANCE;
final ModuleIdentifier moduleIdentifier;
if (jar) {
loader = new JarModuleLoader(environmentLoader, new JarFile(nameArgument));
moduleIdentifier = ((JarModuleLoader) loader).getMyIdentifier();
} else if (classpathDefined || classDefined) {
loader = new ClassPathModuleLoader(environmentLoader, nameArgument, classpath, deps);
moduleIdentifier = ModuleIdentifier.CLASSPATH;
} else {
loader = environmentLoader;
moduleIdentifier = ModuleIdentifier.fromString(nameArgument);
}
Module.initBootModuleLoader(loader);
if (jaxpModuleIdentifier != null) {
__JAXPRedirected.changeAll(jaxpModuleIdentifier, Module.getBootModuleLoader());
} else {
__JAXPRedirected.changeAll(moduleIdentifier, Module.getBootModuleLoader());
}
final Module module;
try {
module = loader.loadModule(moduleIdentifier);
} catch (ModuleNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
return;
}
final String ourJavaVersion = doPrivileged(new PropertyReadAction("java.specification.version", "1.6"));
final String requireJavaVersion = module.getProperty("jboss.require-java-version", ourJavaVersion);
final Pattern versionPattern = Pattern.compile("1\\.(\\d+)");
final Matcher requireMatcher = versionPattern.matcher(requireJavaVersion);
final Matcher ourMatcher = versionPattern.matcher(ourJavaVersion);
if (requireMatcher.matches() && ourMatcher.matches() && Integer.valueOf(requireMatcher.group(1)) > Integer.valueOf(ourMatcher.group(1))) {
System.err.printf("This application requires Java specification version %s or later to run (this Java virtual machine implements specification version %s)%n", requireJavaVersion, ourJavaVersion);
System.exit(1);
}
ModularURLStreamHandlerFactory.addHandlerModule(module);
ModularContentHandlerFactory.addHandlerModule(module);
// at this point, having a security manager already installed will prevent correct operation.
final SecurityManager existingSecMgr = System.getSecurityManager();
if (existingSecMgr != null) {
System.err.println("An existing security manager was detected. You must use the -secmgr switch to start with a security manager.");
System.exit(1);
return; // not reached
}
try {
final Iterator iterator = module.loadService(Policy.class).iterator();
if (iterator.hasNext()) {
Policy.setPolicy(iterator.next());
}
} catch (Exception ignored) {}
// configure policy so that if SM is enabled, modules can still function
final ModulesPolicy policy = new ModulesPolicy(Policy.getPolicy());
Policy.setPolicy(policy);
if (secMgrModule != null) {
final Module loadedModule;
try {
loadedModule = loader.loadModule(ModuleIdentifier.fromString(secMgrModule));
} catch (ModuleNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
return;
}
final Iterator iterator = ServiceLoader.load(SecurityManager.class, loadedModule.getClassLoaderPrivate()).iterator();
if (iterator.hasNext()) {
System.setSecurityManager(iterator.next());
} else {
System.err.println("No security manager found in module " + secMgrModule);
System.exit(1);
}
}
if (defaultSecMgr) {
final Iterator iterator = module.loadService(SecurityManager.class).iterator();
if (iterator.hasNext()) {
System.setSecurityManager(iterator.next());
} else {
System.setSecurityManager(new SecurityManager());
}
}
final ModuleClassLoader bootClassLoader = module.getClassLoaderPrivate();
setContextClassLoader(bootClassLoader);
final String serviceName = getServiceName(bootClassLoader, "java.util.prefs.PreferencesFactory");
if (serviceName != null) {
final String old = System.setProperty("java.util.prefs.PreferencesFactory", serviceName);
try {
Preferences.systemRoot();
} finally {
if (old == null) {
System.clearProperty("java.util.prefs.PreferencesFactory");
} else {
System.setProperty("java.util.prefs.PreferencesFactory", old);
}
}
}
final String logManagerName = getServiceName(bootClassLoader, "java.util.logging.LogManager");
if (logManagerName != null) {
System.setProperty("java.util.logging.manager", logManagerName);
if (LogManager.getLogManager().getClass() == LogManager.class) {
System.err.println("WARNING: Failed to load the specified log manager class " + logManagerName);
} else {
Module.setModuleLogger(new JDKModuleLogger());
}
}
final String mbeanServerBuilderName = getServiceName(bootClassLoader, "javax.management.MBeanServerBuilder");
if (mbeanServerBuilderName != null) {
System.setProperty("javax.management.builder.initial", mbeanServerBuilderName);
// Initialize the platform mbean server
ManagementFactory.getPlatformMBeanServer();
}
ModuleLoader.installMBeanServer();
try {
module.run(moduleArgs);
} catch (InvocationTargetException e) {
throw e.getCause();
}
return;
}
private static String getServiceName(ClassLoader classLoader, String className) throws IOException {
final InputStream stream = classLoader.getResourceAsStream("META-INF/services/" + className);
if (stream == null) {
return null;
}
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
final int i = line.indexOf('#');
if (i != -1) {
line = line.substring(0, i);
}
line = line.trim();
if (line.length() == 0) continue;
return line;
}
return null;
} finally {
StreamUtil.safeClose(stream);
}
}
private static final String JAR_NAME;
private static final String VERSION_STRING;
static {
final Enumeration resources;
String jarName = "(unknown)";
String versionString = "(unknown)";
try {
final ClassLoader classLoader = Main.class.getClassLoader();
resources = classLoader == null ? ModuleClassLoader.getSystemResources("META-INF/MANIFEST.MF") : classLoader.getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
final URL url = resources.nextElement();
try {
final InputStream stream = url.openStream();
if (stream != null) try {
final Manifest manifest = new Manifest(stream);
final Attributes mainAttributes = manifest.getMainAttributes();
if (mainAttributes != null && "JBoss Modules".equals(mainAttributes.getValue("Specification-Title"))) {
jarName = mainAttributes.getValue("Jar-Name");
versionString = mainAttributes.getValue("Jar-Version");
}
} finally {
StreamUtil.safeClose(stream);
}
} catch (IOException ignored) {}
}
} catch (IOException ignored) {}
JAR_NAME = jarName;
VERSION_STRING = versionString;
}
/**
* Get the name of the JBoss Modules JAR.
*
* @return the name
*/
public static String getJarName() {
return JAR_NAME;
}
/**
* Get the version string of JBoss Modules.
*
* @return the version string
*/
public static String getVersionString() {
return VERSION_STRING;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/MavenArtifactUtil.java 0000775 0000000 0000000 00000033716 12572057235 0027623 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import static org.jboss.modules.ModuleXmlParser.endOfDocument;
import static org.jboss.modules.ModuleXmlParser.unexpectedContent;
import static org.jboss.modules.xml.XmlPullParser.END_DOCUMENT;
import static org.jboss.modules.xml.XmlPullParser.END_TAG;
import static org.jboss.modules.xml.XmlPullParser.FEATURE_PROCESS_NAMESPACES;
import static org.jboss.modules.xml.XmlPullParser.START_TAG;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.List;
import org.jboss.modules.xml.MXParser;
import org.jboss.modules.xml.XmlPullParser;
import org.jboss.modules.xml.XmlPullParserException;
/**
* Helper class to resolve a maven artifact
*
* @author Bill Burke
* @author Tomaz Cerar
* @version $Revision: 2 $
*/
class MavenArtifactUtil {
private static MavenSettings mavenSettings;
private static final Object settingLoaderMutex = new Object();
public static MavenSettings getSettings() throws IOException {
if (mavenSettings != null) {
return mavenSettings;
}
synchronized (settingLoaderMutex) {
MavenSettings settings = new MavenSettings();
Path m2 = java.nio.file.Paths.get(System.getProperty("user.home"), ".m2");
Path settingsPath = m2.resolve("settings.xml");
if (Files.notExists(settingsPath)) {
String mavenHome = System.getenv("M2_HOME");
if (mavenHome != null) {
settingsPath = java.nio.file.Paths.get(mavenHome, "conf", "settings.xml");
}
}
if (Files.exists(settingsPath)) {
parseSettingsXml(settingsPath, settings);
}
if (settings.getLocalRepository() == null) {
Path repository = m2.resolve("repository");
settings.setLocalRepository(repository);
}
settings.resolveActiveSettings();
mavenSettings = settings;
return mavenSettings;
}
}
private static MavenSettings parseSettingsXml(Path settings, MavenSettings mavenSettings) throws IOException {
try {
final MXParser reader = new MXParser();
reader.setFeature(FEATURE_PROCESS_NAMESPACES, false);
InputStream source = Files.newInputStream(settings, StandardOpenOption.READ);
reader.setInput(source, null);
int eventType;
while ((eventType = reader.next()) != END_DOCUMENT) {
switch (eventType) {
case START_TAG: {
switch (reader.getName()) {
case "settings": {
parseSettings(reader, mavenSettings);
break;
}
}
}
default: {
break;
}
}
}
return mavenSettings;
} catch (XmlPullParserException e) {
throw new IOException("Could not parse maven settings.xml");
}
}
private static void parseSettings(final XmlPullParser reader, MavenSettings mavenSettings) throws XmlPullParserException, IOException {
int eventType;
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
switch (eventType) {
case END_TAG: {
return;
}
case START_TAG: {
switch (reader.getName()) {
case "localRepository": {
String localRepository = reader.nextText();
if (!"".equals(localRepository)) {
mavenSettings.setLocalRepository(java.nio.file.Paths.get(localRepository));
}
break;
}
case "profiles": {
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
if (eventType == START_TAG) {
switch (reader.getName()) {
case "profile": {
parseProfile(reader, mavenSettings);
break;
}
}
} else {
break;
}
}
break;
}
case "activeProfiles": {
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
if (eventType == START_TAG) {
switch (reader.getName()) {
case "activeProfile": {
mavenSettings.addActiveProfile(reader.nextText());
break;
}
}
} else {
break;
}
}
break;
}
default: {
skip(reader);
}
}
break;
}
default: {
throw unexpectedContent(reader);
}
}
}
throw endOfDocument(reader);
}
private static void parseProfile(final XmlPullParser reader, MavenSettings mavenSettings) throws XmlPullParserException, IOException {
int eventType;
MavenSettings.Profile profile = new MavenSettings.Profile();
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
if (eventType == START_TAG) {
switch (reader.getName()) {
case "id": {
profile.setId(reader.nextText());
break;
}
case "repositories": {
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
if (eventType == START_TAG) {
switch (reader.getName()) {
case "repository": {
parseRepository(reader, profile);
break;
}
}
} else {
break;
}
}
break;
}
default: {
skip(reader);
}
}
} else {
break;
}
}
mavenSettings.addProfile(profile);
}
private static void parseRepository(final XmlPullParser reader, MavenSettings.Profile profile) throws XmlPullParserException, IOException {
int eventType;
while ((eventType = reader.nextTag()) != END_DOCUMENT) {
if (eventType == START_TAG) {
switch (reader.getName()) {
case "url": {
profile.addRepository(reader.nextText());
break;
}
default: {
skip(reader);
}
}
} else {
break;
}
}
}
private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
private static final Object artifactLock = new Object();
/**
* Tries to find a maven jar artifact from the system property "local.maven.repo.path" This property is a list of
* platform separated directory names. If not specified, then it looks in ${user.home}/.m2/repository by default.
*
* If it can't find it in local paths, then will try to download from a remote repository from the system property
* "remote.maven.repo". There is no default remote repository. It will download both the pom and jar and put it
* into the first directory listed in "local.maven.repo.path" (or the default dir). This directory will be created
* if it doesn't exist.
*
* Finally, if you do not want a message to console, then set the system property "maven.download.message" to
* "false"
*
* @param qualifier group:artifact:version[:classifier]
* @return absolute path to artifact, null if none exists
* @throws IOException
*/
public static File resolveJarArtifact(String qualifier) throws IOException {
String[] split = qualifier.split(":");
if (split.length < 3) {
throw new IllegalArgumentException("Illegal artifact " + qualifier);
}
String groupId = split[0];
String artifactId = split[1];
String version = split[2];
String classifier = "";
if (split.length >= 4) { classifier = "-" + split[3]; }
String artifactRelativePath = relativeArtifactPath(groupId, artifactId, version);
String artifactRelativeHttpPath = relativeArtifactHttpPath(groupId, artifactId, version);
final MavenSettings settings = getSettings();
final Path localRepository = settings.getLocalRepository();
// serialize artifact lookup because we want to prevent parallel download
synchronized (artifactLock) {
String jarPath = artifactRelativePath + classifier + ".jar";
Path fp = java.nio.file.Paths.get(localRepository.toString(), jarPath);
if (Files.exists(fp)) {
return fp.toFile();
}
List remoteRepos = mavenSettings.getRemoteRepositories();
if (remoteRepos.isEmpty()) {
return null;
}
final File jarFile = new File(localRepository.toFile(), jarPath);
final File pomFile = new File(localRepository.toFile(), artifactRelativePath + ".pom");
for (String remoteRepository : remoteRepos) {
try {
String remotePomPath = remoteRepository + artifactRelativeHttpPath + ".pom";
String remoteJarPath = remoteRepository + artifactRelativeHttpPath + classifier + ".jar";
downloadFile(qualifier + ":pom", remotePomPath, pomFile);
downloadFile(qualifier + ":jar", remoteJarPath, jarFile);
if (jarFile.exists()) { //download successful
return jarFile;
}
} catch (IOException e) {
Module.log.trace(e, "Could not download '%s' from '%s' repository", artifactRelativePath, remoteRepository);
//
}
}
//could not find it in remote
Module.log.trace("Could not find in any remote repository");
return null;
}
}
public static String relativeArtifactPath(String groupId, String artifactId, String version) {
return relativeArtifactPath(File.separatorChar, groupId, artifactId, version);
}
public static String relativeArtifactHttpPath(String groupId, String artifactId, String version) {
return relativeArtifactPath('/', groupId, artifactId, version);
}
private static String relativeArtifactPath(char separator, String groupId, String artifactId, String version) {
StringBuilder builder = new StringBuilder(groupId.replace('.', separator));
builder.append(separator).append(artifactId).append(separator).append(version).append(separator).append(artifactId).append('-').append(version);
return builder.toString();
}
public static void downloadFile(String artifact, String src, File dest) throws IOException {
if (dest.exists()){
return;
}
final URL url = new URL(src);
final URLConnection connection = url.openConnection();
boolean message = Boolean.getBoolean("maven.download.message");
try (InputStream bis = connection.getInputStream()){
dest.getParentFile().mkdirs();
if (message) { System.out.println("Downloading " + artifact); }
Files.copy(bis, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/MavenSettings.java 0000664 0000000 0000000 00000005434 12572057235 0027021 0 ustar 00root root 0000000 0000000 package org.jboss.modules;
import java.io.File;
import java.nio.file.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author Tomaz Cerar (c) 2014 Red Hat Inc.
*/
final class MavenSettings {
private Path localRepository;
private final List remoteRepositories = new LinkedList<>();
private final Map profiles = new HashMap<>();
private final List activeProfileNames = new LinkedList<>();
MavenSettings() {
configureDefaults();
}
void configureDefaults() {
//always add maven central
remoteRepositories.add("https://repo1.maven.org/maven2/");
String localRepositoryPath = System.getProperty("local.maven.repo.path");
if (localRepositoryPath != null) {
System.out.println("Please use 'maven.repo.local' instead of 'local.maven.repo.path'");
localRepository = java.nio.file.Paths.get(localRepositoryPath.split(File.pathSeparator)[0]);
}
localRepositoryPath = System.getProperty("maven.repo.local");
if (localRepositoryPath != null) {
localRepository = java.nio.file.Paths.get(localRepositoryPath);
}
String remoteRepository = System.getProperty("remote.maven.repo");
if (remoteRepository != null) {
if (!remoteRepository.endsWith("/")) {
remoteRepository += "/";
}
remoteRepositories.add(remoteRepository);
}
}
public void setLocalRepository(Path localRepository) {
this.localRepository = localRepository;
}
public Path getLocalRepository() {
return localRepository;
}
public List getRemoteRepositories() {
return remoteRepositories;
}
public void addProfile(Profile profile) {
this.profiles.put(profile.getId(), profile);
}
public void addActiveProfile(String profileName) {
activeProfileNames.add(profileName);
}
void resolveActiveSettings() {
for (String name : activeProfileNames) {
Profile p = profiles.get(name);
if (p != null) {
remoteRepositories.addAll(p.getRepositories());
}
}
}
static final class Profile {
private String id;
final List repositories = new LinkedList<>();
Profile() {
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void addRepository(String url) {
if (!url.endsWith("/")) {
url += "/";
}
repositories.add(url);
}
public List getRepositories() {
return repositories;
}
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Metrics.java 0000664 0000000 0000000 00000002602 12572057235 0025632 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.security.AccessController;
/**
* @author David M. Lloyd
*/
final class Metrics {
static final boolean ENABLED;
static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean();
private Metrics() {
}
static long getCurrentCPUTime() {
return ENABLED ? false ? THREAD_MX_BEAN.getCurrentThreadCpuTime() : System.nanoTime() : 0L;
}
static {
ENABLED = Boolean.parseBoolean(AccessController.doPrivileged(new PropertyReadAction("jboss.modules.metrics", "false")));
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModularContentHandlerFactory.java 0000664 0000000 0000000 00000006705 12572057235 0032020 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author David M. Lloyd
*/
final class ModularContentHandlerFactory implements ContentHandlerFactory {
private static final PrivilegedAction CONTENT_MODULES_LIST_ACTION = new PropertyReadAction("jboss.content.handler.modules");
private static final List modules;
static {
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
final SecurityManager sm = System.getSecurityManager();
final String urlModulesList;
if (sm != null) {
urlModulesList = AccessController.doPrivileged(CONTENT_MODULES_LIST_ACTION);
} else {
urlModulesList = CONTENT_MODULES_LIST_ACTION.run();
}
if (urlModulesList != null) {
final List moduleList = new ArrayList();
int f = 0;
int i;
do {
i = urlModulesList.indexOf('|', f);
final String moduleId = (i == -1 ? urlModulesList.substring(f) : urlModulesList.substring(f, i)).trim();
if (moduleId.length() > 0) {
try {
final ModuleIdentifier identifier = ModuleIdentifier.fromString(moduleId);
Module module = Module.getBootModuleLoader().loadModule(identifier);
moduleList.add(module);
} catch (RuntimeException e) {
// skip it
} catch (ModuleLoadException e) {
// skip it
}
}
f = i + 1;
} while (i != -1);
list.addAll(moduleList);
}
modules = list;
}
static final ModularContentHandlerFactory INSTANCE = new ModularContentHandlerFactory();
static void addHandlerModule(Module module) {
modules.add(module);
}
public ContentHandler createContentHandler(final String mimeType) {
for (Module module : modules) {
ServiceLoader loader = module.loadService(ContentHandlerFactory.class);
for (ContentHandlerFactory factory : loader) try {
final ContentHandler handler = factory.createContentHandler(mimeType);
if (handler != null) {
return handler;
}
} catch (RuntimeException e) {
// ignored
}
}
return null;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/ModularURLStreamHandlerFactory.java 0000664 0000000 0000000 00000011016 12572057235 0032213 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The root URL stream handler factory for the module system.
*
* @author David M. Lloyd
*/
final class ModularURLStreamHandlerFactory implements URLStreamHandlerFactory {
private static final PrivilegedAction URL_MODULES_LIST_ACTION = new PropertyReadAction("jboss.protocol.handler.modules");
private static final List modules;
private static final ThreadLocal> reentered = new ThreadLocal>() {
protected Set initialValue() {
return new FastCopyHashSet();
}
};
static {
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
final SecurityManager sm = System.getSecurityManager();
final String urlModulesList;
if (sm != null) {
urlModulesList = AccessController.doPrivileged(URL_MODULES_LIST_ACTION);
} else {
urlModulesList = URL_MODULES_LIST_ACTION.run();
}
if (urlModulesList != null) {
final List moduleList = new ArrayList();
int f = 0;
int i;
do {
i = urlModulesList.indexOf('|', f);
final String moduleId = (i == -1 ? urlModulesList.substring(f) : urlModulesList.substring(f, i)).trim();
if (moduleId.length() > 0) {
try {
final ModuleIdentifier identifier = ModuleIdentifier.fromString(moduleId);
Module module = Module.getBootModuleLoader().loadModule(identifier);
moduleList.add(module);
} catch (RuntimeException e) {
// skip it
} catch (ModuleLoadException e) {
// skip it
}
}
f = i + 1;
} while (i != -1);
list.addAll(moduleList);
}
modules = list;
}
static final ModularURLStreamHandlerFactory INSTANCE = new ModularURLStreamHandlerFactory();
static void addHandlerModule(Module module) {
modules.add(module);
}
private ModularURLStreamHandlerFactory() {
}
private URLStreamHandler locateHandler(final String protocol) {
for (Module module : modules) {
ServiceLoader loader = module.loadService(URLStreamHandlerFactory.class);
for (URLStreamHandlerFactory factory : loader) {
try {
final URLStreamHandler handler = factory.createURLStreamHandler(protocol);
if (handler != null) {
return handler;
}
} catch (RuntimeException e) {
// ignored
}
}
}
return null;
}
public URLStreamHandler createURLStreamHandler(final String protocol) {
final Set set = reentered.get();
if (set.add(protocol)) {
try {
if (System.getSecurityManager() == null) {
return locateHandler(protocol);
}
return AccessController.doPrivileged(new PrivilegedAction() {
public URLStreamHandler run() {
return locateHandler(protocol);
}
});
} finally {
set.remove(protocol);
}
}
return null;
}
}
jboss-modules-1.4.4.Final/src/main/java/org/jboss/modules/Module.java 0000664 0000000 0000000 00000176516 12572057235 0025471 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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.
*/
package org.jboss.modules;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.jboss.modules._private.ModulesPrivateAccess;
import org.jboss.modules.filter.ClassFilter;
import org.jboss.modules.filter.ClassFilters;
import org.jboss.modules.filter.PathFilter;
import org.jboss.modules.filter.PathFilters;
import org.jboss.modules.log.ModuleLogger;
import org.jboss.modules.log.NoopModuleLogger;
import __redirected.__JAXPRedirected;
import org.jboss.modules.security.ModularPermissionFactory;
/**
* A module is a unit of classes and other resources, along with the specification of what is imported and exported
* by this module from and to other modules. Modules are created by {@link ModuleLoader}s which build modules from
* various configuration information and resource roots.
*
* @author David M. Lloyd
* @author John Bailey
* @author Flavia Rainone
* @author Jason T. Greene
* @author thomas.diesler@jboss.com
*
* @apiviz.landmark
*/
public final class Module {
private static final AtomicReference BOOT_MODULE_LOADER;
static {
log = NoopModuleLogger.getInstance();
BOOT_MODULE_LOADER = new AtomicReference();
EMPTY_CLASS_FILTERS = new FastCopyHashSet(0);
EMPTY_PATH_FILTERS = new FastCopyHashSet(0);
GET_DEPENDENCIES = new RuntimePermission("getDependencies");
GET_CLASS_LOADER = new RuntimePermission("getClassLoader");
GET_BOOT_MODULE_LOADER = new RuntimePermission("getBootModuleLoader");
ACCESS_MODULE_LOGGER = new RuntimePermission("accessModuleLogger");
ADD_CONTENT_HANDLER_FACTORY = new RuntimePermission("addContentHandlerFactory");
ADD_URL_STREAM_HANDLER_FACTORY = new RuntimePermission("addURLStreamHandlerFactory");
final String pkgsString = AccessController.doPrivileged(new PropertyReadAction("jboss.modules.system.pkgs"));
final List list = new ArrayList();
list.add("java.");
list.add("sun.reflect.");
list.add("__redirected.");
if (pkgsString != null) {
int i;
int nc = -1;
do {
i = nc + 1;
nc = pkgsString.indexOf(',', i);
String part;
if (nc == -1) {
part = pkgsString.substring(i).trim();
} else {
part = pkgsString.substring(i, nc).trim();
}
if (part.length() > 0) {
list.add((part + ".").intern());
}
} while (nc != -1);
}
systemPackages = list.toArray(list.toArray(new String[list.size()]));
final ListIterator iterator = list.listIterator();
// http://youtrack.jetbrains.net/issue/IDEA-72097
//noinspection WhileLoopReplaceableByForEach
while (iterator.hasNext()) {
iterator.set(iterator.next().replace('.', '/'));
}
systemPaths = list.toArray(list.toArray(new String[list.size()]));
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
try {
URL.setURLStreamHandlerFactory(ModularURLStreamHandlerFactory.INSTANCE);
} catch (Throwable t) {
// todo log a warning or something
}
try {
URLConnection.setContentHandlerFactory(ModularContentHandlerFactory.INSTANCE);
} catch (Throwable t) {
// todo log a warning or something
}
__JAXPRedirected.initAll();
return null;
}
});
}
// static properties
static final String[] systemPackages;
static final String[] systemPaths;
static final ModulesPrivateAccess PRIVATE_ACCESS = new ModulesPrivateAccess() {
public ModuleClassLoader getClassLoaderOf(final Module module) {
return module.getClassLoaderPrivate();
}
};
/**
* Private access for module internal code. Throws {@link SecurityException} for user code.
*
* @throws SecurityException always
*/
public static ModulesPrivateAccess getPrivateAccess() {
if (CallerContext.getCallingClass() == ModularPermissionFactory.class) {
return PRIVATE_ACCESS;
}
throw new SecurityException();
}
/**
* The system-wide module logger, which may be changed via {@link #setModuleLogger(org.jboss.modules.log.ModuleLogger)}.
*/
static volatile ModuleLogger log;
private static final FastCopyHashSet EMPTY_CLASS_FILTERS;
private static final FastCopyHashSet EMPTY_PATH_FILTERS;
// immutable properties
/**
* The identifier of this module.
*/
private final ModuleIdentifier identifier;
/**
* The name of the main class, if any (may be {@code null}).
*/
private final String mainClassName;
/**
* The module class loader for this module.
*/
private final ModuleClassLoader moduleClassLoader;
/**
* The module loader which created this module.
*/
private final ModuleLoader moduleLoader;
/**
* The fallback local loader, if any is defined.
*/
private final LocalLoader fallbackLoader;
/**
* The properties map specified when this module was defined.
*/
private final Map properties;
/**
* The assigned permission collection.
*/
private final PermissionCollection permissionCollection;
// mutable properties
/**
* The linkage state.
*/
private volatile Linkage linkage = Linkage.NONE;
// private constants
private static final RuntimePermission GET_DEPENDENCIES;
private static final RuntimePermission GET_CLASS_LOADER;
private static final RuntimePermission GET_BOOT_MODULE_LOADER;
private static final RuntimePermission ACCESS_MODULE_LOGGER;
private static final RuntimePermission ADD_CONTENT_HANDLER_FACTORY;
private static final RuntimePermission ADD_URL_STREAM_HANDLER_FACTORY;
/**
* Construct a new instance from a module specification.
*
* @param spec the module specification
* @param moduleLoader the module loader
*/
Module(final ConcreteModuleSpec spec, final ModuleLoader moduleLoader) {
this.moduleLoader = moduleLoader;
// Initialize state from the spec.
identifier = spec.getModuleIdentifier();
mainClassName = spec.getMainClass();
fallbackLoader = spec.getFallbackLoader();
permissionCollection = spec.getPermissionCollection();
//noinspection ThisEscapedInObjectConstruction
final ModuleClassLoader.Configuration configuration = new ModuleClassLoader.Configuration(this, spec.getAssertionSetting(), spec.getResourceLoaders(), spec.getClassFileTransformer());
final ModuleClassLoaderFactory factory = spec.getModuleClassLoaderFactory();
ModuleClassLoader moduleClassLoader = null;
if (factory != null) moduleClassLoader = factory.create(configuration);
if (moduleClassLoader == null) moduleClassLoader = new ModuleClassLoader(configuration);
this.moduleClassLoader = moduleClassLoader;
final Map properties = spec.getProperties();
this.properties = properties.isEmpty() ? Collections.emptyMap() : new LinkedHashMap(properties);
}
LocalLoader getFallbackLoader() {
return fallbackLoader;
}
Dependency[] getDependenciesInternal() {
return linkage.getDependencies();
}
DependencySpec[] getDependencySpecsInternal() {
return linkage.getDependencySpecs();
}
ModuleClassLoader getClassLoaderPrivate() {
return moduleClassLoader;
}
/**
* Get the current dependencies of this module.
*
* @return the current dependencies of this module
* @throws SecurityException if a security manager is enabled and the caller does not have the {@code getDependencies}
* {@link RuntimePermission}
*/
public DependencySpec[] getDependencies() throws SecurityException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(GET_DEPENDENCIES);
}
return getDependencySpecsInternal().clone();
}
/**
* Get an exported resource from a specific root in this module.
*
* @param rootPath the module root to search
* @param resourcePath the path of the resource
* @return the resource
*/
public Resource getExportedResource(final String rootPath, final String resourcePath) {
return moduleClassLoader.loadResourceLocal(rootPath, resourcePath);
}
/**
* Run a module's main class, if any.
*
* @param args the arguments to pass
* @throws NoSuchMethodException if there is no main method
* @throws InvocationTargetException if the main method failed
* @throws ClassNotFoundException if the main class is not found
*/
public void run(final String[] args) throws NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
try {
if (mainClassName == null) {
throw new NoSuchMethodException("No main class defined for " + this);
}
final ClassLoader oldClassLoader = SecurityActions.setContextClassLoader(moduleClassLoader);
try {
final Class> mainClass = Class.forName(mainClassName, false, moduleClassLoader);
try {
Class.forName(mainClassName, true, moduleClassLoader);
} catch (Throwable t) {
throw new InvocationTargetException(t, "Failed to initialize main class '" + mainClassName + "'");
}
final Method mainMethod = mainClass.getMethod("main", String[].class);
final int modifiers = mainMethod.getModifiers();
if (! Modifier.isStatic(modifiers)) {
throw new NoSuchMethodException("Main method is not static for " + this);
}
// ignore the return value
mainMethod.invoke(null, new Object[] {args});
} finally {
SecurityActions.setContextClassLoader(oldClassLoader);
}
} catch (IllegalAccessException e) {
// unexpected; should be public
throw new IllegalAccessError(e.getMessage());
}
}
/**
* Get this module's identifier.
*
* @return the identifier
*/
public ModuleIdentifier getIdentifier() {
return identifier;
}
/**
* Get the module loader which created this module.
*
* @return the module loader of this module
*/
public ModuleLoader getModuleLoader() {
return moduleLoader;
}
/**
* Load a service loader from this module.
*
* @param serviceType the service type class
* @param the service type
* @return the service loader
*/
public ServiceLoader loadService(Class serviceType) {
return ServiceLoader.load(serviceType, moduleClassLoader);
}
/**
* Load a service loader from a module in the caller's module loader. The caller's
* module loader refers to the loader of the module of the class that calls this method.
* Note that {@link #loadService(Class)} is more efficient since it does not need to crawl
* the stack.
*
* @param the the service type
* @param identifier the module identifier containing the service loader
* @param serviceType the service type class
* @return the loaded service from the caller's module
* @throws ModuleLoadException if the named module failed to load
*/
public static ServiceLoader loadServiceFromCallerModuleLoader(ModuleIdentifier identifier, Class serviceType) throws ModuleLoadException {
return getCallerModuleLoader().loadModule(identifier).loadService(serviceType);
}
/**
* Get the class loader for a module. The class loader can be used to access non-exported classes and
* resources of the module.
*
* If a security manager is present, then this method invokes the security manager's {@code checkPermission} method
* with a RuntimePermission("getClassLoader")
permission to verify access to the class loader. If
* access is not granted, a {@code SecurityException} will be thrown.
*
* @return the module class loader
*/
public ModuleClassLoader getClassLoader() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(GET_CLASS_LOADER);
}
return moduleClassLoader;
}
/**
* Get all the paths exported by this module.
*
* @return the paths that are exported by this module
*/
public Set getExportedPaths() {
return Collections.unmodifiableSet(getPathsUnchecked().keySet());
}
/**
* Get the module for a loaded class, or {@code null} if the class did not come from any module.
*
* @param clazz the class
* @return the module it came from
*/
public static Module forClass(Class> clazz) {
final ClassLoader cl = clazz.getClassLoader();
return forClassLoader(cl, false);
}
/**
* Get the module for a class loader, or {@code null} if the class loader is not associated with any module. If
* the class loader is unknown, it is possible to check the parent class loader up the chain, and so on until a module is found.
*
* @param cl the class loader
* @param search {@code true} to search up the delegation chain
* @return the associated module
*/
public static Module forClassLoader(ClassLoader cl, boolean search) {
if (cl instanceof ModuleClassLoader) {
return ((ModuleClassLoader) cl).getModule();
} else if (search && cl != null) {
return forClassLoader(cl.getParent(), true);
} else {
return null;
}
}
/**
* Gets the boot module loader. The boot module loader is the
* initial loader that is established by the module framework. It typically
* is based off of the environmental module path unless it is overridden by
* specifying a different class name for the {@code boot.module.loader} system
* property.
*
* @return the boot module loader
*/
public static ModuleLoader getBootModuleLoader() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(GET_BOOT_MODULE_LOADER);
}
ModuleLoader loader;
while ((loader = BOOT_MODULE_LOADER.get()) == null) {
loader = DefaultBootModuleLoaderHolder.INSTANCE;
if (BOOT_MODULE_LOADER.compareAndSet(null, loader)) {
break;
}
// get it again
}
return loader;
}
static void initBootModuleLoader(ModuleLoader loader) {
BOOT_MODULE_LOADER.set(loader);
}
/**
* Gets the current module loader. The current module loader is the
* loader of the module from the calling class. Note that this method
* must crawl the stack to determine this, so other mechanisms are more
* efficient.
*
* @return the current module loader, or {@code null} if this method is called outside of a module
*/
public static ModuleLoader getCallerModuleLoader() {
Module callerModule = getCallerModule();
return callerModule == null ? null : callerModule.getModuleLoader();
}
/**
* Get the current thread's context module loader. This loader is the one which defined the module
* whose class loader is, or is a parent of, the thread's current context class loader. If there is none,
* then {@code null} is returned.
*
* @return the module loader, or {@code null} if none is set
*/
public static ModuleLoader getContextModuleLoader() {
return Module.forClassLoader(Thread.currentThread().getContextClassLoader(), true).getModuleLoader();
}
/**
* Get a module from the current module loader. Note that this must crawl the
* stack to determine this, so other mechanisms are more efficient.
* @see #getCallerModuleLoader()
*
* @param identifier the module identifier
* @return the module
* @throws ModuleLoadException if the module could not be loaded
*/
public static Module getModuleFromCallerModuleLoader(final ModuleIdentifier identifier) throws ModuleLoadException {
return getCallerModuleLoader().loadModule(identifier);
}
/**
* Get the caller's module. The caller's module is the module containing the method that calls this
* method. Note that this method crawls the stack so other ways of obtaining the
* module are more efficient.
*
* @return the current module
*/
public static Module getCallerModule() {
return forClass(CallerContext.getCallingClass());
}
/**
* Get the module with the given identifier from the module loader used by this module.
*
* @param identifier the module identifier
* @return the module
* @throws ModuleLoadException if an error occurs
*/
public Module getModule(final ModuleIdentifier identifier) throws ModuleLoadException {
return moduleLoader.loadModule(identifier);
}
/**
* Load a class from a module in the system module loader.
*
* @see #getBootModuleLoader()
*
* @param moduleIdentifier the identifier of the module from which the class
* should be loaded
* @param className the class name to load
* @return the class
* @throws ModuleLoadException if the module could not be loaded
* @throws ClassNotFoundException if the class could not be loaded
*/
public static Class> loadClassFromBootModuleLoader(final ModuleIdentifier moduleIdentifier, final String className)
throws ModuleLoadException, ClassNotFoundException {
return Class.forName(className, true, getBootModuleLoader().loadModule(moduleIdentifier).getClassLoader());
}
/**
* Load a class from a module in the caller's module loader.
*
* @see #getCallerModuleLoader()
*
* @param moduleIdentifier the identifier of the module from which the class
* should be loaded
* @param className the class name to load
* @return the class
* @throws ModuleLoadException if the module could not be loaded
* @throws ClassNotFoundException if the class could not be loaded
*/
public static Class> loadClassFromCallerModuleLoader(final ModuleIdentifier moduleIdentifier, final String className)
throws ModuleLoadException, ClassNotFoundException {
return Class.forName(className, true, getModuleFromCallerModuleLoader(moduleIdentifier).getClassLoader());
}
/**
* Load a class from a local loader.
*
* @param className the class name
* @param resolve {@code true} to resolve the class after definition
* @return the class
*/
Class> loadModuleClass(final String className, final boolean resolve) throws ClassNotFoundException {
for (String s : systemPackages) {
if (className.startsWith(s)) {
return moduleClassLoader.loadClass(className, resolve);
}
}
final String path = pathOfClass(className);
final Map> paths = getPathsUnchecked();
final List loaders = paths.get(path);
if (loaders != null) {
Class> clazz;
for (LocalLoader loader : loaders) {
clazz = loader.loadClassLocal(className, resolve);
if (clazz != null) {
return clazz;
}
}
}
final LocalLoader fallbackLoader = this.fallbackLoader;
if (fallbackLoader != null) {
return fallbackLoader.loadClassLocal(className, resolve);
}
return null;
}
/**
* Load a resource from a local loader.
*
* @param name the resource name
* @return the resource URL, or {@code null} if not found
*/
URL getResource(final String name) {
final String canonPath = PathUtils.canonicalize(name);
for (String s : Module.systemPaths) {
if (canonPath.startsWith(s)) {
return moduleClassLoader.getResource(canonPath);
}
}
log.trace("Attempting to find resource %s in %s", canonPath, this);
final String path = pathOf(canonPath);
final Map> paths = getPathsUnchecked();
final List loaders = paths.get(path);
if (loaders != null) {
for (LocalLoader loader : loaders) {
final List resourceList = loader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
return resource.getURL();
}
}
}
final LocalLoader fallbackLoader = this.fallbackLoader;
if (fallbackLoader != null) {
final List resourceList = fallbackLoader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
return resource.getURL();
}
}
return null;
}
/**
* Load a resource from a local loader.
*
* @param name the resource name
* @return the resource stream, or {@code null} if not found
*/
InputStream getResourceAsStream(final String name) throws IOException {
final String canonPath = PathUtils.canonicalize(name);
for (String s : Module.systemPaths) {
if (canonPath.startsWith(s)) {
return moduleClassLoader.getResourceAsStream(canonPath);
}
}
log.trace("Attempting to find resource %s in %s", canonPath, this);
final String path = pathOf(canonPath);
final Map> paths = getPathsUnchecked();
final List loaders = paths.get(path);
if (loaders != null) {
for (LocalLoader loader : loaders) {
final List resourceList = loader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
return resource.openStream();
}
}
}
final LocalLoader fallbackLoader = this.fallbackLoader;
if (fallbackLoader != null) {
final List resourceList = fallbackLoader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
return resource.openStream();
}
}
return null;
}
/**
* Load all resources of a given name from a local loader.
*
* @param name the resource name
* @return the enumeration of all the matching resource URLs (may be empty)
*/
Enumeration getResources(final String name) {
final String canonPath = PathUtils.canonicalize(PathUtils.relativize(name));
for (String s : Module.systemPaths) {
if (canonPath.startsWith(s)) {
try {
return moduleClassLoader.getResources(canonPath);
} catch (IOException e) {
return ConcurrentClassLoader.EMPTY_ENUMERATION;
}
}
}
log.trace("Attempting to find all resources %s in %s", canonPath, this);
final String path = pathOf(canonPath);
final Map> paths = getPathsUnchecked();
final List loaders = paths.get(path);
final List list = new ArrayList();
if (loaders != null) {
for (LocalLoader loader : loaders) {
final List resourceList = loader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
list.add(resource.getURL());
}
}
}
final LocalLoader fallbackLoader = this.fallbackLoader;
if (fallbackLoader != null) {
final List resourceList = fallbackLoader.loadResourceLocal(canonPath);
for (Resource resource : resourceList) {
list.add(resource.getURL());
}
}
return list.size() == 0 ? ConcurrentClassLoader.EMPTY_ENUMERATION : Collections.enumeration(list);
}
/**
* Get an exported resource URL.
*
* @param name the resource name
* @return the resource, or {@code null} if it was not found
*/
public URL getExportedResource(final String name) {
return getResource(name);
}
/**
* Get all exported resource URLs for a resource name.
*
* @param name the resource name
* @return the resource URLs
*/
public Enumeration getExportedResources(final String name) {
return getResources(name);
}
/**
* Enumerate all the imported resources in this module, subject to a path filter. The filter applies to
* the containing path of each resource.
*
* @param filter the filter to apply to the search
* @return the resource iterator (possibly empty)
* @throws ModuleLoadException if linking a dependency module fails for some reason
*/
public Iterator iterateResources(final PathFilter filter) throws ModuleLoadException {
final Map> paths = getPaths();
final Iterator>> iterator = paths.entrySet().iterator();
return new Iterator() {
private String path;
private Iterator resourceIterator;
private Iterator loaderIterator;
private Resource next;
public boolean hasNext() {
while (next == null) {
if (resourceIterator != null) {
assert path != null;
if (resourceIterator.hasNext()) {
next = resourceIterator.next();
return true;
}
resourceIterator = null;
}
if (loaderIterator != null) {
assert path != null;
if (loaderIterator.hasNext()) {
final LocalLoader loader = loaderIterator.next();
if (loader instanceof IterableLocalLoader) {
resourceIterator = ((IterableLocalLoader)loader).iterateResources(path, false);
continue;
}
}
loaderIterator = null;
}
if (! iterator.hasNext()) {
return false;
}
final Map.Entry> entry = iterator.next();
path = entry.getKey();
if (filter.accept(path)) {
loaderIterator = entry.getValue().iterator();
}
}
return true;
}
public Resource next() {
if (! hasNext()) throw new NoSuchElementException();
try {
return next;
} finally {
next = null;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* Enumerate all imported resources in this module which match the given glob expression. The glob applies to
* the whole resource name.
*
* @param glob the glob to apply
* @return the iterator
* @throws ModuleLoadException if linking a dependency module fails for some reason
*/
public Iterator globResources(final String glob) throws ModuleLoadException {
String safeGlob = PathUtils.canonicalize(PathUtils.relativize(glob));
final int i = safeGlob.lastIndexOf('/');
if (i == -1) {
return PathFilters.filtered(PathFilters.match(glob), iterateResources(PathFilters.acceptAll()));
} else {
return PathFilters.filtered(PathFilters.match(glob.substring(i + 1)), iterateResources(PathFilters.match(glob.substring(0, i))));
}
}
/**
* Get the (unmodifiable) set of paths which are imported into this module class loader, including local paths. The
* set will include all paths defined by the module's resource loaders, minus any paths excluded by filters. The
* set will generally always contain an empty entry (""). The set is unordered and unsorted, and is iterable in
* O(n) time and accessible in O(1) time.
*
* @return the set of paths
* @throws ModuleLoadException if the module was previously unlinked, and there was an exception while linking
*/
public final Set