Source Code Cross Referenced for Manifest.java in  » 6.0-JDK-Modules » j2me » java » util » jar » 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 » j2me » java.util.jar 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)Manifest.java	1.41 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
006:         *   
007:         * This program is free software; you can redistribute it and/or  
008:         * modify it under the terms of the GNU General Public License version  
009:         * 2 only, as published by the Free Software Foundation.   
010:         *   
011:         * This program is distributed in the hope that it will be useful, but  
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
014:         * General Public License version 2 for more details (a copy is  
015:         * included at /legal/license.txt).   
016:         *   
017:         * You should have received a copy of the GNU General Public License  
018:         * version 2 along with this work; if not, write to the Free Software  
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
020:         * 02110-1301 USA   
021:         *   
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package java.util.jar;
029:
030:        import java.io.FilterInputStream;
031:        import java.io.DataOutputStream;
032:        import java.io.InputStream;
033:        import java.io.OutputStream;
034:        import java.io.IOException;
035:        import java.util.Map;
036:        import java.util.HashMap;
037:        import java.util.Iterator;
038:
039:        /**
040:         * The Manifest class is used to maintain Manifest entry names and their
041:         * associated Attributes. There are main Manifest Attributes as well as
042:         * per-entry Attributes. For information on the Manifest format, please
043:         * see the 
044:         * <a href="../../../../guide/jar/jar.html">
045:         * Manifest format specification</a>.
046:         *
047:         * @author  David Connelly
048:         * @version 1.33, 05/03/00
049:         * @see	    Attributes
050:         * @since   1.2
051:         */
052:        public class Manifest implements  Cloneable {
053:            // manifest main attributes
054:            private Attributes attr = new Attributes();
055:
056:            // manifest entries
057:            private Map entries = new HashMap();
058:
059:            /**
060:             * Constructs a new, empty Manifest.
061:             */
062:            public Manifest() {
063:            }
064:
065:            /**
066:             * Constructs a new Manifest from the specified input stream.
067:             *
068:             * @param is the input stream containing manifest data
069:             * @throws IOException if an I/O error has occured
070:             */
071:            public Manifest(InputStream is) throws IOException {
072:                read(is);
073:            }
074:
075:            /**
076:             * Constructs a new Manifest that is a copy of the specified Manifest.
077:             *
078:             * @param man the Manifest to copy
079:             */
080:            public Manifest(Manifest man) {
081:                attr.putAll(man.getMainAttributes());
082:                entries.putAll(man.getEntries());
083:            }
084:
085:            /**
086:             * Returns the main Attributes for the Manifest.
087:             * @return the main Attributes for the Manifest
088:             */
089:            public Attributes getMainAttributes() {
090:                return attr;
091:            }
092:
093:            /**
094:             * Returns a Map of the entries contained in this Manifest. Each entry
095:             * is represented by a String name (key) and associated Attributes (value).
096:             *
097:             * @return a Map of the entries contained in this Manifest
098:             */
099:            public Map getEntries() {
100:                return entries;
101:            }
102:
103:            /**
104:             * Returns the Attributes for the specified entry name.
105:             * This method is defined as:
106:             * <pre>
107:             *	    return (Attributes)getEntries().get(name)
108:             * </pre>
109:             *
110:             * @param name entry name
111:             * @return the Attributes for the specified entry name
112:             */
113:            public Attributes getAttributes(String name) {
114:                return (Attributes) getEntries().get(name);
115:            }
116:
117:            /**
118:             * Clears the main Attributes as well as the entries in this Manifest.
119:             */
120:            public void clear() {
121:                attr.clear();
122:                entries.clear();
123:            }
124:
125:            /**
126:             * Writes the Manifest to the specified OutputStream. 
127:             * Attributes.Name.MANIFEST_VERSION must be set in 
128:             * MainAttributes prior to invoking this method.
129:             *
130:             * @param out the output stream
131:             * @exception IOException if an I/O error has occurred
132:             * @see #getMainAttributes
133:             */
134:            public void write(OutputStream out) throws IOException {
135:                DataOutputStream dos = new DataOutputStream(out);
136:                // Write out the main attributes for the manifest
137:                attr.writeMain(dos);
138:                // Now write out the pre-entry attributes
139:                Iterator it = entries.entrySet().iterator();
140:                while (it.hasNext()) {
141:                    Map.Entry e = (Map.Entry) it.next();
142:                    StringBuffer buffer = new StringBuffer("Name: ");
143:                    String value = (String) e.getKey();
144:                    if (value != null) {
145:                        byte[] vb = value.getBytes("UTF8");
146:                        value = new String(vb, 0, vb.length);
147:                    }
148:                    buffer.append(value);
149:                    buffer.append("\r\n");
150:                    make72Safe(buffer);
151:                    dos.writeBytes(buffer.toString());
152:                    ((Attributes) e.getValue()).write(dos);
153:                }
154:                dos.flush();
155:            }
156:
157:            /**
158:             * Adds line breaks to enforce a maximum 72 bytes per line.
159:             */
160:            static void make72Safe(StringBuffer line) {
161:                int length = line.length();
162:                if (length > 72) {
163:                    int index = 70;
164:                    while (index < length - 2) {
165:                        line.insert(index, "\r\n ");
166:                        index += 72;
167:                        length += 3;
168:                    }
169:                }
170:                return;
171:            }
172:
173:            /**
174:             * Reads the Manifest from the specified InputStream. The entry
175:             * names and attributes read will be merged in with the current
176:             * manifest entries.
177:             *
178:             * @param is the input stream
179:             * @exception IOException if an I/O error has occurred
180:             */
181:            public void read(InputStream is) throws IOException {
182:                // Buffered input stream for reading manifest data
183:                FastInputStream fis = new FastInputStream(is);
184:                // Line buffer
185:                byte[] lbuf = new byte[512];
186:                // Read the main attributes for the manifest
187:                attr.read(fis, lbuf);
188:                // Total number of entries, attributes read
189:                int ecount = 0, acount = 0;
190:                // Average size of entry attributes
191:                int asize = 2;
192:                // Now parse the manifest entries
193:                int len;
194:                String name = null;
195:                boolean skipEmptyLines = true;
196:                byte[] lastline = null;
197:
198:                while ((len = fis.readLine(lbuf)) != -1) {
199:                    if (lbuf[--len] != '\n') {
200:                        throw new IOException("manifest line too long");
201:                    }
202:                    if (len > 0 && lbuf[len - 1] == '\r') {
203:                        --len;
204:                    }
205:                    if (len == 0 && skipEmptyLines) {
206:                        continue;
207:                    }
208:                    skipEmptyLines = false;
209:
210:                    if (name == null) {
211:                        name = parseName(lbuf, len);
212:                        if (name == null) {
213:                            throw new IOException("invalid manifest format");
214:                        }
215:                        if (fis.peek() == ' ') {
216:                            // name is wrapped
217:                            lastline = new byte[len - 6];
218:                            System.arraycopy(lbuf, 6, lastline, 0, len - 6);
219:                            continue;
220:                        }
221:                    } else {
222:                        // continuation line
223:                        byte[] buf = new byte[lastline.length + len - 1];
224:                        System.arraycopy(lastline, 0, buf, 0, lastline.length);
225:                        System
226:                                .arraycopy(lbuf, 1, buf, lastline.length,
227:                                        len - 1);
228:                        if (fis.peek() == ' ') {
229:                            // name is wrapped
230:                            lastline = buf;
231:                            continue;
232:                        }
233:                        name = new String(buf, 0, buf.length, "UTF8");
234:                        lastline = null;
235:                    }
236:                    Attributes attr = getAttributes(name);
237:                    if (attr == null) {
238:                        attr = new Attributes(asize);
239:                        entries.put(name, attr);
240:                    }
241:                    attr.read(fis, lbuf);
242:                    ecount++;
243:                    acount += attr.size();
244:                    // Fix for when the average is 0. When it is 0, 
245:                    // you get an Attributes object with an initial
246:                    // capacity of 0, which tickles a bug in HashMap.
247:                    asize = Math.max(2, acount / ecount);
248:
249:                    name = null;
250:                    skipEmptyLines = true;
251:                }
252:            }
253:
254:            private String parseName(byte[] lbuf, int len) {
255:                if (toLower(lbuf[0]) == 'n' && toLower(lbuf[1]) == 'a'
256:                        && toLower(lbuf[2]) == 'm' && toLower(lbuf[3]) == 'e'
257:                        && lbuf[4] == ':' && lbuf[5] == ' ') {
258:                    try {
259:                        return new String(lbuf, 6, len - 6, "UTF8");
260:                    } catch (Exception e) {
261:                    }
262:                }
263:                return null;
264:            }
265:
266:            private int toLower(int c) {
267:                return (c >= 'A' && c <= 'Z') ? 'a' + (c - 'A') : c;
268:            }
269:
270:            /**
271:             * Returns true if the specified Object is also a Manifest and has
272:             * the same main Attributes and entries.
273:             *
274:             * @param o the object to be compared
275:             * @return true if the specified Object is also a Manifest and has
276:             * the same main Attributes and entries
277:             */
278:            public boolean equals(Object o) {
279:                if (o instanceof  Manifest) {
280:                    Manifest m = (Manifest) o;
281:                    return attr.equals(m.getMainAttributes())
282:                            && entries.equals(m.getEntries());
283:                } else {
284:                    return false;
285:                }
286:            }
287:
288:            /**
289:             * Returns the hash code for this Manifest.
290:             */
291:            public int hashCode() {
292:                return attr.hashCode() + entries.hashCode();
293:            }
294:
295:            /**
296:             * Returns a shallow copy of this Manifest.  The shallow copy is
297:             * implemented as follows:
298:             * <pre>
299:             *     public Object clone() { return new Manifest(this); }
300:             * </pre>
301:             * @return a shallow copy of this Manifest
302:             */
303:            public Object clone() {
304:                return new Manifest(this );
305:            }
306:
307:            /*
308:             * A fast buffered input stream for parsing manifest files.
309:             */
310:            static class FastInputStream extends FilterInputStream {
311:                private byte buf[];
312:                private int count = 0;
313:                private int pos = 0;
314:
315:                FastInputStream(InputStream in) {
316:                    this (in, 8192);
317:                }
318:
319:                FastInputStream(InputStream in, int size) {
320:                    super (in);
321:                    buf = new byte[size];
322:                }
323:
324:                public int read() throws IOException {
325:                    if (pos >= count) {
326:                        fill();
327:                        if (pos >= count) {
328:                            return -1;
329:                        }
330:                    }
331:                    return buf[pos++] & 0xff;
332:                }
333:
334:                public int read(byte[] b, int off, int len) throws IOException {
335:                    int avail = count - pos;
336:                    if (avail <= 0) {
337:                        if (len >= buf.length) {
338:                            return in.read(b, off, len);
339:                        }
340:                        fill();
341:                        avail = count - pos;
342:                        if (avail <= 0) {
343:                            return -1;
344:                        }
345:                    }
346:                    if (len > avail) {
347:                        len = avail;
348:                    }
349:                    System.arraycopy(buf, pos, b, off, len);
350:                    pos += len;
351:                    return len;
352:                }
353:
354:                /*
355:                 * Reads 'len' bytes from the input stream, or until an end-of-line
356:                 * is reached. Returns the number of bytes read.
357:                 */
358:                public int readLine(byte[] b, int off, int len)
359:                        throws IOException {
360:                    byte[] tbuf = this .buf;
361:                    int total = 0;
362:                    while (total < len) {
363:                        int avail = count - pos;
364:                        if (avail <= 0) {
365:                            fill();
366:                            avail = count - pos;
367:                            if (avail <= 0) {
368:                                return -1;
369:                            }
370:                        }
371:                        int n = len - total;
372:                        if (n > avail) {
373:                            n = avail;
374:                        }
375:                        int tpos = pos;
376:                        int maxpos = tpos + n;
377:                        while (tpos < maxpos && tbuf[tpos++] != '\n')
378:                            ;
379:                        n = tpos - pos;
380:                        System.arraycopy(tbuf, pos, b, off, n);
381:                        off += n;
382:                        total += n;
383:                        pos = tpos;
384:                        if (tbuf[tpos - 1] == '\n') {
385:                            break;
386:                        }
387:                    }
388:                    return total;
389:                }
390:
391:                public byte peek() throws IOException {
392:                    if (pos == count)
393:                        fill();
394:                    return buf[pos];
395:                }
396:
397:                public int readLine(byte[] b) throws IOException {
398:                    return readLine(b, 0, b.length);
399:                }
400:
401:                public long skip(long n) throws IOException {
402:                    if (n <= 0) {
403:                        return 0;
404:                    }
405:                    long avail = count - pos;
406:                    if (avail <= 0) {
407:                        return in.skip(n);
408:                    }
409:                    if (n > avail) {
410:                        n = avail;
411:                    }
412:                    pos += n;
413:                    return n;
414:                }
415:
416:                public int available() throws IOException {
417:                    return (count - pos) + in.available();
418:                }
419:
420:                public void close() throws IOException {
421:                    if (in != null) {
422:                        in.close();
423:                        in = null;
424:                        buf = null;
425:                    }
426:                }
427:
428:                private void fill() throws IOException {
429:                    count = pos = 0;
430:                    int n = in.read(buf, 0, buf.length);
431:                    if (n > 0) {
432:                        count = n;
433:                    }
434:                }
435:            }
436:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.