FileDocCategorySizeDatePackage
AvalonMailStore.javaAPI DocApache James 2.3.115828Fri Jan 12 12:56:22 GMT 2007org.apache.james.core

AvalonMailStore

public class AvalonMailStore extends org.apache.avalon.framework.logger.AbstractLogEnabled implements org.apache.avalon.framework.service.Serviceable, org.apache.avalon.framework.activity.Initializable, org.apache.avalon.framework.context.Contextualizable, org.apache.avalon.cornerstone.services.store.Store, org.apache.avalon.framework.configuration.Configurable
Provides a registry of mail repositories. A mail repository is uniquely identified by its destinationURL, type and model.

Fields Summary
private static final String
REPOSITORY_NAME
private static long
id
private Map
repositories
private Map
classes
private Map
defaultConfigs
protected org.apache.avalon.framework.context.Context
context
The Avalon context used by the instance
protected org.apache.avalon.framework.configuration.Configuration
configuration
The Avalon configuration used by the instance
protected org.apache.avalon.framework.service.ServiceManager
m_manager
The Avalon component manager used by the instance
Constructors Summary
Methods Summary
public voidconfigure(org.apache.avalon.framework.configuration.Configuration configuration)

see
org.apache.avalon.framework.configuration.Configurable#configure(Configuration)

        this.configuration = configuration;
    
public voidcontextualize(org.apache.avalon.framework.context.Context context)

see
org.apache.avalon.framework.context.Contextualizable#contextualize(Context)


           
        
              
        this.context = context;
    
private voidcopyConfig(org.apache.avalon.framework.configuration.Configuration fromConfig, org.apache.avalon.framework.configuration.DefaultConfiguration toConfig)
Copies values from one config into another, overwriting duplicate attributes and merging children.

param
fromConfig the Configuration to be copied
param
toConfig the Configuration to which data is being copied

        // Copy attributes
        String[] attrs = fromConfig.getAttributeNames();
        for ( int i = 0; i < attrs.length; i++ ) {
            String attrName = attrs[i];
            String attrValue = fromConfig.getAttribute(attrName, null);
            toConfig.setAttribute(attrName, attrValue);
        }

        // Copy children
        Configuration[] children = fromConfig.getChildren();
        for ( int i = 0; i < children.length; i++ ) {
            Configuration child = children[i];
            String childName = child.getName();
            Configuration existingChild = toConfig.getChild(childName, false);
            if ( existingChild == null ) {
                toConfig.addChild(child);
            }
            else {
                copyConfig(child, (DefaultConfiguration)existingChild);
            }
        }

        // Copy value
        String val = fromConfig.getValue(null);
        if ( val != null ) {
            toConfig.setValue(val);
        }
    
public static final java.lang.StringgetName()

Returns a new name for a repository.

Synchronized on the AvalonMailStore.class object to ensure against duplication of the repository name

return
a new repository name

        synchronized (AvalonMailStore.class) {
            return REPOSITORY_NAME + id++;
        }
    
public voidinitialize()

see
org.apache.avalon.framework.activity.Initializable#initialize()


        getLogger().info("JamesMailStore init...");
        repositories = new ReferenceMap();
        classes = new HashMap();
        defaultConfigs = new HashMap();
        Configuration[] registeredClasses
            = configuration.getChild("repositories").getChildren("repository");
        for ( int i = 0; i < registeredClasses.length; i++ )
        {
            registerRepository(registeredClasses[i]);
        }

    
public booleanisSelectable(java.lang.Object hint)
Returns whether the mail store has a repository corresponding to the passed in hint.

param
hint the Configuration object used to look up the repository
return
whether the mail store has a repository corresponding to this hint

        Object comp = null;
        try {
            comp = select(hint);
        } catch(ServiceException ex) {
            if (getLogger().isErrorEnabled()) {
                getLogger().error("Exception AvalonMailStore.hasComponent-" + ex.toString());
            }
        }
        return (comp != null);
    
public synchronized voidregisterRepository(org.apache.avalon.framework.configuration.Configuration repConf)

Registers a new mail repository type in the mail store's registry based upon a passed in Configuration object.

This is presumably synchronized to prevent corruption of the internal registry.

