org.refcodes.filesystem.impls.InMemoryFileSystemImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-filesystem Show documentation
Show all versions of refcodes-filesystem Show documentation
Artifact for the refcodes virtual file system design.
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
// under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// =============================================================================
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// together with the GPL linking exception applied; as being applied by the GNU
// Classpath ("http://www.gnu.org/software/classpath/license.html")
// =============================================================================
// Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
// =============================================================================
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.filesystem.impls;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.io.IOUtils;
import org.refcodes.filesystem.ConcurrentAccessException;
import org.refcodes.filesystem.FileAlreadyExistsException;
import org.refcodes.filesystem.FileHandle;
import org.refcodes.filesystem.FileHandle.MutableFileHandle;
import org.refcodes.filesystem.FileSystem;
import org.refcodes.filesystem.FileSystemUtility;
import org.refcodes.filesystem.IllegalFileHandleException;
import org.refcodes.filesystem.IllegalKeyException;
import org.refcodes.filesystem.IllegalNameException;
import org.refcodes.filesystem.IllegalPathException;
import org.refcodes.filesystem.NoCreateAccessException;
import org.refcodes.filesystem.NoDeleteAccessException;
import org.refcodes.filesystem.NoListAccessException;
import org.refcodes.filesystem.NoReadAccessException;
import org.refcodes.filesystem.NoWriteAccessException;
import org.refcodes.filesystem.UnknownFileException;
import org.refcodes.filesystem.UnknownFileSystemException;
import org.refcodes.filesystem.UnknownKeyException;
import org.refcodes.filesystem.UnknownPathException;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.impls.RuntimeLoggerFactorySingleton;
/**
* An in-memory {@link FileSystem} using an {@link ConcurrentHashMap} for
* implementation.
*/
public class InMemoryFileSystemImpl implements FileSystem {
private static RuntimeLogger LOGGER = RuntimeLoggerFactorySingleton.createRuntimeLogger();
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private Map _fileSystemMap = new ConcurrentHashMap();
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Constructs an in-memory {@link FileSystem}.
*/
public InMemoryFileSystemImpl() {}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
@Override
public boolean hasFile( String aKey ) throws IllegalKeyException, NoListAccessException, UnknownFileSystemException, IOException {
return _fileSystemMap.containsKey( new FileHandleImpl( aKey ) );
}
@Override
public boolean hasFile( String aPath, String aName ) throws IllegalPathException, IllegalNameException, NoListAccessException, UnknownFileSystemException, IOException {
return _fileSystemMap.containsKey( new FileHandleImpl( aPath, aName ) );
}
@Override
public boolean hasFile( FileHandle aFileHandle ) throws NoListAccessException, UnknownFileSystemException, IOException, IllegalFileHandleException {
return _fileSystemMap.containsKey( aFileHandle );
}
@Override
public FileHandle createFile( String aKey ) throws FileAlreadyExistsException, NoCreateAccessException, IllegalKeyException, UnknownFileSystemException, IOException, NoListAccessException {
Date theDate = new Date();
FileHandle theFileHandle = new FileHandleImpl( FileSystemUtility.getPath( aKey ), FileSystemUtility.getName( aKey ), 0, theDate, theDate );
if ( _fileSystemMap.containsKey( theFileHandle ) ) {
throw new FileAlreadyExistsException( aKey, "The file with the key \"" + aKey + "\" already exists." );
}
_fileSystemMap.put( theFileHandle, new byte[] {} );
return theFileHandle;
}
@Override
public FileHandle createFile( String aPath, String aName ) throws FileAlreadyExistsException, NoCreateAccessException, IllegalNameException, IllegalPathException, UnknownFileSystemException, IOException, NoListAccessException {
Date theDate = new Date();
FileHandle theFileHandle = new FileHandleImpl( aPath, aName, 0, theDate, theDate );
if ( _fileSystemMap.containsKey( theFileHandle ) ) {
throw new FileAlreadyExistsException( theFileHandle.toKey(), "The file with the key \"" + theFileHandle.toKey() + "\" already exists." );
}
_fileSystemMap.put( theFileHandle, new byte[] {} );
return theFileHandle;
}
@Override
public FileHandle getFileHandle( String aKey ) throws NoListAccessException, IllegalKeyException, UnknownFileSystemException, IOException, UnknownKeyException {
FileHandle theFileHandle = new FileHandleImpl( aKey );
theFileHandle = toFileHandle( theFileHandle );
if ( theFileHandle == null ) {
throw new UnknownKeyException( aKey, "The file with the key \"" + aKey + "\" does not exist." );
}
return theFileHandle;
}
@Override
public FileHandle getFileHandle( String aPath, String aName ) throws NoListAccessException, IllegalNameException, IllegalPathException, UnknownFileSystemException, IOException, UnknownKeyException {
FileHandle theFileHandle = new FileHandleImpl( aPath, aName );
for ( FileHandle eFileHandle : _fileSystemMap.keySet() ) {
if ( eFileHandle.equals( theFileHandle ) ) {
return eFileHandle;
}
}
throw new UnknownKeyException( FileSystemUtility.toKey( aPath, aName ), "The file with the path \"" + aPath + "\" and name \"" + aName + "\" ( = key \"" + FileSystemUtility.toKey( aPath, aName ) + "\") does not exist." );
}
@Override
public void fromFile( FileHandle aFromFileHandle, OutputStream aOutputStream ) throws ConcurrentAccessException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
byte[] theBuffer = _fileSystemMap.get( aFromFileHandle );
if ( theBuffer == null ) {
throw new UnknownFileException( aFromFileHandle, "The (from) file with the key \"" + aFromFileHandle.toKey() + "\" does not exist." );
}
aOutputStream.write( theBuffer );
aOutputStream.flush();
}
@Override
public synchronized void toFile( FileHandle aToFileHandle, InputStream aInputStream ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
if ( !hasFile( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
byte[] theBuffer = IOUtils.toByteArray( aInputStream );
MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setSize( theBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), theBuffer );
}
@Override
public synchronized InputStream fromFile( FileHandle aFromFileHandle ) throws ConcurrentAccessException, UnknownFileException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
byte[] theBuffer = _fileSystemMap.get( aFromFileHandle );
if ( theBuffer == null ) {
throw new UnknownFileException( aFromFileHandle, "The (from) file with the key \"" + aFromFileHandle.toKey() + "\" does not exist." );
}
return new ByteArrayInputStream( theBuffer );
}
@Override
public OutputStream toFile( final FileHandle aToFileHandle ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, IllegalFileHandleException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
final PipedInputStream thePipedInputStream = new PipedInputStream();
PipedOutputStream thePipedOutputStream = new PipedOutputStream( thePipedInputStream );
Thread t = new Thread() {
@Override
public void run() {
try {
byte[] theBuffer = IOUtils.toByteArray( thePipedInputStream );
MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setSize( theBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), theBuffer );
}
catch ( IOException e ) {
LOGGER.warn( "Unable to write the output stream to the file with key \"" + aToFileHandle.toKey() + "\".", e );
}
finally {}
}
};
t.start();
return thePipedOutputStream;
}
@Override
public void fromFile( FileHandle aFromFileHandle, File aToFile ) throws ConcurrentAccessException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
byte[] theBuffer = _fileSystemMap.get( aFromFileHandle );
if ( theBuffer == null ) {
throw new UnknownFileException( aFromFileHandle, "The (from) file with the key \"" + aFromFileHandle.toKey() + "\" does not exist." );
}
OutputStream theOutputStream = new FileOutputStream( aToFile );
IOUtils.copy( new ByteArrayInputStream( theBuffer ), theOutputStream );
}
@Override
public void toFile( FileHandle aToFileHandle, File aFromFile ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
FileInputStream theFileInputStream = new FileInputStream( aFromFile );
byte[] theBuffer = IOUtils.toByteArray( theFileInputStream );
_fileSystemMap.put( aToFileHandle, theBuffer );
}
@Override
public void toFile( FileHandle aToFileHandle, byte[] aBuffer ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setSize( aBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), aBuffer );
}
@Override
public synchronized FileHandle renameFile( FileHandle aFileHandle, String aNewName ) throws UnknownFileException, ConcurrentAccessException, FileAlreadyExistsException, NoCreateAccessException, NoDeleteAccessException, IllegalNameException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
MutableFileHandle theMutableNewFileHandle = theFileHandle.toMutableFileHandle();
theMutableNewFileHandle.setName( FileSystemUtility.getName( aNewName ) );
FileHandle theNewFileHandle = theMutableNewFileHandle.toFileHandle();
if ( _fileSystemMap.containsKey( theNewFileHandle ) ) {
throw new FileAlreadyExistsException( theNewFileHandle.toKey(), "The file with the key \"" + theNewFileHandle.toKey() + "\" already exist." );
}
byte[] theBuffer = _fileSystemMap.remove( theFileHandle );
_fileSystemMap.put( theNewFileHandle, theBuffer );
return theNewFileHandle;
}
@Override
public synchronized FileHandle moveFile( FileHandle aFileHandle, String aNewKey ) throws UnknownFileException, ConcurrentAccessException, FileAlreadyExistsException, NoCreateAccessException, NoDeleteAccessException, IllegalKeyException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
MutableFileHandle theMutableNewFileHandle = theFileHandle.toMutableFileHandle();
theMutableNewFileHandle.setPath( FileSystemUtility.getPath( aNewKey ) );
theMutableNewFileHandle.setName( FileSystemUtility.getName( aNewKey ) );
FileHandle theNewFileHandle = theMutableNewFileHandle.toFileHandle();
if ( _fileSystemMap.containsKey( theNewFileHandle ) ) {
throw new FileAlreadyExistsException( theNewFileHandle.toKey(), "The file with the key \"" + aFileHandle.toKey() + "\" already exist." );
}
byte[] theBuffer = _fileSystemMap.remove( theFileHandle );
_fileSystemMap.put( theNewFileHandle, theBuffer );
return theNewFileHandle;
}
@Override
public void deleteFile( FileHandle aFileHandle ) throws ConcurrentAccessException, UnknownFileException, NoDeleteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileHandleException {
FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
_fileSystemMap.remove( theFileHandle );
}
@Override
public boolean hasFiles( String aPath, boolean isRecursively ) throws NoListAccessException, IllegalPathException, UnknownFileSystemException, IOException {
for ( FileHandle eFileHandle : _fileSystemMap.keySet() ) {
if ( isRecursively ) {
if ( eFileHandle.getPath().equals( aPath ) || eFileHandle.getPath().startsWith( aPath + PATH_DELIMITER ) ) {
return true;
}
}
else {
if ( eFileHandle.getPath().equals( aPath ) ) {
return true;
}
}
}
return false;
}
@Override
public List getFileHandles( String aPath, boolean isRecursively ) throws NoListAccessException, UnknownPathException, IllegalPathException, UnknownFileSystemException, IOException {
List theFileHandles = new ArrayList();
for ( FileHandle eFileHandle : _fileSystemMap.keySet() ) {
if ( isRecursively ) {
if ( eFileHandle.getPath().equals( aPath ) || eFileHandle.getPath().startsWith( aPath + PATH_DELIMITER ) ) {
theFileHandles.add( eFileHandle );
}
}
else {
if ( eFileHandle.getPath().equals( aPath ) ) {
theFileHandles.add( eFileHandle );
}
}
}
return theFileHandles;
}
// /////////////////////////////////////////////////////////////////////////
// COMPONENT:
// /////////////////////////////////////////////////////////////////////////
@Override
public void destroy() {
_fileSystemMap.clear();
}
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
/**
* Retrieves the actual managed {@link FileHandle} equal to the provided
* one.
*
* @param aFileHandle The {@link FileHandle} for which to get the managed
* one.
*
* @return The managed {@link FileHandle} or null if none equal file handl
* was found in the internal map.
*/
private FileHandle toFileHandle( FileHandle aFileHandle ) {
for ( FileHandle eFileHandle : _fileSystemMap.keySet() ) {
if ( eFileHandle.equals( aFileHandle ) ) {
return eFileHandle;
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy