001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.util;
017:
018: import java.io.BufferedInputStream;
019: import java.io.ByteArrayInputStream;
020: import java.io.ByteArrayOutputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.net.URL;
024: import java.util.Enumeration;
025: import java.util.HashMap;
026: import java.util.jar.JarEntry;
027: import java.util.jar.JarFile;
028: import java.util.jar.JarInputStream;
029:
030: public class MemoryClassLoader extends ClassLoader {
031: private final static int BUFFER_SIZE = 1024;
032: private HashMap classes = new HashMap();
033: private HashMap others = new HashMap();
034:
035: public MemoryClassLoader(ClassLoader parent, JarFile file) {
036: this (parent, new JarFile[] { file });
037: }
038:
039: public MemoryClassLoader(ClassLoader parent, JarFile[] file) {
040: super (parent);
041: for (int i = 0; i < file.length; i++) {
042: addJar(file[i]);
043: try {
044: file[i].close();
045: } catch (IOException e) {
046: }
047: }
048: }
049:
050: public MemoryClassLoader(ClassLoader parent, JarInputStream stream) {
051: this (parent, new JarInputStream[] { stream });
052: }
053:
054: public MemoryClassLoader(ClassLoader parent, JarInputStream[] stream) {
055: super (parent);
056: for (int i = 0; i < stream.length; i++) {
057: addJar(stream[i]);
058: }
059: }
060:
061: /* ********** ClassLoader Overrides ********** */
062:
063: public InputStream getResourceAsStream(String name) {
064: InputStream stream = getParent().getResourceAsStream(name);
065: if (stream == null) {
066: byte[] buf = (byte[]) others.get(name);
067: if (buf != null) {
068: stream = new ByteArrayInputStream(buf);
069: }
070: }
071: return stream;
072: }
073:
074: public URL getResource(String name) {
075: throw new Error("Not Yet Implemented!");
076:
077: }
078:
079: protected Enumeration findResources(String name) throws IOException {
080: throw new Error("Not Yet Implemented!");
081:
082: }
083:
084: public boolean equals(Object o) {
085: if (o instanceof MemoryClassLoader) {
086: return ((MemoryClassLoader) o).getParent() == getParent();
087: }
088: return false;
089: }
090:
091: public int hashCode() {
092: return getParent().hashCode();
093: }
094:
095: public Class findClass(String name) throws ClassNotFoundException {
096: byte[] data = findClassData(name);
097: if (data != null) {
098: return defineClass(name, data, 0, data.length);
099: } else {
100: throw new ClassNotFoundException();
101: }
102: }
103:
104: /* ******** End ClassLoader Overrides ******** */
105:
106: public void addJar(JarFile jar) {
107: Enumeration entries = jar.entries();
108: while (entries.hasMoreElements()) {
109: JarEntry entry = (JarEntry) entries.nextElement();
110: if (entry.getName().endsWith(".class")) {
111: try {
112: addClassFile(jar, entry);
113: } catch (IOException e) {
114: e.printStackTrace();
115: }
116: } else {
117: try {
118: addOtherFile(jar, entry);
119: } catch (IOException e) {
120: e.printStackTrace();
121: }
122: }
123: }
124: }
125:
126: public void addJar(JarInputStream stream) {
127: byte[] buf = new byte[BUFFER_SIZE];
128: int count;
129: try {
130: while (true) {
131: JarEntry entry = stream.getNextJarEntry();
132: if (entry == null)
133: break;
134: String name = entry.getName();
135: int size = (int) entry.getSize();
136: ByteArrayOutputStream out = size >= 0 ? new ByteArrayOutputStream(
137: size)
138: : new ByteArrayOutputStream(BUFFER_SIZE);
139: while ((count = stream.read(buf)) > -1)
140: out.write(buf, 0, count);
141: out.close();
142: if (name.endsWith(".class")) {
143: classes.put(getClassName(name), out.toByteArray());
144: } else {
145: others.put(name, out.toByteArray());
146: }
147: }
148: } catch (IOException e) {
149: e.printStackTrace();
150: }
151: }
152:
153: private byte[] findClassData(String name) {
154: return (byte[]) classes.remove(name);
155: }
156:
157: private void addClassFile(JarFile jar, JarEntry entry)
158: throws IOException {
159: classes.put(getClassName(entry.getName()), getFileBytes(jar,
160: entry));
161: }
162:
163: private void addOtherFile(JarFile jar, JarEntry entry)
164: throws IOException {
165: others.put(entry.getName(), getFileBytes(jar, entry));
166: }
167:
168: private static String getClassName(String fileName) {
169: return fileName.substring(0, fileName.length() - 6).replace(
170: '/', '.');
171: }
172:
173: private static byte[] getFileBytes(JarFile jar, JarEntry entry)
174: throws IOException {
175: ByteArrayOutputStream stream = new ByteArrayOutputStream(
176: (int) entry.getSize());
177: byte[] buf = new byte[BUFFER_SIZE];
178: BufferedInputStream in = new BufferedInputStream(jar
179: .getInputStream(entry));
180: int count;
181: while ((count = in.read(buf)) > -1)
182: stream.write(buf, 0, count);
183: in.close();
184: stream.close();
185:
186: return stream.toByteArray();
187: }
188: }
|