View Javadoc

1   /*
2    * This file is part of Domingo
3    * an Open Source Java-API to Lotus Notes/Domino
4    * hosted at http://domingo.sourceforge.net
5    *
6    * Copyright (c) 2003-2007 Beck et al. projects GmbH Munich, Germany (http://www.bea.de)
7    *
8    * This library is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU Lesser General Public
10   * License as published by the Free Software Foundation; either
11   * version 2.1 of the License, or (at your option) any later version.
12   *
13   * This library is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   * Lesser General Public License for more details.
17   *
18   * You should have received a copy of the GNU Lesser General Public
19   * License along with this library; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21   */
22  
23  package de.bea.domingo.groupware.map;
24  
25  import java.io.IOException;
26  import java.io.Serializable;
27  import java.util.ArrayList;
28  import java.util.Calendar;
29  import java.util.Comparator;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.SortedSet;
33  import java.util.TreeSet;
34  
35  import de.bea.domingo.DDatabase;
36  import de.bea.domingo.DDocument;
37  import de.bea.domingo.DNotesException;
38  import de.bea.domingo.DSession;
39  import de.bea.domingo.DView;
40  import de.bea.domingo.DViewEntry;
41  import de.bea.domingo.groupware.CalendarEntry;
42  import de.bea.domingo.groupware.CalendarEntryDigest;
43  import de.bea.domingo.groupware.CalendarInterface;
44  import de.bea.domingo.groupware.Email;
45  import de.bea.domingo.groupware.EmailDigest;
46  import de.bea.domingo.groupware.GroupwareRuntimeException;
47  import de.bea.domingo.groupware.Mailbox;
48  import de.bea.domingo.map.BaseDatabase;
49  import de.bea.domingo.map.MapperRegistrationException;
50  import de.bea.domingo.map.MappingException;
51  import de.bea.domingo.map.NotesLocation;
52  
53  /***
54   * Interface to mail databases.
55   *
56   * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
57   */
58  public final class MailDatabase extends BaseDatabase implements Mailbox, CalendarInterface {
59  
60      private static final String CALENDAR_VIEW = "($Calendar)";
61  
62      /*** Owner name. */
63      private final String fOwner;
64  
65      /***
66       * Constructor.
67       *
68       * @param locationUri URI of location of database.
69       * @param owner name of mailbox owner
70       * @throws IOException if the location is not a valid notes location
71       * @throws DNotesException if the database cannot be opened
72       */
73      public MailDatabase(final String locationUri, final String owner) throws IOException, DNotesException {
74          super(locationUri);
75          fOwner = owner;
76      }
77  
78      /***
79       * Constructor.
80       *
81       * @param session an existing domingo session
82       * @param location location of database.
83       * @param owner name of mailbox owner
84       * @throws DNotesException if the uri is invalid or the database cannot be
85       *             opened
86       */
87      public MailDatabase(final DSession session, final NotesLocation location, final String owner) throws DNotesException {
88          super(session, location);
89          fOwner = owner;
90      }
91  
92      /***
93       * Constructor.
94       *
95       * @param database a mail database
96       * @param owner name of mailbox owner
97       * @throws DNotesException if the database is invalid or cannot be opened
98       */
99      public MailDatabase(final DDatabase database, final String owner) throws DNotesException {
100         super(database);
101         fOwner = owner;
102     }
103 
104     /***
105      * Registers all mappers needed for a mail database.
106      *
107      * @throws MapperRegistrationException if an error occurred during registering a mapper
108      * @see de.bea.domingo.map.BaseDatabase#registerMappers()
109      */
110     protected void registerMappers() throws MapperRegistrationException {
111         register(EmailMapper.class);
112         register(CalendarEntryMapper.class);
113     }
114 
115     /***
116      * {@inheritDoc}
117      * @see de.bea.domingo.groupware.Mailbox#getOwner()
118      */
119     public String getOwner() {
120         // TODO read owner from calendar profile
121         return fOwner;
122     }
123 
124     /***
125      * {@inheritDoc}
126      *
127      * @see de.bea.domingo.groupware.Mailbox#reply(de.bea.domingo.groupware.Email, boolean, boolean)
128      */
129     public Email reply(final Email memo, final boolean withHistory, final boolean withAttachments) {
130         Email reply = new Email(memo);
131         reply.setSubject("Re: " + memo.getSubject());
132         String sender = getDatabase().getSession().getCommonUserName();
133         reply.setFrom(sender);
134         reply.setPrincipal(sender);
135         reply.setReplyTo(sender);
136         reply.setRecipient(memo.getFrom());
137         reply.setBcc("");
138         // TODO handle withHistory
139         // TODO handle withAttachments
140         return reply;
141     }
142 
143     /***
144      * {@inheritDoc}
145      *
146      * @see de.bea.domingo.groupware.Mailbox#replyToAll(de.bea.domingo.groupware.Email, boolean, boolean)
147      */
148     public Email replyToAll(final Email memo, final boolean withHistory, final boolean withAttachments) {
149         Email reply = new Email(memo);
150         reply.setSubject("Re: " + memo.getSubject());
151         String sender = getDatabase().getSession().getCommonUserName();
152         reply.setFrom(sender);
153         reply.setPrincipal(sender);
154         reply.setReplyTo(sender);
155         reply.setRecipient(memo.getFrom());
156         reply.setCc(memo.getCc());
157         reply.setBcc(memo.getBcc());
158         // todo handle parameter withHistory
159         // todo handle parameter withAttachments
160         return reply;
161     }
162 
163     /***
164      * {@inheritDoc}
165      *
166      * @see de.bea.domingo.groupware.Mailbox#remove(de.bea.domingo.groupware.Email)
167      */
168     public void remove(final Email memo) {
169         final String unid = memo.getUnid();
170         final DDocument document = getDatabase().getDocumentByUNID(unid);
171         document.remove(true);
172     }
173 
174     /***
175      * {@inheritDoc}
176      *
177      * @see de.bea.domingo.groupware.Mailbox#remove(de.bea.domingo.groupware.EmailDigest)
178      */
179     public void remove(final EmailDigest memo) {
180         final String unid = memo.getUnid();
181         final DDocument document = getDatabase().getDocumentByUNID(unid);
182         document.remove(true);
183     }
184 
185 //    /***
186 //     * {@inheritDoc}
187 //     *
188 //     * @see de.bea.domingo.groupware.MailboxInterface#getNewMails(java.util.Calendar)
189 //     */
190 //    public List getNewMails(final Calendar since) {
191 //        return null; // TODO
192 //    }
193 
194     /***
195      * {@inheritDoc}
196      *
197      * @see de.bea.domingo.groupware.CalendarInterface#getObjects(java.util.Calendar,
198      *      java.util.Calendar)
199      */
200     public List getObjects(final Calendar from, final Calendar to) {
201 
202         SortedSet calendarEntrySet = new TreeSet(new CalendarEntryComparator());
203         DView view = getDatabase().getView(CALENDAR_VIEW);
204         Iterator it = view.getAllEntriesByKey(from, to, true);
205         while (it.hasNext()) {
206             DViewEntry entry = (DViewEntry) it.next();
207             CalendarEntryDigest entryDigest = new CalendarEntryDigest();
208 
209             try {
210                 map(entry, entryDigest);
211             } catch (MappingException e) {
212                 throw new GroupwareRuntimeException("Cannot get next calendar entry", e);
213             }
214 
215             // This check filters out TO-DO items appearing in the calendar view
216             // (they appear unless the user has checked "do not display to-do
217             // entries in the calendar") in the Calendar Preferences.
218             if (null != entryDigest.getStartDateTime()) {
219                 calendarEntrySet.add(entryDigest);
220             }
221         }
222         return new ArrayList(calendarEntrySet);
223     }
224 
225     /***
226      * {@inheritDoc}
227      *
228      * @see de.bea.domingo.groupware.CalendarInterface#getCalendar()
229      */
230     public Iterator getCalendar() {
231         return getCalendar(false);
232     }
233 
234     /***
235      * {@inheritDoc}
236      *
237      * @see de.bea.domingo.groupware.CalendarInterface#getCalendar(boolean
238      *      reverseOrder)
239      */
240     public Iterator getCalendar(final boolean reverseOrder) {
241         DView view = getDatabase().getView(CALENDAR_VIEW);
242         Iterator allEntries;
243         if (reverseOrder) {
244             allEntries = view.getAllEntriesReverse();
245         } else {
246             allEntries = view.getAllEntries();
247         }
248         return new CalendarIterator(allEntries);
249     }
250 
251     /***
252      * {@inheritDoc}
253      *
254      * @see de.bea.domingo.groupware.Mailbox#getInbox()
255      */
256     public Iterator getInbox() {
257         return getInbox(false);
258     }
259 
260     /***
261      * {@inheritDoc}
262      *
263      * @see de.bea.domingo.groupware.Mailbox#getInbox(boolean)
264      */
265     public Iterator getInbox(final boolean reverseOrder) {
266         DView view = getDatabase().getView("($Inbox)");
267         Iterator allEntries;
268         if (reverseOrder) {
269             allEntries = view.getAllEntriesReverse();
270         } else {
271             allEntries = view.getAllEntries();
272         }
273         return new MailIterator(allEntries);
274     }
275 
276     /***
277      * Compares calendar entries by start date.
278      */
279     private static final class CalendarEntryComparator implements Comparator, Serializable {
280 
281         private static final long serialVersionUID = 8982105227393259520L;
282 
283         public int compare(final Object o1, final Object o2) {
284             CalendarEntryDigest ced1 = (CalendarEntryDigest) o1;
285             CalendarEntryDigest ced2 = (CalendarEntryDigest) o2;
286             if (null == ced1 && null == ced2) { return 0; }
287             if (null == ced1) { return -1; }
288             if (null == ced2) { return 1; }
289             if (null == ced1.getStartDateTime()) { return -1; }
290             if (null == ced2.getStartDateTime()) { return 1; }
291             return (ced1.getStartDateTime().getTime().compareTo(ced2.getStartDateTime().getTime()));
292         }
293     }
294 
295     /***
296      * Iterates thru a collection of view entries and returns for each
297      * view-entry the corresponding email digest.
298      */
299     private class MailIterator implements Iterator {
300 
301         private final Iterator allEntries;
302 
303         /***
304          * Constructor.
305          *
306          * @param allEntries collection of view-entries
307          */
308         public MailIterator(final Iterator allEntries) {
309             this.allEntries = allEntries;
310         }
311 
312         /***
313          * @see java.util.Iterator#hasNext()
314          */
315         public boolean hasNext() {
316             return allEntries.hasNext();
317         }
318 
319         /***
320          * @see java.util.Iterator#next()
321          */
322         public Object next() {
323             DViewEntry entry = (DViewEntry) allEntries.next();
324             EmailDigest memoDigest = new EmailDigest();
325             try {
326                 map(entry, memoDigest);
327                 entry.getDocument().recycle();
328             } catch (MappingException e) {
329                 throw new GroupwareRuntimeException("Cannot get next email", e);
330             }
331             return memoDigest;
332         }
333 
334         /***
335          * @see java.util.Iterator#remove()
336          */
337         public void remove() {
338             throw new UnsupportedOperationException();
339         }
340 
341     }
342 
343     /***
344      * Iterates thru a collection of view entries and returns for each
345      * view-entry the corresponding calendar digest.
346      */
347     private class CalendarIterator implements Iterator {
348 
349         private final Iterator allEntries;
350 
351         /***
352          * Constructor.
353          *
354          * @param allEntries
355          */
356         public CalendarIterator(final Iterator allEntries) {
357             this.allEntries = allEntries;
358         }
359 
360         /***
361          * @see java.util.Iterator#hasNext()
362          */
363         public boolean hasNext() {
364             return this.allEntries.hasNext();
365         }
366 
367         /***
368          * @see java.util.Iterator#next()
369          */
370         public Object next() {
371             DViewEntry entry = (DViewEntry) allEntries.next();
372             CalendarEntryDigest entryDigest = new CalendarEntryDigest();
373             try {
374                 map(entry, entryDigest);
375                 entry.getDocument().recycle();
376             } catch (MappingException e) {
377                 throw new GroupwareRuntimeException("Cannot get next calendar entry", e);
378             }
379             return entryDigest;
380         }
381 
382         /***
383          * @see java.util.Iterator#remove()
384          */
385         public void remove() {
386             throw new UnsupportedOperationException();
387         }
388     }
389 
390     /***
391      * Returns the email represented by the given email-digest.
392      *
393      * @param emailDigest an email-digest
394      * @return the corresponding email
395      */
396     public Email getEmail(final EmailDigest emailDigest) {
397         DDocument memoDocument = getDatabase().getDocumentByUNID(emailDigest.getUnid());
398         Email email = new Email();
399         try {
400             map(memoDocument, email);
401             memoDocument.recycle();
402         } catch (MappingException e) {
403             throw new GroupwareRuntimeException("Cannot get email", e);
404         }
405         return email;
406     }
407 
408     /***
409      * Returns the full calendar entry for a given calendar entry digest.
410      *
411      * @param entryDigest a calendar digest
412      * @return the full calendar entry
413      */
414     public Object getCalendarEntry(final CalendarEntryDigest entryDigest) {
415         return this.getCalendarEntry(entryDigest.getUnid());
416     }
417 
418     /***
419      * Returns a calendar entry for a given unid.
420      *
421      * @see de.bea.domingo.groupware.CalendarEntry#getAppointmentUnid()
422      *
423      * @param unid the Notes document unique id of the calendar entry.
424      * @return the calendar entry
425      */
426     public Object getCalendarEntry(final String unid) {
427         DDocument calDocument = getDatabase().getDocumentByUNID(unid);
428         CalendarEntry entry = new CalendarEntry();
429         try {
430             map(calDocument, entry);
431             calDocument.recycle();
432         } catch (MappingException e) {
433             throw new GroupwareRuntimeException("Cannot get calendar entry", e);
434         }
435         return entry;
436     }
437 
438     /***
439      * {@inheritDoc}
440      *
441      * @see de.bea.domingo.groupware.Mailbox#newEmail()
442      */
443     public Email newEmail() {
444         return new Email();
445     }
446 
447     /***
448      * {@inheritDoc}
449      *
450      * @see de.bea.domingo.groupware.Mailbox#forward(de.bea.domingo.groupware.Email)
451      */
452     public Email forward(final Email memo) {
453         return forward(memo, true);
454     }
455 
456     /***
457      * {@inheritDoc}
458      *
459      * @see de.bea.domingo.groupware.Mailbox#forward(de.bea.domingo.groupware.Email,
460      *      boolean)
461      */
462     public Email forward(final Email memo, final boolean withAttachments) {
463         // TODO forward a memo
464         return null;
465     }
466 
467     /***
468      * {@inheritDoc}
469      *
470      * @see de.bea.domingo.groupware.Mailbox#saveAsDraft(de.bea.domingo.groupware.Email)
471      */
472     public void saveAsDraft(final Email memo) {
473         // TODO save a new memo as draft
474     }
475 
476     /***
477      * {@inheritDoc}
478      *
479      * @see de.bea.domingo.groupware.Mailbox#send(de.bea.domingo.groupware.Email)
480      */
481     public void send(final Email memo) {
482         DDocument document = getDatabase().createDocument();
483         try {
484             map(memo, document);
485         } catch (MappingException e) {
486             throw new GroupwareRuntimeException("Cannot send email", e);
487         }
488         document.send("");
489     }
490 
491     /***
492      * {@inheritDoc}
493      *
494      * @see de.bea.domingo.groupware.CalendarInterface#save(de.bea.domingo.groupware.CalendarEntry)
495      */
496     public void save(final CalendarEntry entry) {
497         DDocument document = getDatabase().createDocument();
498         try {
499             map(entry, document);
500         } catch (MappingException e) {
501             throw new GroupwareRuntimeException("Cannot create calendar entry", e);
502         }
503         document.save();
504     }
505 
506     /***
507      * {@inheritDoc}
508      *
509      * @see de.bea.domingo.groupware.Mailbox#remove(de.bea.domingo.groupware.Email)
510      */
511     public void remove(final CalendarEntry entry) {
512         final String unid = entry.getUnid();
513         final DDocument document = getDatabase().getDocumentByUNID(unid);
514         document.remove(true);
515     }
516 
517     /***
518      * {@inheritDoc}
519      *
520      * @see de.bea.domingo.groupware.Mailbox#remove(de.bea.domingo.groupware.EmailDigest)
521      */
522     public void remove(final CalendarEntryDigest entryDigest) {
523         final String unid = entryDigest.getUnid();
524         final DDocument document = getDatabase().getDocumentByUNID(unid);
525         document.remove(true);
526     }
527 }