X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=ext%2Fjavax.mail.mbox%2Fsrc%2Fcom%2Fsun%2Fmail%2Fmbox%2FMboxMessage.java;fp=ext%2Fjavax.mail.mbox%2Fsrc%2Fcom%2Fsun%2Fmail%2Fmbox%2FMboxMessage.java;h=0000000000000000000000000000000000000000;hb=1bd71c9dd096b7caaec556f6a0e3b39e3f4eb4c0;hp=db57a2652d98a353c147de23c9e05dbbb7423578;hpb=d5763e48c2b09a5298d33a74a73683cbdf4a6931;p=gpl%2Fargeo-slc.git diff --git a/ext/javax.mail.mbox/src/com/sun/mail/mbox/MboxMessage.java b/ext/javax.mail.mbox/src/com/sun/mail/mbox/MboxMessage.java deleted file mode 100644 index db57a2652..000000000 --- a/ext/javax.mail.mbox/src/com/sun/mail/mbox/MboxMessage.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0, which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the - * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, - * version 2 with the GNU Classpath Exception, which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - */ - -package com.sun.mail.mbox; - -import java.io.*; -import java.util.StringTokenizer; -import java.util.Date; -import java.text.SimpleDateFormat; -import javax.activation.*; -import javax.mail.*; -import javax.mail.internet.*; -import javax.mail.event.MessageChangedEvent; -import com.sun.mail.util.LineInputStream; - -/** - * This class represents an RFC822 style email message that resides in a file. - * - * @author Bill Shannon - */ - -public class MboxMessage extends MimeMessage { - - boolean writable = false; - // original msg flags, used by MboxFolder to detect modification - Flags origFlags; - /* - * A UNIX From line looks like: - * From address Day Mon DD HH:MM:SS YYYY - */ - String unix_from; - InternetAddress unix_from_user; - Date rcvDate; - int lineCount = -1; - private static OutputStream nullOutputStream = new OutputStream() { - public void write(int b) { } - public void write(byte[] b, int off, int len) { } - }; - - /** - * Construct an MboxMessage from the InputStream. - */ - public MboxMessage(Session session, InputStream is) - throws MessagingException, IOException { - super(session); - BufferedInputStream bis; - if (is instanceof BufferedInputStream) - bis = (BufferedInputStream)is; - else - bis = new BufferedInputStream(is); - LineInputStream dis = new LineInputStream(bis); - bis.mark(1024); - String line = dis.readLine(); - if (line != null && line.startsWith("From ")) - this.unix_from = line; - else - bis.reset(); - parse(bis); - saved = true; - } - - /** - * Construct an MboxMessage using the given InternetHeaders object - * and content from an InputStream. - */ - public MboxMessage(MboxFolder folder, InternetHeaders hdrs, InputStream is, - int msgno, String unix_from, boolean writable) - throws MessagingException { - super(folder, hdrs, null, msgno); - setFlagsFromHeaders(); - origFlags = getFlags(); - this.unix_from = unix_from; - this.writable = writable; - this.contentStream = is; - } - - /** - * Returns the "From" attribute. The "From" attribute contains - * the identity of the person(s) who wished this message to - * be sent.

- * - * If our superclass doesn't have a value, we return the address - * from the UNIX From line. - * - * @return array of Address objects - * @exception MessagingException - */ - public Address[] getFrom() throws MessagingException { - Address[] ret = super.getFrom(); - if (ret == null) { - InternetAddress ia = getUnixFrom(); - if (ia != null) - ret = new InternetAddress[] { ia }; - } - return ret; - } - - /** - * Returns the address from the UNIX "From" line. - * - * @return UNIX From address - * @exception MessagingException - */ - public synchronized InternetAddress getUnixFrom() - throws MessagingException { - if (unix_from_user == null && unix_from != null) { - int i; - // find the space after the address, before the date - i = unix_from.indexOf(' ', 5); - if (i > 5) { - try { - unix_from_user = - new InternetAddress(unix_from.substring(5, i)); - } catch (AddressException e) { - // ignore it - } - } - } - return unix_from_user != null ? - (InternetAddress)unix_from_user.clone() : null; - } - - private String getUnixFromLine() { - if (unix_from != null) - return unix_from; - String from = "unknown"; - try { - Address[] froma = getFrom(); - if (froma != null && froma.length > 0 && - froma[0] instanceof InternetAddress) - from = ((InternetAddress)froma[0]).getAddress(); - } catch (MessagingException ex) { } - Date d = null; - try { - d = getSentDate(); - } catch (MessagingException ex) { - // ignore - } - if (d == null) - d = new Date(); - // From shannon Mon Jun 10 12:06:52 2002 - SimpleDateFormat fmt = new SimpleDateFormat("EEE LLL dd HH:mm:ss yyyy"); - return "From " + from + " " + fmt.format(d); - } - - /** - * Get the date this message was received, from the UNIX From line. - * - * @return the date this message was received - * @exception MessagingException - */ - @SuppressWarnings("deprecation") // for Date constructor - public Date getReceivedDate() throws MessagingException { - if (rcvDate == null && unix_from != null) { - int i; - // find the space after the address, before the date - i = unix_from.indexOf(' ', 5); - if (i > 5) { - try { - rcvDate = new Date(unix_from.substring(i)); - } catch (IllegalArgumentException iae) { - // ignore it - } - } - } - return rcvDate == null ? null : new Date(rcvDate.getTime()); - } - - /** - * Return the number of lines for the content of this message. - * Return -1 if this number cannot be determined.

- * - * Note that this number may not be an exact measure of the - * content length and may or may not account for any transfer - * encoding of the content.

- * - * This implementation returns -1. - * - * @return number of lines in the content. - * @exception MessagingException - */ - public int getLineCount() throws MessagingException { - if (lineCount < 0 && isMimeType("text/plain")) { - LineCounter lc = null; - // writeTo will set the SEEN flag, remember the original state - boolean seen = isSet(Flags.Flag.SEEN); - try { - lc = new LineCounter(nullOutputStream); - getDataHandler().writeTo(lc); - lineCount = lc.getLineCount(); - } catch (IOException ex) { - // ignore it, can't happen - } finally { - try { - if (lc != null) - lc.close(); - } catch (IOException ex) { - // can't happen - } - } - if (!seen) - setFlag(Flags.Flag.SEEN, false); - } - return lineCount; - } - - /** - * Set the specified flags on this message to the specified value. - * - * @param flags the flags to be set - * @param set the value to be set - */ - public void setFlags(Flags newFlags, boolean set) - throws MessagingException { - Flags oldFlags = (Flags)flags.clone(); - super.setFlags(newFlags, set); - if (!flags.equals(oldFlags)) { - setHeadersFromFlags(this); - if (folder != null) - ((MboxFolder)folder).notifyMessageChangedListeners( - MessageChangedEvent.FLAGS_CHANGED, this); - } - } - - /** - * Return the content type, mapping from SunV3 types to MIME types - * as necessary. - */ - public String getContentType() throws MessagingException { - String ct = super.getContentType(); - if (ct.indexOf('/') < 0) - ct = SunV3BodyPart.MimeV3Map.toMime(ct); - return ct; - } - - /** - * Produce the raw bytes of the content. This method is used during - * parsing, to create a DataHandler object for the content. Subclasses - * that can provide a separate input stream for just the message - * content might want to override this method.

- * - * This implementation just returns a ByteArrayInputStream constructed - * out of the content byte array. - * - * @see #content - */ - protected InputStream getContentStream() throws MessagingException { - if (folder != null) - ((MboxFolder)folder).checkOpen(); - if (isExpunged()) - throw new MessageRemovedException("mbox message expunged"); - if (!isSet(Flags.Flag.SEEN)) - setFlag(Flags.Flag.SEEN, true); - return super.getContentStream(); - } - - /** - * Return a DataHandler for this Message's content. - * If this is a SunV3 multipart message, handle it specially. - * - * @exception MessagingException - */ - public synchronized DataHandler getDataHandler() - throws MessagingException { - if (dh == null) { - // XXX - Following is a kludge to avoid having to register - // the "multipart/x-sun-attachment" data type with the JAF. - String ct = getContentType(); - if (ct.equalsIgnoreCase("multipart/x-sun-attachment")) - dh = new DataHandler( - new SunV3Multipart(new MimePartDataSource(this)), ct); - else - return super.getDataHandler(); // will set "dh" - } - return dh; - } - - // here only to allow package private access from MboxFolder - protected void setMessageNumber(int msgno) { - super.setMessageNumber(msgno); - } - - // here to synchronize access to expunged field - public synchronized boolean isExpunged() { - return super.isExpunged(); - } - - // here to synchronize and to allow access from MboxFolder - protected synchronized void setExpunged(boolean expunged) { - super.setExpunged(expunged); - } - - // XXX - We assume that only body parts that are part of a SunV3 - // multipart will use the SunV3 headers (X-Sun-Content-Length, - // X-Sun-Content-Lines, X-Sun-Data-Type, X-Sun-Encoding-Info, - // X-Sun-Data-Description, X-Sun-Data-Name) so we don't handle - // them here. - - /** - * Set the flags for this message based on the Status, - * X-Status, and X-Dt-Delete-Time headers. - * - * SIMS 2.0: - * "X-Status: DFAT", deleted, flagged, answered, draft. - * Unset flags represented as "$". - * User flags not supported. - * - * University of Washington IMAP server: - * "X-Status: DFAT", deleted, flagged, answered, draft. - * Unset flags not present. - * "X-Keywords: userflag1 userflag2" - */ - private synchronized void setFlagsFromHeaders() { - flags = new Flags(Flags.Flag.RECENT); - try { - String s = getHeader("Status", null); - if (s != null) { - if (s.indexOf('R') >= 0) - flags.add(Flags.Flag.SEEN); - if (s.indexOf('O') >= 0) - flags.remove(Flags.Flag.RECENT); - } - s = getHeader("X-Dt-Delete-Time", null); // set by dtmail - if (s != null) - flags.add(Flags.Flag.DELETED); - s = getHeader("X-Status", null); // set by IMAP server - if (s != null) { - if (s.indexOf('D') >= 0) - flags.add(Flags.Flag.DELETED); - if (s.indexOf('F') >= 0) - flags.add(Flags.Flag.FLAGGED); - if (s.indexOf('A') >= 0) - flags.add(Flags.Flag.ANSWERED); - if (s.indexOf('T') >= 0) - flags.add(Flags.Flag.DRAFT); - } - s = getHeader("X-Keywords", null); // set by IMAP server - if (s != null) { - StringTokenizer st = new StringTokenizer(s); - while (st.hasMoreTokens()) - flags.add(st.nextToken()); - } - } catch (MessagingException e) { - // ignore it - } - } - - /** - * Set the various header fields that represent the message flags. - */ - static void setHeadersFromFlags(MimeMessage msg) { - try { - Flags flags = msg.getFlags(); - StringBuilder status = new StringBuilder(); - if (flags.contains(Flags.Flag.SEEN)) - status.append('R'); - if (!flags.contains(Flags.Flag.RECENT)) - status.append('O'); - if (status.length() > 0) - msg.setHeader("Status", status.toString()); - else - msg.removeHeader("Status"); - - boolean sims = false; - String s = msg.getHeader("X-Status", null); - // is it a SIMS 2.0 format X-Status header? - sims = s != null && s.length() == 4 && s.indexOf('$') >= 0; - status.setLength(0); - if (flags.contains(Flags.Flag.DELETED)) - status.append('D'); - else if (sims) - status.append('$'); - if (flags.contains(Flags.Flag.FLAGGED)) - status.append('F'); - else if (sims) - status.append('$'); - if (flags.contains(Flags.Flag.ANSWERED)) - status.append('A'); - else if (sims) - status.append('$'); - if (flags.contains(Flags.Flag.DRAFT)) - status.append('T'); - else if (sims) - status.append('$'); - if (status.length() > 0) - msg.setHeader("X-Status", status.toString()); - else - msg.removeHeader("X-Status"); - - String[] userFlags = flags.getUserFlags(); - if (userFlags.length > 0) { - status.setLength(0); - for (int i = 0; i < userFlags.length; i++) - status.append(userFlags[i]).append(' '); - status.setLength(status.length() - 1); // smash trailing space - msg.setHeader("X-Keywords", status.toString()); - } - if (flags.contains(Flags.Flag.DELETED)) { - s = msg.getHeader("X-Dt-Delete-Time", null); - if (s == null) - // XXX - should be time - msg.setHeader("X-Dt-Delete-Time", "1"); - } - } catch (MessagingException e) { - // ignore it - } - } - - protected void updateHeaders() throws MessagingException { - super.updateHeaders(); - setHeadersFromFlags(this); - } - - /** - * Save any changes made to this message. - */ - public void saveChanges() throws MessagingException { - if (folder != null) - ((MboxFolder)folder).checkOpen(); - if (isExpunged()) - throw new MessageRemovedException("mbox message expunged"); - if (!writable) - throw new MessagingException("Message is read-only"); - - super.saveChanges(); - - try { - /* - * Count the size of the body, in order to set the Content-Length - * header. (Should we only do this to update an existing - * Content-Length header?) - * XXX - We could cache the content bytes here, for use later - * in writeTo. - */ - ContentLengthCounter cos = new ContentLengthCounter(); - OutputStream os = new NewlineOutputStream(cos); - super.writeTo(os); - os.flush(); - setHeader("Content-Length", String.valueOf(cos.getSize())); - // setContentSize((int)cos.getSize()); - } catch (MessagingException e) { - throw e; - } catch (Exception e) { - throw new MessagingException("unexpected exception " + e); - } - } - - /** - * Expose modified flag to MboxFolder. - */ - boolean isModified() { - return modified; - } - - /** - * Put out a byte stream suitable for saving to a file. - * XXX - ultimately implement "ignore headers" here? - */ - public void writeToFile(OutputStream os) throws IOException { - try { - if (getHeader("Content-Length") == null) { - /* - * Count the size of the body, in order to set the - * Content-Length header. - */ - ContentLengthCounter cos = new ContentLengthCounter(); - OutputStream oos = new NewlineOutputStream(cos); - super.writeTo(oos, null); - oos.flush(); - setHeader("Content-Length", String.valueOf(cos.getSize())); - // setContentSize((int)cos.getSize()); - } - - os = new NewlineOutputStream(os, true); - PrintStream pos = new PrintStream(os, false, "iso-8859-1"); - - pos.println(getUnixFromLine()); - super.writeTo(pos, null); - pos.flush(); - } catch (MessagingException e) { - throw new IOException("unexpected exception " + e); - } - } - - public void writeTo(OutputStream os, String[] ignoreList) - throws IOException, MessagingException { - // set the SEEN flag now, which will normally be set by - // getContentStream, so it will show up in our headers - if (!isSet(Flags.Flag.SEEN)) - setFlag(Flags.Flag.SEEN, true); - super.writeTo(os, ignoreList); - } - - /** - * Interpose on superclass method to make sure folder is still open - * and message hasn't been expunged. - */ - public String[] getHeader(String name) - throws MessagingException { - if (folder != null) - ((MboxFolder)folder).checkOpen(); - if (isExpunged()) - throw new MessageRemovedException("mbox message expunged"); - return super.getHeader(name); - } - - /** - * Interpose on superclass method to make sure folder is still open - * and message hasn't been expunged. - */ - public String getHeader(String name, String delimiter) - throws MessagingException { - if (folder != null) - ((MboxFolder)folder).checkOpen(); - if (isExpunged()) - throw new MessageRemovedException("mbox message expunged"); - return super.getHeader(name, delimiter); - } -}