source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/BerryBasket.java@ 24993

Last change on this file since 24993 was 24993, checked in by sjm84, 12 years ago

Adding UserContext to replace the use of lang and uid

  • Property svn:keywords set to Author Date Id Revision
File size: 19.1 KB
Line 
1/*
2 * BerryBasket.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;
28
29import org.w3c.dom.Element;
30import org.w3c.dom.NodeList;
31
32import org.greenstone.util.GlobalProperties;
33import org.greenstone.gsdl3.util.GSXML;
34import org.greenstone.gsdl3.util.GSPath;
35import org.greenstone.gsdl3.util.UserContext;
36
37import java.net.InetAddress;
38import java.util.Properties;
39import java.util.Date;
40
41import javax.mail.*;
42import javax.mail.internet.*;
43
44import java.awt.event.ActionEvent;
45import java.awt.event.ActionListener;
46import javax.swing.Timer;
47
48import org.apache.log4j.*;
49
50public class BerryBasket extends ServiceRack
51{
52
53 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.BerryBasket.class.getName());
54
55 // the services on offer
56 // these strings must match what is found in the properties file
57 protected static final String ADD_ITEM_SERVICE = "AddItem";
58 protected static final String DISPLAY_ITEMS_SERVICE = "DisplayList";
59 protected static final String ITEM_NUM_SERVICE = "ItemNum";
60 protected static final String DELETE_ITEMS_SERVICE = "DeleteItems";
61 protected static final String SEND_MAIL_SERVICE = "SendMail";
62 protected static final String DELETE_ITEM_SERVICE = "DeleteItem";
63
64 protected static final String ITEM_PARAM = "item";
65 protected static final String delimiter = "|";
66 protected static final int delay = 1800000;
67
68 protected Hashtable userMap = null;
69 protected Hashtable timerMap = null;
70 protected String username = "";
71 protected String password = "";
72
73 /** constructor */
74 public BerryBasket()
75 {
76 userMap = new Hashtable();
77 timerMap = new Hashtable();
78 }
79
80 private Hashtable updateDocMap(Element request)
81 {
82
83 String id = request.getAttribute("uid");
84
85 if (userMap.containsKey(id))
86 {
87 if (timerMap.containsKey(id))
88 {
89 UserTimer timer = (UserTimer) timerMap.get(id);
90 timer.restart();
91 }
92 return (Hashtable) userMap.get(id);
93 }
94 else
95 {
96 UserTimer timer = new UserTimer(delay, id);
97 timerMap.put(id, timer);
98 timer.start();
99 Hashtable newDocs = new Hashtable();
100 userMap.put(id, newDocs);
101 return newDocs;
102 }
103 }
104
105 /** configure this service */
106 public boolean configure(Element info, Element extra_info)
107 {
108 logger.info("Configuring BerryBasket...");
109 this.config_info = info;
110
111 // set up short_service_info_ - for now just has name and type
112 Element add_service = this.doc.createElement(GSXML.SERVICE_ELEM);
113 add_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
114 add_service.setAttribute(GSXML.NAME_ATT, ADD_ITEM_SERVICE);
115 this.short_service_info.appendChild(add_service);
116
117 // set up short_service_info_ - for now just has name and type
118 Element disp_service = this.doc.createElement(GSXML.SERVICE_ELEM);
119 disp_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
120 disp_service.setAttribute(GSXML.NAME_ATT, DISPLAY_ITEMS_SERVICE);
121 this.short_service_info.appendChild(disp_service);
122
123 // set up short_service_info_ - for now just has name and type
124 Element num_service = this.doc.createElement(GSXML.SERVICE_ELEM);
125 num_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
126 num_service.setAttribute(GSXML.NAME_ATT, ITEM_NUM_SERVICE);
127 this.short_service_info.appendChild(num_service);
128
129 // set up short_service_info_ - for now just has name and type
130 Element delete_service = this.doc.createElement(GSXML.SERVICE_ELEM);
131 delete_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
132 delete_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEMS_SERVICE);
133 this.short_service_info.appendChild(delete_service);
134
135 // set up short_service_info_ - for now just has name and type
136 Element deleteone_service = this.doc.createElement(GSXML.SERVICE_ELEM);
137 deleteone_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
138 deleteone_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEM_SERVICE);
139 this.short_service_info.appendChild(deleteone_service);
140
141 // set up short_service_info_ - for now just has name and type
142 Element mail_service = this.doc.createElement(GSXML.SERVICE_ELEM);
143 mail_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
144 mail_service.setAttribute(GSXML.NAME_ATT, SEND_MAIL_SERVICE);
145 this.short_service_info.appendChild(mail_service);
146
147 return true;
148
149 }
150
151 /** returns a specific service description */
152 protected Element getServiceDescription(String service_id, String lang, String subset)
153 {
154
155 if (service_id.equals(ADD_ITEM_SERVICE))
156 {
157 Element add_service = this.doc.createElement(GSXML.SERVICE_ELEM);
158 add_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
159 add_service.setAttribute(GSXML.NAME_ATT, ADD_ITEM_SERVICE);
160 return add_service;
161 }
162 if (service_id.equals(DISPLAY_ITEMS_SERVICE))
163 {
164
165 Element disp_service = this.doc.createElement(GSXML.SERVICE_ELEM);
166 disp_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
167 disp_service.setAttribute(GSXML.NAME_ATT, DISPLAY_ITEMS_SERVICE);
168 return disp_service;
169 }
170
171 if (service_id.equals(ITEM_NUM_SERVICE))
172 {
173
174 Element num_service = this.doc.createElement(GSXML.SERVICE_ELEM);
175 num_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
176 num_service.setAttribute(GSXML.NAME_ATT, ITEM_NUM_SERVICE);
177 return num_service;
178 }
179
180 if (service_id.equals(DELETE_ITEMS_SERVICE))
181 {
182
183 Element del_service = this.doc.createElement(GSXML.SERVICE_ELEM);
184 del_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
185 del_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEMS_SERVICE);
186 return del_service;
187 }
188
189 if (service_id.equals(DELETE_ITEM_SERVICE))
190 {
191
192 Element delone_service = this.doc.createElement(GSXML.SERVICE_ELEM);
193 delone_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
194 delone_service.setAttribute(GSXML.NAME_ATT, DELETE_ITEM_SERVICE);
195 return delone_service;
196 }
197
198 if (service_id.equals(SEND_MAIL_SERVICE))
199 {
200
201 Element mail_service = this.doc.createElement(GSXML.SERVICE_ELEM);
202 mail_service.setAttribute(GSXML.TYPE_ATT, "gather"); // what??
203 mail_service.setAttribute(GSXML.NAME_ATT, SEND_MAIL_SERVICE);
204 return mail_service;
205 }
206
207 return null;
208 }
209
210 protected Element processAddItem(Element request)
211 {
212 Hashtable docsMap = updateDocMap(request);
213
214 // Create a new (empty) result message
215 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
216
217 // Get the parameters of the request
218 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
219 if (param_list == null)
220 {
221 logger.error("BerryBasket Error: AddItem request had no paramList.");
222 return result; // Return the empty result
223 }
224
225 HashMap params = GSXML.extractParams(param_list, false);
226
227 String item = (String) params.get("item");
228 String collection = "";
229 int pos = item.indexOf(":");
230 if (pos != -1)
231 {
232 collection = item.substring(0, pos);
233 item = item.substring(pos + 1);
234 }
235
236 if (docsMap.containsKey(collection))
237 {
238 Hashtable items = (Hashtable) docsMap.get(collection);
239 if (!items.containsKey(item))
240 {
241 Item newItem = generateItem(collection, item);
242 items.put(item, newItem);
243 result.appendChild(newItem.wrapIntoElement());
244 }
245 }
246 else
247 {
248 Hashtable items = new Hashtable();
249 Item newItem = generateItem(collection, item);
250 items.put(item, newItem);
251 docsMap.put(collection, items);
252 result.appendChild(newItem.wrapIntoElement());
253 }
254
255 return result;
256 }
257
258 private Item generateItem(String collection, String id)
259 {
260
261 Item item = new Item(collection, id);
262 String to = GSPath.appendLink(collection, "DocumentMetadataRetrieve");
263 ArrayList tmp = new ArrayList();
264 tmp.add(id);
265
266 UserContext userContext = new UserContext();
267 userContext.setLanguage("en");
268 userContext.setUserID("dumy");
269 Element response = getDocumentMetadata(to, userContext, tmp.iterator());
270 Element doc_node = (Element) response.getElementsByTagName(GSXML.DOC_NODE_ELEM).item(0);
271
272 String node_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
273 Element metadata_list = (Element) doc_node.getElementsByTagName(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER).item(0);
274
275 //assign title metadata if any
276 Element metadata = GSXML.getNamedElement(metadata_list, "metadata", "name", "Title");
277 if (metadata != null)
278 {
279 item.title = GSXML.getNodeText(metadata).trim();
280 }
281 //assign date metadata if any
282 metadata = GSXML.getNamedElement(metadata_list, "metadata", "name", "Date");
283 if (metadata != null)
284 {
285 item.date = GSXML.getNodeText(metadata).trim();
286 }
287
288 //assign root title metadata if any
289 metadata = GSXML.getNamedElement(metadata_list, "metadata", "name", "root_Title");
290 if (metadata != null)
291 {
292 String rootTitle = GSXML.getNodeText(metadata).trim();
293 if (!rootTitle.equals(item.title))
294 {
295 item.rootTitle = rootTitle;
296 }
297
298 }
299
300 return item;
301 }
302
303 protected Element processDeleteItems(Element request)
304 {
305 Hashtable docsMap = updateDocMap(request);
306
307 // Create a new (empty) result message
308 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
309
310 // Get the parameters of the request
311 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
312
313 if (param_list == null)
314 {
315 logger.error("BerryBasket Error: DeleteItem request had no paramList.");
316 return result; // Return the empty result
317 }
318
319 HashMap params = GSXML.extractParams(param_list, false);
320
321 String param = (String) params.get("items");
322
323 if (param == null)
324 return result;
325
326 String[] items = param.split("\\|");
327
328 for (int i = 0; i < items.length; i++)
329 {
330 String item = items[i];
331 if (item.trim().length() == 0)
332 continue;
333 String collection = "";
334 int pos = item.indexOf(":");
335 if (pos != -1)
336 {
337 collection = item.substring(0, pos);
338 item = item.substring(pos + 1);
339 }
340
341 if (docsMap.containsKey(collection))
342 {
343 Hashtable itemMap = (Hashtable) docsMap.get(collection);
344 if (itemMap.containsKey(item))
345 {
346 itemMap.remove(item);
347 }
348 if (itemMap.size() == 0)
349 {
350 docsMap.remove(collection);
351 }
352 }
353
354 }
355
356 return result;
357 }
358
359 protected Element processDeleteItem(Element request)
360 {
361 Hashtable docsMap = updateDocMap(request);
362
363 // Create a new (empty) result message
364 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
365
366 // Get the parameters of the request
367 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
368
369 if (param_list == null)
370 {
371 logger.error("BerryBasket Error: DeleteItem request had no paramList.");
372 return result; // Return the empty result
373 }
374
375 HashMap params = GSXML.extractParams(param_list, false);
376
377 String param = (String) params.get("item");
378
379 if (param == null)
380 return result;
381
382 String item = param;
383
384 String collection = "";
385 int pos = item.indexOf(":");
386
387 if (pos != -1)
388 {
389 collection = item.substring(0, pos);
390 item = item.substring(pos + 1);
391 }
392
393 if (docsMap.containsKey(collection))
394 {
395 Hashtable itemMap = (Hashtable) docsMap.get(collection);
396 if (itemMap.containsKey(item))
397 {
398 itemMap.remove(item);
399 }
400 if (itemMap.size() == 0)
401 {
402 docsMap.remove(collection);
403 }
404 }
405
406 return result;
407 }
408
409 protected Element processItemNum(Element request)
410 {
411 Hashtable docsMap = updateDocMap(request);
412
413 // Create a new (empty) result message
414 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
415
416 int size = 0;
417 String ids = "";
418 Iterator keys = docsMap.keySet().iterator();
419
420 while (keys.hasNext())
421 {
422 Hashtable items = (Hashtable) docsMap.get((String) keys.next());
423 size += items.size();
424 Iterator values = items.values().iterator();
425 while (values.hasNext())
426 {
427 Item item = (Item) values.next();
428 result.appendChild(item.wrapIntoElement());
429 }
430 }
431
432 Element selement = this.doc.createElement("size");
433 selement.setAttribute("value", size + "");
434 result.appendChild(selement);
435
436 return result;
437 }
438
439 private Element getDocumentMetadata(String to, UserContext userContext, Iterator ids)
440 {
441
442 // Build a request to obtain some document metadata
443 Element dm_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
444 Element dm_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
445 dm_message.appendChild(dm_request);
446
447 // Create a parameter list to specify the required metadata information
448 HashSet meta_names = new HashSet();
449 meta_names.add("Title"); // the default
450 meta_names.add("root_Title");
451 meta_names.add("Date");
452
453 Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
454
455 Element param = null;
456 Iterator i = meta_names.iterator();
457 while (i.hasNext())
458 {
459 String name = (String) i.next();
460 param = this.doc.createElement(GSXML.PARAM_ELEM);
461 param_list.appendChild(param);
462 param.setAttribute(GSXML.NAME_ATT, "metadata");
463 param.setAttribute(GSXML.VALUE_ATT, name);
464
465 }
466
467 dm_request.appendChild(param_list);
468
469 // create the doc node list for the metadata request
470 Element dm_doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
471 dm_request.appendChild(dm_doc_list);
472
473 while (ids.hasNext())
474 {
475 // Add the documentNode to the list
476 Element dm_doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
477 dm_doc_list.appendChild(dm_doc_node);
478 dm_doc_node.setAttribute(GSXML.NODE_ID_ATT, (String) ids.next());
479 }
480
481 return (Element) this.router.process(dm_message);
482
483 }
484
485 protected Element processDisplayList(Element request)
486 {
487 Hashtable docsMap = updateDocMap(request);
488
489 // Create a new (empty) result message
490 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
491
492 Iterator keys = docsMap.keySet().iterator();
493
494 while (keys.hasNext())
495 {
496 String collection = (String) keys.next();
497 Hashtable items = (Hashtable) docsMap.get(collection);
498 Iterator itemItr = items.values().iterator();
499
500 Element collectionNode = this.doc.createElement("berryList");
501 collectionNode.setAttribute("name", collection);
502 result.appendChild(collectionNode);
503
504 while (itemItr.hasNext())
505 {
506 Item item = (Item) itemItr.next();
507 Element itemElement = this.doc.createElement("item");
508
509 collectionNode.appendChild(itemElement);
510 itemElement.setAttribute("name", item.docid);
511 itemElement.setAttribute("collection", item.collection);
512 itemElement.setAttribute("title", item.title);
513 itemElement.setAttribute("date", item.date);
514 itemElement.setAttribute("root_title", item.rootTitle);
515 }
516 }
517
518 return result;
519
520 }
521
522 public Element processSendMail(Element request)
523 {
524 // Create a new (empty) result message
525 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
526
527 // Get the parameters of the request
528 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
529
530 if (param_list == null)
531 {
532 logger.error("BerryBasket Error: SendMail request had no paramList.");
533 return result; // Return the empty result
534 }
535
536 HashMap params = GSXML.extractParams(param_list, false);
537
538 String to = (String) params.get("address");
539 String subject = (String) params.get("subject");
540 String content = (String) params.get("content");
541 String cc = (String) params.get("cc");
542 String bcc = (String) params.get("bcc");
543
544 String mailhost = GlobalProperties.getProperty("mail.smtp.host");
545 username = GlobalProperties.getProperty("mail.smtp.username");
546 password = GlobalProperties.getProperty("mail.smtp.password");
547 String from = GlobalProperties.getProperty("mail.from");
548
549 String mailer = "msgsend";
550
551 try
552 {
553
554 Properties props = System.getProperties();
555
556 //Setup smtp host and from address
557 // XXX - could use Session.getTransport() and Transport.connect()
558 // XXX - assume we're using SMTP
559 if (mailhost != null && !mailhost.trim().equals(""))
560 {
561 props.put("mail.smtp.host", mailhost);
562 }
563 else
564 {
565 props.put("mail.smtp.host", "localhost");
566 }
567 if (from != null && !from.trim().equals(""))
568 {
569 props.put("mail.from", from);
570 }
571
572 //setup username and password to the smtp server
573 if (username == null || username.trim().equals(""))
574 username = "";
575 if (password == null || password.trim().equals(""))
576 password = "";
577 Authenticator auth = new Authenticator()
578 {
579 protected PasswordAuthentication getPasswordAuthentication()
580 {
581 return new PasswordAuthentication(username, password);
582 }
583 };
584
585 Session session = Session.getInstance(props, auth);
586
587 Message msg = new MimeMessage(session);
588 msg.setFrom();
589 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
590 if (cc != null)
591 {
592 msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc, false));
593 }
594 if (bcc != null)
595 {
596 msg.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bcc, false));
597 }
598 msg.setSubject(subject);
599 msg.setText(content.replaceAll("-------", "&"));
600 msg.setHeader("X-Mailer", mailer);
601 msg.setSentDate(new Date());
602
603 // send the thing off
604 Transport.send(msg);
605
606 logger.info("\nMail was sent successfully.");
607 result.appendChild(this.doc.createTextNode("Mail was sent successfully."));
608 }
609 catch (Exception e)
610 {
611 e.printStackTrace();
612 result.appendChild(this.doc.createTextNode(e.getMessage()));
613 }
614
615 return result;
616 }
617
618 protected class Item
619 {
620 public String collection;
621 public String docid;
622 public String title = "";
623 public String query = "";
624 public String date = "";
625 public String rootTitle = "";
626
627 public Item(String coll, String id)
628 {
629 this.collection = coll;
630 this.docid = id;
631 }
632
633 public boolean equals(Object o)
634 {
635 if (!(o instanceof Item))
636 {
637 return false;
638 }
639 Item item = (Item) o;
640 String id = collection + ":" + docid;
641 String idin = item.collection + ":" + item.docid;
642 return id.equals(idin);
643
644 }
645
646 public String toString()
647 {
648
649 return collection + ":" + docid + ":" + "[" + ((!rootTitle.equals("")) ? (rootTitle + ":") : "") + title + "]";
650 }
651
652 public Element wrapIntoElement()
653 {
654 Element itemElement = doc.createElement("item");
655 itemElement.setAttribute("name", docid);
656 itemElement.setAttribute("collection", collection);
657 itemElement.setAttribute("title", title);
658 itemElement.setAttribute("date", date);
659 itemElement.setAttribute("root_title", rootTitle);
660 return itemElement;
661 }
662 }
663
664 private class UserTimer extends Timer implements ActionListener
665 {
666 String id = "";
667
668 public UserTimer(int delay, String id)
669 {
670 super(delay, (ActionListener) null);
671 addActionListener(this);
672 this.id = id;
673 }
674
675 public void actionPerformed(ActionEvent e)
676 {
677 userMap.remove(id);
678 timerMap.remove(id);
679 stop();
680 }
681
682 }
683
684}
Note: See TracBrowser for help on using the repository browser.