/* * Created on 25-May-2004 * Created by Paul Gardner * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.update; /** * @author parg * */ import java.io.*; import java.util.*; import java.util.jar.*; import org.gudy.azureus2.plugins.logging.LoggerChannel; public class UpdateJarPatcher { private static String MANIFEST_NAME = "META-INF/MANIFEST.MF"; protected Map patch_entries = new HashMap(); protected UpdateJarPatcher( InputStream input_file, InputStream patch_file, OutputStream output_file, LoggerChannel log ) throws IOException { readPatchEntries( patch_file ); JarInputStream jis = new JarInputStream(input_file); JarOutputStream jos = new JarOutputStream(output_file); boolean manifest_found = false; while( true ){ JarEntry is_entry = jis.getNextJarEntry(); if ( is_entry == null ){ break; } if ( is_entry.isDirectory()){ continue; } String name = is_entry.getName(); if ( name.equalsIgnoreCase( MANIFEST_NAME )){ manifest_found = true; } InputStream eis = getPatch( name); if ( eis != null ){ log.log( "patch - replace: " + name ); }else{ eis = jis; } JarEntry os_entry = new JarEntry(name); writeEntry( jos, os_entry, eis ); } // write any new entries Iterator it = patch_entries.keySet().iterator(); while( it.hasNext()){ String name = (String)it.next(); if ( name.equalsIgnoreCase( MANIFEST_NAME )){ manifest_found = true; } log.log( "patch - add: " + name); InputStream eis = (InputStream)patch_entries.get(name); JarEntry os_entry = new JarEntry(name); writeEntry( jos, os_entry, eis ); } if ( !manifest_found ){ JarEntry entry = new JarEntry( MANIFEST_NAME ); ByteArrayInputStream bais = new ByteArrayInputStream("Manifest-Version: 1.0\r\n\r\n".getBytes()); writeEntry( jos, entry, bais ); } jos.finish(); // FLUSH is not sufficient!!!! } private static void writeEntry( JarOutputStream jos, JarEntry entry, InputStream data ) throws IOException { jos.putNextEntry(entry); byte[] newBytes = new byte[4096]; int size = data.read(newBytes); while (size != -1){ jos.write(newBytes, 0, size); size = data.read(newBytes); } } protected void readPatchEntries( InputStream is ) throws IOException { JarInputStream jis = new JarInputStream(is ); while( true ){ JarEntry ent = jis.getNextJarEntry(); if ( ent == null ){ break; } if ( ent.isDirectory()){ continue; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[8192]; while( true ){ int l = jis.read( buffer ); if ( l <= 0 ){ break; } baos.write( buffer, 0, l ); } patch_entries.put( ent.getName(), new ByteArrayInputStream( baos.toByteArray())); } } public InputStream getPatch( String name ) { return((InputStream)patch_entries.remove(name)); } }