/******************************************************************************* * Copyright (c) 2006, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.update.internal.jarprocessor; import java.io.*; import java.util.*; import java.util.zip.*; /** * @author aniefer@ca.ibm.com * */ public class ZipProcessor { private IProcessStep signStep = null; private IProcessStep packStep = null; private IProcessStep packUnpackStep = null; private IProcessStep unpackStep = null; private String workingDirectory = null; private Properties properties = null; private Set packExclusions = null; private Set signExclusions = null; private String command = null; private boolean packing = false; private boolean signing = false; private boolean repacking = false; private boolean unpacking = false; private boolean verbose = false; private boolean processAll = false; public void setWorkingDirectory(String dir) { workingDirectory = dir; } public String getWorkingDirectory() { if (workingDirectory == null) workingDirectory = "."; //$NON-NLS-1$ return workingDirectory; } public void setSignCommand(String command) { this.command = command; this.signing = (command != null); } public void setPack(boolean pack) { this.packing = pack; } public void setRepack(boolean repack) { this.repacking = repack; } public void setUnpack(boolean unpack) { this.unpacking = unpack; } public void setVerbose(boolean verbose) { this.verbose = verbose; } public void setProcessAll(boolean all) { this.processAll = all; } public void processZip(File zipFile) throws ZipException, IOException { if (verbose) System.out.println("Processing " + zipFile.getPath()); //$NON-NLS-1$ ZipFile zip = new ZipFile(zipFile); initialize(zip); String extension = unpacking ? "pack.gz" : ".jar"; //$NON-NLS-1$ //$NON-NLS-2$ File tempDir = new File(getWorkingDirectory(), "temp_" + zipFile.getName()); //$NON-NLS-1$ JarProcessor processor = new JarProcessor(); processor.setVerbose(verbose); processor.setProcessAll(processAll); processor.setWorkingDirectory(tempDir.getCanonicalPath()); if (unpacking) { processor.addProcessStep(unpackStep); } File outputFile = new File(getWorkingDirectory(), zipFile.getName() + ".temp"); //$NON-NLS-1$ File parent = outputFile.getParentFile(); if (!parent.exists()) parent.mkdirs(); ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(outputFile)); Enumeration entries = zip.entries(); if (entries.hasMoreElements()) { for (ZipEntry entry = (ZipEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (ZipEntry) entries.nextElement() : null) { String name = entry.getName(); InputStream entryStream = zip.getInputStream(entry); boolean pack = packing && !packExclusions.contains(name); boolean sign = signing && !signExclusions.contains(name); boolean repack = repacking && !packExclusions.contains(name); File extractedFile = null; if (entry.getName().endsWith(extension) && (pack || sign || repack || unpacking)) { extractedFile = new File(tempDir, name); parent = extractedFile.getParentFile(); if (!parent.exists()) parent.mkdirs(); if (verbose) System.out.println("Extracting " + entry.getName()); //$NON-NLS-1$ FileOutputStream extracted = new FileOutputStream(extractedFile); Utils.transferStreams(entryStream, extracted, true); // this will close the stream entryStream = null; boolean skip = Utils.shouldSkipJar(extractedFile, processAll, verbose); if (skip) { //skipping this file entryStream = new FileInputStream(extractedFile); if (verbose) System.out.println(entry.getName() + " is not marked, skipping."); //$NON-NLS-1$ } else { if (unpacking) { File result = processor.processJar(extractedFile); name = name.substring(0, name.length() - extractedFile.getName().length()) + result.getName(); extractedFile = result; } else { if (repack || sign) { processor.clearProcessSteps(); if (repack) processor.addProcessStep(packUnpackStep); if (sign) processor.addProcessStep(signStep); extractedFile = processor.processJar(extractedFile); } if (pack) { processor.clearProcessSteps(); processor.addProcessStep(packStep); File modifiedFile = processor.processJar(extractedFile); if (modifiedFile.exists()) { try { String newName = name.substring(0, name.length() - extractedFile.getName().length()) + modifiedFile.getName(); if (verbose) { System.out.println("Adding " + newName + " to " + outputFile.getPath()); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println(); } ZipEntry zipEntry = new ZipEntry(newName); entryStream = new FileInputStream(modifiedFile); zipOut.putNextEntry(zipEntry); Utils.transferStreams(entryStream, zipOut, false); //we want to keep zipOut open entryStream.close(); Utils.clear(modifiedFile); } catch (IOException e) { Utils.close(entryStream); if (verbose) { e.printStackTrace(); System.out.println("Warning: Problem reading " + modifiedFile.getPath() + "."); } } entryStream = null; } else if (verbose) { System.out.println("Warning: " + modifiedFile.getPath() + " not found."); } } } if (extractedFile.exists()) { try { entryStream = new FileInputStream(extractedFile); } catch (IOException e) { if (verbose) { e.printStackTrace(); System.out.println("Warning: Problem reading " + extractedFile.getPath() + "."); } } } if (verbose && entryStream != null) { System.out.println("Adding " + name + " to " + outputFile.getPath()); //$NON-NLS-1$ //$NON-NLS-2$ } } } if (entryStream != null) { ZipEntry newEntry = new ZipEntry(name); try { zipOut.putNextEntry(newEntry); Utils.transferStreams(entryStream, zipOut, false); zipOut.closeEntry(); } catch (ZipException e) { if(verbose) { System.out.println("Warning: " + name + " already exists in " + outputFile.getName() + ". Skipping."); } } entryStream.close(); } if (extractedFile != null) Utils.clear(extractedFile); if (verbose) { System.out.println(); System.out.println("Processing " + zipFile.getPath()); //$NON-NLS-1$ } } } zipOut.close(); zip.close(); File finalFile = new File(getWorkingDirectory(), zipFile.getName()); if (finalFile.exists()) finalFile.delete(); outputFile.renameTo(finalFile); Utils.clear(tempDir); } private void initialize(ZipFile zip) { ZipEntry entry = zip.getEntry("pack.properties"); //$NON-NLS-1$ properties = new Properties(); if (entry != null) { InputStream stream = null; try { stream = zip.getInputStream(entry); properties.load(stream); } catch (IOException e) { if (verbose) e.printStackTrace(); } finally { Utils.close(stream); } } packExclusions = Utils.getPackExclusions(properties); signExclusions = Utils.getSignExclusions(properties); packUnpackStep = new PackUnpackStep(properties, verbose); packStep = new PackStep(properties, verbose); signStep = new SignCommandStep(properties, command, verbose); unpackStep = new UnpackStep(properties, verbose); } }