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

Last change on this file since 24221 was 24221, checked in by sjm84, 13 years ago

Added more functionality to ArchiveRetrieve, added an additonal parameter to printXMLNode in GSXML that controls whether text nodes are to be printed or not and also made the infodb type of collections more easily accessible

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