1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.james.jcr;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.text.SimpleDateFormat;
23 import java.util.Calendar;
24 import java.util.Date;
25
26 import javax.jcr.Node;
27 import javax.jcr.PathNotFoundException;
28 import javax.jcr.RepositoryException;
29 import javax.mail.Address;
30 import javax.mail.BodyPart;
31 import javax.mail.Message;
32 import javax.mail.MessagingException;
33 import javax.mail.Multipart;
34 import javax.mail.Part;
35 import javax.mail.Message.RecipientType;
36 import javax.mail.internet.ContentType;
37 import javax.mail.internet.MimeMessage;
38
39 import org.apache.jackrabbit.util.Text;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class JCRStoreBean {
64
65
66
67
68 private Node parent;
69
70 public void setParentNode(Node parent) {
71 this.parent = parent;
72 }
73
74
75
76
77
78
79
80
81 public void storeMessage(Message message)
82 throws MessagingException, RepositoryException {
83 try {
84 Date date = message.getSentDate();
85 Node year = getOrAddNode(parent, format("yyyy", date), "nt:folder");
86 Node month = getOrAddNode(year, format("mm", date), "nt:folder");
87 Node day = getOrAddNode(month, format("dd", date), "nt:folder");
88 Node node = createNode(day, getMessageName(message), "nt:file");
89 importEntity(message, node);
90 parent.save();
91 } catch (IOException e) {
92 throw new MessagingException("Could not read message", e);
93 }
94 }
95
96
97
98
99
100
101
102
103
104
105 private void importEntity(Part entity, Node parent)
106 throws MessagingException, RepositoryException, IOException {
107 Node node = parent.addNode("jcr:content", "nt:unstructured");
108
109 setProperty(node, "description", entity.getDescription());
110 setProperty(node, "disposition", entity.getDisposition());
111 setProperty(node, "filename", entity.getFileName());
112
113 if (entity instanceof MimeMessage) {
114 MimeMessage mime = (MimeMessage) entity;
115 setProperty(node, "subject", mime.getSubject());
116 setProperty(node, "message-id", mime.getMessageID());
117 setProperty(node, "content-id", mime.getContentID());
118 setProperty(node, "content-md5", mime.getContentMD5());
119 setProperty(node, "language", mime.getContentLanguage());
120 setProperty(node, "sent", mime.getSentDate());
121 setProperty(node, "received", mime.getReceivedDate());
122 setProperty(node, "from", mime.getFrom());
123 setProperty(node, "to", mime.getRecipients(RecipientType.TO));
124 setProperty(node, "cc", mime.getRecipients(RecipientType.CC));
125 setProperty(node, "bcc", mime.getRecipients(RecipientType.BCC));
126 setProperty(node, "reply-to", mime.getReplyTo());
127 setProperty(node, "sender", mime.getSender());
128 }
129
130 Object content = entity.getContent();
131 ContentType type = getContentType(entity);
132 node.setProperty("jcr:mimeType", type.getBaseType());
133 if (content instanceof Multipart) {
134 Multipart multipart = (Multipart) content;
135 for (int i = 0; i < multipart.getCount(); i++) {
136 BodyPart part = multipart.getBodyPart(i);
137 Node child;
138 if (part.getFileName() != null) {
139 child = createNode(node, part.getFileName(), "nt:file");
140 } else {
141 child = createNode(node, "part", "nt:unstructured");
142 }
143 importEntity(part, child);
144 }
145 } else if (content instanceof String) {
146 byte[] bytes = ((String) content).getBytes("UTF-8");
147 node.setProperty("jcr:encoding", "UTF-8");
148 node.setProperty("jcr:data", new ByteArrayInputStream(bytes));
149 } else if (content instanceof InputStream) {
150 setProperty(
151 node, "jcr:encoding", type.getParameter("encoding"));
152 node.setProperty("jcr:data", (InputStream) content);
153 } else {
154 node.setProperty("jcr:data", entity.getInputStream());
155 }
156 }
157
158
159
160
161
162
163
164
165
166 private String format(String format, Date date) {
167 return new SimpleDateFormat(format).format(date);
168 }
169
170
171
172
173
174
175
176
177 private String getMessageName(Message message)
178 throws MessagingException {
179 String name = message.getSubject();
180 if (name == null) {
181 name = "unnamed";
182 } else {
183 name = name.replaceAll("[^A-Za-z0-9 ]", "").trim();
184 if (name.length() == 0) {
185 name = "unnamed";
186 }
187 }
188 return name;
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202 private Node getOrAddNode(Node parent, String name, String type)
203 throws RepositoryException {
204 try {
205 return parent.getNode(name);
206 } catch (PathNotFoundException e) {
207 return parent.addNode(name, type);
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220
221 private Node createNode(Node parent, String name, String type)
222 throws RepositoryException {
223 String original = name;
224 name = Text.escapeIllegalJcrChars(name);
225 for (int i = 2; parent.hasNode(name); i++) {
226 name = Text.escapeIllegalJcrChars(original + i);
227 }
228 return parent.addNode(name, type);
229 }
230
231
232
233
234
235
236
237
238
239 private static ContentType getContentType(Part entity) {
240 try {
241 String type = entity.getContentType();
242 if (type != null) {
243 return new ContentType(type);
244 } else {
245 return new ContentType("text/plain");
246 }
247 } catch (MessagingException e) {
248 ContentType type = new ContentType();
249 type.setPrimaryType("application");
250 type.setSubType("octet-stream");
251 return type;
252 }
253 }
254
255
256
257
258
259
260
261
262
263 private void setProperty(Node node, String name, String value)
264 throws RepositoryException {
265 if (value != null) {
266 node.setProperty(name, value);
267 }
268 }
269
270
271
272
273
274
275
276
277
278
279 private void setProperty(Node node, String name, String[] values)
280 throws RepositoryException {
281 if (values != null && values.length > 0) {
282 node.setProperty(name, values);
283 }
284 }
285
286
287
288
289
290
291
292
293
294 private void setProperty(Node node, String name, Date value)
295 throws RepositoryException {
296 if (value != null) {
297 Calendar calendar = Calendar.getInstance();
298 calendar.setTime(value);
299 node.setProperty(name, calendar);
300 }
301 }
302
303
304
305
306
307
308
309
310
311 private void setProperty(Node node, String name, Address value)
312 throws RepositoryException {
313 if (value != null) {
314 node.setProperty(name, value.toString());
315 }
316 }
317
318
319
320
321
322
323
324
325
326
327 private void setProperty(Node node, String name, Address[] values)
328 throws RepositoryException {
329 if (values != null && values.length > 0) {
330 String[] strings = new String[values.length];
331 for (int i = 0; i < values.length; i++) {
332 strings[i] = values[i].toString();
333 }
334 node.setProperty(name, strings);
335 }
336 }
337
338 }