KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jarg > Jarg


1 /* ====================================================================
2  * Copyright (c) 2002, Hidetoshi Ohuchi <hchacha@users.sourceforge.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the hchacha nor the names of its contributors
17  * may be used to endorse or promote products derived from this
18  * software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  * ====================================================================
33  */

34 package jarg;
35
36 import java.io.*;
37 import java.util.*;
38 import java.util.jar.*;
39 import java.util.zip.*;
40
41 import org.apache.bcel.classfile.*;
42 import org.apache.bcel.generic.*;
43 import org.apache.bcel.Constants;
44
45 /**
46  * The Main class of Java Archive Grinder (jarg) .
47  *
48  * Copyright (c) 2002,
49  * <A HREF="mailto:Hidetoshi Ohuchi <hchacha@users.sourceforge.net>">
50  * Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;</A><BR>
51  *
52  * @version 0.9.14 - $Id: Jarg.java,v 1.26 2003/02/10 17:46:14 hchacha Exp $
53  * @author Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;
54  */

55 public class Jarg {
56    private boolean isPrintVersion = false;
57    private boolean isShowTime = false;
58    private String JavaDoc renameLogFileName;
59    private String JavaDoc jarFile;
60
61    boolean isVerbose = false;
62    boolean isVerboseRN = false;
63    boolean isVerboseBCO = false;
64    boolean isVerboseUCI = false;
65    boolean isVerboseUFM = false;
66    boolean isVerboseAll = false;
67    boolean isShowStat = false;
68
69    private boolean isCompressed = true;
70    private boolean isRemoveDirectryEntry = true;
71    boolean isRemoveLocalVariable = true;
72    boolean isRemoveLineNumber = true;
73    boolean isRemoveSourceFile = true;
74    boolean isRemoveSynthetic = true;
75    boolean isRemoveInnerClasses = true;
76    boolean isRemoveExceptions = true;
77    boolean isRenameClass = true;
78    boolean isRenameField = true;
79    boolean isRenameMethod = true;
80    boolean isByteCodeOptimizing = true;
81    ArrayList main_class = new ArrayList();
82
83    boolean isJ2ME = false;
84    String JavaDoc j2me_prev;
85    String JavaDoc j2me_cp;
86
87    Statistics statistics = new Statistics();
88
89    // excepting
90
private Set _excpPathes = new TreeSet();
91    String JavaDoc[] excpPathes;
92    Set excpPackages = new HashSet();
93    Set excpClasses = new HashSet();
94    Set excpFields = new HashSet();
95    Set excpMethods = new HashSet();
96
97    // logging
98
PrintStream renameLog;
99
100    private static void printVersion() {
101       System.out.println("jarg - Java Archive Grinder (jarg) - ver 0.9.15-pre1");
102    }
103
104    private static void printUsage() {
105       printVersion();
106       System.out.println("[usage] java -jar jarg.jar {options} xxxx.jar");
107       System.out.println(" options");
108       System.out.println(" -version : show version");
109       System.out.println(" -verbose : verbose mode");
110       System.out.println(" -verbosern : verbose of renaming");
111       System.out.println(" -verboseuci : verbose of removing unused classes and interfaces");
112       System.out.println(" -verboseufm : verbose of removing unused fields and methods");
113       System.out.println(" -verbosebco : verbose of byte-code optimizing");
114       System.out.println(" -verboseall : verbose all");
115
116       System.out.println(" -showstat : show statistics");
117       System.out.println(" -showtime : show time");
118
119       System.out.println(" -main : main class name. ");
120       System.out.println(" if this option is specified, unused classes are removed.");
121       System.out.println(" These one or more options can be specified.");
122
123       System.out.println(" -nocomp : no commpressed output jar file");
124
125       System.out.println(" -normdir : no remove directry entry in jar file");
126       System.out.println(" -normlv : no remove local variable");
127       System.out.println(" -normln : no remove line number");
128       System.out.println(" -normsf : no remove source file");
129       System.out.println(" -normsy : no remove 'Synthetic'");
130       System.out.println(" -normin : no remove 'InnerClasses'");
131       System.out.println(" -normex : no remove 'Exceptions'");
132
133       System.out.println(" -nornc : no rename class");
134       System.out.println(" -nornf : no rename field");
135       System.out.println(" -nornm : no rename method");
136
137       System.out.println(" -nobco : no byte-code optimizing");
138
139       System.out.println(" -excpp @file : list of excepting package");
140       System.out.println(" -excpc @file : list of excepting class");
141       System.out.println(" -excpf @file : list of excepting field");
142       System.out.println(" -excpm @file : list of excepting method");
143       System.out.println(" -rnlog file : rename log file");
144
145       System.out.println(" -j2me-prev preverify : preverify command path");
146       System.out.println(" -j2me-cp classpath : preverify class path");
147       System.out.println();
148       System.out.println(" remove class example > java -jar jarg.jar -main path.to.class -main path.to.class2");
149       System.out.println(" j2me example > java -jar jarg.jar -j2me-prev c:\\j2mewtk\\bin\\preverify.exe -j2me-cp c:\\j2mewtk\\lib\\midpapi.zip xxx.jar");
150    }
151
152    Jarg() {
153       setupExcepting();
154    }
155
156    private void setupExcepting() {
157       //
158
_excpPathes.add("java.lang");
159       _excpPathes.add("java.security");
160       //
161
// excpPackages.add();
162
//
163
excpClasses.add("sun.awt.font.StandardGlyphVector");
164       excpClasses.add("java.io.ObjectStreamField");
165       excpClasses.add("java.io.File");
166       excpClasses.add("java.io.Win32FileSystem");
167    }
168
169    private void fixupExcpPathes() {
170       excpPathes = new String JavaDoc[_excpPathes.size()];
171       _excpPathes.toArray(excpPathes);
172       _excpPathes = null;
173    }
174
175    private void readExcpPackagFile(String JavaDoc fnm) throws FileNotFoundException, IOException {
176       FileReader frd = new FileReader(fnm);
177       LineNumberReader rd = new LineNumberReader(frd);
178       String JavaDoc line;
179       while ((line = rd.readLine()) != null) {
180          line = line.trim();
181          if (line.startsWith("#")) {
182             // comment skip
183
} else if (line.endsWith(".*")) {
184             _excpPathes.add(line.substring(0, line.length()-2));
185          } else {
186             excpPackages.add(line);
187          }
188       }
189       rd.close();
190       frd.close();
191    }
192
193    private List readExcpFile(String JavaDoc fnm) throws FileNotFoundException, IOException {
194       List lst = new ArrayList();
195       FileReader frd = new FileReader(fnm);
196       LineNumberReader rd = new LineNumberReader(frd);
197       String JavaDoc line;
198       while ((line = rd.readLine()) != null) {
199          line = line.trim();
200          if (line.startsWith("#")) {
201             // comment skip
202
} else {
203             lst.add(line);
204          }
205       }
206       rd.close();
207       frd.close();
208       return lst;
209    }
210
211    private boolean setOptions(String JavaDoc[] args) throws FileNotFoundException, IOException {
212       for (int i=0; i < args.length; i++) {
213          String JavaDoc arg = args[i];
214          if (arg.startsWith("-")) {
215             if (arg.equals("-version")) {
216                this.isPrintVersion = true;
217                return false;
218             } else if (arg.equals("-verbose")) {
219                this.isVerbose = true;
220                this.isShowStat = true;
221             } else if (arg.equals("-verbosern")) {
222                this.isVerboseRN = true;
223             } else if (arg.equals("-verboseuci")) {
224                this.isVerboseUCI = true;
225             } else if (arg.equals("-verboseufm")) {
226                this.isVerboseUFM = true;
227             } else if (arg.equals("-verbosebco")) {
228                this.isVerboseBCO = true;
229             } else if (arg.equals("-verboseall")) {
230                this.isVerbose = true;
231                this.isVerboseRN = true;
232                this.isVerboseUCI = true;
233                this.isVerboseUFM = true;
234                this.isVerboseBCO = true;
235                this.isVerboseAll = true;
236                this.isShowStat = true;
237             } else if (arg.equals("-showstat")) {
238                this.isShowStat = true;
239             } else if (arg.equals("-showtime")) {
240                this.isShowTime = true;
241             } else if (arg.equals("-nocomp")) {
242                this.isCompressed = false;
243             } else if (arg.equals("-normdir")) {
244                this.isRemoveDirectryEntry = false;
245             } else if (arg.equals("-normlv")) {
246                this.isRemoveLocalVariable = false;
247                this.isRemoveSourceFile = false;
248             } else if (arg.equals("-normln")) {
249                this.isRemoveLineNumber = false;
250                this.isRemoveSourceFile = false;
251             } else if (arg.equals("-normsf")) {
252                this.isRemoveSourceFile = false;
253             } else if (arg.equals("-normsy")) {
254                this.isRemoveSynthetic = false;
255             } else if (arg.equals("-normin")) {
256                this.isRemoveInnerClasses = false;
257             } else if (arg.equals("-normex")) {
258                this.isRemoveExceptions = false;
259             } else if (arg.equals("-nornc")) {
260                this.isRenameClass = false;
261             } else if (arg.equals("-nornf")) {
262                this.isRenameField = false;
263             } else if (arg.equals("-nornm")) {
264                this.isRenameMethod = false;
265             } else if (arg.equals("-nobco")) {
266                this.isByteCodeOptimizing = false;
267             } else if (arg.equals("-main")) {
268                i++;
269                if (i < args.length) {
270                   this.main_class.add(args[i]);
271                }
272             } else if (arg.equals("-excpp")) {
273                i++;
274                if (i < args.length && args[i].startsWith("@")) {
275                   this.readExcpPackagFile(args[i].substring(1));
276                } else {
277                   System.out.println("illigal option : " + arg + " : need @");
278                   printUsage();
279                   return false;
280                }
281             } else if (arg.equals("-excpc")) {
282                i++;
283                if (i < args.length && args[i].startsWith("@")) {
284                   List lst = this.readExcpFile(args[i].substring(1));
285                   this.excpClasses.addAll(lst);
286                } else {
287                   System.out.println("illigal option : " + arg + " : need @");
288                   printUsage();
289                   return false;
290                }
291             } else if (arg.equals("-excpf")) {
292                i++;
293                if (i < args.length && args[i].startsWith("@")) {
294                   List lst = this.readExcpFile(args[i].substring(1));
295                   this.excpFields.addAll(lst);
296                } else {
297                   System.out.println("illigal option : " + arg + " : need @");
298                   printUsage();
299                   return false;
300                }
301             } else if (arg.equals("-excpm")) {
302                i++;
303                if (i < args.length && args[i].startsWith("@")) {
304                   List lst = this.readExcpFile(args[i].substring(1));
305                   this.excpMethods.addAll(lst);
306                } else {
307                   System.out.println("illigal option : " + arg + " : need @");
308                   printUsage();
309                   return false;
310                }
311             } else if (arg.equals("-rnlog")) {
312                i++;
313                if (i < args.length) {
314                   this.renameLogFileName = args[i];
315                } else {
316                   System.out.println("illigal option : " + arg + " : need a file name");
317                   printUsage();
318                   return false;
319                }
320             } else if (arg.equals("-j2me-prev")) {
321                i++;
322                if (i < args.length) {
323                   this.j2me_prev = args[i];
324                   this.isJ2ME = true;
325                } else {
326                   System.out.println("illigal option : " + arg + " : need a command path to preverify");
327                   printUsage();
328                   return false;
329                }
330             } else if (arg.equals("-j2me-cp")) {
331                i++;
332                if (i < args.length) {
333                   this.j2me_cp = args[i];
334                   this.isJ2ME = true;
335                } else {
336                   System.out.println("illigal option : " + arg + " : need a class path for preverify");
337                   printUsage();
338                   return false;
339                }
340             } else {
341                System.out.println("illigal option : " + arg);
342                printUsage();
343                return false;
344             }
345          } else if (arg.endsWith(".jar")) {
346             this.jarFile = args[i];
347          }
348       }
349       return true;
350    }
351
352    public static void main(String JavaDoc[] args) {
353       Jarg rn = new Jarg();
354       try {
355          if (!rn.setOptions(args)) {
356             return;
357          }
358          if (rn.isJ2ME) {
359             if (rn.j2me_prev == null || rn.j2me_cp == null) {
360                System.out.println("illigal option for j2me: need 2 options : -j2me-prev -j2me-cp");
361                printUsage();
362             }
363          }
364          if (rn.jarFile != null) {
365             if (rn.renameLogFileName != null) {
366                FileOutputStream logout = new FileOutputStream(rn.renameLogFileName);
367                rn.renameLog = new PrintStream(logout);
368                rn.renameLog.println("jarg : " + rn.jarFile);
369                rn.renameLog.println();
370             }
371             long st = System.currentTimeMillis();
372             rn.fixupExcpPathes();
373             rn.procJarFile(rn.jarFile);
374             long ed = System.currentTimeMillis();
375             if (rn.isShowTime) {
376                System.out.println("" + (ed - st) + "[msec]");
377             }
378             if (rn.renameLog != null) {
379                rn.renameLog.close();
380             }
381             if (rn.isShowStat) {
382                rn.statistics.print();
383             }
384          } else {
385             printUsage();
386          }
387       } catch(Exception JavaDoc e) {
388          System.err.println(e.getMessage());
389          e.printStackTrace(System.err);
390       }
391    }
392
393    private List metainf = new ArrayList();
394    private List image = new ArrayList();
395
396    private void procJarFile(String JavaDoc jarfn) throws IOException {
397       // in file
398
File jarf = new File(jarfn);
399       if (!jarf.exists()) {
400          System.err.println("File not found : " + jarfn);
401          return;
402       }
403       JarFile jarin = new JarFile(jarf);
404
405       // out file
406
String JavaDoc jarfn2 = jarfn.substring(0, jarfn.length()-4) + "_s.jar";
407       File jarfout = new File(jarfn2);
408       if (jarfout.exists()) {
409          jarfout.delete();
410       }
411       FileOutputStream fout = new FileOutputStream(jarfout);
412       JarOutputStream jarout = new JarOutputStream(fout);
413
414       //
415
Object JavaDoc[][] zess = getEntries(jarin);
416
417       // META-INF
418
ZipEntry[] zes = (ZipEntry[])zess[0];
419       {
420          Set storedSet = new HashSet();
421          for (int i=0; i<zes.length; i++) {
422             ZipEntry ze = zes[i];
423             String JavaDoc zeNm = ze.getName();
424             if (storedSet.contains(zeNm)) {
425                continue;
426             }
427             byte[] buf = null;
428             if (ze.isDirectory()) {
429                if (!isRemoveDirectryEntry && zeNm != null & zeNm.length() > 0) {
430                   outJarEntry(jarout, zeNm, null);
431                   if (this.isVerbose) {
432                      System.out.println(zeNm);
433                   }
434                }
435             } else {
436                buf = inJarEntry2(jarin, ze);
437                outJarEntry(jarout, zeNm, buf);
438                if (this.isVerbose) {
439                   System.out.println(zeNm);
440                }
441             }
442             storedSet.add(zeNm);
443          }
444          storedSet.clear();
445          storedSet = null;
446       }
447
448       // other
449
if (this.isVerbose) {
450          System.out.println("Reading class files ...");
451       }
452       List imglst = new ArrayList();
453       PackageCollection pkgcol = new PackageCollection(this);
454
455       DirectoryHandler[] dhs = (DirectoryHandler[])zess[1];
456       for (int i=0; i<dhs.length; i++) {
457          DirectoryHandler dh = dhs[i];
458
459          PackageHandler pkgh = new PackageHandler(this, dh.path);
460
461          // read files
462
for (int j=0; j<dh.zes.length; j++) {
463             ZipEntry ze = dh.zes[j];
464             if (ze.isDirectory()) {
465                outJarEntry(jarout, ze.getName(), null);
466                if (this.isVerboseAll) {
467                   System.out.println(ze.getName());
468                }
469             } else if (ze.getName().endsWith(".class")) {
470                byte[] buf = inJarEntry2(jarin, ze);
471                ClassHandler clsh = new ClassHandler(this, ze.getName(), buf);
472                pkgh.addClassHandler(clsh);
473             } else {
474                byte[] buf = inJarEntry2(jarin, ze);
475                ImageHandler imh = new ImageHandler(this, ze.getName(), buf);
476                imglst.add(imh);
477             }
478          }
479
480          pkgcol.addPackageHandler(pkgh);
481       }
482       jarin.close();
483
484       // check used class
485
if (main_class.size() > 0) {
486          if (this.isVerbose) {
487             System.out.println("Scan class files for checking used classes ...");
488          }
489          pkgcol.doCheckUsedClass();
490          for (int i=0; i<main_class.size(); i++) {
491             pkgcol.markUsedClass(((String JavaDoc)main_class.get(i)).replace('.','/'));
492          }
493       }
494
495       // optimize
496
if (this.isVerbose) {
497          System.out.println("Optimizing class files ...");
498       }
499       pkgcol.doOptimize();
500
501       // for j2me
502
File outdir2 = new File(".jarg.me.tmp.2");
503       if (isJ2ME) {
504          outdir2.mkdir();
505          procJ2ME(outdir2, pkgcol);
506       }
507
508       // write directory
509
if (!isRemoveDirectryEntry) {
510          for (int i=0; i<dhs.length; i++) {
511             DirectoryHandler dh = dhs[i];
512
513             if (dh.path != null & dh.path.length() > 0) {
514                outJarEntry(jarout, dh.path, null);
515                if (this.isVerbose) {
516                   System.out.println(dh.path);
517                }
518             }
519          }
520       }
521
522       // write class
523
if (this.isVerbose) {
524          System.out.println("Writing class files ...");
525       }
526       Iterator pit = pkgcol.packages.keySet().iterator();
527       while (pit.hasNext()) {
528          String JavaDoc pkey = (String JavaDoc)pit.next();
529          PackageHandler pkgh = (PackageHandler)pkgcol.packages.get(pkey);
530
531          // write class files
532
Iterator cit = pkgh.classes.keySet().iterator();
533          while (cit.hasNext()) {
534             String JavaDoc ckey = (String JavaDoc)cit.next();
535             ClassHandler clsh = (ClassHandler)pkgh.classes.get(ckey);
536             if (main_class.size() > 0 && !clsh.isUsed) {
537                if (this.isVerboseUCI) {
538                   System.out.println("" + clsh.filename + " is removed");
539                }
540             } else {
541                clsh.setupNewStatistics();
542                byte[] buf = clsh.getBytes();
543                this.statistics.addNewClassFileSize(buf.length);
544
545                try {
546                   byte[] buff;
547                   if (isJ2ME) {
548                      buff = inClassFile(new File(outdir2, clsh.filename));
549                   } else {
550                      buff = clsh.getBytes();
551                   }
552                   outJarEntry(jarout, clsh.filename, buff);
553                } catch (IOException ex) {
554                   jarout.close();
555                   fout.close();
556                   throw ex;
557                }
558
559                if (this.isVerbose) {
560                   int cmp = (int)((100.0 * buf.length)/(double)clsh.orgsize);
561                   System.out.println("" + clsh.filename + " (" + cmp + "%)");
562                }
563             }
564          }
565       }
566
567       // write image
568
if (this.isVerbose) {
569          System.out.println("Writing other files ...");
570       }
571       Iterator iit = imglst.iterator();
572       while (iit.hasNext()) {
573          ImageHandler imh = (ImageHandler)iit.next();
574          outJarEntry(jarout, imh.filename, imh.getBytes());
575          if (this.isVerbose) {
576             System.out.println(imh.filename);
577          }
578       }
579
580       jarout.close();
581       fout.close();
582       if (isJ2ME) {
583          deleteDirs(outdir2);
584       }
585    }
586
587    private Object JavaDoc[][] getEntries(JarFile jarin) {
588       List lstmt = new ArrayList();
589       Map map = new HashMap();
590       List lst = new ArrayList();
591
592       Enumeration en = jarin.entries();
593       while (en.hasMoreElements()) {
594          // read a entry
595
ZipEntry ze = (ZipEntry)en.nextElement();
596          if (ze.getName().startsWith("META-INF/")) {
597             lstmt.add(ze);
598          } else {
599             String JavaDoc path = ze.getName();
600             if (!ze.isDirectory()) {
601                int idx = path.lastIndexOf('/');
602                if (idx < 0) {
603                   path = "";
604                } else {
605                   path = path.substring(0, idx+1);
606                }
607             }
608             DirectoryHandler dh = (DirectoryHandler)map.get(path);
609             if (dh == null) {
610                dh = new DirectoryHandler(this, path, jarin);
611                map.put(path, dh);
612                lst.add(dh);
613             }
614             if (!ze.isDirectory()) {
615                dh.addFile(ze);
616             }
617          }
618       }
619
620       // META-INF
621
ZipEntry[] zesmt = new ZipEntry[lstmt.size()];
622       lstmt.toArray(zesmt);
623
624       // other
625
DirectoryHandler[] dhs = new DirectoryHandler[lst.size()];
626       lst.toArray(dhs);
627       Arrays.sort(dhs);
628       for (int j=0; j<dhs.length; j++) {
629          DirectoryHandler dh = dhs[j];
630          dh.fixEntry();
631       }
632
633       // return
634
Object JavaDoc[][] r = new Object JavaDoc[2][];
635       r[0] = zesmt;
636       r[1] = dhs;
637
638       return r;
639    }
640
641    private byte[] inJarEntry2(JarFile jarin, ZipEntry ze) throws IOException {
642       long sz = ze.getSize();
643 // String nm = ze.getName();
644
// System.out.print(nm);
645
// long cmpsz = ze.getCompressedSize();
646
// String cmt = ze.getComment();
647
// System.out.println(" : " + sz + " : " + cmpsz + " : " + cmt);
648

649       // read a entry data
650
byte[] buf = new byte[(int)sz];
651       InputStream zein = jarin.getInputStream(ze);
652       DataInputStream din = new DataInputStream(zein);
653       din.readFully(buf);
654       din.close();
655       zein.close();
656
657       return buf;
658    }
659
660    private void outJarEntry(JarOutputStream jarout, String JavaDoc filename, byte[] buf) throws IOException {
661       // write a entry
662
ZipEntry ze = new ZipEntry(filename);
663       CRC32 crc32 = new CRC32();
664       int zeM = (this.isCompressed) ? ZipEntry.DEFLATED : ZipEntry.STORED;
665
666       ze.setMethod(zeM);
667       ze.setCompressedSize(-1);
668       if (buf == null) {
669          ze.setSize(0);
670          ze.setCrc(0);
671       } else {
672          ze.setSize(buf.length);
673          crc32.reset();
674          crc32.update(buf);
675          ze.setCrc(crc32.getValue());
676       }
677       jarout.putNextEntry(ze);
678
679       // write a entry data
680
if (buf != null) {
681          if (this.isCompressed) {
682             jarout.setMethod(ZipOutputStream.DEFLATED);
683             jarout.setLevel(Deflater.BEST_COMPRESSION);
684          }
685          jarout.write(buf);
686       }
687       jarout.closeEntry();
688    }
689
690    private void procJ2ME(File outdir2, PackageCollection pkgcol) throws IOException {
691       File outdir = new File(".jarg.me.tmp");
692       outdir.mkdir();
693
694       procJ2MEout(pkgcol, outdir);
695
696       // launch preverify command
697
//..\..\..\bin\preverify -classpath ..\..\..\lib\midpapi.zip;..\tmpclasses -d ..\classes ..\tmpclasses
698
String JavaDoc[] cmdarray = {
699          j2me_prev,
700          "-classpath", j2me_cp + File.pathSeparator + outdir.getPath(),
701          "-d", outdir2.getPath(),
702          outdir.getPath()
703          };
704
705       Process JavaDoc proc = Runtime.getRuntime().exec(cmdarray);
706       InputStream ein = new BufferedInputStream(proc.getErrorStream());
707       int r = 0;
708       try {
709          r = proc.waitFor();
710       } catch (InterruptedException JavaDoc ex) {
711       }
712       for (;;) {
713          int i = ein.read();
714          if (i < 0) {
715             break;
716          }
717          System.err.write(i);
718       }
719       ein.close();
720
721       deleteDirs(outdir);
722
723       if (r != 0) {
724          // ERROR
725
throw new IOException("not exec preverify command.");
726       }
727    }
728
729    private void deleteDirs(File dir) throws IOException {
730       if (dir.isDirectory()) {
731          File[] children = dir.listFiles();
732          for (int i=0; i<children.length; i++) {
733             deleteDirs(children[i]);
734          }
735       }
736       dir.delete();
737    }
738
739    private void procJ2MEout(PackageCollection pkgcol, File outdir) throws IOException {
740       Iterator pit = pkgcol.packages.keySet().iterator();
741       while (pit.hasNext()) {
742          String JavaDoc pkey = (String JavaDoc)pit.next();
743          PackageHandler pkgh = (PackageHandler)pkgcol.packages.get(pkey);
744
745          // write class files
746
Iterator cit = pkgh.classes.keySet().iterator();
747          while (cit.hasNext()) {
748             String JavaDoc ckey = (String JavaDoc)cit.next();
749             ClassHandler clsh = (ClassHandler)pkgh.classes.get(ckey);
750             byte[] buf = clsh.getBytes();
751
752             try {
753                outClassFile(outdir, clsh.filename, clsh.getBytes());
754             } catch (IOException ex) {
755                throw ex;
756             }
757          }
758       }
759    }
760
761    private void outClassFile(File baseDir, String JavaDoc filepath, byte[] data) throws IOException {
762       File newfile = new File(baseDir, filepath);
763       File parent = newfile.getParentFile();
764       if (!parent.exists()) {
765          parent.mkdirs();
766       }
767       OutputStream out = new BufferedOutputStream(new FileOutputStream(newfile));
768       out.write(data);
769       out.close();
770    }
771
772    private byte[] inClassFile(File infile) throws IOException {
773       byte[] buff = new byte[(int)(infile.length())];
774       InputStream in = new BufferedInputStream(new FileInputStream(infile));
775       DataInputStream din = new DataInputStream(in);
776       din.readFully(buff);
777       din.close();
778       return buff;
779    }
780 }
781
Popular Tags