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

org.refcodes.cryptography.alt.filesystem.impls.FileSystemEncryptionServerImpl Maven / Gradle / Ivy

The 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.cryptography.alt.filesystem.impls;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.List;

import org.refcodes.component.Component;
import org.refcodes.cryptography.CipherVersion;
import org.refcodes.cryptography.EncryptionServer;
import org.refcodes.cryptography.consts.CryptographyConsts;
import org.refcodes.cryptography.traps.CipherUidAlreadyInUseException;
import org.refcodes.exception.traps.HiddenException;
import org.refcodes.exception.utils.ExceptionUtility;
import org.refcodes.filesystem.FileHandle;
import org.refcodes.filesystem.FileSystem;
import org.refcodes.filesystem.traps.ConcurrentAccessException;
import org.refcodes.filesystem.traps.FileAlreadyExistsException;
import org.refcodes.filesystem.traps.IllegalFileHandleException;
import org.refcodes.filesystem.traps.IllegalNameException;
import org.refcodes.filesystem.traps.IllegalPathException;
import org.refcodes.filesystem.traps.NoCreateAccessException;
import org.refcodes.filesystem.traps.NoListAccessException;
import org.refcodes.filesystem.traps.NoWriteAccessException;
import org.refcodes.filesystem.traps.UnknownFileException;
import org.refcodes.filesystem.traps.UnknownFileSystemException;
import org.refcodes.filesystem.traps.UnknownPathException;
import org.refcodes.filesystem.utils.FileSystemUtility;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.factories.impls.RuntimeLoggerFactorySingleton;

/**
 * Abstract file system based implementation for non abstract
 * {@link EncryptionServer} implementations.
 */
public class FileSystemEncryptionServerImpl implements EncryptionServer, Component {

	private static RuntimeLogger LOGGER = RuntimeLoggerFactorySingleton.getInstance().createInstance();

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private FileSystem _fileSystem;
	private String _path;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTOR:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Constructs the server with the required services and configuration
	 * passed.
	 * 
	 * @param aFileSystem The data store service where to retrieve the
	 *        Cipher-Versions from
	 * 
	 * @param aDataStorePath The directory where the cryptography relevant data
	 *        is being persisted
	 */
	public FileSystemEncryptionServerImpl( FileSystem aFileSystem, String aDataStorePath ) {
		_fileSystem = aFileSystem;
		_path = FileSystemUtility.toNormalizedPath( aDataStorePath );
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	@Override
	public void addCipherVersion( String aNameSpace, CipherVersion aCipherVersion ) throws CipherUidAlreadyInUseException {

		String theNameSpaceKey = FileSystemUtility.toKey( _path, aNameSpace );
		LOGGER.debug( "Using file system key \"" + theNameSpaceKey + "\"." );

		OutputStream theOutputStream = null;
		ObjectOutputStream theObjectOutputStream = null;

		try {
			List theFileHandles = _fileSystem.getFileHandles( theNameSpaceKey, false );
			String eName, eCipherUid;
			for ( FileHandle eFile : theFileHandles ) {
				eName = eFile.getName();
				if ( eName.endsWith( CryptographyConsts.CIPHER_VERSION_FILE_SUFFIX ) ) {
					eCipherUid = eName.substring( 0, (eName.length() - CryptographyConsts.CIPHER_VERSION_FILE_SUFFIX.length()) );
					LOGGER.debug( "Found file \"" + eName + "\" containing Cipher-Version for cipher UID \"" + eCipherUid + "\"." );
					if ( eCipherUid.equals( aCipherVersion.getUniversalId() ) ) {
						throw new CipherUidAlreadyInUseException( aCipherVersion.getUniversalId(), "The cipher UID \"" + aCipherVersion.getUniversalId() + "\" is already in use by another Cipher-Version, aborting adding a new Cipher-Version! " );
					}
				}
			}

			FileHandle theFile = _fileSystem.createFile( theNameSpaceKey, aCipherVersion.getUniversalId() + CryptographyConsts.CIPHER_VERSION_FILE_SUFFIX );

			theOutputStream = new ByteArrayOutputStream();
			theObjectOutputStream = new ObjectOutputStream( theOutputStream );
			theObjectOutputStream.writeObject( aCipherVersion );
			theObjectOutputStream.flush();
			InputStream theInputStream = new ByteArrayInputStream( ((ByteArrayOutputStream) theOutputStream).toByteArray() );
			_fileSystem.toFile( theFile, theInputStream );
		}
		catch ( FileAlreadyExistsException e ) {
			throw new CipherUidAlreadyInUseException( aCipherVersion.getUniversalId(), "The cipher UID \"" + aCipherVersion.getUniversalId() + "\" is already in use by another Cipher-Version, aborting adding a new Cipher-Version: " + ExceptionUtility.toMessage( e ), e );
		}
		catch ( ConcurrentAccessException e ) {
			throw new CipherUidAlreadyInUseException( aCipherVersion.getUniversalId(), "The cipher UID \"" + aCipherVersion.getUniversalId() + "\" is already in use by another Cipher-Version, aborting adding a new Cipher-Version: " + ExceptionUtility.toMessage( e ), e );
		}
		catch ( IOException e ) {
			throw new HiddenException( e );
		}
		catch ( NoListAccessException e ) {
			throw new HiddenException( e );
		}
		catch ( UnknownPathException e ) {
			throw new HiddenException( e );
		}
		catch ( IllegalPathException e ) {
			throw new HiddenException( e );
		}
		catch ( IllegalFileHandleException e ) {
			throw new HiddenException( e );
		}
		catch ( UnknownFileSystemException e ) {
			throw new HiddenException( e );
		}
		catch ( NoCreateAccessException e ) {
			throw new HiddenException( e );
		}
		catch ( IllegalNameException e ) {
			throw new HiddenException( e );
		}
		catch ( NoWriteAccessException e ) {
			throw new HiddenException( e );
		}
		catch ( UnknownFileException e ) {
			throw new HiddenException( e );
		}
		finally {
			if ( theObjectOutputStream != null ) try {
				theObjectOutputStream.close();
			}
			catch ( IOException e ) {
				LOGGER.warn( "Unable to close output stream for file system path \"" + _path + "\" and name \"" + aCipherVersion.getUniversalId() + CryptographyConsts.CIPHER_VERSION_FILE_SUFFIX + "\"!" );
			}
			if ( theOutputStream != null ) try {
				theOutputStream.close();
			}
			catch ( IOException e ) {
				LOGGER.warn( "Unable to close object output stream for file system path \"" + _path + "\" and name \"" + aCipherVersion.getUniversalId() + CryptographyConsts.CIPHER_VERSION_FILE_SUFFIX + "\"!" );
			}
		}
	}

	// /////////////////////////////////////////////////////////////////////////
	// SERVICE:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void destroy() {
		FileSystem theFileSystem = _fileSystem;
		if ( theFileSystem != null ) {
			theFileSystem.destroy();
		}
		_fileSystem = null;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy