Source Code Cross Referenced for Driver.java in  » 6.0-JDK-Modules-com.sun.java » util » com » sun » java » util » jar » pack » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun.java » util » com.sun.java.util.jar.pack 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package com.sun.java.util.jar.pack;
027:
028:        import java.lang.Error;
029:        import java.io.*;
030:        import java.text.MessageFormat;
031:        import java.util.*;
032:        import java.util.jar.*;
033:        import java.util.zip.*;
034:
035:        /** Command line interface for Pack200.
036:         */
037:        class Driver {
038:            private static final ResourceBundle RESOURCE = ResourceBundle
039:                    .getBundle("com.sun.java.util.jar.pack.DriverResource");
040:
041:            public static void main(String[] ava) throws IOException {
042:                ArrayList<String> av = new ArrayList<String>(Arrays.asList(ava));
043:
044:                boolean doPack = true;
045:                boolean doUnpack = false;
046:                boolean doRepack = false;
047:                boolean doForceRepack = false;
048:                boolean doZip = true;
049:                String logFile = null;
050:                String verboseProp = Utils.DEBUG_VERBOSE;
051:
052:                {
053:                    // Non-standard, undocumented "--unpack" switch enables unpack mode.
054:                    String arg0 = av.isEmpty() ? "" : av.get(0);
055:                    if (arg0.equals("--pack")) {
056:                        av.remove(0);
057:                    } else if (arg0.equals("--unpack")) {
058:                        av.remove(0);
059:                        doPack = false;
060:                        doUnpack = true;
061:                    }
062:                }
063:
064:                // Collect engine properties here:
065:                HashMap<String, String> engProps = new HashMap<String, String>();
066:                engProps.put(verboseProp, System.getProperty(verboseProp));
067:
068:                String optionMap;
069:                String[] propTable;
070:                if (doPack) {
071:                    optionMap = PACK200_OPTION_MAP;
072:                    propTable = PACK200_PROPERTY_TO_OPTION;
073:                } else {
074:                    optionMap = UNPACK200_OPTION_MAP;
075:                    propTable = UNPACK200_PROPERTY_TO_OPTION;
076:                }
077:
078:                // Collect argument properties here:
079:                HashMap<String, String> avProps = new HashMap<String, String>();
080:                try {
081:                    for (;;) {
082:                        String state = parseCommandOptions(av, optionMap,
083:                                avProps);
084:                        // Translate command line options to Pack200 properties:
085:                        eachOpt: for (Iterator<String> opti = avProps.keySet()
086:                                .iterator(); opti.hasNext();) {
087:                            String opt = opti.next();
088:                            String prop = null;
089:                            for (int i = 0; i < propTable.length; i += 2) {
090:                                if (opt.equals(propTable[1 + i])) {
091:                                    prop = propTable[0 + i];
092:                                    break;
093:                                }
094:                            }
095:                            if (prop != null) {
096:                                String val = avProps.get(opt);
097:                                opti.remove(); // remove opt from avProps
098:                                if (!prop.endsWith(".")) {
099:                                    // Normal string or boolean.
100:                                    if (!(opt.equals("--verbose") || opt
101:                                            .endsWith("="))) {
102:                                        // Normal boolean; convert to T/F.
103:                                        boolean flag = (val != null);
104:                                        if (opt.startsWith("--no-"))
105:                                            flag = !flag;
106:                                        val = flag ? "true" : "false";
107:                                    }
108:                                    engProps.put(prop, val);
109:                                } else if (prop.contains(".attribute.")) {
110:                                    for (String val1 : val.split("\0")) {
111:                                        String[] val2 = val1.split("=", 2);
112:                                        engProps.put(prop + val2[0], val2[1]);
113:                                    }
114:                                } else {
115:                                    // Collection property: pack.pass.file.cli.NNN
116:                                    int idx = 1;
117:                                    for (String val1 : val.split("\0")) {
118:                                        String prop1;
119:                                        do {
120:                                            prop1 = prop + "cli." + (idx++);
121:                                        } while (engProps.containsKey(prop1));
122:                                        engProps.put(prop1, val1);
123:                                    }
124:                                }
125:                            }
126:                        }
127:
128:                        // See if there is any other action to take.
129:                        if (state == "--config-file=") {
130:                            String propFile = av.remove(0);
131:                            InputStream propIn = new FileInputStream(propFile);
132:                            Properties fileProps = new Properties();
133:                            fileProps.load(new BufferedInputStream(propIn));
134:                            if (engProps.get(verboseProp) != null)
135:                                fileProps.list(System.out);
136:                            propIn.close();
137:                            for (Map.Entry<Object, Object> me : fileProps
138:                                    .entrySet())
139:                                engProps.put((String) me.getKey(), (String) me
140:                                        .getValue());
141:                        } else if (state == "--version") {
142:                            System.out.println(MessageFormat.format(RESOURCE
143:                                    .getString(DriverResource.VERSION),
144:                                    Driver.class.getName(), "1.31, 07/05/05"));
145:                            return;
146:                        } else if (state == "--help") {
147:                            printUsage(doPack, true, System.out);
148:                            System.exit(1);
149:                            return;
150:                        } else {
151:                            break;
152:                        }
153:                    }
154:                } catch (IllegalArgumentException ee) {
155:                    System.err.println(MessageFormat.format(RESOURCE
156:                            .getString(DriverResource.BAD_ARGUMENT), ee));
157:                    printUsage(doPack, false, System.err);
158:                    System.exit(2);
159:                    return;
160:                }
161:
162:                // Deal with remaining non-engine properties:
163:                for (String opt : avProps.keySet()) {
164:                    String val = avProps.get(opt);
165:                    if (opt == "--repack") {
166:                        doRepack = true;
167:                    } else if (opt == "--no-gzip") {
168:                        doZip = (val == null);
169:                    } else if (opt == "--log-file=") {
170:                        logFile = val;
171:                    } else {
172:                        throw new InternalError(MessageFormat.format(RESOURCE
173:                                .getString(DriverResource.BAD_OPTION), opt,
174:                                avProps.get(opt)));
175:                    }
176:                }
177:
178:                if (logFile != null && !logFile.equals("")) {
179:                    if (logFile.equals("-")) {
180:                        System.setErr(System.out);
181:                    } else {
182:                        OutputStream log = new FileOutputStream(logFile);
183:                        //log = new BufferedOutputStream(out);
184:                        System.setErr(new PrintStream(log));
185:                    }
186:                }
187:
188:                boolean verbose = (engProps.get(verboseProp) != null);
189:
190:                String packfile = "";
191:                if (!av.isEmpty())
192:                    packfile = av.remove(0);
193:
194:                String jarfile = "";
195:                if (!av.isEmpty())
196:                    jarfile = av.remove(0);
197:
198:                String newfile = ""; // output JAR file if --repack
199:                String bakfile = ""; // temporary backup of input JAR
200:                String tmpfile = ""; // temporary file to be deleted
201:                if (doRepack) {
202:                    // The first argument is the target JAR file.
203:                    // (Note:  *.pac is nonstandard, but may be necessary
204:                    // if a host OS truncates file extensions.)
205:                    if (packfile.toLowerCase().endsWith(".pack")
206:                            || packfile.toLowerCase().endsWith(".pac")
207:                            || packfile.toLowerCase().endsWith(".gz")) {
208:                        System.err.println(MessageFormat.format(RESOURCE
209:                                .getString(DriverResource.BAD_REPACK_OUTPUT),
210:                                packfile));
211:                        printUsage(doPack, false, System.err);
212:                        System.exit(2);
213:                    }
214:                    newfile = packfile;
215:                    // The optional second argument is the source JAR file.
216:                    if (jarfile.equals("")) {
217:                        // If only one file is given, it is the only JAR.
218:                        // It serves as both input and output.
219:                        jarfile = newfile;
220:                    }
221:                    tmpfile = createTempFile(newfile, ".pack").getPath();
222:                    packfile = tmpfile;
223:                    doZip = false; // no need to zip the temporary file
224:                }
225:
226:                if (!av.isEmpty()
227:                // Accept jarfiles ending with .jar or .zip.
228:                        // Accept jarfile of "-" (stdout), but only if unpacking.
229:                        || !(jarfile.toLowerCase().endsWith(".jar")
230:                                || jarfile.toLowerCase().endsWith(".zip") || (jarfile
231:                                .equals("-") && !doPack))) {
232:                    printUsage(doPack, false, System.err);
233:                    System.exit(2);
234:                    return;
235:                }
236:
237:                if (doRepack)
238:                    doPack = doUnpack = true;
239:                else if (doPack)
240:                    doUnpack = false;
241:
242:                Pack200.Packer jpack = Pack200.newPacker();
243:                Pack200.Unpacker junpack = Pack200.newUnpacker();
244:
245:                jpack.properties().putAll(engProps);
246:                junpack.properties().putAll(engProps);
247:                if (doRepack && newfile.equals(jarfile)) {
248:                    String zipc = getZipComment(jarfile);
249:                    if (verbose && zipc.length() > 0)
250:                        System.out
251:                                .println(MessageFormat
252:                                        .format(
253:                                                RESOURCE
254:                                                        .getString(DriverResource.DETECTED_ZIP_COMMENT),
255:                                                zipc));
256:                    if (zipc.indexOf(Utils.PACK_ZIP_ARCHIVE_MARKER_COMMENT) >= 0) {
257:                        System.out.println(MessageFormat.format(RESOURCE
258:                                .getString(DriverResource.SKIP_FOR_REPACKED),
259:                                jarfile));
260:                        doPack = false;
261:                        doUnpack = false;
262:                        doRepack = false;
263:                    }
264:                }
265:
266:                try {
267:
268:                    if (doPack) {
269:                        // Mode = Pack.
270:                        JarFile in = new JarFile(new File(jarfile));
271:                        OutputStream out;
272:                        // Packfile must be -, *.gz, *.pack, or *.pac.
273:                        if (packfile.equals("-")) {
274:                            out = System.out;
275:                            // Send warnings, etc., to stderr instead of stdout.
276:                            System.setOut(System.err);
277:                        } else if (doZip) {
278:                            if (!packfile.endsWith(".gz")) {
279:                                System.err
280:                                        .println(MessageFormat
281:                                                .format(
282:                                                        RESOURCE
283:                                                                .getString(DriverResource.WRITE_PACK_FILE),
284:                                                        packfile));
285:                                printUsage(doPack, false, System.err);
286:                                System.exit(2);
287:                            }
288:                            out = new FileOutputStream(packfile);
289:                            out = new BufferedOutputStream(out);
290:                            out = new GZIPOutputStream(out);
291:                        } else {
292:                            if (!packfile.toLowerCase().endsWith(".pack")
293:                                    && !packfile.toLowerCase().endsWith(".pac")) {
294:                                System.err
295:                                        .println(MessageFormat
296:                                                .format(
297:                                                        RESOURCE
298:                                                                .getString(DriverResource.WIRTE_PACKGZ_FILE),
299:                                                        packfile));
300:                                printUsage(doPack, false, System.err);
301:                                System.exit(2);
302:                            }
303:                            out = new FileOutputStream(packfile);
304:                            out = new BufferedOutputStream(out);
305:                        }
306:                        jpack.pack(in, out);
307:                        //in.close();  // p200 closes in but not out
308:                        out.close();
309:                    }
310:
311:                    if (doRepack && newfile.equals(jarfile)) {
312:                        // If the source and destination are the same,
313:                        // we will move the input JAR aside while regenerating it.
314:                        // This allows us to restore it if something goes wrong.
315:                        File bakf = createTempFile(jarfile, ".bak");
316:                        // On Windows target must be deleted see 4017593 
317:                        bakf.delete();
318:                        boolean okBackup = new File(jarfile).renameTo(bakf);
319:                        if (!okBackup) {
320:                            throw new Error(
321:                                    MessageFormat
322:                                            .format(
323:                                                    RESOURCE
324:                                                            .getString(DriverResource.SKIP_FOR_MOVE_FAILED),
325:                                                    bakfile));
326:                        } else {
327:                            // Open jarfile recovery bracket.
328:                            bakfile = bakf.getPath();
329:                        }
330:                    }
331:
332:                    if (doUnpack) {
333:                        // Mode = Unpack.
334:                        InputStream in;
335:                        if (packfile.equals("-"))
336:                            in = System.in;
337:                        else
338:                            in = new FileInputStream(new File(packfile));
339:                        BufferedInputStream inBuf = new BufferedInputStream(in);
340:                        in = inBuf;
341:                        if (Utils.isGZIPMagic(Utils.readMagic(inBuf))) {
342:                            in = new GZIPInputStream(in);
343:                        }
344:                        String outfile = newfile.equals("") ? jarfile : newfile;
345:                        OutputStream fileOut;
346:                        if (outfile.equals("-"))
347:                            fileOut = System.out;
348:                        else
349:                            fileOut = new FileOutputStream(outfile);
350:                        fileOut = new BufferedOutputStream(fileOut);
351:                        JarOutputStream out = new JarOutputStream(fileOut);
352:                        junpack.unpack(in, out);
353:                        //in.close();  // p200 closes in but not out
354:                        out.close();
355:                        // At this point, we have a good jarfile (or newfile, if -r)
356:                    }
357:
358:                    if (!bakfile.equals("")) {
359:                        // On success, abort jarfile recovery bracket.
360:                        new File(bakfile).delete();
361:                        bakfile = "";
362:                    }
363:
364:                } finally {
365:                    // Close jarfile recovery bracket.
366:                    if (!bakfile.equals("")) {
367:                        File jarFile = new File(jarfile);
368:                        jarFile.delete(); // Win32 requires this, see above
369:                        new File(bakfile).renameTo(jarFile);
370:                    }
371:                    // In all cases, delete temporary *.pack.
372:                    if (!tmpfile.equals(""))
373:                        new File(tmpfile).delete();
374:                }
375:            }
376:
377:            static private File createTempFile(String basefile, String suffix)
378:                    throws IOException {
379:                File base = new File(basefile);
380:                String prefix = base.getName();
381:                if (prefix.length() < 3)
382:                    prefix += "tmp";
383:
384:                File where = base.getParentFile();
385:
386:                if (base.getParentFile() == null && suffix.equals(".bak"))
387:                    where = new File(".").getAbsoluteFile();
388:
389:                File f = File.createTempFile(prefix, suffix, where);
390:                return f;
391:            }
392:
393:            static private void printUsage(boolean doPack, boolean full,
394:                    PrintStream out) {
395:                String prog = doPack ? "pack200" : "unpack200";
396:                String[] packUsage = (String[]) RESOURCE
397:                        .getObject(DriverResource.PACK_HELP);
398:                String[] unpackUsage = (String[]) RESOURCE
399:                        .getObject(DriverResource.UNPACK_HELP);
400:                String[] usage = doPack ? packUsage : unpackUsage;
401:                for (int i = 0; i < usage.length; i++) {
402:                    out.println(usage[i]);
403:                    if (!full) {
404:                        out.println(MessageFormat.format(RESOURCE
405:                                .getString(DriverResource.MORE_INFO), prog));
406:                        break;
407:                    }
408:                }
409:            }
410:
411:            static private String getZipComment(String jarfile)
412:                    throws IOException {
413:                byte[] tail = new byte[1000];
414:                long filelen = new File(jarfile).length();
415:                if (filelen <= 0)
416:                    return "";
417:                long skiplen = Math.max(0, filelen - tail.length);
418:                InputStream in = new FileInputStream(new File(jarfile));
419:                try {
420:                    in.skip(skiplen);
421:                    in.read(tail);
422:                    for (int i = tail.length - 4; i >= 0; i--) {
423:                        if (tail[i + 0] == 'P' && tail[i + 1] == 'K'
424:                                && tail[i + 2] == 5 && tail[i + 3] == 6) {
425:                            // Skip sig4, disks4, entries4, clen4, coff4, cmt2
426:                            i += 4 + 4 + 4 + 4 + 4 + 2;
427:                            if (i < tail.length)
428:                                return new String(tail, i, tail.length - i,
429:                                        "UTF8");
430:                            return "";
431:                        }
432:                    }
433:                    return "";
434:                } finally {
435:                    in.close();
436:                }
437:            }
438:
439:            private static final String PACK200_OPTION_MAP = (""
440:                    + "--repack                 $ \n  -r +>- @--repack              $ \n"
441:                    + "--no-gzip                $ \n  -g +>- @--no-gzip             $ \n"
442:                    + "--strip-debug            $ \n  -G +>- @--strip-debug         $ \n"
443:                    + "--no-keep-file-order     $ \n  -O +>- @--no-keep-file-order  $ \n"
444:                    + "--segment-limit=      *> = \n  -S +>  @--segment-limit=      = \n"
445:                    + "--effort=             *> = \n  -E +>  @--effort=             = \n"
446:                    + "--deflate-hint=       *> = \n  -H +>  @--deflate-hint=       = \n"
447:                    + "--modification-time=  *> = \n  -m +>  @--modification-time=  = \n"
448:                    + "--pass-file=        *> &\0 \n  -P +>  @--pass-file=        &\0 \n"
449:                    + "--unknown-attribute=  *> = \n  -U +>  @--unknown-attribute=  = \n"
450:                    + "--class-attribute=  *> &\0 \n  -C +>  @--class-attribute=  &\0 \n"
451:                    + "--field-attribute=  *> &\0 \n  -F +>  @--field-attribute=  &\0 \n"
452:                    + "--method-attribute= *> &\0 \n  -M +>  @--method-attribute= &\0 \n"
453:                    + "--code-attribute=   *> &\0 \n  -D +>  @--code-attribute=   &\0 \n"
454:                    + "--config-file=      *>   . \n  -f +>  @--config-file=        . \n"
455:
456:                    // Negative options as required by CLIP:
457:                    + "--no-strip-debug  !--strip-debug         \n"
458:                    + "--gzip            !--no-gzip             \n"
459:                    + "--keep-file-order !--no-keep-file-order  \n"
460:
461:                    // Non-Standard Options
462:                    + "--verbose                $ \n  -v +>- @--verbose             $ \n"
463:                    + "--quiet        !--verbose  \n  -q +>- !--verbose               \n"
464:                    + "--log-file=           *> = \n  -l +>  @--log-file=           = \n"
465:                    //+"--java-option=      *> = \n  -J +>  @--java-option=        = \n"
466:                    + "--version                . \n  -V +>  @--version             . \n"
467:                    + "--help               . \n  -? +> @--help . \n  -h +> @--help . \n"
468:
469:                    // Termination:
470:                    + "--           . \n" // end option sequence here
471:                    + "-   +?    >- . \n" // report error if -XXX present; else use stdout
472:            );
473:            // Note: Collection options use "\0" as a delimiter between arguments.
474:
475:            // For Java version of unpacker (used for testing only):
476:            private static final String UNPACK200_OPTION_MAP = (""
477:                    + "--deflate-hint=       *> = \n  -H +>  @--deflate-hint=       = \n"
478:                    + "--verbose                $ \n  -v +>- @--verbose             $ \n"
479:                    + "--quiet        !--verbose  \n  -q +>- !--verbose               \n"
480:                    + "--remove-pack-file       $ \n  -r +>- @--remove-pack-file    $ \n"
481:                    + "--log-file=           *> = \n  -l +>  @--log-file=           = \n"
482:                    + "--config-file=        *> . \n  -f +>  @--config-file=        . \n"
483:
484:                    // Termination:
485:                    + "--           . \n" // end option sequence here
486:                    + "-   +?    >- . \n" // report error if -XXX present; else use stdin
487:                    + "--version                . \n  -V +>  @--version             . \n"
488:                    + "--help               . \n  -? +> @--help . \n  -h +> @--help . \n");
489:
490:            private static final String[] PACK200_PROPERTY_TO_OPTION = {
491:                    Pack200.Packer.SEGMENT_LIMIT, "--segment-limit=",
492:                    Pack200.Packer.KEEP_FILE_ORDER, "--no-keep-file-order",
493:                    Pack200.Packer.EFFORT, "--effort=",
494:                    Pack200.Packer.DEFLATE_HINT, "--deflate-hint=",
495:                    Pack200.Packer.MODIFICATION_TIME, "--modification-time=",
496:                    Pack200.Packer.PASS_FILE_PFX, "--pass-file=",
497:                    Pack200.Packer.UNKNOWN_ATTRIBUTE, "--unknown-attribute=",
498:                    Pack200.Packer.CLASS_ATTRIBUTE_PFX, "--class-attribute=",
499:                    Pack200.Packer.FIELD_ATTRIBUTE_PFX, "--field-attribute=",
500:                    Pack200.Packer.METHOD_ATTRIBUTE_PFX, "--method-attribute=",
501:                    Pack200.Packer.CODE_ATTRIBUTE_PFX, "--code-attribute=",
502:                    //Pack200.Packer.PROGRESS, "--progress=",
503:                    Utils.DEBUG_VERBOSE, "--verbose",
504:                    Utils.COM_PREFIX + "strip.debug", "--strip-debug", };
505:
506:            private static final String[] UNPACK200_PROPERTY_TO_OPTION = {
507:                    Pack200.Unpacker.DEFLATE_HINT, "--deflate-hint=",
508:                    //Pack200.Unpacker.PROGRESS, "--progress=",
509:                    Utils.DEBUG_VERBOSE, "--verbose",
510:                    Utils.UNPACK_REMOVE_PACKFILE, "--remove-pack-file", };
511:
512:            /*-*
513:             * Remove a set of command-line options from args,
514:             * storing them in the map in a canonicalized form.
515:             * <p>
516:             * The options string is a newline-separated series of
517:             * option processing specifiers.
518:             */
519:            private static String parseCommandOptions(List<String> args,
520:                    String options, Map<String, String> properties) {
521:                //System.out.println(args+" // "+properties);
522:
523:                String resultString = null;
524:
525:                // Convert options string into optLines dictionary.
526:                TreeMap<String, String[]> optmap = new TreeMap<String, String[]>();
527:                loadOptmap: for (String optline : options.split("\n")) {
528:                    String[] words = optline.split("\\p{Space}+");
529:                    if (words.length == 0)
530:                        continue loadOptmap;
531:                    String opt = words[0];
532:                    words[0] = ""; // initial word is not a spec
533:                    if (opt.length() == 0 && words.length >= 1) {
534:                        opt = words[1]; // initial "word" is empty due to leading ' '
535:                        words[1] = "";
536:                    }
537:                    if (opt.length() == 0)
538:                        continue loadOptmap;
539:                    String[] prevWords = optmap.put(opt, words);
540:                    if (prevWords != null)
541:                        throw new RuntimeException(
542:                                MessageFormat
543:                                        .format(
544:                                                RESOURCE
545:                                                        .getString(DriverResource.DUPLICATE_OPTION),
546:                                                optline.trim()));
547:                }
548:
549:                // State machine for parsing a command line.
550:                ListIterator<String> argp = args.listIterator();
551:                ListIterator<String> pbp = new ArrayList<String>()
552:                        .listIterator();
553:                doArgs: for (;;) {
554:                    // One trip through this loop per argument.
555:                    // Multiple trips per option only if several options per argument.
556:                    String arg;
557:                    if (pbp.hasPrevious()) {
558:                        arg = pbp.previous();
559:                        pbp.remove();
560:                    } else if (argp.hasNext()) {
561:                        arg = argp.next();
562:                    } else {
563:                        // No more arguments at all.
564:                        break doArgs;
565:                    }
566:                    tryOpt: for (int optlen = arg.length();; optlen--) {
567:                        // One time through this loop for each matching arg prefix.
568:                        String opt;
569:                        // Match some prefix of the argument to a key in optmap.
570:                        findOpt: for (;;) {
571:                            opt = arg.substring(0, optlen);
572:                            if (optmap.containsKey(opt))
573:                                break findOpt;
574:                            if (optlen == 0)
575:                                break tryOpt;
576:                            // Decide on a smaller prefix to search for.
577:                            SortedMap<String, String[]> pfxmap = optmap
578:                                    .headMap(opt);
579:                            // pfxmap.lastKey is no shorter than any prefix in optmap.
580:                            int len = pfxmap.isEmpty() ? 0 : pfxmap.lastKey()
581:                                    .length();
582:                            optlen = Math.min(len, optlen - 1);
583:                            opt = arg.substring(0, optlen);
584:                            // (Note:  We could cut opt down to its common prefix with
585:                            // pfxmap.lastKey, but that wouldn't save many cycles.)
586:                        }
587:                        opt = opt.intern();
588:                        assert (arg.startsWith(opt));
589:                        assert (opt.length() == optlen);
590:                        String val = arg.substring(optlen); // arg == opt+val
591:
592:                        // Execute the option processing specs for this opt.
593:                        // If no actions are taken, then look for a shorter prefix.
594:                        boolean didAction = false;
595:                        boolean isError = false;
596:
597:                        int pbpMark = pbp.nextIndex(); // in case of backtracking
598:                        String[] specs = optmap.get(opt);
599:                        eachSpec: for (String spec : specs) {
600:                            if (spec.length() == 0)
601:                                continue eachSpec;
602:                            if (spec.startsWith("#"))
603:                                break eachSpec;
604:                            int sidx = 0;
605:                            char specop = spec.charAt(sidx++);
606:
607:                            // Deal with '+'/'*' prefixes (spec conditions).
608:                            boolean ok;
609:                            switch (specop) {
610:                            case '+':
611:                                // + means we want an non-empty val suffix.
612:                                ok = (val.length() != 0);
613:                                specop = spec.charAt(sidx++);
614:                                break;
615:                            case '*':
616:                                // * means we accept empty or non-empty
617:                                ok = true;
618:                                specop = spec.charAt(sidx++);
619:                                break;
620:                            default:
621:                                // No condition prefix means we require an exact
622:                                // match, as indicated by an empty val suffix.
623:                                ok = (val.length() == 0);
624:                                break;
625:                            }
626:                            if (!ok)
627:                                continue eachSpec;
628:
629:                            String specarg = spec.substring(sidx);
630:                            switch (specop) {
631:                            case '.': // terminate the option sequence
632:                                resultString = (specarg.length() != 0) ? specarg
633:                                        .intern()
634:                                        : opt;
635:                                break doArgs;
636:                            case '?': // abort the option sequence
637:                                resultString = (specarg.length() != 0) ? specarg
638:                                        .intern()
639:                                        : arg;
640:                                isError = true;
641:                                break eachSpec;
642:                            case '@': // change the effective opt name
643:                                opt = specarg.intern();
644:                                break;
645:                            case '>': // shift remaining arg val to next arg
646:                                pbp.add(specarg + val); // push a new argument
647:                                val = "";
648:                                break;
649:                            case '!': // negation option
650:                                String negopt = (specarg.length() != 0) ? specarg
651:                                        .intern()
652:                                        : opt;
653:                                properties.remove(negopt);
654:                                properties.put(negopt, null); // leave placeholder
655:                                didAction = true;
656:                                break;
657:                            case '$': // normal "boolean" option
658:                                String boolval;
659:                                if (specarg.length() != 0) {
660:                                    // If there is a given spec token, store it.
661:                                    boolval = specarg;
662:                                } else {
663:                                    String old = properties.get(opt);
664:                                    if (old == null || old.length() == 0) {
665:                                        boolval = "1";
666:                                    } else {
667:                                        // Increment any previous value as a numeral.
668:                                        boolval = ""
669:                                                + (1 + Integer.parseInt(old));
670:                                    }
671:                                }
672:                                properties.put(opt, boolval);
673:                                didAction = true;
674:                                break;
675:                            case '=': // "string" option
676:                            case '&': // "collection" option
677:                                // Read an option.
678:                                boolean append = (specop == '&');
679:                                String strval;
680:                                if (pbp.hasPrevious()) {
681:                                    strval = pbp.previous();
682:                                    pbp.remove();
683:                                } else if (argp.hasNext()) {
684:                                    strval = argp.next();
685:                                } else {
686:                                    resultString = arg + " ?";
687:                                    isError = true;
688:                                    break eachSpec;
689:                                }
690:                                if (append) {
691:                                    String old = properties.get(opt);
692:                                    if (old != null) {
693:                                        // Append new val to old with embedded delim.
694:                                        String delim = specarg;
695:                                        if (delim.length() == 0)
696:                                            delim = " ";
697:                                        strval = old + specarg + strval;
698:                                    }
699:                                }
700:                                properties.put(opt, strval);
701:                                didAction = true;
702:                                break;
703:                            default:
704:                                throw new RuntimeException(
705:                                        MessageFormat
706:                                                .format(
707:                                                        RESOURCE
708:                                                                .getString(DriverResource.BAD_SPEC),
709:                                                        opt, spec));
710:                            }
711:                        }
712:
713:                        // Done processing specs.
714:                        if (didAction && !isError) {
715:                            continue doArgs;
716:                        }
717:
718:                        // The specs should have done something, but did not.
719:                        while (pbp.nextIndex() > pbpMark) {
720:                            // Remove anything pushed during these specs.
721:                            pbp.previous();
722:                            pbp.remove();
723:                        }
724:
725:                        if (isError) {
726:                            throw new IllegalArgumentException(resultString);
727:                        }
728:
729:                        if (optlen == 0) {
730:                            // We cannot try a shorter matching option.
731:                            break tryOpt;
732:                        }
733:                    }
734:
735:                    // If we come here, there was no matching option.
736:                    // So, push back the argument, and return to caller.
737:                    pbp.add(arg);
738:                    break doArgs;
739:                }
740:                // Report number of arguments consumed.
741:                args.subList(0, argp.nextIndex()).clear();
742:                // Report any unconsumed partial argument.
743:                while (pbp.hasPrevious())
744:                    args.add(0, pbp.previous());
745:                //System.out.println(args+" // "+properties+" -> "+resultString);
746:                return resultString;
747:            }
748:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.