FileDocCategorySizeDatePackage
AbstractFileRepository.javaAPI DocApache James 2.3.112438Fri Jan 12 12:56:24 GMT 2007org.apache.james.mailrepository.filepair

AbstractFileRepository

public abstract class AbstractFileRepository extends org.apache.avalon.framework.logger.AbstractLogEnabled implements org.apache.avalon.framework.service.Serviceable, org.apache.avalon.cornerstone.services.store.Repository, org.apache.avalon.framework.activity.Initializable, org.apache.avalon.framework.context.Contextualizable, org.apache.avalon.framework.configuration.Configurable
This an abstract class implementing functionality for creating a file-store.

Fields Summary
protected static final boolean
DEBUG
protected static final String
HANDLED_URL
protected static final int
BYTE_MASK
protected static final char[]
HEX_DIGITS
protected String
m_path
protected String
m_destination
protected String
m_extension
protected String
m_name
protected FilenameFilter
m_filter
protected File
m_baseDirectory
protected org.apache.avalon.framework.service.ServiceManager
m_serviceManager
Constructors Summary
Methods Summary
public voidconfigure(org.apache.avalon.framework.configuration.Configuration configuration)

        if( null == m_destination )
        {
            final String destination = configuration.getAttribute( "destinationURL" );
            setDestination( destination );
        }
    
public synchronized booleancontainsKey(java.lang.String key)
Indicates if the given key is associated to a contained object.

        try
        {
            final File file = getFile( key );
            if( DEBUG ) getLogger().debug( "checking key " + key );
            return file.exists();
        }
        catch( final Exception e )
        {
            throw new RuntimeException( "Exception caught while searching " +
                                        "an object: " + e );
        }
    
public voidcontextualize(org.apache.avalon.framework.context.Context context)


       

            
    
        try
        {
            m_baseDirectory = (File) context.get( "urn:avalon:home" );
        }
        catch( ContextException ce )
        {
            m_baseDirectory = (File) context.get( "app.home" );
        }
    
protected org.apache.james.mailrepository.filepair.AbstractFileRepositorycreateChildRepository()

        return (AbstractFileRepository) getClass().newInstance();
    
protected java.lang.Stringdecode(java.lang.String filename)
Inverse of encode exept it do not use path. So decode(encode(s) - m_path) = s. In other words it returns a String that can be used as key to retive the record contained in the 'filename' file.

        filename = filename.substring( 0, filename.length() - m_extension.length() );
        final int size = filename.length();
        final byte[] bytes = new byte[ size >>> 1 ];

        for( int i = 0, j = 0; i < size; j++ )
        {
            bytes[ j ] = Byte.parseByte( filename.substring( i, i + 2 ), 16 );
            i +=2;
        }

        return new String( bytes );
    
protected java.lang.Stringencode(java.lang.String key)
Returns a String that uniquely identifies the object. Note: since this method uses the Object.toString() method, it's up to the caller to make sure that this method doesn't change between different JVM executions (like it may normally happen). For this reason, it's highly recommended (even if not mandated) that Strings be used as keys.

        final byte[] bytes = key.getBytes();
        final char[] buffer = new char[ bytes.length << 1 ];

        for( int i = 0, j = 0; i < bytes.length; i++ )
        {
            final int k = bytes[ i ];
            buffer[ j++ ] = HEX_DIGITS[ ( k >>> 4 ) & BYTE_MASK ];
            buffer[ j++ ] = HEX_DIGITS[ k & BYTE_MASK ];
        }

        StringBuffer result = new StringBuffer();
        result.append( m_path );
        result.append( File.separator );
        result.append( buffer );
        result.append( m_extension );
        return result.toString();
    
