KickJava   Java API By Example, From Geeks To Geeks.

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


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.Hashtable JavaDoc;
22 import java.util.Vector JavaDoc;
23 import java.util.zip.ZipException JavaDoc;
24
25 /**
26  * ZipExtraField related methods
27  *
28  */

29 public class ExtraFieldUtils {
30
31     /**
32      * Static registry of known extra fields.
33      *
34      * @since 1.1
35      */

36     private static Hashtable JavaDoc implementations;
37
38     static {
39         implementations = new Hashtable JavaDoc();
40         register(AsiExtraField.class);
41         register(JarMarker.class);
42     }
43
44     /**
45      * Register a ZipExtraField implementation.
46      *
47      * <p>The given class must have a no-arg constructor and implement
48      * the {@link ZipExtraField ZipExtraField interface}.</p>
49      * @param c the class to register
50      *
51      * @since 1.1
52      */

53     public static void register(Class JavaDoc c) {
54         try {
55             ZipExtraField ze = (ZipExtraField) c.newInstance();
56             implementations.put(ze.getHeaderId(), c);
57         } catch (ClassCastException JavaDoc cc) {
58             throw new RuntimeException JavaDoc(c + " doesn\'t implement ZipExtraField");
59         } catch (InstantiationException JavaDoc ie) {
60             throw new RuntimeException JavaDoc(c + " is not a concrete class");
61         } catch (IllegalAccessException JavaDoc ie) {
62             throw new RuntimeException JavaDoc(c + "\'s no-arg constructor is not public");
63         }
64     }
65
66     /**
67      * Create an instance of the approriate ExtraField, falls back to
68      * {@link UnrecognizedExtraField UnrecognizedExtraField}.
69      * @param headerId the header identifier
70      * @return an instance of the appropiate ExtraField
71      * @exception InstantiationException if unable to instantiate the class
72      * @exception IllegalAccessException if not allowed to instatiate the class
73      * @since 1.1
74      */

75     public static ZipExtraField createExtraField(ZipShort headerId)
76         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
77         Class JavaDoc c = (Class JavaDoc) implementations.get(headerId);
78         if (c != null) {
79             return (ZipExtraField) c.newInstance();
80         }
81         UnrecognizedExtraField u = new UnrecognizedExtraField();
82         u.setHeaderId(headerId);
83         return u;
84     }
85
86     /**
87      * Split the array into ExtraFields and populate them with the
88      * give data.
89      * @param data an array of bytes
90      * @return an array of ExtraFields
91      * @since 1.1
92      * @throws ZipException on error
93      */

94     public static ZipExtraField[] parse(byte[] data) throws ZipException JavaDoc {
95         Vector JavaDoc v = new Vector JavaDoc();
96         int start = 0;
97         while (start <= data.length - 4) {
98             ZipShort headerId = new ZipShort(data, start);
99             int length = (new ZipShort(data, start + 2)).getValue();
100             if (start + 4 + length > data.length) {
101                 throw new ZipException JavaDoc("data starting at " + start
102                     + " is in unknown format");
103             }
104             try {
105                 ZipExtraField ze = createExtraField(headerId);
106                 ze.parseFromLocalFileData(data, start + 4, length);
107                 v.addElement(ze);
108             } catch (InstantiationException JavaDoc ie) {
109                 throw new ZipException JavaDoc(ie.getMessage());
110             } catch (IllegalAccessException JavaDoc iae) {
111                 throw new ZipException JavaDoc(iae.getMessage());
112             }
113             start += (length + 4);
114         }
115         if (start != data.length) { // array not exhausted
116
throw new ZipException JavaDoc("data starting at " + start
117                 + " is in unknown format");
118         }
119
120         ZipExtraField[] result = new ZipExtraField[v.size()];
121         v.copyInto(result);
122         return result;
123     }
124
125     /**
126      * Merges the local file data fields of the given ZipExtraFields.
127      * @param data an array of ExtraFiles
128      * @return an array of bytes
129      * @since 1.1
130      */

131     public static byte[] mergeLocalFileDataData(ZipExtraField[] data) {
132         int sum = 4 * data.length;
133         for (int i = 0; i < data.length; i++) {
134             sum += data[i].getLocalFileDataLength().getValue();
135         }
136         byte[] result = new byte[sum];
137         int start = 0;
138         for (int i = 0; i < data.length; i++) {
139             System.arraycopy(data[i].getHeaderId().getBytes(),
140                              0, result, start, 2);
141             System.arraycopy(data[i].getLocalFileDataLength().getBytes(),
142                              0, result, start + 2, 2);
143             byte[] local = data[i].getLocalFileDataData();
144             System.arraycopy(local, 0, result, start + 4, local.length);
145             start += (local.length + 4);
146         }
147         return result;
148     }
149
150     /**
151      * Merges the central directory fields of the given ZipExtraFields.
152      * @param data an array of ExtraFields
153      * @return an array of bytes
154      * @since 1.1
155      */

156     public static byte[] mergeCentralDirectoryData(ZipExtraField[] data) {
157         int sum = 4 * data.length;
158         for (int i = 0; i < data.length; i++) {
159             sum += data[i].getCentralDirectoryLength().getValue();
160         }
161         byte[] result = new byte[sum];
162         int start = 0;
163         for (int i = 0; i < data.length; i++) {
164             System.arraycopy(data[i].getHeaderId().getBytes(),
165                              0, result, start, 2);
166             System.arraycopy(data[i].getCentralDirectoryLength().getBytes(),
167                              0, result, start + 2, 2);
168             byte[] local = data[i].getCentralDirectoryData();
169             System.arraycopy(local, 0, result, start + 4, local.length);
170             start += (local.length + 4);
171         }
172         return result;
173     }
174 }
175
Popular Tags