source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/AppletAction.java@ 28382

Last change on this file since 28382 was 28382, checked in by davidb, 11 years ago

Elimination of the 'this.doc' field from the Action baseclass and the subclasses that rely on it. For Greenstone3 purposes it is unsafe to create this object in the constructor to the action and then store it for other methods to access. This is because the Greenstone 3 (and in particular calls to 'process' operate in a multi-threaded context, that is managed by the Servlet server (e.g. Tomcat by default). Calls to DOM methods are not guaranteed to be thread safe, this became apparent when we started looking in to an exception that was being thrown, and centred around use of the DOM method 'item(i)'. The change this commit makes is to remove 'this.doc' being stored as a field. A document is now created in the top level of a call to 'process()' and when a DOM reference is needed in a subsequent method an Element variable (typically passed in as a parameter to the method) is used (through 'Document doc = element.getOwnerDocument()') to gain access to the DOM

  • Property svn:keywords set to Author Date Id Revision
File size: 5.0 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import org.greenstone.gsdl3.core.ModuleInterface;
4import org.greenstone.gsdl3.util.*;
5// XML classes
6import org.w3c.dom.Node;
7import org.w3c.dom.NodeList;
8import org.w3c.dom.Document;
9import org.w3c.dom.Element;
10
11import java.util.HashMap;
12import java.io.File;
13import java.io.Serializable;
14
15import org.apache.log4j.*;
16
17/** action class for handling applets */
18public class AppletAction extends Action
19{
20
21 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.AppletAction.class.getName());
22
23 public Node process(Node message_node)
24 {
25
26 Element message = this.converter.nodeToElement(message_node);
27 Document doc = message.getOwnerDocument();
28
29 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
30 Element result = doc.createElement(GSXML.MESSAGE_ELEM);
31 Element page_response = doc.createElement(GSXML.RESPONSE_ELEM);
32 result.appendChild(page_response);
33
34 // get the collection and service params
35 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
36 HashMap<String, Serializable> params = GSXML.extractParams(cgi_param_list, false);
37
38 // request_type is display (d) or request (r)
39 String request_type = (String) params.get(GSParams.REQUEST_TYPE);
40 if (!request_type.equals("d") && !request_type.equals("r"))
41 {
42 logger.error("AppletAction Error: the rt arg should be either d or r, instead it was " + request_type + "!");
43 return result;
44 }
45
46 String collection = (String) params.get(GSParams.COLLECTION);
47 boolean coll_specified = true;
48 String service_name = (String) params.get(GSParams.SERVICE);
49 UserContext userContext = new UserContext(request);
50 String to = null;
51 if (collection == null || collection.equals(""))
52 {
53 coll_specified = false;
54 to = service_name;
55 }
56 else
57 {
58 to = GSPath.appendLink(collection, service_name);
59 }
60
61 if (request_type.equals("r"))
62 {
63 // we are processing stuff for the applet send a message to the service, type="query", and take out the something element, and return that as our result - the applet must take xml
64
65 Element mr_message = doc.createElement(GSXML.MESSAGE_ELEM);
66 Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
67 mr_message.appendChild(mr_request);
68 // just append all the params for now - should filter out unneeded ones
69 mr_request.appendChild(doc.importNode(cgi_param_list, true));
70
71 // process the request
72 Element mr_response = (Element) this.mr.process(mr_message);
73 // get the applet data out and pass it back as is.
74 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.APPLET_DATA_ELEM);
75 Element applet_info = GSXML.getFirstElementChild(GSXML.getNodeByPath(mr_response, path));
76 //Element applet_info = (Element)GSXML.getNodeByPath(mr_response, path).getFirstChild();
77 return applet_info;
78
79 }
80
81 // get the applet description, and the collection info if a collection is specified
82
83 Element mr_message = doc.createElement(GSXML.MESSAGE_ELEM);
84 Element applet_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, to, userContext);
85 mr_message.appendChild(applet_request);
86
87 Element mr_response = (Element) this.mr.process(mr_message);
88
89 // add in the applet info
90 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.SERVICE_ELEM);
91 //path = GSPath.appendLink(path, GSXML.APPLET_ELEM);
92 Element service_elem = (Element) doc.importNode(GSXML.getNodeByPath(mr_response, path), true);
93 Element applet_elem = (Element) GSXML.getChildByTagName(service_elem, GSXML.APPLET_ELEM);
94 // must handle any params that have values that are not
95 // necessarily known by the service
96 // should this be done here or by web receptionist??
97 // cant really have an applet without web?
98 editLocalParams(applet_elem, (String) config_params.get(GSConstants.LIBRARY_NAME), collection);
99 page_response.appendChild(service_elem);
100
101 //append site metadata
102 addSiteMetadata(page_response, userContext);
103 //addInterfaceOptions(page_response);
104 return result;
105
106 }
107
108 /**
109 * this method looks through the PARAMs of the applet description for
110 * 'library' or 'collection'. If found, the params are set to the
111 * appropriate values should this be done here or in the receptionist?
112 */
113 protected void editLocalParams(Element description, String library_name, String full_collection_name)
114 {
115
116 Node child = description.getFirstChild();
117 while (child != null)
118 {
119 if (child.getNodeType() == Node.ELEMENT_NODE)
120 {
121 String param = child.getNodeName();
122 if (param.equals("PARAM") || param.equals("param"))
123 {
124 String name = ((Element) child).getAttribute("NAME");
125 if (name == null || name.equals(""))
126 {
127 // somethings wrong!!
128 }
129 else if (name.equals("library"))
130 {
131 ((Element) child).setAttribute("VALUE", library_name);
132 }
133 else if (name.equals("collection"))
134 {
135 ((Element) child).setAttribute("VALUE", full_collection_name);
136 }
137
138 }
139 }
140 child = child.getNextSibling();
141 }
142 }
143
144}
Note: See TracBrowser for help on using the repository browser.