All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.filesystem.impls.InMemoryFileSystemImpl Maven / Gradle / Ivy

There is a newer version: 3.3.9
Show newest version
// /////////////////////////////////////////////////////////////////////////////
// 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