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 pg...@apache.org on 2002/10/14 09:03:49 UTC

cvs commit: jakarta-james/proposals/imap/java/org/apache/james James.java

pgoldstein    2002/10/14 00:03:49

  Modified:    proposals/imap/conf james-assembly.xml james-config.xml
                        james-server.xml
               proposals/imap/java/org/apache/james James.java
  Log:
  Modified the IMAP build to deal with a couple of build issues.
  Brought the James.java and assorted Phoenix deployment files up
  to current revision.
  Thanks to Peter Loffler
  
  Revision  Changes    Path
  1.4       +56 -50    jakarta-james/proposals/imap/conf/james-assembly.xml
  
  Index: james-assembly.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/imap/conf/james-assembly.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- james-assembly.xml	17 Sep 2002 21:51:27 -0000	1.3
  +++ james-assembly.xml	14 Oct 2002 07:03:49 -0000	1.4
  @@ -2,12 +2,28 @@
   
   <assembly>
   
  +  <!-- The list of blocks being run in this Phoenix server. -->
  +  <!-- -->
  +  <!-- Each block element has a name attribute that is unique -->
  +  <!-- among the blocks. It also has a class attribute that -->
  +  <!-- specifies the class providing that block-->
  +  <!-- -->
  +  <!-- The block element may have one or more provide sub-elements. -->
  +  <!-- Each provide element represents another block on which this -->
  +  <!-- block depends.  Phoenix will calculate a dependency chain when it -->
  +  <!-- reads this file, and will load and start the blocks in the order -->
  +  <!-- specified by that chain.  Each provide element has a name attribute, -->
  +  <!-- which matches the name of a block defined in this file.  It also -->
  +  <!-- has a role attribute.  This attribute is the string by which the -->
  +  <!-- enclosing block will identify the required block. -->
  +  <!-- -->
  +
     <!-- The James block  -->
  -  <block class="org.apache.james.James" name="James" >
  +  <block name="James" class="org.apache.james.James" >
   
       <!-- Specify which components will provide the services required by this
       block. The roles are specified in the code and the .xinfo file. The names
  -    here must match the names specified for  a Block in this xml file.   -->
  +    here must match the names specified for a Block in this xml file.   -->
       <provide name="dnsserver" role="org.apache.james.services.DNSServer"/>
       <provide name="mailstore" role="org.apache.james.services.MailStore"/>
       <provide name="users-store" role="org.apache.james.services.UsersStore"/>
  @@ -24,25 +40,22 @@
     </block>
   
     <!-- The James Spool Manager block  -->
  -  <block class="org.apache.james.transport.JamesSpoolManager"
  -         name="spoolmanager" >
  +  <block name="spoolmanager" class="org.apache.james.transport.JamesSpoolManager" >
       <provide name="James" role="org.apache.mailet.MailetContext"/>
       <provide name="mailstore" role="org.apache.james.services.MailStore"/>
       <provide name="thread-manager"
                role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
     </block>
   
  -  <block class="org.apache.james.dnsserver.DNSServer" name="dnsserver"/>
  +  <block name="dnsserver" class="org.apache.james.dnsserver.DNSServer" />
   
  -  <block class="org.apache.james.remotemanager.RemoteManager" name="remotemanager" >
  +  <block name="remotemanager" class="org.apache.james.remotemanager.RemoteManager" >
       <provide name="mailstore" role="org.apache.james.services.MailStore"/>
       <provide name="users-store" role="org.apache.james.services.UsersStore"/>
       <provide name="sockets"
  -        role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
  +             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
       <provide name="connections"
  -        role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
  -    <provide name="scheduler"
  -        role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/>
  +             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
       <provide name="James" role="org.apache.james.services.MailServer"/>
     </block>
   
  @@ -70,56 +83,51 @@
     </block>
   
     <!-- POP3 Server -->
  -  <block class="org.apache.james.pop3server.POP3Server" name="pop3server" >
  +  <block name="pop3server" class="org.apache.james.pop3server.POP3Server" >
       <provide name="mailstore" role="org.apache.james.services.MailStore"/>
       <provide name="users-store" role="org.apache.james.services.UsersStore"/>
       <provide name="sockets"
  -        role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
  +             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
       <provide name="connections"
  -        role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
  -    <provide name="scheduler"
  -        role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/>
  +             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
       <provide name="James" role="org.apache.james.services.MailServer"/>
     </block>
   
     <!-- SMTP Server -->
  -  <block class="org.apache.james.smtpserver.SMTPServer" name="smtpserver" >
  +  <block name="smtpserver" class="org.apache.james.smtpserver.SMTPServer" >
       <provide name="James" role="org.apache.mailet.MailetContext"/>
       <provide name="mailstore" role="org.apache.james.services.MailStore"/>
       <provide name="users-store" role="org.apache.james.services.UsersStore"/>
       <provide name="sockets"
  -        role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
  +             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
       <provide name="connections"
  -        role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
  -    <provide name="scheduler"
  -        role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/>
  +             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
       <provide name="James" role="org.apache.james.services.MailServer"/>
     </block>
   
     <!-- NNTP Server -->
  -  <block class="org.apache.james.nntpserver.NNTPServer" name="nntpserver" >
  -    <provide name="nntpauth" role="org.apache.james.nntpserver.AuthService"/>
  +  <block name="nntpserver" class="org.apache.james.nntpserver.NNTPServer" >
  +    <provide name="users-store" role="org.apache.james.services.UsersStore"/>
       <provide name="sockets"
  -        role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
  +             role="org.apache.avalon.cornerstone.services.sockets.SocketManager"/>
       <provide name="connections"
  -        role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
  -    <provide name="scheduler"
  -        role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/>
  +             role="org.apache.avalon.cornerstone.services.connection.ConnectionManager"/>
       <provide name="nntp-repository"
  -        role="org.apache.james.nntpserver.repository.NNTPRepository"/>
  -  </block>
  -
  -  <!-- NNTP Authentication Service -->
  -  <block class="org.apache.james.nntpserver.AuthServiceImpl" name="nntpauth" >
  -    <provide name="users-store" role="org.apache.james.services.UsersStore"/>
  +             role="org.apache.james.nntpserver.repository.NNTPRepository"/>
     </block>
   
     <!-- NNTP Repository -->
  -  <block class="org.apache.james.nntpserver.repository.NNTPRepositoryImpl" name="nntp-repository" >
  +  <block name="nntp-repository" class="org.apache.james.nntpserver.repository.NNTPRepositoryImpl" />
  +
  +  <!-- FetchPOP Service -->
  +  <block name="fetchpop" class="org.apache.james.fetchpop.FetchScheduler" >
  +    <provide name="scheduler"
  +             role="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler"/> 
  +    <provide name="James" role="org.apache.james.services.MailServer"/>      
     </block>
   
     <!-- The High Level Storage block -->
  -  <block class="org.apache.james.core.AvalonMailStore" name="mailstore" >
  +  <block name="mailstore" class="org.apache.james.core.AvalonMailStore" >
       <provide name="objectstorage"
                role="org.apache.avalon.cornerstone.services.store.Store"/>
       <provide name="database-connections"
  @@ -127,7 +135,7 @@
     </block>
   
     <!-- The User Storage block -->
  -  <block class="org.apache.james.core.AvalonUsersStore" name="users-store" >
  +  <block name="users-store" class="org.apache.james.core.AvalonUsersStore" >
       <!-- Configure file based user store here, defaults should be fine -->
       <provide name="objectstorage"
                role="org.apache.avalon.cornerstone.services.store.Store"/>
  @@ -141,35 +149,33 @@
          (unless you want secure sockets (TLS)) -->
   
     <!-- The Storage block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.masterstore.RepositoryManager"
  -         name="objectstorage">
  -  </block>
  +  <block name="objectstorage"
  +         class="org.apache.avalon.cornerstone.blocks.masterstore.RepositoryManager" />
   
     <!-- The Connection Manager block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.connection.DefaultConnectionManager"
  -           name="connections">
  +  <block name="connections"
  +         class="org.apache.james.util.connection.SimpleConnectionManager" >
       <provide name="thread-manager"
                role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
     </block>
   
     <!-- The Socket Manager block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.sockets.DefaultSocketManager"
  -         name="sockets"/>
  +  <block name="sockets"
  +         class="org.apache.avalon.cornerstone.blocks.sockets.DefaultSocketManager"/>
   
  -  <!-- The Time Manager block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.scheduler.DefaultTimeScheduler"
  -         name="scheduler">
  +  <!-- The Time Scheduler block -->
  +  <block name="scheduler"
  +         class="org.apache.avalon.cornerstone.blocks.scheduler.DefaultTimeScheduler" >
       <provide name="thread-manager"
                role="org.apache.avalon.cornerstone.services.threads.ThreadManager" />
     </block>
   
     <!-- The DataSourceSelector block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.datasource.DefaultDataSourceSelector"
  -         name="database-connections"/>
  +  <block name="database-connections"
  +         class="org.apache.avalon.cornerstone.blocks.datasource.DefaultDataSourceSelector" />
   
     <!-- The ThreadManager block -->
  -  <block class="org.apache.avalon.cornerstone.blocks.threads.DefaultThreadManager"
  -         name="thread-manager" />
  +  <block name="thread-manager"
  +         class="org.apache.avalon.cornerstone.blocks.threads.DefaultThreadManager" />
   
   </assembly>
  -
  
  
  
  1.4       +110 -26   jakarta-james/proposals/imap/conf/james-config.xml
  
  Index: james-config.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/imap/conf/james-config.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- james-config.xml	17 Sep 2002 21:51:27 -0000	1.3
  +++ james-config.xml	14 Oct 2002 07:03:49 -0000	1.4
  @@ -7,10 +7,10 @@
                                  README!
   
   This configuration file is designed to run without alteration for simple tests.
  -It assumes you have a DNS server on localhost and assigns a root pasword of root.
  +It assumes you have a DNS server on localhost and assigns a root password of root.
   
   In case the defaults do not suit you, the items you are most likely to need to change
  -are preceeded by a CHECKME! or CONFIRM? comment in the left margin.
  +are preceded by a CHECKME! or CONFIRM? comment in the left margin.
   
   For production use you will probably need to make more extensive changes, see
   http://jakarta.apache.org/james/configuration_v2_0.html
  @@ -30,14 +30,24 @@
              If autodetectIP is not FALSE, James will also allow add the IP address for each servername.
              The automatic IP detection is to support RFC 2821, Sec 4.1.3, address literals.
              By default, the servername 'localhost' is specified. This can be removed, if required. -->
  -      <servernames autodetect="TRUE" autodetectIP="TRUE">
  +      <servernames autodetect="true" autodetectIP="true">
            <!--<servername>To override autodetected server names  uncomment this.  </servername> -->
            <servername>localhost</servername>
  +        <!-- IMPORTANT if you are using fetchpop it is important to include the -->
  +        <!-- fetched domains here to prevent looping                            -->
         </servernames>
   
         <!-- Set whether user names are case sensitive or case insensitive -->
         <!-- Set whether to enable local aliases -->
  -      <usernames ignoreCase="TRUE" enableAliases="TRUE" enableForwarding="TRUE"/>
  +      <usernames ignoreCase="true" enableAliases="true" enableForwarding="true"/>
  +
  +      <!-- Set the type of permanent mailfolders to be used.      -->
  +      <!-- If IMAP service is to be provided, the storage type
  +      <!-- must be 'IMAP'; if only POP3 service is being provided -->
  +      <!-- then use must be 'basic' (default) . At some stage POP3-->
  +      <!-- will, hopefully, be able to use IMAP storage as well.  -->
  +      <!-- This choice is irrelevant if the only service provided is SMTP. -->
  +      <storage>IMAP</storage>
   
         <!-- The inbox repository is the location for users inboxes -->
         <!-- Default setting: file based repository - enter path ( use  "file:///" for absolute) -->
  @@ -54,7 +64,28 @@
            <repository destinationURL="db://maildb/inbox/" type="MAIL"/>
         </inboxRepository>-->
      </James>
  -
  +   
  +   <!-- Fetch pop block, fetches mail from POP3 servers and inserts it into the incoming spool -->
  +   <!-- IMPORTANT it is important to prevent mail from looping by setting the  -->
  +   <!-- fetched domains in the <servernames> section of the <James> block      -->
  +   <!-- above. fetchpop is disabled by default.                                  -->
  +   
  +    <fetchpop enabled="false">
  +        <!-- you can have as many fetch tasks as you want to        -->
  +        <!-- but each must have a unique name to identify itself by -->
  +        <fetch name="mydomain.com">
  +            <!-- host name or IP address -->
  +            <host>mail.mydomain.com</host>
  +            <!-- acount login username -->
  +            <user>username</user>
  +            <!-- account login password -->
  +            <password>pass</password>
  +            <!-- Interval to check this account in milliseconds, 600000 is every ten minutes -->
  +            <interval>600000</interval>
  +        </fetch>
  +    </fetchpop>
  +    
  +    
      <!-- The James Spool Manager block  -->
      <spoolmanager>
         <!-- number of spool threads -->
  @@ -96,7 +127,7 @@
            <!-- Sample matching to kill a message (send to Null) -->
            <mailet match="RecipientIs=badboy@badhost" class="Null"/>
   
  -         <!-- Send remaining mails to the transport processor for either  local or remote delivery -->
  +         <!-- Send remaining mails to the transport processor for either local or remote delivery -->
            <mailet match="All" class="ToProcessor">
               <processor> transport </processor>
            </mailet>
  @@ -119,7 +150,7 @@
            <!--<mailet match="All" class="NotifyPostmaster"/>-->
         </processor>
   
  -      <!--  Processor CONFIGURATION SAMPLE: transport is a sample custom  processor for local or remote delivery -->
  +      <!--  Processor CONFIGURATION SAMPLE: transport is a sample custom processor for local or remote delivery -->
         <processor name="transport">
   
            <!-- Is the recipient is for a local account, deliver it locally -->
  @@ -130,7 +161,7 @@
               <processor>error</processor>
            </mailet>
   
  -<!-- CHECKME!    Anti-relay mailet: Add your network address here,
  +        <!-- CHECKME!    Anti-relay mailet: Add your network address here,
                     e.g. "RemoteAddrNotInNetwork=127.0.0.1, abc.de.*, 192.168.0.*"-->
   
            <!-- This matcher-mailet pair can prevent relaying...
  @@ -221,7 +252,7 @@
                  autodetect is TRUE, James will attempt to discover its own name OR
                  use 'localhost'. If autodetect is FALSE, James will use the value
                  given OR 'localhost' -->
  -         <helloName autodetect="TRUE">myMailServer</helloName>
  +         <helloName autodetect="true">myMailServer</helloName>
            <administrator_accounts>
   <!-- CHECKME! Change the default password! -->
   <!-- FILL ME!!!!!!  You must provide a password for your  administrator accounts (cannot be blank) -->
  @@ -266,7 +297,10 @@
     <imapsystem>
     </imapsystem>
   
  -   <pop3server>
  +    <!-- The POP3 server is enabled by default -->
  +    <!-- Disabling blocks will stop them from listening, -->
  +    <!-- but does not free as many resources as removing them would -->
  +   <pop3server enabled="true">
         <!-- port 995 is the well-known/IANA registered port for POP3S  ie over SSL/TLS -->
         <!-- port 100 is the well-known/IANA registered port for Standard POP3 -->
         <port>110</port>
  @@ -282,12 +316,15 @@
                  autodetect is TRUE, James will attempt to discover its own name OR
                  use 'localhost'. If autodetect is FALSE, James will use the value
                  given OR 'localhost' -->
  -         <helloName autodetect="TRUE">myMailServer</helloName>
  +         <helloName autodetect="true">myMailServer</helloName>
            <connectiontimeout>120000</connectiontimeout>
         </handler>
      </pop3server>
   
  -   <smtpserver>
  +    <!-- The SMTP server is enabled by default -->
  +    <!-- Disabling blocks will stop them from listening, -->
  +    <!-- but does not free as many resources as removing them would -->
  +   <smtpserver enabled="true">
         <port>25</port>
   
         <!--  uncomment this if you want to bind to a specific inetaddress -->
  @@ -301,7 +338,7 @@
                autodetect is TRUE, James will attempt to discover its own name OR
                use 'localhost'. If autodetect is FALSE, James will use the value
                given OR 'localhost' -->
  -         <helloName autodetect="TRUE">myMailServer</helloName>
  +         <helloName autodetect="true">myMailServer</helloName>
            <connectiontimeout>360000</connectiontimeout>
            <!--  uncomment this if you want
                  SMTP AUTH support. This is useful if you have users who need to use
  @@ -318,7 +355,11 @@
            <maxmessagesize>0</maxmessagesize>
         </handler>
      </smtpserver>
  -   <nntpserver>
  +   
  +    <!-- The NNTP server is enabled by default -->
  +    <!-- Disabling blocks will stop them from listening, -->
  +    <!-- but does not free as many resources as removing them would -->
  +   <nntpserver enabled="true">
         <!-- port 563 is the well-known/IANA registered port for nntp over SSL/TLS -->
         <!-- port 119 is the well-known/IANA registered port for Standard nntp -->
         <port>119</port>
  @@ -334,16 +375,13 @@
               autodetect is TRUE, James will attempt to discover its own name OR
               use 'localhost'. If autodetect is FALSE, James will use the value
               given OR 'localhost' -->
  -         <helloName autodetect="TRUE">myMailServer</helloName>
  +         <helloName autodetect="true">myMailServer</helloName>
            <connectiontimeout>120000</connectiontimeout>
  +          <!-- Set the authRequired value to true to enable authenticated NNTP -->
  +         <authRequired>false</authRequired>
         </handler>
      </nntpserver>
   
  -   <nntpauth>
  -      <!-- make this true, if you want only authenticated users to access NNTP-->
  -      <authRequired>false</authRequired>
  -   </nntpauth>
  -
      <nntp-repository>
         <!-- make this true to disallow posting to all newsgroups-->
         <readOnly>false</readOnly>
  @@ -462,8 +500,8 @@
         User repositories are required for the following purposes:
         - holding information about Users of the James mail server
         - holding lists of users for the listserv mailet
  -      Currently, 2 different storage options are available:
  -      - file-based storage using Java serialisation
  +      Currently, two different storage options are available:
  +      - file-based storage using Java serialization
         - database-backed storage
         (Use of database or file-system is defined on a "per-repository" basis)
         Note: Two user repositories are required for default configuration:
  @@ -535,8 +573,19 @@
         </data-sources>
      </database-connections>
   
  -   <!-- Configuration for Cornerstone Blocks only after here NOTHING BELOW THIS SHOULD NEED CHANGING,
  -    (unless you want secure sockets (TLS)) -->
  +   <!-- Configuration for Cornerstone Services -->
  +   <!-- -->
  +   <!-- For a simple configuration, nothing beneath this line should require -->
  +   <!-- alteration. -->
  +   <!-- -->
  +   <!-- You will need to adjust the Socket Manager service configuration if you want -->
  +   <!-- to enable secure sockets (TLS) for any James service.                        -->
  +   <!-- -->
  +   <!-- Complex or high volume configurations may require changes to the parameters -->
  +   <!-- in this section.  Please read the James and Avalon documentation before -->
  +   <!-- attempting to adjust this section. -->
  +   <!-- -->
  +
      <!-- The Storage block -->
      <objectstorage>
         <repositories>
  @@ -568,7 +617,42 @@
            </repository>
         </repositories>
      </objectstorage>
  +   <!-- The Connection Manager block -->
  +   <!-- -->
  +   <!-- The idle-timeout is the number of milliseconds that it will take for idle -->
  +   <!-- client connections managed by this connection manager to be marked at timed out. -->
  +   <!-- If no value is specified, the value defaults to 5 minutes, 300000 milliseconds -->
  +   <!-- A value of 0 means that client sockets will not timeout. -->
  +   <!-- -->
  +   <!-- The max-connections parameter specifies the maximum number of client connections -->
  +   <!-- that this connection manager will allow per managed server socket. -->
  +   <!-- If no value is specified, the value defaults to 30. -->
  +   <!-- A value of 0 means that there is no limit imposed by the connection manager, although -->
  +   <!-- resource limitations imposed by other components (i.e. max # of threads) may -->
  +   <!-- serve to limit the number of open connections. -->
  +   <!-- -->
  +   <connections>
  +      <idle-timeout>300000</idle-timeout>
  +      <max-connections>30</max-connections>
  +   </connections>
      <!-- The Socket Manager block -->
  +   <!-- -->
  +   <!-- The server-sockets element has a number of factory sub-elements. -->
  +   <!-- Each of the factory elements has a name and class attribute -->
  +   <!-- The name attribute for each factory element must be unique.  -->
  +   <!-- The class attribute is the name of a class that implements the -->
  +   <!-- interface org.apache.avalon.cornerstone.services.ServerSocketFactory -->
  +   <!-- Specific factory elements may require some sub-elements.  This is -->
  +   <!-- factory class dependent. -->
  +   <!-- -->
  +   <!-- The client-sockets element has a number of factory sub-elements. -->
  +   <!-- Each of the factory elements has a name and class attribute -->
  +   <!-- The name attribute for each factory element must be unique.  -->
  +   <!-- The class attribute is the name of a class that implements the -->
  +   <!-- interface org.apache.avalon.cornerstone.services.SocketFactory -->
  +   <!-- Specific factory elements may require some sub-elements.  This is -->
  +   <!-- factory class dependent. -->
  +   <!-- -->
      <sockets>
         <server-sockets>
            <factory name="plain" class="org.apache.avalon.cornerstone.blocks.sockets.DefaultServerSocketFactory"/>
  @@ -594,7 +678,7 @@
            <priority>5</priority>
            <!-- are threads daemon threads ? -->
            <is-daemon>false</is-daemon>
  -         <max-threads>40</max-threads>
  +         <max-threads>100</max-threads>
            <!-- these are ignored at the moment but will be fixed in later revisions -->
            <min-threads>20</min-threads>
            <min-spare-threads>20</min-spare-threads>
  
  
  
  1.3       +9 -1      jakarta-james/proposals/imap/conf/james-server.xml
  
  Index: james-server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/imap/conf/james-server.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- james-server.xml	17 Sep 2002 21:51:27 -0000	1.2
  +++ james-server.xml	14 Oct 2002 07:03:49 -0000	1.3
  @@ -27,7 +27,7 @@
           <log-target id-ref="remotemanager-target"/>
         </category>
         <category name="imapserver" log-level="DEBUG"/>
  -        <log-target name="imapserver-target"/>
  +        <log-target id-ref="imapserver-target"/>
         </category>
         <category name="pop3server" log-level="DEBUG">
           <log-target id-ref="pop3server-target"/>
  @@ -59,6 +59,9 @@
         <category name="scheduler" log-level="DEBUG">
           <log-target id-ref="scheduler-target"/>
         </category>
  +      <category name="fetchpop" log-level="INFO">
  +        <log-target id-ref="fetchpop-target"/>
  +      </category>
       </categories>
   
       <targets>
  @@ -145,6 +148,11 @@
         <file id="scheduler-target">
           <filename>${app.home}/logs/scheduler.log</filename>
           <format>%{time:dd/MM/yy hh:mm:ss} %5.5{priority} %{category}: %{message}\n%{throwable}</format>
  +        <append>true</append>
  +      </file>
  +      <file id="fetchpop-target">
  +        <filename>${app.home}/logs/fetchpop.log</filename>
  +        <format>%{time:dd/MM/yy HH:mm:ss} %5.5{priority} %{category}: %{message}\n%{throwable}</format>
           <append>true</append>
         </file>
       </targets>
  
  
  
  1.6       +407 -71   jakarta-james/proposals/imap/java/org/apache/james/James.java
  
  Index: James.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/proposals/imap/java/org/apache/james/James.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- James.java	9 Aug 2002 16:48:05 -0000	1.5
  +++ James.java	14 Oct 2002 07:03:49 -0000	1.6
  @@ -18,14 +18,14 @@
   import org.apache.avalon.framework.context.DefaultContext;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.logger.Logger;
  -import org.apache.avalon.phoenix.BlockContext;
   import org.apache.james.core.MailHeaders;
   import org.apache.james.core.MailImpl;
  +import org.apache.james.imapserver.ACLMailbox;
  +import org.apache.james.imapserver.Host;
   import org.apache.james.services.*;
   import org.apache.james.userrepository.DefaultJamesUser;
  +import org.apache.james.util.RFC2822Headers;
   import org.apache.james.util.RFC822DateFormat;
  -import org.apache.james.imapserver.ACLMailbox;
  -import org.apache.james.imapserver.Host;
   import org.apache.mailet.Mail;
   import org.apache.mailet.MailAddress;
   import org.apache.mailet.MailetContext;
  @@ -55,87 +55,186 @@
    * @author Serge
    * @author <a href="mailto:charles@benett1.demon.co.uk">Charles Benett</a>
    *
  -
  - * This is $Revision$
  - * Committed on $Date$ by: $Author$
  + * @version This is $Revision$
   
    */
   public class James
       extends AbstractLogEnabled
  -    implements Contextualizable, Composable, Configurable,
  +    implements Contextualizable, Composable, Configurable, JamesMBean,
                  Initializable, MailServer, MailetContext, Component {
   
  -    private final static String VERSION = Constants.SOFTWARE_NAME + " " + Constants.SOFTWARE_VERSION;
  -    private final static boolean DEEP_DEBUG = true;
  +    /**
  +     * The software name and version
  +     */
  +    private final static String SOFTWARE_NAME_VERSION = Constants.SOFTWARE_NAME + " " + Constants.SOFTWARE_VERSION;
   
  +    /**
  +     * The component manager used both internally by James and by Mailets.
  +     */
       private DefaultComponentManager compMgr; //Components shared
  +
  +    /**
  +     * TODO: Investigate what this is supposed to do.  Looks like it
  +     *       was supposed to be the Mailet context.
  +     */
       private DefaultContext context;
  +
  +    /**
  +     * The top level configuration object for this server.
  +     */
       private Configuration conf;
   
  +    /**
  +     * The logger used by the Mailet API.
  +     */
       private Logger mailetLogger = null;
  +
  +    /**
  +     * The mail store containing the inbox repository and the spool.
  +     */
       private MailStore mailstore;
  +
  +    /**
  +     * The store containing the local user repository.
  +     */
       private UsersStore usersStore;
  +
  +    /**
  +     * The spool used for processing mail handled by this server.
  +     */
       private SpoolRepository spool;
  +
  +    /**
  +     * The repository that stores the user inboxes.
  +     */
       private MailRepository localInbox;
  +
  +    /**
  +     * The root URL used to get mailboxes from the repository
  +     */
       private String inboxRootURL;
  +
  +    /**
  +     * The user repository for this mail server.  Contains all the users with inboxes
  +     * on this server.
  +     */
       private UsersRepository localusers;
  +
  +    /**
  +     * The collection of domain/server names for which this instance of James
  +     * will receive and process mail.
  +     */
       private Collection serverNames;
  +
  +    /**
  +     * Whether to ignore case when looking up user names on this server
  +     */
       private boolean ignoreCase;
  +
  +    /**
  +     * Whether to enable aliasing for users on this server
  +     */
       private boolean enableAliases;
  +
  +    /**
  +     * Whether to enable forwarding for users on this server
  +     */
       private boolean enableForwarding;
   
  -    // this used to be long, but increment operations on long are not
  -    // thread safe. Changed to int. 'int' should be ok, because id generation
  -    // is based on System time and count
  -    private static int count;
  +    /**
  +     * The number of mails generated.  Access needs to be synchronized for
  +     * thread safety and to ensure that all threads see the latest value.
  +     */
  +    private static long count;
  +
  +    /**
  +     * The address of the postmaster for this server
  +     */
       private MailAddress postmaster;
  +
  +    /**
  +     * A map used to store mailboxes and reduce the cost of lookup of individual
  +     * mailboxes.
  +     */
       private Map mailboxes; //Not to be shared!
  +
  +    /**
  +     * A hash table of server attributes
  +     * These are the MailetContext attributes
  +     */
       private Hashtable attributes = new Hashtable();
   
  -    // IMAP related fields
  +    /**
  +     * The Avalon context used by the instance
  +     */
  +    protected Context           myContext;
  +
  +    /**
  +     * An RFC822 date formatter used to format dates in mail headers
  +     */
  +    private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
  +
  +    /**
  +     * Whether James should use IMAP storage
  +     */
       private boolean useIMAPstorage = false;
  -    private Host imapHost;
  -    
  -    protected BlockContext           blockContext;
   
  +    /**
  +     * The host to be used for IMAP storage
  +     */
  +    private Host imapHost;
   
  +    /**
  +     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(Context)
  +     */
       public void contextualize(final Context context) {
  -        this.blockContext = (BlockContext)context;
  -    }
  -
  -    public void configure(Configuration conf) {
  -        this.conf = conf;
  +        this.myContext = context;
       }
   
       /**
  -     * Override compose method of AbstractBlock to create new
  -     * ComponentManager object
  +     * @see org.apache.avalon.framework.component.Composable#compose(ComponentManager)
        */
       public void compose(ComponentManager comp) {
           compMgr = new DefaultComponentManager(comp);
           mailboxes = new HashMap(31);
       }
   
  +    /**
  +     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
  +     */
  +    public void configure(Configuration conf) {
  +        this.conf = conf;
  +    }
  +
  +    /**
  +     * @see org.apache.avalon.framework.activity.Initializable#initialize()
  +     */
       public void initialize() throws Exception {
   
           getLogger().info("JAMES init...");
   
           // TODO: This should retrieve a more specific named thread pool from
  -        // BlockContext that is set up in server.xml
  -        // workerPool = blockContext.getThreadPool( "default" );
  +        // Context that is set up in server.xml
           try {
               mailstore = (MailStore) compMgr.lookup( MailStore.ROLE );
           } catch (Exception e) {
  -            getLogger().warn("Can't get Store: " + e);
  +            if (getLogger().isWarnEnabled()) {
  +                getLogger().warn("Can't get Store: " + e);
  +            }
  +        }
  +        if (getLogger().isDebugEnabled()) {
  +            getLogger().debug("Using MailStore: " + mailstore.toString());
           }
  -        getLogger().debug("Using MailStore: " + mailstore.toString());
           try {
               usersStore = (UsersStore) compMgr.lookup( UsersStore.ROLE );
           } catch (Exception e) {
  -            getLogger().warn("Can't get Store: " + e);
  +            if (getLogger().isWarnEnabled()) {
  +                getLogger().warn("Can't get Store: " + e);
  +            }
  +        }
  +        if (getLogger().isDebugEnabled()) {
  +            getLogger().debug("Using UsersStore: " + usersStore.toString());
           }
  -        getLogger().debug("Using UsersStore: " + usersStore.toString());
  -        context = new DefaultContext();
   
           String hostName = null;
           try {
  @@ -143,37 +242,86 @@
           } catch  (UnknownHostException ue) {
               hostName = "localhost";
           }
  +
  +        context = new DefaultContext();
           context.put("HostName", hostName);
           getLogger().info("Local host is: " + hostName);
   
           // Get the domains and hosts served by this instance
  -        serverNames = new Vector();
  +        serverNames = new HashSet();
           Configuration serverConf = conf.getChild("servernames");
           if (serverConf.getAttributeAsBoolean("autodetect") && (!hostName.equals("localhost"))) {
  -            serverNames.add(hostName.toLowerCase());
  +            serverNames.add(hostName.toLowerCase(Locale.US));
           }
   
           final Configuration[] serverNameConfs =
               conf.getChild( "servernames" ).getChildren( "servername" );
           for ( int i = 0; i < serverNameConfs.length; i++ ) {
  -            serverNames.add( serverNameConfs[i].getValue());
  +            serverNames.add( serverNameConfs[i].getValue().toLowerCase(Locale.US));
  +
  +            if (serverConf.getAttributeAsBoolean("autodetectIP", true)) {
  +                try {
  +                    /* This adds the IP address(es) for each host to support
  +                     * support <us...@address-literal> - RFC 2821, sec 4.1.3.
  +                     * It might be proper to use the actual IP addresses
  +                     * available on this server, but we can't do that
  +                     * without NetworkInterface from JDK 1.4.  Because of
  +                     * Virtual Hosting considerations, we may need to modify
  +                     * this to keep hostname and IP associated, rather than
  +                     * just both in the set.
  +                     */
  +                    InetAddress[] addrs = InetAddress.getAllByName(serverNameConfs[i].getValue());
  +                    for (int j = 0; j < addrs.length ; j++) {
  +                        serverNames.add(addrs[j].getHostAddress());
  +                    }
  +                }
  +                catch(Exception genericException) {
  +                    getLogger().error("Cannot get IP address(es) for " + serverNameConfs[i].getValue());
  +                }
  +            }
           }
           if (serverNames.isEmpty()) {
               throw new ConfigurationException( "Fatal configuration error: no servernames specified!");
           }
   
  -        for (Iterator i = serverNames.iterator(); i.hasNext(); ) {
  -            getLogger().info("Handling mail for: " + i.next());
  +        if (getLogger().isInfoEnabled()) {
  +            for (Iterator i = serverNames.iterator(); i.hasNext(); ) {
  +                getLogger().info("Handling mail for: " + i.next());
  +            }
           }
           context.put(Constants.SERVER_NAMES, this.serverNames);
           attributes.put(Constants.SERVER_NAMES, this.serverNames);
   
   
           // Get postmaster
  -        String postMasterAddress = conf.getChild("postmaster").getValue("root@localhost");
  +        String postMasterAddress = conf.getChild("postmaster").getValue("postmaster");
  +        // if there is no @domain part, then add the first one from the
  +        // list of supported domains that isn't localhost.  If that
  +        // doesn't work, use the hostname, even if it is localhost.
  +        if (postMasterAddress.indexOf('@') < 0) {
  +            String domainName = null;    // the domain to use
  +            // loop through candidate domains until we find one or exhaust the list
  +            for ( int i = 0; domainName == null && i < serverNameConfs.length ; i++ ) {
  +                String serverName = serverNameConfs[i].getValue().toLowerCase(Locale.US);
  +                if (!("localhost".equals(serverName))) {
  +                    domainName = serverName;    // ok, not localhost, so use it
  +                }
  +            }
  +            // if we found a suitable domain, use it.  Otherwise fallback to the host name.
  +            postMasterAddress = postMasterAddress + "@" + (domainName != null ? domainName : hostName);
  +        }
           this.postmaster = new MailAddress( postMasterAddress );
           context.put( Constants.POSTMASTER, postmaster );
   
  +        if (!isLocalServer(postmaster.getHost())) {
  +            StringBuffer warnBuffer
  +                = new StringBuffer(320)
  +                        .append("The specified postmaster address ( ")
  +                        .append(postmaster)
  +                        .append(" ) is not a local address.  This is not necessarily a problem, but it does mean that emails addressed to the postmaster will be routed to another server.  For some configurations this may cause problems.");
  +            getLogger().warn(warnBuffer.toString());
  +        }
  +
           Configuration userNamesConf = conf.getChild("usernames");
           ignoreCase = userNamesConf.getAttributeAsBoolean("ignoreCase", false);
           enableAliases = userNamesConf.getAttributeAsBoolean("enableAliases", false);
  @@ -191,15 +339,15 @@
           getLogger().info("Local users repository opened");
   
           try {
  -        // Get storage system
  +            // Get storage config param
               if (conf.getChild("storage").getValue().equals("IMAP")) {
                   useIMAPstorage = true;
                   getLogger().info("Using IMAP Store-System");
               }
           }catch(Exception e) {
  -            // No Storage Entry in Config File found
  +            // No storage entry found in config file
           }
  -        
  +
           // Get the LocalInbox repository
           if (useIMAPstorage) {
               try {
  @@ -220,14 +368,15 @@
               }
               inboxRootURL = inboxRepConf.getAttribute("destinationURL");
           }
  -        
           getLogger().info("Private Repository LocalInbox opened");
   
           // Add this to comp
           compMgr.put( MailServer.ROLE, this);
   
           spool = mailstore.getInboundSpool();
  -        if (DEEP_DEBUG) getLogger().debug("Got spool");
  +        if (getLogger().isDebugEnabled()) {
  +            getLogger().debug("Got spool");
  +        }
   
           // For mailet engine provide MailetContext
           //compMgr.put("org.apache.mailet.MailetContext", this);
  @@ -235,10 +384,18 @@
           // an attribute
           attributes.put(Constants.AVALON_COMPONENT_MANAGER, compMgr);
   
  -        System.out.println(VERSION);
  +        System.out.println(SOFTWARE_NAME_VERSION);
           getLogger().info("JAMES ...init end");
       }
   
  +    /**
  +     * Place a mail on the spool for processing
  +     *
  +     * @param message the message to send
  +     *
  +     * @throws MessagingException if an exception is caught while placing the mail
  +     *                            on the spool
  +     */
       public void sendMail(MimeMessage message) throws MessagingException {
           MailAddress sender = new MailAddress((InternetAddress)message.getFrom()[0]);
           Collection recipients = new HashSet();
  @@ -249,11 +406,32 @@
           sendMail(sender, recipients, message);
       }
   
  +    /**
  +     * Place a mail on the spool for processing
  +     *
  +     * @param sender the sender of the mail
  +     * @param recipients the recipients of the mail
  +     * @param message the message to send
  +     *
  +     * @throws MessagingException if an exception is caught while placing the mail
  +     *                            on the spool
  +     */
       public void sendMail(MailAddress sender, Collection recipients, MimeMessage message)
               throws MessagingException {
           sendMail(sender, recipients, message, Mail.DEFAULT);
       }
   
  +    /**
  +     * Place a mail on the spool for processing
  +     *
  +     * @param sender the sender of the mail
  +     * @param recipients the recipients of the mail
  +     * @param message the message to send
  +     * @param state the state of the message
  +     *
  +     * @throws MessagingException if an exception is caught while placing the mail
  +     *                            on the spool
  +     */
       public void sendMail(MailAddress sender, Collection recipients, MimeMessage message, String state)
               throws MessagingException {
           MailImpl mail = new MailImpl(getId(), sender, recipients, message);
  @@ -261,6 +439,16 @@
           sendMail(mail);
       }
   
  +    /**
  +     * Place a mail on the spool for processing
  +     *
  +     * @param sender the sender of the mail
  +     * @param recipients the recipients of the mail
  +     * @param msg an <code>InputStream</code> containing the message
  +     *
  +     * @throws MessagingException if an exception is caught while placing the mail
  +     *                            on the spool
  +     */
       public void sendMail(MailAddress sender, Collection recipients, InputStream msg)
               throws MessagingException {
           // parse headers
  @@ -274,6 +462,14 @@
           sendMail(new MailImpl(getId(), sender, recipients, new SequenceInputStream(headersIn, msg)));
       }
   
  +    /**
  +     * Place a mail on the spool for processing
  +     *
  +     * @param mail the mail to place on the spool
  +     *
  +     * @throws MessagingException if an exception is caught while placing the mail
  +     *                            on the spool
  +     */
       public void sendMail(Mail mail) throws MessagingException {
           MailImpl mailimpl = (MailImpl)mail;
           try {
  @@ -285,11 +481,24 @@
               }
               throw new MessagingException("Exception spooling message: " + e.getMessage(), e);
           }
  -        getLogger().info("Mail " + mailimpl.getName() + " pushed in spool");
  +        if (getLogger().isDebugEnabled()) {
  +            StringBuffer logBuffer =
  +                new StringBuffer(64)
  +                        .append("Mail ")
  +                        .append(mailimpl.getName())
  +                        .append(" pushed in spool");
  +            getLogger().debug(logBuffer.toString());
  +        }
       }
   
       /**
  -     * For POP3 server only - at the momment.
  +     * <p>Retrieve the mail repository for a user</p>
  +     *
  +     * <p>For POP3 server only - at the moment.</p>
  +     *
  +     * @param userName the name of the user whose inbox is to be retrieved
  +     *
  +     * @return the POP3 inbox for the user
        */
       public synchronized MailRepository getUserInbox(String userName) {
           MailRepository userInbox = (MailRepository) null;
  @@ -304,8 +513,15 @@
               throw new RuntimeException("Error in getUserInbox.");
           } else {
               // need mailbox object
  -            getLogger().info("Need inbox for " + userName );
  -            String destination = inboxRootURL + userName + "/";
  +            if (getLogger().isDebugEnabled()) {
  +                getLogger().debug("Retrieving and caching inbox for " + userName );
  +            }
  +            StringBuffer destinationBuffer =
  +                new StringBuffer(192)
  +                        .append(inboxRootURL)
  +                        .append(userName)
  +                        .append("/");
  +            String destination = destinationBuffer.toString();
               DefaultConfiguration mboxConf
                   = new DefaultConfiguration("repository", "generated:AvalonFileRepository.compose()");
               mboxConf.setAttribute("destinationURL", destination);
  @@ -315,17 +531,41 @@
                   mailboxes.put(userName, userInbox);
               } catch (Exception e) {
                   e.printStackTrace();
  -                getLogger().error("Cannot open user Mailbox" + e);
  +                if (getLogger().isErrorEnabled())
  +                {
  +                    getLogger().error("Cannot open user Mailbox" + e);
  +                }
                   throw new RuntimeException("Error in getUserInbox." + e);
               }
               return userInbox;
           }
       }
   
  +    /**
  +     * Return a new mail id.
  +     *
  +     * @return a new mail id
  +     */
       public String getId() {
  -        return "Mail" + System.currentTimeMillis() + "-" + count++;
  +        long localCount = -1;
  +        synchronized (James.class) {
  +            localCount = count++;
  +        }
  +        StringBuffer idBuffer =
  +            new StringBuffer(64)
  +                    .append("Mail")
  +                    .append(System.currentTimeMillis())
  +                    .append("-")
  +                    .append(count++);
  +        return idBuffer.toString();
       }
   
  +    /**
  +     * The main method.  Should never be invoked, as James must be called
  +     * from within an Avalon framework container.
  +     *
  +     * @param args the command line arguments
  +     */
       public static void main(String[] args) {
           System.out.println("ERROR!");
           System.out.println("Cannot execute James as a stand alone application.");
  @@ -335,6 +575,13 @@
   
       //Methods for MailetContext
   
  +    /**
  +     * <p>Get the prioritized list of mail servers for a given host.</p>
  +     *
  +     * <p>TODO: This needs to be made a more specific ordered subtype of Collection.</p>
  +     *
  +     * @param host 
  +     */
       public Collection getMailServers(String host) {
           DNSServer dnsServer = null;
           try {
  @@ -388,9 +635,9 @@
           //Create the reply message
           MimeMessage reply = (MimeMessage) orig.reply(false);
           //If there is a Return-Path header,
  -        if (orig.getHeader("Return-Path") != null) {
  +        if (orig.getHeader(RFC2822Headers.RETURN_PATH) != null) {
               //Return the message to that address, not to the Reply-To address
  -            reply.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(orig.getHeader("Return-Path")[0]));
  +            reply.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(orig.getHeader(RFC2822Headers.RETURN_PATH)[0]));
           }
           //Create the list of recipients in our MailAddress format
           Collection recipients = new HashSet();
  @@ -406,17 +653,17 @@
               //Add message as the first mime body part
               MimeBodyPart part = new MimeBodyPart();
               part.setContent(message, "text/plain");
  -            part.setHeader("Content-Type", "text/plain");
  +            part.setHeader(RFC2822Headers.CONTENT_TYPE, "text/plain");
               multipart.addBodyPart(part);
   
               //Add the original message as the second mime body part
               part = new MimeBodyPart();
               part.setContent(orig.getContent(), orig.getContentType());
  -            part.setHeader("Content-Type", orig.getContentType());
  +            part.setHeader(RFC2822Headers.CONTENT_TYPE, orig.getContentType());
               multipart.addBodyPart(part);
  -            reply.setHeader("Date", RFC822DateFormat.toString(new Date()));
  +            reply.setHeader(RFC2822Headers.DATE, rfc822DateFormat.format(new Date()));
               reply.setContent(multipart);
  -            reply.setHeader("Content-Type", multipart.getContentType());
  +            reply.setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());
           } catch (IOException ioe) {
               throw new MessagingException("Unable to create multipart body", ioe);
           }
  @@ -426,6 +673,10 @@
   
       /**
        * Returns whether that account has a local inbox on this server
  +     *
  +     * @param name the name to be checked
  +     *
  +     * @return whether the account has a local inbox
        */
       public boolean isLocalUser(String name) {
           if (ignoreCase) {
  @@ -437,15 +688,33 @@
   
       /**
        * Returns the address of the postmaster for this server.
  +     *
  +     * @return the <code>MailAddress</code> for the postmaster
        */
       public MailAddress getPostmaster() {
           return postmaster;
       }
  -    
  -    public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage message) {
  +
  +    public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage message)
  +        throws MessagingException {
           String username;
  +        if (recipient == null) {
  +            throw new IllegalArgumentException("Recipient for mail to be spooled cannot be null.");
  +        }
  +        if (message == null) {
  +            throw new IllegalArgumentException("Mail message to be spooled cannot be null.");
  +        }
           if (ignoreCase) {
  -            username = localusers.getRealName(recipient.getUser());
  +            String originalUsername = recipient.getUser();
  +            username = localusers.getRealName(originalUsername);
  +            if (username == null) {
  +                StringBuffer errorBuffer =
  +                    new StringBuffer(128)
  +                        .append("The inbox for user ")
  +                        .append(originalUsername)
  +                        .append(" was not found on this server.");
  +                throw new MessagingException(errorBuffer.toString());
  +            }
           } else {
               username = recipient.getUser();
           }
  @@ -455,23 +724,45 @@
               if (enableAliases && user.getAliasing()) {
                   username = user.getAlias();
               }
  +            // Forwarding takes precedence over local aliases
               if (enableForwarding && user.getForwarding()) {
                   MailAddress forwardTo = user.getForwardingDestination();
  +                if (forwardTo == null) {
  +                    StringBuffer errorBuffer = 
  +                        new StringBuffer(128)
  +                            .append("Forwarding was enabled for ")
  +                            .append(username)
  +                            .append(" but no forwarding address was set for this account.");
  +                    throw new MessagingException(errorBuffer.toString());
  +                }
                   Collection recipients = new HashSet();
                   recipients.add(forwardTo);
                   try {
                       sendMail(sender, recipients, message);
  -                    getLogger().info("Mail for " + username + " forwarded to "
  -                                         +  forwardTo.toString());
  +                    if (getLogger().isInfoEnabled()) {
  +                        StringBuffer logBuffer =
  +                            new StringBuffer(128)
  +                                    .append("Mail for ")
  +                                    .append(username)
  +                                    .append(" forwarded to ")
  +                                    .append(forwardTo.toString());
  +                        getLogger().info(logBuffer.toString());
  +                    }
                       return;
                   } catch (MessagingException me) {
  -                    getLogger().error("Error forwarding mail to "
  -                              + forwardTo.toString()
  -                              + "attempting local delivery");
  +                    if (getLogger().isErrorEnabled()) {
  +                        StringBuffer logBuffer =
  +                            new StringBuffer(128)
  +                                    .append("Error forwarding mail to ")
  +                                    .append(forwardTo.toString())
  +                                    .append("attempting local delivery");
  +                        getLogger().error(logBuffer.toString());
  +                    }
  +                    throw me;
                   }
               }
           }
  -        
  +
           if (useIMAPstorage) {
               ACLMailbox mbox = null;
               try {
  @@ -498,26 +789,62 @@
               Collection recipients = new HashSet();
               recipients.add(recipient);
               MailImpl mailImpl = new MailImpl(getId(), sender, recipients, message);
  -            getUserInbox(username).store(mailImpl);
  +            MailRepository userInbox = getUserInbox(username);
  +            if (userInbox == null) {
  +                StringBuffer errorBuffer =
  +                    new StringBuffer(128)
  +                        .append("The inbox for user ")
  +                        .append(username)
  +                        .append(" was not found on this server.");
  +                throw new MessagingException(errorBuffer.toString());
  +            }
  +            userInbox.store(mailImpl);
           }
       }
   
  +    /**
  +     * Return the major version number for the server
  +     *
  +     * @return the major vesion number for the server
  +     */
       public int getMajorVersion() {
  -        return 1;
  +        return 2;
       }
   
  +    /**
  +     * Return the minor version number for the server
  +     *
  +     * @return the minor vesion number for the server
  +     */
       public int getMinorVersion() {
  -        return 3;
  +        return 1;
       }
   
  +    /**
  +     * Check whether the mail domain in question is to be 
  +     * handled by this server.
  +     *
  +     * @param serverName the name of the server to check
  +     * @return whether the server is local
  +     */
       public boolean isLocalServer( final String serverName ) {
  -        return serverNames.contains(serverName.toLowerCase());
  +        return serverNames.contains(serverName.toLowerCase(Locale.US));
       }
   
  +    /**
  +     * Return the type of the server
  +     *
  +     * @return the type of the server
  +     */
       public String getServerInfo() {
           return "Apache Jakarta JAMES";
       }
   
  +    /**
  +     * Return the logger for the Mailet API
  +     *
  +     * @return the logger for the Mailet API
  +     */
       private Logger getMailetLogger() {
           if (mailetLogger == null) {
               mailetLogger = getLogger().getChildLogger("Mailet");
  @@ -525,16 +852,25 @@
           return mailetLogger;
       }
   
  +    /**
  +     * Log a message to the Mailet logger
  +     *
  +     * @param message the message to pass to the Mailet logger
  +     */
       public void log(String message) {
           getMailetLogger().info(message);
       }
   
  +    /**
  +     * Log a message and a Throwable to the Mailet logger
  +     *
  +     * @param message the message to pass to the Mailet logger
  +     * @param t the <code>Throwable</code> to be logged
  +     */
       public void log(String message, Throwable t) {
  -        //System.err.println(message);
  -        //t.printStackTrace(); //DEBUG
           getMailetLogger().info(message,t);
       }
  -   
  +
       /**
        * Adds a user to this mail server. Currently just adds user to a
        * UsersRepository.
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>