| /******************************************************************************* |
| * 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); |
| } |
| } |