FileDocCategorySizeDatePackage
CommandListservManager.javaAPI DocApache James 2.3.116689Fri Jan 12 12:56:28 GMT 2007org.apache.james.transport.mailets

CommandListservManager

public class CommandListservManager extends org.apache.mailet.GenericMailet implements ICommandListservManager
CommandListservManager is the default implementation of {@link ICommandListservManager}. It loads all the configured {@link IListServCommand}s and delegates to them at runtime.
It isn't responsible for procesing messages sent to the main mailing list, but is responsible for individual commands sent by users, such as: info, subscribe, etc...
Requests sent to the CommandListservManager take the form of:
<listName>-<commandName>@domain
If the command isn't recognized an error will be sent using {@link #onError}.

The configuration for this mailet sould be in the 'root' processor block.
<mailet match="CommandListservMatcher=announce@localhost" class="CommandListservManager">
<listName>announce</listName>
<displayName>Announce mailing list</displayName>
<listOwner>owner@localhost</listOwner>
<repositoryName>list-announce</repositoryName>
<listDomain>localhost</listDomain>

<commandpackages>
<commandpackage>org.apache.james.transport.mailets.listservcommands</commandpackage>
</commandpackages>

<commands>
<command name="subscribe" class="Subscribe"/>
<command name="subscribe-confirm" class="SubscribeConfirm"/>
<command name="unsubscribe" class="UnSubscribe"/>
<command name="unsubscribe-confirm" class="UnSubscribeConfirm"/>
<command name="error" class="ErrorCommand"/>
<command name="owner" class="Owner"/>
<command name="info" class="Info"/>
</commands>
</mailet>


Todo: refine the command matching so we can have more sophistciated commands such as:
<listName>-<commandName>-<optCommandParam>@domain
version
CVS $Revision: 430699 $ $Date: 2006-08-11 09:02:35 +0200 (Fr, 11 Aug 2006) $
since
2.2.0

Fields Summary
protected Map
commandMap
protected List
commandPackages
protected org.apache.james.services.UsersRepository
usersRepository
protected String
listName
protected String
displayName
protected String
listOwner
protected String
listDomain
protected org.apache.james.util.XMLResources
xmlResources
Constructors Summary
Methods Summary
public org.apache.james.transport.mailets.listservcommands.IListServCommandgetCommand(java.lang.String name)
Get a specific command specified by the 'commands' configuration block. For instance:
<commands>
<command name="subscribe" class="Subscribe"/>
<command name="subscribe-confirm" class="SubscribeConfirm"/>
<command name="unsubscribe" class="UnSubscribe"/>
<command name="unsubscribe-confirm" class="UnSubscribeConfirm"/>
<command name="error" class="ErrorCommand"/>
<command name="owner" class="Owner"/>
<command name="info" class="Info"/>
</commands>

param
name case in-sensitive
return
a {@link IListServCommand} if found, null otherwise

        return (IListServCommand) commandMap.get(name.toLowerCase(Locale.US));
    
protected java.lang.StringgetCommandName(org.apache.mailet.MailAddress mailAddress)
Get the name of the command

