001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.mail;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021: import java.util.Set;
022: import javax.mail.Folder;
023: import javax.mail.MessagingException;
024: import javax.mail.Store; //import javax.mail.Session;
025: import org.apache.avalon.framework.context.Context;
026: import org.apache.avalon.framework.context.ContextException;
027: import org.apache.avalon.framework.context.DefaultContext;
028: import org.apache.avalon.framework.logger.Logger;
029: import org.apache.avalon.framework.logger.LogEnabled;
030: import org.apache.cocoon.environment.Request;
031:
032: /**
033: * Encapsulation of context info of this webmail application
034: *
035: * @author Bernhard Huber
036: * @since 29 December 2002
037: * @version $Id: MailContext.java 468424 2006-10-27 15:44:53Z vgritsenko $
038: */
039: public class MailContext extends DefaultContext implements LogEnabled {
040:
041: /**
042: * attribute name of MailContext object in an application session, eg http-session
043: */
044: public final static String SESSION_MAIL_CONTEXT = "mail-context";
045:
046: /**
047: * Description of the Field
048: */
049: public final static String MAIL_SESSION_ENTRY = "mail-session";
050:
051: /**
052: * Description of the Field
053: */
054: public final static String MAIL_STORE_ENTRY = "mail-store";
055:
056: /**
057: * Description of the Field
058: */
059: public final static String MAIL_CURRENT_WORKING_FOLDER_ENTRY = "mail-current-working-folder";
060: /**
061: * Description of the Field
062: */
063: public final static String MAIL_CURRENT_WORKING_COMMAND_ENTRY = "mail-current-working-command";
064:
065: private Request request;
066: private Logger logger;
067:
068: /**
069: *Constructor for the MailContext object
070: *
071: * @param parent Description of the Parameter
072: */
073: MailContext(Context parent) {
074: super (parent);
075: }
076:
077: /**
078: * Sets the request attribute of the MailContext object
079: *
080: * @param request The new request value
081: */
082: public void setRequest(Request request) {
083: this .request = request;
084: }
085:
086: /**
087: * A specialization of the plain Context get method.
088: * <p>
089: * Implementing special key prefixes
090: * </p>
091: * <ul>
092: * <li>"param:key" get key from request parameters
093: * </li>
094: * <li>"param-integer:key" get key from request parameters, casting to Integer
095: * </li>
096: * <li>"param-folder:key" get key from request parameters, ie foldername, lookup
097: * foldername using key "folder:foldername"
098: * </li>
099: * <li>key get key via plain context get method
100: * </li>
101: * </ul>
102: *
103: * @param key Description of the Parameter
104: * @return Description of the Return Value
105: * @exception ContextException Description of the Exception
106: */
107: public Object get(Object key) throws ContextException {
108: String keyString = (String) key;
109:
110: final String PARAM_PREFIX_ENTRY = "param:";
111: final String PARAM_INTEGER_PREFIX_ENTRY = "param-integer:";
112: final String PARAM_FOLDER_PREFIX_ENTRY = "param-folder:";
113:
114: if (keyString.startsWith(PARAM_PREFIX_ENTRY)) {
115: String paramName = keyString.substring(PARAM_PREFIX_ENTRY
116: .length());
117: String paramValue = getParameter(paramName);
118: if (paramValue == null) {
119: String message = "No parameter "
120: + String.valueOf(keyString) + " available.";
121: throw new ContextException(message);
122: }
123: return paramValue;
124: } else if (keyString.startsWith(PARAM_INTEGER_PREFIX_ENTRY)) {
125: String paramName = keyString
126: .substring(PARAM_INTEGER_PREFIX_ENTRY.length());
127: try {
128: return getParameterAsInteger(paramName);
129: } catch (NumberFormatException nfe) {
130: String message = "Cannot create Integer for parameter "
131: + String.valueOf(keyString);
132: throw new ContextException(message, nfe);
133: }
134: } else if (keyString.startsWith(PARAM_FOLDER_PREFIX_ENTRY)) {
135: String paramName = keyString
136: .substring(PARAM_FOLDER_PREFIX_ENTRY.length());
137: String folderName = getParameter(paramName);
138: if (folderName == null) {
139: // no folderName is available in the parameters bag
140: // try to get the current working folder
141: try {
142: folderName = (String) super
143: .get(MAIL_CURRENT_WORKING_FOLDER_ENTRY);
144: } catch (ContextException ce) {
145: // no current working folder entry available
146: String message = "No "
147: + MAIL_CURRENT_WORKING_FOLDER_ENTRY
148: + " entry available ";
149: getLogger().error(message);
150: throw new ContextException(message, ce);
151: }
152: }
153:
154: // get folder object, folderName is okay
155: Folder folder;
156: try {
157: folder = (Folder) getFolder(folderName);
158: } catch (ContextException ce) {
159: // folder is not stored yet
160:
161: Store store = (Store) get(MAIL_STORE_ENTRY);
162: // get folder, eventually connect the store
163: try {
164: if (!store.isConnected()) {
165: store.connect();
166: }
167: final String DEFAULT_FOLDER_NAME = "~";
168:
169: // empty folder name is specified by empty string, or "~"
170: if (folderName.equals(DEFAULT_FOLDER_NAME)
171: || folderName.length() == 0) {
172: folder = store.getDefaultFolder();
173: } else {
174: folder = store.getFolder(folderName);
175: }
176:
177: // save the Folder, for later access
178: putFolder(folder);
179: } catch (MessagingException me) {
180: String message = "Cannot get folder "
181: + String.valueOf(folderName);
182: throw new ContextException(message, ce);
183: }
184: }
185: return folder;
186: } else {
187: return super .get(key);
188: }
189: }
190:
191: /**
192: * Gets the theFolder attribute of the MailContext object
193: *
194: * @param entry Description of the Parameter
195: * @return The theFolder value
196: * @exception ContextException Description of the Exception
197: */
198: public Folder getTheFolder(String entry) throws ContextException {
199: Folder f;
200: try {
201: f = (Folder) get("param-folder:" + entry);
202: } catch (Exception e) {
203: String message = "Cannot get Folder object for "
204: + String.valueOf(entry);
205: throw new ContextException(message, e);
206: }
207: return f;
208: }
209:
210: /**
211: * Gets the folder attribute of the MailContext object
212: *
213: * @param folderName Description of the Parameter
214: * @return The folder value
215: * @exception ContextException Description of the Exception
216: */
217: public Object getFolder(String folderName) throws ContextException {
218: // canonicalize folder name
219: folderName = canoncializeFoldername(folderName);
220:
221: final String key = "folder:" + folderName;
222: getLogger().debug("Getting folder " + String.valueOf(key));
223:
224: Object o = super .get(key);
225: getLogger().debug(
226: "Successfully getting folder " + String.valueOf(key)
227: + ": " + String.valueOf(o));
228: return o;
229: }
230:
231: /**
232: * Remove and close Store of this MailContext, implicitly remove all folders, too.
233: */
234: public void removeStore() {
235: try {
236: getLogger().info("Remove store " + String.valueOf(this ));
237: removeAllFolders();
238:
239: Map map = getContextData();
240: Store store = (Store) map.remove(MAIL_STORE_ENTRY);
241: if (store != null) {
242: MailCommandManager.closeStore(store);
243: }
244: } catch (Exception e) {
245: String message = "Cannot remove store";
246: getLogger().error(message, e);
247: }
248: }
249:
250: /**
251: * remove all folders in this MailContext object
252: */
253: public void removeAllFolders() {
254: try {
255: getLogger().info("Remove folders " + String.valueOf(this ));
256:
257: Map map = getContextData();
258: Set entrySet = map.entrySet();
259: Iterator i = entrySet.iterator();
260: while (i.hasNext()) {
261: Map.Entry me = (Map.Entry) i.next();
262: String key = (String) me.getKey();
263: if (key.startsWith("folder:")) {
264: Folder f = (Folder) me.getValue();
265: MailCommandManager.closeFolder(f);
266: i.remove();
267: }
268: }
269: } catch (Exception e) {
270: String message = "Cannot remove all folders";
271: getLogger().error(message, e);
272: }
273: }
274:
275: /**
276: * put a folder in this MailContext object map
277: *
278: * @param folder Description of the Parameter
279: * @exception ContextException Description of the Exception
280: */
281: public void putFolder(Folder folder) throws ContextException {
282: String folderName = folder.getFullName();
283: // canonicalize folder name
284: folderName = canoncializeFoldername(folderName);
285:
286: final String key = "folder:" + folderName;
287:
288: getLogger().debug(
289: "Putting folder key: " + String.valueOf(key)
290: + " folder " + String.valueOf(folder));
291:
292: // close folder if folder is overwritten
293: try {
294: Object objRef = super .get(key);
295: if (objRef != null) {
296: // close this folder as it is goint to get overwritten
297: try {
298: Folder f = (Folder) objRef;
299: MailCommandManager.closeFolder(f);
300: } catch (MessagingException me) {
301: String message = "Cannot close folder";
302: getLogger().warn(message, me);
303: }
304: }
305: } catch (ContextException e) {
306: // ignore as we set it
307: }
308:
309: // Shall we garbage collect folders?
310:
311: super .put(key, folder);
312: }
313:
314: /**
315: * Description of the Method
316: *
317: * @param folders Description of the Parameter
318: * @exception ContextException Description of the Exception
319: */
320: public void putFolder(Folder[] folders) throws ContextException {
321: for (int i = 0; i < folders.length; i++) {
322: putFolder(folders[i]);
323: }
324: }
325:
326: /**
327: * Description of the Method
328: *
329: * @param logger Description of the Parameter
330: */
331: public void enableLogging(Logger logger) {
332: this .logger = logger;
333: }
334:
335: /**
336: * Gets the parameter attribute of the MailContext object
337: *
338: * @param key Description of the Parameter
339: * @return The parameter value
340: */
341: protected String getParameter(String key) {
342: return request.getParameter(key);
343: }
344:
345: /**
346: * Gets the parameterAsInteger attribute of the MailContext object
347: *
348: * @param key Description of the Parameter
349: * @return The parameterAsInteger value
350: */
351: protected Integer getParameterAsInteger(String key) {
352: String value = request.getParameter(key);
353: return new Integer(value);
354: }
355:
356: /**
357: * Gets the logger attribute of the MailContext object
358: *
359: * @return The logger value
360: */
361: protected Logger getLogger() {
362: return this .logger;
363: }
364:
365: /**
366: * Description of the Method
367: *
368: * @param fn Description of the Parameter
369: * @return Description of the Return Value
370: */
371: protected String canoncializeFoldername(String fn) {
372: //
373: return fn;
374: }
375:
376: }
|