KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > jar > CreatePackage


1 /*
2  * Copyright area
3  */

4
5 package org.objectweb.fractal.jar;
6
7 import java.io.FileInputStream JavaDoc;
8 import java.io.FileOutputStream JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.io.InputStream JavaDoc;
11 import java.io.OutputStream JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.Set JavaDoc;
16 import java.util.zip.ZipEntry JavaDoc;
17 import java.util.zip.ZipOutputStream JavaDoc;
18
19 import org.objectweb.asm.Attribute;
20 import org.objectweb.asm.ClassReader;
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.CodeVisitor;
23 import org.objectweb.asm.Label;
24 import org.objectweb.asm.Type;
25
26 import org.objectweb.fractal.adl.ADLException;
27 import org.objectweb.fractal.adl.Definition;
28 import org.objectweb.fractal.adl.Loader;
29 import org.objectweb.fractal.adl.Node;
30 import org.objectweb.fractal.adl.Parser;
31 import org.objectweb.fractal.adl.ParserException;
32 import org.objectweb.fractal.adl.components.Component;
33 import org.objectweb.fractal.adl.components.ComponentContainer;
34 import org.objectweb.fractal.adl.components.ComponentDefinition;
35 import org.objectweb.fractal.adl.xml.XMLParser;
36
37 import org.objectweb.fractal.jar.adl.File;
38 import org.objectweb.fractal.jar.adl.FileContainer;
39 import org.objectweb.fractal.jar.adl.FileLoader;
40 import org.objectweb.fractal.jar.adl.VersionDefinition;
41
42 public class CreatePackage {
43
44   String JavaDoc src;
45
46   String JavaDoc dst;
47   
48   String JavaDoc definition;
49     
50   boolean recursive;
51   
52   Set JavaDoc excludes;
53   
54   Set JavaDoc content;
55
56   Set JavaDoc classes;
57   
58   Set JavaDoc dependencies;
59   
60   Set JavaDoc libraryDependencies;
61   
62   Loader loader;
63   
64   public CreatePackage (
65     String JavaDoc src,
66     String JavaDoc dst,
67     String JavaDoc definition,
68     boolean recursive,
69     Set JavaDoc excludes)
70   {
71     this.src = src;
72     this.dst = dst;
73     this.definition = definition;
74     this.recursive = recursive;
75     this.excludes = excludes;
76     this.content = new HashSet JavaDoc();
77     this.classes = new HashSet JavaDoc();
78     this.dependencies = new HashSet JavaDoc();
79     this.libraryDependencies = new HashSet JavaDoc();
80   }
81   
82   public void create () throws Exception JavaDoc {
83     FileLoader fl = new FileLoader();
84     fl.clientLoader = new XMLLoader();
85     loader = fl;
86
87     Definition d = loader.load(definition, null);
88     String JavaDoc version = ((VersionDefinition)d).getVersion();
89     
90     String JavaDoc f = definition + "-" + version + ".far";
91     OutputStream JavaDoc os = new FileOutputStream JavaDoc(new java.io.File JavaDoc(dst, f));
92     ZipOutputStream JavaDoc zos = new ZipOutputStream JavaDoc(os);
93     
94     zos.putNextEntry(new ZipEntry JavaDoc("META-INF/MANIFEST.MF"));
95     zos.write("Manifest-Version: 1.0\n".getBytes());
96     zos.write(("Component-Name: " + definition + "-" + version + "\n").getBytes());
97     zos.closeEntry();
98
99     addFile(definition.replace('.', '/') + ".fractal", version, zos, true);
100     addFiles((Node)d, version, zos, true);
101     
102     zos.close();
103     
104     dependencies.removeAll(classes);
105     if (dependencies.size() > 0) {
106       Iterator JavaDoc i = dependencies.iterator();
107       System.out.println(
108         "WARNING: the following classes are needed by the classes " +
109         "listed in the ADL files, but they are not listed in the ADL files");
110       while (i.hasNext()) {
111         System.out.println(" " + i.next());
112       }
113     }
114   }
115   
116   private void addFiles (Node n, String JavaDoc version, ZipOutputStream JavaDoc z, boolean add) throws Exception JavaDoc {
117     if (n instanceof FileContainer) {
118       File[] files = ((FileContainer)n).getFiles();
119       for (int i = 0; i < files.length; ++i) {
120         try {
121           addFile(files[i].getName(), version, z, add);
122         } catch (Exception JavaDoc e) {
123           throw new ADLException("Cannot add file", (Node)files[i], e);
124         }
125       }
126     }
127     if (n instanceof ComponentContainer) {
128       Component[] components = ((ComponentContainer)n).getComponents();
129       for (int i = 0; i < components.length; ++i) {
130         addFiles((Node)components[i], version, z, add);
131       }
132     }
133     
134     if (n instanceof ComponentDefinition) {
135       try {
136         addDefinitions(((ComponentDefinition)n).getExtends(), z, recursive);
137       } catch (Exception JavaDoc e) {
138         throw new ADLException("Cannot read or add inherited files", n, e);
139       }
140     }
141     if (n instanceof Component) {
142       try {
143         addDefinitions(((Component)n).getDefinition(), z, recursive);
144       } catch (Exception JavaDoc e) {
145         throw new ADLException("Cannot read or add referenced files", n, e);
146       }
147     }
148   }
149
150   private void addFile (String JavaDoc f, String JavaDoc version, ZipOutputStream JavaDoc z, boolean add) throws Exception JavaDoc {
151     if (add) {
152       String JavaDoc entry = version + '/' + f;
153       if (content.contains(entry)) {
154         return;
155       } else {
156         content.add(entry);
157       }
158       InputStream JavaDoc is = new FileInputStream JavaDoc(new java.io.File JavaDoc(src, f));
159       z.putNextEntry(new ZipEntry JavaDoc(entry));
160       
161       byte[] b = new byte[Math.min(100000, is.available())];
162       while (true) {
163         int n = is.read(b, 0, b.length);
164         if (n == -1) {
165           break;
166         } else {
167           z.write(b, 0, n);
168         }
169       }
170       
171       z.closeEntry();
172     }
173     
174     if (f.endsWith(".class")) {
175       classes.add(f);
176       InputStream JavaDoc is = new FileInputStream JavaDoc(new java.io.File JavaDoc(src, f));
177       new ClassReader(is).accept(new DependencyClassVisitor(), true);
178     }
179   }
180   
181   private void addDefinitions (String JavaDoc definitions, ZipOutputStream JavaDoc z, boolean add)
182     throws Exception JavaDoc
183   {
184     if (definitions == null) {
185       return;
186     }
187     int comma = definitions.indexOf(',');
188     if (comma != -1) {
189       addDefinitions(definitions.substring(0, comma), z, add);
190       addDefinitions(definitions.substring(comma + 1), z, add);
191       return;
192     }
193     int dash = definitions.indexOf('-');
194     String JavaDoc definition = definitions.substring(0, dash);
195     String JavaDoc version = definitions.substring(dash + 1);
196     
197     if (!excludes.contains(definition)) {
198       Definition d = loader.load(definition, null);
199       if (!((VersionDefinition)d).getVersion().equals(version)) {
200         throw new Exception JavaDoc("The declared version does not match the requested version");
201       }
202       addFile(definition.replace('.', '/') + ".fractal", version, z, add);
203       addFiles((Node)d, version, z, add);
204     }
205   }
206   
207   // -------------------------------------------------------------------------
208

209   class XMLLoader implements Loader {
210
211     private Parser parser = new XMLParser(true);
212     
213     public Definition load (final String JavaDoc name, final Map JavaDoc context)
214       throws ADLException
215     {
216       try {
217         String JavaDoc file = name.replace('.', '/') + ".fractal";
218         InputStream JavaDoc is;
219         try {
220           is = new FileInputStream JavaDoc(new java.io.File JavaDoc(src, file));
221         } catch (IOException JavaDoc e) {
222           throw new ADLException(
223             "Cannot find file " + src + '/' + file, null, e);
224         }
225         Definition d = (Definition)parser.parse(is, file);
226         if (d.getName() == null) {
227           throw new ADLException("Definition name missing", (Node)d);
228         }
229         if (!d.getName().equals(name)) {
230           throw new ADLException(
231             "Wrong definition name ('" + name +
232             "' expected, instead of '" + d.getName() + "')", (Node)d);
233         }
234         return d;
235       } catch (ParserException e) {
236         throw new ADLException("Cannot load '" + name + "'", null, e);
237       }
238     }
239   }
240   
241   // -------------------------------------------------------------------------
242

243   void addClassDependency (String JavaDoc s) {
244     if (s.startsWith("java") || s.startsWith("org/objectweb/fractal/api")) {
245       libraryDependencies.add(s + ".class");
246     } else {
247       dependencies.add(s + ".class");
248     }
249   }
250
251   void addTypeDependency (Type type) {
252     if (type.getSort() == Type.ARRAY) {
253       addTypeDependency(type.getElementType());
254     } else if (type.getSort() == Type.OBJECT) {
255       addClassDependency(type.getClassName().replace('.', '/'));
256     }
257   }
258
259   void addTypeDependency (Type[] types) {
260     for (int i = 0; i < types.length; ++i) {
261       addTypeDependency(types[i]);
262     }
263   }
264
265   class DependencyClassVisitor implements ClassVisitor, CodeVisitor {
266
267     public void visit (
268       final int version,
269       final int access,
270       final String JavaDoc name,
271       final String JavaDoc superName,
272       final String JavaDoc[] interfaces,
273       final String JavaDoc sourceFile)
274     {
275       addClassDependency(superName);
276       if (interfaces != null) {
277         for (int i = 0; i < interfaces.length; ++i) {
278           addClassDependency(interfaces[i]);
279         }
280       }
281     }
282
283     public void visitInnerClass (
284       final String JavaDoc name,
285       final String JavaDoc outerName,
286       final String JavaDoc innerName,
287       final int access)
288     {
289     }
290
291     public void visitField (
292       final int access,
293       final String JavaDoc name,
294       final String JavaDoc desc,
295       final Object JavaDoc value,
296       final Attribute attrs)
297     {
298       addTypeDependency(Type.getType(desc));
299     }
300
301     public CodeVisitor visitMethod (
302       final int access,
303       final String JavaDoc name,
304       final String JavaDoc desc,
305       final String JavaDoc[] exceptions,
306       final Attribute attrs)
307     {
308       addTypeDependency(Type.getArgumentTypes(desc));
309       addTypeDependency(Type.getReturnType(desc));
310       if (exceptions != null) {
311         for (int i = 0; i < exceptions.length; ++i) {
312           addClassDependency(exceptions[i]);
313         }
314       }
315       return this;
316     }
317
318     public void visitAttribute (final Attribute attr) {
319     }
320
321     public void visitEnd () {
322     }
323     
324     public void visitInsn (final int opcode) {
325     }
326
327     public void visitIntInsn (final int opcode, final int operand) {
328     }
329
330     public void visitVarInsn (final int opcode, final int var) {
331     }
332
333     public void visitTypeInsn (final int opcode, final String JavaDoc desc) {
334       if (desc.charAt(0) == '[') {
335         addTypeDependency(Type.getType(desc));
336       } else {
337         addClassDependency(desc);
338       }
339     }
340
341     public void visitFieldInsn (
342       final int opcode,
343       final String JavaDoc owner,
344       final String JavaDoc name,
345       final String JavaDoc desc)
346     {
347       addClassDependency(owner);
348       addTypeDependency(Type.getType(desc));
349     }
350
351     public void visitMethodInsn (
352       final int opcode,
353       final String JavaDoc owner,
354       final String JavaDoc name,
355       final String JavaDoc desc)
356     {
357       addClassDependency(owner);
358       addTypeDependency(Type.getArgumentTypes(desc));
359       addTypeDependency(Type.getReturnType(desc));
360     }
361
362     public void visitJumpInsn (final int opcode, final Label label) {
363     }
364
365     public void visitLabel (final Label label) {
366     }
367
368     public void visitLdcInsn (final Object JavaDoc cst) {
369     }
370
371     public void visitIincInsn (final int var, final int increment) {
372     }
373
374     public void visitTableSwitchInsn (
375       final int min,
376       final int max,
377       final Label dflt,
378       final Label[] labels)
379     {
380     }
381
382     public void visitLookupSwitchInsn (
383       final Label dflt,
384       final int[] keys,
385       final Label[] labels)
386     {
387     }
388
389     public void visitMultiANewArrayInsn (final String JavaDoc desc, final int dims) {
390       addTypeDependency(Type.getType(desc));
391     }
392
393     public void visitTryCatchBlock (
394       final Label start,
395       final Label end,
396       final Label handler,
397       final String JavaDoc type)
398     {
399       addClassDependency(type);
400     }
401
402     public void visitMaxs (final int maxStack, final int maxLocals) {
403     }
404
405     public void visitLocalVariable (
406       final String JavaDoc name,
407       final String JavaDoc desc,
408       final Label start,
409       final Label end,
410       final int index)
411     {
412     }
413
414     public void visitLineNumber (final int line, final Label start) {
415     }
416   }
417
418   // -------------------------------------------------------------------------
419

420   public static void main (String JavaDoc[] args) throws Exception JavaDoc {
421     if (args.length < 3) {
422       printUsage();
423     }
424     boolean recursive = false;
425     Set JavaDoc excludes = new HashSet JavaDoc();
426     for (int i = 3; i < args.length; ++i) {
427       if (args[i].equals("-r")) {
428         recursive = true;
429       } else if (args[i].equals("-e")) {
430         if (i < args.length - 1) {
431           excludes.add(args[++i]);
432         } else {
433           printUsage();
434         }
435       } else {
436         printUsage();
437       }
438     }
439     new CreatePackage(args[0], args[1], args[2], recursive, excludes).create();
440   }
441   
442   private static void printUsage () {
443     System.err.println("Usage: <src> <dst> <definition> [-r] [-e xxx]*");
444     System.exit(0);
445   }
446 }
447
Popular Tags