001 /****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one *
003 * or more contributor license agreements. See the NOTICE file *
004 * distributed with this work for additional information *
005 * regarding copyright ownership. The ASF licenses this file *
006 * to you under the Apache License, Version 2.0 (the *
007 * "License"); you may not use this file except in compliance *
008 * with the License. You may obtain a copy of the License at *
009 * *
010 * http://www.apache.org/licenses/LICENSE-2.0 *
011 * *
012 * Unless required by applicable law or agreed to in writing, *
013 * software distributed under the License is distributed on an *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015 * KIND, either express or implied. See the License for the *
016 * specific language governing permissions and limitations *
017 * under the License. *
018 ****************************************************************/
019
020
021 package org.apache.mailet.base;
022
023 import javax.mail.MessagingException;
024
025 import org.apache.mailet.Mail;
026 import org.apache.mailet.Mailet;
027 import org.apache.mailet.MailetConfig;
028 import org.apache.mailet.MailetContext;
029 import org.apache.mailet.MailetContext.LogLevel;
030
031 import java.util.*;
032
033 /**
034 * GenericMailet makes writing mailets easier. It provides simple
035 * versions of the lifecycle methods init and destroy and of the methods
036 * in the MailetConfig interface. GenericMailet also implements the log
037 * method, declared in the MailetContext interface.
038 * <p>
039 * To write a generic mailet, you need only override the abstract service
040 * method.
041 *
042 * @version 1.0.0, 24/04/1999
043 */
044 public abstract class GenericMailet implements Mailet, MailetConfig {
045 private MailetConfig config = null;
046
047 /**
048 * Called by the mailer container to indicate to a mailet that the
049 * mailet is being taken out of service.
050 */
051 public void destroy() {
052 //Do nothing
053 }
054
055 /**
056 * <p>Gets a boolean valued init parameter.</p>
057 * <p>A convenience method. The result is parsed
058 * from the value of the named parameter in the {@link MailetConfig}.</p>
059 * @param name name of the init parameter to be queried
060 * @param defaultValue this value will be substituted when the named value
061 * cannot be parse or when the init parameter is absent
062 * @return true when the init parameter is <code>true</code> (ignoring case);
063 * false when the init parameter is <code>false</code> (ignoring case);
064 * otherwise the default value
065 * @throws NullPointerException before {@link #init(MailetConfig)}
066 */
067 public boolean getInitParameter(String name, boolean defaultValue) {
068 if (config == null) {
069 throw new NullPointerException("Mailet configuration must be set before getInitParameter is called.");
070 }
071 return MailetUtil.getInitParameter(config, name, defaultValue);
072 }
073
074 /**
075 * Returns a String containing the value of the named initialization
076 * parameter, or null if the parameter does not exist.
077 * <p>
078 * This method is supplied for convenience. It gets the value of the
079 * named parameter from the mailet's MailetConfig object.
080 *
081 * @param name - a String specifying the name of the initialization parameter
082 * @return a String containing the value of the initalization parameter
083 */
084 public String getInitParameter(String name) {
085 return config.getInitParameter(name);
086 }
087
088 /**
089 * Returns a String containing the value of the named initialization
090 * parameter, or defValue if the parameter does not exist.
091 * <p>
092 * This method is supplied for convenience. It gets the value of the
093 * named parameter from the mailet's MailetConfig object.
094 *
095 * @param name - a String specifying the name of the initialization parameter
096 * @param defValue - a String specifying the default value when the parameter
097 * is not present
098 * @return a String containing the value of the initalization parameter
099 */
100 public String getInitParameter(String name, String defValue) {
101 String res = config.getInitParameter(name);
102 if (res == null) {
103 return defValue;
104 } else {
105 return res;
106 }
107 }
108
109 /**
110 * Returns the names of the mailet's initialization parameters as an
111 * Iterator of String objects, or an empty Iterator if the mailet has no
112 * initialization parameters.
113 * <p>
114 * This method is supplied for convenience. It gets the parameter names from
115 * the mailet's MailetConfig object.
116 *
117 * @return an Iterator of String objects containing the names of
118 * the mailet's initialization parameters
119 */
120 public Iterator<String> getInitParameterNames() {
121 return config.getInitParameterNames();
122 }
123
124 /**
125 * Returns this Mailet's MailetConfig object.
126 *
127 * @return the MailetConfig object that initialized this mailet
128 */
129 public MailetConfig getMailetConfig() {
130 return config;
131 }
132
133 /**
134 * Returns a reference to the MailetContext in which this mailet is
135 * running.
136 *
137 * @return the MailetContext object passed to this mailet by the init method
138 */
139 public MailetContext getMailetContext() {
140 return getMailetConfig().getMailetContext();
141 }
142
143 /**
144 * Returns information about the mailet, such as author, version, and
145 * copyright. By default, this method returns an empty string. Override
146 * this method to have it return a meaningful value.
147 *
148 * @return information about this mailet, by default an empty string
149 */
150 public String getMailetInfo() {
151 return "";
152 }
153
154 /**
155 * Returns the name of this mailet instance.
156 *
157 * @return the name of this mailet instance
158 */
159 public String getMailetName() {
160 return config.getMailetName();
161 }
162
163
164 /**
165 * <p>Called by the mailet container to indicate to a mailet that the
166 * mailet is being placed into service.</p>
167 *
168 * <p>This implementation stores the MailetConfig object it receives from
169 * the mailet container for later use. When overriding this form of the
170 * method, call super.init(config).</p>
171 *
172 * @param newConfig - the MailetConfig object that contains
173 * configutation information for this mailet
174 * @throws MessagingException
175 * if an exception occurs that interrupts the mailet's normal operation
176 */
177 public void init(MailetConfig newConfig) throws MessagingException {
178 config = newConfig;
179 init();
180 }
181
182 /**
183 * <p>A convenience method which can be overridden so that there's no
184 * need to call super.init(config).</p>
185 *
186 * Instead of overriding init(MailetConfig), simply override this
187 * method and it will be called by GenericMailet.init(MailetConfig config).
188 * The MailetConfig object can still be retrieved via getMailetConfig().
189 *
190 * @throws MessagingException
191 * if an exception occurs that interrupts the mailet's normal operation
192 */
193 public void init() throws MessagingException {
194 //Do nothing... can be overriden
195 }
196
197 /**
198 * Writes the specified message to a mailet log file.
199 *
200 * @param message - a String specifying the message to be written to the log file
201 */
202 public void log(String message) {
203 getMailetContext().log(LogLevel.INFO, message);
204 }
205
206 /**
207 * Writes an explanatory message and a stack trace for a given Throwable
208 * exception to the mailet log file.
209 *
210 * @param message - a String that describes the error or exception
211 * @param t - the java.lang.Throwable to be logged
212 */
213 public void log(String message, Throwable t) {
214 getMailetContext().log(LogLevel.ERROR, message, t);
215 }
216
217 /**
218 * <p>Called by the mailet container to allow the mailet to process a
219 * message.</p>
220 *
221 * <p>This method is declared abstract so subclasses must override it.</p>
222 *
223 * @param mail - the Mail object that contains the MimeMessage and
224 * routing information
225 * @throws javax.mail.MessagingException - if an exception occurs that interferes with the mailet's normal operation
226 */
227 public abstract void service(Mail mail) throws javax.mail.MessagingException;
228
229
230
231 /**
232 * Utility method: Checks if there are unallowed init parameters specified in the
233 * configuration file against the String[] allowedInitParameters.
234 * @param allowedArray array of strings containing the allowed parameter names
235 * @throws MessagingException if an unknown parameter name is found
236 */
237 protected final void checkInitParameters(String[] allowedArray) throws MessagingException {
238 // if null then no check is requested
239 if (allowedArray == null) {
240 return;
241 }
242
243 Collection<String> allowed = new HashSet<String>();
244 Collection<String> bad = new ArrayList<String>();
245
246 Collections.addAll(allowed, allowedArray);
247
248 Iterator<String> iterator = getInitParameterNames();
249 while (iterator.hasNext()) {
250 String parameter = iterator.next();
251 if (!allowed.contains(parameter)) {
252 bad.add(parameter);
253 }
254 }
255
256 if (bad.size() > 0) {
257 throw new MessagingException("Unexpected init parameters found: "
258 + arrayToString(bad.toArray()));
259 }
260 }
261
262 /**
263 * Utility method for obtaining a string representation of an array of Objects.
264 */
265 protected final String arrayToString(Object[] array) {
266 if (array == null) {
267 return "null";
268 }
269 StringBuilder sb = new StringBuilder(1024);
270 sb.append("[");
271 for (int i = 0; i < array.length; i++) {
272 if (i > 0) {
273 sb.append(",");
274 }
275 sb.append(array[i]);
276 }
277 sb.append("]");
278 return sb.toString();
279 }
280
281 }
282
283