/* * 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.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.util.security.MD5; /** * A class which has the ability to write to files, deal with * permissions/ownership, and rollback changes later on. */ public class FileWriter extends WriterHandler { private static final int MODE_CREATEONLY = 1; private static final int MODE_CREATEOROVERWRITE = 2; private static final int MODE_REWRITE = 3; private final Log log = LogFactory.getLog(FileWriter.class); private File destFile; private InputStream inStream; private WriterHandler writer; private int mode; private long length; private String expectedMD5Sum; public FileWriter(File destFile, InputStream inStream, long size){ super(); this.destFile = destFile; this.inStream = inStream; this.length = size; this.writer = null; this.mode = MODE_CREATEOROVERWRITE; } public FileWriter(File destFile, byte[] data){ this(destFile, new ByteArrayInputStream(data), data.length); } /** * Verify the MD5 check sum on file write. * * @param expectedMD5sum The expected MD5 check sum. */ public void setVerifyMD5CheckSumOnWrite(String expectedMD5sum) { this.expectedMD5Sum = expectedMD5sum; } public File getDestFile(){ return this.destFile; } public void setCreateOnly(){ this.mode = MODE_CREATEONLY; } public boolean isCreateOnly(){ return this.mode == MODE_CREATEONLY; } public void setCreateOrOverwrite(){ this.mode = MODE_CREATEOROVERWRITE; } public boolean isCreateOrOverwrite(){ return this.mode == MODE_CREATEOROVERWRITE; } public void setRewrite(){ this.mode = MODE_REWRITE; } public boolean isRewrite(){ return this.mode == MODE_REWRITE; } public void rollback() throws IOException { super.rollback(); this.writer.rollback(); } public void cleanup(){ super.cleanup(); this.writer.cleanup(); } /** * Write the file. * * @throws IOException if the file write fails. */ public void write() throws IOException { super.write(); if(this.isCreateOrOverwrite()) this.writer = new CreateOrOverwriteWriter(this.destFile, this.inStream, this.length); else if(this.isCreateOnly()) this.writer = new CreateOnlyWriter(this.destFile, this.inStream, this.length); else if(this.isRewrite()) this.writer = new RewriteWriter(this.destFile, this.inStream, this.length); else throw new IllegalStateException("Unhandled write mode"); this.writer.write(); } /** * Verify the MD5 check sum of the written file. * * @throws IOException if the MD5 check sum verification fails. * @throws IllegalStateException if the file has not been written yet. */ public void verifyMD5CheckSum() throws IOException { if (this.writer == null || !this.writer.hasWritten()) { throw new IllegalStateException("the file must be written before " + "verifying the MD5 check sum"); } if (this.expectedMD5Sum != null) { String actualMD5Sum = MD5.getMD5Checksum(getDestFile()); log.debug("Verifying MD5 check sum for file "+getDestFile()+ "; expected="+this.expectedMD5Sum+", actual="+actualMD5Sum); if (!this.expectedMD5Sum.equals(actualMD5Sum)) { throw new IOException("MD5 check sum failed for file "+ getDestFile()+"; expected="+this.expectedMD5Sum+ ", actual="+actualMD5Sum); } } } }