org.smallmind.nutsnbolts.lang.ClasspathClassGate Maven / Gradle / Ivy
/*
* Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 David Berkman
*
* This file is part of the SmallMind Code Project.
*
* The SmallMind Code Project is free software, you can redistribute
* it and/or modify it under either, at your discretion...
*
* 1) The terms of GNU Affero General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* ...or...
*
* 2) The terms of the Apache License, Version 2.0.
*
* The SmallMind Code Project is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License or Apache License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and the Apache License along with the SmallMind Code Project. If not, see
* or .
*
* Additional permission under the GNU Affero GPL version 3 section 7
* ------------------------------------------------------------------
* If you modify this Program, or any covered work, by linking or
* combining it with other code, such other code is not for that reason
* alone subject to any of the requirements of the GNU Affero GPL
* version 3.
*/
package org.smallmind.nutsnbolts.lang;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.CodeSource;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.smallmind.nutsnbolts.io.PathUtility;
public class ClasspathClassGate implements ClassGate {
private final HashMap filePathMap;
private final String[] pathComponents;
public ClasspathClassGate () {
this(System.getProperty("java.class.path"));
}
public ClasspathClassGate (String classPath) {
this(classPath.split(System.getProperty("path.separator"), -1));
}
public ClasspathClassGate (String... pathComponents) {
this.pathComponents = pathComponents;
filePathMap = new HashMap<>();
}
public long getLastModDate (String name)
throws IOException {
Path filePath;
synchronized (filePathMap) {
if ((filePath = filePathMap.get(name)) != null) {
return Files.getLastModifiedTime(filePath).toMillis();
}
}
return ClassGate.STATIC_CLASS;
}
@Override
public CodeSource getCodeSource () {
return null;
}
public ClassStreamTicket getTicket (String name)
throws Exception {
String classFileName;
classFileName = name.replace('.', '/') + ".class";
for (String pathComponent : pathComponents) {
InputStream classStream;
if (pathComponent.endsWith(".jar")) {
if ((classStream = findJarStream(pathComponent, classFileName)) != null) {
return new ClassStreamTicket(classStream, ClassGate.STATIC_CLASS);
}
} else {
Path classFile;
long timeStamp;
if ((classFile = findPath(pathComponent, classFileName)) != null) {
synchronized (filePathMap) {
filePathMap.put(name, classFile.toAbsolutePath().normalize());
timeStamp = Files.getLastModifiedTime(classFile).toMillis();
return new ClassStreamTicket(Files.newInputStream(classFile), timeStamp);
}
}
}
}
return null;
}
public URL getResource (String path)
throws IOException {
for (String pathComponent : pathComponents) {
JarLocator jarLocator;
if (pathComponent.endsWith(".jar")) {
if ((jarLocator = findJarLocator(pathComponent, path)) != null) {
return new URL("jar:file://" + rectifyPath(pathComponent) + "!/" + jarLocator.getJarEntry().getName());
}
} else {
Path resourcePath;
if ((resourcePath = findPath(pathComponent, path)) != null) {
return new URL("file://" + rectifyPath(PathUtility.asNormalizedString(resourcePath)));
}
}
}
return null;
}
private String rectifyPath (String path) {
String rectifiedPath = path.replace('\\', '/');
return (rectifiedPath.charAt(0) == '/') ? rectifiedPath : '/' + rectifiedPath;
}
public InputStream getResourceAsStream (String path)
throws IOException {
for (String pathComponent : pathComponents) {
InputStream resourceStream;
if (pathComponent.endsWith(".jar")) {
if ((resourceStream = findJarStream(pathComponent, path)) != null) {
return resourceStream;
}
} else {
Path resourceFile;
if ((resourceFile = findPath(pathComponent, path)) != null) {
return Files.newInputStream(resourceFile, StandardOpenOption.READ);
}
}
}
return null;
}
private InputStream findJarStream (String jarComponentPath, String path)
throws IOException {
JarLocator jarLocator;
if ((jarLocator = findJarLocator(jarComponentPath, path)) != null) {
return new BufferedInputStream(jarLocator.getInputStream());
}
return null;
}
private JarLocator findJarLocator (String jarComponentPath, String path)
throws IOException {
JarFile jarFile;
JarEntry jarEntry;
Enumeration entryEnumeration;
jarFile = new JarFile(jarComponentPath);
entryEnumeration = jarFile.entries();
while (entryEnumeration.hasMoreElements()) {
if ((jarEntry = entryEnumeration.nextElement()).getName().equals((path.charAt(0) == '/') ? path.substring(1) : path)) {
return new JarLocator(jarFile, jarEntry);
}
}
return null;
}
private Path findPath (String fileComponentPath, String path) {
Path completePath;
completePath = Paths.get(fileComponentPath, (path.charAt(0) == '/') ? path.substring(1) : path);
if (Files.isRegularFile(completePath)) {
return completePath;
}
return null;
}
private static class JarLocator {
private final JarFile jarFile;
private final JarEntry jarEntry;
private JarLocator (JarFile jarFile, JarEntry jarEntry) {
this.jarFile = jarFile;
this.jarEntry = jarEntry;
}
private JarEntry getJarEntry () {
return jarEntry;
}
public InputStream getInputStream ()
throws IOException {
return jarFile.getInputStream(jarFile.getEntry(jarEntry.getName()));
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy