initial import
0 parents
Showing
with
1897 additions
and
0 deletions
nbactions.xml
0 → 100644
pom.xml
0 → 100644
package com.starphoenixmedia.candle_pos; | ||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Enumeration; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.Objects; | ||
import java.util.function.Consumer; | ||
import java.util.jar.Attributes; | ||
import java.util.jar.Attributes.Name; | ||
import java.util.jar.JarEntry; | ||
import java.util.jar.JarFile; | ||
import java.util.jar.Manifest; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
import java.util.zip.ZipEntry; | ||
/** | ||
* | ||
* @author Jessica Hawkwell <[email protected]> | ||
*/ | ||
public class FireCodeClassLoader extends ClassLoader | ||
{ | ||
/** | ||
* JarName -> File mapping. | ||
* Also used to determine if a jar has already been loaded. | ||
*/ | ||
private static HashMap<String, File> jars; | ||
/** | ||
* ClassPath -> File mapping. | ||
* Also used to determine if a ClassPath has already been loaded. | ||
*/ | ||
private static HashMap<String, File> flds; | ||
/** | ||
* Set buffer length to 4096. | ||
*/ | ||
public static final int BUFFER_LEN = 4096; | ||
/** | ||
* Package lists. | ||
*/ | ||
private static HashMap<String, Package> pkgs; | ||
/** | ||
* Package -> Jar/CP mapping. | ||
*/ | ||
private static HashMap<String, String> maps; | ||
/** | ||
* Loaded classes. | ||
*/ | ||
private static HashMap<String, Class<?>> clss; | ||
/** | ||
* Parent class loader. | ||
*/ | ||
private final ClassLoader parent; | ||
/** | ||
* Constructor. | ||
*/ | ||
public FireCodeClassLoader() | ||
{ | ||
parent = getClass().getClassLoader(); | ||
jars = new HashMap<>(); | ||
flds = new HashMap<>(); | ||
pkgs = new HashMap<>(); | ||
clss = new HashMap<>(); | ||
maps = new HashMap<>(); | ||
} | ||
/** | ||
* Constructor. | ||
* @param cl ClassLoader to be considered the parent | ||
*/ | ||
public FireCodeClassLoader(ClassLoader cl) | ||
{ | ||
parent = cl; | ||
jars = new HashMap<>(); | ||
flds = new HashMap<>(); | ||
pkgs = new HashMap<>(); | ||
clss = new HashMap<>(); | ||
maps = new HashMap<>(); | ||
} | ||
/** Initialize this ClassLoader. | ||
*/ | ||
public void init() | ||
{ | ||
Iterator<String> paths; | ||
paths = cpDirs(System.getProperty("java.class.path")); | ||
File f; | ||
String s; | ||
while ( paths.hasNext() ) | ||
{ | ||
s = paths.next(); | ||
f = new File(s); | ||
if ( f.isDirectory() ) { addDir(f); } | ||
else if ( s.toLowerCase().endsWith(".jar") ) { addJar(f); } | ||
} | ||
} | ||
@Override public Class<?> findClass(String name) throws ClassNotFoundException | ||
{ | ||
if ( clss.containsKey(name) ) { return clss.get(name); } | ||
else { throw new ClassNotFoundException(name); } | ||
} | ||
@Override public URL getResource(final String path) { return getResource(true, path); } | ||
private URL getResource(boolean goup, final String path) | ||
{ | ||
String pth; | ||
URL u = null; | ||
if ( path.startsWith("/") ) { pth = path.substring(1); } else { pth = path; } | ||
try { u = this.getResourceLocator(pth); } catch ( Throwable t ) { } | ||
if ( (u == null) && goup ) { u = parent.getResource(path); } | ||
return u; | ||
} | ||
@Override public Package getPackage(String name) { return pkgs.get(name); } | ||
@Override public Package[] getPackages() { return pkgs.values().toArray(new Package[]{}); } | ||
private URL getResourceLocator(final String path) throws Throwable | ||
{ | ||
JarFile jf; | ||
ZipEntry ze; | ||
Iterator<File> it; | ||
File f; | ||
// FAST search | ||
if ( !maps.isEmpty() ) | ||
{ | ||
String pack = path.replace("/", ".").substring(0, path.lastIndexOf("/")); | ||
if ( maps.containsKey(pack) ) | ||
{ | ||
f = new File(maps.get(pack)); | ||
if ( f.isDirectory() ) | ||
{ return new URL("file:".concat(maps.get(pack)).concat(File.separator).concat(path)); } | ||
else { return new URL("jar:file:".concat(maps.get(pack)).concat("!/").concat(path)); } | ||
} | ||
} | ||
// slow search | ||
if ( !jars.isEmpty() ) | ||
{ | ||
System.err.println("Warning: Slow search: ".concat(path)); | ||
it = jars.values().iterator(); | ||
while ( it.hasNext() ) | ||
{ | ||
f = it.next(); | ||
jf = new JarFile(f); | ||
ze = jf.getEntry(path); | ||
jf.close(); | ||
if ( ze != null ) | ||
{ return new URL("jar:file:".concat(f.getCanonicalPath()).concat("!/").concat(path)); } | ||
} | ||
} | ||
File t; | ||
if ( !flds.isEmpty() ) | ||
{ | ||
System.err.println("Warning: Slow search: ".concat(path)); | ||
it = flds.values().iterator(); | ||
while ( it.hasNext() ) | ||
{ | ||
f = it.next(); | ||
try | ||
{ | ||
t = new File("file:".concat(f.getCanonicalPath()).concat(File.separator).concat(path)); | ||
if ( t.exists() ) { return new URL(t.getCanonicalPath()); } | ||
} | ||
catch ( IOException x ) {} | ||
} | ||
} | ||
return null; | ||
} | ||
@Override public InputStream getResourceAsStream(final String path) | ||
{ return getResourceAsStream(true, path); } | ||
private InputStream getResourceAsStream(boolean goup, final String path) | ||
{ | ||
final URL u = getResource(goup, path); | ||
if ( u == null ) { return null; } | ||
try { return u.openStream(); } catch ( IOException e ) { e.printStackTrace(System.out); } | ||
return null; | ||
} | ||
@Override public Enumeration<URL> getResources(String name) throws IOException | ||
{ | ||
if ( jars.isEmpty() ) { return null; } | ||
ArrayList<URL> ar = new ArrayList<>(); | ||
Iterator<File> it = jars.values().iterator(); | ||
File f; | ||
JarFile jf; | ||
ZipEntry ze; | ||
while ( it.hasNext() ) | ||
{ | ||
f = it.next(); | ||
jf = new JarFile(f); | ||
ze = jf.getEntry(name); | ||
jf.close(); | ||
if ( ze != null ) { ar.add(new URL("jar:file:".concat(f.getCanonicalPath()).concat("!/").concat(name))); } | ||
} | ||
return new Iterator2Enum<>(ar.iterator()); | ||
} | ||
@Override public Class<?> loadClass(final String name) throws ClassNotFoundException | ||
{ return loadClass(name, true); } | ||
@Override protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException | ||
{ | ||
// fast exit | ||
String pack = name.substring(0, name.lastIndexOf('.')); | ||
if ( !maps.containsKey(pack) ) { return parent.loadClass(name); } | ||
//Class<?> cls; | ||
Class<?> cls = findLoadedClass(name); | ||
if ( cls != null ) { return cls; } // */ | ||
final InputStream is = getResourceAsStream(false, name.replaceAll("\\.", "/").concat(".class")); | ||
if ( is == null ) { cls = parent.loadClass(name); } | ||
else | ||
{ | ||
try { return loadClassWorker(name, resolve, is); } | ||
catch ( IOException ex ) { throw new ClassNotFoundException("Couln't load ".concat(name)); } | ||
} | ||
return cls; | ||
} | ||
private Class<?> loadClassWorker(final String name, final boolean resolve, final InputStream is) | ||
throws ClassNotFoundException, IOException | ||
{ | ||
getClassLoadingLock(name); | ||
Class<?> cls; | ||
final byte[] buffer = new byte[BUFFER_LEN]; | ||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
byte[] bytecode; | ||
int i; | ||
while ( (i = is.read(buffer, 0, BUFFER_LEN)) > 0 ) { baos.write(buffer, 0, i); } | ||
is.close(); | ||
bytecode = baos.toByteArray(); | ||
if ( bytecode == null ) { throw new ClassNotFoundException("Cannot load class: " + name); } | ||
try | ||
{ | ||
cls = this.defineClass(name, bytecode, 0, bytecode.length); | ||
if ( resolve ) { this.resolveClass(cls); } | ||
} | ||
catch ( SecurityException e ) { cls = parent.loadClass(name); } | ||
return cls; | ||
} | ||
private String addDefHelper(Attributes manifest, Attributes file, me key) | ||
{ | ||
if ( (file != null) && !file.isEmpty() ) | ||
{ if ( file.containsKey(key.getPrimary()) ) { return file.getValue(key.getPrimary()); } } | ||
if ( (manifest != null) && !manifest.isEmpty() ) | ||
{ | ||
if ( manifest.containsKey(key.getPrimary()) ) { return manifest.getValue(key.getPrimary()); } | ||
else { return key.getDefault(); } | ||
} | ||
return "null"; | ||
} | ||
private void defPkg(String pack, String file, Attributes master, Attributes pkg) | ||
throws MalformedURLException | ||
{ | ||
Package p; | ||
if ( !pkgs.containsKey(pack) ) | ||
{ | ||
p = definePackage(pack, | ||
addDefHelper(master, pkg, me.SPECTITLE), addDefHelper(master, pkg, me.SPECVERSION), | ||
addDefHelper(master, pkg, me.SPECVENDOR), | ||
addDefHelper(master, pkg, me.IMPLTITLE), addDefHelper(master, pkg, me.IMPLVERSION), | ||
addDefHelper(master, pkg, me.IMPLVENDOR), | ||
new URL("file:".concat(file)) | ||
); | ||
pkgs.put(pack, p); | ||
maps.put(pack, file); | ||
} | ||
} | ||
public void addDir(File dir) | ||
{ | ||
String pt = null; | ||
try { pt = dir.getCanonicalPath(); } | ||
catch (IOException ex) { Logger.getLogger(FireCodeClassLoader.class.getName()).log(Level.SEVERE, null, ex); } | ||
if ( pt != null ) | ||
{ | ||
if ( !flds.containsKey(pt) ) | ||
{ | ||
flds.put(pt, new File(pt)); | ||
// easy part done, now scan and add packages | ||
StringBuilder sb = new StringBuilder(pt); | ||
sb.append(File.separator); | ||
sb.append("META-INF"); | ||
sb.append(File.separator); | ||
sb.append("MANIFEST.MF"); | ||
File f = new File(sb.toString()); | ||
try | ||
{ | ||
Manifest mf; | ||
if ( f.exists() ) | ||
{ | ||
FileInputStream fis = new FileInputStream(f); | ||
mf = new Manifest(fis); | ||
} | ||
else { mf = new Manifest(); } | ||
if ( mf.getMainAttributes().containsKey(Name.CLASS_PATH) ) | ||
{ addClassPath(mf.getMainAttributes().getValue(Name.CLASS_PATH)); } | ||
addDirHelper(dir, null, "", mf); | ||
System.out.println("Added Dir ".concat(pt)); | ||
} | ||
catch (IOException x) {} | ||
} | ||
} | ||
} | ||
private void addDirHelper(File root, File dir, String name, Manifest mf) throws IOException | ||
{ | ||
File[] files; | ||
if ( dir != null ) { files = dir.listFiles(); } else { files = root.listFiles(); } | ||
String n; | ||
for ( File f : files ) | ||
{ | ||
if ( f.isDirectory() ) | ||
{ | ||
if ( name.isEmpty() ) { addDirHelper(root, f, f.getName(), mf); } | ||
else | ||
{ | ||
n = name.concat(".").concat(f.getName()); | ||
if ( n.startsWith(".") ) { n = n.substring(1); } | ||
if ( !flds.containsKey(n) ) | ||
{ defPkg(n, root.getCanonicalPath(), mf.getMainAttributes(), mf.getAttributes(n)); } | ||
addDirHelper(root, f, n, mf); | ||
} | ||
} | ||
else if ( f.isFile() && f.getName().endsWith(".jar") ) { addJar(f); } | ||
} | ||
} | ||
public void addJar(File jar) | ||
{ | ||
String pt = null; | ||
try { pt = jar.getCanonicalPath(); } | ||
catch (IOException ex) { Logger.getLogger(FireCodeClassLoader.class.getName()).log(Level.SEVERE, null, ex); } | ||
if ( pt != null ) | ||
{ | ||
if ( !jars.containsKey(pt) ) | ||
{ | ||
jars.put(pt, new File(pt)); | ||
String tp; | ||
// easy part done, now scan and add packages | ||
try | ||
{ | ||
JarFile jf = new JarFile(jars.get(pt)); | ||
Enumeration<JarEntry> en = jf.entries(); | ||
Manifest mf = jf.getManifest(); | ||
Attributes msf = mf.getMainAttributes(); | ||
JarEntry je; | ||
if ( msf.containsKey(Name.CLASS_PATH) ) { addClassPath(msf.getValue(Name.CLASS_PATH)); } | ||
while ( en.hasMoreElements() ) | ||
{ | ||
je = en.nextElement(); | ||
tp = je.getName(); | ||
if ( tp.endsWith("/") ) { tp = tp.substring(0, tp.lastIndexOf("/")); } | ||
if ( je.isDirectory() && !tp.startsWith("META-INF") && tp.contains("/") ) | ||
{ | ||
tp = je.getName().replace('/', '.'); | ||
tp = tp.substring(0, tp.lastIndexOf(".")); | ||
defPkg(tp, jf.getName(), msf, je.getAttributes()); | ||
} | ||
} | ||
System.out.println("Added Jar ".concat(pt)); | ||
} | ||
catch ( IOException x ) {} | ||
} | ||
} | ||
} | ||
private Iterator<String> cpDirs(String cp) | ||
{ | ||
String[] pt; | ||
ArrayList<String> al = new ArrayList<>(); | ||
if ( cp.contains(File.pathSeparator) || cp.contains(" ") ) | ||
{ pt = cp.split("[ ".concat(File.pathSeparator).concat("]")); } | ||
else { pt = new String[]{cp}; } | ||
al.addAll(Arrays.asList(pt)); | ||
return al.iterator(); | ||
} | ||
private void addClassPath(String list) { addClassPath(cpDirs(list)); } | ||
private void addClassPath(Iterator<String> it) | ||
{ | ||
String st; | ||
File finale; | ||
String[] lists = new String[] | ||
{ | ||
System.getProperty("user.home").concat("/.m2/repository/"), | ||
"./libs/", | ||
"./" | ||
}; | ||
File f; | ||
File t; | ||
while ( it.hasNext() ) | ||
{ | ||
finale = null; | ||
st = it.next(); | ||
f = new File(st); | ||
if ( f.exists() ) { finale = f; } | ||
for ( String s : lists ) | ||
{ | ||
if ( finale == null ) | ||
{ | ||
t = new File(s.concat(f.getPath())); | ||
if ( t.exists() ) { finale = t; } | ||
} | ||
} | ||
if ( finale != null ) | ||
{ | ||
if ( finale.isDirectory() ) { addDir(finale); } | ||
else if ( finale.getName().endsWith(".jar") ) { addJar(finale); } | ||
} | ||
} | ||
} | ||
private enum me | ||
{ | ||
NAME(new Name("Package"), "App"), | ||
SPECTITLE(Name.SPECIFICATION_TITLE, "Default"), | ||
SPECVERSION(Name.SPECIFICATION_VERSION, "1.0"), | ||
SPECVENDOR(Name.SPECIFICATION_VENDOR, "Developer"), | ||
IMPLTITLE(Name.IMPLEMENTATION_TITLE, "Default"), | ||
IMPLVERSION(Name.IMPLEMENTATION_VERSION, "1.0"), | ||
IMPLVENDOR(Name.IMPLEMENTATION_VENDOR, "Developer"), | ||
SEALED(Name.SEALED, "false"); | ||
private final Name p; | ||
private final String d; | ||
me(Name pri, String def) | ||
{ | ||
p = pri; | ||
d = def; | ||
} | ||
public Name getPrimary() { return p; } | ||
public String getDefault() { return d; } | ||
} | ||
public class Enum2Iterator<E> implements Iterator<E> | ||
{ | ||
Enumeration<E> en; | ||
public Enum2Iterator(Enumeration<E> enumer) { en = enumer; } | ||
@Override public void forEachRemaining(Consumer<? super E> action) | ||
{ | ||
Objects.requireNonNull(action); | ||
while ( en.hasMoreElements() ) { action.accept(en.nextElement()); } | ||
} | ||
@Override public boolean hasNext() { return en.hasMoreElements(); } | ||
@Override public E next() { return en.nextElement(); } | ||
} | ||
public class Iterator2Enum<E> implements Enumeration<E> | ||
{ | ||
Iterator<E> it; | ||
public Iterator2Enum(Iterator<E> iter) { it = iter; } | ||
@Override public boolean hasMoreElements() { return it.hasNext(); } | ||
@Override public E nextElement() { return it.next(); } | ||
} | ||
} |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
-
Please register or sign in to post a comment