<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">










<html>
  <head>
    <title>James Server - CPD Results</title>
    <style type="text/css" media="all">
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
    </style>
    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
      </head>
  <body class="composite">
    <div id="banner">
                  <a href="http://james.apache.org/index.html" id="bannerLeft">
    
                                            <img src="images/james-server-logo.gif" alt="" />
    
            </a>
                        <a href="http://www.apache.org/index.html" id="bannerRight">
    
                                            <img src="images/asf-logo-reduced.gif" alt="" />
    
            </a>
            <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="breadcrumbs">
          
  

  
    
  
  
            <div class="xleft">
        Last Published: 05/28/2009
                      </div>
            <div class="xright">      <a href="../../index.html">JAMES Project</a>
          |
          <a href="../../server/index.html">Server</a>
          |
          <a href="../../mailet/index.html">Mailets</a>
          |
          <a href="../../jspf/index.html">jSPF</a>
          |
          <a href="../../mime4j/index.html">Mime4J</a>
          |
          <a href="../../jsieve/index.html">JSieve</a>
          |
          <a href="../../postage/index.html">Postage</a>
          
  

  
    
  
  
  </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="leftColumn">
      <div id="navcolumn">
           
  

  
    
  
  
                   <h5>James Server</h5>
        <ul>
              
    <li class="none">
              <a href="../index.html">Overview</a>
        </li>
              
    <li class="none">
              <a href="../design_objectives.html">Objectives</a>
        </li>
              
          
              
      
              
        <li class="expanded">
              <a href="../FAQ.html">James FAQ</a>
                <ul>
                  
    <li class="none">
              <a href="../james_and_sendmail.html">James and Sendmail</a>
        </li>
              </ul>
        </li>
              
    <li class="none">
              <a href="http://wiki.apache.org/james">Wiki</a>
        </li>
              
    <li class="none">
              <a href="../rfclist.html">Useful RFCs</a>
        </li>
          </ul>
          <h5>Overview</h5>
        <ul>
              
    <li class="none">
              <a href="index.html">Introduction</a>
        </li>
              
    <li class="none">
              <a href="release-notes.html">Release Notes</a>
        </li>
              
    <li class="none">
              <a href="jira-report.html">Changes</a>
        </li>
          </ul>
          <h5>Concepts</h5>
        <ul>
              
    <li class="none">
              <a href="summary.html">Summary</a>
        </li>
              
    <li class="none">
              <a href="spoolmanager.html">SpoolManager</a>
        </li>
              
    <li class="none">
              <a href="repositories.html">Repositories</a>
        </li>
              
    <li class="none">
              <a href="mailet_api.html">The Mailet API</a>
        </li>
          </ul>
          <h5>How to...</h5>
        <ul>
              
    <li class="none">
              <a href="build_instructions.html">Build James</a>
        </li>
              
    <li class="none">
              <a href="installation_instructions.html">Install James</a>
        </li>
          </ul>
          <h5>Mailets</h5>
        <ul>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/index.html">Overview</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/api/index.html">API</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/base/index.html">Basic Toolkit</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/crypto/index.html">Crypto</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/standard/index.html">Sieve</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/maven-mailetdocs-plugin/index.html">MailetDocs</a>
        </li>
              
    <li class="none">
              <a href="james-server-mailets-function/mailet-report.html">Server</a>
        </li>
              
    <li class="none">
              <a href="http://james.apache.org/mailet/standard/index.html">Standard</a>
        </li>
          </ul>
          <h5>Configuration</h5>
        <ul>
              
    <li class="none">
              <a href="dns_configuration.html">DNS Server</a>
        </li>
              
    <li class="none">
              <a href="pop3_configuration.html">POP3 Server</a>
        </li>
              
    <li class="none">
              <a href="smtp_configuration.html">SMTP Server</a>
        </li>
              
    <li class="none">
              <a href="nntp_configuration.html">NNTP Server</a>
        </li>
              
    <li class="none">
              <a href="fetchmail_configuration.html">FetchMail</a>
        </li>
              
    <li class="none">
              <a href="remotemanager_configuration.html">RemoteManager</a>
        </li>
              
    <li class="none">
              <a href="spoolmanager_configuration.html">SpoolManager</a>
        </li>
              
    <li class="none">
              <a href="serverwide_configuration.html">Server-wide</a>
        </li>
              
    <li class="none">
              <a href="adding_users.html">Adding Users</a>
        </li>
              
    <li class="none">
              <a href="provided_matchers.html">Provided Matchers</a>
        </li>
              
    <li class="none">
              <a href="provided_mailets.html">Provided Mailets</a>
        </li>
          </ul>
          <h5>Common Configurations</h5>
        <ul>
              
    <li class="none">
              <a href="smtp_auth.html">Using SMTP AUTH</a>
        </li>
              
    <li class="none">
              <a href="using_database.html">Using a Database with James</a>
        </li>
              
    <li class="none">
              <a href="usingTLS.html">Using TLS/SSL</a>
        </li>
              
    <li class="none">
              <a href="mailing_lists.html">Creating Mailing Lists</a>
        </li>
          </ul>
          <h5>Customization</h5>
        <ul>
              
    <li class="none">
              <a href="custom_matcher.html">How to write a custom Matcher</a>
        </li>
              
    <li class="none">
              <a href="custom_mailet.html">How to write a custom Mailet</a>
        </li>
          </ul>
          <h5>Project Documentation</h5>
        <ul>
              
                
              
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
              
        <li class="collapsed">
              <a href="project-info.html">Project Information</a>
              </li>
              
                
              
            
            
      
            
      
            
      
            
      
            
      
            
      
            
      
              
            <li class="expanded">
              <a href="project-reports.html">Project Reports</a>
                <ul>
                  
    <li class="none">
              <strong>CPD Report</strong>
        </li>
                  
    <li class="none">
              <a href="apidocs/index.html">JavaDocs</a>
        </li>
                  
    <li class="none">
              <a href="jira-report.html">JIRA Report</a>
        </li>
                  
    <li class="none">
              <a href="mailet-report.html">Mailet Reference</a>
        </li>
                  
    <li class="none">
              <a href="pmd.html">PMD Report</a>
        </li>
                  
    <li class="none">
              <a href="xref/index.html">Source Xref</a>
        </li>
                  
    <li class="none">
              <a href="testapidocs/index.html">Test JavaDocs</a>
        </li>
                  
    <li class="none">
              <a href="xref-test/index.html">Test Source Xref</a>
        </li>
              </ul>
        </li>
          </ul>
          <h5>Project</h5>
        <ul>
              
    <li class="none">
              <a href="http://issues.apache.org/jira/browse/JAMES">Bug Database</a>
        </li>
              
    <li class="none">
              <a href="http://svn.apache.org/viewvc/james/server/">Source Code</a>
        </li>
              
    <li class="none">
              <a href="../todo.html">TODO</a>
        </li>
          </ul>
          <h5>Downloads</h5>
        <ul>
              
    <li class="none">
              <a href="../../download.cgi">Stable releases</a>
        </li>
              
    <li class="none">
              <a href="../../downloadunstable.cgi">Unstable releases</a>
        </li>
              
    <li class="none">
              <a href="http://people.apache.org/builds/james/nightly/">Nightly builds</a>
        </li>
          </ul>
                                       <a href="http://maven.apache.org/" title="Built by Maven" id="poweredBy">
            <img alt="Built by Maven" src="./images/logos/maven-feather.png"></img>
          </a>
                       
  

  
    
  
  
        </div>
    </div>
    <div id="bodyColumn">
      <div id="contentBox">
        <div class="section"><h2>CPD Results</h2><p>The following document contains the results of PMD's  <a href="http://pmd.sourceforge.net/cpd.html">CPD</a> 3.9.</p></div><div class="section"><h2>Duplications</h2><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/RemoteDelivery.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/RemoteDelivery.html#278">278</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Retry.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Retry.html#243">243</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>    public void init() throws MessagingException {
        // Set isDebug flag.
        isDebug = (getInitParameter(&quot;debug&quot;) == null) ? false : new Boolean(getInitParameter(&quot;debug&quot;)).booleanValue();

        // Create list of Delay Times.
        ArrayList delayTimesList = new ArrayList();
        try {
            if (getInitParameter(&quot;delayTime&quot;) != null) {
                delayTimeMatcher = new Perl5Matcher();
                String delayTimesParm = getInitParameter(&quot;delayTime&quot;);

                // Split on commas
                StringTokenizer st = new StringTokenizer (delayTimesParm,&quot;,&quot;);
                while (st.hasMoreTokens()) {
                    String delayTime = st.nextToken();
                    delayTimesList.add (new Delay(delayTime));
                }
            } else {
                // Use default delayTime.
                delayTimesList.add(new Delay());
            }
        } catch (Exception e) {
            log(&quot;Invalid delayTime setting: &quot; + getInitParameter(&quot;delayTime&quot;));
        }

        try {
            // Get No. of Max Retries.
            if (getInitParameter(&quot;maxRetries&quot;) != null) {
                maxRetries = Integer.parseInt(getInitParameter(&quot;maxRetries&quot;));
            }
    
            // Check consistency of 'maxRetries' with delayTimesList attempts.
            int totalAttempts = calcTotalAttempts(delayTimesList);
    
            // If inconsistency found, fix it.
            if (totalAttempts &gt; maxRetries) {
                log(&quot;Total number of delayTime attempts exceeds maxRetries specified. &quot;
                        + &quot; Increasing maxRetries from &quot;
                        + maxRetries
                        + &quot; to &quot;
                        + totalAttempts);
                maxRetries = totalAttempts;
            } else {
                int extra = maxRetries - totalAttempts;
                if (extra != 0) {
                    log(&quot;maxRetries is larger than total number of attempts specified.  &quot;
                            + &quot;Increasing last delayTime with &quot;
                            + extra
                            + &quot; attempts &quot;);
    
                    // Add extra attempts to the last delayTime.
                    if (delayTimesList.size() != 0) {
                        // Get the last delayTime.
                        Delay delay = (Delay) delayTimesList.get(delayTimesList
                                .size() - 1);
    
                        // Increase no. of attempts.
                        delay.setAttempts(delay.getAttempts() + extra);
                        log(&quot;Delay of &quot; + delay.getDelayTime()
                                + &quot; msecs is now attempted: &quot; + delay.getAttempts()
                                + &quot; times&quot;);
                    } else {
                        throw new MessagingException(
                                &quot;No delaytimes, cannot continue&quot;);
                    }
                }
            }
            delayTimes = expandDelays(delayTimesList);
        } catch (Exception e) {
            log(&quot;Invalid maxRetries setting: &quot; + getInitParameter(&quot;maxRetries&quot;));
        }

        ServiceManager compMgr = (ServiceManager) getMailetContext()
                .getAttribute(Constants.AVALON_COMPONENT_MANAGER);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/vut/JDBCVirtualUserTable.java</td><td>Apache JAMES Server Avalon User function</td><td><a href="./xref/org/apache/james/vut/JDBCVirtualUserTable.html#179">179</a></td></tr><tr class="a"><td>org/apache/james/domain/JDBCDomainList.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/domain/JDBCDomainList.html#167">167</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            } catch (Exception e) {
                getLogger().fatalError(e.getMessage(), e);
                throw e;
            }

            if (getLogger().isDebugEnabled()) {
                logBuffer =
                    new StringBuffer(128)
                            .append(&quot;Reading SQL resources from file: &quot;)
                            .append(sqlFileName)
                            .append(&quot;, section &quot;)
                            .append(this.getClass().getName())
                            .append(&quot;.&quot;);
                getLogger().debug(logBuffer.toString());
            }

            // Build the statement parameters
            Map sqlParameters = new HashMap();
            if (tableName != null) {
                sqlParameters.put(&quot;table&quot;, tableName);
            }
            
            sqlQueries = new SqlResources();
            sqlQueries.init(sqlFile, this.getClass().getName(),
                            conn, sqlParameters);

            // Check if the required table exists. If not, create it.
            DatabaseMetaData dbMetaData = conn.getMetaData();
            // Need to ask in the case that identifiers are stored, ask the DatabaseMetaInfo.
            // Try UPPER, lower, and MixedCase, to see if the table is there.
           
            if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
           
                // Users table doesn't exist - create it.
                createStatement =
                    conn.prepareStatement(sqlQueries.getSqlString(&quot;createTable&quot;, true));
                createStatement.execute();

                if (getLogger().isInfoEnabled()) {
                    logBuffer =
                        new StringBuffer(64)
                                .append(&quot;JdbcVirtalUserTable: Created table '&quot;)
                                .append(tableName)
                                .append(&quot;'.&quot;);
                    getLogger().info(logBuffer.toString());
                }
            }

          
        } finally {
            theJDBCUtil.closeJDBCStatement(createStatement);
            theJDBCUtil.closeJDBCConnection(conn);
        }
    }
    
    /**
     * The JDBCUtil helper class
     */
    private final JDBCUtil theJDBCUtil = new JDBCUtil() {
        protected void delegatedLog(String logString) {
            getLogger().debug(&quot;JDBCVirtualUserTable: &quot; + logString);
        }
    };

    public void setDataSourceComponent(DataSourceComponent dataSourceComponent) {
        this.dataSourceComponent = dataSourceComponent;
    }
    

    public void setFileSystem(FileSystem fileSystem) {
        this.fileSystem = fileSystem;
    }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/domain/AbstractDomainList.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/domain/AbstractDomainList.html#82">82</a></td></tr><tr class="a"><td>org/apache/james/impl/vut/AbstractVirtualUserTable.java</td><td>Apache JAMES Server User Library</td><td><a href="./xref/org/apache/james/impl/vut/AbstractVirtualUserTable.html#374">374</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                    getLogger().info(&quot;Handling mail for: &quot; + i.next());
                }
            }  
            return domains;
        } else {
            return null;
        }
    }

    /**
     * Return a List which holds all ipAddress of the domains in the given List
     * 
     * @param domains List of domains
     * @return domainIP List of ipaddress for domains
     */
    private static List getDomainsIP(List domains,DNSService dns,Logger log) {
        List domainIP = new ArrayList();
        if (domains.size() &gt; 0 ) {
            for (int i = 0; i &lt; domains.size(); i++) {
                List domList = getDomainIP(domains.get(i).toString(),dns,log);
                
                for(int i2 = 0; i2 &lt; domList.size();i2++) {
                    if(domainIP.contains(domList.get(i2)) == false) {
                        domainIP.add(domList.get(i2));
                    }
                }
            }
        }
        return domainIP;    
    }
    
    /**
     * @see #getDomainsIP(List, DNSService, Logger)
     */
    private static List getDomainIP(String domain, DNSService dns, Logger log) {
        List domainIP = new ArrayList();
        try {
            InetAddress[]  addrs = dns.getAllByName(domain);
            for (int j = 0; j &lt; addrs.length ; j++) {
                String ip = addrs[j].getHostAddress();
                if (domainIP.contains(ip) == false) {
                    domainIP.add(ip);
                }
            }
        } catch (UnknownHostException e) {
            log.error(&quot;Cannot get IP address(es) for &quot; + domain);
        }
        return domainIP;
    }

    /**
     * @see org.apache.james.api.vut.management.VirtualUserTableManagement#getUserDomainMappings(java.lang.String, java.lang.String)
     */
    public Collection getUserDomainMappings(String user, String domain) {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#465">465</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#588">588</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            out.println(&quot;Removing from the white list of &quot; + (new MailAddress(senderUser, senderHost)) + &quot; ...&quot;);
            out.println();
            
            MimeMessage message = mail.getMessage() ;
            
            Object content= message.getContent();
            
            if (message.getContentType().startsWith(&quot;text/plain&quot;)
            &amp;&amp; content instanceof String) {
                StringTokenizer st = new StringTokenizer((String) content, &quot; \t\n\r\f,;:&lt;&gt;&quot;);
                while (st.hasMoreTokens()) {
                    ResultSet selectRS = null;
                    try {
                        MailAddress recipientMailAddress;
                        try {
                            recipientMailAddress = new MailAddress(st.nextToken());
                        }
                        catch (javax.mail.internet.ParseException pe) {
                            continue;
                        }
                        String recipientUser = recipientMailAddress.getUser().toLowerCase(Locale.US);
                        String recipientHost = recipientMailAddress.getHost().toLowerCase(Locale.US);
                        
                        if (getMailetContext().isLocalServer(recipientHost)) {
                            // not a remote recipient, so skip
                            continue;
                        }
                        
                        if (conn == null) {
                            conn = datasource.getConnection();
                        }
                        
                        if (selectStmt == null) {
                            selectStmt = conn.prepareStatement(selectByPK);
                        }
                        selectStmt.setString(1, senderUser);
                        selectStmt.setString(2, senderHost);
                        selectStmt.setString(3, recipientUser);
                        selectStmt.setString(4, recipientHost);
                        selectRS = selectStmt.executeQuery();
                        if (!selectRS.next()) {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/vut/JDBCVirtualUserTable.java</td><td>Apache JAMES Server Avalon User function</td><td><a href="./xref/org/apache/james/vut/JDBCVirtualUserTable.html#523">523</a></td></tr><tr class="a"><td>org/apache/james/domain/JDBCDomainList.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/domain/JDBCDomainList.html#257">257</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                    if(domains.contains(domains) == false) {
                        domains.add(domain);
                    }
                }
            } finally {
                theJDBCUtil.closeJDBCResultSet(mappingRS);
            }
            
        } catch (SQLException sqle) {
            getLogger().error(&quot;Error accessing database&quot;, sqle);
        } finally {
            theJDBCUtil.closeJDBCStatement(mappingStmt);
            theJDBCUtil.closeJDBCConnection(conn);
        }
        if (domains.size() == 0) {
            return null;
        } else {
            return domains;
        }
    }

    /**
     * @see org.apache.james.api.domainlist.DomainList#containsDomain(java.lang.String)
     */
    public boolean containsDomain(String domain) {
        Connection conn = null;
        PreparedStatement mappingStmt = null;
        
        try {
            conn = dataSourceComponent.getConnection();
            mappingStmt = conn.prepareStatement(sqlQueries.getSqlString(&quot;selectDomain&quot;, true));

            ResultSet mappingRS = null;
            try {
                mappingStmt.setString(1, domain);
                mappingRS = mappingStmt.executeQuery();
                if (mappingRS.next()) {
                    return true;
                }
            } finally {
                theJDBCUtil.closeJDBCResultSet(mappingRS);
            }
            
        } catch (SQLException sqle) {
            getLogger().error(&quot;Error accessing database&quot;, sqle);
        } finally {
            theJDBCUtil.closeJDBCStatement(mappingStmt);
            theJDBCUtil.closeJDBCConnection(conn);
        }
        return false;
    }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/vut/JDBCVirtualUserTable.java</td><td>Apache JAMES Server Avalon User function</td><td><a href="./xref/org/apache/james/vut/JDBCVirtualUserTable.html#135">135</a></td></tr><tr class="a"><td>org/apache/james/domain/JDBCDomainList.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/domain/JDBCDomainList.html#122">122</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        if (getLogger().isDebugEnabled()) {
            StringBuffer logBuffer =
                new StringBuffer(128)
                        .append(&quot;Parsed URL: table = '&quot;)
                        .append(tableName)
                        .append(&quot;'&quot;);
            getLogger().debug(logBuffer.toString());
        }
    
        sqlFileName = arg0.getChild(&quot;sqlFile&quot;).getValue();
        
        Configuration autoConf = arg0.getChild(&quot;autodetect&quot;);
        if (autoConf != null) {
            setAutoDetect(autoConf.getValueAsBoolean(true));    
        }
        
        Configuration autoIPConf = arg0.getChild(&quot;autodetectIP&quot;);
        if (autoConf != null) {
            setAutoDetectIP(autoIPConf.getValueAsBoolean(true));    
        }
    }
    
    /**
     * @see org.apache.avalon.framework.activity.Initializable#initialize()
     */
    public void initialize() throws Exception {
    
        setDataSourceComponent((DataSourceComponent) datasources.select(dataSourceName));
    
        StringBuffer logBuffer = null;
        if (getLogger().isDebugEnabled()) {
            getLogger().debug(this.getClass().getName() + &quot;.initialize()&quot;);
        }

        // Test the connection to the database, by getting the DatabaseMetaData.
        Connection conn = dataSourceComponent.getConnection();
        PreparedStatement createStatement = null;

        try {
            // Initialise the sql strings.

            InputStream sqlFile = null;
            try {
                sqlFile = fileSystem.getResource(sqlFileName);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#218">218</a></td></tr><tr class="a"><td>org/apache/james/transport/matchers/IsInWhiteList.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/matchers/IsInWhiteList.html#118">118</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        if (repositoryPath != null) {
            log(&quot;repositoryPath: &quot; + repositoryPath);
        }
        else {
            throw new MessagingException(&quot;repositoryPath is null&quot;);
        }

        ServiceManager serviceManager = (ServiceManager) getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);

        try {
            // Get the DataSourceSelector block
            DataSourceSelector datasources = (DataSourceSelector) serviceManager.lookup(DataSourceSelector.ROLE);
            // Get the data-source required.
            int stindex =   repositoryPath.indexOf(&quot;://&quot;) + 3;
            String datasourceName = repositoryPath.substring(stindex);
            datasource = (DataSourceComponent) datasources.select(datasourceName);
        } catch (Exception e) {
            throw new MessagingException(&quot;Can't get datasource&quot;, e);
        }

         try {
            // Get the UsersRepository
            localusers = (UsersRepository)serviceManager.lookup(UsersRepository.ROLE);
        } catch (Exception e) {
            throw new MessagingException(&quot;Can't get the local users repository&quot;, e);
        }

        try {
            initSqlQueries(datasource.getConnection(), getMailetContext());
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception initializing queries&quot;, e);
        }        
        
        selectByPK = sqlQueries.getSqlString(&quot;selectByPK&quot;, true);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/RemoteDelivery.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/RemoteDelivery.html#512">512</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Retry.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Retry.html#421">421</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        return delayTimes[retryCount];
    }


    /**
     * This class is used to hold a delay time and its corresponding number of
     * retries.
     **/
    private class Delay {
        private int attempts = 1;

        private long delayTime = DEFAULT_DELAY_TIME;

        /**
         * This constructor expects Strings of the form
         * &quot;[attempt\*]delaytime[unit]&quot;.
         * &lt;p&gt;
         * The optional attempt is the number of tries this delay should be used
         * (default = 1). The unit, if present, must be one of
         * (msec,sec,minute,hour,day). The default value of unit is 'msec'.
         * &lt;p&gt;
         * The constructor multiplies the delaytime by the relevant multiplier
         * for the unit, so the delayTime instance variable is always in msec.
         * 
         * @param initString
         *            the string to initialize this Delay object from
         **/
        public Delay(String initString) throws MessagingException {
            // Default unit value to 'msec'.
            String unit = &quot;msec&quot;;

            if (delayTimeMatcher.matches(initString, PATTERN)) {
                MatchResult res = delayTimeMatcher.getMatch();

                // The capturing groups will now hold:
                // at 1: attempts * (if present)
                // at 2: delaytime
                // at 3: unit (if present)
                if (res.group(1) != null &amp;&amp; !res.group(1).equals(&quot;&quot;)) {
                    // We have an attempt *
                    String attemptMatch = res.group(1);

                    // Strip the * and whitespace.
                    attemptMatch = attemptMatch.substring(0,
                            attemptMatch.length() - 1).trim();
                    attempts = Integer.parseInt(attemptMatch);
                }

                delayTime = Long.parseLong(res.group(2));

                if (!res.group(3).equals(&quot;&quot;)) {
                    // We have a value for 'unit'.
                    unit = res.group(3).toLowerCase(Locale.US);
                }
            } else {
                throw new MessagingException(initString + &quot; does not match &quot;
                        + PATTERN_STRING);
            }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/pop3server/POP3Handler.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/POP3Handler.html#189">189</a></td></tr><tr class="a"><td>org/apache/james/smtpserver/SMTPHandler.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/SMTPHandler.html#207">207</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        String responseString = clearResponseBuffer();
        helper.writeLoggedFlushedResponse(responseString);

        //the core in-protocol handling logic
        //run all the connection handlers, if it fast fails, end the session
        //parse the command command, look up for the list of command handlers
        //Execute each of the command handlers. If any command handlers writes
        //response then, End the subsequent command handler processing and
        //start parsing new command. Once the message is received, run all
        //the message handlers. The message handlers can either terminate
        //message or terminate session

        //At the beginning
        //mode = command_mode
        //once the commandHandler writes response, the mode is changed to RESPONSE_MODE.
        //This will cause to skip the subsequent command handlers configured for that command.
        //For instance:
        //There are 2 commandhandlers MailAddressChecker and MailCmdHandler for
        //MAIL command. If MailAddressChecker validation of the MAIL FROM
        //address is successful, the MailCmdHandlers will be executed.
        //Incase it fails, it has to write response. Once we write response
        //there is no need to execute the MailCmdHandler.
        //Next, Once MAIL message is received the DataCmdHandler and any other
        //equivalent commandHandler will call setMail method. this will change
        //he mode to MAIL_RECEIVED_MODE. This mode will trigger the message
        //handlers to be execute. Message handlers can abort message. In that case,
        //message will not spooled.

        //Session started - RUN all connect handlers
        List connectHandlers = handlerChain.getConnectHandlers();
        if(connectHandlers != null) {
            int count = connectHandlers.size();
            for(int i = 0; i &lt; count; i++) {
                ((ConnectHandler)connectHandlers.get(i)).onConnect(this);
                if(sessionEnded) {
                    break;
                }
            }
        }

        helper.getWatchdog().start();
        while(!sessionEnded) {
          //Reset the current command values
          curCommandName = null;
          curCommandArgument = null;
          mode = COMMAND_MODE;

          //parse the command
          String cmdString =  readCommandLine();
          if (cmdString == null) {
              break;
          }
          int spaceIndex = cmdString.indexOf(&quot; &quot;);
          if (spaceIndex &gt; 0) {
              curCommandName = cmdString.substring(0, spaceIndex);
              curCommandArgument = cmdString.substring(spaceIndex + 1);
          } else {
              curCommandName = cmdString;
          }
          curCommandName = curCommandName.toUpperCase(Locale.US);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/api/vut/management/VirtualUserTableManagementMBean.java</td><td>Apache JAMES Server User API</td><td><a href="./xref/org/apache/james/api/vut/management/VirtualUserTableManagementMBean.html#47">47</a></td></tr><tr class="a"><td>org/apache/james/api/vut/management/VirtualUserTableManagementService.java</td><td>Apache JAMES Server User API</td><td><a href="./xref/org/apache/james/api/vut/management/VirtualUserTableManagementService.html#45">45</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>    public boolean addRegexMapping(String virtualUserTable, String user, String domain, String regex) throws VirtualUserTableManagementException;
    
    /**
     * Remove regex mapping
     * 
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param regex the regex.
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean removeRegexMapping(String virtualUserTable, String user,String domain, String regex) throws VirtualUserTableManagementException;
    
    /***
     * Add address mapping
     * 
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param address 
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean addAddressMapping(String virtualUserTable, String user, String domain, String address) throws VirtualUserTableManagementException;
    
    /**
     * Remove address mapping
     *
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param address 
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean removeAddressMapping(String virtualUserTable, String user,String domain, String address) throws VirtualUserTableManagementException;
    
    /**
     * Add error mapping
     *
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param error
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean addErrorMapping(String virtualUserTable, String user, String domain, String error) throws VirtualUserTableManagementException;

    /**
     * Remove error mapping
     *
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param error
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean removeErrorMapping(String virtualUserTable, String user,String domain, String error) throws VirtualUserTableManagementException;
    
    /**
     * Return the explicit mapping stored for the given user and domain. Return null
     * if no mapping was found
     *
     * @param virtualUserTable The virtualUserTable     
     * @param user the username
     * @param domain the domain
     * @return the collection which holds the mappings. 
     * @throws VirtualUserTableManagementException  get thrown if an invalid use or domain was given
     */
    public Collection getUserDomainMappings(String virtualUserTable, String user, String domain) throws VirtualUserTableManagementException;
    
    /**
    * Try to identify the right method based on the prefix of the mapping and add it.
    *
    * @param virtualUserTable The virtualUserTable 
    * @param user the username. Null if no username should be used
    * @param domain the domain. Null if no domain should be used
    * @param mapping the mapping.
    * @return true if successfully
    * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
    */
    public boolean addMapping(String virtualUserTable, String user, String domain, String mapping) throws VirtualUserTableManagementException;
    
    /**
     * Try to identify the right method based on the prefix of the mapping and remove it.
     *
     * @param virtualUserTable The virtualUserTable 
     * @param user the username. Null if no username should be used
     * @param domain the domain. Null if no domain should be used
     * @param mapping the mapping.
     * @return true if successfully
     * @throws VirtualUserTableManagementException get thrown if an invalid argument was given
     */
    public boolean removeMapping(String virtualUserTable, String user, String domain, String mapping) throws VirtualUserTableManagementException;</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/AbstractRedirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/AbstractRedirect.html#400">400</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Redirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Redirect.html#335">335</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        String addressList = getInitParameter(&quot;recipients&quot;,getInitParameter(&quot;to&quot;));
                                 
        // if nothing was specified, return &lt;CODE&gt;null&lt;/CODE&gt; meaning no change
        if (addressList == null) {
            return null;
        }

        try {
            InternetAddress[] iaarray = InternetAddress.parse(addressList, false);
            for (int i = 0; i &lt; iaarray.length; i++) {
                String addressString = iaarray[i].getAddress();
                MailAddress specialAddress = getSpecialAddress(addressString,
                new String[] {&quot;postmaster&quot;, &quot;sender&quot;, &quot;from&quot;, &quot;replyTo&quot;, &quot;reversePath&quot;, &quot;unaltered&quot;, &quot;recipients&quot;, &quot;to&quot;, &quot;null&quot;});
                if (specialAddress != null) {
                    newRecipients.add(specialAddress);
                } else {
                    newRecipients.add(new MailAddress(iaarray[i]));
                }
            }
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception thrown in getRecipients() parsing: &quot; + addressList, e);
        }
        if (newRecipients.size() == 0) {
            throw new MessagingException(&quot;Failed to initialize \&quot;recipients\&quot; list; empty &lt;recipients&gt; init parameter found.&quot;);
        }

        return newRecipients;
    }

    /**
     * @return the &lt;CODE&gt;to&lt;/CODE&gt; init parameter
     * or the postmaster address
     * or &lt;CODE&gt;SpecialAddress.SENDER&lt;/CODE&gt;
     * or &lt;CODE&gt;SpecialAddress.REVERSE_PATH&lt;/CODE&gt;
     * or &lt;CODE&gt;SpecialAddress.UNALTERED&lt;/CODE&gt;
     * or the &lt;CODE&gt;recipients&lt;/CODE&gt; init parameter if missing
     * or &lt;CODE&gt;null&lt;/CODE&gt; if also the latter is missing
     */
    protected InternetAddress[] getTo() throws MessagingException {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/Forward.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Forward.html#120">120</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Redirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Redirect.html#340">340</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        }

        try {
            InternetAddress[] iaarray = InternetAddress.parse(addressList, false);
            for (int i = 0; i &lt; iaarray.length; i++) {
                String addressString = iaarray[i].getAddress();
                MailAddress specialAddress = getSpecialAddress(addressString,
                new String[] {&quot;postmaster&quot;, &quot;sender&quot;, &quot;from&quot;, &quot;replyTo&quot;, &quot;reversePath&quot;, &quot;unaltered&quot;, &quot;recipients&quot;, &quot;to&quot;, &quot;null&quot;});
                if (specialAddress != null) {
                    newRecipients.add(specialAddress);
                } else {
                    newRecipients.add(new MailAddress(iaarray[i]));
                }
            }
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception thrown in getRecipients() parsing: &quot; + addressList, e);
        }
        if (newRecipients.size() == 0) {
            throw new MessagingException(&quot;Failed to initialize \&quot;recipients\&quot; list; empty &lt;recipients&gt; init parameter found.&quot;);
        }

        return newRecipients;
    }

    /**
     * @return the &lt;CODE&gt;to&lt;/CODE&gt; init parameter
     * or the postmaster address
     * or &lt;CODE&gt;SpecialAddress.SENDER&lt;/CODE&gt;
     * or &lt;CODE&gt;SpecialAddress.REVERSE_PATH&lt;/CODE&gt;
     * or &lt;CODE&gt;SpecialAddress.UNALTERED&lt;/CODE&gt;
     * or the &lt;CODE&gt;recipients&lt;/CODE&gt; init parameter if missing
     * or &lt;CODE&gt;null&lt;/CODE&gt; if also the latter is missing
     */
    protected InternetAddress[] getTo() throws MessagingException {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/pop3server/ListCmdHandler.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/ListCmdHandler.html#100">100</a></td></tr><tr class="a"><td>org/apache/james/pop3server/UidlCmdHandler.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/UidlCmdHandler.html#76">76</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                                    .append(mc.getName());
                        session.writeResponse(responseBuffer.toString());
                    } else {
                        StringBuffer responseBuffer =
                            new StringBuffer(64)
                                    .append(POP3Handler.ERR_RESPONSE)
                                    .append(&quot; Message (&quot;)
                                    .append(num)
                                    .append(&quot;) already deleted.&quot;);
                        session.writeResponse(responseBuffer.toString());
                    }
                } catch (IndexOutOfBoundsException npe) {
                    StringBuffer responseBuffer =
                        new StringBuffer(64)
                                .append(POP3Handler.ERR_RESPONSE)
                                .append(&quot; Message (&quot;)
                                .append(num)
                                .append(&quot;) does not exist.&quot;);
                    session.writeResponse(responseBuffer.toString());
                } catch (NumberFormatException nfe) {
                    StringBuffer responseBuffer =
                        new StringBuffer(64)
                                .append(POP3Handler.ERR_RESPONSE)
                                .append(&quot; &quot;)
                                .append(argument)
                                .append(&quot; is not a valid number&quot;);
                    session.writeResponse(responseBuffer.toString());
                }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/util/bayesian/BayesianAnalyzer.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/bayesian/BayesianAnalyzer.html#372">372</a></td></tr><tr class="a"><td>org/apache/james/util/bayesian/BayesianAnalyzer.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/bayesian/BayesianAnalyzer.html#424">424</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        String token;
        String header = &quot;&quot;;
        
        //Build a Map of tokens encountered.
        while ((token = nextToken(stream)) != null) {
            boolean endingLine = false;
            if (token.length() &gt; 0 &amp;&amp; token.charAt(token.length() - 1) == '\n') {
                endingLine = true;
                token = token.substring(0, token.length() - 1);
            }
            
            if (token.length() &gt; 0 &amp;&amp; header.length() + token.length() &lt; 90 &amp;&amp; !allDigits(token)) {
                if (token.equals(&quot;From:&quot;)
                || token.equals(&quot;Return-Path:&quot;)
                || token.equals(&quot;Subject:&quot;)
                || token.equals(&quot;To:&quot;)
                ) {
                    header = token;
                    if (!endingLine) {
                        continue;
                    }
                }
                
                token = header + token;</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/pop3server/POP3HandlerChain.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/POP3HandlerChain.html#175">175</a></td></tr><tr class="a"><td>org/apache/james/smtpserver/SMTPHandlerChain.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/SMTPHandlerChain.html#314">314</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>    }

    /**
     * Add it to map (key as command name, value is an array list of commandhandlers)
     *
     * @param commandName the command name which will be key
     * @param cmdHandler The commandhandler object
     */
    private void addToMap(String commandName, CommandHandler cmdHandler) {
        ArrayList handlers = (ArrayList)commandHandlerMap.get(commandName);
        if(handlers == null) {
            handlers = new ArrayList();
            commandHandlerMap.put(commandName, handlers);
        }
        handlers.add(cmdHandler);
    }

    /**
     * Returns all the configured commandhandlers for the specified command
     *
     * @param command the command name which will be key
     * @return List of commandhandlers
     */
    List getCommandHandlers(String command) {
        if (command == null) {
            return null;
        }
        if (getLogger().isDebugEnabled()) {
            getLogger().debug(&quot;Lookup command handler for command: &quot; + command);
        }
        List handlers =  (List)commandHandlerMap.get(command);
        if(handlers == null) {
            handlers = (List)commandHandlerMap.get(UnknownCmdHandler.UNKNOWN_COMMAND);
        }

        return handlers;
    }

    /**
     * Returns all the configured message handlers
     *
     * @return List of message handlers
     */
    List getMessageHandlers() {
        return messageHandlers;
    }

    /**
     * Returns all the configured connect handlers
     *
     * @return List of connect handlers
     */
    List getConnectHandlers() {
        return connectHandlers;
    }

}</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/nntpserver/NNTPHandler.java</td><td>Apache JAMES Server NNTP function</td><td><a href="./xref/org/apache/james/nntpserver/NNTPHandler.html#768">768</a></td></tr><tr class="a"><td>org/apache/james/nntpserver/NNTPHandler.java</td><td>Apache JAMES Server NNTP function</td><td><a href="./xref/org/apache/james/nntpserver/NNTPHandler.html#899">899</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                            .append(&quot;221 0 &quot;)
                            .append(param);
                helper.writeLoggedFlushedResponse(respBuffer.toString());
            }
        } else {
            int newArticleNumber = currentArticleNumber;
            if ( group == null ) {
                helper.writeLoggedFlushedResponse(&quot;412 no newsgroup selected&quot;);
                return;
            } else {
                if ( param == null ) {
                    if ( currentArticleNumber &lt; 0 ) {
                        helper.writeLoggedFlushedResponse(&quot;420 no current article selected&quot;);
                        return;
                    } else {
                        article = group.getArticle(currentArticleNumber);
                    }
                }
                else {
                    newArticleNumber = Integer.parseInt(param);
                    article = group.getArticle(newArticleNumber);
                }
                if ( article == null ) {
                    helper.writeLoggedFlushedResponse(&quot;423 no such article number in this group&quot;);
                    return;
                } else {
                    currentArticleNumber = newArticleNumber;
                    String articleID = article.getUniqueID();
                    if (articleID == null) {
                        articleID = &quot;&lt;0&gt;&quot;;
                    }
                    StringBuffer respBuffer =
                        new StringBuffer(128)
                                .append(&quot;221 &quot;)</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/AbstractRedirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/AbstractRedirect.html#405">405</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Forward.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Forward.html#120">120</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        }

        try {
            InternetAddress[] iaarray = InternetAddress.parse(addressList, false);
            for (int i = 0; i &lt; iaarray.length; i++) {
                String addressString = iaarray[i].getAddress();
                MailAddress specialAddress = getSpecialAddress(addressString,
                new String[] {&quot;postmaster&quot;, &quot;sender&quot;, &quot;from&quot;, &quot;replyTo&quot;, &quot;reversePath&quot;, &quot;unaltered&quot;, &quot;recipients&quot;, &quot;to&quot;, &quot;null&quot;});
                if (specialAddress != null) {
                    newRecipients.add(specialAddress);
                } else {
                    newRecipients.add(new MailAddress(iaarray[i]));
                }
            }
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception thrown in getRecipients() parsing: &quot; + addressList, e);
        }
        if (newRecipients.size() == 0) {
            throw new MessagingException(&quot;Failed to initialize \&quot;recipients\&quot; list; empty &lt;recipients&gt; init parameter found.&quot;);
        }

        return newRecipients;
    }

    /**
     * @return null
     */
    protected InternetAddress[] getTo() throws MessagingException {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#743">743</a></td></tr><tr class="a"><td>org/apache/james/transport/matchers/IsInWhiteList.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/matchers/IsInWhiteList.html#226">226</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            theJDBCUtil.closeJDBCConnection(conn);
        }
    }

    /** Gets the main name of a local customer, handling alias */
    private String getPrimaryName(String originalUsername) {
        String username;
        try {
            username = localusers.getRealName(originalUsername);
            JamesUser user = (JamesUser) localusers.getUserByName(username);
            if (user.getAliasing()) {
                username = user.getAlias();
            }
        }
        catch (Exception e) {
            username = originalUsername;
        }
        return username;
    }
    
    /**
     * Initializes the sql query environment from the SqlResources file.
     * Will look for conf/sqlResources.xml.
     * Will &lt;I&gt;not&lt;/I&gt; create the database resources, if missing
     * (this task is done, if needed, in the {@link WhiteListManager}
     * initialization routine).
     * @param conn The connection for accessing the database
     * @param mailetContext The current mailet context,
     * for finding the conf/sqlResources.xml file
     * @throws Exception If any error occurs
     */
    private void initSqlQueries(Connection conn, org.apache.mailet.MailetContext mailetContext) throws Exception {
        try {
            if (conn.getAutoCommit()) {
                conn.setAutoCommit(false);
            }
            
            this.sqlFile = new File((String) mailetContext.getAttribute(&quot;confDir&quot;), &quot;sqlResources.xml&quot;).getCanonicalFile();
            sqlQueries.init(this.sqlFile, &quot;WhiteList&quot; , conn, getSqlParameters());</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/util/bayesian/JDBCBayesianAnalyzer.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/bayesian/JDBCBayesianAnalyzer.html#393">393</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#793">793</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        dbUpdated = createTable(conn, &quot;whiteListTableName&quot;, &quot;createWhiteListTable&quot;);
        
        //Commit our changes if necessary.
        if (conn != null &amp;&amp; dbUpdated &amp;&amp; !conn.getAutoCommit()) {
            conn.commit();
            dbUpdated = false;
        }
            
    }
    
    private boolean createTable(Connection conn, String tableNameSqlStringName, String createSqlStringName) throws SQLException {
        String tableName = sqlQueries.getSqlString(tableNameSqlStringName, true);
        
        DatabaseMetaData dbMetaData = conn.getMetaData();

        // Try UPPER, lower, and MixedCase, to see if the table is there.
        if (theJDBCUtil.tableExists(dbMetaData, tableName)) {
            return false;
        }
        
        PreparedStatement createStatement = null;
        
        try {
            createStatement =
                    conn.prepareStatement(sqlQueries.getSqlString(createSqlStringName, true));
            createStatement.execute();
            
            StringBuffer logBuffer = null;
            logBuffer =
                    new StringBuffer(64)
                    .append(&quot;Created table '&quot;)
                    .append(tableName)
                    .append(&quot;' using sqlResources string '&quot;)
                    .append(createSqlStringName)
                    .append(&quot;'.&quot;);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/AbstractRedirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/AbstractRedirect.html#480">480</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/Redirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/Redirect.html#375">375</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        String addressList = getInitParameter(&quot;to&quot;,getInitParameter(&quot;recipients&quot;));

        // if nothing was specified, return null meaning no change
        if (addressList == null) {
            return null;
        }

        try {
            iaarray = InternetAddress.parse(addressList, false);
            for(int i = 0; i &lt; iaarray.length; ++i) {
                String addressString = iaarray[i].getAddress();
                MailAddress specialAddress = getSpecialAddress(addressString,
                                                new String[] {&quot;postmaster&quot;, &quot;sender&quot;, &quot;from&quot;, &quot;replyTo&quot;, &quot;reversePath&quot;, &quot;unaltered&quot;, &quot;recipients&quot;, &quot;to&quot;, &quot;null&quot;});
                if (specialAddress != null) {
                    iaarray[i] = specialAddress.toInternetAddress();
                }
            }
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception thrown in getTo() parsing: &quot; + addressList, e);
        }
        if (iaarray.length == 0) {
            throw new MessagingException(&quot;Failed to initialize \&quot;to\&quot; list; empty &lt;to&gt; init parameter found.&quot;);
        }

        return iaarray;
    }

    /**
     * @return the &lt;CODE&gt;reversePath&lt;/CODE&gt; init parameter 
     * or the postmaster address
     * or &lt;CODE&gt;SpecialAddress.SENDER&lt;/CODE&gt;
     * or &lt;CODE&gt;SpecialAddress.NULL&lt;/CODE&gt;
     * or &lt;CODE&gt;null&lt;/CODE&gt; if missing
     */
    protected MailAddress getReversePath() throws MessagingException {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/nntpserver/NNTPHandler.java</td><td>Apache JAMES Server NNTP function</td><td><a href="./xref/org/apache/james/nntpserver/NNTPHandler.html#770">770</a></td></tr><tr class="a"><td>org/apache/james/nntpserver/NNTPHandler.java</td><td>Apache JAMES Server NNTP function</td><td><a href="./xref/org/apache/james/nntpserver/NNTPHandler.html#969">969</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                helper.writeLoggedResponse(respBuffer.toString());
            }
        } else {
            int newArticleNumber = currentArticleNumber;
            if ( group == null ) {
                helper.writeLoggedFlushedResponse(&quot;412 no newsgroup selected&quot;);
                return;
            } else {
                if ( param == null ) {
                    if ( currentArticleNumber &lt; 0 ) {
                        helper.writeLoggedFlushedResponse(&quot;420 no current article selected&quot;);
                        return;
                    } else {
                        article = group.getArticle(currentArticleNumber);
                    }
                }
                else {
                    newArticleNumber = Integer.parseInt(param);
                    article = group.getArticle(newArticleNumber);
                }
                if ( article == null ) {
                    helper.writeLoggedFlushedResponse(&quot;423 no such article number in this group&quot;);
                    return;
                } else {
                    currentArticleNumber = newArticleNumber;
                    String articleID = article.getUniqueID();
                    if (articleID == null) {
                        articleID = &quot;&lt;0&gt;&quot;;
                    }
                    StringBuffer respBuffer =
                        new StringBuffer(128)
                                .append(&quot;220 &quot;)</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#528">528</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#651">651</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                    log(&quot;Removal request issued by &quot; + senderMailAddress);
                }
                //Commit our changes if necessary.
                if (conn != null &amp;&amp; dbUpdated &amp;&amp; !conn.getAutoCommit()) {
                    conn.commit() ;
                    dbUpdated = false;
                }
            }
            else {
                out.println(&quot;The message must be plain - no action&quot;);
            }
            
            out.println();
            out.println(&quot;Finished&quot;);
            
            sendReplyFromPostmaster(mail, sout.toString());
            
        } catch (SQLException sqle) {
            out.println(&quot;Error accessing the database&quot;);
            sendReplyFromPostmaster(mail, sout.toString());
            throw new MessagingException(&quot;Error accessing the database&quot;, sqle);
        } catch (IOException ioe) {
            out.println(&quot;Error getting message content&quot;);
            sendReplyFromPostmaster(mail, sout.toString());
            throw new MessagingException(&quot;Error getting message content&quot;, ioe);
        } finally {
            theJDBCUtil.closeJDBCStatement(selectStmt);
            theJDBCUtil.closeJDBCStatement(deleteStmt);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/vut/JDBCVirtualUserTable.java</td><td>Apache JAMES Server Avalon User function</td><td><a href="./xref/org/apache/james/vut/JDBCVirtualUserTable.html#170">170</a></td></tr><tr class="a"><td>org/apache/james/mailrepository/JDBCMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/JDBCMailRepository.html#298">298</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        Connection conn = datasource.getConnection();
        PreparedStatement createStatement = null;

        try {
            // Initialise the sql strings.

            InputStream sqlFile = null;
            try {
                sqlFile = fileSystem.getResource(sqlFileName);
            } catch (Exception e) {
                getLogger().fatalError(e.getMessage(), e);
                throw e;
            }

            if (getLogger().isDebugEnabled()) {
                logBuffer =
                    new StringBuffer(128)
                            .append(&quot;Reading SQL resources from file: &quot;)
                            .append(sqlFileName)
                            .append(&quot;, section &quot;)
                            .append(this.getClass().getName())
                            .append(&quot;.&quot;);
                getLogger().debug(logBuffer.toString());
            }

            // Build the statement parameters
            Map sqlParameters = new HashMap();
            if (tableName != null) {
                sqlParameters.put(&quot;table&quot;, tableName);
            }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/BayesianAnalysis.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/BayesianAnalysis.html#230">230</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/BayesianAnalysisFeeder.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/BayesianAnalysisFeeder.html#189">189</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        initDb();
        
    }
    
    private void initDb() throws MessagingException {
        
        try {
            ServiceManager serviceManager = (ServiceManager) getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
            
            // Get the DataSourceSelector block
            DataSourceSelector datasources = (DataSourceSelector) serviceManager.lookup(DataSourceSelector.ROLE);
            
            // Get the data-source required.
            int stindex =   repositoryPath.indexOf(&quot;://&quot;) + 3;
            
            String datasourceName = repositoryPath.substring(stindex);
            
            datasource = (DataSourceComponent) datasources.select(datasourceName);
        } catch (Exception e) {
            throw new MessagingException(&quot;Can't get datasource&quot;, e);
        }
        
        try {
            analyzer.initSqlQueries(datasource.getConnection(), getMailetContext().getAttribute(&quot;confDir&quot;) + &quot;/sqlResources.xml&quot;);
        } catch (Exception e) {
            throw new MessagingException(&quot;Exception initializing queries&quot;, e);
        }        </pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/AbstractRedirect.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/AbstractRedirect.html#1031">1031</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/DSNBounce.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/DSNBounce.html#217">217</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            setRecipients(newMail, getRecipients(originalMail), originalMail);
            setTo(newMail, getTo(originalMail), originalMail);
            setSubjectPrefix(newMail, getSubjectPrefix(originalMail), originalMail);
            if(newMail.getMessage().getHeader(RFC2822Headers.DATE) == null) {
                newMail.getMessage().setHeader(RFC2822Headers.DATE,rfc822DateFormat.format(new Date()));
            }
            setReplyTo(newMail, getReplyTo(originalMail), originalMail);
            setReversePath(newMail, getReversePath(originalMail), originalMail);
            setSender(newMail, getSender(originalMail), originalMail);
            setIsReply(newMail, isReply(originalMail), originalMail);
    
            newMail.getMessage().saveChanges();</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/util/XMLResources.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/XMLResources.html#142">142</a></td></tr><tr class="a"><td>org/apache/james/util/sql/SqlResources.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/sql/SqlResources.html#184">184</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                        .append(sqlDefsSection)
                        .append(&quot;\' does not exist.&quot;);
            throw new RuntimeException(exceptionBuffer.toString());
        }

        // Get parameters defined within the file as defaults,
        // and use supplied parameters as overrides.
        Map parameters = new HashMap();
        // First read from the &lt;params&gt; element, if it exists.
        Element parametersElement = 
            (Element)(sectionElement.getElementsByTagName(&quot;parameters&quot;).item(0));
        if ( parametersElement != null ) {
            NamedNodeMap params = parametersElement.getAttributes();
            int paramCount = params.getLength();
            for (int i = 0; i &lt; paramCount; i++ ) {
                Attr param = (Attr)params.item(i);
                String paramName = param.getName();
                String paramValue = param.getValue();
                parameters.put(paramName, paramValue);
            }
        }
        // Then copy in the parameters supplied with the call.
        parameters.putAll(configParameters);

        // 2 maps - one for storing default statements,
        // the other for statements with a &quot;db&quot; attribute matching this 
        // connection.
        Map defaultSqlStatements = new HashMap();</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#333">333</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#485">485</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                        String recipientUser = recipientMailAddress.getUser().toLowerCase(Locale.US);
                        String recipientHost = recipientMailAddress.getHost().toLowerCase(Locale.US);
                        
                        if (getMailetContext().isLocalServer(recipientHost)) {
                            // not a remote recipient, so skip
                            continue;
                        }
                        
                        if (conn == null) {
                            conn = datasource.getConnection();
                        }
                        
                        if (selectStmt == null) {
                            selectStmt = conn.prepareStatement(selectByPK);
                        }
                        selectStmt.setString(1, senderUser);
                        selectStmt.setString(2, senderHost);
                        selectStmt.setString(3, recipientUser);
                        selectStmt.setString(4, recipientHost);
                        selectRS = selectStmt.executeQuery();
                        if (selectRS.next()) {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/pop3server/RetrCmdHandler.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/RetrCmdHandler.html#74">74</a></td></tr><tr class="a"><td>org/apache/james/pop3server/TopCmdHandler.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/TopCmdHandler.html#102">102</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                        writeMessageContentTo(mc.getMessage(),nouts,lines);
                        nouts.flush();
                        edouts.checkCRLFTerminator();
                        edouts.flush();
                    } finally {
                        session.writeResponse(&quot;.&quot;);
                    }
                } else {
                    StringBuffer responseBuffer =
                        new StringBuffer(64)
                                .append(POP3Handler.ERR_RESPONSE)
                                .append(&quot; Message (&quot;)
                                .append(num)
                                .append(&quot;) already deleted.&quot;);
                    responseString = responseBuffer.toString();
                    session.writeResponse(responseString);
                }
            } catch (IOException ioe) {
                responseString = POP3Handler.ERR_RESPONSE + &quot; Error while retrieving message.&quot;;
                session.writeResponse(responseString);
            } catch (MessagingException me) {
                responseString = POP3Handler.ERR_RESPONSE + &quot; Error while retrieving message.&quot;;
                session.writeResponse(responseString);
            } catch (IndexOutOfBoundsException iob) {
                StringBuffer exceptionBuffer =</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/pop3server/POP3HandlerChain.java</td><td>Apache JAMES Server POP3 function</td><td><a href="./xref/org/apache/james/pop3server/POP3HandlerChain.html#149">149</a></td></tr><tr class="a"><td>org/apache/james/smtpserver/SMTPHandlerChain.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/SMTPHandlerChain.html#127">127</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            }
        }

        // the size must be greater than 1 because we added UnknownCmdHandler to
        // the map

        if (commandHandlerMap.size() &lt; 2) {
            if (getLogger().isErrorEnabled()) {
                getLogger().error(&quot;No commandhandlers configured&quot;);
            }
            throw new ConfigurationException(&quot;No commandhandlers configured&quot;);
        } else {
            boolean found = true;
            for (int i = 0; i &lt; mandatoryCommands.length; i++) {
                if (!commandHandlerMap.containsKey(mandatoryCommands[i])) {
                    if (getLogger().isErrorEnabled()) {
                        getLogger().error(
                                &quot;No commandhandlers configured for the command:&quot;
                                        + mandatoryCommands[i]);
                    }
                    found = false;
                    break;
                }
            }

            if (!found) {
                throw new ConfigurationException(
                        &quot;No commandhandlers configured for mandatory commands&quot;);
            }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/JDBCAlias.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/JDBCAlias.html#89">89</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/JDBCVirtualUserTable.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/JDBCVirtualUserTable.html#128">128</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        try {
            ServiceManager componentManager = (ServiceManager)getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
            // Get the DataSourceSelector service
            DataSourceSelector datasources = (DataSourceSelector)componentManager.lookup(DataSourceSelector.ROLE);
            // Get the data-source required.
            datasource = (DataSourceComponent)datasources.select(datasourceName);

            conn = datasource.getConnection();

            // Check if the required table exists. If not, complain.
            DatabaseMetaData dbMetaData = conn.getMetaData();
            // Need to ask in the case that identifiers are stored, ask the DatabaseMetaInfo.
            // Try UPPER, lower, and MixedCase, to see if the table is there.
            if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
                StringBuffer exceptionBuffer =
                                              new StringBuffer(128)
                                              .append(&quot;Could not find table '&quot;)
                                              .append(tableName)
                                              .append(&quot;' in datasource '&quot;)
                                              .append(datasourceName)
                                              .append(&quot;'&quot;);
                throw new MailetException(exceptionBuffer.toString());
            }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#333">333</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/WhiteListManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/WhiteListManager.html#608">608</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                        String recipientUser = recipientMailAddress.getUser().toLowerCase(Locale.US);
                        String recipientHost = recipientMailAddress.getHost().toLowerCase(Locale.US);
                        
                        if (getMailetContext().isLocalServer(recipientHost)) {
                            // not a remote recipient, so skip
                            continue;
                        }
                        
                        if (conn == null) {
                            conn = datasource.getConnection();
                        }
                        
                        if (selectStmt == null) {
                            selectStmt = conn.prepareStatement(selectByPK);
                        }
                        selectStmt.setString(1, senderUser);
                        selectStmt.setString(2, senderHost);
                        selectStmt.setString(3, recipientUser);
                        selectStmt.setString(4, recipientHost);
                        selectRS = selectStmt.executeQuery();
                        if (!selectRS.next()) {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/mailrepository/JDBCMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/JDBCMailRepository.html#523">523</a></td></tr><tr class="a"><td>org/apache/james/mailrepository/JDBCMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/JDBCMailRepository.html#627">627</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        ObjectOutputStream oos = new ObjectOutputStream(baos);
                        try {
                            if (mc instanceof MailImpl) {
                            oos.writeObject(((MailImpl)mc).getAttributesRaw());
                            } else {
                                HashMap temp = new HashMap();
                                for (Iterator i = mc.getAttributeNames(); i.hasNext(); ) {
                                    String hashKey = (String) i.next();
                                    temp.put(hashKey,mc.getAttribute(hashKey));
                                }
                                oos.writeObject(temp);
                            }
                            oos.flush();
                            ByteArrayInputStream attrInputStream =
                                new ByteArrayInputStream(baos.toByteArray());</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/util/bayesian/JDBCBayesianAnalyzer.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/bayesian/JDBCBayesianAnalyzer.html#399">399</a></td></tr><tr class="a"><td>org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.html#619">619</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        }
    }

    /**
     * Create the table if not exists.
     * 
     * @param conn
     *            The connection
     * @param tableNameSqlStringName
     *            The tableSqlname
     * @param createSqlStringName
     *            The createSqlname
     * @return true or false
     * @throws SQLException
     */
    private boolean createTable(Connection conn, String tableNameSqlStringName,
    String createSqlStringName) throws SQLException {
        String tableName = sqlQueries.getSqlString(tableNameSqlStringName, true);

        DatabaseMetaData dbMetaData = conn.getMetaData();

        // Try UPPER, lower, and MixedCase, to see if the table is there.
        if (theJDBCUtil.tableExists(dbMetaData, tableName)) {
            return false;
        }

        PreparedStatement createStatement = null;

        try {
            createStatement = conn.prepareStatement(sqlQueries.getSqlString(createSqlStringName, true));
            createStatement.execute();

            StringBuffer logBuffer = null;
            logBuffer = new StringBuffer(64).append(&quot;Created table '&quot;).append(tableName)
            .append(&quot;' using sqlResources string '&quot;)
            .append(createSqlStringName).append(&quot;'.&quot;);</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/smtpserver/core/DataCmdHandler.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/core/DataCmdHandler.html#153">153</a></td></tr><tr class="a"><td>org/apache/james/smtpserver/core/SendMailHandler.java</td><td>Apache JAMES Server SMTP function</td><td><a href="./xref/org/apache/james/smtpserver/core/SendMailHandler.html#100">100</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>                   StringBuffer errorBuffer =
                     new StringBuffer(256)
                         .append(&quot;Rejected message from &quot;)
                         .append(session.getState().get(SMTPSession.SENDER).toString())
                         .append(&quot; from host &quot;)
                         .append(session.getRemoteHost())
                         .append(&quot; (&quot;)
                         .append(session.getRemoteIPAddress())
                         .append(&quot;) exceeding system maximum message size of &quot;)
                         .append(session.getConfigurationData().getMaxMessageSize());
                   getLogger().error(errorBuffer.toString());
              } else {
                   responseString = &quot;451 &quot;+DSNStatus.getStatus(DSNStatus.TRANSIENT,DSNStatus.UNDEFINED_STATUS)+&quot; Error processing message.&quot;;</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/domain/JDBCDomainList.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/domain/JDBCDomainList.html#167">167</a></td></tr><tr class="a"><td>org/apache/james/mailrepository/JDBCMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/JDBCMailRepository.html#307">307</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>            } catch (Exception e) {
                getLogger().fatalError(e.getMessage(), e);
                throw e;
            }

            if (getLogger().isDebugEnabled()) {
                logBuffer =
                    new StringBuffer(128)
                            .append(&quot;Reading SQL resources from file: &quot;)
                            .append(sqlFileName)
                            .append(&quot;, section &quot;)
                            .append(this.getClass().getName())
                            .append(&quot;.&quot;);
                getLogger().debug(logBuffer.toString());
            }

            // Build the statement parameters
            Map sqlParameters = new HashMap();
            if (tableName != null) {
                sqlParameters.put(&quot;table&quot;, tableName);
            }</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/util/XMLResources.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/XMLResources.html#278">278</a></td></tr><tr class="a"><td>org/apache/james/util/sql/SqlResources.java</td><td>Apache JAMES Server Common Utilities</td><td><a href="./xref/org/apache/james/util/sql/SqlResources.html#346">346</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>    private String substituteSubString( String input, 
                                        String find,
                                        String replace )
    {
        int find_length = find.length();
        int replace_length = replace.length();

        StringBuffer output = new StringBuffer(input);
        int index = input.indexOf(find);
        int outputOffset = 0;

        while ( index &gt; -1 ) {
            output.replace(index + outputOffset, index + outputOffset + find_length, replace);
            outputOffset = outputOffset + (replace_length - find_length);

            index = input.indexOf(find, index + find_length);
        }

        String result = output.toString();
        return result;
    }

    /**
     * Returns a named SQL string for the specified connection,
     * replacing parameters with the values set.
     * 
     * @param name   the name of the SQL resource required.
     * @return the requested resource
     */
    public String getSqlString(String name)</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/mailrepository/AbstractMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/AbstractMailRepository.html#112">112</a></td></tr><tr class="a"><td>org/apache/james/mailrepository/javamail/AbstractJavamailStoreMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/javamail/AbstractJavamailStoreMailRepository.html#253">253</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        if (getLock().lock(key)) {
            if ((DEEP_DEBUG) &amp;&amp; (getLogger().isDebugEnabled())) {
                StringBuffer debugBuffer = new StringBuffer(256).append(
                        &quot;Locked &quot;).append(key).append(&quot; for &quot;).append(
                        Thread.currentThread().getName()).append(&quot; @ &quot;).append(
                        new java.util.Date(System.currentTimeMillis()));
                getLogger().debug(debugBuffer.toString());
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * Releases a lock on a message identified by a key
     * 
     * @param key
     *            the key of the message to be unlocked
     * 
     * @return true if successfully released the lock, false otherwise
     */
    public boolean unlock(String key) {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/mailrepository/AbstractMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/AbstractMailRepository.html#90">90</a></td></tr><tr class="a"><td>org/apache/james/mailrepository/javamail/AbstractJavamailStoreMailRepository.java</td><td>Apache JAMES Server Core function</td><td><a href="./xref/org/apache/james/mailrepository/javamail/AbstractJavamailStoreMailRepository.html#276">276</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>        if (getLock().unlock(key)) {
            if ((DEEP_DEBUG) &amp;&amp; (getLogger().isDebugEnabled())) {
                StringBuffer debugBuffer = new StringBuffer(256).append(
                        &quot;Unlocked &quot;).append(key).append(&quot; for &quot;).append(
                        Thread.currentThread().getName()).append(&quot; @ &quot;).append(
                        new java.util.Date(System.currentTimeMillis()));
                getLogger().debug(debugBuffer.toString());
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * Removes a specified message
     * 
     * @param mail
     *            the message to be removed from the repository
     * @throws MessagingException
     */
    public void remove(Mail mail) throws MessagingException {</pre></div></td></tr><table class="bodyTable"></p><p><table class="bodyTable"><tr class="a"><th>File</th><th>Project</th><th>Line</th></tr><tr class="b"><td>org/apache/james/transport/mailets/CommandListservManager.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/CommandListservManager.html#416">416</a></td></tr><tr class="a"><td>org/apache/james/transport/mailets/CommandListservProcessor.java</td><td>Apache JAMES Server Mailets function</td><td><a href="./xref/org/apache/james/transport/mailets/CommandListservProcessor.html#452">452</a></td></tr><tr class="b"><td colspan='3'><div class="source"><pre>    }

    /**
     * Retrieves a data field, potentially defined by a super class.
     * @return null if not found, the object otherwise
     */
    protected static Object getField(Object instance, String name) throws IllegalAccessException {
        Class clazz = instance.getClass();
        Field[] fields;
        while (clazz != null) {
            fields = clazz.getDeclaredFields();
            for (int index = 0; index &lt; fields.length; index++) {
                Field field = fields[index];
                if (field.getName().equals(name)) {
                    field.setAccessible(true);
                    return field.get(instance);
                }
            }
            clazz = clazz.getSuperclass();
        }

        return null;
    }</pre></div></td></tr><table class="bodyTable"></p></div>
      </div>
    </div>
    <div class="clear">
      <hr/>
    </div>
    <div id="footer">
      <div class="xright">&#169;  
          2002-2009
    
          The Apache Software Foundation
          
  

  
    
  
  
  </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
    </script>
    <script type="text/javascript">
      _uacct = "UA-1384591-1";
      urchinTracker();
    </script>
  </body>
</html>
