/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. 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. */ package org.hyperic.util.file; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; /** * Common superclass for TgzUpdater and ZipUpdater */ public abstract class ArchiveUpdater { public static ZipUpdater zipUpdater = new ZipUpdater(); public static TgzUpdater tgzUpdater = new TgzUpdater(); public ArchiveUpdater () {} public static ArchiveUpdater getUpdater (File f) throws FileNotFoundException { if (!f.exists()) { throw new FileNotFoundException("Archive does not exist: " + f.getAbsolutePath()); } if (f.getPath().toLowerCase().endsWith(".tgz") || f.getPath().toLowerCase().endsWith(".tar.gz")) { return tgzUpdater; } else if (f.getPath().toLowerCase().endsWith(".zip") || f.getPath().toLowerCase().endsWith(".jar")) { return zipUpdater; } else { throw new IllegalArgumentException("Unrecognized archive: " + f); } } /** * Update an archive. args array is interpreted as: * args[0] - the archive to update * args[1] - destination file, or "SAME" to update the original * file in place * args[2] - the path within the archive to update * args[3] - the file to use to update the archive */ public static void main (String[] args) { if (args.length != 4) { System.err.println("Usage: java " + ArchiveUpdater.class.getName() + " <archive> <dest|SAME> <path> <file>"); return; } File archive = new File(args[0]); File destFile = getDestFile(args[1]); try { ArchiveUpdater updater = getUpdater(archive); updater.update(archive, destFile, args[2], new File(args[3])); } catch (IOException e) { System.err.println("IOException: " + e.getMessage()); e.printStackTrace(); } } /** * Update an archive. If the pathToReplace does not exist, the file * will be added to the archive. * @param arch The archive to update * @param out The destination file. If null or equal to arch, then the * original archive will be overwritten. * @param pathToReplace The path within the archive that will be replaced. * This may optionally begin with the String "**", in which case the first * file whose name matches the filename after the ** will be updated. * @param replacementFile The new file whose contents will be used to * populate the replacement path. */ public void update (File arch, File out, String pathToReplace, File replacementFile) throws IOException { FileInputStream fi = null; try { fi = new FileInputStream(replacementFile); update(arch, out, pathToReplace, fi, replacementFile.length()); } finally { if (fi != null) try { fi.close(); } catch (IOException e) {} } } /** * Same as the other update method, but this accepts an InputStream as * the replacement file instead of a File object. * @param rsize The size of the replacement stream, in bytes. */ public abstract void update (File arch, File out, String pathToReplace, InputStream replacement, long rsize) throws IOException; protected boolean matches (String archPath, String match) { if (match.startsWith("**")) { return archPath.endsWith(match.substring(2, match.length())); } else { return archPath.equals(match); } } protected void doClose (InputStream is) { if (is != null) { try { is.close(); } catch (IOException e) {} } } protected void doClose (OutputStream os) { if (os != null) { try { os.close(); } catch (IOException e) {} } } public static File getDestFile (String arg) { if ( arg.equalsIgnoreCase("SAME") ) return null; return new File(arg); } }