/*
* Capsule
* Copyright (c) 2014-2015, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are licensed under the terms
* of the Eclipse Public License v1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package co.paralleluniverse.common;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.ProviderNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
/**
*
* @author pron
*/
public class PathClassLoader extends FlexibleClassLoader {
private final Object[] paths;
public PathClassLoader(Path[] paths, ClassLoader parent, boolean childFirst) throws IOException {
super(parent, childFirst);
this.paths = process(paths);
}
public PathClassLoader(Path[] paths, boolean childFirst) throws IOException {
super(childFirst);
this.paths = process(paths);
}
public PathClassLoader(Path[] paths, ClassLoader parent) throws IOException {
this(paths, parent, false);
}
public PathClassLoader(Path[] paths) throws IOException {
this(paths, false);
}
private static Object[] process(Path[] paths) throws IOException {
try {
final Object[] os = new Object[paths.length];
for (int i = 0; i < paths.length; i++) {
final Path p = paths[i];
final Object o;
if (Files.isRegularFile(p))
o = FileSystems.newFileSystem(p, null);
else
o = p;
os[i] = o;
}
return os;
} catch (ProviderNotFoundException e) {
throw new RuntimeException(e);
}
}
public final void close() {
IOException ex = null;
for (Object p : paths) {
if (p instanceof FileSystem) {
try {
((FileSystem) p).close();
} catch (IOException e) {
if (ex == null)
ex = e;
else
ex.addSuppressed(e);
}
}
}
}
private Path resolve(Object o, String name) {
final Path p;
if (o instanceof FileSystem)
p = ((FileSystem) o).getPath(name);
else
p = ((Path) o).resolve(name);
return p;
}
@Override
protected URL findResource1(String name) {
try {
for (Object o : paths) {
final Path p = resolve(o, name);
if (Files.exists(p))
return p.toUri().toURL();
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected Enumeration<URL> findResources1(String name) {
try {
final List<URL> urls = new ArrayList<>();
for (Object o : paths) {
final Path p = resolve(o, name);
if (Files.exists(p))
urls.add(p.toUri().toURL());
}
return Collections.enumeration(urls);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected InputStream findResourceAsStream(String name) {
try {
for (Object o : paths) {
final Path p = resolve(o, name);
if (isFileResource(p))
return Files.newInputStream(p);
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected byte[] readResource(String name) {
try {
for (Object o : paths) {
final Path p = resolve(o, name);
if (isFileResource(p))
return Files.readAllBytes(p);
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private boolean isFileResource(Path p) {
return Files.exists(p) && !Files.isDirectory(p);
}
}