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 ch...@apache.org on 2001/05/11 10:50:45 UTC

cvs commit: jakarta-james/src/org/apache/mailet GenericMailet.java GenericMatcher.java GenericRecipientMatcher.java Mail.java MailAddress.java Mailet.java MailetConfig.java MailetContext.java MailetException.java Matcher.java MatcherConfig.java

charlesb    01/05/11 01:50:44

  Added:       src/java/org/apache/mailet GenericMailet.java
                        GenericMatcher.java GenericRecipientMatcher.java
                        Mail.java MailAddress.java Mailet.java
                        MailetConfig.java MailetContext.java
                        MailetException.java Matcher.java
                        MatcherConfig.java
  Removed:     src/org/apache/mailet GenericMailet.java GenericMatcher.java
                        GenericRecipientMatcher.java Mail.java
                        MailAddress.java Mailet.java MailetConfig.java
                        MailetContext.java MailetException.java
                        Matcher.java MatcherConfig.java
  Log:
  Moved src/org/apache/mailet/* to src/java/org/apache/mailet
  
  Revision  Changes    Path
  1.1                  jakarta-james/src/java/org/apache/mailet/GenericMailet.java
  
  Index: GenericMailet.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  import javax.mail.*;
  
  /**
   * GenericMailet makes writing mailets easier. It provides simple
   * versions of the lifecycle methods init and destroy and of the methods
   * in the MailetConfig interface. GenericMailet also implements the log
   * method, declared in the MailetContext interface.
   * <p>
   * To write a generic mailet, you need only override the abstract service
   * method.
   *
   * @version 1.0.0, 24/04/1999
   * @author  Federico Barbieri   <sc...@pop.systemy.it>
   * @author  Stefano Mazzocchi   <st...@apache.org>
   * @author  Pierpaolo Fumagalli <pi...@apache.org>
   * @author  Serge Knystautas    <se...@lokitech.com>
   */
  public abstract class GenericMailet implements Mailet, MailetConfig {
      private MailetConfig config = null;
  
      /**
       * Called by the mailer container to indicate to a mailet that the
       * mailet is being taken out of service.
       */
      public void destroy() {
          //Do nothing
      }
  
      /**
       * Returns a String containing the value of the named initialization
       * parameter, or null if the parameter does not exist.
       * <p>
       * This method is supplied for convenience. It gets the value of the
       * named parameter from the mailet's MailetConfig object.
       *
       * @param name - a String specifying the name of the initialization parameter
       * @return String a String containing the value of the initalization parameter
       */
      public String getInitParameter(String name) {
          return config.getInitParameter(name);
      }
  
      /**
       * Returns the names of the mailet's initialization parameters as an
       * Iterator of String objects, or an empty Iterator if the mailet has no
       * initialization parameters.
       * <p>
       * This method is supplied for convenience. It gets the parameter names from
       * the mailet's MailetConfig object.
       *
       * @return Iterator an iterator of String objects containing the names of
       *          the mailet's initialization parameters
       */
      public Iterator getInitParameterNames() {
          return config.getInitParameterNames();
      }
  
      /**
       * Returns this matcher's MailetConfig object.
       *
       * @return MailetConfig the MailetConfig object that initialized this mailet
       */
      public MailetConfig getMailetConfig() {
          return config;
      }
  
      /**
       * Returns a reference to the MailetContext in which this mailet is
       * running.
       *
       * @return MailetContext the MailetContext object passed to this mailet by the init method
       */
      public MailetContext getMailetContext() {
          return getMailetConfig().getMailetContext();
      }
  
      /**
       * Returns information about the mailet, such as author, version, and
       * copyright.  By default, this method returns an empty string. Override
       * this method to have it return a meaningful value.
       *
       * @return String information about this mailet, by default an empty string
       */
      public String getMailetInfo() {
          return "";
      }
  
      /**
       * Returns the name of this mailet instance.
       *
       * @return the name of this mailet instance
       */
      public String getMailetName() {
          return config.getMailetName();
      }
  
  
      /**
       * Called by the mailet container to indicate to a mailet that the
       * mailet is being placed into service.
       *
       * This implementation stores the MailetConfig object it receives from
       * the mailet container for alter use. When overriding this form of the
       * method, call super.init(config).
       *
       * @param MailetConfig config - the MailetConfig object that contains
       *          configutation information for this mailet
       * @throws MessagingException
       *          if an exception occurs that interrupts the mailet's normal operation
       */
      public void init(MailetConfig newConfig) throws MessagingException {
          config = newConfig;
          init();
      }
  
      /**
       * A convenience method which can be overridden so that there's no
       * need to call super.init(config).
       *
       * Instead of overriding init(MailetConfig), simply override this
       * method and it will be called by GenericMailet.init(MailetConfig config).
       * The MailetConfig object can still be retrieved via getMailetConfig().
       *
       * @throws MessagingException
       *          if an exception occurs that interrupts the mailet's normal operation
       */
      public void init() throws MessagingException {
          //Do nothing... can be overriden
      }
  
      /**
       * Writes the specified message to a mailet log file, prepended by
       * the mailet's name.
       *
       * @param msg - a String specifying the message to be written to the log file
       */
      public void log(String message) {
          getMailetContext().log(config.getMailetName() + ": " + message);
      }
  
      /**
       * Writes an explanatory message and a stack trace for a given Throwable
       * exception to the mailet log file, prepended by the mailet's name.
       *
       * @param message - a String that describes the error or exception
       * @param t - the java.lang.Throwable error or exception
       */
      public void log(String message, Throwable t) {
          getMailetContext().log(config.getMailetName() + ": " + message, t);
      }
  
      /**
       * 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 javax.mail.MessagingException - if an exception occurs that interferes with the mailet's normal operation
       *          occurred
       */
      public abstract void service(Mail mail) throws javax.mail.MessagingException;
  }
  
  
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/GenericMatcher.java
  
  Index: GenericMatcher.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  import javax.mail.*;
  
  /**
   * GenericMatcher implements the Matcher and MatcherConfig interfaces.
   * GenericMatcher makes writing matchers easier. It provides simple versions of
   * the lifecycle methods init and destroy and of the methods in the MatcherConfig
   * interface. GenericMatcher also implements the log method, declared in the
   * MatcherContext interface.
   * <p>
   * To write a generic matcher, you need only override the abstract match method.
   *
   * @version 1.0.0, 24/04/1999
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public abstract class GenericMatcher implements Matcher, MatcherConfig {
      MatcherConfig config = null;
  
      /**
       * Called by the mailet container to indicate to a matcher that the
       * matcher is being taken out of service.
       */
      public void destroy() {
          //Do nothing
      }
  
      /**
       * Returns a String containing the value of the named initialization
       * parameter, or null if the parameter does not exist.
       * <p>
       * This method is supplied for convenience. It gets the value of the
       * named parameter from the matcher's MatcherConfig object.
       *
       * @return String a String containing the value of the initalization parameter
       */
      public String getCondition() {
          return config.getCondition();
      }
  
      /**
       * Returns this matcher's MatcherConfig object.
       *
       * @return MatcherConfig the MatcherConfig object that initialized this matcher
       */
      public MatcherConfig getMatcherConfig() {
          return config;
      }
  
      /**
       * Returns a reference to the MailetContext in which this matcher is
       * running.
       *
       * @return MailetContext the MailetContext object passed to this matcher by the init method
       */
      public MailetContext getMailetContext() {
          return getMatcherConfig().getMailetContext();
      }
  
      /**
       * Returns information about the matcher, such as author, version, and
       * copyright.  By default, this method returns an empty string. Override
       * this method to have it return a meaningful value.
       *
       * @return String information about this matcher, by default an empty string
       */
      public String getMatcherInfo() {
          return "";
      }
  
      /**
       * Returns the name of this matcher instance.
       *
       * @return the name of this matcher instance
       */
      public String getMatcherName() {
          return config.getMatcherName();
      }
  
  
      /**
       * Called by the matcher container to indicate to a matcher that the
       * matcher is being placed into service.
       *
       * This implementation stores the MatcherConfig object it receives from
       * the matcher container for alter use. When overriding this form of the
       * method, call super.init(config).
       *
       * @param MatcherConfig config - the MatcherConfig object that contains
       *          configutation information for this matcher
       * @throws MessagingException
       *          if an exception occurs that interrupts the matcher's normal operation
       */
      public void init(MatcherConfig newConfig) throws MessagingException {
          config = newConfig;
          init();
      }
  
      /**
       * A convenience method which can be overridden so that there's no
       * need to call super.init(config).
       *
       * Instead of overriding init(MatcherConfig), simply override this
       * method and it will be called by GenericMatcher.init(MatcherConfig config).
       * The MatcherConfig object can still be retrieved via getMatcherConfig().
       *
       * @throws MatcherException
       *          if an exception occurs that interrupts the matcher's normal operation
       */
      public void init() throws MessagingException {
          //Do nothing... can be overriden
      }
  
      /**
       * Writes the specified message to a matcher log file, prepended by
       * the matcher's name.
       *
       * @param msg - a String specifying the message to be written to the log file
       */
      public void log(String message) {
          getMailetContext().log(getMatcherName() + ": " + message);
      }
  
      /**
       * Writes an explanatory message and a stack trace for a given Throwable
       * exception to the matcher log file, prepended by the matcher's name.
       *
       * @param message - a String that describes the error or exception
       * @param t - the java.lang.Throwable error or exception
       */
      public void log(String message, Throwable t) {
          getMailetContext().log(getMatcherName() + ": " + message, t);
      }
  
      /**
       * Called by the matcher container to allow the matcher 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
       * @return java.util.Collection - the recipients that the mailet container should have the
       *          mailet affect.
       * @throws javax.mail.MessagingException - if an exception occurs that interferes with the mailet's normal operation
       *          occurred
       */
      public abstract Collection match(Mail mail) throws MessagingException;
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/GenericRecipientMatcher.java
  
  Index: GenericRecipientMatcher.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  import javax.mail.*;
  
  /**
   * GenericMatcher makes writing recipient based matchers easier. It provides
   * simple versions of the lifecycle methods init and destroy and of the methods
   * in the MatcherConfig interface. GenericMatcher also implements the log method,
   * declared in the
   * MatcherContext interface.
   *
   * @version 1.0.0, 24/04/1999
   * @author Federico Barbieri <sc...@pop.systemy.it>
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public abstract class GenericRecipientMatcher extends GenericMatcher {
  
      /**
       * Matches each recipient one by one through matchRecipient(MailAddress
       * recipient) method.  Handles splitting the recipients Collection
       * as appropriate.
       *
       * @param mail - the message and routing information to determine whether to match
       * @return Collection the Collection of MailAddress objects that have been matched
       */
      public final Collection match(Mail mail) throws MessagingException {
          Collection matching = new Vector();
          for (Iterator i = mail.getRecipients().iterator(); i.hasNext(); ) {
              MailAddress rec = (MailAddress) i.next();
              if (matchRecipient(rec)) {
                  matching.add(rec);
              }
          }
          return matching;
      }
  
      /**
       * Simple check to match exclusively on the email address (not
       * message information).
       *
       * @param recipient - the address to determine whether to match
       * @return boolean whether the recipient is a match
       */
      public abstract boolean matchRecipient(MailAddress recipient) throws MessagingException;
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/Mail.java
  
  Index: Mail.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import javax.mail.*;
  import javax.mail.internet.*;
  
  /**
   * Wrap a MimeMessage with routing information (from SMTP) such
   * as SMTP specified recipients, sender, and ip address and hostname
   * of sending server.  It also contains its state which represents
   * which processor in the mailet container it is currently running.
   * Special processor names are "root" and "error".
   *
   * @author Federico Barbieri <sc...@systemy.it>
   * @author Serge Knystautas <se...@lokitech.com>
   * @version 0.9
   */
  public interface Mail extends Serializable, Cloneable {
      String GHOST = "ghost";
      String DEFAULT = "root";
      String ERROR = "error";
      String TRANSPORT = "transport";
  
      /**
       * Returns the MimeMessage stored in this message
       *
       * @return the MimeMessage that this Mail object wraps
       * @throws MessagingException - an error occured while loading this object
       */
      MimeMessage getMessage() throws MessagingException;
  
      /**
       * Returns a Collection of MailAddress objects that are recipients of this message
       *
       * @return a Collection of MailAddress objects that are recipients of this message
       */
      Collection getRecipients();
  
      /**
       * The sender of the message, as specified by the MAIL FROM header, or internally defined
       *
       * @return a MailAddress of the sender of this message
       */
      MailAddress getSender();
  
      /**
       * The current state of the message, such as GHOST, ERROR, or DEFAULT
       *
       * @return the state of this message
       */
      String getState();
  
      /**
       * The remote hostname of the server that connected to send this message
       *
       * @return a String of the hostname of the server that connected to send this message
       */
      String getRemoteHost();
  
      /**
       * The remote ip address of the server that connected to send this message
       *
       * @return a String of the ip address of the server that connected to send this message
       */
      String getRemoteAddr();
  
      /**
       * The error message, if any, associated with this message.  Not sure why this is needed.
       *
       * @return a String of a descriptive error message
       */
      String getErrorMessage();
  
      /**
       * Sets the error message associated with this message.  Not sure why this is needed.
       *
       * @param msg - a descriptive error message
       */
      void setErrorMessage(String msg);
  
      /**
       * Sets the MimeMessage associated with this message via an inputstream.  The Mail
       * object will parse out the inputstream and construct a MimeMessage object.
       *
       * @param in - the inputstream to read to construct the MimeMessage
       * @throws MessagingException - if there was an error parsing the inputstream
       */
      void setMessage(InputStream in) throws MessagingException;
  
      /**
       * Sets the MimeMessage associated with this message via the object.
       *
       * @param message - the new MimeMessage that this Mail object will wrap
       */
      void setMessage(MimeMessage message);
  
      /**
       * Sets the state of this message.
       *
       * @param state - the new state of this message
       */
      void setState(String state);
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/MailAddress.java
  
  Index: MailAddress.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import javax.mail.internet.InternetAddress;
  import javax.mail.internet.ParseException;
  
  /**
   * A representation of an email address.
   * <p>This class encapsulates functionalities to access to different
   * parts of an email address without dealing with its parsing.
   * <p>
   * A MailAddress is an address specified in the MAIL FROM and
   * RCPT TO commands in SMTP sessions.  These are either passed by
   * an external server to the mailet-compliant SMTP server, or they
   * are created programmatically by the mailet-compliant server to
   * send to another (external) SMTP server.  Mailets and matchers
   * use the MailAddress for the purpose of evaluating the sender
   * and recipient(s) of a message.
   * <p>
   * MailAddress parses an email address as defined in RFC 821
   * (SMTP) p. 30 and 31 where addresses are defined in BNF convention.
   * As the mailet API does not support the aged "SMTP-relayed mail"
   * addressing protocol, this leaves all addresses to be a <mailbox>,
   * as per the spec.  The MailAddress's "user" is the <local-part> of
   * the <mailbox> and "host" is the <domain> of the mailbox.
   * <p>
   * This class is a good way to validate email addresses as there are
   * some valid addresses which would fail with a simpler approach
   * to parsing address.  It also removes parsing burden from
   * mailets and matchers that might not realize the flexibility of an
   * SMTP address.  For instance, "serge@home"@lokitech.com is a valid
   * SMTP address (the quoted text serge@home is the user and
   * lokitech.com is the host).  This means all current parsing to date
   * is incorrect as we just find the first @ and use that to separate
   * user from host.
   * <p>
   * This parses an address as per the BNF specification for <mailbox>
   * from RFC 821 on page 30 and 31, section 4.1.2. COMMAND SYNTAX.
   * http://www.freesoft.org/CIE/RFC/821/15.htm
   *
   * @version 1.0
   * @author Roberto Lo Giacco <rl...@mail.com>
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public class MailAddress implements java.io.Serializable {
      //We hardcode the serialVersionUID so that from James 1.2 on,
      //  MailAddress will be deserializable (so your mail doesn't get lost)
      public static final long serialVersionUID = 2779163542539434916L;
  
      private final static char[] SPECIAL =
      {'<', '>', '(', ')', '[', ']', '\\', '.', ',', ';', ':', '@', '\"'};
  
      private String user = null;
      private String host = null;
      //Used for parsing
      private int pos = 0;
  
      /**
       * Construct a MailAddress parsing the provided <code>String</code> object.
       * <p>The <code>personal</code> variable is left empty.
       *
       * @param   address the email address compliant to the RFC822 format
       * @throws  ParseException    if the parse failed
       */
      public MailAddress(String address) throws ParseException {
          address = address.trim();
          StringBuffer userSB = new StringBuffer();
          StringBuffer hostSB = new StringBuffer();
          //Begin parsing
          //<mailbox> ::= <local-part> "@" <domain>
  
          try {
              //parse local-part
              //<local-part> ::= <dot-string> | <quoted-string>
              if (address.charAt(pos) == '\"') {
                  userSB.append(parseQuotedLocalPart(address));
              } else {
                  userSB.append(parseUnquotedLocalPart(address));
              }
              if (userSB.toString().length() == 0) {
                  throw new ParseException("No local-part (user account) found at position " + (pos + 1));
              }
  
              //find @
              if (address.charAt(pos) != '@') {
                  throw new ParseException("Did not find @ between local-part and domain at position " + (pos + 1));
              }
              pos++;
  
              //parse domain
              //<domain> ::=  <element> | <element> "." <domain>
              //<element> ::= <name> | "#" <number> | "[" <dotnum> "]"
              while (true) {
                  if (address.charAt(pos) == '#') {
                      hostSB.append(parseNumber(address));
                  } else if (address.charAt(pos) == '[') {
                      hostSB.append(parseDotNum(address));
                  } else {
                      hostSB.append(parseDomainName(address));
                  }
                  if (pos >= address.length()) {
                      break;
                  }
                  if (address.charAt(pos) == '.') {
                      hostSB.append('.');
                      pos++;
                      continue;
                  }
                  break;
              }
  
              if (hostSB.toString().length() == 0) {
                  throw new ParseException("No domain found at position " + (pos + 1));
              }
          } catch (ArrayIndexOutOfBoundsException aioobe) {
              throw new ParseException("Out of data at position " + (pos + 1));
          }
  
          user = userSB.toString();
          host = hostSB.toString();
      }
  
      /**
       * Construct a MailAddress with the provided personal name and email
       * address.
       *
       * @param   user        the username or account name on the mail server
       * @param   host        the server that should accept messages for this user
       * @throws  ParseException    if the parse failed
       */
      public MailAddress(String newUser, String newHost) throws ParseException {
          /* NEEDS TO BE REWORKED TO VALIDATE EACH CHAR */
          user = newUser;
          host = newHost;
      }
  
      /**
       * Constructs a MailAddress from a JavaMail InternetAddress, using only the
       * email address portion, discarding the personal name.
       */
      public MailAddress(InternetAddress address) throws ParseException {
          this(address.getAddress());
      }
  
      /**
       * Return the host part.
       *
       * @return  a <code>String</code> object representing the host part
       *          of this email address.
       * @throws  AddressException    if the parse failed
       */
      public String getHost() {
          return host;
      }
  
      /**
       * Return the user part.
       *
       * @return  a <code>String</code> object representing the user part
       *          of this email address.
       * @throws  AddressException    if the parse failed
       */
      public String getUser() {
          return user;
      }
  
      public String toString() {
          return user + "@" + host;
      }
  
      public InternetAddress toInternetAddress() {
          try {
              return new InternetAddress(toString());
          } catch (javax.mail.internet.AddressException ae) {
              //impossible really
              return null;
          }
      }
  
      public boolean equals(Object obj) {
          if (obj == null) {
              return false;
          } else if (obj instanceof String) {
              return toString().equalsIgnoreCase(obj.toString());
          } else if (obj instanceof MailAddress) {
              MailAddress addr = (MailAddress)obj;
              return getUser().equalsIgnoreCase(addr.getUser()) && getHost().equalsIgnoreCase(addr.getHost());
          }
          return false;
      }
  
      /**
       * Return a hashCode for this object which should be identical for addresses
       * which are equivalent.  This is implemented by obtaining the default
       * hashcode of the String representation of the MailAddress.  Without this
       * explicit definition, the default hashCode will create different hashcodes
       * for separate object instances.
       *
       * @returns the hashcode.
       * @author Stuart Roebuck <st...@adolos.com>
       */
      public int hashCode() {
          return toString().toLowerCase().hashCode();
      }
  
      private String parseQuotedLocalPart(String address) throws ParseException {
          StringBuffer resultSB = new StringBuffer();
          resultSB.append('\"');
          pos++;
          //<quoted-string> ::=  """ <qtext> """
          //<qtext> ::=  "\" <x> | "\" <x> <qtext> | <q> | <q> <qtext>
          while (true) {
              if (address.charAt(pos) == '\"') {
                  resultSB.append('\"');
                  //end of quoted string... move forward
                  pos++;
                  break;
              }
              if (address.charAt(pos) == '\\') {
                  resultSB.append('\\');
                  pos++;
                  //<x> ::= any one of the 128 ASCII characters (no exceptions)
                  char x = address.charAt(pos);
                  if (x < 0 || x > 128) {
                      throw new ParseException("Invalid \\ syntaxed character at position " + (pos + 1));
                  }
                  resultSB.append(x);
                  pos++;
              } else {
                  //<q> ::= any one of the 128 ASCII characters except <CR>,
                  //<LF>, quote ("), or backslash (\)
                  char q = address.charAt(pos);
                  if (q <= 0 || q == '\n' || q == '\r' || q == '\"' || q == '\\') {
                      throw new ParseException("Unquoted local-part (user account) must be one of the 128 ASCI characters exception <CR>, <LF>, quote (\"), or backslash (\\) at position " + (pos + 1));
                  }
                  resultSB.append(q);
                  pos++;
              }
          }
          return resultSB.toString();
      }
  
      private String parseUnquotedLocalPart(String address) throws ParseException {
          StringBuffer resultSB = new StringBuffer();
          //<dot-string> ::= <string> | <string> "." <dot-string>
          boolean lastCharDot = false;
          while (true) {
              //<string> ::= <char> | <char> <string>
              //<char> ::= <c> | "\" <x>
              if (address.charAt(pos) == '\\') {
                  resultSB.append('\\');
                  pos++;
                  //<x> ::= any one of the 128 ASCII characters (no exceptions)
                  char x = address.charAt(pos);
                  if (x < 0 || x > 128) {
                      throw new ParseException("Invalid \\ syntaxed character at position " + (pos + 1));
                  }
                  resultSB.append(x);
                  pos++;
                  lastCharDot = false;
              } else if (address.charAt(pos) == '.') {
                  resultSB.append('.');
                  pos++;
                  lastCharDot = true;
              } else if (address.charAt(pos) == '@') {
                  //End of local-part
                  break;
              } else {
                  //<c> ::= any one of the 128 ASCII characters, but not any
                  //    <special> or <SP>
                  //<special> ::= "<" | ">" | "(" | ")" | "[" | "]" | "\" | "."
                  //    | "," | ";" | ":" | "@"  """ | the control
                  //    characters (ASCII codes 0 through 31 inclusive and
                  //    127)
                  //<SP> ::= the space character (ASCII code 32)
                  char c = address.charAt(pos);
                  if (c <= 31 || c == 127 || c == ' ') {
                      throw new ParseException("Invalid character in local-part (user account) at position " + (pos + 1));
                  }
                  for (int i = 0; i < SPECIAL.length; i++) {
                      if (c == SPECIAL[i]) {
                          throw new ParseException("Invalid character in local-part (user account) at position " + (pos + 1));
                      }
                  }
                  resultSB.append(c);
                  pos++;
                  lastCharDot = false;
              }
          }
          if (lastCharDot) {
              throw new ParseException("local-part (user account) ended with a \".\", which is invalid.");
          }
          return resultSB.toString();
      }
  
      private String parseNumber(String address) throws ParseException {
          //<number> ::= <d> | <d> <number>
  
          StringBuffer resultSB = new StringBuffer();
          //We keep the position from the class level pos field
          while (true) {
              if (pos >= address.length()) {
                  break;
              }
              //<d> ::= any one of the ten digits 0 through 9
              char d = address.charAt(pos);
              if (d == '.') {
                  break;
              }
              if (d < '0' || d > '9') {
                  throw new ParseException("In domain, did not find a number in # address at position " + (pos + 1));
              }
              resultSB.append(d);
              pos++;
          }
          return resultSB.toString();
      }
  
      private String parseDotNum(String address) throws ParseException {
          StringBuffer resultSB = new StringBuffer();
          //<dotnum> ::= <snum> "." <snum> "." <snum> "." <snum>
          for (int octet = 0; octet < 4; octet++) {
              //<snum> ::= one, two, or three digits representing a decimal
              //                      integer value in the range 0 through 255
              //<d> ::= any one of the ten digits 0 through 9
              StringBuffer snumSB = new StringBuffer();
              for (int digits = 0; digits < 3; digits++) {
                  char d = address.charAt(pos);
                  if (d == '.') {
                      break;
                  }
                  if (d == ']') {
                      break;
                  }
                  if (d < '0' || d > '9') {
                      throw new ParseException("Invalid number at position " + (pos + 1));
                  }
                  snumSB.append(d);
                  pos++;
              }
              if (snumSB.toString().length() == 0) {
                  throw new ParseException("Number not found at position " + (pos + 1));
              }
              try {
                  int snum = Integer.parseInt(snumSB.toString());
                  if (snum > 255) {
                      throw new ParseException("Invalid number at position " + (pos + 1));
                  }
              } catch (NumberFormatException nfe) {
                  throw new ParseException("Invalid number at position " + (pos + 1));
              }
              resultSB.append(snumSB.toString());
              if (address.charAt(pos) == ']') {
                  if (octet < 3) {
                      throw new ParseException("End of number reached too quickly at " + (pos + 1));
                  } else {
                      break;
                  }
              }
              if (address.charAt(pos) == '.') {
                  resultSB.append('.');
                  pos++;
              }
          }
          if (address.charAt(pos) != ']') {
              throw new ParseException("Did not find closing bracket \"]\" in domain at position " + (pos + 1));
          }
          resultSB.append(']');
          pos++;
          return resultSB.toString();
      }
  
      private String parseDomainName(String address) throws ParseException {
          StringBuffer resultSB = new StringBuffer();
          //<name> ::= <a> <ldh-str> <let-dig>
          //<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
          //<let-dig> ::= <a> | <d>
          //<let-dig-hyp> ::= <a> | <d> | "-"
          //<a> ::= any one of the 52 alphabetic characters A through Z
          //  in upper case and a through z in lower case
          //<d> ::= any one of the ten digits 0 through 9
  
          //basically, this is a series of letters, digits, and hyphens,
          // but it can't start with a digit or hypthen
          // and can't end with a hyphen
  
          //by practice though, we should relax this as domain names can start
          // with digits as well as letters.  So only check that doesn't start
          // or end with hyphen.
          while (true) {
              if (pos >= address.length()) {
                  break;
              }
              char ch = address.charAt(pos);
              if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'
                  || ch == '-') {
                  resultSB.append(ch + "");
                  pos++;
                  continue;
              }
              if (ch == '.') {
                  break;
              }
              throw new ParseException("Invalid character at " + pos);
          }
          String result = resultSB.toString();
          if (result.startsWith("-") || result.endsWith("-")) {
              throw new ParseException("Domain name cannot begin or end with a hyphen \"-\" at position " + (pos + 1));
          }
          return result;
      }
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/Mailet.java
  
  Index: Mailet.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  /**
   * Draft of a Mailet inteface. The <code>service</code> perform all needed work
   * on the Mail object. Whatever remains at the end of the service is considered
   * to need futher processing and will go to the next Mailet if there is one
   * configured or will go to the error processor if not.
   * Setting a Mail state (setState(String)) to Mail.GHOST or cleaning its recipient
   * list has the same meaning that s no more processing is needed.
   * Instead of creating new messages, the mailet can put a message with new recipients
   * at the top of the mail queue, or insert them immediately after it's execution
   * through the API are provided by the MailetContext interface.
   * <p>
   * This interface defines methods to initialize a mailet, to service messages, and to
   * remove a mailet from the server. These are known as life-cycle methods and are called
   * in the following sequence:
   * <ol>
   * <li>The mailet is constructed, then initialized with the init method. </li>
   * <li>Any messages for the service method are handled.</li>
   * <li>The mailet is taken out of service, then destroyed with the destroy method,
   *      then garbage collected and finalized.</li>
   * </ol>
   * In addition to the life-cycle methods, this interface provides the getMailletConfig
   * method, which the mailet can use to get any startup information, and the
   * getMailetInfo method, which allows the mailet to return basic information about itself,
   * such as author, version, and copyright.
   *
   * @version 1.0.0, 24/04/1999
   * @author  Federico Barbieri   <sc...@pop.systemy.it>
   * @author  Stefano Mazzocchi   <st...@apache.org>
   * @author  Pierpaolo Fumagalli <pi...@apache.org>
   * @author  Serge Knystautas    <se...@lokitech.com>
   */
  public interface Mailet {
  
      /**
       * Called by the mailet container to indicate to a mailet that the
       * mailet is being taken out of service. This method is only called once
       * all threads within the mailet's service method have exited or after a
       * timeout period has passed. After the mailet container calls this method,
       * it will not call the service method again on this mailet.
       * <p>
       * This method gives the mailet an opportunity to clean up any resources that
       * are being held (for example, memory, file handles, threads) and make sure
       * that any persistent state is synchronized with the mailet's current state in memory.
       */
      void destroy();
  
      /**
       * Returns information about the mailet, such as author, version, and
       * copyright.
       * <p>
       * The string that this method returns should be plain text and not markup
       * of any kind (such as HTML, XML, etc.).
       *
       * @return a String containing servlet information
       */
      String getMailetInfo();
  
      /**
       * Returns a MailetConfig object, which contains initialization and
       * startup parameters for this mailet.
       * <p>
       * Implementations of this interface are responsible for storing the MailetConfig
       * object so that this method can return it. The GenericMailet class, which implements
       * this interface, already does this.
       *
       * @return the MailletConfig object that initializes this mailet
       */
      MailetConfig getMailetConfig();
  
      /**
       * Called by the mailet container to indicate to a mailet that the
       * mailet is being placed into service.
       * <p>
       * The mailet container calls the init method exactly once after
       * instantiating the mailet. The init method must complete successfully
       * before the mailet can receive any requests.
       *
       * @param config - a MailetConfig object containing the mailet's configuration
       *          and initialization parameters
       * @throws MessagingException - if an exception has occurred that interferes with
       *          the mailet's normal operation
       */
      void init(MailetConfig config) throws javax.mail.MessagingException;
  
      /**
       * Called by the mailet container to allow the mailet to process to
       * a message message.
       * <p>
       * This method is only called after the mailet's init() method has completed
       * successfully.
       * <p>
       * Mailets typically run inside multithreaded mailet containers that can handle
       * multiple requests concurrently. Developers must be aware to synchronize access
       * to any shared resources such as files, network connections, and as well as the
       * mailet's class and instance variables. More information on multithreaded
       * programming in Java is available in <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">the
       * Java tutorial on multi-threaded programming</a>.
       *
       * @param mail - the Mail object that contains the message and routing information
       * @throws javax.mail.MessagingException - if an message or address parsing exception occurs or
       *      an exception that interferes with the mailet's normal operation
       */
      void service(Mail mail) throws javax.mail.MessagingException;
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/MailetConfig.java
  
  Index: MailetConfig.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  
  /**
   * A mailet configuration object used by a mailet container used to pass information
   * to a mailet during initialization.
   * <p>
   * The configuration information contains initialization parameters, which are a set
   * of name/value pairs, and a MailetContext object, which gives the mailet information
   * about the server.
   *
   * @version 1.0.0, 24/04/1999
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public interface MailetConfig {
  
      /**
       * Returns a String containing the value of the named initialization
       * parameter, or null if the parameter does not exist.
       *
       * @param name - a String specifying the name of the initialization parameter
       * @return a String containing the value of the initialization parameter
       */
      String getInitParameter(String name);
  
      /**
       * Returns the names of the mailet's initialization parameters as an
       * Iterator of String objects, or an empty Iterator if the mailet has
       * no initialization parameters.
       *
       * @return an Iterator of String objects containing the names of the mailet's
       *      initialization parameters
       */
      Iterator getInitParameterNames();
  
      /**
       * Returns a reference to the MailetContext in which the mailet is
       * executing.
       *
       * @return a MailetContext object, used by the mailet to interact with its
       *      mailet container
       */
      MailetContext getMailetContext();
  
      /**
       * Returns the name of this mailet instance. The name may be provided via
       * server administration, assigned in the application deployment descriptor,
       * or for an unregistered (and thus unnamed) mailet instance it will be the
       * mailet's class name.
       *
       * @return the name of the mailet instance
       */
      String getMailetName();
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/MailetContext.java
  
  Index: MailetContext.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  import javax.mail.*;
  import javax.mail.internet.*;
  
  /**
   * Defines a set of methods that a mailet or matcher uses to communicate
   * with its mailet container, for example, to send a new message, to
   * deliver a message locally, or write to a log file.
   *
   * The MailetContext object is contained within the MailetConfig and
   * MatcherConfig objects, which the mailet container provides the
   * mailets and matchers when they are initialized.
   *
   * @version 1.0.0, 24/04/1999
   * @author  Federico Barbieri   <sc...@pop.systemy.it>
   * @author  Stefano Mazzocchi   <st...@apache.org>
   * @author  Pierpaolo Fumagalli <pi...@apache.org>
   * @author  Serge Knystautas    <se...@lokitech.com>
   */
  public interface MailetContext {
  
      /**
       * Bounces the message using a stanard format with the given message.
       * Will be sent back to the sender from the postmaster as specified for
       * this mailet context, adding message to top of mail server queue using
       * sendMail().
       *
       * @param mail - the message that is to be bounced and sender to whom to return the message
       * @param message - a descriptive message as to why the message bounced
       */
      void bounce(Mail mail, String message) throws MessagingException;
  
      /**
       * Bounces the email message using the provided email address as the
       * sender of the bounce.
       *
       * @param mail - the message that is to be bounced and sender to whom to return the message
       * @param message - a descriptive message as to why the message bounced
       * @param bouncer - the address to give as the sender of the bounced message
       */
      void bounce(Mail mail, String message, MailAddress bouncer) throws MessagingException;
  
      /**
       * Returns a Collection of Strings of hostnames or ip addresses that
       * are specified as mail server listeners for the given hostname.
       * This is done using MX records, and the hostnames or ip addresses
       * are returned sorted by MX priority.
       *
       * @param host - the domain name for which to find mail servers
       * @return a Collection of Strings of hostnames, sorted by priority
       */
      Collection getMailServers(String host);
  
      /**
       * Returns the postmaster's address for this mailet context.
       *
       * @return a MailAddress of the Postmaster's address
       */
      MailAddress getPostmaster();
  
      /**
       * Returns the mailet container attribute with the given name, or null
       * if there is no attribute by that name.  An attribute allows a mailet container
       * to give the mailet additional information not already provided by this interface.
       * See * your server documentation for information about its attributes. A list of
       * supported attributes can be retrieved using getAttributeNames.
       * <p>
       * The attribute is returned as a java.lang.Object or some subclass. Attribute
       * names should follow the same convention as package names. The Java Mailet API
       * specification reserves names matching java.*, javax.*, and sun.*
       *
       * @param name - a String specifying the name of the attribute
       * @return an Object containing the value of the attribute, or null if no attribute
       *      exists matching the given name
       */
      Object getAttribute(String name);
  
      /**
       * Returns an Iterator containing the attribute names available within
       * this mailet context.  Use the getAttribute(java.lang.String) method with an
       * attribute name to get the value of an attribute.
       *
       * @return an Iterator of attribute names
       */
      Iterator getAttributeNames();
  
      /**
       * Returns the minor version of the Mailet API that this mailet
       * container supports. All implementations that comply with Version 1.2 must have
       * this method return the integer 1.
       *
       * @return 1
       */
      int getMajorVersion();
  
      /**
       * Returns the minor version of the Mailet API that this mailet
       * container supports.  All implementations that comply with Version 1.2 must have
       * this method return the integer 2.
       *
       * @return 2
       */
      int getMinorVersion();
  
      /**
       * Returns the name and version of the mailet container on which
       * the mailet is running.
       * <p>
       * The form of the returned string is servername/versionnumber. For example,
       * JAMES may return the string JAMES/1.2.
       * <p>
       * The mailet container may return other optional information after the primary
       * string in parentheses, for example, JAMES/1.2 (JDK 1.3.0; Windows NT 4.0 x86).
       *
       * @return a String containing at least the mailet container name and version number
       */
      String getServerInfo();
  
      /**
       * Checks if a server is serviced by mail context
       *
       * @param serverName - name of server.
       * @return true if server is local, i.e. serviced by this mail context
       */
      boolean isLocalServer(String serverName);
  
      /**
       * Checks if a user account is exists in the mail context.
       *
       * @param userAccount - user identifier.
       * @return true if the acount is a local account
       */
      boolean isLocalUser(String userAccount);
  
      /**
       * Writes the specified message to a mailet log file, usually an event
       * log.  The name and type of the mailet log file is specific to the mailet
       * container.
       *
       * @param msg - a String specifying the message to be written to the log file
       */
      void log(String message);
  
      /**
       * Writes an explanatory message and a stack trace for a given Throwable
       * exception to the mailet log file.
       *
       * @param message - a String that describes the error or exception
       * @param throwable - the Throwable error or exception
       */
      void log(String message, Throwable t);
  
      /**
       * Removes the attribute with the given name from the mailet context.  After
       * removal, subsequent calls to getAttribute(java.lang.String) to retrieve
       * the attribute's value will return null.
       *
       * @param name - a String specifying the name of the attribute to be removed
       */
      void removeAttribute(String name);
  
      /**
       * Send an outgoing message to the top of this mailet container's root queue.
       * This is the equivalent of opening an SMTP session to localhost.
       * This uses sender and recipients as specified in the message itself.
       *
       * @param msg - the MimeMessage of the headers and body content of the outgoing message
       * @throws MessagingException - if the message fails to parse
       */
      void sendMail(MimeMessage msg)
          throws MessagingException;
  
      /**
       * Send an outgoing message to the top of this mailet container's root queue.
       * Is the equivalent of opening an SMTP session to localhost.
       *
       * @param sender - the sender of the message
       * @param recipients - a Collection of String objects of recipients
       * @param msg - the MimeMessage of the headers and body content of the outgoing message
       * @throws MessagingException - if the message fails to parse
       */
      void sendMail(MailAddress sender, Collection recipients, MimeMessage msg)
          throws MessagingException;
  
      /**
       * Send an outgoing message to the top of this mailet container queue for the
       * appropriate processor that is specified.
       *
       * @param sender - the sender of the message
       * @param recipients - a Collection of String objects of recipients
       * @param msg - the MimeMessage of the headers and body content of the outgoing message
       * @param state - the state of the message, indicates which processor to use
       * @throws MessagingException - if the message fails to parse
       */
      void sendMail(MailAddress sender, Collection recipients, MimeMessage msg, String state)
          throws MessagingException;
  
      /**
       * Binds an object to a given attribute name in this mailet context.  If the name
       * specified is already used for an attribute, this method will remove the old
       * attribute and bind the name to the new attribute.
       * <p>
       * Attribute names should follow the same convention as package names. The Java
       * Mailet API specification reserves names matching java.*, javax.*, and sun.*.
       *
       * @param name - a String specifying the name of the attribute
       * @param object - an Object representing the attribute to be bound
       */
      void setAttribute(String name, Object object);
  
      /**
       * Stores mail into local accounts (POP3 by default, or the IMAP4 Inbox)
       *
       * @param sender - the sender of the incoming message
       * @param recipient - the user who is receiving this message (as a complete email address)
       * @param msg - the MimeMessage to store in a local mailbox
       * @throws MessagingException - if the message fails to parse
       */
      void storeMail(MailAddress sender, MailAddress recipient, MimeMessage msg)
          throws MessagingException;
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/MailetException.java
  
  Index: MailetException.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import javax.mail.*;
  
  /**
   * Defines a general exception a mailet can throw when it encounters difficulty.
   *
   * @version 1.0.0, 24/04/1999
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public class MailetException extends MessagingException {
  
      /**
       * Constructs a new mailet exception.
       */
      public MailetException() {
          super();
      }
  
      /**
       * Constructs a new mailet exception with the specified message.
       */
      public MailetException(String message) {
          super(message);
      }
  
      /**
       * Constructs a new mailet exception when the mailet needs to throw
       * an exception and include a message about the "root cause" exception
       * that interfered with its normal operation, including a description
       * message.
       */
      public MailetException(String message, Exception e) {
          super(message, e);
      }
  
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/Matcher.java
  
  Index: Matcher.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  import java.util.*;
  
  /**
   * This interface define the behaviour of the message "routing" inside
   * the mailet container. The match(Mail) method returns a Collection of
   * recipients that meet this class's criteria.
   * <p>
   * An important feature of the mailet container is the ability to fork
   * processing of messages.  When a message first arrives at the server,
   * it might have multiple recipients specified.  As a message is passed
   * to a matcher, the matcher might only "match" one of the listed
   * recipients.  It would then return only the matching recipient in
   * the Collection.  The mailet container should then duplicate the
   * message splitting the recipient list across the two messages as per
   * what the matcher returned.
   * <p>
   * <b>[THIS PARAGRAPH NOT YET IMPLEMENTED]</b>
   * <i>The matcher can extend this forking to further separation by returning
   * a Collection of Collection objects.  This allows a matcher to fork
   * multiple processes if there are multiple recipients that require
   * separate processing.  For example, we could write a ListservMatcher
   * that handles multiple listservs.  When someone cross-posts across
   * multiple listservs that this matcher handles, it could put each
   * listserv address (recipient) that it handles in a separate Collection
   * object.  By returning each of these Collections within a container
   * Collection object, it could indicate to the mailet container how
   * many forks to spawn.</i>
   * <p>
   * This interface defines methods to initialize a matcher, to match
   * messages, and to remove a matcher from the server. These are known
   * as life-cycle methods and are called in the following sequence:
   * <ol>
   * <li>The matcher is constructed, then initialized with the init method.</li>
   * <li>Any calls from clients to the match method are handled.</li>
   * <li>The matcher is taken out of service, then destroyed with the
   *      destroy method, then garbage collected and finalized.</li>
   * </ol>
   * In addition to the life-cycle methods, this interface provides the
   * getMatcherConfig method, which the matcher can use to get any startup
   * information, and the getMatcherInfo method, which allows the matcher
   * to return basic information about itself, such as author, version,
   * and copyright.
   *
   * @version 1.0.0, 24/04/1999
   * @author Federico Barbieri <sc...@pop.systemy.it>
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public interface Matcher {
  
      /**
       * Called by the mailet container to indicate to a matcher that the matcher
       * is being taken out of service. This method is only called once all threads
       * within the matcher's service method have exited or after a timeout period
       * has passed. After the mailet container calls this method, it will not call
       * the match method again on this matcher.
       * <p>
       * This method gives the matcher an opportunity to clean up any resources that
       * are being held (for example, memory, file handles, threads) and make sure
       * that any persistent state is synchronized with the matcher's current state in memory.
       */
      void destroy();
  
      /**
       * Returns a MatcherConfig object, which contains initialization and
       * startup parameters for this matcher.
       * <p>
       * Implementations of this interface are responsible for storing the
       * MatcherConfig object so that this method can return it. The GenericMatcher
       * class, which implements this interface, already does this.
       *
       * @return the MatcherConfig object that initializes this matcher
       */
      MatcherConfig getMatcherConfig();
  
      /**
       * Returns information about the matcher, such as author, version, and copyright.
       * <p>
       * The string that this method returns should be plain text and not markup
       * of any kind (such as HTML, XML, etc.).
       *
       * @return a String containing matcher information
       */
      String getMatcherInfo();
  
      /**
       * Called by the mailet container to indicate to a matcher that the
       * matcher is being placed into service.
       * <p>
       * The mailet container calls the init method exactly once after instantiating
       * the matcher. The init method must complete successfully before the matcher
       * can receive any messages.
       *
       * @param config - a MatcherConfig object containing the matcher's configuration
       *          and initialization parameters
       * @throws javax.mail.MessagingException - if an exception has occurred that
       *          interferes with the matcher's normal operation
       */
      void init( MatcherConfig config ) throws javax.mail.MessagingException;
  
      /**
       * Takes a Mail message, looks at any pertinent information, and then returns a subset
       * of recipients that meet the "match" conditions.
       * <p>
       * This method is only called after the matcher's init() method has completed
       * successfully.
       * <p>
       * Matchers typically run inside multithreaded mailet containers that can handle
       * multiple requests concurrently. Developers must be aware to synchronize access
       * to any shared resources such as files, network connections, and as well as the
       * matcher's class and instance variables. More information on multithreaded
       * programming in Java is available in <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">the
       * Java tutorial on multi-threaded programming</a>.
       *
       * @param mail - the Mail object that contains the message and routing information
       * @return a Collection of String objects (recipients) that meet the match criteria
       * @throws MessagingException - if an message or address parsing exception occurs or
       *      an exception that interferes with the matcher's normal operation
       */
      Collection match( Mail mail ) throws javax.mail.MessagingException;
  }
  
  
  
  1.1                  jakarta-james/src/java/org/apache/mailet/MatcherConfig.java
  
  Index: MatcherConfig.java
  ===================================================================
  /*
   * Copyright (C) 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.mailet;
  
  /**
   * A matcher configuration object used by a mailet container used to pass information
   * to a matcher during initialization.
   * <p>
   * The configuration information contains an initialization parameter,
   * which is set as a condition String, and a MailetContext object,
   * which gives the mailet information about the mailet container.
   *
   * @version 1.0.0, 24/04/1999
   * @author Serge Knystautas <se...@lokitech.com>
   */
  public interface MatcherConfig {
  
      /**
       * The simple condition defined for this matcher, e.g., for
       * SenderIs=admin@localhost, this would return admin@localhost.
       *
       * @return a String containing the value of the initialization parameter
       */
      String getCondition();
  
      /**
       * Returns a reference to the MailetContext in which the matcher is executing
       *
       * @return a MailetContext object, used by the matcher to interact with its
       *      mailet container
       */
      MailetContext getMailetContext();
  
      /**
       * Returns the name of this matcher instance. The name may be provided via server
       * administration, assigned in the application deployment descriptor, or for
       * an unregistered (and thus unnamed) matcher instance it will be the matcher's
       * class name.
       *
       * @return the name of the matcher instance
       */
      String getMatcherName();
  }
  
  
  

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