KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > eperson > Subscribe


1 /*
2  * Subscribe.java
3  *
4  * Version: $Revision: 1.11 $
5  *
6  * Date: $Date: 2006/11/24 00:44:02 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.eperson;
41
42 import java.io.IOException JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.text.ParseException JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.Date JavaDoc;
47 import java.util.List JavaDoc;
48
49 import javax.mail.MessagingException JavaDoc;
50
51 import org.apache.log4j.Logger;
52 import org.dspace.authorize.AuthorizeException;
53 import org.dspace.authorize.AuthorizeManager;
54 import org.dspace.content.Collection;
55 import org.dspace.content.DCDate;
56 import org.dspace.content.DCValue;
57 import org.dspace.content.Item;
58 import org.dspace.core.ConfigurationManager;
59 import org.dspace.core.Context;
60 import org.dspace.core.Email;
61 import org.dspace.core.LogManager;
62 import org.dspace.handle.HandleManager;
63 import org.dspace.search.Harvest;
64 import org.dspace.search.HarvestedItemInfo;
65 import org.dspace.storage.rdbms.DatabaseManager;
66 import org.dspace.storage.rdbms.TableRow;
67 import org.dspace.storage.rdbms.TableRowIterator;
68
69 /**
70  * Class defining methods for sending new item e-mail alerts to users
71  *
72  * @author Robert Tansley
73  * @version $Revision: 1.11 $
74  */

