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

Last change on this file since 30820 was 30820, checked in by kjdon, 8 years ago

don't add empty root title

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