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.generation;
018:
019: import org.apache.avalon.framework.parameters.Parameters;
020:
021: import org.apache.cocoon.ProcessingException;
022: import org.apache.cocoon.environment.SourceResolver;
023: import org.apache.cocoon.xml.XMLUtils;
024:
025: import org.xml.sax.Attributes;
026: import org.xml.sax.SAXException;
027:
028: import javax.mail.AuthenticationFailedException;
029: import javax.mail.Folder;
030: import javax.mail.Message;
031: import javax.mail.Session;
032: import javax.mail.Store;
033: import java.io.IOException;
034: import java.util.Map;
035: import java.util.Properties;
036:
037: /**
038: * Generates an XML listing of messages from an IMAP mail server.
039: *
040: * <p>You <b>must</b> configure this generator with "host", "user", and "pass" parameters
041: * which specifies the mail server host, the user to login as, and the password to use,
042: * respectively. Beware that these passwords will be sent cleartext since the Generator
043: * does not use an SSL-enabled IMAP connection.</p>
044: *
045: * <p>Also beware that storing sensitive data, (such as mail usernames and passwords) can
046: * be very dangerous, so please be very careful in the method by which you send the user
047: * and password parameters to the generator.</p>
048: *
049: * Instructions: get the JavaMail API jar from http://java.sun.com/products/javamail/, and
050: * the JAF activation.jar from http://java.sun.com/beans/glasgow/jaf.html. Put mail.jar
051: * and activation.jar in xml-cocoon2/lib/local/, and recompile. These jars could actually be
052: * moved to lib/optional and added to jars.xml in the future.
053: *
054: * <br>TODO Refactor all of this to use the MailCommandManager, etc...
055: *
056: * @author <a href="mailto:tony@apache.org">Tony Collen</a>
057: * @version $Id: IMAPGenerator.java 433543 2006-08-22 06:22:54Z crossley $
058: */
059: public class IMAPGenerator extends AbstractGenerator {
060:
061: static final String URI = "http://apache.org/cocoon/imap/1.0/";
062: static final String PREFIX = "imap";
063:
064: private String host;
065: private String user;
066: private String pass;
067:
068: private Properties props = new Properties();
069: private Message message[];
070:
071: public void setup(SourceResolver resolver, Map objectModel,
072: String src, Parameters par) throws ProcessingException,
073: SAXException, IOException {
074:
075: // TODO: the default values should be something else...
076: this .host = par.getParameter("host", "none");
077: this .user = par.getParameter("user", "none");
078: this .pass = par.getParameter("pass", "none");
079:
080: if (this .host.equals("none") || this .user.equals("none")
081: || this .pass.equals("none")) {
082:
083: throw new ProcessingException(
084: "You must configure this generator with host, user, and pass parameters.");
085: }
086: }
087:
088: public void generate() throws SAXException, ProcessingException {
089:
090: try {
091: Session sess = Session.getDefaultInstance(this .props, null);
092: Store st = sess.getStore("imap");
093:
094: log("Connecting to IMAP server @ " + this .host);
095: st.connect(this .host, this .user, this .pass);
096:
097: log("Attempting to open default folder");
098: Folder f = st.getFolder("inbox");
099:
100: f.open(Folder.READ_WRITE);
101:
102: log("Downloading message list from folder");
103: this .message = f.getMessages();
104:
105: int i = 0;
106:
107: log("Starting XML generation");
108: this .contentHandler.startDocument();
109: this .contentHandler.startPrefixMapping(PREFIX, URI);
110:
111: start("imap", XMLUtils.EMPTY_ATTRIBUTES);
112: start("messages", XMLUtils.EMPTY_ATTRIBUTES);
113:
114: for (i = 0; i < this .message.length; i++) {
115: // Loop through the messages and output XML.
116: // TODO: actually use the attributes...
117:
118: start("msg", XMLUtils.EMPTY_ATTRIBUTES);
119:
120: start("subject", XMLUtils.EMPTY_ATTRIBUTES);
121: data(this .message[i].getSubject());
122: end("subject");
123:
124: start("from", XMLUtils.EMPTY_ATTRIBUTES);
125: data(this .message[i].getFrom()[0].toString());
126: end("from");
127:
128: start("sentDate", XMLUtils.EMPTY_ATTRIBUTES);
129: data(this .message[i].getSentDate().toString());
130: end("sentDate");
131:
132: start("num", XMLUtils.EMPTY_ATTRIBUTES);
133: data(Integer.toString(this .message[i]
134: .getMessageNumber()));
135: end("num");
136:
137: end("msg");
138: }
139:
140: end("messages");
141: end("imap");
142:
143: this .contentHandler.endPrefixMapping(PREFIX);
144: this .contentHandler.endDocument();
145:
146: log("Finished generating XML");
147:
148: } catch (AuthenticationFailedException afe) {
149: throw new ProcessingException(
150: "Failed to authenticate with the IMAP server.");
151: } catch (Exception e) {
152: // TODO: be more specific when catching this exception...
153: throw new ProcessingException(e.toString());
154: }
155: }
156:
157: /**
158: * Recycle the generator by removing references
159: */
160: public void recycle() {
161: this .host = null;
162: this .user = null;
163: this .pass = null;
164:
165: this .props = null;
166: this .message = null;
167:
168: super .recycle();
169: }
170:
171: private void start(String name, Attributes attr)
172: throws SAXException {
173: super .contentHandler.startElement(URI, name, PREFIX + ":"
174: + name, attr);
175: }
176:
177: private void end(String name) throws SAXException {
178: super .contentHandler.endElement(URI, name, PREFIX + ":" + name);
179: }
180:
181: private void data(String data) throws SAXException {
182: super .contentHandler.characters(data.toCharArray(), 0, data
183: .length());
184: }
185:
186: private void log(String msg) {
187: getLogger().debug(msg);
188: }
189: }
|