75 public class Subscribe
76 {
77     /** log4j logger */
78     private static Logger log = Logger.getLogger(Subscribe.class);
79
80     /**
81      * Subscribe an e-person to a collection. An e-mail will be sent every day a
82      * new item appears in the collection.
83      *
84      * @param context
85      * DSpace context
86      * @param eperson
87      * EPerson to subscribe
88      * @param collection
89      * Collection to subscribe to
90      */

91     public static void subscribe(Context context, EPerson eperson,
92             Collection collection) throws SQLException JavaDoc, AuthorizeException
93     {
94         // Check authorisation. Must be administrator, or the eperson.
95
if (AuthorizeManager.isAdmin(context)
96                 || ((context.getCurrentUser() != null) && (context
97                         .getCurrentUser().getID() == eperson.getID())))
98         {
99             // already subscribed?
100
TableRowIterator r = DatabaseManager.query(context,
101                     "SELECT * FROM subscription WHERE eperson_id= ? " +
102                     " AND collection_id= ? ",
103                     eperson.getID(),collection.getID());
104
105             if (!r.hasNext())
106             {
107                 // Not subscribed, so add them
108
TableRow row = DatabaseManager.create(context, "subscription");
109                 row.setColumn("eperson_id", eperson.getID());
110                 row.setColumn("collection_id", collection.getID());
111                 DatabaseManager.update(context, row);
112
113                 log.info(LogManager.getHeader(context, "subscribe",
114                         "eperson_id=" + eperson.getID() + ",collection_id="
115                                 + collection.getID()));
116             }
117             
118             r.close();
119         }
120         else
121         {
122             throw new AuthorizeException(
123                     "Only admin or e-person themselves can subscribe");
124         }
125     }
126
127     /**
128      * Unsubscribe an e-person to a collection. Passing in <code>null</code>
129      * for the collection unsubscribes the e-person from all collections they
130      * are subscribed to.
131      *
132      * @param context
133      * DSpace context
134      * @param eperson
135      * EPerson to unsubscribe
136      * @param collection
137      * Collection to unsubscribe from
138      */

139     public static void unsubscribe(Context context, EPerson eperson,
140             Collection collection) throws SQLException JavaDoc, AuthorizeException
141     {
142         // Check authorisation. Must be administrator, or the eperson.
143
if (AuthorizeManager.isAdmin(context)
144                 || ((context.getCurrentUser() != null) && (context
145                         .getCurrentUser().getID() == eperson.getID())))
146         {
147             if (collection == null)
148             {
149                 // Unsubscribe from all
150
DatabaseManager.updateQuery(context,
151                         "DELETE FROM subscription WHERE eperson_id= ? ",
152                         eperson.getID());
153             }
154             else
155             {
156                 DatabaseManager.updateQuery(context,
157                         "DELETE FROM subscription WHERE eperson_id= ? " +
158                         "AND collection_id= ? ",
159                         eperson.getID(),collection.getID());
160
161                 log.info(LogManager.getHeader(context, "unsubscribe",
162                         "eperson_id=" + eperson.getID() + ",collection_id="
163                                 + collection.getID()));
164             }
165         }
166         else
167         {
168             throw new AuthorizeException(
169                     "Only admin or e-person themselves can unsubscribe");
170         }
171     }
172
173     /**
174      * Find out which collections an e-person is subscribed to
175      *
176      * @param context
177      * DSpace context
178      * @param eperson
179      * EPerson
180      * @return array of collections e-person is subscribed to
181      */

182     public static Collection[] getSubscriptions(Context context, EPerson eperson)
183             throws SQLException JavaDoc
184     {
185         TableRowIterator tri = DatabaseManager.query(context,
186                 "SELECT collection_id FROM subscription WHERE eperson_id= ? ",
187                 eperson.getID());
188
189         List JavaDoc collections = new ArrayList JavaDoc();
190
191         while (tri.hasNext())
192         {
193             TableRow row = tri.next();
194
195             collections.add(Collection.find(context, row
196                     .getIntColumn("collection_id")));
197         }
198
199         tri.close();
200         
201         Collection[] collArray = new Collection[collections.size()];
202
203         return (Collection[]) collections.toArray(collArray);
204     }
205
206     /**
207      * Is that e-person subscribed to that collection?
208      *
209      * @param context
210      * DSpace context
211      * @param eperson
212      * find out if this e-person is subscribed
213      * @param collection
214      * find out if subscribed to this collection
215      * @return <code>true</code> if they are subscribed
216      */

217     public static boolean isSubscribed(Context context, EPerson eperson,
218             Collection collection) throws SQLException JavaDoc
219     {
220         TableRowIterator tri = DatabaseManager.query(context,
221                 "SELECT * FROM subscription WHERE eperson_id= ? " +
222                 "AND collection_id= ? ",
223                 eperson.getID(),collection.getID());
224         
225         boolean result = tri.hasNext();
226         tri.close();
227         
228         return result;
229     }
230
231     /**
232      * Process subscriptions. This must be invoked only once a day. Messages are
233      * only sent out when a collection has actually received new items, so that
234      * people's mailboxes are not clogged with many "no new items" mails.
235      * <P>
236      * Yesterday's newly available items are included. If this is run at for
237      * example midday, any items that have been made available during the
238      * current day will not be included, but will be included in the next day's
239      * run.
240      * <P>
241      * For example, if today's date is 2002-10-10 (in UTC) items made available
242      * during 2002-10-09 (UTC) will be included.
243      *
244      * @param context
245      * DSpace context object
246      */

247     public static void processDaily(Context context) throws SQLException JavaDoc,
248             IOException JavaDoc
249     {
250         // Grab the subscriptions
251
TableRowIterator tri = DatabaseManager.query(context,
252                 "SELECT * FROM subscription ORDER BY eperson_id");
253
254         EPerson currentEPerson = null;
255         List JavaDoc collections = null; // List of Collections
256

257         // Go through the list collating subscriptions for each e-person
258
while (tri.hasNext())
259         {
260             TableRow row = tri.next();
261
262             // Does this row relate to the same e-person as the last?
263
if ((currentEPerson == null)
264                     || (row.getIntColumn("eperson_id") != currentEPerson
265                             .getID()))
266             {
267                 // New e-person. Send mail for previous e-person
268
if (currentEPerson != null)
269                 {
270
271                     try
272                     {
273                         sendEmail(context, currentEPerson, collections);
274                     }
275                     catch (MessagingException JavaDoc me)
276                     {
277                         log.error("Failed to send subscription to eperson_id="
278                                 + currentEPerson.getID());
279                         log.error(me);
280                     }
281                 }
282
283                 currentEPerson = EPerson.find(context, row
284                         .getIntColumn("eperson_id"));
285                 collections = new ArrayList JavaDoc();
286             }
287
288             collections.add(Collection.find(context, row
289                     .getIntColumn("collection_id")));
290         }
291         
292         tri.close();
293         
294         // Process the last person
295
if (currentEPerson != null)
296         {
297             try
298             {
299                 sendEmail(context, currentEPerson, collections);
300             }
301             catch (MessagingException JavaDoc me)
302             {
303                 log.error("Failed to send subscription to eperson_id="
304                         + currentEPerson.getID());
305                 log.error(me);
306             }
307         }
308     }
309
310     /**
311      * Sends an email to the given e-person with details of new items in the
312      * given collections, items that appeared yesterday. No e-mail is sent if
313      * there aren't any new items in any of the collections.
314      *
315      * @param context
316      * DSpace context object
317      * @param eperson
318      * eperson to send to
319      * @param collections
320      * List of collection IDs (Integers)
321      */

322     public static void sendEmail(Context context, EPerson eperson,
323             List JavaDoc collections) throws IOException JavaDoc, MessagingException JavaDoc,
324             SQLException JavaDoc
325     {
326         // Get the start and end dates for yesterday
327
Date JavaDoc thisTimeYesterday = new Date JavaDoc(System.currentTimeMillis()
328                 - (24 * 60 * 60 * 1000));
329
330         DCDate dcDateYesterday = new DCDate(thisTimeYesterday);
331
332         // this time yesterday in ISO 8601, stripping the time
333
String JavaDoc isoDateYesterday = dcDateYesterday.toString().substring(0, 10);
334
335         String JavaDoc startDate = isoDateYesterday;
336         String JavaDoc endDate = isoDateYesterday + "T23:59:59Z";
337
338         // FIXME: text of email should be more configurable from an
339
// i18n viewpoint
340
StringBuffer JavaDoc emailText = new StringBuffer JavaDoc();
341         boolean isFirst = true;
342
343         for (int i = 0; i < collections.size(); i++)
344         {
345             Collection c = (Collection) collections.get(i);
346
347             try {
348                 List JavaDoc itemInfos = Harvest.harvest(context, c, startDate, endDate, 0, // Limit
349
// and
350
// offset
351
// zero,
352
// get
353
// everything
354
0, true, // Need item objects
355
false, // But not containers
356
false); // Or withdrawals
357

358                 // Only add to buffer if there are new items
359
if (itemInfos.size() > 0)
360                 {
361                     if (!isFirst)
362                     {
363                         emailText
364                                 .append("\n---------------------------------------\n");
365                     }
366                     else
367                     {
368                         isFirst = false;
369                     }
370     
371                     emailText.append("New items in collection ").append(
372                             c.getMetadata("name")).append(": ").append(
373                             itemInfos.size()).append("\n\n");
374     
375                     for (int j = 0; j < itemInfos.size(); j++)
376                     {
377                         HarvestedItemInfo hii = (HarvestedItemInfo) itemInfos
378                                 .get(j);
379     
380                         DCValue[] titles = hii.item.getDC("title", null, Item.ANY);
381                         emailText.append(" Title: ");
382     
383                         if (titles.length > 0)
384                         {
385                             emailText.append(titles[0].value);
386                         }
387                         else
388                         {
389                             emailText.append("Untitled");
390                         }
391     
392                         DCValue[] authors = hii.item.getDC("contributor", Item.ANY,
393                                 Item.ANY);
394     
395                         if (authors.length > 0)
396                         {
397                             emailText.append("\n Authors: ").append(
398                                     authors[0].value);
399     
400                             for (int k = 1; k < authors.length; k++)
401                             {
402                                 emailText.append("\n ").append(
403                                         authors[k].value);
404                             }
405                         }
406     
407                         emailText.append("\n ID: ").append(
408                                 HandleManager.getCanonicalForm(hii.handle)).append(
409                                 "\n\n");
410                     }
411                 }
412             }
413             catch (ParseException JavaDoc pe)
414             {
415                 // This should never get thrown as the Dates are auto-generated
416
}
417         }
418
419         // Send an e-mail if there were any new items
420
if (emailText.length() > 0)
421         {
422             Email email = ConfigurationManager.getEmail("subscription");
423
424             email.addRecipient(eperson.getEmail());
425             email.addArgument(emailText.toString());
426             email.send();
427
428             log.info(LogManager.getHeader(context, "sent_subscription",
429                     "eperson_id=" + eperson.getID()));
430         }
431     }
432
433     /**
434      * Method for invoking subscriptions via the command line
435      *
436      * @param argv
437      * command-line arguments, none used yet
438      */

439     public static void main(String JavaDoc[] argv)
440     {
441         Context context = null;
442
443         try
444         {
445             context = new Context();
446             processDaily(context);
447             context.complete();
448         }
449         catch( Exception JavaDoc e )
450         {
451             log.fatal(e);
452         }
453         finally
454         {
455             if( context != null && context.isValid() )
456             {
457                 // Nothing is actually written
458
context.abort();
459             }
460         }
461     }
462 }
463
Popular Tags