/************************************************************************* * * $RCSfile: ParcelZipper.java,v $ * * $Revision: 1.6 $ * * last change: $Author: toconnor $ $Date: 2003-02-12 12:41:50 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ package org.openoffice.idesupport.zip; import java.io.*; import java.util.Enumeration; import java.util.zip.*; import java.beans.PropertyVetoException; import org.openoffice.idesupport.filter.FileFilter; import org.openoffice.idesupport.filter.BinaryOnlyFilter; import org.openoffice.idesupport.filter.ExceptParcelFilter; import org.openoffice.idesupport.xml.Manifest; import org.openoffice.idesupport.xml.ParcelDescriptor; public class ParcelZipper { public static final String PARCEL_PREFIX_DIR = "Scripts/"; public static final String PARCEL_EXTENSION = "sxp"; public static final String CONTENTS_DIRNAME = "Contents"; public static final String PARCEL_DESCRIPTOR_XML = "parcel-descriptor.xml"; private static ParcelZipper zipper = null; private static final FileFilter DEFAULT_FILTER = BinaryOnlyFilter.getInstance(); private ParcelZipper() { } public static ParcelZipper getParcelZipper() { if (zipper == null) { synchronized(ParcelZipper.class) { if (zipper == null) zipper = new ParcelZipper(); } } return zipper; } public String zipParcel(File basedir) throws IOException { File targetfile, targetdir; if (basedir.getName().equals(CONTENTS_DIRNAME)) targetdir = basedir.getParentFile(); else targetdir = basedir; targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION); return zipParcel(basedir, targetfile, DEFAULT_FILTER); } public String zipParcel(File basedir, File targetfile) throws IOException { return zipParcel(basedir, targetfile, DEFAULT_FILTER); } public String zipParcel(File basedir, FileFilter filter) throws IOException { File targetfile, targetdir; if (basedir.getName().equals(CONTENTS_DIRNAME)) targetdir = basedir.getParentFile(); else targetdir = basedir; targetfile = new File(targetdir, targetdir.getName() + "." + PARCEL_EXTENSION); return zipParcel(basedir, targetfile, filter); } public String zipParcel(File basedir, File targetfile, FileFilter filter) throws IOException { String realpath, tmppath; realpath = targetfile.getPath(); tmppath = realpath + ".tmp"; File tmpfile = new File(tmppath); try { if (tmpfile.exists() == true) tmpfile.delete(); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tmpfile)); File[] children = basedir.listFiles(); for (int i = 0; i < children.length; i++) addFileToParcel(children[i], "", out, filter); out.close(); } catch (IOException ioe) { tmpfile.delete(); throw ioe; } if (targetfile.exists() == true) targetfile.delete(); tmpfile.renameTo(targetfile); return targetfile.getAbsolutePath(); } private void addFileToParcel(File root, String path, ZipOutputStream out, FileFilter filter) throws IOException { ZipEntry ze; if (root.isDirectory() == true) { ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName() + "/"); out.putNextEntry(ze); out.closeEntry(); File[] children = root.listFiles(); for (int i = 0; i < children.length; i++) addFileToParcel(children[i], path + root.getName() + "/", out, filter); } else { if (filter.validate(root.getName()) == false && root.getName().equals("parcel-descriptor.xml") == false) return; ze = new ZipEntry(/* PARCEL_PREFIX_DIR + */ path + root.getName()); out.putNextEntry(ze); byte[] bytes = new byte[1024]; int len; FileInputStream fis = new FileInputStream(root); while ((len = fis.read(bytes)) != -1) out.write(bytes, 0, len); out.closeEntry(); } } public boolean isOverwriteNeeded(File parcel, File target) throws IOException { boolean result; if (target.isDirectory()) result = isDirectoryOverwriteNeeded(parcel, target); else result = isDocumentOverwriteNeeded(parcel, target); return result; } private boolean isDirectoryOverwriteNeeded(File parcel, File target) { String parcelDir = getParcelDirFromParcelZip(parcel.getName()); File[] children = target.listFiles(); for (int i = 0; i < children.length; i++) if (children[i].getName().equals(parcelDir)) return true; return false; } private boolean isDocumentOverwriteNeeded(File parcel, File document) throws IOException { ZipFile documentZip; boolean result = false; try { documentZip = new ZipFile(document); } catch (IOException ioe) { return false; } String name = PARCEL_PREFIX_DIR + getParcelLanguage(parcel) + "/" + getParcelDirFromParcelZip(parcel.getName()) + "/" + PARCEL_DESCRIPTOR_XML; if (documentZip.getEntry(name) != null) result = true; try { documentZip.close(); } catch (IOException ioe) { } return result; } public String deployParcel(File parcel, File target) throws IOException { String output = null; if (target.isDirectory()) output = unzipToDirectory(parcel, target); else output = unzipToZip(parcel, target); return output; } private String getParcelDirFromParcelZip(String zipname) { String result = zipname.substring(0, zipname.lastIndexOf(".")); return result; } private String unzipToDirectory(File parcel, File targetDirectory) throws IOException { ZipInputStream in; File parcelDir = new File(targetDirectory, getParcelLanguage(parcel) + File.separator + getParcelDirFromParcelZip(parcel.getName())); if (isDirectoryOverwriteNeeded(parcel, targetDirectory)) { if (deleteDir(parcelDir) == false) { throw new IOException("Could not overwrite: " + parcelDir.getAbsolutePath()); } } in = new ZipInputStream(new FileInputStream(parcel)); File outFile; ZipEntry inEntry = in.getNextEntry(); byte[] bytes = new byte[1024]; int len; while (inEntry != null) { outFile = new File(parcelDir, inEntry.getName()); if (inEntry.isDirectory()) { //System.err.println("Creating directory: " + outFile.getAbsolutePath()); outFile.mkdir(); } else { if (outFile.getParentFile().exists() != true) outFile.getParentFile().mkdirs(); FileOutputStream out = new FileOutputStream(outFile); // System.out.println("Writing file: " + outFile.getAbsolutePath()); while ((len = in.read(bytes)) != -1) out.write(bytes, 0, len); out.close(); } inEntry = in.getNextEntry(); } in.close(); return parcelDir.getAbsolutePath(); } private boolean deleteDir(File basedir) { if (basedir.isDirectory()) { String[] children = basedir.list(); for (int i=0; i