1*cd519653SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*cd519653SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*cd519653SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*cd519653SAndrew Rist  * distributed with this work for additional information
6*cd519653SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*cd519653SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*cd519653SAndrew Rist  * "License"); you may not use this file except in compliance
9*cd519653SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*cd519653SAndrew Rist  *
11*cd519653SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*cd519653SAndrew Rist  *
13*cd519653SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*cd519653SAndrew Rist  * software distributed under the License is distributed on an
15*cd519653SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*cd519653SAndrew Rist  * KIND, either express or implied.  See the License for the
17*cd519653SAndrew Rist  * specific language governing permissions and limitations
18*cd519653SAndrew Rist  * under the License.
19*cd519653SAndrew Rist  *
20*cd519653SAndrew Rist  *************************************************************/
21*cd519653SAndrew Rist 
22*cd519653SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package org.openoffice.idesupport.zip;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import java.io.*;
27cdf0e10cSrcweir import java.util.Enumeration;
28cdf0e10cSrcweir import java.util.zip.*;
29cdf0e10cSrcweir import java.beans.PropertyVetoException;
30cdf0e10cSrcweir 
31cdf0e10cSrcweir import org.openoffice.idesupport.filter.FileFilter;
32cdf0e10cSrcweir import org.openoffice.idesupport.filter.BinaryOnlyFilter;
33cdf0e10cSrcweir import org.openoffice.idesupport.filter.ExceptParcelFilter;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir import com.sun.star.script.framework.container.ParcelDescriptor;
36cdf0e10cSrcweir import org.openoffice.idesupport.xml.Manifest;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir public class ParcelZipper
39cdf0e10cSrcweir {
40cdf0e10cSrcweir     public static final String PARCEL_PREFIX_DIR = "Scripts/";
41cdf0e10cSrcweir     public static final String PARCEL_EXTENSION = "sxp";
42cdf0e10cSrcweir     public static final String CONTENTS_DIRNAME = "Contents";
43cdf0e10cSrcweir     public static final String PARCEL_DESCRIPTOR_XML = "parcel-descriptor.xml";
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     private static ParcelZipper zipper = null;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir     private static final FileFilter DEFAULT_FILTER =
48cdf0e10cSrcweir         BinaryOnlyFilter.getInstance();
49cdf0e10cSrcweir 
ParcelZipper()50cdf0e10cSrcweir     private ParcelZipper() {
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir 
getParcelZipper()53cdf0e10cSrcweir     public static ParcelZipper getParcelZipper() {
54cdf0e10cSrcweir         if (zipper == null) {
55cdf0e10cSrcweir             synchronized(ParcelZipper.class) {
56cdf0e10cSrcweir                 if (zipper == null)
57cdf0e10cSrcweir                     zipper = new ParcelZipper();
58cdf0e10cSrcweir             }
59cdf0e10cSrcweir         }
60cdf0e10cSrcweir         return zipper;
61cdf0e10cSrcweir     }
62cdf0e10cSrcweir 
zipParcel(File basedir)63cdf0e10cSrcweir     public String zipParcel(File basedir) throws IOException {
64cdf0e10cSrcweir         File targetfile, targetdir;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir         if (basedir.getName().equals(CONTENTS_DIRNAME))
67cdf0e10cSrcweir             targetdir = basedir.getParentFile();
68cdf0e10cSrcweir         else
69cdf0e10cSrcweir             targetdir = basedir;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir         targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION);
72cdf0e10cSrcweir 
73cdf0e10cSrcweir         return zipParcel(basedir, targetfile, DEFAULT_FILTER);
74cdf0e10cSrcweir     }
75cdf0e10cSrcweir 
zipParcel(File basedir, File targetfile)76cdf0e10cSrcweir     public String zipParcel(File basedir, File targetfile) throws IOException {
77cdf0e10cSrcweir         return zipParcel(basedir, targetfile, DEFAULT_FILTER);
78cdf0e10cSrcweir     }
79cdf0e10cSrcweir 
zipParcel(File basedir, FileFilter filter)80cdf0e10cSrcweir     public String zipParcel(File basedir, FileFilter filter) throws IOException {
81cdf0e10cSrcweir         File targetfile, targetdir;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir         if (basedir.getName().equals(CONTENTS_DIRNAME))
84cdf0e10cSrcweir             targetdir = basedir.getParentFile();
85cdf0e10cSrcweir         else
86cdf0e10cSrcweir             targetdir = basedir;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir         targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION);
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         return zipParcel(basedir, targetfile, filter);
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir 
zipParcel(File basedir, File targetfile, FileFilter filter)93cdf0e10cSrcweir     public String zipParcel(File basedir, File targetfile, FileFilter filter)
94cdf0e10cSrcweir         throws IOException {
95cdf0e10cSrcweir         String realpath, tmppath;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir         realpath = targetfile.getPath();
98cdf0e10cSrcweir         tmppath = realpath + ".tmp";
99cdf0e10cSrcweir 
100cdf0e10cSrcweir         File tmpfile = new File(tmppath);
101cdf0e10cSrcweir         ZipOutputStream out = null;
102cdf0e10cSrcweir         try {
103cdf0e10cSrcweir             if (tmpfile.exists() == true)
104cdf0e10cSrcweir                 tmpfile.delete();
105cdf0e10cSrcweir 
106cdf0e10cSrcweir             out = new ZipOutputStream(new FileOutputStream(tmpfile));
107cdf0e10cSrcweir 
108cdf0e10cSrcweir             File[] children = basedir.listFiles();
109cdf0e10cSrcweir             for (int i = 0; i < children.length; i++)
110cdf0e10cSrcweir                 addFileToParcel(children[i], "", out, filter);
111cdf0e10cSrcweir         }
112cdf0e10cSrcweir         catch (IOException ioe) {
113cdf0e10cSrcweir             out.close();
114cdf0e10cSrcweir             tmpfile.delete();
115cdf0e10cSrcweir             throw ioe;
116cdf0e10cSrcweir         }
117cdf0e10cSrcweir         finally {
118cdf0e10cSrcweir             if (out != null)
119cdf0e10cSrcweir                 out.close();
120cdf0e10cSrcweir         }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir         if (targetfile.exists() == true)
123cdf0e10cSrcweir             targetfile.delete();
124cdf0e10cSrcweir         tmpfile.renameTo(targetfile);
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         return targetfile.getAbsolutePath();
127cdf0e10cSrcweir     }
128cdf0e10cSrcweir 
addFileToParcel(File root, String path, ZipOutputStream out, FileFilter filter)129cdf0e10cSrcweir     private void addFileToParcel(File root, String path, ZipOutputStream out, FileFilter filter)
130cdf0e10cSrcweir         throws IOException {
131cdf0e10cSrcweir         ZipEntry ze;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         if (root.isDirectory() == true) {
134cdf0e10cSrcweir             ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName() + "/");
135cdf0e10cSrcweir             out.putNextEntry(ze);
136cdf0e10cSrcweir             out.closeEntry();
137cdf0e10cSrcweir             File[] children = root.listFiles();
138cdf0e10cSrcweir 
139cdf0e10cSrcweir             for (int i = 0; i < children.length; i++)
140cdf0e10cSrcweir                 addFileToParcel(children[i], path + root.getName() + "/", out, filter);
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir         else {
143cdf0e10cSrcweir             if (filter.validate(root.getName()) == false &&
144cdf0e10cSrcweir                 root.getName().equals("parcel-descriptor.xml") == false)
145cdf0e10cSrcweir                 return;
146cdf0e10cSrcweir 
147cdf0e10cSrcweir             ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName());
148cdf0e10cSrcweir             out.putNextEntry(ze);
149cdf0e10cSrcweir 
150cdf0e10cSrcweir             byte[] bytes = new byte[1024];
151cdf0e10cSrcweir             int len;
152cdf0e10cSrcweir 
153cdf0e10cSrcweir             FileInputStream fis = null;
154cdf0e10cSrcweir             try {
155cdf0e10cSrcweir                 fis = new FileInputStream(root);
156cdf0e10cSrcweir 
157cdf0e10cSrcweir                 while ((len = fis.read(bytes)) != -1)
158cdf0e10cSrcweir                     out.write(bytes, 0, len);
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir             finally {
161cdf0e10cSrcweir                 if (fis != null) fis.close();
162cdf0e10cSrcweir             }
163cdf0e10cSrcweir             out.closeEntry();
164cdf0e10cSrcweir         }
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir 
isOverwriteNeeded(File parcel, File target)167cdf0e10cSrcweir     public boolean isOverwriteNeeded(File parcel, File target)
168cdf0e10cSrcweir         throws IOException
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         boolean result;
171cdf0e10cSrcweir 
172cdf0e10cSrcweir         if (target.isDirectory())
173cdf0e10cSrcweir             result = isDirectoryOverwriteNeeded(parcel, target);
174cdf0e10cSrcweir         else
175cdf0e10cSrcweir             result = isDocumentOverwriteNeeded(parcel, target);
176cdf0e10cSrcweir 
177cdf0e10cSrcweir         return result;
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir 
isDirectoryOverwriteNeeded(File parcel, File target)180cdf0e10cSrcweir     private boolean isDirectoryOverwriteNeeded(File parcel, File target) {
181cdf0e10cSrcweir         String parcelDir = getParcelDirFromParcelZip(parcel.getName());
182cdf0e10cSrcweir 
183cdf0e10cSrcweir         File langdir;
184cdf0e10cSrcweir         try {
185cdf0e10cSrcweir             langdir = new File(target, getParcelLanguage(parcel));
186cdf0e10cSrcweir         }
187cdf0e10cSrcweir         catch (IOException ioe) {
188cdf0e10cSrcweir             return false;
189cdf0e10cSrcweir         }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir         if (langdir.exists() == false)
192cdf0e10cSrcweir             return false;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir         File[] children = langdir.listFiles();
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         for (int i = 0; i < children.length; i++)
197cdf0e10cSrcweir             if (children[i].getName().equals(parcelDir))
198cdf0e10cSrcweir                 return true;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir         return false;
201cdf0e10cSrcweir     }
202cdf0e10cSrcweir 
isDocumentOverwriteNeeded(File parcel, File document)203cdf0e10cSrcweir     private boolean isDocumentOverwriteNeeded(File parcel, File document)
204cdf0e10cSrcweir         throws IOException
205cdf0e10cSrcweir     {
206cdf0e10cSrcweir         ZipFile documentZip = null;
207cdf0e10cSrcweir         boolean result = false;
208cdf0e10cSrcweir 
209cdf0e10cSrcweir         try {
210cdf0e10cSrcweir             documentZip = new ZipFile(document);
211cdf0e10cSrcweir 
212cdf0e10cSrcweir             String name =
213cdf0e10cSrcweir                 PARCEL_PREFIX_DIR + getParcelLanguage(parcel) +
214cdf0e10cSrcweir                     "/" + getParcelDirFromParcelZip(parcel.getName()) +
215cdf0e10cSrcweir                     "/" + PARCEL_DESCRIPTOR_XML;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir             if (documentZip.getEntry(name) != null)
218cdf0e10cSrcweir                 result = true;
219cdf0e10cSrcweir         }
220cdf0e10cSrcweir         catch (IOException ioe) {
221cdf0e10cSrcweir             return false;
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir         finally {
224cdf0e10cSrcweir             if (documentZip != null) documentZip.close();
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         return result;
228cdf0e10cSrcweir     }
229cdf0e10cSrcweir 
deployParcel(File parcel, File target)230cdf0e10cSrcweir     public String deployParcel(File parcel, File target)
231cdf0e10cSrcweir         throws IOException {
232cdf0e10cSrcweir 
233cdf0e10cSrcweir         String output = null;
234cdf0e10cSrcweir         if (target.isDirectory())
235cdf0e10cSrcweir             output = unzipToDirectory(parcel, target);
236cdf0e10cSrcweir         else
237cdf0e10cSrcweir             output = unzipToZip(parcel, target);
238cdf0e10cSrcweir         return output;
239cdf0e10cSrcweir     }
240cdf0e10cSrcweir 
getParcelDirFromParcelZip(String zipname)241cdf0e10cSrcweir     private String getParcelDirFromParcelZip(String zipname) {
242cdf0e10cSrcweir         String result = zipname.substring(0, zipname.lastIndexOf("."));
243cdf0e10cSrcweir         return result;
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir 
unzipToDirectory(File parcel, File targetDirectory)246cdf0e10cSrcweir     private String unzipToDirectory(File parcel, File targetDirectory)
247cdf0e10cSrcweir         throws IOException {
248cdf0e10cSrcweir 
249cdf0e10cSrcweir         ZipInputStream in = null;
250cdf0e10cSrcweir         File parcelDir = new File(targetDirectory,
251cdf0e10cSrcweir             getParcelLanguage(parcel) + File.separator +
252cdf0e10cSrcweir             getParcelDirFromParcelZip(parcel.getName()));
253cdf0e10cSrcweir 
254cdf0e10cSrcweir         if (isDirectoryOverwriteNeeded(parcel, targetDirectory)) {
255cdf0e10cSrcweir             if (deleteDir(parcelDir) == false) {
256cdf0e10cSrcweir                 throw new IOException("Could not overwrite: " +
257cdf0e10cSrcweir                     parcelDir.getAbsolutePath());
258cdf0e10cSrcweir             }
259cdf0e10cSrcweir         }
260cdf0e10cSrcweir 
261cdf0e10cSrcweir         try {
262cdf0e10cSrcweir             in = new ZipInputStream(new FileInputStream(parcel));
263cdf0e10cSrcweir 
264cdf0e10cSrcweir             File outFile;
265cdf0e10cSrcweir             ZipEntry inEntry = in.getNextEntry();
266cdf0e10cSrcweir             byte[] bytes = new byte[1024];
267cdf0e10cSrcweir             int len;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir             while (inEntry != null) {
270cdf0e10cSrcweir                 outFile = new File(parcelDir, inEntry.getName());
271cdf0e10cSrcweir                 if (inEntry.isDirectory()) {
272cdf0e10cSrcweir                     outFile.mkdir();
273cdf0e10cSrcweir                 }
274cdf0e10cSrcweir                 else {
275cdf0e10cSrcweir                     if (outFile.getParentFile().exists() != true)
276cdf0e10cSrcweir                         outFile.getParentFile().mkdirs();
277cdf0e10cSrcweir 
278cdf0e10cSrcweir                     FileOutputStream out = null;
279cdf0e10cSrcweir                     try {
280cdf0e10cSrcweir                         out = new FileOutputStream(outFile);
281cdf0e10cSrcweir 
282cdf0e10cSrcweir                         while ((len = in.read(bytes)) != -1)
283cdf0e10cSrcweir                             out.write(bytes, 0, len);
284cdf0e10cSrcweir                     }
285cdf0e10cSrcweir                     finally {
286cdf0e10cSrcweir                         if (out != null) out.close();
287cdf0e10cSrcweir                     }
288cdf0e10cSrcweir                 }
289cdf0e10cSrcweir                 inEntry = in.getNextEntry();
290cdf0e10cSrcweir             }
291cdf0e10cSrcweir         }
292cdf0e10cSrcweir         finally {
293cdf0e10cSrcweir             if (in != null) in.close();
294cdf0e10cSrcweir         }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir         return parcelDir.getAbsolutePath();
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir 
deleteDir(File basedir)299cdf0e10cSrcweir     private boolean deleteDir(File basedir) {
300cdf0e10cSrcweir         if (basedir.isDirectory()) {
301cdf0e10cSrcweir             String[] children = basedir.list();
302cdf0e10cSrcweir             for (int i=0; i<children.length; i++) {
303cdf0e10cSrcweir                 boolean success = deleteDir(new File(basedir, children[i]));
304cdf0e10cSrcweir                 if (!success) {
305cdf0e10cSrcweir                     return false;
306cdf0e10cSrcweir                 }
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir         }
309cdf0e10cSrcweir         return basedir.delete();
310cdf0e10cSrcweir     }
311cdf0e10cSrcweir 
unzipToZip(File parcel, File targetDocument)312cdf0e10cSrcweir     private String unzipToZip(File parcel, File targetDocument)
313cdf0e10cSrcweir         throws IOException {
314cdf0e10cSrcweir 
315cdf0e10cSrcweir         ZipInputStream documentStream = null;
316cdf0e10cSrcweir         ZipInputStream parcelStream = null;
317cdf0e10cSrcweir         ZipOutputStream outStream = null;
318cdf0e10cSrcweir         Manifest manifest;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir         String language = getParcelLanguage(parcel);
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         if (isDocumentOverwriteNeeded(parcel, targetDocument)) {
323cdf0e10cSrcweir             String parcelName = language + "/" +
324cdf0e10cSrcweir                 getParcelDirFromParcelZip(parcel.getName());
325cdf0e10cSrcweir             removeParcel(targetDocument, parcelName);
326cdf0e10cSrcweir         }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         // first write contents of document to tmpfile
329cdf0e10cSrcweir         File tmpfile = new File(targetDocument.getAbsolutePath() + ".tmp");
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         manifest = addParcelToManifest(targetDocument, parcel);
332cdf0e10cSrcweir 
333cdf0e10cSrcweir         try {
334cdf0e10cSrcweir             documentStream =
335cdf0e10cSrcweir                 new ZipInputStream(new FileInputStream(targetDocument));
336cdf0e10cSrcweir             parcelStream = new ZipInputStream(new FileInputStream(parcel));
337cdf0e10cSrcweir             outStream = new ZipOutputStream(new FileOutputStream(tmpfile));
338cdf0e10cSrcweir 
339cdf0e10cSrcweir             copyParcelToZip(parcelStream, outStream, PARCEL_PREFIX_DIR +
340cdf0e10cSrcweir                 language + "/" + getParcelDirFromParcelZip(parcel.getName()));
341cdf0e10cSrcweir             copyDocumentToZip(documentStream, outStream, manifest);
342cdf0e10cSrcweir         }
343cdf0e10cSrcweir         catch (IOException ioe) {
344cdf0e10cSrcweir             tmpfile.delete();
345cdf0e10cSrcweir             throw ioe;
346cdf0e10cSrcweir         }
347cdf0e10cSrcweir         finally {
348cdf0e10cSrcweir             if (documentStream != null) documentStream.close();
349cdf0e10cSrcweir             if (parcelStream != null) parcelStream.close();
350cdf0e10cSrcweir             if (outStream != null) outStream.close();
351cdf0e10cSrcweir         }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         if (targetDocument.delete() == false) {
354cdf0e10cSrcweir             tmpfile.delete();
355cdf0e10cSrcweir             throw new IOException("Could not overwrite " + targetDocument);
356cdf0e10cSrcweir         }
357cdf0e10cSrcweir         else
358cdf0e10cSrcweir             tmpfile.renameTo(targetDocument);
359cdf0e10cSrcweir 
360cdf0e10cSrcweir         return targetDocument.getAbsolutePath();
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir 
copyParcelToZip(ZipInputStream in, ZipOutputStream out, String parcelName)363cdf0e10cSrcweir     private void copyParcelToZip(ZipInputStream in, ZipOutputStream out,
364cdf0e10cSrcweir         String parcelName) throws IOException {
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         ZipEntry outEntry;
367cdf0e10cSrcweir         ZipEntry inEntry = in.getNextEntry();
368cdf0e10cSrcweir         byte[] bytes = new byte[1024];
369cdf0e10cSrcweir         int len;
370cdf0e10cSrcweir 
371cdf0e10cSrcweir         while (inEntry != null) {
372cdf0e10cSrcweir             if(parcelName!=null)
373cdf0e10cSrcweir                 outEntry = new ZipEntry(parcelName + "/" + inEntry.getName());
374cdf0e10cSrcweir             else
375cdf0e10cSrcweir                 outEntry = new ZipEntry(inEntry);
376cdf0e10cSrcweir             out.putNextEntry(outEntry);
377cdf0e10cSrcweir 
378cdf0e10cSrcweir             if (inEntry.isDirectory() == false)
379cdf0e10cSrcweir                 while ((len = in.read(bytes)) != -1)
380cdf0e10cSrcweir                     out.write(bytes, 0, len);
381cdf0e10cSrcweir 
382cdf0e10cSrcweir             out.closeEntry();
383cdf0e10cSrcweir             inEntry = in.getNextEntry();
384cdf0e10cSrcweir         }
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
copyDocumentToZip(ZipInputStream in, ZipOutputStream out, Manifest manifest)387cdf0e10cSrcweir     private void copyDocumentToZip(ZipInputStream in, ZipOutputStream out,
388cdf0e10cSrcweir         Manifest manifest) throws IOException {
389cdf0e10cSrcweir 
390cdf0e10cSrcweir         ZipEntry outEntry;
391cdf0e10cSrcweir         ZipEntry inEntry;
392cdf0e10cSrcweir         byte[] bytes = new byte[1024];
393cdf0e10cSrcweir         int len;
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         while ((inEntry = in.getNextEntry()) != null) {
396cdf0e10cSrcweir 
397cdf0e10cSrcweir             outEntry = new ZipEntry(inEntry);
398cdf0e10cSrcweir             out.putNextEntry(outEntry);
399cdf0e10cSrcweir 
400cdf0e10cSrcweir             if(inEntry.getName().equals("META-INF/manifest.xml") &&
401cdf0e10cSrcweir                manifest != null) {
402cdf0e10cSrcweir                 InputStream manifestStream = null;
403cdf0e10cSrcweir                 try {
404cdf0e10cSrcweir                     manifestStream = manifest.getInputStream();
405cdf0e10cSrcweir                     while ((len = manifestStream.read(bytes)) != -1)
406cdf0e10cSrcweir                         out.write(bytes, 0, len);
407cdf0e10cSrcweir                 }
408cdf0e10cSrcweir                 finally {
409cdf0e10cSrcweir                     if (manifestStream != null)
410cdf0e10cSrcweir                         manifestStream.close();
411cdf0e10cSrcweir                 }
412cdf0e10cSrcweir             }
413cdf0e10cSrcweir             else if (inEntry.isDirectory() == false) {
414cdf0e10cSrcweir                 while ((len = in.read(bytes)) != -1)
415cdf0e10cSrcweir                     out.write(bytes, 0, len);
416cdf0e10cSrcweir             }
417cdf0e10cSrcweir 
418cdf0e10cSrcweir             out.closeEntry();
419cdf0e10cSrcweir         }
420cdf0e10cSrcweir     }
421cdf0e10cSrcweir 
removeParcel(File document, String parcelName)422cdf0e10cSrcweir     public String removeParcel(File document, String parcelName)
423cdf0e10cSrcweir         throws IOException {
424cdf0e10cSrcweir 
425cdf0e10cSrcweir         ZipInputStream documentStream = null;
426cdf0e10cSrcweir         ZipOutputStream outStream = null;
427cdf0e10cSrcweir         Manifest manifest = null;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir         if (!parcelName.startsWith(PARCEL_PREFIX_DIR))
430cdf0e10cSrcweir             parcelName = PARCEL_PREFIX_DIR + parcelName;
431cdf0e10cSrcweir         manifest = removeParcelFromManifest(document, parcelName);
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         // first write contents of document to tmpfile
434cdf0e10cSrcweir         File tmpfile = new File(document.getAbsolutePath() + ".tmp");
435cdf0e10cSrcweir 
436cdf0e10cSrcweir         try {
437cdf0e10cSrcweir             ZipEntry outEntry;
438cdf0e10cSrcweir             ZipEntry inEntry;
439cdf0e10cSrcweir             byte[] bytes = new byte[1024];
440cdf0e10cSrcweir             int len;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir             documentStream = new ZipInputStream(new FileInputStream(document));
443cdf0e10cSrcweir             outStream = new ZipOutputStream(new FileOutputStream(tmpfile));
444cdf0e10cSrcweir 
445cdf0e10cSrcweir             while ((inEntry = documentStream.getNextEntry()) != null) {
446cdf0e10cSrcweir 
447cdf0e10cSrcweir                 if(inEntry.getName().startsWith(parcelName))
448cdf0e10cSrcweir                     continue;
449cdf0e10cSrcweir 
450cdf0e10cSrcweir                 outEntry = new ZipEntry(inEntry);
451cdf0e10cSrcweir                 outStream.putNextEntry(outEntry);
452cdf0e10cSrcweir 
453cdf0e10cSrcweir                 if(inEntry.getName().equals("META-INF/manifest.xml") &&
454cdf0e10cSrcweir                    manifest != null) {
455cdf0e10cSrcweir                     InputStream manifestStream = null;
456cdf0e10cSrcweir                     try {
457cdf0e10cSrcweir                         manifestStream = manifest.getInputStream();
458cdf0e10cSrcweir                         while ((len = manifestStream.read(bytes)) != -1)
459cdf0e10cSrcweir                             outStream.write(bytes, 0, len);
460cdf0e10cSrcweir                     }
461cdf0e10cSrcweir                     finally {
462cdf0e10cSrcweir                         if (manifestStream != null)
463cdf0e10cSrcweir                             manifestStream.close();
464cdf0e10cSrcweir                     }
465cdf0e10cSrcweir                 }
466cdf0e10cSrcweir                 else if (inEntry.isDirectory() == false) {
467cdf0e10cSrcweir                     while ((len = documentStream.read(bytes)) != -1)
468cdf0e10cSrcweir                         outStream.write(bytes, 0, len);
469cdf0e10cSrcweir                 }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir                 outStream.closeEntry();
472cdf0e10cSrcweir             }
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir         catch (IOException ioe) {
475cdf0e10cSrcweir             tmpfile.delete();
476cdf0e10cSrcweir             throw ioe;
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir         finally {
479cdf0e10cSrcweir             if (documentStream != null)
480cdf0e10cSrcweir                 documentStream.close();
481cdf0e10cSrcweir 
482cdf0e10cSrcweir             if (outStream != null)
483cdf0e10cSrcweir                 outStream.close();
484cdf0e10cSrcweir         }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         if (document.delete() == false) {
487cdf0e10cSrcweir             tmpfile.delete();
488cdf0e10cSrcweir             throw new IOException("Could not overwrite " + document);
489cdf0e10cSrcweir         }
490cdf0e10cSrcweir         else
491cdf0e10cSrcweir             tmpfile.renameTo(document);
492cdf0e10cSrcweir 
493cdf0e10cSrcweir         return document.getAbsolutePath();
494cdf0e10cSrcweir     }
495cdf0e10cSrcweir 
getManifestFromDocument(File document)496cdf0e10cSrcweir     private Manifest getManifestFromDocument(File document) {
497cdf0e10cSrcweir         ZipFile documentZip = null;
498cdf0e10cSrcweir         Manifest result = null;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir         try {
501cdf0e10cSrcweir             documentZip = new ZipFile(document);
502cdf0e10cSrcweir             ZipEntry original = documentZip.getEntry("META-INF/manifest.xml");
503cdf0e10cSrcweir             if (original != null) {
504cdf0e10cSrcweir                 result = new Manifest(documentZip.getInputStream(original));
505cdf0e10cSrcweir             }
506cdf0e10cSrcweir         }
507cdf0e10cSrcweir         catch (IOException ioe) {
508cdf0e10cSrcweir             result = null;
509cdf0e10cSrcweir         }
510cdf0e10cSrcweir         finally {
511cdf0e10cSrcweir             try {
512cdf0e10cSrcweir                 if (documentZip != null)
513cdf0e10cSrcweir                     documentZip.close();
514cdf0e10cSrcweir             }
515cdf0e10cSrcweir             catch (IOException ioe) {}
516cdf0e10cSrcweir         }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir         return result;
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir 
addParcelToManifest(File document, File parcel)521cdf0e10cSrcweir     private Manifest addParcelToManifest(File document, File parcel)
522cdf0e10cSrcweir         throws IOException {
523cdf0e10cSrcweir 
524cdf0e10cSrcweir         ZipFile parcelZip = null;
525cdf0e10cSrcweir         Manifest result = null;
526cdf0e10cSrcweir 
527cdf0e10cSrcweir         result = getManifestFromDocument(document);
528cdf0e10cSrcweir         if (result == null)
529cdf0e10cSrcweir             return null;
530cdf0e10cSrcweir 
531cdf0e10cSrcweir         String language = getParcelLanguage(parcel);
532cdf0e10cSrcweir 
533cdf0e10cSrcweir         try {
534cdf0e10cSrcweir             parcelZip = new ZipFile(parcel);
535cdf0e10cSrcweir 
536cdf0e10cSrcweir             String prefix = PARCEL_PREFIX_DIR + language + "/" +
537cdf0e10cSrcweir                 getParcelDirFromParcelZip(parcel.getName()) + "/";
538cdf0e10cSrcweir 
539cdf0e10cSrcweir             Enumeration entries = parcelZip.entries();
540cdf0e10cSrcweir             while (entries.hasMoreElements()) {
541cdf0e10cSrcweir                 ZipEntry entry = (ZipEntry)entries.nextElement();
542cdf0e10cSrcweir                 result.add(prefix + entry.getName());
543cdf0e10cSrcweir             }
544cdf0e10cSrcweir         }
545cdf0e10cSrcweir         catch (IOException ioe) {
546cdf0e10cSrcweir             return null;
547cdf0e10cSrcweir         }
548cdf0e10cSrcweir         finally {
549cdf0e10cSrcweir             try {
550cdf0e10cSrcweir                 if (parcelZip != null)
551cdf0e10cSrcweir                     parcelZip.close();
552cdf0e10cSrcweir             }
553cdf0e10cSrcweir             catch (IOException ioe) {}
554cdf0e10cSrcweir         }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir         return result;
557cdf0e10cSrcweir     }
558cdf0e10cSrcweir 
removeParcelFromManifest(File document, String name)559cdf0e10cSrcweir     private Manifest removeParcelFromManifest(File document, String name) {
560cdf0e10cSrcweir         Manifest result = null;
561cdf0e10cSrcweir 
562cdf0e10cSrcweir         result = getManifestFromDocument(document);
563cdf0e10cSrcweir         if (result == null)
564cdf0e10cSrcweir             return null;
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         result.remove(name);
567cdf0e10cSrcweir         return result;
568cdf0e10cSrcweir     }
569cdf0e10cSrcweir 
getParcelLanguage(File file)570cdf0e10cSrcweir     public String getParcelLanguage(File file) throws IOException {
571cdf0e10cSrcweir         ZipFile zf = null;
572cdf0e10cSrcweir         ZipEntry ze = null;
573cdf0e10cSrcweir         InputStream is = null;
574cdf0e10cSrcweir         ParcelDescriptor pd;
575cdf0e10cSrcweir 
576cdf0e10cSrcweir         try {
577cdf0e10cSrcweir             zf = new ZipFile(file);
578cdf0e10cSrcweir             ze = zf.getEntry(PARCEL_DESCRIPTOR_XML);
579cdf0e10cSrcweir 
580cdf0e10cSrcweir             if (ze == null)
581cdf0e10cSrcweir                 throw new IOException("Could not find Parcel Descriptor in parcel");
582cdf0e10cSrcweir 
583cdf0e10cSrcweir             is = zf.getInputStream(ze);
584cdf0e10cSrcweir             pd = new ParcelDescriptor(is);
585cdf0e10cSrcweir         }
586cdf0e10cSrcweir         finally {
587cdf0e10cSrcweir             if (zf != null)
588cdf0e10cSrcweir                 zf.close();
589cdf0e10cSrcweir 
590cdf0e10cSrcweir             if (is != null)
591cdf0e10cSrcweir                 is.close();
592cdf0e10cSrcweir         }
593cdf0e10cSrcweir 
594cdf0e10cSrcweir         return pd.getLanguage().toLowerCase();
595cdf0e10cSrcweir     }
596cdf0e10cSrcweir }
597