KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > vfs > MailtoPath


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.vfs;
30
31 import com.caucho.util.CharBuffer;
32 import com.caucho.util.StringCharCursor;
33
34 import java.io.IOException JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Map JavaDoc;
38
39 /**
40  * The mailto: scheme sends mail using the SMTP protocol.
41  * Attributes set headers. Headers can be set as long as no data
42  * has been flushed.
43  *
44  * <code><pre>
45  * WriteStream os = Vfs.openWrite("mailto:nobody@foo.com");
46  * os.setAttribute("subject", "Reminder message");
47  *
48  * os.println("This is just a simple reminder.");
49  * os.close();
50  * </pre></code>
51  *
52  * <p>The attributes set SMTP headers:
53  * <ul>
54  * <li>subject - message subject
55  * <li>to - recipient
56  * <li>cc - copy list
57  * <li>bcc - blind copy list
58  * <li><em>X-foo</em> - user-specified header
59  * </ul>
60  *
61  * <p>You can also set attributes in the URL as query parameters.
62  *
63  * <code><pre>
64  * Vfs.openWrite("mailto:nobody@foo.com?subject=dinner");
65  * </pre></code>
66  */

67 public class MailtoPath extends Path {
68   protected String JavaDoc url;
69   private ArrayList JavaDoc<Recipient> _to;
70   private ArrayList JavaDoc cc;
71   private ArrayList JavaDoc bcc;
72   private HashMap JavaDoc<String JavaDoc,Object JavaDoc> _attributes;
73
74   MailtoPath(MailtoPath parent, String JavaDoc path,
75              ArrayList JavaDoc<Recipient> to,
76              HashMap JavaDoc<String JavaDoc,Object JavaDoc> attr)
77   {
78     super(parent);
79
80     this.url = path;
81     _to = to;
82     _attributes = attr;
83   }
84
85   /**
86    * Parse the scheme for the recipient and the attributes.
87    */

88   protected Path schemeWalk(String JavaDoc userPath, Map JavaDoc<String JavaDoc,Object JavaDoc> attributes,
89                             String JavaDoc uri, int offset)
90   {
91     StringCharCursor cursor = new StringCharCursor(uri, offset);
92     
93     ArrayList JavaDoc<Recipient> to = parseAddressList(cursor);
94     HashMap JavaDoc<String JavaDoc,Object JavaDoc> attr = new HashMap JavaDoc<String JavaDoc,Object JavaDoc>();
95
96     CharBuffer buf = new CharBuffer();
97     if (cursor.current() == '?') {
98       char ch = cursor.next();
99       while (isUserChar(ch)) {
100     buf.clear();
101     for (; isUserChar(ch); ch = cursor.next())
102       buf.append(ch);
103     String JavaDoc key = buf.toString();
104
105     if (ch != '=')
106       throw new RuntimeException JavaDoc("broken attribute at: " + ch);
107     buf.clear();
108     for (ch = cursor.next();
109          ch != cursor.DONE && ch != '&';
110          ch = cursor.next())
111       buf.append(ch);
112
113     attr.put(key, buf.toString());
114
115     while (ch == '&' || ch == ' ' || ch == '\t')
116       ch = cursor.next();
117       }
118     }
119
120     return new MailtoPath(this, userPath, to, attr);
121   }
122
123   /**
124    * Parses the address list from the URL.
125    *
126    * @param cursor parse cursor for the URL
127    * @return a list of recipient addresses
128    */

129   static ArrayList JavaDoc<Recipient> parseAddressList(StringCharCursor cursor)
130   {
131     ArrayList JavaDoc<Recipient> to = new ArrayList JavaDoc<Recipient>();
132
133     char ch = cursor.current();
134     CharBuffer buf = new CharBuffer();
135
136     while (Character.isWhitespace(ch))
137       ch = cursor.next();
138     
139     while (isUserChar(ch)) {
140       buf.clear();
141       for (; isUserChar(ch); ch = cursor.next())
142     buf.append(ch);
143
144       Recipient rcpt = new Recipient();
145       to.add(rcpt);
146       rcpt.user = buf.toString();
147
148       if (ch == '@') {
149     ch = cursor.next();
150     if (! isUserChar(ch))
151       throw new RuntimeException JavaDoc("bad url");
152
153     buf.clear();
154     for (; isUserChar(ch); ch = cursor.next())
155       buf.append(ch);
156
157     rcpt.host = buf.toString();
158       }
159
160       while (ch == ',' || ch == ' ' || ch == '\t' ||
161          ch == '\n' || ch == '\r') {
162     ch = cursor.next();
163       }
164     }
165
166     return to;
167   }
168
169   /**
170    * Returns true if the char is a valid recipient character.
171    */

172   private static boolean isUserChar(int ch)
173   {
174     switch (ch) {
175     case '.': case '-': case '_': case '!': case '$':
176     case '~': case '^': case '*': case '/': case '+':
177       return true;
178
179     default:
180       return (ch >= 'a' && ch <= 'z' ||
181           ch >= 'A' && ch <= 'Z' ||
182           ch >= '0' && ch <= '9');
183     }
184   }
185
186   /**
187    * The URL looks like "mailto:user@host.com"
188    */

189   public String JavaDoc getURL()
190   {
191     return getPath();
192   }
193
194   /**
195    * The scheme is "mailto:"
196    */

197   public String JavaDoc getScheme()
198   {
199     return "mailto";
200   }
201
202   /**
203    * The path looks like "mailto:user@host.com"
204    */

205   public String JavaDoc getPath()
206   {
207     return "mailto:" + url;
208   }
209
210   /**
211    * Gets the value of the RFC822 message headers.
212    */

213   public Object JavaDoc getAttribute(String JavaDoc name)
214   {
215     return _attributes.get(name);
216   }
217
218   /**
219    * Implementation to open a WriteStream.
220    */

221   public StreamImpl openWriteImpl()
222     throws IOException JavaDoc
223   {
224     return new SmtpStream(_to, _attributes);
225   }
226
227   static class Recipient {
228     String JavaDoc user;
229     String JavaDoc host;
230   }
231 }
232
Popular Tags