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

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

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

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