/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package fedora.server.storage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import org.apache.log4j.Logger; import fedora.server.Context; import fedora.server.errors.ObjectIntegrityException; import fedora.server.errors.ObjectNotFoundException; import fedora.server.errors.ServerException; import fedora.server.errors.StorageDeviceException; import fedora.server.errors.StreamIOException; import fedora.server.errors.UnsupportedTranslationException; import fedora.server.storage.translation.DOTranslator; /** * A RepositoryReader that uses a directory of serialized objects as its working * repository. * <p> * All files in the directory must be digital object serializations, and none * may have the same PID. This is verified upon construction. * </p> * <p> * Note: This implementation does not recognize when files are added to the * directory. What is in the directory at construction-time is what is assumed * to be the extent of the repository for the life of the object. * </p> * * @author Chris Wilper */ public class DirectoryBasedRepositoryReader implements RepositoryReader { /** Logger for this class. */ private static final Logger LOG = Logger.getLogger(DirectoryBasedRepositoryReader.class.getName()); private final DOTranslator m_translator; private final String m_exportFormat; private final String m_storageFormat; private final String m_encoding; private final HashMap m_files = new HashMap(); /** * Initializes the RepositoryReader by looking at all files in the provided * directory and ensuring that they're all serialized digital objects and * that there are no PID conflicts. * * @param directory * the directory where this repository is based. * @param translator * the serialization/deserialization engine for objects. * @param exportFormat * the format to use for export requests. * @param storageFormat * the format of the objects on disk. * @param encoding * The character encoding used across all formats. */ public DirectoryBasedRepositoryReader(File directory, DOTranslator translator, String exportFormat, String storageFormat, String encoding) throws StorageDeviceException, ObjectIntegrityException, StreamIOException, UnsupportedTranslationException, ServerException { m_translator = translator; m_exportFormat = exportFormat; m_storageFormat = storageFormat; m_encoding = encoding; File[] files = directory.listFiles(); if (!directory.isDirectory()) { throw new StorageDeviceException("Repository storage directory not found."); } try { for (File thisFile : files) { try { FileInputStream in = new FileInputStream(thisFile); SimpleDOReader reader = new SimpleDOReader(null, this, m_translator, m_exportFormat, m_storageFormat, m_encoding, in); String pid = reader.GetObjectPID(); if (reader.GetObjectPID().length() == 0) { LOG.warn("File " + thisFile + " has no pid...skipping"); } else { m_files.put(pid, thisFile); } } catch (NullPointerException npe) { LOG.warn("Error in " + thisFile.getName() + "...skipping"); } } } catch (FileNotFoundException fnfe) { // impossible } } private InputStream getStoredObjectInputStream(String pid) throws ObjectNotFoundException { try { return new FileInputStream((File) m_files.get(pid)); } catch (Throwable th) { throw new ObjectNotFoundException("The object, " + pid + " was " + "not found in the repository."); } } public DOReader getReader(boolean UseCachedObject, Context context, String pid) throws ObjectIntegrityException, ObjectNotFoundException, StreamIOException, UnsupportedTranslationException, ServerException { return new SimpleDOReader(null, this, m_translator, m_exportFormat, m_storageFormat, m_encoding, getStoredObjectInputStream(pid)); } public ServiceDeploymentReader getServiceDeploymentReader(boolean UseCachedObject, Context context, String pid) throws ObjectIntegrityException, ObjectNotFoundException, StreamIOException, UnsupportedTranslationException, ServerException { return new SimpleServiceDeploymentReader(null, this, m_translator, m_exportFormat, m_storageFormat, m_encoding, getStoredObjectInputStream(pid)); } public ServiceDefinitionReader getServiceDefinitionReader(boolean UseCachedObject, Context context, String pid) throws ObjectIntegrityException, ObjectNotFoundException, StreamIOException, UnsupportedTranslationException, ServerException { return new SimpleServiceDefinitionReader(null, this, m_translator, m_exportFormat, m_storageFormat, m_encoding, getStoredObjectInputStream(pid)); } public String[] listObjectPIDs(Context context) { String[] out = new String[m_files.keySet().size()]; Iterator iter = m_files.keySet().iterator(); int i = 0; while (iter.hasNext()) { out[i++] = (String) iter.next(); } return out; } }