📄 abstractredirect.java
字号:
/**************************************************************** * 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. * ****************************************************************/package org.apache.james.transport.mailets;import java.io.PrintWriter;import java.io.StringWriter;import java.util.Collection;import java.util.Date;import java.util.Enumeration;import java.util.HashSet;import java.util.Iterator;import java.util.Locale;import java.util.ArrayList;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.internet.ParseException;import javax.mail.Session;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import org.apache.mailet.RFC2822Headers;import org.apache.mailet.dates.RFC822DateFormat;import org.apache.james.core.MailImpl;import org.apache.james.core.MimeMessageUtil;import org.apache.mailet.GenericMailet;import org.apache.mailet.Mail;import org.apache.mailet.MailAddress;/** * <P>Abstract mailet providing configurable redirection services.<BR> * This mailet can be subclassed to make authoring redirection mailets simple.<BR> * By extending it and overriding one or more of these methods new behaviour can * be quickly created without the author having to address any other issue than * the relevant one:</P> * <UL> * <LI>attachError() , should error messages be appended to the message</LI> * <LI>getAttachmentType(), what should be attached to the message</LI> * <LI>getInLineType(), what should be included in the message</LI> * <LI>getMessage(), The text of the message itself</LI> * <LI>getRecipients(), the recipients the mail is sent to</LI> * <LI>getReplyTo(), where replies to this message will be sent</LI> * <LI>getReversePath(), what to set the reverse-path to</LI> * <LI>getSender(), who the mail is from</LI> * <LI>getSubject(), a string to replace the message subject</LI> * <LI>getSubjectPrefix(), a prefix to be added to the message subject, possibly already replaced by a new subject</LI> * <LI>getTo(), a list of people to whom the mail is *apparently* sent</LI> * <LI>isReply(), should this mailet set the IN_REPLY_TO header to the id of the current message</LI> * <LI>getPassThrough(), should this mailet allow the original message to continue processing or GHOST it.</LI> * <LI>getFakeDomainCheck(), should this mailet check if the sender domain address is valid.</LI> * <LI>isStatic(), should this mailet run the get methods for every mail, or just once.</LI> * </UL> * <P>For each of the methods above (generically called "getX()" methods in this class * and its subclasses), there is an associated "getX(Mail)" method and most times * a "setX(Mail, Tx, Mail)" method.<BR> * The roles are the following:</P> * <UL> * <LI>a "getX()" method returns the correspondent "X" value that can be evaluated "statically" * once at init time and then stored in a variable and made available for later use by a * "getX(Mail)" method;</LI> * <LI>a "getX(Mail)" method is the one called to return the correspondent "X" value * that can be evaluated "dynamically", tipically based on the currently serviced mail; * the default behaviour is to return the value of getX();</LI> * <LI>a "setX(Mail, Tx, Mail)" method is called to change the correspondent "X" value * of the redirected Mail object, using the value returned by "gexX(Mail)"; * if such value is null, it does nothing.</LI> * </UL> * <P>Here follows the typical pattern of those methods:</P> * <PRE><CODE> * ... * Tx x; * ... * protected boolean getX(Mail originalMail) throws MessagingException { * boolean x = (isStatic()) ? this.x : getX(); * ... * return x; * } * ... * public void init() throws MessagingException { * ... * isStatic = (getInitParameter("static") == null) ? false : new Boolean(getInitParameter("static")).booleanValue(); * if(isStatic()) { * ... * X = getX(); * ... * } * ... * public void service(Mail originalMail) throws MessagingException { * ... * setX(newMail, getX(originalMail), originalMail); * ... * } * ... * </CODE></PRE> * <P>The <I>isStatic</I> variable and method is used to allow for the situations * (deprecated since version 2.2, but possibly used by previoulsy written extensions * to {@link Redirect}) in which the getX() methods are non static: in this case * {@link #isStatic()} must return false.<BR> * Finally, a "getX()" method may return a "special address" (see {@link SpecialAddress}), * that later will be resolved ("late bound") by a "getX(Mail)" or "setX(Mail, Tx, Mail)": * it is a dynamic value that does not require <CODE>isStatic</CODE> to be false.</P> * * <P>Supports by default the <CODE>passThrough</CODE> init parameter (false if missing). * Subclasses can override this behaviour overriding {@link #getPassThrough()}.</P> * * @version CVS $Revision: 494012 $ $Date: 2007-01-08 11:23:58 +0100 (Mo, 08 Jan 2007) $ * @since 2.2.0 */public abstract class AbstractRedirect extends GenericMailet { /** * Gets the expected init parameters. * * @return null meaning no check */ protected String[] getAllowedInitParameters() { return null; } /** * Controls certain log messages. */ protected boolean isDebug = false; /** * Holds the value of the <CODE>static</CODE> init parameter. */ protected boolean isStatic = false; private static class AddressMarker { public static MailAddress SENDER; public static MailAddress REVERSE_PATH; public static MailAddress FROM; public static MailAddress REPLY_TO; public static MailAddress TO; public static MailAddress RECIPIENTS; public static MailAddress DELETE; public static MailAddress UNALTERED; public static MailAddress NULL; static { try { SENDER = new MailAddress("sender","address.marker"); REVERSE_PATH = new MailAddress("reverse.path","address.marker"); FROM = new MailAddress("from","address.marker"); REPLY_TO = new MailAddress("reply.to","address.marker"); TO = new MailAddress("to","address.marker"); RECIPIENTS = new MailAddress("recipients","address.marker"); DELETE = new MailAddress("delete","address.marker"); UNALTERED = new MailAddress("unaltered","address.marker"); NULL = new MailAddress("null","address.marker"); } catch (Exception _) {} } } /** * Class containing "special addresses" constants. * Such addresses mean dynamic values that later will be resolved ("late bound") * by a "getX(Mail)" or "setX(Mail, Tx, Mail)". */ protected static class SpecialAddress { public static final MailAddress SENDER = AddressMarker.SENDER; public static final MailAddress REVERSE_PATH = AddressMarker.REVERSE_PATH; public static final MailAddress FROM = AddressMarker.FROM; public static final MailAddress REPLY_TO = AddressMarker.REPLY_TO; public static final MailAddress TO = AddressMarker.TO; public static final MailAddress RECIPIENTS = AddressMarker.RECIPIENTS; public static final MailAddress DELETE = AddressMarker.DELETE; public static final MailAddress UNALTERED = AddressMarker.UNALTERED; public static final MailAddress NULL = AddressMarker.NULL; } // The values that indicate how to attach the original mail // to the new mail. protected static final int UNALTERED = 0; protected static final int HEADS = 1; protected static final int BODY = 2; protected static final int ALL = 3; protected static final int NONE = 4; protected static final int MESSAGE = 5; private boolean passThrough = false; private boolean fakeDomainCheck = true; private int attachmentType = NONE; private int inLineType = BODY; private String messageText; private Collection recipients; private MailAddress replyTo; private MailAddress reversePath; private MailAddress sender; private String subject; private String subjectPrefix; private InternetAddress[] apparentlyTo; private boolean attachError = false; private boolean isReply = false; private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat(); /* ******************************************************************** */ /* ****************** Begin of getX and setX methods ****************** */ /* ******************************************************************** */ /** * <P>Gets the <CODE>static</CODE> property.</P> * <P>Return true to reduce calls to getTo, getSender, getRecipients, getReplyTo, getReversePath amd getMessage * where these values don't change (eg hard coded, or got at startup from the mailet config); * return false where any of these methods generate their results dynamically eg in response to the message being processed, * or by reference to a repository of users.</P> * <P>It is now (from version 2.2) somehow obsolete, as should be always true because the "good practice" * is to use "getX()" methods statically, and use instead "getX(Mail)" methods for dynamic situations. * A false value is now meaningful only for subclasses of {@link Redirect} older than version 2.2 * that were relying on this.</P> * * <P>Is a "getX()" method.</P> * * @return true, as normally "getX()" methods shouls be static */ protected boolean isStatic() { return true; } /** * Gets the <CODE>passThrough</CODE> property. * Return true to allow the original message to continue through the processor, false to GHOST it. * Is a "getX()" method. * * @return the <CODE>passThrough</CODE> init parameter, or false if missing */ protected boolean getPassThrough() throws MessagingException { return new Boolean(getInitParameter("passThrough")).booleanValue(); } /** * Gets the <CODE>passThrough</CODE> property, * built dynamically using the original Mail object. * Is a "getX(Mail)" method. * * @return {@link #getPassThrough()} */ protected boolean getPassThrough(Mail originalMail) throws MessagingException { return (isStatic()) ? this.passThrough : getPassThrough(); } /** * Gets the <CODE>fakeDomainCheck</CODE> property. * Return true to check if the sender domain is valid. * Is a "getX()" method. * * @return the <CODE>fakeDomainCheck</CODE> init parameter, or true if missing */ protected boolean getFakeDomainCheck() throws MessagingException { return new Boolean(getInitParameter("fakeDomainCheck")).booleanValue(); } /** * Gets the <CODE>fakeDomainCheck</CODE> property, * built dynamically using the original Mail object. * Is a "getX(Mail)" method. * * @return {@link #getFakeDomainCheck()} */ protected boolean getFakeDomainCheck(Mail originalMail) throws MessagingException { return (isStatic()) ? this.fakeDomainCheck : getFakeDomainCheck(); } /** * Gets the <CODE>inline</CODE> property. * May return one of the following values to indicate how to append the original message * to build the new message: * <ul> * <li><CODE>UNALTERED</CODE> : original message is the new message body</li> * <li><CODE>BODY</CODE> : original message body is appended to the new message</li> * <li><CODE>HEADS</CODE> : original message headers are appended to the new message</li> * <li><CODE>ALL</CODE> : original is appended with all headers</li> * <li><CODE>NONE</CODE> : original is not appended</li> * </ul> * Is a "getX()" method. * * @return the <CODE>inline</CODE> init parameter, or <CODE>UNALTERED</CODE> if missing */ protected int getInLineType() throws MessagingException { return getTypeCode(getInitParameter("inline","unaltered")); } /** * Gets the <CODE>inline</CODE> property,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -