blob: c8183ec0458de3d9548bc1fe8578b69f4b8e1393 [file] [log] [blame]
/*
* 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.geronimo.javamail.store.pop3.message;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.IllegalWriteException;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.event.MessageChangedEvent;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeMessage;
import org.apache.geronimo.javamail.store.pop3.POP3CommandFactory;
import org.apache.geronimo.javamail.store.pop3.POP3Connection;
import org.apache.geronimo.javamail.store.pop3.POP3Folder;
import org.apache.geronimo.javamail.store.pop3.POP3Response;
import org.apache.geronimo.javamail.store.pop3.response.POP3ListResponse;
import org.apache.geronimo.javamail.store.pop3.response.POP3ResponseFactory;
/**
* POP3 implementation of javax.mail.internet.MimeMessage
*
* Only the most basic information is given and Message objects created here is
* a light-weight reference to the actual Message As per the JavaMail spec items
* from the actual message will get filled up on demand
*
* If some other items are obtained from the server as a result of one call,
* then the other details are also processed and filled in. For ex if RETR is
* called then header information will also be processed in addition to the
* content
*
* @version $Rev$ $Date$
*/
public class POP3Message extends MimeMessage {
private POP3Connection pop3Con;
private int msgSize = -1;
private int headerSize = -1;
// We can't use header bcos it's already initialize to
// to an empty InternetHeader
private InputStream rawHeaders;
// used to force loading of headers again
private boolean loadHeaders = true;
// to get accessed to the debug setting and log
private Session session;
protected POP3Message(Folder folder, int msgnum, Session session, POP3Connection pop3Con) {
super(folder, msgnum);
this.pop3Con = pop3Con;
this.session = session;
}
/**
* @see javax.mail.internet.MimeMessage#getContentStream()
*/
protected InputStream getContentStream() throws MessagingException {
POP3Response msgResponse = null;
try {
msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_RETR(msgnum));
} catch (Exception e) {
e.printStackTrace();
}
loadHeaders = true;
loadHeaders(msgResponse.getData());
loadContent(msgResponse.getData());
return contentStream;
}
public void setFlags(Flags newFlags, boolean set) throws MessagingException {
Flags oldFlags = (Flags) flags.clone();
super.setFlags(newFlags, set);
if (!flags.equals(oldFlags)) {
((POP3Folder) folder).notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, this);
}
}
protected void loadHeaders(InputStream in) throws MessagingException {
if (loadHeaders || rawHeaders == null) {
rawHeaders = in;
headers = new InternetHeaders(rawHeaders);
loadHeaders = false;
}
}
protected void loadContent(InputStream stream) throws MessagingException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
int byteRead = stream.read();
int lastByte = -1;
for (; byteRead > 0;) {
if (byteRead == ' ' && lastByte == '\n') {
break;
}
lastByte = byteRead;
byteRead = stream.read();
}
for (; stream.available() > 0;) {
out.write(stream.read());
}
contentStream = new ByteArrayInputStream(out.toByteArray());
msgSize = contentStream.available();
} catch (IOException e) {
throw new MessagingException("Error loading content info", e);
}
}
public int getSize() throws MessagingException {
if (msgSize >= 0) {
return msgSize;
}
try {
if (msgSize < 0) {
if (rawHeaders == null) {
loadHeaders();
}
POP3ListResponse res = (POP3ListResponse) POP3ResponseFactory.getListResponse(pop3Con
.sendCommand(POP3CommandFactory.getCOMMAND_LIST(msgnum)));
msgSize = res.getSize() - headerSize;
}
return msgSize;
} catch (MessagingException ex) {
throw new MessagingException("error getting size", ex);
}
}
/**
* notice that we pass zero as the no of lines from the message,as it
* doesn't serv any purpose to get only a certain number of lines.
*
* However this maybe important if a mail client only shows 3 or 4 lines of
* the message in the list and then when the user clicks they would load the
* message on demand.
*
*/
protected void loadHeaders() throws MessagingException {
POP3Response msgResponse = null;
try {
msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_TOP(msgnum, 0));
} catch (Exception e) {
e.printStackTrace();
}
loadHeaders(msgResponse.getData());
}
/***************************************************************************
* Following is a set of methods that deal with headers I have tried to use
* the bare minimum
*
* Used sun's POP3 impl & JavaMail API as a guide in decided which methods
* are important.
**************************************************************************/
public String[] getHeader(String name) throws MessagingException {
if (rawHeaders == null)
loadHeaders();
return headers.getHeader(name);
}
public String getHeader(String name, String delimiter) throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getHeader(name, delimiter);
}
public Enumeration getAllHeaders() throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getAllHeaders();
}
public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getMatchingHeaders(names);
}
public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getNonMatchingHeaders(names);
}
public Enumeration getAllHeaderLines() throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getAllHeaderLines();
}
public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getMatchingHeaderLines(names);
}
public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
if (headers == null)
loadHeaders();
return headers.getNonMatchingHeaderLines(names);
}
// the following are overrides for header modification methods. These
// messages are read only,
// so the headers cannot be modified.
public void addHeader(String name, String value) throws MessagingException {
throw new IllegalWriteException("POP3 messages are read-only");
}
public void setHeader(String name, String value) throws MessagingException {
throw new IllegalWriteException("POP3 messages are read-only");
}
public void removeHeader(String name) throws MessagingException {
throw new IllegalWriteException("POP3 messages are read-only");
}
public void addHeaderLine(String line) throws MessagingException {
throw new IllegalWriteException("POP3 messages are read-only");
}
/**
* We cannot modify these messages
*/
public void saveChanges() throws MessagingException {
throw new IllegalWriteException("POP3 messages are read-only");
}
}