source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/FavouriteBasket.java@ 37518

Last change on this file since 37518 was 37518, checked in by kjdon, 14 months ago

simplified Favourites - items now are just collection and id. no metadata involved. getting metadata is done by the action now (a=gdl), and depends on format statements etc. the xml element is now documentNode, not item.

  • Property svn:keywords set to Author Date Id Revision
File size: 16.7 KB
Line 
1/*
2 * FavouriteBasket.java
3 * Copyright (C) 2006 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20package org.greenstone.gsdl3.service;
21
22import java.sql.Statement;
23import java.util.Hashtable;
24import java.util.HashMap;
25import java.util.ArrayList;
26import java.util.HashSet;
27import java.util.Iterator;
28import java.util.Set;
29
30import org.w3c.dom.Document;
31import org.w3c.dom.Element;
32import org.w3c.dom.NodeList;
33
34import org.greenstone.util.GlobalProperties;
35import org.greenstone.gsdl3.util.GSXML;
36import org.greenstone.gsdl3.util.GSPath;
37import org.greenstone.gsdl3.util.UserContext;
38import org.greenstone.gsdl3.util.XMLConverter;
39
40import java.io.Serializable;
41import java.net.InetAddress;
42import java.util.Properties;
43import java.util.Date;
44
45import javax.mail.*;
46import javax.mail.internet.*;
47
48import java.awt.event.ActionEvent;
49import java.awt.event.ActionListener;
50import javax.swing.Timer;
51
52import org.apache.log4j.*;
53
54public class FavouriteBasket extends ServiceRack
55{
56
57 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.FavouriteBasket.class.getName());
58
59 // the services on offer
60 // these strings must match what is found in the properties file
61 protected static final String ADD_ITEM_SERVICE = "AddFavourite";
62 protected static final String DISPLAY_ITEMS_SERVICE = "GetFavouritesList";
63 protected static final String ITEM_NUM_SERVICE = "GetNumFavourites";
64 protected static final String DELETE_ITEMS_SERVICE = "DeleteFavourites";
65 protected static final String SEND_MAIL_SERVICE = "SendFavouritesMail";
66 //protected static final String DELETE_ITEM_SERVICE = "DeleteItem";
67
68 // for AddFavourite
69 protected static final String ITEM_PARAM = "item";
70 // for DeleteFavouritess
71 protected static final String ITEMS_PARAM = "items";
72 // for SendMail
73 protected static final String ADDRESS_PARAM = "address";
74 protected static final String SUBJECT_PARAM = "subject";
75 protected static final String CONTENT_PARAM = "content";
76 protected static final String CC_PARAM = "cc";
77 protected static final String BCC_PARAM = "bcc";
78
79
80 protected static final String delimiter = "|";
81 protected static final int delay = 1800000;
82
83 protected Hashtable<String, Hashtable<String, Hashtable<String, Item>>> userMap = null;
84 protected Hashtable<String, UserTimer> timerMap = null;
85 protected String username = "";
86 protected String password = "";
87
88 HashSet<String> meta_names = null;
89
90 /** constructor */
91 public FavouriteBasket()
92 {
93 userMap = new Hashtable<String, Hashtable<String, Hashtable<String, Item>>>();
94 timerMap = new Hashtable<String, UserTimer>();
95 }
96
97 private Hashtable<String, Hashtable<String, Item>> updateDocMap(Element request)
98 {
99
100 UserContext userContext = new UserContext(request);
101 String id = null;
102 String user_name =userContext.getUsername();
103 if (user_name == null || user_name.equals("")) {
104 id = userContext.getUserID();
105 } else {
106 id = user_name;
107 }
108 if (userMap.containsKey(id))
109 {
110 if (timerMap.containsKey(id))
111 {
112 UserTimer timer = timerMap.get(id);
113 timer.restart();
114 }
115 return userMap.get(id);
116 }
117 else
118 {
119 UserTimer timer = new UserTimer(delay, id);
120 timerMap.put(id, timer);
121 timer.start();
122 Hashtable<String, Hashtable<String, Item>> newDocs = new Hashtable<String, Hashtable<String, Item>>();
123 userMap.put(id, newDocs);
124 return newDocs;
125 }
126 }
127
128 /** configure this service */
129 public boolean configure(Element info, Element extra_info)
130 {
131 logger.info("Configuring FavouriteBasket...");
132 this.config_info = info;
133
134 // set up short_service_info_ - for now just has name and type
135 Element add_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
136 add_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
137 add_service.setAttribute(GSXML.NAME_ATT, ADD_ITEM_SERVICE);
138 this.short_service_info.appendChild(add_service);
139
140 // set up short_service_info_ - for now just has name and type
141 Element disp_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
142 disp_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
143 disp_service.setAttribute(GSXML.NAME_ATT, DISPLAY_ITEMS_SERVICE);
144 this.short_service_info.appendChild(disp_service);
145
146 // set up short_service_info_ - for now just has name and type
147 Element num_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
148 num_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
149 num_service.setAttribute(GSXML.NAME_ATT, ITEM_NUM_SERVICE);
150 this.short_service_info.appendChild(num_service);
151
152 // set up short_service_info_ - for now just has name and type
153 Element delete_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
154 delete_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
155 delete_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEMS_SERVICE);
156 this.short_service_info.appendChild(delete_service);
157
158 // set up short_service_info_ - for now just has name and type
159 // Element deleteone_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
160 // deleteone_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
161 // deleteone_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEM_SERVICE);
162 // this.short_service_info.appendChild(deleteone_service);
163
164 // set up short_service_info_ - for now just has name and type
165 Element mail_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
166 mail_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
167 mail_service.setAttribute(GSXML.NAME_ATT, SEND_MAIL_SERVICE);
168 this.short_service_info.appendChild(mail_service);
169
170 return true;
171
172 }
173
174 /** returns a specific service description */
175 protected Element getServiceDescription(Document doc, String service_id, String lang, String subset)
176 {
177
178 if (service_id.equals(ADD_ITEM_SERVICE))
179 {
180 Element add_service = doc.createElement(GSXML.SERVICE_ELEM);
181 add_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
182 add_service.setAttribute(GSXML.NAME_ATT, ADD_ITEM_SERVICE);
183 return add_service;
184 }
185 if (service_id.equals(DISPLAY_ITEMS_SERVICE))
186 {
187
188 Element disp_service = doc.createElement(GSXML.SERVICE_ELEM);
189 disp_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
190 disp_service.setAttribute(GSXML.NAME_ATT, DISPLAY_ITEMS_SERVICE);
191 return disp_service;
192 }
193
194 if (service_id.equals(ITEM_NUM_SERVICE))
195 {
196
197 Element num_service = doc.createElement(GSXML.SERVICE_ELEM);
198 num_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
199 num_service.setAttribute(GSXML.NAME_ATT, ITEM_NUM_SERVICE);
200 return num_service;
201 }
202
203 if (service_id.equals(DELETE_ITEMS_SERVICE))
204 {
205
206 Element del_service = doc.createElement(GSXML.SERVICE_ELEM);
207 del_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
208 del_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEMS_SERVICE);
209 return del_service;
210 }
211
212 if (service_id.equals(SEND_MAIL_SERVICE))
213 {
214
215 Element mail_service = doc.createElement(GSXML.SERVICE_ELEM);
216 mail_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
217 mail_service.setAttribute(GSXML.NAME_ATT, SEND_MAIL_SERVICE);
218 return mail_service;
219 }
220
221 return null;
222 }
223
224 protected Element processAddFavourite(Element request)
225 {
226
227 Hashtable<String, Hashtable<String, Item>> docsMap = updateDocMap(request);
228
229 // Create a new (empty) result message
230 Document result_doc = XMLConverter.newDOM();
231 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
232
233 // Get the parameters of the request
234 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
235 if (param_list == null)
236 {
237 logger.error("FavouriteBasket Error: AddFavourite request had no paramList.");
238 return result; // Return the empty result
239 }
240
241 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
242
243 String item = (String) params.get(ITEM_PARAM);
244 String collection = "";
245 int pos = item.indexOf(":");
246 if (pos != -1)
247 {
248 collection = item.substring(0, pos);
249 item = item.substring(pos + 1);
250 }
251
252 if (docsMap.containsKey(collection))
253 {
254 Hashtable<String, Item> items = docsMap.get(collection);
255 if (!items.containsKey(item))
256 {
257 Item newItem = new Item(collection, item);
258 items.put(item, newItem);
259 result.appendChild(newItem.wrapIntoElement(result_doc));
260 }
261 }
262 else
263 {
264 Hashtable<String, Item> items = new Hashtable<String, Item>();
265 Item newItem = new Item(collection, item);
266 items.put(item, newItem);
267 docsMap.put(collection, items);
268 result.appendChild(newItem.wrapIntoElement(result_doc));
269 }
270
271 return result;
272 }
273
274
275 protected Element processDeleteFavouritess(Element request)
276 {
277
278 Hashtable<String, Hashtable<String, Item>> docsMap = updateDocMap(request);
279
280 // Create a new (empty) result message
281 Document result_doc = XMLConverter.newDOM();
282 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
283
284 // Get the parameters of the request
285 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
286
287 if (param_list == null)
288 {
289 logger.error("FavouriteBasket Error: DeleteItem request had no paramList.");
290 return result; // Return the empty result
291 }
292
293 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
294
295 String param = (String) params.get(ITEMS_PARAM);
296
297 if (param == null)
298 return result;
299
300 String[] items = param.split("\\|");
301
302 for (int i = 0; i < items.length; i++)
303 {
304 String item = items[i];
305 if (item.trim().length() == 0)
306 continue;
307 String collection = "";
308 int pos = item.indexOf(":");
309 if (pos != -1)
310 {
311 collection = item.substring(0, pos);
312 item = item.substring(pos + 1);
313 }
314
315 if (docsMap.containsKey(collection))
316 {
317 Hashtable itemMap = docsMap.get(collection);
318 if (itemMap.containsKey(item))
319 {
320 itemMap.remove(item);
321 }
322 if (itemMap.size() == 0)
323 {
324 docsMap.remove(collection);
325 }
326 }
327
328 }
329
330 return result;
331 }
332
333
334 protected Element processGetNumFavourites(Element request)
335 {
336 Hashtable<String, Hashtable<String, Item>> docsMap = updateDocMap(request);
337
338 // Create a new (empty) result message
339 Document result_doc = XMLConverter.newDOM();
340 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
341
342 int size = 0;
343 String ids = "";
344 Iterator<String> keys = docsMap.keySet().iterator();
345
346 while (keys.hasNext())
347 {
348 Hashtable items = docsMap.get(keys.next());
349 size += items.size();
350 Iterator values = items.values().iterator();
351 while (values.hasNext())
352 {
353 Item item = (Item) values.next();
354 result.appendChild(item.wrapIntoElement(result_doc));
355 }
356 }
357
358 Element selement = result_doc.createElement("size");
359 selement.setAttribute("value", size + "");
360 result.appendChild(selement);
361
362 return result;
363 }
364
365
366 protected Element processGetFavouritesList(Element request)
367 {
368 Hashtable<String, Hashtable<String, Item>> docsMap = updateDocMap(request);
369
370 // Create a new (empty) result message
371 Document result_doc = XMLConverter.newDOM();
372 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
373
374 Iterator<String> keys = docsMap.keySet().iterator();
375
376 while (keys.hasNext())
377 {
378 String collection = keys.next();
379 Hashtable items = docsMap.get(collection);
380 Iterator itemItr = items.values().iterator();
381
382 Element collectionNode = result_doc.createElement("favouriteList");
383 collectionNode.setAttribute("name", collection);
384 result.appendChild(collectionNode);
385
386 while (itemItr.hasNext())
387 {
388 Item item = (Item) itemItr.next();
389 collectionNode.appendChild(item.wrapIntoElement(result_doc));
390 }
391 }
392
393 return result;
394 }
395
396
397
398
399 public Element processSendFavouritesMail(Element request)
400 {
401 // Create a new (empty) result message
402 Document result_doc = XMLConverter.newDOM();
403 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
404
405 // Get the parameters of the request
406 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
407
408 if (param_list == null)
409 {
410 logger.error("FavouriteBasket Error: SendMail request had no paramList.");
411 return result; // Return the empty result
412 }
413
414 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
415
416 String to = (String) params.get(ADDRESS_PARAM);
417 String subject = (String) params.get(SUBJECT_PARAM);
418 String content = (String) params.get(CONTENT_PARAM);
419 String cc = (String) params.get(CC_PARAM);
420 String bcc = (String) params.get(BCC_PARAM);
421
422 String mailhost = GlobalProperties.getProperty("mail.smtp.host");
423 username = GlobalProperties.getProperty("mail.smtp.username");
424 password = GlobalProperties.getProperty("mail.smtp.password");
425 String from = GlobalProperties.getProperty("mail.from");
426 String port = GlobalProperties.getProperty("mail.smtp.port");
427 String mail_security = GlobalProperties.getProperty("mail.security");
428 String mailer = "msgsend";
429
430 try
431 {
432
433 Properties props = System.getProperties();
434
435 //Setup smtp host and from address
436 // XXX - could use Session.getTransport() and Transport.connect()
437 // XXX - assume we're using SMTP
438 if (mailhost != null && !mailhost.trim().equals(""))
439 {
440 props.put("mail.smtp.host", mailhost);
441 }
442 else
443 {
444 props.put("mail.smtp.host", "localhost");
445 }
446 if (from != null && !from.trim().equals(""))
447 {
448 props.put("mail.from", from);
449 }
450
451
452 if (port != null && !port.trim().equals("")) {
453 props.put("mail.smtp.port", port);
454 }
455
456 if (mail_security != null) {
457 mail_security = mail_security.trim();
458 if (mail_security.equals("ssl")) {
459 props.put("mail.smtp.ssl.enable", "true");
460 } else if (mail_security.equals("tls")) {
461 props.put("mail.smtp.starttls.enable", "true");
462 }
463 else if (mail_security.equals("")) {
464 logger.error("unknown security protocol "+mail_security +", should be ssl or tls");
465 }
466 }
467
468 // this doesn't seem to matter having this when
469 // username and password are empty
470 props.put("mail.smtp.auth", "true");
471
472 //setup username and password to the smtp server
473
474 if (username == null || username.trim().equals(""))
475 username = "";
476 if (password == null || password.trim().equals(""))
477 password = "";
478
479 Authenticator auth = new Authenticator()
480 {
481 protected PasswordAuthentication getPasswordAuthentication()
482 {
483 return new PasswordAuthentication(username, password);
484 }
485 };
486
487 Session session = Session.getInstance(props, auth);
488
489 Message msg = new MimeMessage(session);
490 msg.setFrom();
491 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
492 if (cc != null)
493 {
494 msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc, false));
495 }
496 if (bcc != null)
497 {
498 msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc, false));
499 }
500 msg.setSubject(subject);
501 msg.setText(content.replaceAll("-------", "&"));
502 msg.setHeader("X-Mailer", mailer);
503 msg.setSentDate(new Date());
504
505 // send the thing off
506 Transport.send(msg);
507
508 logger.info("\nMail was sent successfully.");
509 result.appendChild(result_doc.createTextNode("Mail was sent successfully."));
510 }
511 catch (Exception e)
512 {
513 logger.error("Error sending mail!");
514 e.printStackTrace();
515 result.appendChild(result_doc.createTextNode(e.getMessage()));
516 }
517
518 return result;
519 }
520
521 protected class Item
522 {
523 public String collection;
524 public String docid;
525
526 public Item(String coll, String id)
527 {
528 this.collection = coll;
529 this.docid = id;
530 }
531
532 public boolean equals(Object o)
533 {
534 if (!(o instanceof Item))
535 {
536 return false;
537 }
538 Item item = (Item) o;
539 String id = collection + ":" + docid;
540 String idin = item.collection + ":" + item.docid;
541 return id.equals(idin);
542
543 }
544
545 public Element wrapIntoElement(Document doc)
546 {
547 Element itemElement = doc.createElement("documentNode");
548 itemElement.setAttribute("nodeID", docid);
549 itemElement.setAttribute("collection", collection);
550
551 return itemElement;
552 }
553 }
554
555 private class UserTimer extends Timer implements ActionListener
556 {
557 String id = "";
558
559 public UserTimer(int delay, String id)
560 {
561 super(delay, (ActionListener) null);
562 addActionListener(this);
563 this.id = id;
564 }
565
566 public void actionPerformed(ActionEvent e)
567 {
568 userMap.remove(id);
569 timerMap.remove(id);
570 stop();
571 }
572
573 }
574
575}
Note: See TracBrowser for help on using the repository browser.