| /* |
| * 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.cocoon.mail; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import javax.mail.Folder; |
| import javax.mail.Message; |
| import javax.mail.Provider; |
| import javax.mail.Store; |
| import javax.mail.URLName; |
| |
| import org.apache.avalon.framework.context.ContextException; |
| import org.apache.avalon.framework.logger.Logger; |
| import org.apache.avalon.framework.parameters.Parameters; |
| import org.apache.avalon.framework.thread.ThreadSafe; |
| import org.apache.cocoon.ProcessingException; |
| import org.apache.cocoon.acting.ServiceableAction; |
| import org.apache.cocoon.environment.ObjectModelHelper; |
| import org.apache.cocoon.environment.Redirector; |
| import org.apache.cocoon.environment.Request; |
| import org.apache.cocoon.environment.Session; |
| import org.apache.cocoon.environment.SourceResolver; |
| import org.apache.cocoon.mail.command.AbstractMailCommand; |
| |
| /** |
| * This action creates javamail objects, and puts XMLizable object wrappers |
| * of these objects into the request attribute map. |
| * <p> |
| * This action enables javamail access as action. It creates an http sesion, |
| * and puts the MailContext object into the session attributes. |
| * </p> |
| * |
| * @see MailContext |
| * |
| * @author Bernhard Huber |
| * @version $Id$ |
| * @since Cocoon 2.1, 16 December 2002 |
| */ |
| public class MailAction extends ServiceableAction implements ThreadSafe { |
| |
| /** |
| * Request attribute name of a XMLizable folder |
| */ |
| public final static String REQUEST_ATTRIBUTE_FOLDER = "folder"; |
| |
| /** |
| * Request attribute name of a XMLizable folders object |
| */ |
| public final static String REQUEST_ATTRIBUTE_FOLDERS = "folders"; |
| |
| /** |
| * Request attribute name of a XMLizable message object |
| */ |
| public final static String REQUEST_ATTRIBUTE_MESSAGE = "message"; |
| |
| /** |
| * Request attribute name of a XMLizable messages object |
| */ |
| public final static String REQUEST_ATTRIBUTE_MESSAGES = "messages"; |
| |
| |
| /** |
| * Execute mail commands. |
| * |
| * @param redirector Cocoon's redirector |
| * @param resolver Cocoon's source resolver, used for testing if a source is resolvable |
| * @param source the source, e.g.: index.html |
| * @param objectModel Description of the Parameter |
| * @param par Description of the Parameter |
| * @exception Exception Description of the Exception |
| */ |
| public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters par) |
| throws Exception { |
| Map actionMap = new HashMap(); |
| |
| Request request = ObjectModelHelper.getRequest(objectModel); |
| |
| String command = request.getParameter("cmd"); |
| String folderName = request.getParameter("folder"); |
| String userid = request.getParameter("mail-userid"); |
| String password = request.getParameter("mail-password"); |
| |
| // assert mailContext is available |
| Session session = request.getSession(true); |
| MailContext mailContext = (MailContext) session.getAttribute(MailContext.SESSION_MAIL_CONTEXT); |
| if (mailContext == null) { |
| // no mailContext is yet available |
| // create it and put it into http-session |
| mailContext = new MailContextHttpSession(null); |
| mailContext.enableLogging(getLogger()); |
| session.setAttribute(MailContext.SESSION_MAIL_CONTEXT, mailContext); |
| } |
| |
| // assert mailSession is available |
| javax.mail.Session mailSession; |
| Store mailStore; |
| try { |
| try { |
| mailSession = (javax.mail.Session) mailContext.get(MailContext.MAIL_SESSION_ENTRY); |
| } catch (ContextException ce) { |
| // build session properties |
| Properties sessionProperties = new Properties(); |
| String[] allParameterNames = par.getNames(); |
| for (int i = 0; i < allParameterNames.length; i++) { |
| String parameterName = allParameterNames[i]; |
| final String PARAMETER_NAME_PREFIX = "javax.mail.Session.props:"; |
| if (parameterName.startsWith(PARAMETER_NAME_PREFIX)) { |
| String sessionPropName = parameterName.substring(PARAMETER_NAME_PREFIX.length()); |
| String sessionPropValue = par.getParameter(parameterName, null); |
| if (sessionPropValue != null) { |
| getLogger().debug("Add session property " + |
| String.valueOf(sessionPropName) + ": " + |
| String.valueOf(sessionPropValue)); |
| sessionProperties.put(sessionPropName, sessionPropValue); |
| } |
| } |
| } |
| mailSession = javax.mail.Session.getDefaultInstance(sessionProperties, null); |
| checkProviders(mailSession); |
| mailContext.put(MailContext.MAIL_SESSION_ENTRY, mailSession); |
| } |
| } catch (Exception e) { |
| String message = "Cannot create mail session"; |
| getLogger().error(message, e); |
| throw new ProcessingException(message, e); |
| } |
| |
| // assert mailStore is available |
| String storeURLNameExpanded = null; |
| String storeURLNameTemplate = par.getParameter("store-urlname", null); |
| try { |
| try { |
| mailStore = (Store) mailContext.get(MailContext.MAIL_STORE_ENTRY); |
| } catch (ContextException ce) { |
| |
| // imap://{userid}:{password}@host:port/ |
| storeURLNameExpanded = getURLNameExpanded(storeURLNameTemplate, userid, password); |
| |
| URLName urlNameExpanded = new URLName(storeURLNameExpanded); |
| getLogger().info("get store using URLName " + String.valueOf(urlNameExpanded)); |
| mailStore = mailSession.getStore(urlNameExpanded); |
| mailStore.connect(); |
| mailContext.put(MailContext.MAIL_STORE_ENTRY, mailStore); |
| } |
| } catch (Exception e) { |
| String message = "Cannot get store, and connect " + String.valueOf(storeURLNameExpanded); |
| getLogger().error(message, e); |
| throw new ProcessingException(message, e); |
| } |
| |
| if (folderName != null) { |
| // make folderName the current working folder (a la cwd) |
| // check foldername a bit |
| mailContext.put(MailContext.MAIL_CURRENT_WORKING_FOLDER_ENTRY, folderName); |
| } else { |
| // no folderName in request parameter, retrieve current working folder |
| folderName = (String) mailContext.get(MailContext.MAIL_CURRENT_WORKING_FOLDER_ENTRY); |
| } |
| actionMap.put(MailContext.MAIL_CURRENT_WORKING_FOLDER_ENTRY, folderName); |
| |
| if (command != null) { |
| mailContext.put(MailContext.MAIL_CURRENT_WORKING_COMMAND_ENTRY, command); |
| } else { |
| command = (String) mailContext.get(MailContext.MAIL_CURRENT_WORKING_COMMAND_ENTRY); |
| } |
| actionMap.put(MailContext.MAIL_CURRENT_WORKING_COMMAND_ENTRY, command); |
| |
| // mailSession and mailStore are available |
| |
| // excecute mail command, and populate request attribute |
| mailContext.setRequest(request); |
| populateRequestAttribute(request, mailContext); |
| // it's better to release ref to request, as it is not needed, and helps |
| // recycling of the request |
| mailContext.setRequest(null); |
| |
| return actionMap; |
| } |
| |
| |
| /** |
| * Gets the uRLNameExpanded attribute of the MailGenerator object |
| * |
| * @param storeURLNameTemplate Description of the Parameter |
| * @param userid Description of the Parameter |
| * @param password Description of the Parameter |
| * @return The uRLNameExpanded value |
| */ |
| protected String getURLNameExpanded(String storeURLNameTemplate, String userid, String password) { |
| String tokenStart = "''"; |
| String tokenEnd = "''"; |
| Properties filters = new Properties(); |
| filters.put("mail-userid", userid); |
| filters.put("mail-passwd", password); |
| |
| return filter(tokenStart, tokenEnd, storeURLNameTemplate, filters); |
| } |
| |
| |
| /** |
| * Replace occurences of <code>TOKEN_STARTxxxTOKEN_END</code> by value of entry xxx in tokens table. |
| * |
| * @param tokenStart token start marker |
| * @param tokenEnd token end marker |
| * @param s the string examined |
| * @param tokens Description of the Parameter |
| * @return String replaced all tokenized entries of original String s. |
| */ |
| protected String filter(final String tokenStart, final String tokenEnd, String s, Properties tokens) { |
| int index = s.indexOf(tokenStart); |
| |
| if (index > -1) { |
| try { |
| StringBuffer b = new StringBuffer(); |
| int i = 0; |
| String token; |
| String value; |
| |
| do { |
| int endIndex = s.indexOf(tokenEnd, index + tokenStart.length() + 1); |
| if (endIndex == -1) { |
| break; |
| } |
| token = s.substring(index + tokenStart.length(), endIndex); |
| b.append(s.substring(i, index)); |
| if (tokens.containsKey(token)) { |
| value = (String) tokens.get(token); |
| b.append(value); |
| i = index + tokenStart.length() + token.length() + tokenEnd.length(); |
| } else { |
| // just append TOKEN_START and search further |
| b.append(tokenStart); |
| i = index + tokenStart.length(); |
| } |
| } while ((index = s.indexOf(tokenStart, i)) > -1); |
| |
| b.append(s.substring(i)); |
| return b.toString(); |
| } catch (StringIndexOutOfBoundsException e) { |
| return s; |
| } |
| } else { |
| return s; |
| } |
| } |
| |
| |
| /** |
| * Check that the provider need is available |
| * |
| * @param session The javamail Session used for checking its providers. |
| */ |
| protected void checkProviders(javax.mail.Session session) { |
| Provider[] providers = session.getProviders(); |
| // just log the available providers |
| for (int i = 0; i < providers.length; i++) { |
| getLogger().info("mail provider " + providers[i]); |
| } |
| } |
| |
| |
| /** |
| * Populate request attribute map. |
| * <p> |
| * Execute mail command, and populate request attribute map with |
| * XMLizable javamail objects, created by the mail command |
| * </p> |
| * |
| * @param request triggering the creation of javamail objects |
| * @param mailContext javamail context, store, session, folders |
| * @exception Exception Description of the Exception |
| */ |
| protected void populateRequestAttribute(Request request, MailContext mailContext) throws Exception { |
| String folderName = (String) mailContext.get(MailContext.MAIL_CURRENT_WORKING_FOLDER_ENTRY); |
| request.setAttribute(MailContext.MAIL_CURRENT_WORKING_FOLDER_ENTRY, folderName); |
| String command = (String) mailContext.get(MailContext.MAIL_CURRENT_WORKING_COMMAND_ENTRY); |
| request.setAttribute(MailContext.MAIL_CURRENT_WORKING_COMMAND_ENTRY, command); |
| |
| // build javamail objects |
| List javaMailResult = retrieveJavaMailObjects(mailContext); |
| Iterator javaMailResultIterator; |
| |
| // put javamail objects into request attribute map |
| javaMailResultIterator = javaMailResult.iterator(); |
| //Request request = ObjectModelHelper.getRequest(objectModel); |
| putXMLizerToRequestAttribute(request, javaMailResultIterator); |
| } |
| |
| |
| /** |
| * Put XMLizable javamail objects into request attribute map |
| * |
| * @param request holding the destination attribute map |
| * @param resultIterator Iterator of |
| */ |
| protected void putXMLizerToRequestAttribute(Request request, Iterator resultIterator) { |
| if (resultIterator != null) { |
| // marshal java mail objects |
| Logger logger = getLogger(); |
| |
| // make it an optional parameter? |
| String datePattern = "dd.MM.yyyy HH:mm"; |
| SimpleDateFormat sdf = new SimpleDateFormat(datePattern); |
| |
| while (resultIterator.hasNext()) { |
| Object objRef = resultIterator.next(); |
| |
| getLogger().debug("Creating XMLizer for " + String.valueOf(objRef)); |
| |
| if (objRef instanceof Folder) { |
| MailContentHandlerDelegate.FolderXMLizer fx = new MailContentHandlerDelegate.FolderXMLizer((Folder) objRef); |
| fx.enableLogging(logger); |
| request.setAttribute(REQUEST_ATTRIBUTE_FOLDER, fx); |
| } else if (objRef instanceof Folder[]) { |
| Folder[] folders = (Folder[]) objRef; |
| MailContentHandlerDelegate.FolderXMLizer[] fxs = new MailContentHandlerDelegate.FolderXMLizer[folders.length]; |
| for (int i = 0; i < folders.length; i++) { |
| fxs[i] = new MailContentHandlerDelegate.FolderXMLizer(folders[i]); |
| fxs[i].enableLogging(logger); |
| } |
| // trust that array of XMLizable is handled |
| request.setAttribute(REQUEST_ATTRIBUTE_FOLDERS, fxs); |
| } else if (objRef instanceof Message) { |
| MailContentHandlerDelegate.MessageXMLizer mx = new MailContentHandlerDelegate.MessageXMLizer((Message) objRef); |
| mx.enableLogging(logger); |
| mx.setSimpleDateFormat(sdf); |
| request.setAttribute(REQUEST_ATTRIBUTE_MESSAGE, mx); |
| } else if (objRef instanceof Message[]) { |
| MailContentHandlerDelegate.MessageEnvelopeXMLizer mex = new MailContentHandlerDelegate.MessageEnvelopeXMLizer((Message[]) objRef); |
| mex.enableLogging(logger); |
| mex.setSimpleDateFormat(sdf); |
| request.setAttribute(REQUEST_ATTRIBUTE_MESSAGES, mex); |
| } |
| } |
| } |
| } |
| |
| |
| /** |
| * Retrieve javamail objects |
| * |
| * @param mailContext Description of the Parameter |
| * @return List of retrieved javamail objects |
| * @exception ProcessingException thrown iff retrieval fails |
| */ |
| protected List retrieveJavaMailObjects(MailContext mailContext) throws ProcessingException { |
| |
| List result; |
| try { |
| // do we have a MailCommandManager ? |
| MailCommandManager mam = new MailCommandManager(); |
| mam.enableLogging(getLogger()); |
| |
| // build the MailCommand(s) |
| MailCommandBuilder mab = new MailCommandBuilder(); |
| mab.enableLogging(getLogger()); |
| AbstractMailCommand ama = mab.buildAbstractMailCommand(mailContext); |
| |
| getLogger().debug("Executing " + String.valueOf(ama)); |
| |
| // execute the command(s) |
| result = mam.execute(ama); |
| |
| // return the javamail objects |
| return result; |
| } catch (Exception e) { |
| String message = "Cannot retrieve javamail objects"; |
| getLogger().error(message, e); |
| throw new ProcessingException(message, e); |
| } |
| } |
| } |