org.refcodes.filesystem.InMemoryFileSystem 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, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed 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/TEXT-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;
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 java.util.logging.Level;
import java.util.logging.Logger;
import org.refcodes.exception.Trap;
import org.refcodes.filesystem.FileHandle.MutableFileHandle;
/**
* An in-memory {@link FileSystem} using an {@link ConcurrentHashMap} for
* implementation.
*/
public class InMemoryFileSystem implements FileSystem {
private static final Logger LOGGER = Logger.getLogger( InMemoryFileSystem.class.getName() );
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private final Map _fileSystemMap = new ConcurrentHashMap<>();
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Constructs an in-memory {@link FileSystem}.
*/
public InMemoryFileSystem() {}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public boolean hasFile( String aKey ) throws IllegalKeyException, NoListAccessException, UnknownFileSystemException, IOException {
return _fileSystemMap.containsKey( new FileHandleImpl( aKey ) );
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasFile( String aPath, String aName ) throws IllegalPathException, IllegalNameException, NoListAccessException, UnknownFileSystemException, IOException {
return _fileSystemMap.containsKey( new FileHandleImpl( aPath, aName ) );
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasFile( FileHandle aFileHandle ) throws NoListAccessException, UnknownFileSystemException, IOException, IllegalFileException {
return _fileSystemMap.containsKey( aFileHandle );
}
/**
* {@inheritDoc}
*/
@Override
public FileHandle createFile( String aKey ) throws FileAlreadyExistsException, NoCreateAccessException, IllegalKeyException, UnknownFileSystemException, IOException, NoListAccessException {
final Date theDate = new Date();
final 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;
}
/**
* {@inheritDoc}
*/
@Override
public FileHandle createFile( String aPath, String aName ) throws FileAlreadyExistsException, NoCreateAccessException, IllegalNameException, IllegalPathException, UnknownFileSystemException, IOException, NoListAccessException {
final Date theDate = new Date();
final 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;
}
/**
* {@inheritDoc}
*/
@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( "The file with the key \"" + aKey + "\" does not exist.", aKey );
}
return theFileHandle;
}
/**
* {@inheritDoc}
*/
@Override
public FileHandle getFileHandle( String aPath, String aName ) throws NoListAccessException, IllegalNameException, IllegalPathException, UnknownFileSystemException, IOException, UnknownKeyException {
final FileHandle theFileHandle = new FileHandleImpl( aPath, aName );
for ( FileHandle eFileHandle : _fileSystemMap.keySet() ) {
if ( eFileHandle.equals( theFileHandle ) ) {
return eFileHandle;
}
}
throw new UnknownKeyException( "The file with the path \"" + aPath + "\" and name \"" + aName + "\" ( = key \"" + FileSystemUtility.toKey( aPath, aName ) + "\") does not exist.", FileSystemUtility.toKey( aPath, aName ) );
}
/**
* {@inheritDoc}
*/
@Override
public void fromFile( FileHandle aFromFileHandle, OutputStream aOutputStream ) throws ConcurrentAccessException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final 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();
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void toFile( FileHandle aToFileHandle, InputStream aInputStream ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
if ( !hasFile( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
final byte[] theBuffer = aInputStream.readAllBytes();
final MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setFileSize( theBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), theBuffer );
}
/**
* {@inheritDoc}
*/
@Override
public synchronized InputStream fromFile( FileHandle aFromFileHandle ) throws ConcurrentAccessException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final 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 );
}
/**
* {@inheritDoc}
*/
@Override
public OutputStream toFile( final FileHandle aToFileHandle ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, IllegalFileException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
final PipedInputStream thePipedInputStream = new PipedInputStream();
final PipedOutputStream thePipedOutputStream = new PipedOutputStream( thePipedInputStream );
final Thread t = new Thread() {
/**
* {@inheritDoc}
*/
@Override
public void run() {
try {
final byte[] theBuffer = thePipedInputStream.readAllBytes();
final MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setFileSize( theBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), theBuffer );
}
catch ( IOException e ) {
LOGGER.log( Level.WARNING, "Unable to write the output stream to the file with key \"" + aToFileHandle.toKey() + "\" as of: " + Trap.asMessage( e ), e );
}
finally {}
}
};
t.start();
return thePipedOutputStream;
}
/**
* {@inheritDoc}
*/
@Override
public void fromFile( FileHandle aFromFileHandle, File aToFile ) throws ConcurrentAccessException, UnknownFileException, NoReadAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final byte[] theBuffer = _fileSystemMap.get( aFromFileHandle );
if ( theBuffer == null ) {
throw new UnknownFileException( aFromFileHandle, "The (from) file with the key \"" + aFromFileHandle.toKey() + "\" does not exist." );
}
try ( OutputStream theOutputStream = new FileOutputStream( aToFile ) ) {
new ByteArrayInputStream( theBuffer ).transferTo( theOutputStream );
}
}
/**
* {@inheritDoc}
*/
@Override
public void toFile( FileHandle aToFileHandle, File aFromFile ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
try ( FileInputStream theFileInputStream = new FileInputStream( aFromFile ) ) {
final byte[] theBuffer = theFileInputStream.readAllBytes();
_fileSystemMap.put( aToFileHandle, theBuffer );
}
}
/**
* {@inheritDoc}
*/
@Override
public void toFile( FileHandle aToFileHandle, byte[] aBuffer ) throws ConcurrentAccessException, UnknownFileException, NoWriteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
if ( !_fileSystemMap.containsKey( aToFileHandle ) ) {
throw new UnknownFileException( aToFileHandle, "The (to) file with the key \"" + aToFileHandle.toKey() + "\" does not exist." );
}
final MutableFileHandle theMutableToFileHandle = aToFileHandle.toMutableFileHandle();
theMutableToFileHandle.setFileSize( aBuffer.length );
_fileSystemMap.put( theMutableToFileHandle.toFileHandle(), aBuffer );
}
/**
* {@inheritDoc}
*/
@Override
public synchronized FileHandle renameFile( FileHandle aFileHandle, String aNewName ) throws UnknownFileException, ConcurrentAccessException, FileAlreadyExistsException, NoCreateAccessException, NoDeleteAccessException, IllegalNameException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
final MutableFileHandle theMutableNewFileHandle = theFileHandle.toMutableFileHandle();
theMutableNewFileHandle.setName( FileSystemUtility.getName( aNewName ) );
final FileHandle theNewFileHandle = theMutableNewFileHandle.toFileHandle();
if ( _fileSystemMap.containsKey( theNewFileHandle ) ) {
throw new FileAlreadyExistsException( theNewFileHandle.toKey(), "The file with the key \"" + theNewFileHandle.toKey() + "\" already exist." );
}
final byte[] theBuffer = _fileSystemMap.remove( theFileHandle );
_fileSystemMap.put( theNewFileHandle, theBuffer );
return theNewFileHandle;
}
/**
* {@inheritDoc}
*/
@Override
public synchronized FileHandle moveFile( FileHandle aFileHandle, String aNewKey ) throws UnknownFileException, ConcurrentAccessException, FileAlreadyExistsException, NoCreateAccessException, NoDeleteAccessException, IllegalKeyException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
final MutableFileHandle theMutableNewFileHandle = theFileHandle.toMutableFileHandle();
theMutableNewFileHandle.setPath( FileSystemUtility.getPath( aNewKey ) );
theMutableNewFileHandle.setName( FileSystemUtility.getName( aNewKey ) );
final FileHandle theNewFileHandle = theMutableNewFileHandle.toFileHandle();
if ( _fileSystemMap.containsKey( theNewFileHandle ) ) {
throw new FileAlreadyExistsException( theNewFileHandle.toKey(), "The file with the key \"" + aFileHandle.toKey() + "\" already exist." );
}
final byte[] theBuffer = _fileSystemMap.remove( theFileHandle );
_fileSystemMap.put( theNewFileHandle, theBuffer );
return theNewFileHandle;
}
/**
* {@inheritDoc}
*/
@Override
public void deleteFile( FileHandle aFileHandle ) throws ConcurrentAccessException, UnknownFileException, NoDeleteAccessException, UnknownFileSystemException, IOException, NoListAccessException, IllegalFileException {
final FileHandle theFileHandle = toFileHandle( aFileHandle );
if ( theFileHandle == null ) {
throw new UnknownFileException( aFileHandle, "The file with the key \"" + aFileHandle.toKey() + "\" does not exist." );
}
_fileSystemMap.remove( theFileHandle );
}
/**
* {@inheritDoc}
*/
@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;
}
/**
* {@inheritDoc}
*/
@Override
public List getFileHandles( String aPath, boolean isRecursively ) throws NoListAccessException, UnknownPathException, IllegalPathException, UnknownFileSystemException, IOException {
final 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:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@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 - 2024 Weber Informatics LLC | Privacy Policy