00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package org.knopflerfish.framework.bundlestorage.memory;
00036
00037
00038 import org.osgi.framework.Constants;
00039 import java.io.*;
00040
00041 import java.util.ArrayList;
00042 import java.util.Enumeration;
00043 import java.util.HashMap;
00044 import java.util.Hashtable;
00045 import java.util.Iterator;
00046 import java.util.StringTokenizer;
00047 import java.util.Vector;
00048 import java.util.jar.*;
00049
00057 class Archive {
00058
00062 Manifest manifest;
00063
00068 protected HashMap content;
00069
00070 ArrayList subDirs;
00071
00079 Archive(InputStream is) throws IOException {
00080 JarInputStream ji = new JarInputStream(is);
00081 manifest = ji.getManifest();
00082 if (manifest == null) {
00083 throw new IOException("Bundle manifest is missing");
00084 }
00085 if (manifest.getMainAttributes().getValue(Constants.BUNDLE_NATIVECODE) != null) {
00086 throw new IOException("Native code not allowed by memory storage");
00087 }
00088 content = loadJarStream(ji);
00089 }
00090
00091
00102 Archive(Archive a, String path) throws IOException {
00103 byte [] bs = (byte [])a.content.remove(path);
00104 if (bs != null) {
00105 JarInputStream ji = new JarInputStream(new ByteArrayInputStream(bs));
00106 content = loadJarStream(ji);
00107 } else {
00108 throw new FileNotFoundException("No such file: " + path);
00109 }
00110 }
00111
00112
00119 String getAttribute(String key) {
00120 return manifest.getMainAttributes().getValue(key);
00121 }
00122
00123
00132 byte[] getClassBytes(String classFile) throws IOException {
00133 byte[] bytes;
00134 if ((bytes = (byte[]) content.remove(classFile)) == null) {
00135 if (subDirs == null) {
00136 return null;
00137 }
00138 Iterator it = subDirs.iterator();
00139 boolean found = false;
00140 while (it.hasNext()) {
00141 String subDir = (String) it.next();
00142 bytes = (byte[]) content.remove(subDir + "/" + classFile);
00143 if (bytes != null) {
00144 found = true;
00145 break;
00146 }
00147 }
00148 if (!found) {
00149 return null;
00150 }
00151 }
00152 return bytes;
00153 }
00154
00155
00162 InputStream getInputStream(String component) {
00163 if (component.startsWith("/")) {
00164 component = component.substring(1);
00165 }
00166 byte[] b = (byte[]) content.get(component);
00167 if (b != null) {
00168 return new ByteArrayInputStream(b);
00169 } else {
00170 return null;
00171 }
00172 }
00173
00174
00175
00176
00177 Enumeration findResourcesPath(String path) {
00178 Vector answer = new Vector();
00179
00180 path.replace('\\', '/');
00181 if (path.startsWith("/")) {
00182 path = path.substring(1);
00183 }
00184 if (!path.endsWith("/") ) {
00185 if (path.length() > 1) {
00186 path += "/";
00187 }
00188 }
00189
00190 Iterator it = content.keySet().iterator();
00191 while (it.hasNext()) {
00192 String entry = (String) it.next();
00193 if (entry.startsWith(path)) {
00194 String terminal = entry.substring(path.length());
00195 StringTokenizer st = new StringTokenizer(terminal, "/");
00196 String entryPath;
00197 if (st.hasMoreTokens()) {
00198 entryPath = path + st.nextToken();
00199 } else {
00200 entryPath = path;
00201 }
00202 if (!answer.contains(entryPath)) {
00203 answer.add(entryPath);
00204 }
00205 }
00206 }
00207
00208 if (answer.size() == 0) {
00209 return null;
00210 }
00211 return answer.elements();
00212 }
00213
00214
00223 Archive getSubArchive(String path) throws IOException {
00224 return new Archive(this, path);
00225 }
00226
00227
00228
00229
00230
00231
00237 private HashMap loadJarStream(JarInputStream ji) throws IOException {
00238 HashMap files = new HashMap();
00239 JarEntry je;
00240 while ((je = ji.getNextJarEntry()) != null) {
00241 if (!je.isDirectory()) {
00242 int len = (int) je.getSize();
00243 if (len == -1) {
00244 len = 8192;
00245 }
00246 byte[] b = new byte[len];
00247 int pos = 0;
00248 do {
00249 if (pos == len) {
00250 len *= 2;
00251 byte[] oldb = b;
00252 b = new byte[len];
00253 System.arraycopy(oldb, 0, b, 0, oldb.length);
00254 }
00255 int n;
00256 while ((len - pos) > 0 && (n = ji.read(b, pos, len - pos)) > 0) {
00257 pos += n;
00258 }
00259 } while (ji.available() > 0);
00260 if (pos != b.length) {
00261 byte[] oldb = b;
00262 b = new byte[pos];
00263 System.arraycopy(oldb, 0, b, 0, pos);
00264 }
00265 files.put(je.getName(), b);
00266 }
00267 }
00268 return files;
00269 }
00270
00271 }