MboxMessage.java
上传用户:huihesys
上传日期:2007-01-04
资源大小:3877k
文件大小:11k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2.  * MboxMessage.java
  3.  * Copyright (C) 1999 dog <dog@dog.net.uk>
  4.  * 
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  * 
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  * 
  19.  * You may retrieve the latest version of this library from
  20.  * http://www.dog.net.uk/knife/
  21.  */
  22. package dog.mail.mbox;
  23. import java.io.*;
  24. import java.util.*;
  25. import javax.activation.DataHandler;
  26. import javax.mail.*;
  27. import javax.mail.internet.*;
  28. /**
  29.  * The message class implementing the Mbox mail protocol.
  30.  *
  31.  * @author dog@dog.net.uk
  32.  * @version 1.2.1
  33.  */
  34. public class MboxMessage extends MimeMessage {
  35. /**
  36.  * The offset of the start of this message from the beginning of the file.
  37.  */
  38. protected long startOffset = -1;
  39. /**
  40.  * The offset of the start of this message's content from the beginning of the file.
  41.  */
  42. protected long contentOffset = -1;
  43. /**
  44.  * Creates a Mbox message.
  45.  * This is called by the MboxStore.
  46.  */
  47. protected MboxMessage(MboxFolder folder, InputStream in, int msgnum) throws MessagingException {
  48. super(folder, msgnum);
  49. if (!(in instanceof ByteArrayInputStream) && !(in instanceof BufferedInputStream))
  50. in = new BufferedInputStream(in);
  51. headers = new InternetHeaders(in);
  52. try {
  53. int fetchsize = MboxStore.fetchsize;
  54. byte bytes[];
  55. if (in instanceof ByteArrayInputStream) {
  56. fetchsize = in.available();
  57. bytes = new byte[fetchsize];
  58. int len = in.read(bytes, 0, fetchsize);
  59. } else {
  60. ByteArrayOutputStream out = new ByteArrayOutputStream();
  61. bytes = new byte[fetchsize];
  62. int len;
  63. while ((len = in.read(bytes, 0, fetchsize))!=-1)
  64. out.write(bytes, 0, len);
  65. bytes = out.toByteArray();
  66. }
  67. content = bytes;
  68. } catch(IOException e) {
  69. throw new MessagingException("I/O error", e);
  70. }
  71. }
  72. /**
  73.  * Creates a Mbox message.
  74.  * This is called by the MboxStore.
  75.  */
  76. protected MboxMessage(MboxFolder folder, RandomAccessFile file, int msgnum) throws MessagingException {
  77. super(folder, msgnum);
  78. // just create the headers for now
  79. headers = new InternetHeaders();
  80. try {
  81. startOffset = file.getFilePointer();
  82. String line;
  83. while ((line=file.readLine())!=null) {
  84. if (line.length()==0)
  85. break;
  86. headers.addHeaderLine(line);
  87. }
  88. contentOffset = file.getFilePointer();
  89. } catch(IOException e) {
  90. throw new MessagingException("I/O error", e);
  91. }
  92. }
  93. /**
  94.  * Creates a Mbox message.
  95.  * This is called by the MboxFolder when appending.
  96.  * It creates a copy of the specified message for the new folder.
  97.  */
  98. protected MboxMessage(MboxFolder folder, MimeMessage message, int msgnum) throws MessagingException {
  99. super(folder, msgnum);
  100. headers = new InternetHeaders();
  101. for (Enumeration enum = message.getAllHeaderLines(); enum.hasMoreElements(); )
  102. headers.addHeaderLine((String)enum.nextElement());
  103. try {
  104. InputStream in = message.getInputStream();
  105. ByteArrayOutputStream out = new ByteArrayOutputStream();
  106. byte[] bytes = new byte[1024];
  107. for (int len = in.read(bytes); len>-1; len = in.read(bytes))
  108. out.write(bytes, 0, len);
  109. content = out.toByteArray();
  110. } catch (IOException e) {
  111. throw new MessagingException("I/O error", e);
  112. }
  113. }
  114. /**
  115.  * Returns the content of this message as a Java object.
  116.  */
  117. public Object getContent() throws MessagingException, IOException {
  118. if (content==null)
  119. retrieveContent();
  120. return super.getContent();
  121. }
  122. /**
  123.  * Returns the content of this message as a byte stream.
  124.  */
  125. public InputStream getContentStream() throws MessagingException {
  126. if (content==null)
  127. try {
  128. retrieveContent();
  129. } catch (IOException e) {
  130. throw new MessagingException("I/O error", e);
  131. }
  132. return super.getContentStream();
  133. }
  134. /**
  135.  * Returns the content of this message as a decoded stream.
  136.  */
  137. public InputStream getInputStream() throws MessagingException, IOException {
  138. if (content==null)
  139. retrieveContent();
  140. return super.getInputStream();
  141. }
  142. /**
  143.  * Returns the number of lines in the content of this message.
  144.  */
  145. public int getLineCount() throws MessagingException {
  146. if (content==null)
  147. try {
  148. retrieveContent();
  149. } catch (IOException e) {
  150. throw new MessagingException("I/O error", e);
  151. }
  152. return super.getLineCount();
  153. }
  154. protected void retrieveContent() throws IOException {
  155. if (contentOffset<0) return;
  156. int fetchsize = MboxStore.fetchsize;
  157. byte bytes[];
  158. RandomAccessFile file = 
  159. new RandomAccessFile(((MboxFolder)folder).file, "r");
  160. file.seek(contentOffset);
  161. String line;
  162. ByteArrayOutputStream out = new ByteArrayOutputStream();
  163. boolean length0 = false;
  164. for (line = file.readLine(); line!=null; line = file.readLine()) {
  165. if (line.startsWith("From ") && length0) { // end of message
  166. content = out.toByteArray();
  167. break;
  168. } else {
  169. if (line.endsWith("r"))
  170. line = line.substring(0, line.length()-1);
  171. length0 = (line.length()==0 || line.equals("r"));
  172. out.write(line.getBytes());
  173. out.write('n');
  174. }
  175. }
  176. if (content==null) // end of file
  177. content = out.toByteArray();
  178. }
  179. /**
  180.  * Returns the from address.
  181.  */
  182. public Address[] getFrom() throws MessagingException {
  183. Address[] a = getAddressHeader("From");
  184. if (a==null) a = getAddressHeader("Sender");
  185. return a;
  186. }
  187. /**
  188.  * Returns the recipients' addresses.
  189.  */
  190. public Address[] getRecipients(RecipientType type) throws MessagingException {
  191. if (type==RecipientType.NEWSGROUPS) {
  192. String key = getHeader("Newsgroups", ",");
  193. if (key==null) return null;
  194. return NewsAddress.parse(key);
  195. } else {
  196. return getAddressHeader(getHeaderKey(type));
  197. }
  198. }
  199. /**
  200.  * Returns the reply-to address.
  201.  */
  202. public Address[] getReplyTo() throws MessagingException {
  203. Address[] a = getAddressHeader("Reply-To");
  204. if (a==null) a = getFrom();
  205. return a;
  206. }
  207. /**
  208.  * Returns an array of addresses for the specified header key.
  209.  */
  210. protected Address[] getAddressHeader(String key) throws MessagingException {
  211. String header = getHeader(key, ",");
  212. if (header==null) return null;
  213. try {
  214. return InternetAddress.parse(header);
  215. } catch (AddressException e) {
  216.             String message = e.getMessage();
  217. if (message!=null && message.indexOf("@domain")>-1)
  218. try {
  219. return parseAddress(header, "localhost");
  220. } catch (AddressException e2) {
  221. throw new MessagingException("Invalid address: "+header, e);
  222. }
  223. throw e;
  224. }
  225. }
  226. /**
  227.  * Makes a pass at parsing internet addresses.
  228.  */
  229. protected Address[] parseAddress(String in, String defhost) throws AddressException {
  230.         Vector v = new Vector();
  231. for (StringTokenizer st = new StringTokenizer(in, ","); st.hasMoreTokens(); ) {
  232.             String s = st.nextToken().trim();
  233. try {
  234. v.addElement(new InternetAddress(s));
  235. } catch (AddressException e) {
  236. int index = s.indexOf('>');
  237. if (index>-1) { // name <address>
  238. StringBuffer buffer = new StringBuffer();
  239. buffer.append(s.substring(0, index));
  240. buffer.append('@');
  241. buffer.append(defhost);
  242. buffer.append(s.substring(index));
  243. v.addElement(new InternetAddress(buffer.toString()));
  244. } else {
  245. index = s.indexOf(" (");
  246. if (index>-1) { // address (name)
  247. StringBuffer buffer = new StringBuffer();
  248. buffer.append(s.substring(0, index));
  249. buffer.append('@');
  250. buffer.append(defhost);
  251. buffer.append(s.substring(index));
  252. v.addElement(new InternetAddress(buffer.toString()));
  253. } else // address
  254. v.addElement(new InternetAddress(s+"@"+defhost));
  255. }
  256. }
  257. }
  258.         Address[] a = new Address[v.size()]; v.copyInto(a);
  259. return a;
  260. }
  261. /**
  262.  * Returns the header key for the specified RecipientType.
  263.  */
  264. protected String getHeaderKey(RecipientType type) throws MessagingException {
  265. if (type==RecipientType.TO)
  266. return "To";
  267. if (type==RecipientType.CC)
  268. return "Cc";
  269. if (type==RecipientType.BCC)
  270. return "Bcc";
  271. if (type==RecipientType.NEWSGROUPS)
  272. return "Newsgroups";
  273. throw new MessagingException("Invalid recipient type: "+type);
  274. }
  275. // -- Need to override these since we are read-only --
  276. /**
  277.  * Mbox messages are read-only.
  278.  */
  279. public void setFrom(Address address) throws MessagingException {
  280. throw new IllegalWriteException("MboxMessage is read-only");
  281. }
  282. /**
  283.  * Mbox messages are read-only.
  284.  */
  285. public void addFrom(Address aaddress[]) throws MessagingException {
  286. throw new IllegalWriteException("MboxMessage is read-only");
  287. }
  288. /**
  289.  * Mbox messages are read-only.
  290.  */
  291. public void setRecipients(javax.mail.Message.RecipientType recipienttype, Address aaddress[]) throws MessagingException {
  292. throw new IllegalWriteException("MboxMessage is read-only");
  293. }
  294. /**
  295.  * Mbox messages are read-only.
  296.  */
  297. public void addRecipients(javax.mail.Message.RecipientType recipienttype, Address aaddress[]) throws MessagingException {
  298. throw new IllegalWriteException("MboxMessage is read-only");
  299. }
  300. /**
  301.  * Mbox messages are read-only.
  302.  */
  303. public void setReplyTo(Address aaddress[]) throws MessagingException {
  304. throw new IllegalWriteException("MboxMessage is read-only");
  305. }
  306. /**
  307.  * Mbox messages are read-only.
  308.  */
  309. public void setSubject(String s, String s1) throws MessagingException {
  310. throw new IllegalWriteException("MboxMessage is read-only");
  311. }
  312. /**
  313.  * Mbox messages are read-only.
  314.  */
  315. public void setSentDate(Date date) throws MessagingException {
  316. throw new IllegalWriteException("MboxMessage is read-only");
  317. }
  318. /**
  319.  * Mbox messages are read-only.
  320.  */
  321. public void setDisposition(String s) throws MessagingException {
  322. throw new IllegalWriteException("MboxMessage is read-only");
  323. }
  324. /**
  325.  * Mbox messages are read-only.
  326.  */
  327. public void setContentID(String s) throws MessagingException {
  328. throw new IllegalWriteException("MboxMessage is read-only");
  329. }
  330. /**
  331.  * Mbox messages are read-only.
  332.  */
  333. public void setContentMD5(String s) throws MessagingException {
  334. throw new IllegalWriteException("MboxMessage is read-only");
  335. }
  336. /**
  337.  * Mbox messages are read-only.
  338.  */
  339. public void setDescription(String s, String s1) throws MessagingException {
  340. throw new IllegalWriteException("MboxMessage is read-only");
  341. }
  342. /**
  343.  * Mbox messages are read-only.
  344.  */
  345. public void setDataHandler(DataHandler datahandler) throws MessagingException {
  346. throw new IllegalWriteException("MboxMessage is read-only");
  347. }
  348. // -- Utility methods --
  349. public boolean equals(Object other) {
  350. if (other instanceof MimeMessage) {
  351. MimeMessage message = (MimeMessage)other;
  352. return (message.getFolder()==getFolder() && message.getMessageNumber()==getMessageNumber());
  353. }
  354. return false;
  355. }
  356. }