001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2001 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package bossa.modules;
012:
013: import bossa.util.*;
014: import java.io.*;
015: import java.util.jar.*;
016: import gnu.bytecode.ClassFileInput;
017:
018: /**
019: A compiled package located in a jar file.
020:
021: @author Daniel Bonniot (Daniel.Bonniot@inria.fr)
022: */
023:
024: class JarCompiledContent extends CompiledContent {
025: static JarCompiledContent create(Package pkg, JarFile jar) {
026: // Jar and Zip files use forward slashes
027: String pkgName = pkg.getName().replace('.', '/');
028:
029: JarEntry itfEntry = jar.getJarEntry(pkgName + "/package.nicei");
030: if (itfEntry == null)
031: return null;
032:
033: JarEntry bytecodeEntry = jar.getJarEntry(pkgName + "/"
034: + Package.packageClassName + ".class");
035: if (bytecodeEntry == null)
036: return null;
037:
038: JarEntry dispatchEntry = jar.getJarEntry(pkgName
039: + "/dispatch.class");
040: if (dispatchEntry == null)
041: return null;
042:
043: return new JarCompiledContent(pkg, jar, itfEntry,
044: bytecodeEntry, dispatchEntry);
045: }
046:
047: JarCompiledContent(Package pkg, JarFile jar, JarEntry itfEntry,
048: JarEntry bytecodeEntry, JarEntry dispatchEntry) {
049: this .pkg = pkg;
050: this .jar = jar;
051:
052: this .itfEntry = itfEntry;
053: this .bytecodeEntry = bytecodeEntry;
054: this .dispatchEntry = dispatchEntry;
055:
056: this .lastCompilation = Math.min(itfEntry.getTime(), Math.min(
057: bytecodeEntry.getTime(), dispatchEntry.getTime()));
058:
059: /* Use the date of creation of the jar file if it is later.
060: The package might have been compiled earlier, but we probably did
061: not get to see it before it was put into this jar.
062: This is in particular the case if the jar is an upgraded library.
063: */
064: this .lastCompilation = Math.max(new File(jar.getName())
065: .lastModified(), this .lastCompilation);
066: }
067:
068: Content.Unit[] getDefinitions() {
069: BufferedReader res = null;
070:
071: try {
072: res = new BufferedReader(new InputStreamReader(jar
073: .getInputStream(itfEntry)));
074:
075: bytecode = ClassFileInput.readClassType(jar
076: .getInputStream(bytecodeEntry));
077: dispatch = ClassFileInput.readClassType(jar
078: .getInputStream(dispatchEntry));
079: } catch (IOException e) {
080: User.error(pkg.name, "Error reading archive " + getName());
081: }
082:
083: return new Content.Unit[] { new Content.Unit(res, pkg.name
084: .toString()) };
085: }
086:
087: gnu.bytecode.ClassType readClass(String name) {
088: JarEntry entry = jar.getJarEntry(name.replace('.', '/')
089: + ".class");
090: if (entry == null)
091: return null;
092:
093: try {
094: return ClassFileInput.readClassType(name, jar
095: .getInputStream(entry));
096: } catch (IOException e) {
097: return null;
098: }
099: }
100:
101: void addClasses(java.util.Set/*<Content.Stream>*/classes) {
102: String pkgPrefix = pkg.getName().replace('.', '/') + "/";
103:
104: java.util.Enumeration en = jar.entries();
105: while (en.hasMoreElements()) {
106: JarEntry e = (JarEntry) en.nextElement();
107: String fullname = e.getName();
108: if (fullname.startsWith(pkgPrefix)
109: && fullname.indexOf('/', pkgPrefix.length()) == -1
110: && fullname.endsWith(".class")) {
111: String name = fullname.substring(pkgPrefix.length());
112: try {
113: classes.add(new Content.Stream(jar
114: .getInputStream(e), name));
115: } catch (IOException ex) {
116: User.error(pkg.name, "Error reading archive "
117: + getName());
118: }
119: }
120: }
121: }
122:
123: InputStream getBytecodeStream() {
124: try {
125: return jar.getInputStream(bytecodeEntry);
126: } catch (IOException e) {
127: User.error(pkg, "Error reading archive " + getName());
128: return null;
129: }
130: }
131:
132: public String getName() {
133: return nice.tools.util.System.prettyPrint(jar);
134: }
135:
136: public String toString() {
137: return "Compiled package: " + getName();
138: }
139:
140: private Package pkg;
141: private JarFile jar;
142:
143: private JarEntry itfEntry, bytecodeEntry, dispatchEntry;
144: }
|