| <?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 - Writing a Custom Matcher</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="collapsed">
|
| <a href="manage.html" title="4. Manage">4. Manage</a>
|
| </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="expanded">
|
| <a href="dev-extend.html" title="Develop Extensions">Develop Extensions</a>
|
| <ul>
|
| <li class="none">
|
| <a href="dev-extend-mailet.html" title="Mailet">Mailet</a>
|
| </li>
|
| <li class="none">
|
| <strong>Matcher</strong>
|
| </li>
|
| <li class="none">
|
| <a href="dev-extend-smtp-hook.html" title="SMTP Hook">SMTP Hook</a>
|
| </li>
|
| </ul>
|
| </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>Writing a Custom Matcher<a name="Writing_a_Custom_Matcher"></a></h2> |
| |
| <p>Implementing a custom matcher is generally a simple task, most of whose complexity |
| lies in coding the actual work to be done by the matcher. This is largely due to the |
| simplicity of the Matcher interface and the fact that a couple of abstract Matcher template |
| classes are provided in the Mailet package. These two classes, GenericMatcher and |
| GenericRecipientMatcher, greatly simplfy the task of Matcher authoring.</p> |
| <p>As discussed elsewhere in this manual, the Matcher interface does not simply match |
| or not match a particular message. Rather, it returns some subset of the original message |
| recipients as a result of the match(Mail) method. This leads to the two different abstract |
| Matcher implementations.</p> |
| <p>The first, GenericMatcher, is intended for matchers where recipient evaluation is not |
| necessary. Basically, you should subclass this implementation if your matcher is going to |
| return all or none of the recipients.</p> |
| <p>When subclassing this class, there are four methods that potentially need to be |
| overridden. These are getMatcherInfo(), init(), match(Mail), and destroy(). More on these |
| anon.</p> |
| <p>The second implementation, GenericRecipientMatcher, is intended for those matchers where |
| each recipient is evaluated individually. It is a subclass of GenericMatcher, and inherits |
| most of its behavior from that class. The only major difference is that subclasses are |
| expected to override matchRecipient(MailAddress) rather than match(Mail).</p> |
| |
| <div class="section"><h3>Configuration<a name="Configuration"></a></h3> |
| <p>Matchers are passed a single String as part of their configuration. Interpretation of this |
| list is left entirely to the body of the Matcher. This String value is available in |
| the body of the Matcher through use of the getCondition() method of the |
| GenericMatcher class. This method returns the String value passed to the Matcher, and returns |
| null if no value is set. The method getCondition() is available inside the init(), destroy(), match(Mail), |
| and matchRecipient(MailAddress) methods.</p> |
| </div> |
| |
| <div class="section"><h3>Logging<a name="Logging"></a></h3> |
| <p>There is a simple logging mechanism provided by the Mailet API. It does not support |
| logging levels, so any log filtering will have to be implemented in the Matcher code. |
| Logging is done by calling one of the two logging methods on GenericMatcher/GenericRecipientMatcher - log(String) |
| or log(String,Throwable). Logging is available inside the init(), destroy(), match(Mail), |
| and matchRecipient(MailAddress) methods.</p> |
| <p>The value of getMatcherInfo() for the Matcher is prepended to the log entries for that |
| Matcher. So it may be desirable for you to override this method so you can distinguish Matcher |
| log entries by Matcher.</p> |
| </div> |
| |
| <div class="section"><h3>Initialization<a name="Initialization"></a></h3> |
| <p>As part of the Matcher lifecycle, a Matcher is guaranteed to be initialized immediately after |
| being instantiated. This happens once and only once for each Matcher instance. The |
| Initialization phase is where configuration parsing and per-Matcher resource creation generally |
| take place. Depending on your Matcher, it may or may not be necessary to do any initialization |
| of the Matcher. Initialization logic is implemented by overriding the init() method of |
| GenericMatcher/GenericRecipientMatcher.</p> |
| </div> |
| |
| <div class="section"><h3>Matching<a name="Matching"></a></h3> |
| <p>It is the matching phase where the Matcher's work is done. The exact form of this phase largely |
| depends on which Matcher superclass is subclassed.</p> |
| <p>If GenericMatcher is being subclassed, it is the match(Mail) that is implemented. As described |
| above, this method returns a Collection of MailAddresses that is a subset of the original |
| recipients for the Mail object.</p> |
| <p>If it is a purely recipient-filtering Matcher, then the GenericRecipientMatcher should be |
| subclassed. In this case, developers must provide an implementation of the |
| matchRecipient(MailAddress) method. This method returns true if the recipient matches, |
| and false otherwise.</p> |
| </div> |
| |
| <div class="section"><h3>Destruction<a name="Destruction"></a></h3> |
| <p>As part of the Matcher lifecycle, a Matcher is guaranteed to be destroyed when the container |
| cleans up the Matcher. This happens once and only once for each Matcher instance. The |
| Destruction phase is where per-Matcher resource release generally takes place. Depending |
| on your Matcher, it may or may not be necessary to do any destruction |
| of the Matcher. Destruction logic is implemented by overriding the destroy() method of |
| GenericMatcher/GenericRecipientMatcher.</p> |
| </div> |
| |
| </div> |
| |
| <div class="section"><h2>Deploying a Custom Matcher<a name="Deploying_a_Custom_Matcher"></a></h2> |
| <p>Once a Matcher has been successfully implemented there are only a couple of |
| additional steps necessary to actually deploy the Matcher.</p> |
| <div class="section"><h3>Adding Your Matcher to the Classpath<a name="Adding_Your_Matcher_to_the_Classpath"></a></h3> |
| <p> |
| The Matcher must be added to James' classpath so that the Matcher can be loaded by James. There |
| are two ways to add a custom Matcher to the classpath so that James will be able to load the |
| Matcher. These are: |
| </p> |
| <p> |
| 1a. Download the source distribution, add a jar file containing the custom files to the lib |
| directory of the unpacked source distribution, and build a new .sar file by following the |
| directions <a href="build-instructions.html">here</a>. This new .sar file will now |
| include your custom classes. |
| </p> |
| <p> |
| or |
| </p> |
| <p> |
| 1b. Place a jar file containing the custom class files in the lib subdirectory of the James |
| installation. It will also be necessary to unpack the JavaMail and James jar files from |
| the provided .sar file and add them to this directory. |
| </p> |
| <p> |
| or |
| </p> |
| <p> |
| 1c. Place a jar file containing the custom class files in |
| /path/to/james/conf/lib/ subdirectory. |
| </p> |
| <p> |
| 2. After this is done get sure you add the matcher package to the mailetcontainer.xml. For example: |
| <p> |
| </p><div class="source"><pre> |
| <!-- Set the Java packages from which to load mailets and matchers --> |
| <matcherpackages> |
| <matcherpackage>org.apache.james.transport.matchers</matcherpackage> |
| <matcherpackage>org.apache.james.transport.matchers.smime</matcherpackage> |
| <matcherpackage>your.costum.package.transport-matchers</matcherpackage> |
| </matcherpackages> |
| </pre></div> |
| |
| After that restart james. |
| |
| </div> |
| |
| <div class="section"><h3>James Configuration<a name="James_Configuration"></a></h3> |
| <p>Configuration of the processor chain is discussed |
| <a href="config-mailetcontainer.html">elsewhere</a> in this documentation. The |
| details of configuring matcher deployment is discussed at length. Here we will only comment |
| that it is important to add the appropriate matcher package for your custom matcher to the |
| <matcherpackages> list and that the name of your matcher should not conflict with any of |
| the matchers described <a href="dev-provided-matchers.html">here</a>. |
| </p> |
| </div> |
| |
| </div> |
| |
| |
|
|
| </div>
|
| </div>
|
| <div class="clear">
|
| <hr/>
|
| </div>
|
| <div id="footer">
|
| <div class="xright">Copyright © 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>
|