public org.apache.avalon.cornerstone.services.store.RepositorygetChildRepository(java.lang.String childName)

        AbstractFileRepository child = null;

        try
        {
            child = createChildRepository();
        }
        catch( final Exception e )
        {
            throw new RuntimeException( "Cannot create child repository " +
                                        childName + " : " + e );
        }

        try
        {
            child.service( m_serviceManager );
        }
        catch( final ServiceException cme )
        {
            throw new RuntimeException( "Cannot service child " +
                                        "repository " + childName +
                                        " : " + cme );
        }

        try
        {
            child.setDestination( m_destination + File.pathSeparatorChar +
                                  childName + File.pathSeparator );
        }
        catch( final ConfigurationException ce )
        {
            throw new RuntimeException( "Cannot set destination for child child " +
                                        "repository " + childName +
                                        " : " + ce );
        }

        try
        {
            child.initialize();
        }
        catch( final Exception e )
        {
            throw new RuntimeException( "Cannot initialize child " +
                                        "repository " + childName +
                                        " : " + e );
        }

        if( DEBUG )
        {
            getLogger().debug( "Child repository of " + m_name + " created in " +
                               m_destination + File.pathSeparatorChar +
                               childName + File.pathSeparator );
        }

        return child;
    
protected abstract java.lang.StringgetExtensionDecorator()

protected java.io.FilegetFile(java.lang.String key)

        return new File( encode( key ) );
    
protected java.io.InputStreamgetInputStream(java.lang.String key)

        return new FileInputStream( encode( key ) );
    
protected java.io.OutputStreamgetOutputStream(java.lang.String key)

        return new FileOutputStream( getFile( key ) );
    
public voidinitialize()

        getLogger().info( "Init " + getClass().getName() + " Store" );

        m_name = RepositoryManager.getName();
        String m_postfix = getExtensionDecorator();
        m_extension = "." + m_name + m_postfix;
        m_filter = new ExtensionFileFilter(m_extension);
        //m_filter = new NumberedRepositoryFileFilter(getExtensionDecorator());

        final File directory = new File( m_path );
        directory.mkdirs();

        getLogger().info( getClass().getName() + " opened in " + m_path );

        //We will look for all numbered repository files in this
        //  directory and rename them to non-numbered repositories,
        //  logging all the way.

        FilenameFilter num_filter = new NumberedRepositoryFileFilter(getExtensionDecorator());
        final String[] names = directory.list( num_filter );

        try {
            for( int i = 0; i < names.length; i++ ) {
                String origFilename = names[i];

                //This needs to handle (skip over) the possible repository numbers
                int pos = origFilename.length() - m_postfix.length();
                while (pos >= 1 && Character.isDigit(origFilename.charAt(pos - 1))) {
                    pos--;
                }
                pos -= ".".length() + m_name.length();
                String newFilename = origFilename.substring(0, pos) + m_extension;

                File origFile = new File(directory, origFilename);
                File newFile = new File(directory, newFilename);

                if (origFile.renameTo(newFile)) {
                    getLogger().info("Renamed " + origFile + " to " + newFile);
                } else {
                    getLogger().info("Unable to rename " + origFile + " to " + newFile);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

    
public java.util.Iteratorlist()
Returns the list of used keys.

        final File storeDir = new File( m_path );
        final String[] names = storeDir.list( m_filter );
        final ArrayList list = new ArrayList();

        for( int i = 0; i < names.length; i++ )
        {
            String decoded = decode(names[i]);
            list.add(decoded);
        }

        return list.iterator();
    
public synchronized voidremove(java.lang.String key)
Remove the object associated to the given key.

        try
        {
            final File file = getFile( key );
            file.delete();
            if( DEBUG ) getLogger().debug( "removed key " + key );
        }
        catch( final Exception e )
        {
            throw new RuntimeException( "Exception caught while removing" +
                                        " an object: " + e );
        }
    
public voidservice(org.apache.avalon.framework.service.ServiceManager serviceManager)

        m_serviceManager = serviceManager;
    
protected voidsetDestination(java.lang.String destination)

        if( !destination.startsWith( HANDLED_URL ) )
        {
            throw new ConfigurationException( "cannot handle destination " + destination );
        }

        m_path = destination.substring( HANDLED_URL.length() );

        File directory;

        // Check for absolute path
        if( m_path.startsWith( "/" ) )
        {
            directory = new File( m_path );
        }
        else
        {
            directory = new File( m_baseDirectory, m_path );
        }

        try
        {
            directory = directory.getCanonicalFile();
        }
        catch( final IOException ioe )
        {
            throw new ConfigurationException( "Unable to form canonical representation of " +
                                              directory );
        }

        m_path = directory.toString();

        m_destination = destination;