/** * Copyright 2005-2012 Akiban Technologies, Inc. * * 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 com.persistit.ui; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; /** * This is just enough of a ClassLoader implementation to load the JavaHelp * classes from a nested Jar file. The purpose here is to allow jhbasic.jar to * reside unchanged (due to license constraints) inside the * persistit_jsa110_ui.jar file. When the user clicks on Help the first time, * AdminUI constructs an InnerJarClassLoader and calls addJar to load the * contents of inner jar files. The findClass and getResourceAsStream methods * then look up the loaded resources when called. This class keeps a Map * containing all the resources packed in the JAR files, so it is good to unload * this from memory when possible. * * @author Peter Beaman * @version 1.0 */ class InnerJarClassLoader extends ClassLoader { HashMap _resourceMap = new HashMap(); InnerJarClassLoader(final ClassLoader parent) throws IOException { super(parent); } public void addJar(final String jarName) throws IOException { addJar(getClass().getClassLoader().getResourceAsStream(jarName)); } public void addJar(final InputStream is) throws IOException { final JarInputStream jis = new JarInputStream(new BufferedInputStream(is, 32768)); byte[] hbytes = new byte[65536]; for (;;) { final ZipEntry entry = jis.getNextEntry(); if (entry == null) break; final String name = entry.getName(); int offset = 0; for (;;) { final int length = jis.read(hbytes, offset, hbytes.length - offset); if (length == -1) break; offset += length; if (offset == hbytes.length) { final byte[] temp = new byte[hbytes.length + 65536]; System.arraycopy(hbytes, 0, temp, 0, offset); hbytes = temp; } } final byte[] bytes = new byte[offset]; System.arraycopy(hbytes, 0, bytes, 0, offset); _resourceMap.put(name, bytes); jis.closeEntry(); } } @Override public Class findClass(final String className) throws ClassNotFoundException { final String fileName = className.replace('.', '/') + ".class"; final byte[] bytes = (byte[]) _resourceMap.get(fileName); if (bytes != null) { return defineClass(className, bytes, 0, bytes.length); } else throw new ClassNotFoundException(className); } @Override public InputStream getResourceAsStream(final String name) { final byte[] bytes = (byte[]) _resourceMap.get(name); if (bytes != null) return new ByteArrayInputStream(bytes); else return null; } }