param
mailAddress
return
the name of the command

        String user = mailAddress.getUser();
        int index = user.indexOf('-", listName.length());
        String commandName = user.substring(++index);
        return commandName;
    
public org.apache.james.transport.mailets.listservcommands.IListServCommandgetCommandTarget(org.apache.mailet.MailAddress mailAddress)
Based on the to address get a valid or command or null

param
mailAddress
return
IListServCommand or null

        String commandName = getCommandName(mailAddress);
        return getCommand(commandName);
    
public java.util.MapgetCommands()
Get all the available commands

return
a map of {@link IListServCommand}
see
#getCommand

        return commandMap;
    
protected static java.lang.ObjectgetField(java.lang.Object instance, java.lang.String name)
Retrieves a data field, potentially defined by a super class.

return
null if not found, the object otherwise

        Class clazz = instance.getClass();
        Field[] fields;
        while (clazz != null) {
            fields = clazz.getDeclaredFields();
            for (int index = 0; index < fields.length; index++) {
                Field field = fields[index];
                if (field.getName().equals(name)) {
                    field.setAccessible(true);
                    return field.get(instance);
                }
            }
            clazz = clazz.getSuperclass();
        }

        return null;
    
public java.lang.StringgetListDomain()
Get the domain of the list specified by the config param: 'listDomain'.
eg:
<listDomain>localhost</listDomain>

return
a string like localhost

        return listDomain;
    
public java.lang.StringgetListName(boolean displayFormat)
Get the name of this list specified by the config param: 'listName'.
eg:
<listName>announce</listName>

param
displayFormat is whether you want a display version of this or not
return
the official display name of this list


                                              
        
        return displayFormat ? displayName : listName;
    
public java.lang.StringgetListOwner()
Gets the owner of this list specified by the config param: 'listOwner'.
eg:
<listOwner>owner@localhost</listOwner>

return
this is an address like listOwner@localhost

        return listOwner;
    
public java.lang.StringgetResourcesFile()

return
the configuration file for the xml resources

        return getInitParameter("resources");
    
public java.util.PropertiesgetStandardProperties()
Use this to get standard properties for future calls to {@link org.apache.james.util.XMLResources}

return
properties with the "LIST_NAME" and the "DOMAIN_NAME" properties

        Properties standardProperties = new Properties();
        standardProperties.put("LIST_NAME", getListName(false));
        standardProperties.put("DISPLAY_NAME", getListName(true));
        standardProperties.put("DOMAIN_NAME", getListDomain());
        return standardProperties;
    
public org.apache.james.services.UsersRepositorygetUsersRepository()
Get the current user repository for this list serv

return
an instance of {@link UsersRepository} that is used for the member list of the list serv

        return usersRepository;
    
public voidinit()


        try {
            //Well, i want a more complex configuration structure
            //of my mailet, so i have to cheat... and cheat i will...
            Configuration configuration = (Configuration) getField(getMailetConfig(), "configuration");

            //get name
            listName = configuration.getChild("listName").getValue();
            displayName = configuration.getChild("displayName").getValue();
            listOwner = configuration.getChild("listOwner").getValue();
            listDomain = configuration.getChild("listDomain").getValue();

            //initialize resources
            initializeResources();

            //get users store
            initUsersRepository();

            //get command packages
            loadCommandPackages(configuration);

            //load commands
            loadCommands(configuration);

            //register w/context
            getMailetContext().setAttribute(ICommandListservManager.ID + listName, this);
        } catch (Exception e) {
            throw new MessagingException(e.getMessage(), e);
        }
    
protected voidinitUsersRepository()
Fetch the repository of users

        ServiceManager compMgr = (ServiceManager) getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
        try {
            UsersStore usersStore = (UsersStore) compMgr.lookup(UsersStore.ROLE);
            String repName = getInitParameter("repositoryName");

            usersRepository = usersStore.getRepository(repName);
        } catch (Exception e) {
            log("Failed to retrieve Store component:" + e.getMessage());
        }
    
public org.apache.james.util.XMLResources[]initXMLResources(java.lang.String[] names)
Initializes an array of resources

param
names such as 'header, footer' etc...
return
an initialized array of XMLResources
throws
ConfigurationException

        try {
            File xmlFile = new File(getResourcesFile());

            Properties props = getStandardProperties();
            String listName = props.getProperty("LIST_NAME");

            XMLResources[] xmlResources = new XMLResources[names.length];
            for (int index = 0; index < names.length; index++) {
                xmlResources[index] = new XMLResources();
                xmlResources[index].init(xmlFile, names[index], listName, props);
            }
            return xmlResources;
        } catch (Exception e) {
            log(e.getMessage(), e);
            throw new ConfigurationException("Can't initialize:", e);
        }
    
protected voidinitializeResources()
initialize the resources

throws
Exception

        xmlResources = initXMLResources(new String[]{"List Manager"})[0];
    
protected voidloadCommand(java.lang.String commandName, java.lang.String className, org.apache.avalon.framework.configuration.Configuration configuration)
Loads and initializes a single command

param
commandName
param
className
param
configuration
throws
ConfigurationException

        ClassLoader theClassLoader = getClass().getClassLoader();
        for (Iterator it = commandPackages.iterator(); it.hasNext();) {
            String packageName = (String) it.next();

            IListServCommand listServCommand = null;
            try {
                listServCommand = (IListServCommand) theClassLoader.loadClass(packageName + className).newInstance();
            } catch (Exception e) {
                //ignore
                continue;
            }
            listServCommand.init(this, configuration);
            commandMap.put(commandName, listServCommand);
            return;
        }

        throw new ConfigurationException("Unable to load listservcommand: " + commandName);
    
protected voidloadCommandPackages(org.apache.avalon.framework.configuration.Configuration configuration)
loads all of the packages for the commands

param
configuration
throws
ConfigurationException

        commandPackages.add("");
        final Configuration packageConfiguration = configuration.getChild("commandpackages");
        final Configuration[] pkgConfs = packageConfiguration.getChildren("commandpackage");
        for (int index = 0; index < pkgConfs.length; index++) {
            Configuration conf = pkgConfs[index];
            String packageName = conf.getValue().trim();
            if (!packageName.endsWith(".")) {
                packageName += ".";
            }
            commandPackages.add(packageName);
        }
    
protected voidloadCommands(org.apache.avalon.framework.configuration.Configuration configuration)
Load an initialize all of the available commands

param
configuration
throws
ConfigurationException

        final Configuration commandConfigurations = configuration.getChild("commands");
        final Configuration[] commandConfs = commandConfigurations.getChildren("command");
        for (int index = 0; index < commandConfs.length; index++) {
            Configuration commandConf = commandConfs[index];
            String commandName = commandConf.getAttribute("name").toLowerCase();
            String className = commandConf.getAttribute("class");
            loadCommand(commandName, className, commandConf);
        }
    
public voidonError(org.apache.mailet.Mail mail, java.lang.String subject, java.lang.String errorMessage)
An error occurred, send some sort of message

param
subject the subject of the message to send
param
mail
param
errorMessage

        ErrorCommand errorCommand = (ErrorCommand) getCommand("error");
        errorCommand.onError(mail, subject, errorMessage);
    
public voidservice(org.apache.mailet.Mail mail)

Called by the mailet container to allow the mailet to process a message.

This method is declared abstract so subclasses must override it.

param
mail - the Mail object that contains the MimeMessage and routing information
throws
MessagingException - if an exception occurs that interferes with the mailet's normal operation occurred

        if (mail.getRecipients().size() != 1) {
            getMailetContext().bounce(mail, "You can only send one command at a time to this listserv manager.");
            return;
        }
        MailAddress mailAddress = (MailAddress) mail.getRecipients().iterator().next();
        IListServCommand command = getCommandTarget(mailAddress);

        if (command == null) {
            //don't recognize the command
            Properties props = getStandardProperties();
            props.setProperty("COMMAND", getCommandName(mailAddress));
            onError(mail, "unknown command", xmlResources.getString("command.not.understood", props));
        } else {
            command.onCommand(mail);
        }

        // onError or onCommand would have done the job, so regardless
        // of which get rid of this e-mail.  This is something that we
        // should review, and decide if there is any reason to allow a
        // passthrough.
        mail.setState(Mail.GHOST);