<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License.    
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- Generated by Apache Maven Doxia at Apr 17, 2012 -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>
  Apache James Server 3 - Manage Recipient Rewrite Table</title>
    <style type="text/css" media="all">
      @import url("./css/james.css");
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
      @import url("./js/jquery/css/custom-theme/jquery-ui-1.8.5.custom.css");
      @import url("./js/jquery/css/print.css");
      @import url("./js/fancybox/jquery.fancybox-1.3.4.css");
    </style>
    <script type="text/javascript" src="./js/jquery/js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="./js/jquery/js/jquery-ui-1.8.5.custom.min.js"></script>
    <script type="text/javascript" src="./js/fancybox/jquery.fancybox-1.3.4.js"></script>
    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
    <meta name="Date-Revision-yyyymmdd" content="20120417" />
    <meta http-equiv="Content-Language" content="en" />
                                                    
<link title="DOAP" rel="meta" type="application/rdf+xml" href="http://james.apache.org//doap_james-project.rdf"/>
                      
          <!-- Google Analytics -->
    <script type="text/javascript">
    
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-1384591-1']);
      _gaq.push(['_trackPageview']);

      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script').item(0); s.parentNode.insertBefore(ga, s);
      })();

    </script>
    </head>
  <body class="composite">
    <div id="banner">
                                      <a href="../index.html" id="bannerLeft" title="james-server-logo.gif">
              
                                                                            
        <img src="images/logos/james-server-logo.gif" alt="Apache James Server 3.0" />
                </a>
                              <a href="http://www.apache.org/index.html" id="bannerRight">
              
                                        
        <img src="images/logos/asf-logo-reduced.gif" alt="The Apache Software Foundation" />
                </a>
            <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="breadcrumbs">
            
                
                <div class="xleft">
        <span id="publishDate">Last Published: 2012-04-17</span>
                      </div>
            <div class="xright">                    <a href="../../index.html" title="Home">Home</a>
            |
                        <a href="../index.html" title="Server">Server</a>
            |
                        <a href="../../hupa/index.html" title="Hupa">Hupa</a>
            |
                        <a href="../../protocols/index.html" title="Protocols">Protocols</a>
            |
                        <a href="../../imap/index.html" title="IMAP">IMAP</a>
            |
                        <a href="../../mailet/index.html" title="Mailets">Mailets</a>
            |
                        <a href="../../mailbox/index.html" title="Mailbox">Mailbox</a>
            |
                        <a href="../../mime4j/index.html" title="Mime4J">Mime4J</a>
            |
                        <a href="../../jsieve/index.html" title="jSieve">jSieve</a>
            |
                        <a href="../../jspf/index.html" title="jSPF">jSPF</a>
            |
                        <a href="../../jdkim/index.html" title="jDKIM">jDKIM</a>
            |
                        <a href="../../mpt/index.html" title="MPT">MPT</a>
            |
                        <a href="../../postage/index.html" title="Postage">Postage</a>
              
                
      </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="leftColumn">
      <div id="navcolumn">
             
                
                                <h5>Overview</h5>
                  <ul>
                  <li class="none">
                          <a href="index.html" title="Introduction">Introduction</a>
            </li>
                  <li class="none">
                          <a href="release-notes.html" title="Release Notes">Release Notes</a>
            </li>
          </ul>
                       <h5>Features</h5>
                  <ul>
                  <li class="none">
                          <a href="feature-mailetcontainer.html" title="Mailet Container">Mailet Container</a>
            </li>
                  <li class="none">
                          <a href="feature-queue-priority.html" title="Queue Priority">Queue Priority</a>
            </li>
                  <li class="none">
                          <a href="feature-persistence.html" title="Persistence">Persistence</a>
            </li>
                  <li class="none">
                          <a href="feature-protocols.html" title="Protocols">Protocols</a>
            </li>
                  <li class="none">
                          <a href="feature-smtp-hooks.html" title="SMTP Hooks">SMTP Hooks</a>
            </li>
                  <li class="none">
                          <a href="feature-performance.html" title="Performance">Performance</a>
            </li>
                  <li class="none">
                          <a href="feature-security.html" title="Security">Security</a>
            </li>
          </ul>
                       <h5>User Manual</h5>
                  <ul>
                  <li class="none">
                          <a href="quick-start.html" title="1. Quick Start">1. Quick Start</a>
            </li>
                  <li class="none">
                          <a href="install.html" title="2. Install James">2. Install James</a>
            </li>
                                                                                                                                                                                                                                                                                                                                <li class="collapsed">
                          <a href="config.html" title="3. Configure James">3. Configure James</a>
                  </li>
                                                                                                                  <li class="expanded">
                          <a href="manage.html" title="4. Manage">4. Manage</a>
                    <ul>
                      <li class="none">
                          <a href="manage-domains.html" title="Domains">Domains</a>
            </li>
                      <li class="none">
                          <a href="manage-users.html" title="Users">Users</a>
            </li>
                      <li class="none">
            <strong>Recipient Rewrite</strong>
          </li>
              </ul>
        </li>
                                                                                                        <li class="collapsed">
                          <a href="monitor.html" title="5. Monitor">5. Monitor</a>
                  </li>
                                                                                      <li class="collapsed">
                          <a href="upgrade.html" title="6. Upgrade">6. Upgrade</a>
                  </li>
          </ul>
                       <h5>Developers Corner</h5>
                  <ul>
                  <li class="none">
                          <a href="dev.html" title="Architecture">Architecture</a>
            </li>
                  <li class="none">
                          <a href="dev-build.html" title="Build from source">Build from source</a>
            </li>
                  <li class="none">
                          <a href="dev-database-schema.html" title="Database Schema">Database Schema</a>
            </li>
                                                                                                        <li class="collapsed">
                          <a href="dev-extend.html" title="Develop Extensions">Develop Extensions</a>
                  </li>
                                                                                                        <li class="collapsed">
                          <a href="dev-provided.html" title="Provided Extensions">Provided Extensions</a>
                  </li>
                  <li class="none">
                          <a href="https://repository.apache.org/content/repositories/snapshots/org/apache/james/apache-james/" title="Nightly builds">Nightly builds</a>
            </li>
          </ul>
                       <h5>References</h5>
                  <ul>
                  <li class="none">
                          <a href="apidocs/index.html" title="Javadoc">Javadoc</a>
            </li>
                  <li class="none">
                          <a href="https://issues.apache.org/jira/browse/JAMES" title="Issue Tracker">Issue Tracker</a>
            </li>
          </ul>
                       <h5>About James</h5>
                  <ul>
                  <li class="none">
                          <a href="../../index.html" title="Overview">Overview</a>
            </li>
                  <li class="none">
                          <a href="../../newsarchive.html" title="News">News</a>
            </li>
                  <li class="none">
                          <a href="../../mail.html" title="Mailing Lists">Mailing Lists</a>
            </li>
                  <li class="none">
                          <a href="../../contribute.html" title="Contributing">Contributing</a>
            </li>
                  <li class="none">
                          <a href="../../guidelines.html" title="Guidelines">Guidelines</a>
            </li>
                  <li class="none">
                          <a href="http://wiki.apache.org/james" title="Wiki">Wiki</a>
            </li>
                  <li class="none">
                          <a href="../../team-list.html" title="Who We Are">Who We Are</a>
            </li>
                  <li class="none">
                          <a href="../../license.html" title="License">License</a>
            </li>
          </ul>
                       <h5>Download</h5>
                  <ul>
                  <li class="none">
                          <a href="../../download.cgi" title="Releases">Releases</a>
            </li>
                  <li class="none">
                          <a href="https://repository.apache.org/content/repositories/snapshots/org/apache/james/" title=""></a>
            </li>
          </ul>
        <h5>Apache Software Foundation</h5>
  <ul>
    <li>
      <strong>
        <a title="ASF" href="http://www.apache.org/">ASF</a>
      </strong>
    </li>
    <li>
      <a title="Get Involved" href="http://www.apache.org/foundation/getinvolved.html">Get Involved</a>
    </li>
    <li>
      <a title="FAQ" href="http://www.apache.org/foundation/faq.html">FAQ</a>
    </li>
    <li>
      <a title="License" href="http://www.apache.org/licenses/" >License</a>
    </li>
    <li>
      <a title="Sponsorship" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
    </li>
    <li>
      <a title="Thanks" href="http://www.apache.org/foundation/thanks.html">Thanks</a>
    </li>
    <li>
      <a title="Security" href="http://www.apache.org/security/">Security</a>
    </li>
  </ul>
                       <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
        <img class="poweredBy" alt="Built by Maven" src="./images/logos/maven-feather.png" />
      </a>
                   
                
            </div>
    </div>
    <div id="bodyColumn">
      <div id="contentBox">
        <!-- Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied.  See the License for the
  specific language governing permissions and limitations
  under the License. -->

 

  <div class="section"><h2>Manage Recipient Rewrite<a name="Manage_Recipient_Rewrite"></a></h2>
  
    <p>To rewrite recipients, you need to create some &quot;mappings&quot;.</p>

    <p>You will rewrite any recipient to an existing or a non-existing server account.</p>
    
    <p>So read &quot;mapping allows to rewrite a 'fromAny(Existing/NotExisting) user and/or domain' to a 'toAny(Existing/NotExisting)Account'&quot;.</p>

    <p>'An existing account' means an account defined in the Apache James Server.</p>
    
    <p>You can also use regular expressions and wildcards (*) for the 'fromAny'.</p>
    
    <p>The available methods exposed in the management interface are the following:</p>
    
    <div class="source"><pre>
    /**
     * Add regex mapping
     * 
     * @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.
     */
    void addRegexMapping(String user, String domain, String regex) throws Exception;

    /**
     * Remove regex mapping
     * 
     * @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.
     */
    void removeRegexMapping(String user, String domain, String regex) throws Exception;

    /***
     * Add address mapping
     * 
     * @param user
     *            the username. Null if no username should be used
     * @param domain
     *            the domain. Null if no domain should be used
     * @param address
     *            the address.
     */
    void addAddressMapping(String user, String domain, String address) throws Exception;

    /**
     * Remove address mapping
     * 
     * @param user
     *            the username. Null if no username should be used
     * @param domain
     *            the domain. Null if no domain should be used
     * @param address
     */
    void removeAddressMapping(String user, String domain, String address) throws Exception;

    /**
     * Add error mapping
     * 
     * @param user
     *            the username. Null if no username should be used
     * @param domain
     *            the domain. Null if no domain should be used
     * @param error
     */
    void addErrorMapping(String user, String domain, String error) throws Exception;

    /**
     * Remove error mapping
     * 
     * @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
     */
    void removeErrorMapping(String user, String domain, String error) throws Exception;

    /**
     * Add domain mapping
     * 
     * @param domain
     *            the domain. Null if no domain should be used
     * @param targetDomain
     *            the target domain for the mapping
     * @return true if successfully
     */
    void addDomainMapping(String domain, String targetDomain) throws Exception;

    /**
     * Remove domain mapping
     * 
     * @param domain
     *            the domain. Null if no domain should be used
     * @param targetDomain
     *            the target domain for the mapping
     * 
     * @return true if successfully
     */
    void removeDomainMapping(String domain, String targetDomain) throws Exception;

    /**
     * Return the explicit mapping stored for the given user and domain. Return
     * null if no mapping was found
     * 
     * @param user
     *            the username
     * @param domain
     *            the domain
     * @return the collection which holds the mappings.
     */
    Collection&lt;String&gt; getUserDomainMappings(String user, String domain) throws Exception;

    /**
     * Try to identify the right method based on the prefix of the mapping and
     * add it.
     * 
     * @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.
     */
    void addMapping(String user, String domain, String mapping) throws Exception;

    /**
     * Try to identify the right method based on the prefix of the mapping and
     * remove it.
     * 
     * @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.
     */
    void removeMapping(String user, String domain, String mapping) throws Exception;

    /**
     * Return a Map which holds all mappings. The key is the user@domain and the
     * value is a Collection which holds all mappings
     * 
     * @return Map which holds all mappings
     */
    Map&lt;String, Collection&lt;String&gt;&gt; getAllMappings() throws Exception;
    </pre></div>

  </div>

  <div class="section"><h2>Manage Recipient Rewrite Table via Cli<a name="Manage_Recipient_Rewrite_Table_via_Cli"></a></h2>
  
    <p>Not available in this release.</p>
    
  </div>

  <div class="section"><h2>Manage Virtual Users via JMX<a name="Manage_Virtual_Users_via_JMX"></a></h2>
  
    <p>Use and JMX client to access the Virtual User management function.</p>
  
    <p>The managed objects are exposed from localhost only (for security reasons) on the following URL:</p>
      
    <p><tt>service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi</tt></p>
      
  </div>




      </div>
    </div>
    <div class="clear">
      <hr/>
    </div>
    <div id="footer">
      <div class="xright">Copyright &#169;                    2002-2012
                        <a href="http://www.apache.org/">The Apache Software Foundation</a>.
            All Rights Reserved.      
                
      </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
  </body>
</html>
