liquibase.resource.CompositeResourceAccessor Maven / Gradle / Ivy
package liquibase.resource;
import liquibase.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* A {@link liquibase.resource.ResourceAccessor} that will search in a list of other ResourceAccessors until it finds
* one that has a resource of the appropriate name and path.
*/
public class CompositeResourceAccessor implements ResourceAccessor {
private List resourceAccessors;
public CompositeResourceAccessor(List resourceAccessors) {
this.resourceAccessors = resourceAccessors;
}
public CompositeResourceAccessor(ResourceAccessor... resourceAccessors) {
this.resourceAccessors = Arrays.asList(resourceAccessors);
}
@Override
public Set getResourcesAsStream(String path) throws IOException {
for (ResourceAccessor accessor : resourceAccessors) {
Set returnSet = accessor.getResourcesAsStream(path);
if ((returnSet != null) && !returnSet.isEmpty()) {
return returnSet;
}
}
return null;
}
@Override
public Set list(String relativeTo, String path, boolean includeFiles, boolean includeDirectories, boolean recursive) throws IOException {
Set returnSet = new HashSet<>();
for (ResourceAccessor accessor : resourceAccessors) {
Set thisSet = accessor.list(relativeTo, path, includeFiles, includeDirectories, recursive);
if (thisSet != null) {
returnSet.addAll(thisSet);
}
}
if (!returnSet.isEmpty()) {
return returnSet;
}
return null;
}
@Override
public ClassLoader toClassLoader() {
ClassLoader[] loaders=new ClassLoader[resourceAccessors.size()];
int i=0;
for (ResourceAccessor fo: resourceAccessors) {
loaders[i++]=fo.toClassLoader();
}
return new CompositeClassLoader(loaders);
}
//based on code from http://fisheye.codehaus.org/browse/xstream/trunk/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java?r=root
private static class CompositeClassLoader extends ClassLoader {
private final List classLoaders = new ArrayList<>();
public CompositeClassLoader(ClassLoader... classLoaders) {
this.classLoaders.addAll(Arrays.asList(classLoaders));
}
@Override
public Class loadClass(String name,boolean resolve) throws ClassNotFoundException {
for (Object classLoader1 : classLoaders) {
ClassLoader classLoader = (ClassLoader) classLoader1;
try {
Class classe=classLoader.loadClass(name);
if(resolve)
resolveClass(classe);
return classe;
} catch (ClassNotFoundException notFound) {
// ok.. try another one
}
}
// One last try - the context class loader associated with the current thread. Often used in j2ee servers.
// Note: The contextClassLoader cannot be added to the classLoaders list up front as the thread that constructs
// liquibase is potentially different to thread that uses it.
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if (contextClassLoader != null) {
Class classe=contextClassLoader.loadClass(name);
if(resolve)
resolveClass(classe);
return classe;
} else {
throw new ClassNotFoundException(name);
}
}
}
@Override
public String toString() {
List openerStrings = new ArrayList<>();
for (ResourceAccessor opener : resourceAccessors) {
openerStrings.add(opener.toString());
}
return getClass().getName()+"("+StringUtils.join(openerStrings,",")+")";
}
}