KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > zip > ZipEntry


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.zip;
20
21 import java.util.Vector JavaDoc;
22 import java.util.zip.ZipException JavaDoc;
23
24 /**
25  * Extension that adds better handling of extra fields and provides
26  * access to the internal and external file attributes.
27  *
28  */

29 public class ZipEntry extends java.util.zip.ZipEntry JavaDoc implements Cloneable JavaDoc {
30
31     private static final int PLATFORM_UNIX = 3;
32     private static final int PLATFORM_FAT = 0;
33
34     private int internalAttributes = 0;
35     private int platform = PLATFORM_FAT;
36     private long externalAttributes = 0;
37     private Vector JavaDoc/*<ZipExtraField>*/ extraFields = null;
38     private String JavaDoc name = null;
39
40     /**
41      * Creates a new zip entry with the specified name.
42      * @param name the name of the entry
43      * @since 1.1
44      */

45     public ZipEntry(String JavaDoc name) {
46         super(name);
47     }
48
49     /**
50      * Creates a new zip entry with fields taken from the specified zip entry.
51      * @param entry the entry to get fields from
52      * @since 1.1
53      * @throws ZipException on error
54      */

55     public ZipEntry(java.util.zip.ZipEntry JavaDoc entry) throws ZipException JavaDoc {
56         super(entry);
57         byte[] extra = entry.getExtra();
58         if (extra != null) {
59             setExtraFields(ExtraFieldUtils.parse(extra));
60         } else {
61             // initializes extra data to an empty byte array
62
setExtra();
63         }
64     }
65
66     /**
67      * Creates a new zip entry with fields taken from the specified zip entry.
68      * @param entry the entry to get fields from
69      * @throws ZipException on error
70      * @since 1.1
71      */

72     public ZipEntry(ZipEntry entry) throws ZipException JavaDoc {
73         this((java.util.zip.ZipEntry JavaDoc) entry);
74         setInternalAttributes(entry.getInternalAttributes());
75         setExternalAttributes(entry.getExternalAttributes());
76         setExtraFields(entry.getExtraFields());
77     }
78
79     /**
80      * @since 1.9
81      */

82     protected ZipEntry() {
83         super("");
84     }
85
86     /**
87      * Overwrite clone.
88      * @return a cloned copy of this ZipEntry
89      * @since 1.1
90      */

91     public Object JavaDoc clone() {
92         ZipEntry e = (ZipEntry) super.clone();
93
94         e.extraFields = extraFields != null ? (Vector JavaDoc) extraFields.clone() : null;
95         e.setInternalAttributes(getInternalAttributes());
96         e.setExternalAttributes(getExternalAttributes());
97         e.setExtraFields(getExtraFields());
98         return e;
99     }
100
101     /**
102      * Retrieves the internal file attributes.
103      *
104      * @return the internal file attributes
105      * @since 1.1
106      */

107     public int getInternalAttributes() {
108         return internalAttributes;
109     }
110
111     /**
112      * Sets the internal file attributes.
113      * @param value an <code>int</code> value
114      * @since 1.1
115      */

116     public void setInternalAttributes(int value) {
117         internalAttributes = value;
118     }
119
120     /**
121      * Retrieves the external file attributes.
122      * @return the external file attributes
123      * @since 1.1
124      */

125     public long getExternalAttributes() {
126         return externalAttributes;
127     }
128
129     /**
130      * Sets the external file attributes.
131      * @param value an <code>long</code> value
132      * @since 1.1
133      */

134     public void setExternalAttributes(long value) {
135         externalAttributes = value;
136     }
137
138     /**
139      * Sets Unix permissions in a way that is understood by Info-Zip's
140      * unzip command.
141      * @param mode an <code>int</code> value
142      * @since Ant 1.5.2
143      */

144     public void setUnixMode(int mode) {
145         setExternalAttributes((mode << 16)
146                               // MS-DOS read-only attribute
147
| ((mode & 0200) == 0 ? 1 : 0)
148                               // MS-DOS directory flag
149
| (isDirectory() ? 0x10 : 0));
150         platform = PLATFORM_UNIX;
151     }
152
153     /**
154      * Unix permission.
155      * @return the unix permissions
156      * @since Ant 1.6
157      */

158     public int getUnixMode() {
159         return (int) ((getExternalAttributes() >> 16) & 0xFFFF);
160     }
161
162     /**
163      * Platform specification to put into the &quot;version made
164      * by&quot; part of the central file header.
165      *
166      * @return 0 (MS-DOS FAT) unless {@link #setUnixMode setUnixMode}
167      * has been called, in which case 3 (Unix) will be returned.
168      *
169      * @since Ant 1.5.2
170      */

171     public int getPlatform() {
172         return platform;
173     }
174
175     /**
176      * Set the platform (UNIX or FAT).
177      * @param platform an <code>int</code> value - 0 is FAT, 3 is UNIX
178      * @since 1.9
179      */

180     protected void setPlatform(int platform) {
181         this.platform = platform;
182     }
183
184     /**
185      * Replaces all currently attached extra fields with the new array.
186      * @param fields an array of extra fields
187      * @since 1.1
188      */

189     public void setExtraFields(ZipExtraField[] fields) {
190         extraFields = new Vector JavaDoc();
191         for (int i = 0; i < fields.length; i++) {
192             extraFields.addElement(fields[i]);
193         }
194         setExtra();
195     }
196
197     /**
198      * Retrieves extra fields.
199      * @return an array of the extra fields
200      * @since 1.1
201      */

202     public ZipExtraField[] getExtraFields() {
203         if (extraFields == null) {
204             return new ZipExtraField[0];
205         }
206         ZipExtraField[] result = new ZipExtraField[extraFields.size()];
207         extraFields.copyInto(result);
208         return result;
209     }
210
211     /**
212      * Adds an extra fields - replacing an already present extra field
213      * of the same type.
214      * @param ze an extra field
215      * @since 1.1
216      */

217     public void addExtraField(ZipExtraField ze) {
218         if (extraFields == null) {
219             extraFields = new Vector JavaDoc();
220         }
221         ZipShort type = ze.getHeaderId();
222         boolean done = false;
223         for (int i = 0, fieldsSize = extraFields.size(); !done && i < fieldsSize; i++) {
224             if (((ZipExtraField) extraFields.elementAt(i)).getHeaderId().equals(type)) {
225                 extraFields.setElementAt(ze, i);
226                 done = true;
227             }
228         }
229         if (!done) {
230             extraFields.addElement(ze);
231         }
232         setExtra();
233     }
234
235     /**
236      * Remove an extra fields.
237      * @param type the type of extra field to remove
238      * @since 1.1
239      */

240     public void removeExtraField(ZipShort type) {
241         if (extraFields == null) {
242             extraFields = new Vector JavaDoc();
243         }
244         boolean done = false;
245         for (int i = 0, fieldsSize = extraFields.size(); !done && i < fieldsSize; i++) {
246             if (((ZipExtraField) extraFields.elementAt(i)).getHeaderId().equals(type)) {
247                 extraFields.removeElementAt(i);
248                 done = true;
249             }
250         }
251         if (!done) {
252             throw new java.util.NoSuchElementException JavaDoc();
253         }
254         setExtra();
255     }
256
257     /**
258      * Throws an Exception if extra data cannot be parsed into extra fields.
259      * @param extra an array of bytes to be parsed into extra fields
260      * @throws RuntimeException if the bytes cannot be parsed
261      * @since 1.1
262      * @throws RuntimeException on error
263      */

264     public void setExtra(byte[] extra) throws RuntimeException JavaDoc {
265         try {
266             setExtraFields(ExtraFieldUtils.parse(extra));
267         } catch (Exception JavaDoc e) {
268             throw new RuntimeException JavaDoc(e.getMessage());
269         }
270     }
271
272     /**
273      * Unfortunately {@link java.util.zip.ZipOutputStream
274      * java.util.zip.ZipOutputStream} seems to access the extra data
275      * directly, so overriding getExtra doesn't help - we need to
276      * modify super's data directly.
277      *
278      * @since 1.1
279      */

280     protected void setExtra() {
281         super.setExtra(ExtraFieldUtils.mergeLocalFileDataData(getExtraFields()));
282     }
283
284     /**
285      * Retrieves the extra data for the local file data.
286      * @return the extra data for local file
287      * @since 1.1
288      */

289     public byte[] getLocalFileDataExtra() {
290         byte[] extra = getExtra();
291         return extra != null ? extra : new byte[0];
292     }
293
294     /**
295      * Retrieves the extra data for the central directory.
296      * @return the central directory extra data
297      * @since 1.1
298      */

299     public byte[] getCentralDirectoryExtra() {
300         return ExtraFieldUtils.mergeCentralDirectoryData(getExtraFields());
301     }
302
303     /**
304      * Make this class work in JDK 1.1 like a 1.2 class.
305      *
306      * <p>This either stores the size for later usage or invokes
307      * setCompressedSize via reflection.</p>
308      * @param size the size to use
309      * @deprecated since 1.7.
310      * Use setCompressedSize directly.
311      * @since 1.2
312      */

313     public void setComprSize(long size) {
314         setCompressedSize(size);
315     }
316
317     /**
318      * Get the name of the entry.
319      * @return the entry name
320      * @since 1.9
321      */

322     public String JavaDoc getName() {
323         return name == null ? super.getName() : name;
324     }
325
326     /**
327      * Is this entry a directory?
328      * @return true if the entry is a directory
329      * @since 1.10
330      */

331     public boolean isDirectory() {
332         return getName().endsWith("/");
333     }
334
335     /**
336      * Set the name of the entry.
337      * @param name the name to use
338      */

339     protected void setName(String JavaDoc name) {
340         this.name = name;
341     }
342
343     /**
344      * Get the hashCode of the entry.
345      * This uses the name as the hashcode.
346      * @return a hashcode.
347      * @since Ant 1.7
348      */

349     public int hashCode() {
350         // this method has severe consequences on performance. We cannot rely
351
// on the super.hashCode() method since super.getName() always return
352
// the empty string in the current implemention (there's no setter)
353
// so it is basically draining the performance of a hashmap lookup
354
return getName().hashCode();
355     }
356
357     /**
358      * The equality method. In this case, the implementation returns 'this == o'
359      * which is basically the equals method of the Object class.
360      * @param o the object to compare to
361      * @return true if this object is the same as <code>o</code>
362      * @since Ant 1.7
363      */

364     public boolean equals(Object JavaDoc o) {
365         return (this == o);
366     }
367
368 }
369
Popular Tags