/* * Copyright (C) 2004 Anthony Smith * * 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. * * ---------------------------------------------------------------------------- * TITLE $Id$ * --------------------------------------------------------------------------- * * --------------------------------------------------------------------------*/ package opendbcopy.plugin.zip; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import opendbcopy.config.APM; import opendbcopy.config.XMLTags; import opendbcopy.controller.MainController; import opendbcopy.plugin.model.DynamicPluginThread; import opendbcopy.plugin.model.Model; import opendbcopy.plugin.model.exception.MissingAttributeException; import opendbcopy.plugin.model.exception.MissingElementException; import opendbcopy.plugin.model.exception.PluginException; import opendbcopy.util.InputOutputHelper; import org.jdom.Element; /** * class description * * @author Anthony Smith * @version $Revision$ */ public class ZipPlugin extends DynamicPluginThread { private static final String outputFileType = "zip"; private Element conf; private Element input; private Element output; private Model model; private File inputFile; // may be null in case of filelists private List inputFilelists; private File outputFile; private FileOutputStream fos = null; private ZipOutputStream zos = null; /** * Creates a new ZipPluign object. * * @param controller DOCUMENT ME! * @param baseModel DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public ZipPlugin(MainController controller, Model baseModel) throws PluginException { super(controller, baseModel); model = baseModel; } /** * DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ protected final void setUp() throws PluginException { String inputConfSelection = null; conf = model.getConf(); // get input input = model.getInput(); // create new output if it does not yet exist if (model.getOutput() == null) { output = new Element(XMLTags.OUTPUT); model.setOutput(output); } else { output = model.getOutput(); } Element inputConf = conf.getChild(XMLTags.INPUT); Element outputConf = conf.getChild(XMLTags.OUTPUT); if (inputConf == null) { throw new PluginException(new MissingElementException(new Element(XMLTags.INPUT), XMLTags.INPUT)); } if (outputConf == null) { throw new PluginException(new MissingElementException(new Element(XMLTags.OUTPUT), XMLTags.OUTPUT)); } // first check that mandator output path / filename is set // read output file path / filename if (outputConf.getChild(XMLTags.FILE).getAttributeValue(XMLTags.VALUE).length() > 0) { String pathFilename = outputConf.getChild(XMLTags.FILE).getAttributeValue(XMLTags.VALUE); int indexFileExtension = pathFilename.indexOf(outputFileType); // file does not yet contain extension if (indexFileExtension != (pathFilename.length() - outputFileType.length())) { pathFilename = pathFilename + "." + outputFileType; } outputFile = new File(pathFilename); } else { throw new PluginException("Missing output path / filename for compressed file"); } // check what shall be taken as input inputConfSelection = inputConf.getChild(XMLTags.FILE_DIR_FILELISTS_SELECTION).getAttributeValue(XMLTags.VALUE); if ((inputConfSelection != null) && (inputConfSelection.length() > 0)) { if (inputConfSelection.compareToIgnoreCase(XMLTags.FILE) == 0) { inputConfSelection = inputConf.getChild(XMLTags.FILE).getAttributeValue(XMLTags.VALUE); if ((inputConfSelection == null) || (inputConfSelection.length() == 0)) { throw new PluginException("Missing file specified in input configuration"); } // try to retrieve file and check if it exists inputFile = new File(inputConfSelection); if (!inputFile.exists()) { throw new PluginException("File " + inputFile.getAbsolutePath() + " does not exist!"); } } else if (inputConfSelection.compareTo(XMLTags.DIR) == 0) { inputConfSelection = inputConf.getChild(XMLTags.DIR).getAttributeValue(XMLTags.VALUE); if ((inputConfSelection == null) || (inputConfSelection.length() == 0)) { throw new PluginException("Missing directory specified in input configuration"); } // try to retrieve file and check if it exists inputFile = new File(inputConfSelection); if (!inputFile.exists()) { throw new PluginException("Directory " + inputFile.getAbsolutePath() + " does not exist!"); } } // input is provided by filelists from former plugin in its output else if (inputConfSelection.compareTo(XMLTags.FILELISTS) == 0) { if (input == null) { throw new PluginException("Missing output from former plugin!"); } if (input.getChildren(XMLTags.FILELIST).size() == 0) { throw new PluginException("Missing output filelists from former plugin!"); } inputFilelists = input.getChildren(XMLTags.FILELIST); } else { throw new PluginException("You must specify an input type"); } } } /** * DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public final void execute() throws PluginException { // set output Element outputFileElement = null; try { fos = new FileOutputStream(outputFile.getAbsolutePath()); zos = new ZipOutputStream(fos); // zip filelist(s) from input of former plugin if (inputFilelists != null) { Iterator itFileLists = inputFilelists.iterator(); // only takes the first filelist -> future versions shall implement something nicer regarding filelists if (itFileLists.hasNext()) { Element filelist = (Element) itFileLists.next(); String dir = filelist.getAttributeValue(XMLTags.DIR); ArrayList files = InputOutputHelper.getFileList(filelist); zipFiles(files, dir); outputFileElement = InputOutputHelper.createFileElement(inputFile); } } // zip file or directory not from input else { zipFileOrDirectory(inputFile); // create output entry if (inputFile.isFile()) { outputFileElement = InputOutputHelper.createFileElement(inputFile); } else { outputFileElement = InputOutputHelper.createDirElement(inputFile); } } zos.flush(); zos.close(); fos.close(); output.addContent(outputFileElement); logger.info("Created zip file " + outputFile.getAbsolutePath()); } catch (MissingAttributeException e) { throw new PluginException(e); } catch (MissingElementException e) { throw new PluginException(e); } catch (FileNotFoundException e) { throw new PluginException(e); } catch (IOException e) { throw new PluginException(e); } } /** * DOCUMENT ME! * * @param files DOCUMENT ME! * @param dir DOCUMENT ME! * * @throws FileNotFoundException DOCUMENT ME! * @throws IOException DOCUMENT ME! */ private void zipFiles(ArrayList files, String dir) throws FileNotFoundException, IOException { for (int i = 0; i < files.size(); i++) { zipFileEntry((File) files.get(i), dir); } } /** * file may be a single file or directory * * @param file DOCUMENT ME! * * @throws FileNotFoundException DOCUMENT ME! * @throws IOException DOCUMENT ME! */ private void zipFileOrDirectory(File file) throws FileNotFoundException, IOException { if (file.isDirectory()) { String dirRoot = file.getName(); zipDir(file, dirRoot); } else { zipFileEntry(file, null); } } /** * DOCUMENT ME! * * @param fileIn DOCUMENT ME! * @param dirAppender DOCUMENT ME! * * @throws FileNotFoundException DOCUMENT ME! * @throws IOException DOCUMENT ME! */ private void zipDir(File fileIn, String dirAppender) throws FileNotFoundException, IOException { if (fileIn.exists() == true) { if (fileIn.isDirectory() == true) { File[] fileList = fileIn.listFiles(); for (int i = 0; i < fileList.length; i++) { if (fileList[i].isDirectory()) { zipDir(fileList[i], dirAppender + APM.FILE_SEP + fileList[i].getName()); } else if (fileList[i].isFile()) { zipFileEntry(fileList[i], dirAppender); } } } } } /** * DOCUMENT ME! * * @param zipEntryFile DOCUMENT ME! * @param dirAppender DOCUMENT ME! * * @throws FileNotFoundException DOCUMENT ME! * @throws IOException DOCUMENT ME! */ private void zipFileEntry(File zipEntryFile, String dirAppender) throws FileNotFoundException, IOException { // Create a file input stream and a buffered input stream. FileInputStream fis = new FileInputStream(zipEntryFile); BufferedInputStream bis = new BufferedInputStream(fis); // Create a Zip Entry and put it into the archive (no data yet). ZipEntry fileEntry = null; if (dirAppender != null) { fileEntry = new ZipEntry(dirAppender + APM.FILE_SEP + zipEntryFile.getName()); } else { fileEntry = new ZipEntry(zipEntryFile.getName()); } zos.putNextEntry(fileEntry); // Create a byte array object named data and declare byte count variable. byte[] data = new byte[1024]; int byteCount; // Create a loop that reads from the buffered input stream and writes // to the zip output stream until the bis has been entirely read. while ((byteCount = bis.read(data, 0, 1024)) > -1) { zos.write(data, 0, byteCount); } } }