You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2003/09/21 22:03:36 UTC

cvs commit: james-server/src/xdocs documentation_2_1.xml fetchpop_configuration_2_1.xml

noel        2003/09/21 13:03:36

  Modified:    src/java/org/apache/james/fetchmail Tag: branch_2_1_fcs
                        Account.java FetchMail.java FetchScheduler.java
                        FolderProcessor.java MessageProcessor.java
                        ParsedConfiguration.java ProcessorAbstract.java
                        ReaderInputStream.java StoreProcessor.java
               src/conf Tag: branch_2_1_fcs james-config.xml
                        james-fetchmail.xml
               src/xdocs Tag: branch_2_1_fcs documentation_2_1.xml
                        fetchpop_configuration_2_1.xml
  Log:
  FetchMail update from Steve Brewin
  
  Documentation and Samples
  - xdocs
      * now include fetchmail_configuration_2_2.xml
      * documentation_2_1.xml updated to include the above
      * fetchpop_configuration_2_1.xml includes text indicating it is
        deprecated and fetchmail is prefered
  - conf
      * now has a sub-directory 'samples' that has a sub-directory
        'fetchmail' containing the samples described in the xdocs
  
  2) Added features.
  - When the intended recipient cannot be determined by an Account processing
    can optionally be deferred to the next pass, giving other Accounts within
    the fetch task the oppurtunity to resolve the recipient.
  
  3) Improved features.
  - DynamicAccounts are now preserved between passes, enabling communication
    of state and variables such as the List of deferred messages required by the
    defer processing described above.
  
  - Sundry refactorings and tidying up. The major refactoring is that Account
    objects replace ParsedConfiguration as primary source of the context for
    fetchmail delegate classes.
  
  - Within the docs and config have highlighted the fact that the POP3
    protocol does not mandate the SEEN flag, therefore the markSeen attribute
    may not stick when fetching from a POP3 server. Have also refactored the
    code to include handler methods for when JavaMail considers the server to
    have a non-permanent SEEN flag. The default handlers behave as normal when a
    non-permanent flag is tested and log warnings when a non-permanent flag is
    set, subclasses may choose to extend this behaviour, maybe to add SEEN
    support when the server doesn't have it?
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.1.2.2   +92 -0     james-server/src/java/org/apache/james/fetchmail/Attic/Account.java
  
  Index: Account.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/Account.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- Account.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ Account.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -58,6 +58,8 @@
    
   package org.apache.james.fetchmail;
   
  +import java.util.ArrayList;
  +import java.util.List;
   import javax.mail.internet.ParseException;
   
   import org.apache.avalon.framework.configuration.ConfigurationException;
  @@ -87,6 +89,17 @@
        * The user name for this account
        */
       private String fieldUser;
  +
  +    /**
  +     * The ParsedConfiguration
  +     */    
  +    private ParsedConfiguration fieldParsedConfiguration;
  +    
  +    /**
  +     * List of MessageIDs for which processing has been deferred
  +     * because the intended recipient could not be found.
  +     */
  +    private List fieldDeferredRecipientNotFoundMessageIDs;    
       
       /**
        * The sequence number for this account
  @@ -110,6 +123,7 @@
        * Constructor for Account.
        * 
        * @param sequenceNumber
  +     * @param parsedConfiguration
        * @param user
        * @param password
        * @param recipient
  @@ -119,6 +133,7 @@
       
       public Account(
           int sequenceNumber,
  +        ParsedConfiguration parsedConfiguration,
           String user,
           String password,
           String recipient,
  @@ -127,6 +142,7 @@
       {
           this();
           setSequenceNumber(sequenceNumber);
  +        setParsedConfiguration(parsedConfiguration);
           setUser(user);
           setPassword(password);
           setRecipient(recipient);
  @@ -184,6 +200,12 @@
        */
       protected void setRecipient(String recipient) throws ConfigurationException
       {
  +        if (null == recipient)
  +        {
  +            fieldRecipient = null;
  +            return;
  +        }
  +            
           try
           {
               setRecipient(new MailAddress(recipient));
  @@ -253,6 +275,76 @@
       public int compareTo(Object o)
       {
           return getSequenceNumber() - ((Account) o).getSequenceNumber();
  +    }
  +
  +    /**
  +     * Returns the deferredRecipientNotFoundMessageIDs. lazily initialised.
  +     * @return List
  +     */
  +    public List getDeferredRecipientNotFoundMessageIDs()
  +    {
  +        List messageIDs = null;
  +        if (null
  +            == (messageIDs = getDeferredRecipientNotFoundMessageIDsBasic()))
  +        {
  +            updateDeferredRecipientNotFoundMessageIDs();
  +            return getDeferredRecipientNotFoundMessageIDs();
  +        }
  +        return messageIDs;
  +    }
  +
  +    /**
  +     * Returns the deferredRecipientNotFoundMessageIDs.
  +     * @return List
  +     */
  +    private List getDeferredRecipientNotFoundMessageIDsBasic()
  +    {
  +        return fieldDeferredRecipientNotFoundMessageIDs;
  +    }
  +    
  +    /**
  +     * Returns a new List of deferredRecipientNotFoundMessageIDs.
  +     * @return List
  +     */
  +    protected List computeDeferredRecipientNotFoundMessageIDs()
  +    {
  +        return new ArrayList(16);
  +    }    
  +    
  +    /**
  +     * Updates the deferredRecipientNotFoundMessageIDs.
  +     */
  +    protected void updateDeferredRecipientNotFoundMessageIDs()
  +    {
  +        setDeferredRecipientNotFoundMessageIDs(computeDeferredRecipientNotFoundMessageIDs());
  +    }    
  +
  +    /**
  +     * Sets the defferedRecipientNotFoundMessageIDs.
  +     * @param defferedRecipientNotFoundMessageIDs The defferedRecipientNotFoundMessageIDs to set
  +     */
  +    protected void setDeferredRecipientNotFoundMessageIDs(List defferedRecipientNotFoundMessageIDs)
  +    {
  +        fieldDeferredRecipientNotFoundMessageIDs =
  +            defferedRecipientNotFoundMessageIDs;
  +    }
  +
  +    /**
  +     * Returns the parsedConfiguration.
  +     * @return ParsedConfiguration
  +     */
  +    public ParsedConfiguration getParsedConfiguration()
  +    {
  +        return fieldParsedConfiguration;
  +    }
  +
  +    /**
  +     * Sets the parsedConfiguration.
  +     * @param parsedConfiguration The parsedConfiguration to set
  +     */
  +    protected void setParsedConfiguration(ParsedConfiguration parsedConfiguration)
  +    {
  +        fieldParsedConfiguration = parsedConfiguration;
       }
   
   }
  
  
  
  1.9.2.2   +215 -83   james-server/src/java/org/apache/james/fetchmail/FetchMail.java
  
  Index: FetchMail.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/FetchMail.java,v
  retrieving revision 1.9.2.1
  retrieving revision 1.9.2.2
  diff -u -r1.9.2.1 -r1.9.2.2
  --- FetchMail.java	30 Aug 2003 18:52:18 -0000	1.9.2.1
  +++ FetchMail.java	21 Sep 2003 20:03:35 -0000	1.9.2.2
  @@ -59,8 +59,10 @@
   
   import java.util.ArrayList;
   import java.util.Collections;
  +import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
  +import java.util.Map;
   
   import javax.mail.MessagingException;
   
  @@ -107,6 +109,104 @@
   public class FetchMail extends AbstractLogEnabled implements Configurable, Target
   {
       /**
  +     * Enter description here
  +     * 
  +     * Creation Date: 29-Aug-03
  +     * @author sbrewin
  +     * 
  +     * Copyright 2003, Synergy Systems Limited
  +     */
  +    private class DynamicAccountKey
  +    {
  +        /**
  +         * The base user name without prfix or suffix
  +         */
  +        private String fieldUserName;
  +        
  +        /**
  +         * The sequence number of the parameters used to construct the Account
  +         */
  +        private int fieldSequenceNumber;                
  +
  +        /**
  +         * Constructor for DynamicAccountKey.
  +         */
  +        private DynamicAccountKey()
  +        {
  +            super();
  +        }
  +        
  +        /**
  +         * Constructor for DynamicAccountKey.
  +         */
  +        public DynamicAccountKey(String userName, int sequenceNumber)
  +        {
  +            this();
  +            setUserName(userName);
  +            setSequenceNumber(sequenceNumber);
  +        }        
  +
  +        /**
  +         * @see java.lang.Object#equals(Object)
  +         */
  +        public boolean equals(Object obj)
  +        {
  +            if (null == obj)
  +                return false;
  +            if (!(obj.getClass() == getClass()))
  +                return false;
  +            return (
  +                getUserName().equals(((DynamicAccountKey) obj).getUserName())
  +                    && getSequenceNumber()
  +                        == ((DynamicAccountKey) obj).getSequenceNumber());
  +        }
  +
  +        /**
  +         * @see java.lang.Object#hashCode()
  +         */
  +        public int hashCode()
  +        {
  +            return getUserName().hashCode() ^ getSequenceNumber();
  +        }
  +
  +        /**
  +         * Returns the sequenceNumber.
  +         * @return int
  +         */
  +        public int getSequenceNumber()
  +        {
  +            return fieldSequenceNumber;
  +        }
  +
  +        /**
  +         * Returns the userName.
  +         * @return String
  +         */
  +        public String getUserName()
  +        {
  +            return fieldUserName;
  +        }
  +
  +        /**
  +         * Sets the sequenceNumber.
  +         * @param sequenceNumber The sequenceNumber to set
  +         */
  +        protected void setSequenceNumber(int sequenceNumber)
  +        {
  +            fieldSequenceNumber = sequenceNumber;
  +        }
  +
  +        /**
  +         * Sets the userName.
  +         * @param userName The userName to set
  +         */
  +        protected void setUserName(String userName)
  +        {
  +            fieldUserName = userName;
  +        }
  +
  +    }
  +    /**
        * Creation Date: 06-Jun-03
        */
       private class ParsedDynamicAccountParameters
  @@ -300,9 +400,9 @@
       
       /**
        * The Dynamic Accounts for this task.
  -     * These are setup each time the is run.
  +     * These are setup each time the fetchtask is run.
        */
  -    private List fieldDynamicAccounts;        
  +    private Map fieldDynamicAccounts;        
       
      /**
        * The MailServer service
  @@ -333,6 +433,13 @@
       public void configure(Configuration configuration)
           throws ConfigurationException
       {
  +        ParsedConfiguration parsedConfiguration =
  +            new ParsedConfiguration(
  +                configuration,
  +                getLogger(),
  +                getServer(),
  +                getLocalUsers());
  +        setConfiguration(parsedConfiguration);
   
           Configuration[] allAccounts = configuration.getChildren("accounts");
           if (allAccounts.length < 1)
  @@ -366,6 +473,7 @@
                   getStaticAccounts().add(
                       new Account(
                           i,
  +                        parsedConfiguration,
                           accountsChild.getAttribute("user"),
                           accountsChild.getAttribute("password"),
                           accountsChild.getAttribute("recipient"),
  @@ -379,13 +487,6 @@
                       + accountsChild.getName()
                       + "> in <accounts>");
           }
  -
  -        setConfiguration(
  -            new ParsedConfiguration(
  -                configuration,
  -                getLogger(),
  -                getServer(),
  -                getLocalUsers()));
       }
   
       /**
  @@ -403,55 +504,49 @@
           try
           {
               setFetching(true);
  -            getLogger().info(
  -                getConfiguration().getFetchTaskName()
  -                    + " fetcher starting fetches");
  +            getLogger().info("Fetcher starting fetches");
   
  -            // Reset and get the dynamic accounts,
  +            // Update the dynamic accounts,
               // merge with the static accounts and
               // sort the accounts so they are in the order
               // they were entered in config.xml
  -            resetDynamicAccounts();
  +            updateDynamicAccounts();
               ArrayList mergedAccounts =
                   new ArrayList(
                       getDynamicAccounts().size() + getStaticAccounts().size());
  -            mergedAccounts.addAll(getDynamicAccounts());
  +            mergedAccounts.addAll(getDynamicAccounts().values());
               mergedAccounts.addAll(getStaticAccounts());
               Collections.sort(mergedAccounts);
  -
  +            
  +            StringBuffer logMessage = new StringBuffer(64);
  +            logMessage.append("Processing ");
  +            logMessage.append(getStaticAccounts().size());
  +            logMessage.append(" static accounts and ");
  +            logMessage.append(getDynamicAccounts().size());
  +            logMessage.append(" dynamic accounts.");
  +            getLogger().info(logMessage.toString());            
  +            
               // Fetch each account
               Iterator accounts = mergedAccounts.iterator();
               while (accounts.hasNext())
               {
  -                Account account = (Account) accounts.next();
  -                ParsedConfiguration configuration = getConfiguration();
  -                configuration.setUser(account.getUser());
  -                configuration.setPassword(account.getPassword());
  -                configuration.setRecipient(account.getRecipient());
  -                configuration.setIgnoreRecipientHeader(
  -                    account.isIgnoreRecipientHeader());
                   try
                   {
  -                    new StoreProcessor(configuration).process();
  +                    new StoreProcessor((Account) accounts.next()).process();
                   }
                   catch (MessagingException ex)
                   {
  -                    getLogger().debug(ex.toString());
  +                    getLogger().error(ex.toString());
                   }
               }
           }
  -        catch (ConfigurationException ex)
  +        catch (Exception ex)
           {
               getLogger().error(ex.toString());
           }
           finally
           {
  -            // Ensure the dynamic accounts are thrown away
  -            resetDynamicAccounts();
  -
  -            getLogger().info(
  -                getConfiguration().getFetchTaskName()
  -                    + " fetcher completed fetches");
  +            getLogger().info("Fetcher completed fetches");
   
               // Exit Fetching State
               setFetching(false);
  @@ -604,11 +699,11 @@
       }
       
       /**
  -     * Updates the allLocalParameters.
  +     * Updates the ParsedDynamicAccountParameters.
        */
  -    protected void updateAllLocalParameters()
  +    protected void updateParsedDynamicAccountParameters()
       {
  -        setParsedDynamicAccountParameters(computeAllLocalParameters());
  +        setParsedDynamicAccountParameters(computeParsedDynamicAccountParameters());
       }   
       
       /**
  @@ -628,9 +723,9 @@
       }
       
       /**
  -     * Computes the allLocalParameters.
  +     * Computes the ParsedDynamicAccountParameters.
        */
  -    protected List computeAllLocalParameters()
  +    protected List computeParsedDynamicAccountParameters()
       {
           return new ArrayList();
       }   
  @@ -638,52 +733,48 @@
       /**
        * Computes the dynamicAccounts.
        */
  -    protected List computeDynamicAccounts() throws ConfigurationException
  +    protected Map computeDynamicAccounts() throws ConfigurationException
       {
  -        List accounts = new ArrayList(32);
  -        Iterator parameterIterator = getParsedDynamicAccountParameters().iterator();
  -        
  +        Map newAccounts =
  +            new HashMap(
  +                getLocalUsers().countUsers()
  +                    * getParsedDynamicAccountParameters().size());
  +        Map oldAccounts = getDynamicAccountsBasic();
  +        if (null == oldAccounts)
  +            oldAccounts = new HashMap(0);
  +
  +        Iterator parameterIterator =
  +            getParsedDynamicAccountParameters().iterator();
  +
           // Process each ParsedDynamicParameters
           while (parameterIterator.hasNext())
           {
  -            ParsedDynamicAccountParameters parameters =
  -                (ParsedDynamicAccountParameters) parameterIterator.next();
  -            // Create an Account for each local user
  -            Iterator usersIterator = getLocalUsers().list();
  -            while (usersIterator.hasNext())
  +            Map accounts =
  +                computeDynamicAccounts(
  +                    oldAccounts,
  +                    (ParsedDynamicAccountParameters) parameterIterator.next());
  +            // Remove accounts from oldAccounts.
  +            // This avoids an average 2*N increase in heapspace used as the 
  +            // newAccounts are created. 
  +            Iterator oldAccountsIterator = oldAccounts.keySet().iterator();
  +            while (oldAccountsIterator.hasNext())
               {
  -                String userName = (String) usersIterator.next();
  -                StringBuffer userBuffer =
  -                    new StringBuffer(parameters.getUserPrefix());
  -                userBuffer.append(userName);
  -                userBuffer.append(parameters.getUserSuffix());
  -                String user = userBuffer.toString();
  -
  -                StringBuffer recipientBuffer =
  -                    new StringBuffer(parameters.getRecipientPrefix());
  -                recipientBuffer.append(userName);
  -                recipientBuffer.append(parameters.getRecipientSuffix());
  -                String recipient = recipientBuffer.toString();
  -
  -                accounts.add(
  -                    new Account(
  -                        parameters.getSequenceNumber(),
  -                        user,
  -                        parameters.getPassword(),
  -                        recipient,
  -                        parameters.isIgnoreRecipientHeader()));
  +                if (accounts.containsKey(oldAccountsIterator.next()))
  +                    oldAccountsIterator.remove();
               }
  +            // Add this parameter's accounts to newAccounts
  +            newAccounts.putAll(accounts);
           }
  -        return accounts;
  -    }   
  +        return newAccounts;
  +    }
       
       /**
        * Returns the dynamicAccounts. Initializes if required.
  -     * @return List
  +     * @return Map
        */
  -    protected List getDynamicAccounts() throws ConfigurationException
  +    protected Map getDynamicAccounts() throws ConfigurationException
       {
  -        List accounts = null;
  +        Map accounts = null;
           if (null == (accounts = getDynamicAccountsBasic()))
           {
               updateDynamicAccounts();
  @@ -694,9 +785,9 @@
       
       /**
        * Returns the dynamicAccounts.
  -     * @return List
  +     * @return Map
        */
  -    private List getDynamicAccountsBasic()
  +    private Map getDynamicAccountsBasic()
       {
           return fieldDynamicAccounts;
       }   
  @@ -705,12 +796,53 @@
        * Sets the dynamicAccounts.
        * @param dynamicAccounts The dynamicAccounts to set
        */
  -    protected void setDynamicAccounts(List dynamicAccounts)
  +    protected void setDynamicAccounts(Map dynamicAccounts)
       {
           fieldDynamicAccounts = dynamicAccounts;
       }
       
       /**
  +     * Compute the dynamicAccounts for the passed parameters.
  +     * Accounts for existing users are copied and accounts for new users are 
  +     * created.
  +     * @param oldAccounts
  +     * @param parameters
  +     * @return Map - The current Accounts
  +     * @throws ConfigurationException
  +     */
  +    protected Map computeDynamicAccounts(
  +        Map oldAccounts,
  +        ParsedDynamicAccountParameters parameters)
  +        throws ConfigurationException
  +    {
  +        Map accounts = new HashMap(getLocalUsers().countUsers());
  +        Iterator usersIterator = getLocalUsers().list();
  +        while (usersIterator.hasNext())
  +        {
  +            String userName = (String) usersIterator.next();
  +            DynamicAccountKey key =
  +                new DynamicAccountKey(userName, parameters.getSequenceNumber());
  +            Account account = (Account) oldAccounts.get(key);
  +            if (null == account)
  +            {
  +                // Create a new DynamicAccount
  +                account =
  +                    new DynamicAccount(
  +                        parameters.getSequenceNumber(),
  +                        getConfiguration(),
  +                        userName,
  +                        parameters.getUserPrefix(),
  +                        parameters.getUserSuffix(),
  +                        parameters.getPassword(),
  +                        parameters.getRecipientPrefix(),
  +                        parameters.getRecipientSuffix(),
  +                        parameters.isIgnoreRecipientHeader());
  +            }
  +            accounts.put(key, account);
  +        }
  +        return accounts;
  +    }
  +    /**
        * Resets the dynamicAccounts.
        */
       protected void resetDynamicAccounts()
  @@ -719,36 +851,36 @@
       }   
   
       /**
  -     * Returns the allLocalParameters.
  +     * Returns the ParsedDynamicAccountParameters.
        * @return List
        */
       protected List getParsedDynamicAccountParameters()
       {
           List accounts = null;
  -        if (null == (accounts = getAllLocalParametersBasic()))
  +        if (null == (accounts = getParsedDynamicAccountParametersBasic()))
           {
  -            updateAllLocalParameters();
  +            updateParsedDynamicAccountParameters();
               return getParsedDynamicAccountParameters();
           }   
           return fieldParsedDynamicAccountParameters;
       }
       
       /**
  -     * Returns the allLocalParameters.
  +     * Returns the ParsedDynamicAccountParameters.
        * @return List
        */
  -    private List getAllLocalParametersBasic()
  +    private List getParsedDynamicAccountParametersBasic()
       {
           return fieldParsedDynamicAccountParameters;
       }   
   
       /**
  -     * Sets the allLocalParameters.
  -     * @param allLocalParameters The allLocalParameters to set
  +     * Sets the ParsedDynamicAccountParameters.
  +     * @param ParsedDynamicAccountParameters The ParsedDynamicAccountParametersto set
        */
  -    protected void setParsedDynamicAccountParameters(List allLocalParameters)
  +    protected void setParsedDynamicAccountParameters(List parsedDynamicAccountParameters)
       {
  -        fieldParsedDynamicAccountParameters = allLocalParameters;
  +        fieldParsedDynamicAccountParameters = parsedDynamicAccountParameters;
       }
   
   }
  
  
  
  1.8.2.2   +1 -59     james-server/src/java/org/apache/james/fetchmail/FetchScheduler.java
  
  Index: FetchScheduler.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/FetchScheduler.java,v
  retrieving revision 1.8.2.1
  retrieving revision 1.8.2.2
  diff -u -r1.8.2.1 -r1.8.2.2
  --- FetchScheduler.java	30 Aug 2003 18:52:18 -0000	1.8.2.1
  +++ FetchScheduler.java	21 Sep 2003 20:03:35 -0000	1.8.2.2
  @@ -55,64 +55,6 @@
    * originally written at the National Center for Supercomputing Applications,
    * University of Illinois, Urbana-Champaign.
    */
  -
  -/* ====================================================================
  - * The Apache Software License, Version 1.1
  - *
  - * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
  - * reserved.
  - *
  - * Redistribution and use in source and binary forms, with or without
  - * modification, are permitted provided that the following conditions
  - * are met:
  - *
  - * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer.
  - *
  - * 2. Redistributions in binary form must reproduce the above copyright
  - *    notice, this list of conditions and the following disclaimer in
  - *    the documentation and/or other materials provided with the
  - *    distribution.
  - *
  - * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:
  - *       "This product includes software developed by the
  - *        Apache Software Foundation (http://www.apache.org/)."
  - *    Alternately, this acknowledgment may appear in the software itself,
  - *    if and wherever such third-party acknowledgments normally appear.
  - *
  - * 4. The names "Apache", "Jakarta", "JAMES" and "Apache Software Foundation"
  - *    must not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written
  - *    permission, please contact apache@apache.org.
  - *
  - * 5. Products derived from this software may not be called "Apache",
  - *    nor may "Apache" appear in their name, without prior written
  - *    permission of the Apache Software Foundation.
  - *
  - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  - * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  - * SUCH DAMAGE.
  - * ====================================================================
  - *
  - * This software consists of voluntary contributions made by many
  - * individuals on behalf of the Apache Software Foundation.  For more
  - * information on the Apache Software Foundation, please see
  - * <http://www.apache.org/>.
  - *
  - * Portions of this software are based upon public domain software
  - * originally written at the National Center for Supercomputing Applications,
  - * University of Illinois, Urbana-Champaign.
  - */
    
   package org.apache.james.fetchmail;
   
  
  
  
  1.1.2.2   +109 -10   james-server/src/java/org/apache/james/fetchmail/Attic/FolderProcessor.java
  
  Index: FolderProcessor.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/FolderProcessor.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- FolderProcessor.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ FolderProcessor.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -81,15 +81,17 @@
        * The fetched folder
        */ 
       private Folder fieldFolder;
  +    
  +    private Boolean fieldMarkSeenPermanent;
   
       /**
        * Constructor for FolderProcessor.
        * @param folder The folder to be fetched
  -     * @param configuration The configuration parameters
  +     * @param account The account being processed
        */
  -    protected FolderProcessor(Folder folder, ParsedConfiguration configuration)
  +    protected FolderProcessor(Folder folder, Account account)
       {
  -        super(configuration);
  +        super(account);
           setFolder(folder);
       }
       
  @@ -129,13 +131,25 @@
               // Process each message
               for (int i = 0; i < messagesIn.length; i++)
               {
  -                if (isFetchAll() || !messagesIn[i].isSet(Flags.Flag.SEEN))
  +                MimeMessage message = (MimeMessage) messagesIn[i];
  +                if (isFetchAll() || !isSeen(message))
                   {
  -                    new MessageProcessor(
  -                        (MimeMessage) messagesIn[i],
  -                        getConfiguration())
  -                        .process();
  -                    messagesProcessed++;
  +                    try
  +                    {
  +                        new MessageProcessor(message, getAccount()).process();
  +                        messagesProcessed++;
  +                    }
  +                    // Catch and report an exception but don't rethrow it, 
  +                    // allowing subsequent messages to be processed.                    
  +                    catch (MessagingException mex)
  +                    {
  +                        StringBuffer logMessageBuffer =
  +                            new StringBuffer("Exception processing message ID: ");
  +                        logMessageBuffer.append(message.getMessageID());
  +                        logMessageBuffer.append(" - ");
  +                        logMessageBuffer.append(mex.toString());
  +                        getLogger().error(logMessageBuffer.toString());
  +                    }
                   }
               }
           }
  @@ -200,7 +214,7 @@
   
               for (int i = 0; i < folders.length; i++)
               {
  -                new FolderProcessor(folders[i], getConfiguration()).process();
  +                new FolderProcessor(folders[i], getAccount()).process();
               }
   
           }
  @@ -228,6 +242,50 @@
       {
           return fieldFolder;
       }
  +    
  +    /**
  +     * Answer if <code>aMessage</code> has been SEEN.
  +     * @param aMessage
  +     * @return boolean
  +     * @throws MessagingException
  +     */
  +    protected boolean isSeen(MimeMessage aMessage) throws MessagingException
  +    {
  +        boolean isSeen = false;
  +        if (isMarkSeenPermanent().booleanValue())
  +            isSeen = aMessage.isSet(Flags.Flag.SEEN);
  +        else
  +            isSeen = handleMarkSeenNotPermanent(aMessage);
  +        return isSeen;
  +    }
  +
  +    /**
  +     * Answer the result of computing markSeenPermanent.
  +     * @return Boolean
  +     */
  +    protected Boolean computeMarkSeenPermanent()
  +    {
  +        return new Boolean(
  +            getFolder().getPermanentFlags().contains(Flags.Flag.SEEN));
  +    }
  +
  +    /**
  +     * <p>Handler for when the folder does not support the SEEN flag.
  +     * The default behaviour implemented here is to answer the value of the
  +     * SEEN flag anyway.</p>
  +     * 
  +     * <p>Subclasses may choose to override this method and implement their own
  +     *  solutions.</p>
  +     *
  +     * @param aMessage
  +     * @return boolean 
  +     * @throws MessagingException
  +     */
  +    protected boolean handleMarkSeenNotPermanent(MimeMessage aMessage)
  +        throws MessagingException
  +    {
  +        return aMessage.isSet(Flags.Flag.SEEN);
  +    }    
   
       /**
        * Sets the folder.
  @@ -238,4 +296,45 @@
           fieldFolder = folder;
       }
       
  +    /**
  +     * Returns the isMarkSeenPermanent.
  +     * @return Boolean
  +     */
  +    protected Boolean isMarkSeenPermanent()
  +    {
  +        Boolean markSeenPermanent = null;
  +        if (null == (markSeenPermanent = isMarkSeenPermanentBasic()))
  +        {
  +            updateMarkSeenPermanent();
  +            return isMarkSeenPermanent();
  +        }    
  +        return markSeenPermanent;
  +    }
  +    
  +    /**
  +     * Returns the markSeenPermanent.
  +     * @return Boolean
  +     */
  +    private Boolean isMarkSeenPermanentBasic()
  +    {
  +        return fieldMarkSeenPermanent;
  +    }    
  +
  +    /**
  +     * Sets the markSeenPermanent.
  +     * @param markSeenPermanent The isMarkSeenPermanent to set
  +     */
  +    protected void setMarkSeenPermanent(Boolean markSeenPermanent)
  +    {
  +        fieldMarkSeenPermanent = markSeenPermanent;
  +    }
  +    
  +    /**
  +     * Updates the markSeenPermanent.
  +     */
  +    protected void updateMarkSeenPermanent()
  +    {
  +        setMarkSeenPermanent(computeMarkSeenPermanent());
  +    }    
  +
   }
  
  
  
  1.1.2.2   +117 -31   james-server/src/java/org/apache/james/fetchmail/Attic/MessageProcessor.java
  
  Index: MessageProcessor.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/MessageProcessor.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- MessageProcessor.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ MessageProcessor.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -200,23 +200,25 @@
       /**
        * Constructor for MessageProcessor.
        * 
  -     * @param configuration
  +     * @param account
        */
  -    private MessageProcessor(ParsedConfiguration configuration)
  +    private MessageProcessor(Account account)
       {
  -        super(configuration);
  +        super(account);
       }
       
       /**
        * Constructor for MessageProcessor.
        * 
        * @param messageIn
  -     * @param configuration
  +     * @param account
        */
   
  -    MessageProcessor(MimeMessage messageIn, ParsedConfiguration configuration)
  +    MessageProcessor(
  +        MimeMessage messageIn,
  +         Account account)
       {
  -        this(configuration);
  +        this(account);
           setMessageIn(messageIn);
       }   
   
  @@ -227,7 +229,7 @@
        * @see org.apache.james.fetchmail.ProcessorAbstract#process()
        */
       public void process() throws MessagingException
  -    {
  +    {      
           // Log delivery attempt
           StringBuffer logMessageBuffer =
               new StringBuffer("Attempting delivery of message with id. ");
  @@ -240,6 +242,31 @@
   
           if (isRecipientNotFound())
           {
  +            if (isDeferRecipientNotFound())
  +            {
  +
  +                String messageID = getMessageIn().getMessageID();
  +                if (!getDeferredRecipientNotFoundMessageIDs()
  +                    .contains(messageID))
  +                {
  +                    getDeferredRecipientNotFoundMessageIDs().add(messageID);
  +                    StringBuffer messageBuffer =
  +                        new StringBuffer("Deferred processing of message for which the intended recipient could not be found. Message ID: ");
  +                    messageBuffer.append(messageID);
  +                    getLogger().info(messageBuffer.toString());
  +                    return;
  +
  +                }
  +                else
  +                {
  +                    getDeferredRecipientNotFoundMessageIDs().remove(messageID);
  +                    StringBuffer messageBuffer =
  +                        new StringBuffer("Processing deferred message for which the intended recipient could not be found. Message ID: ");
  +                    messageBuffer.append(messageID);
  +                    getLogger().info(messageBuffer.toString());
  +                }
  +            }
  +
               if (isRejectRecipientNotFound())
               {
                   rejectRecipientNotFound();
  @@ -308,10 +335,10 @@
       {
           // Update the flags of the received message
           if (!isLeaveRemoteRecipient())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  +            setMessageDeleted();
   
           if (isMarkRemoteRecipientSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +            setMessageSeen();
   
           StringBuffer messageBuffer =
               new StringBuffer("Rejected mail intended for remote recipient: ");
  @@ -320,7 +347,7 @@
   
           return;
       }
  -
  +    
       /**
        * Method rejectBlacklistedRecipient.
        * @param recipient
  @@ -331,10 +358,9 @@
       {
           // Update the flags of the received message
           if (!isLeaveBlacklisted())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  -
  +            setMessageDeleted();
           if (isMarkBlacklistedSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +            setMessageSeen();
   
           StringBuffer messageBuffer =
               new StringBuffer("Rejected mail intended for blacklisted recipient: ");
  @@ -352,19 +378,21 @@
       {
           // Update the flags of the received message
           if (!isLeaveRecipientNotFound())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  +            setMessageDeleted();
   
           if (isMarkRecipientNotFoundSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +            setMessageSeen();
   
           StringBuffer messageBuffer =
  -            new StringBuffer("Rejected mail for which a sole intended recipient could not be found. Recipients: ");
  +            new StringBuffer("Rejected mail for which a sole intended recipient could not be found. Message ID: ");
  +        messageBuffer.append(getMessageIn().getMessageID());
  +        messageBuffer.append(", recipients: ");
           Address[] allRecipients = getMessageIn().getAllRecipients();
           for (int i = 0; i < allRecipients.length; i++)
           {
               messageBuffer.append(allRecipients[i].toString());
               messageBuffer.append(' ');
  -        }   
  +        }
           getLogger().info(messageBuffer.toString());
           return;
       }
  @@ -379,10 +407,10 @@
       {
           // Update the flags of the received message
           if (!isLeaveUserUndefined())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  +            setMessageDeleted();
   
           if (isMarkUserUndefinedSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +            setMessageSeen();
   
           StringBuffer messageBuffer =
               new StringBuffer("Rejected mail intended for undefined user: ");
  @@ -484,15 +512,16 @@
        */
       protected void handleParseException(
           ParseException ex,
  -        MailAddress intendedRecipient) throws MessagingException
  +        MailAddress intendedRecipient)
  +        throws MessagingException
       {
           // Update the flags of the received message
           if (!isLeaveUndeliverable())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  -    
  +            setMessageDeleted();
  +
           if (isMarkUndeliverableSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  -                    
  +            setMessageSeen();
  +
           getLogger().error(
               getFetchTaskName()
                   + " Message could not be processed due to an error parsing the addresses."
  @@ -503,9 +532,9 @@
                   + " To: "
                   + intendedRecipient.toString());
           getLogger().debug(ex.toString());
  -//      ex.printStackTrace();
  -    }       
  -
  +        //      ex.printStackTrace();
  +    }
  +    
       /**
        * Method isLocalRecipient.
        * @param recipient
  @@ -587,10 +616,10 @@
   
           // Update the flags of the received message
           if (!isLeave())
  -            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  +            setMessageDeleted();
   
           if (isMarkSeen())
  -            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +            setMessageSeen();
       }   
   
   
  @@ -683,7 +712,7 @@
       {
           // If the original recipient should be ignored, answer the 
           // hard-coded recipient
  -        if (isIgnorelRecipientHeader())
  +        if (isIgnoreRecipientHeader())
           {
               StringBuffer messageBuffer =
                   new StringBuffer("Ignoring recipient header. Using configured recipient as new envelope recipient - ");
  @@ -750,7 +779,17 @@
       {
           return fieldRemoteRecipient;
       }
  -
  +    
  +    /**
  +     * Returns <code>boolean</code> indicating if the message to be delivered
  +     * was unprocessed in a previous delivery attempt.
  +     * @return boolean
  +     */
  +    protected boolean isPreviouslyUnprocessed()
  +    {
  +        return true;
  +    }
  +    
       /**
        * Returns the userUndefined.
        * @return boolean
  @@ -759,6 +798,53 @@
       {
           return fieldUserUndefined;
       }
  +    
  +    /**
  +     * Set the DELETED flag.
  +     * @throws MessagingException
  +     */
  +    protected void setMessageDeleted() throws MessagingException
  +    {
  +            getMessageIn().setFlag(Flags.Flag.DELETED, true);
  +    }
  +    
  +    /*    /**
  +     * Set the SEEN flag.
  +     * @throws MessagingException
  +     */
  +    protected void setMessageSeen() throws MessagingException
  +    {
  +        // If the Seen flag is not handled by the folder
  +        // allow a handler to do whatever it deems necessary
  +        if (!getMessageIn()
  +            .getFolder()
  +            .getPermanentFlags()
  +            .contains(Flags.Flag.SEEN))
  +            handleMarkSeenNotPermanent();
  +        else
  +            getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +    }
  +    
  +    /**
  +     * <p>Handler for when the folder does not support the SEEN flag.
  +     * The default behaviour implemented here is to log a warning and set the
  +     * flag anyway.</p>
  +     * 
  +     * <p> Subclasses may choose to override this and implement their own
  +     * solutions.</p>
  +     *  
  +     * @throws MessagingException
  +     */
  +    protected void handleMarkSeenNotPermanent() throws MessagingException
  +    {
  +        StringBuffer messageBuffer = new StringBuffer("Marking message ID: ");
  +        messageBuffer.append(getMessageIn().getMessageID());
  +        messageBuffer.append(
  +            " as SEEN, but the folder does not support a permanent SEEN flag.");
  +        getLogger().warn(messageBuffer.toString());
  +        
  +        getMessageIn().setFlag(Flags.Flag.SEEN, true);
  +    }            
   
       /**
        * Returns the Blacklisted.
  
  
  
  1.1.2.2   +29 -116   james-server/src/java/org/apache/james/fetchmail/Attic/ParsedConfiguration.java
  
  Index: ParsedConfiguration.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/ParsedConfiguration.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- ParsedConfiguration.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ ParsedConfiguration.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -162,12 +162,6 @@
       private String fieldHost;
   
       /**
  -     * Don't parse header looking for recipient
  -     */
  -    private boolean fieldIgnoreRecipientHeader;             
  -
  -
  -    /**
        * Keep retrieved messages on the remote mailserver.  Normally, messages
        * are deleted from the folder on the mailserver after they have been retrieved
        */
  @@ -229,19 +223,13 @@
        * Mark undeliverable messages on the remote mail server as seen.
        * Normally, messages are not marked as seen if they are undeliverable.
        */
  -    private boolean fieldMarkUndeliverableSeen = false;                
  -
  -
  -    /**
  -     * The user password for this fetch task
  -     */
  -    private String fieldPassword; 
  +    private boolean fieldMarkUndeliverableSeen = false; 
       
  -
       /**
  -     * The user to send the fetched mail to
  +     * Defer processing of messages for which the intended recipient cannot
  +     * be determined to the next pass.
        */
  -    private MailAddress fieldRecipient;
  +    private boolean fieldDeferRecipientNotFound = false;                 
   
   
       /**
  @@ -257,11 +245,6 @@
       
   
       /**
  -     * The user name for this fetch task
  -     */
  -    private String fieldUser;
  -    
  -    /**
        * The domain part to use to complete partial addresses
        */
       private String fieldDefaultDomainName; 
  @@ -290,8 +273,7 @@
       private boolean fieldMarkRecipientNotFoundSeen;       
       
       /**
  -     * Only accept mail for local recipients.
  -     * All other mail is rejected.
  +     * Reject mail for blacklisted users
        */
       private boolean fieldRejectBlacklisted;
   
  @@ -304,8 +286,8 @@
       /**
        * The Set of MailAddresses for whom mail should be rejected
        */    
  -    private Set fieldBlacklist;
  -    
  +    private Set fieldBlacklist;   
  +
      /**
        * The Local Users repository
        */
  @@ -359,6 +341,8 @@
   //          recipient.getAttributeAsBoolean("ignorercpt-header"));
               
           Configuration recipientNotFound = conf.getChild("recipientnotfound");
  +        setDeferRecipientNotFound(
  +            recipientNotFound.getAttributeAsBoolean("defer"));         
           setRejectRecipientNotFound(
               recipientNotFound.getAttributeAsBoolean("reject"));     
           setLeaveRecipientNotFound(recipientNotFound.getAttributeAsBoolean("leaveonserver"));
  @@ -396,11 +380,11 @@
           setMarkUserUndefinedSeen(
               userundefined.getAttributeAsBoolean("markseen"));
               
  -        Configuration undeliverable = conf.getChild("undeliverable");
  +        Configuration undeliverable = conf.getChild("undeliverable");      
           setLeaveUndeliverable(
               undeliverable.getAttributeAsBoolean("leaveonserver"));
           setMarkUndeliverableSeen(
  -            undeliverable.getAttributeAsBoolean("markseen"));           
  +            undeliverable.getAttributeAsBoolean("markseen"));                       
   
           if (getLogger().isDebugEnabled())
           {
  @@ -440,15 +424,6 @@
       }
   
       /**
  -     * Returns the ignoreOriginalRecipient.
  -     * @return boolean
  -     */
  -    public boolean isIgnoreRecipientHeader()
  -    {
  -        return fieldIgnoreRecipientHeader;
  -    }
  -
  -    /**
        * Returns the keep.
        * @return boolean
        */
  @@ -489,24 +464,6 @@
       }   
   
       /**
  -     * Returns the password.
  -     * @return String
  -     */
  -    public String getPassword()
  -    {
  -        return fieldPassword;
  -    }
  -
  -    /**
  -     * Returns the recipient.
  -     * @return MailAddress
  -     */
  -    public MailAddress getRecipient()
  -    {
  -        return fieldRecipient;
  -    }
  -
  -    /**
        * Returns the recurse.
        * @return boolean
        */
  @@ -525,15 +482,6 @@
       }
   
       /**
  -     * Returns the user.
  -     * @return String
  -     */
  -    public String getUser()
  -    {
  -        return fieldUser;
  -    }
  -
  -    /**
        * Sets the fetchAll.
        * @param fetchAll The fetchAll to set
        */
  @@ -561,15 +509,6 @@
       }
   
       /**
  -     * Sets the ignoreOriginalRecipient.
  -     * @param ignoreOriginalRecipient The ignoreOriginalRecipient to set
  -     */
  -    protected void setIgnoreRecipientHeader(boolean ignoreOriginalRecipient)
  -    {
  -        fieldIgnoreRecipientHeader = ignoreOriginalRecipient;
  -    }
  -
  -    /**
        * Sets the keep.
        * @param keep The keep to set
        */
  @@ -588,41 +527,6 @@
       }
   
       /**
  -     * Sets the password.
  -     * @param password The password to set
  -     */
  -    protected void setPassword(String password)
  -    {
  -        fieldPassword = password;
  -    }
  -
  -    /**
  -     * Sets the recipient.
  -     * @param recipient The recipient to set
  -     */
  -    protected void setRecipient(MailAddress recipient)
  -    {
  -        fieldRecipient = recipient;
  -    }
  -    
  -    /**
  -     * Sets the recipient.
  -     * @param recipient The recipient to set
  -     */
  -    protected void setRecipient(String recipient) throws ConfigurationException
  -    {
  -        try
  -        {
  -            setRecipient(new MailAddress(recipient));
  -        }
  -        catch (ParseException pe)
  -        {
  -            throw new ConfigurationException(
  -                "Invalid recipient address specified: " + recipient);
  -        }
  -    }   
  -
  -    /**
        * Sets the recurse.
        * @param recurse The recurse to set
        */
  @@ -641,15 +545,6 @@
       }
   
       /**
  -     * Sets the user.
  -     * @param user The user to set
  -     */
  -    protected void setUser(String user)
  -    {
  -        fieldUser = user;
  -    }
  -
  -    /**
        * Returns the logger.
        * @return Logger
        */
  @@ -1066,6 +961,24 @@
       protected void setRejectRecipientNotFound(boolean rejectRecipientNotFound)
       {
           fieldRejectRecipientNotFound = rejectRecipientNotFound;
  +    }
  +
  +    /**
  +     * Returns the deferRecipientNotFound.
  +     * @return boolean
  +     */
  +    public boolean isDeferRecipientNotFound()
  +    {
  +        return fieldDeferRecipientNotFound;
  +    }
  +
  +    /**
  +     * Sets the deferRecipientNotFound.
  +     * @param deferRecipientNotFound The deferRecepientNotFound to set
  +     */
  +    protected void setDeferRecipientNotFound(boolean deferRecipientNotFound)
  +    {
  +        fieldDeferRecipientNotFound = deferRecipientNotFound;
       }
   
   }
  
  
  
  1.1.2.2   +63 -50    james-server/src/java/org/apache/james/fetchmail/Attic/ProcessorAbstract.java
  
  Index: ProcessorAbstract.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/ProcessorAbstract.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- ProcessorAbstract.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ ProcessorAbstract.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -58,6 +58,7 @@
    
   package org.apache.james.fetchmail;
   
  +import java.util.List;
   import java.util.Set;
   
   import javax.mail.MessagingException;
  @@ -76,10 +77,9 @@
    * <p>Typically, processors are chained. A Store processor delegates to a Folder
    * processor that delegates to a Message processor.</p>
    * 
  - * <p><code>ProcessorAbstract</code> wraps a parsed and validated
  - * configuration - 
  - * see <code>org.apache.james.fetchmail.ParsedConfiguration</code>
  - * - representing the environment in which the processor operates.</p>
  + * <p><code>ProcessorAbstract</code> wraps an Account - see 
  + * <code>org.apache.james.fetchmail.Account</code>
  + * - providing contextual information about the environment for the processor.</p>
    * 
    * <p>Creation Date: 27-May-03</p>
    * 
  @@ -92,9 +92,9 @@
       private String fieldAttributePrefix;
       
       /**
  -     * The Configuration for this task
  +     * The Account for this task
        */
  -    private ParsedConfiguration fieldConfiguration; 
  +    private Account fieldAccount;       
   
       /**
        * Constructor for ProcessorAbstract.
  @@ -106,34 +106,15 @@
       
       /**
        * Constructor for ProcessorAbstract.
  -     * @param configuration The <code>ParsedConfiguration</code> to be used during this operation
  +     * @param account The <code>Account</code> to be processed 
        */
  -    protected ProcessorAbstract(ParsedConfiguration configuration)
  +    protected ProcessorAbstract(Account account)
       {
           this();
  -        setConfiguration(configuration);        
  +        setAccount(account);        
       }   
       
       /**
  -     * Returns the configuration.
  -     * @return ParsedConfiguration
  -     */
  -    protected ParsedConfiguration getConfiguration()
  -    {
  -        return fieldConfiguration;
  -    }
  -
  -
  -    /**
  -     * Sets the configuration.
  -     * @param configuration The configuration to set
  -     */
  -    protected void setConfiguration(ParsedConfiguration configuration)
  -    {
  -        fieldConfiguration = configuration;
  -    }
  -    
  -    /**
        * Returns the defaultDomainName.
        * @return String
        */
  @@ -143,6 +124,16 @@
       }
       
       /**
  +     * Returns the message ids. of messages for which processing has been
  +     * deferred as the recipient could not be found
  +     * @return List
  +     */
  +    protected List getDeferredRecipientNotFoundMessageIDs()
  +    {
  +        return getAccount().getDeferredRecipientNotFoundMessageIDs();
  +    }    
  +    
  +    /**
        * Returns the fetchTaskName.
        * @return String
        */
  @@ -200,7 +191,7 @@
        */
       protected String getPassword()
       {
  -        return getConfiguration().getPassword();
  +        return getAccount().getPassword();
       }
   
   
  @@ -210,7 +201,7 @@
        */
       protected MailAddress getRecipient()
       {
  -        return getConfiguration().getRecipient();
  +        return getAccount().getRecipient();
       }
   
   
  @@ -239,7 +230,7 @@
        */
       protected String getUser()
       {
  -        return getConfiguration().getUser();
  +        return getAccount().getUser();
       }
   
   
  @@ -254,12 +245,21 @@
   
   
       /**
  +     * Returns the isDeferRecipientNotFound.
  +     * @return boolean
  +     */
  +    protected boolean isDeferRecipientNotFound()
  +    {
  +        return getConfiguration().isDeferRecipientNotFound();
  +    }
  +    
  +    /**
        * Returns the ignoreOriginalRecipient.
        * @return boolean
        */
  -    protected boolean isIgnorelRecipientHeader()
  +    protected boolean isIgnoreRecipientHeader()
       {
  -        return getConfiguration().isIgnoreRecipientHeader();
  +        return getAccount().isIgnoreRecipientHeader();
       }
   
   
  @@ -317,7 +317,7 @@
       {
           return getConfiguration().isLeaveUndeliverable();
       }       
  -    
  +
       /**
        * Returns the RejectUserUndefinded.
        * @return boolean
  @@ -328,7 +328,7 @@
       }
       
       /**
  -     * Returns the RejectUserUndefinded.
  +     * Returns the RejectUserBlacklisted.
        * @return boolean
        */
       protected boolean isRejectBlacklisted()
  @@ -343,12 +343,8 @@
       protected boolean isRejectRemoteRecipient()
       {
           return getConfiguration().isRejectRemoteRecipient();
  -    }   
  -
  -
  +    }
       
  -
  -
       /**
        * Returns the markBlacklistedSeen.
        * @return boolean
  @@ -410,12 +406,8 @@
       protected boolean isMarkUndeliverableSeen()
       {
           return getConfiguration().isMarkUndeliverableSeen();
  -    }       
  -
  -
  -    
  +    }
       
  -
       /**
        * Answers true if the folder should be opened read only.
        * For this to be true... 
  @@ -454,12 +446,15 @@
       {
           return getConfiguration().getBlacklist();
       }
  -
  -
  -    
  -
  -
       
  +    /**
  +     * Returns the <code>ParsedConfiguration</code> from the <code>Account</code>.
  +     * @return ParsedConfiguration
  +     */
  +    protected ParsedConfiguration getConfiguration()
  +    {
  +        return getAccount().getParsedConfiguration();
  +    }    
   
       /**
        * Returns a lazy initialised attributePrefix.
  @@ -510,5 +505,23 @@
       {
           setAttributePrefix(computeAttributePrefix());
       }    
  +
  +    /**
  +     * Returns the account.
  +     * @return Account
  +     */
  +    public Account getAccount()
  +    {
  +        return fieldAccount;
  +    }
  +
  +    /**
  +     * Sets the account.
  +     * @param account The account to set
  +     */
  +    protected void setAccount(Account account)
  +    {
  +        fieldAccount = account;
  +    }
   
   }
  
  
  
  1.4.2.2   +1 -11     james-server/src/java/org/apache/james/fetchmail/ReaderInputStream.java
  
  Index: ReaderInputStream.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/ReaderInputStream.java,v
  retrieving revision 1.4.2.1
  retrieving revision 1.4.2.2
  diff -u -r1.4.2.1 -r1.4.2.2
  --- ReaderInputStream.java	30 Aug 2003 18:52:18 -0000	1.4.2.1
  +++ ReaderInputStream.java	21 Sep 2003 20:03:35 -0000	1.4.2.2
  @@ -56,16 +56,6 @@
    * University of Illinois, Urbana-Champaign.
    */
   
  -/**
  - * ReaderInputStream.java
  - * 
  - * Copyright (C) 24-Sep-2002 The Apache Software Foundation. All rights reserved.
  - *
  - * This software is published under the terms of the Apache Software License
  - * version 1.1, a copy of which has been included with this distribution in
  - * the LICENSE file. 
  - *
  - */
   package org.apache.james.fetchmail;
   import java.io.IOException;
   import java.io.InputStream;
  
  
  
  1.1.2.2   +6 -6      james-server/src/java/org/apache/james/fetchmail/Attic/StoreProcessor.java
  
  Index: StoreProcessor.java
  ===================================================================
  RCS file: /home/cvs/james-server/src/java/org/apache/james/fetchmail/Attic/StoreProcessor.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- StoreProcessor.java	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ StoreProcessor.java	21 Sep 2003 20:03:35 -0000	1.1.2.2
  @@ -74,11 +74,11 @@
   
       /**
        * Constructor for StoreProcessor.
  -     * @param configuration
  +     * @param account
        */
  -    protected StoreProcessor(ParsedConfiguration configuration)
  +    protected StoreProcessor(Account account)
       {
  -        super(configuration);
  +        super(account);
       }
   
       /**
  @@ -95,7 +95,7 @@
           Folder folder = null;
   
           StringBuffer logMessageBuffer =
  -            new StringBuffer("Fetching mail from server '");
  +            new StringBuffer("Starting fetching mail from server '");
           logMessageBuffer.append(getHost());
           logMessageBuffer.append("' for user '");
           logMessageBuffer.append(getUser());
  @@ -126,7 +126,7 @@
                   getLogger().error(getFetchTaskName() + " No default folder");
   
               // Process the Folder
  -            new FolderProcessor(folder, getConfiguration()).process();
  +            new FolderProcessor(folder, getAccount()).process();
   
           }
           catch (MessagingException ex)
  @@ -144,7 +144,7 @@
               {
                   getLogger().error(ex.getMessage());
               }
  -            logMessageBuffer = new StringBuffer("Fetched mail from server '");
  +            logMessageBuffer = new StringBuffer("Finished fetching mail from server '");
               logMessageBuffer.append(getHost());
               logMessageBuffer.append("' for user '");
               logMessageBuffer.append(getUser());
  
  
  
  No                   revision
  No                   revision
  1.40.2.18 +2 -2      james-server/src/conf/james-config.xml
  
  Index: james-config.xml
  ===================================================================
  RCS file: /home/cvs/james-server/src/conf/james-config.xml,v
  retrieving revision 1.40.2.17
  retrieving revision 1.40.2.18
  diff -u -r1.40.2.17 -r1.40.2.18
  --- james-config.xml	30 Aug 2003 18:52:18 -0000	1.40.2.17
  +++ james-config.xml	21 Sep 2003 20:03:36 -0000	1.40.2.18
  @@ -153,7 +153,7 @@
            <!-- Useful for detecting and eliminating spam. -->
            <!-- For this block to function, the spam processor must be configured. -->
            <!--
  -         <mailet match="SenderInFakeDomain" class="ToProcessor">
  +         <mailet match="SenderInFakeDomain=64.55.105.9,64.94.110.11,194.205.62.122,194.205.62.62,195.7.77.20,206.253.214.102,212.181.91.6,219.88.106.80,194.205.62.42,216.35.187.246,203.119.4.6" class="ToProcessor">
               <processor> spam </processor>
            </mailet>
            -->
  
  
  
  1.1.2.2   +34 -40    james-server/src/conf/Attic/james-fetchmail.xml
  
  Index: james-fetchmail.xml
  ===================================================================
  RCS file: /home/cvs/james-server/src/conf/Attic/james-fetchmail.xml,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- james-fetchmail.xml	30 Aug 2003 18:52:18 -0000	1.1.2.1
  +++ james-fetchmail.xml	21 Sep 2003 20:03:36 -0000	1.1.2.2
  @@ -1,13 +1,22 @@
  -   <!-- FetchMail block.  Uses JavaMail service providers to fetch messages from   -->
  -   <!-- message sources and inserts them into the spool.                           -->
  -   <!-- Warning:  It is important to prevent mail from looping by adding the       -->
  -   <!-- acceptable domains in the <servernames> section of the <James> block in    -->
  -   <!-- the James config.xml file.  FetchMail is disabled by default.              -->
  +   <!-- Fetch mail block, fetches mail from message servers and inserts it into the incoming spool -->
  +   <!-- Warning: It is important to prevent mail from looping by setting the  -->
  +   <!-- fetched domains in the <servernames> section of the <James> block      -->
  +   <!-- above. This block is disabled by default.                              -->
  +      
  +   <!-- See http://james.apache.org/fetchmail_configuration_2_2.html for detailed -->
  +   <!-- configuration instructions and examples.                                  -->   
  +
  +   <!-- I M P O R T A N T -->
  +   <!-- Setting markseen="true" will have no effect on many POP3 servers as the POP3 -->
  +   <!-- protocol does not require the markSeen flag to be supported. When this is the -->
  +   <!-- case, the only way to ensure that messages are fetched just once is to delete -->
  +   <!-- fetched messages from the server with leaveonserver="false". -->
      
      <!-- If you want to perform mailet processing on messages fetched by fetchmail, -->
      <!-- use the HasMailAttribute matcher to detect messages with the MailAttribute -->
  -   <!-- org.apache.james.fetchmail.fetchtask. The attribute's value is that of the -->
  +   <!-- org.apache.james.fetchmail.taskName. The attribute's value is that of the -->
      <!-- fetch task's name parameter described below. -->
  +   
       <fetchmail enabled="false">
           <!-- You can have as many fetch tasks as you want, but each must have a -->
           <!-- unique name by which it is identified. -->
  @@ -25,33 +34,29 @@
               <!-- insufficient information in the headers to do so. When the correct recipient cannot be deduced, -->
               <!-- fetchmail can be configured to leave the mail on the server or deliver it to a default recipient. -->          
               
  -            <!-- When a pop3 server delivers mail for a single user to a specific INBOX you can define -->
  +            <!-- When a message server delivers mail for a single user to a specific INBOX you can define -->
               <!-- each user to James (via the console) and use <alllocal> with ignorercpt-header="true" to deliver mail -->
               <!-- directly from each users INBOX onto James' spool. There is no need to update 'config.xml' -->
               <!-- each time you add or remove users, fetchmail checks the list of users at the start of each fetch. -->
               
  -            <!-- When a pop3 server provides an account that gives access to all mail for a domain through a single -->
  +            <!-- When a message server provides an account that gives access to all mail for a domain through a single -->
               <!-- INBOX, you can use an <account> to fetch all the mail for that domain, using the filter facilities -->
               <!-- described below to reject unwanted messages. -->
               
  -            <!-- When a pop3 server supports BOTH delivery for a single user to a specific INBOX and access to all mail -->
  +            <!-- When a message server supports BOTH delivery for a single user to a specific INBOX and access to all mail -->
               <!-- for a domain through a single INBOX, you can use <alllocal> and <account> together to guarantee that all -->
  -            <!-- wanted mail gets delivered to the correct user and all unwanted mail is deleted from the pop3 -->
  -            <!-- server... --> 
  -            <!-- 1) <alllocal> with ignorercpt-header="true" fetches all of mail for whom the recipient is known by -->     
  -            <!-- virtue of the INBOX it is stored in and delivers it to that user. -->
  -            <!-- 2) <account> fetches all remaining mail for the domain and any new mail that may have arrived -->
  -            <!-- during <alllocal> processing. It deletes unwanted mail, delivers mail for whom the intended recipient can be -->
  -            <!-- deduced and leaves the rest on the server for the next run of <alllocal> (Fully worked example to follow). -->
  +            <!-- local mail gets delivered to the correct user and all unwanted mail is deleted from the message -->
  +            <!-- server. See http://james.apache.org/fetchmail_configuration_2_2.html for details. -->
               
               <!-- Limitations and Future Directions -->
  -            <!-- 1) <alllocal> requires the password for all accounts for a domain on the pop3 server be the same. True in many -->
  -            <!-- cases, but not all. A future version might work out a way of associating James users with pop3 account -->
  -            <!-- properties. -->
  -            <!-- 2) <alllocal> will try to access an INBOX on the pop3 server for all local users. The instance of James used -->
  +            <!-- 1) <alllocal> requires the password for all accounts for a domain on the message server be the same. True -->
  +            <!-- in many cases, but not all. A future version might work out a way of associating James users with a set -->
  +            <!-- of account properties. -->
  +            <!-- 2) <alllocal> will try to access an INBOX on the message server for all local users. The instance of James used -->
               <!-- for this purpose should not have extraneous users defined. This is inefficient, but not fatal. -->
  -            <!-- Again, a future version might work out a way of associating James users with pop3 account properties. -->
  -            <!-- This would allow all local users with an account on a particular pop3 server to be fetched. -->
  +            <!-- Again, a future version might work out a way of associating James users with message account properties. -->
  +            <!-- This would allow all local users with an account on a particular message server to be fetched. -->
  +            
               <accounts>
                   <alllocal userprefix="" usersuffix="@myaccount" password="password" recipientprefix="" recipientsuffix="@mydomain.com" ignorercpt-header="true"/>
                   <account user="myglobalaccount" password="password" recipient="postmaster@localhost" ignorercpt-header="false"/>                                            
  @@ -112,23 +117,12 @@
               <!--     if false, messages left on the server will not be marked as seen -->            
               <undeliverable leaveonserver="true" markseen="false"/>
               
  -            <!-- Fetchmail will leave the fetched message unchanged and will add a new envelope     -->
  -            <!-- recipient before spooling the message in James.  -->
  -            <!-- Fetchmail will try and determine the original recipient of the message             -->
  -            <!-- in the following ways:  -->
  -            <!-- First it tries to parse the Received: headers and look for the "for" parameter    -->
  -            <!-- If the "for" parameter is not found it will check the To: header and if it only   -->
  -            <!-- contains one address it will be used as the new envelope recipient.   -->
  -            <!-- If no recipient can be determined AND the <recipientnotfound reject="false"> is set -->
  -            <!-- the value defined in the <recipient> parameter will be used. -->
  -            <!-- Setting ignorercpt-header to true will force the defined recipient  -->
  -            <!-- to ALWAYS be used, the parsing of headers will be ignored and the recipient will  -->
  -            <!-- always be considered found. -->
  -            <!-- Moved to <account>
  -            <recipient ignorercpt-header="false"/>
  -            -->
  -            
               <!-- Specify what happens to messages for which a recipient cannot be determined. -->
  +            <!-- defer -->
  +            <!--     if true, processing of messages for which a recipient cannot be determined will deferred -->
  +            <!--     until the next fetch of the Account. This gives an opportunity for other Accounts in the -->
  +            <!--     fetch task to determine the recipient and process the mail. -->
  +            <!--     if false, messages for which a recipient cannot be determined are processed immediately. -->
               <!-- reject -->
               <!--     if true, messages for which a recipient cannot be determined will be rejected -->
               <!--     if false, messages for which a recipient cannot be determined will be accepted, -->
  @@ -141,7 +135,7 @@
               <!--     markseen -->
               <!--         if true, messages left on the server will be marked as seen -->
               <!--         if false, messages left on the server will not be marked as seen -->            
  -            <recipientnotfound reject="true" leaveonserver="true" markseen="false"/>                                         
  +            <recipientnotfound defer="true" reject="true" leaveonserver="true" markseen="false"/>                                         
   
               <!-- Specify a list of recipients for whom messages will be rejected -->
               <!-- and what happens to rejected messages. -->
  @@ -190,6 +184,6 @@
               <!--     markseen -->
               <!--         if true, messages left on the server will be marked as seen -->
               <!--         if false, messages left on the server will not be marked as seen -->       
  -            <remoterecipient reject="true" leaveonserver="true" markseen="false" /> 
  +            <remoterecipient reject="true" leaveonserver="true" markseen="false" />
           </fetch>
       </fetchmail>        
  
  
  
  No                   revision
  No                   revision
  1.7.4.1   +2 -1      james-server/src/xdocs/documentation_2_1.xml
  
  Index: documentation_2_1.xml
  ===================================================================
  RCS file: /home/cvs/james-server/src/xdocs/documentation_2_1.xml,v
  retrieving revision 1.7
  retrieving revision 1.7.4.1
  diff -u -r1.7 -r1.7.4.1
  --- documentation_2_1.xml	12 Dec 2002 02:50:26 -0000	1.7
  +++ documentation_2_1.xml	21 Sep 2003 20:03:36 -0000	1.7.4.1
  @@ -52,7 +52,8 @@
   <li><a href="pop3_configuration_2_1.html">POP3 Server Configuration</a></li>
   <li><a href="smtp_configuration_2_1.html">SMTP Server Configuration</a></li>
   <li><a href="nntp_configuration_2_1.html">NNTP Server Configuration</a></li>
  -<li><a href="fetchpop_configuration_2_1.html">FetchPOP Configuration</a></li>
  +<li><a href="fetchpop_configuration_2_1.html">FetchPOP Configuration <i>(deprecated)</i></a></li>
  +<li><a href="fetchmail_configuration_2_2.html">fetchMail Configuration</a></li>
   <li><a href="remotemanager_configuration_2_1.html">RemoteManager Configuration</a></li>
   <li><a href="repositories_2_1.html">Repository Configuration</a></li>
   <li><a href="spoolmanager_configuration_2_1.html">SpoolManager Configuration</a></li>
  
  
  
  1.3.4.1   +6 -0      james-server/src/xdocs/fetchpop_configuration_2_1.xml
  
  Index: fetchpop_configuration_2_1.xml
  ===================================================================
  RCS file: /home/cvs/james-server/src/xdocs/fetchpop_configuration_2_1.xml,v
  retrieving revision 1.3
  retrieving revision 1.3.4.1
  diff -u -r1.3 -r1.3.4.1
  --- fetchpop_configuration_2_1.xml	7 Dec 2002 20:38:20 -0000	1.3
  +++ fetchpop_configuration_2_1.xml	21 Sep 2003 20:03:36 -0000	1.3.4.1
  @@ -7,6 +7,12 @@
    </properties>
   
   <body>
  +<section name="FetchPOP Is Being Deprecated">
  +<p>FetchPOP is being deprecated.
  +<a href="fetchmail_configuration_2_2.html">fetchMail</a> provides a superset of
  +FetchPOP's functionality and is the preferred solution.</p>
  +</section>
  +
   <section name="FetchPOP Configuration">
   <p>FetchPOP is controlled by a configuration block in the config.xml.
   The fetchpop tag defines the boundaries of the configuration block.  It encloses 
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org