/* * Copyright � 2004, Rob Gordon. */ package org.oddjob.persist; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.OutputStream; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.oddjob.arooa.life.ComponentPersistException; /** * Serialize an object to and from file with the given name. The .ser extension * is added to the file name. * <p> * When writing a temporary name is used in case the process is kill mid writing * so there is less chance of a corrupted file. The temporary name includes an * underscore in the name. * * @author Rob Gordon. */ public class SerializeWithFile { private static final Logger logger = Logger.getLogger(SerializeWithFile.class); private final static String EXTENSION = ".ser"; public void toFile(File dir, String name, Object o) throws ComponentPersistException { File inProgress = new File(dir, name + "_"+ EXTENSION); File old = new File(dir, "_" + name + EXTENSION); File finished = new File(dir, name + EXTENSION); ObjectOutput oo = null; try { OutputStream os = new FileOutputStream(inProgress); oo = new ObjectOutputStream(os); } catch (FileNotFoundException e) { throw new ComponentPersistException("Check directory exists!", e); } catch (IOException e) { throw new ComponentPersistException("Failed opening file [" + inProgress + "]", e); } try { oo.writeObject(o); } catch (IOException e) { throw new ComponentPersistException("Failed writing object id [" + name + "], class [" + o.getClass().getName() + "], object [" + o + "]." , e); } finally { try { oo.close(); } catch (IOException e) { // ignore } } // Need to move the old file because on some platforms you can't // rename over an existing file. if (finished.exists()) { if (!finished.renameTo(old)) { logger.warn("Failed renaming " + finished + " to " + old); } } if (!inProgress.renameTo(finished)) { throw new ComponentPersistException("Failed renaming " + inProgress + " to " + finished); } // Now delete the old file for next time. if (old.exists()) { if (!old.delete()) { logger.warn("Failed deleting " + old); } } logger.debug("Saved [" + o + "], id [" + name + "] to file ][" + finished + "]."); } public void remove(File dir, String name) { File f = new File(dir, name + EXTENSION); if (f.exists()) { boolean result = f.delete(); if (result) { logger.debug("Deleted [" + f + "]."); } else { logger.debug("Failed to delete [" + f + "]."); } } } public Object fromFile(File dir, String name, ClassLoader classLoader) throws ComponentPersistException { File f = new File(dir, name + EXTENSION); if (!f.exists()) { return null; } ObjectInput oi = null; try { InputStream is = new FileInputStream(f); oi = new OddjobObjectInputStream(is, classLoader); } catch (IOException e) { throw new ComponentPersistException( "Failed opening file [" + f + "]", e); } try { Object o = oi.readObject(); logger.debug("Loaded [" + o + "] from [" + f + "]."); return o; } catch (Exception e) { throw new ComponentPersistException( "Failed reading component from file " + f, e); } finally { try { oi.close(); } catch (IOException e) { // ignore } } } public void clear(File dir) { if (dir.exists()) { try { FileUtils.forceDelete(dir); logger.debug("Deleted [" + dir + "]."); } catch (IOException e) { throw new RuntimeException("Failed to delete [" + dir + "].", e); } } } public String[] list(File dir) { File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isFile() && pathname.getName().endsWith(EXTENSION)) { return true; } else { return false; } } }); String[] names = new String[files.length]; for (int i = 0 ; i < names.length ; ++i) { String nameWithExtension = files[i].getName(); names[i] = nameWithExtension.substring(0, nameWithExtension.length() - EXTENSION.length()); } logger.debug("Listing [" + names.length + "] file from [" + dir + "]"); return names; } public String[] children(File dir) { File[] files = dir.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return true; } else { return false; } } }); String[] names = new String[files.length]; for (int i = 0 ; i < names.length ; ++i) { names[i] = files[i].getName(); } logger.debug("Children [" + names.length + "] of [" + dir + "]"); return names; } }