param
repConf the Configuration object used to register the repository
throws
ConfigurationException if an error occurs accessing the Configuration object

        String className = repConf.getAttribute("class");
        boolean infoEnabled = getLogger().isInfoEnabled();
        Configuration[] protocols
            = repConf.getChild("protocols").getChildren("protocol");
        Configuration[] types = repConf.getChild("types").getChildren("type");
        for ( int i = 0; i < protocols.length; i++ )
        {
            String protocol = protocols[i].getValue();

            // Get the default configuration for these protocol/type combinations.
            Configuration defConf = repConf.getChild("config");

            for ( int j = 0; j < types.length; j++ )
            {
                String type = types[j].getValue();
                String key = protocol + type ;
                if (infoEnabled) {
                    StringBuffer infoBuffer =
                        new StringBuffer(128)
                            .append("Registering Repository instance of class ")
                            .append(className)
                            .append(" to handle ")
                            .append(protocol)
                            .append(" protocol requests for repositories of type ")
                            .append(type);
                    getLogger().info(infoBuffer.toString());
                }
                if (classes.get(key) != null) {
                    throw new ConfigurationException("The combination of protocol and type comprise a unique key for repositories.  This constraint has been violated.  Please check your repository configuration.");
                }
                classes.put(key, className);
                if (defConf != null) {
                    defaultConfigs.put(key, defConf);
                }
            }
        }

    
public voidrelease(java.lang.Object component)
Return the Component when you are finished with it. In this implementation it does nothing

param
component The Component we are releasing.

public synchronized java.lang.Objectselect(java.lang.Object hint)
This method accept a Configuration object as hint and return the corresponding MailRepository. The Configuration must be in the form of: [addition configuration]

param
hint the Configuration object used to look up the repository
return
the selected repository
throws
ServiceException if any error occurs while parsing the Configuration or retrieving the MailRepository

        Configuration repConf = null;
        try {
            repConf = (Configuration) hint;
        } catch (ClassCastException cce) {
            throw new ServiceException("",
                "hint is of the wrong type. Must be a Configuration", cce);
        }
        String destination = null;
        String protocol = null;
        try {
            destination = repConf.getAttribute("destinationURL");
            int idx = destination.indexOf(':");
            if ( idx == -1 )
                throw new ServiceException("",
                    "destination is malformed. Must be a valid URL: "
                    + destination);
            protocol = destination.substring(0,idx);
        } catch (ConfigurationException ce) {
            throw new ServiceException("",
                "Malformed configuration has no destinationURL attribute", ce);
        }

        try
        {
            String type = repConf.getAttribute("type");
            String repID = destination + type;
            Object reply = repositories.get(repID);
            StringBuffer logBuffer = null;
            if (reply != null) {
                if (getLogger().isDebugEnabled()) {
                    logBuffer =
                        new StringBuffer(128)
                                .append("obtained repository: ")
                                .append(repID)
                                .append(",")
                                .append(reply.getClass());
                    getLogger().debug(logBuffer.toString());
                }
                return reply;
            } else {
                String key = protocol + type;
                String repClass = (String) classes.get( key );

                if (getLogger().isDebugEnabled()) {
                    logBuffer =
                        new StringBuffer(128)
                                .append("obtained repository: ")
                                .append(repClass)
                                .append(" to handle: ")
                                .append(protocol)
                                .append(",")
                                .append(type);
                    getLogger().debug( logBuffer.toString() );
                }

                // If default values have been set, create a new repository
                // configuration element using the default values
                // and the values in the selector.
                // If no default values, just use the selector.
                Configuration config;
                Configuration defConf = (Configuration)defaultConfigs.get(key);
                if ( defConf == null) {
                    config = repConf;
                }
                else {
                    config = new DefaultConfiguration(repConf.getName(),
                                                      repConf.getLocation());
                    copyConfig(defConf, (DefaultConfiguration)config);
                    copyConfig(repConf, (DefaultConfiguration)config);
                }

                try {
                    reply = this.getClass().getClassLoader().loadClass(repClass).newInstance();
                    if (reply instanceof LogEnabled) {
                       setupLogger(reply);
                    }
                    ContainerUtil.contextualize(reply,context);
                    ContainerUtil.service(reply,m_manager);

                    if (reply instanceof Composable) {
                        final String error = "no implementation in place to support Composable";
                        getLogger().error( error );
                        throw new IllegalArgumentException( error );
                    }
                    
                    ContainerUtil.configure(reply,config);
                    ContainerUtil.initialize(reply);

                    repositories.put(repID, reply);
                    if (getLogger().isInfoEnabled()) {
                        logBuffer =
                            new StringBuffer(128)
                                .append("added repository: ")
                                .append(repID)
                                .append("->")
                                .append(repClass);
                        getLogger().info(logBuffer.toString());
                    }
                    return reply;
                } catch (Exception e) {
                    if (getLogger().isWarnEnabled()) {
                        getLogger().warn( "Exception while creating repository:" +
                                          e.getMessage(), e );
                    }
                    throw new
                        ServiceException("", "Cannot find or init repository",
                                           e);
                }
            }
        } catch( final ConfigurationException ce ) {
            throw new ServiceException("", "Malformed configuration", ce );
        }
    
public voidservice(org.apache.avalon.framework.service.ServiceManager manager)

see
org.apache.avalon.framework.service.Servicable#service(ServiceManager)

        DefaultServiceManager def_manager = new DefaultServiceManager(manager);
        def_manager.put(Store.ROLE, this);
        m_manager = def_manager;