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

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

Reformatting this file ahead of some changes

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