source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/ProcessAction.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.1 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.util.Map;
13import java.util.Iterator;
14import java.io.File;
15import java.io.Serializable;
16
17public class ProcessAction extends Action
18{
19
20 /** process a request */
21 public Node process(Node message_node)
22 {
23 Element message = this.converter.nodeToElement(message_node);
24 Document doc = message.getOwnerDocument();
25
26 // the result
27 Element result = doc.createElement(GSXML.MESSAGE_ELEM);
28 Element page_response = doc.createElement(GSXML.RESPONSE_ELEM);
29 result.appendChild(page_response);
30
31 // assume only one request
32 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
33
34 // get the param list
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 String service_name = (String) params.get(GSParams.SERVICE);
38 String cluster_name = (String) params.get(GSParams.CLUSTER);
39 String response_only_p = (String) params.get(GSParams.RESPONSE_ONLY);
40 boolean response_only = false;
41 if (response_only_p != null)
42 {
43 response_only = (response_only_p.equals("1") ? true : false);
44 }
45 String request_type = (String) params.get(GSParams.REQUEST_TYPE);
46 UserContext userContext = new UserContext(request);
47 // what is carried out depends on the request_type
48 // if rt=d, then a describe request is done,
49 // is rt=r, a request and then a describe request is done
50 // if rt=s, a status request is done.
51
52 // if ro=1, then this calls for a process only page - we do the request
53 // (rt should be r or s) and just give the response straight back
54 // without any page processing
55
56 // where to send requests
57 String to;
58 if (cluster_name != null)
59 {
60
61 to = GSPath.appendLink(cluster_name, service_name);
62 }
63 else
64 {
65 to = service_name;
66 }
67
68 if (!request_type.equals("d"))
69 {
70 // if rt=s or rt=r, do the request
71
72 Element mr_query_message = doc.createElement(GSXML.MESSAGE_ELEM);
73 String request_type_att;
74 Element param_list = null;
75 if (request_type.equals("s"))
76 { // status
77 request_type_att = GSXML.REQUEST_TYPE_STATUS;
78 param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
79 Element param = doc.createElement(GSXML.PARAM_ELEM);
80 param.setAttribute(GSXML.NAME_ATT, GSParams.PROCESS_ID);
81 param.setAttribute(GSXML.VALUE_ATT, (String) params.get(GSParams.PROCESS_ID));
82 param_list.appendChild(param);
83 }
84 else
85 {
86 request_type_att = GSXML.REQUEST_TYPE_PROCESS;
87 // add in the service params - except the ones only used by the action
88 HashMap service_params = (HashMap) params.get("s1");
89 if (service_params != null)
90 {
91 param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
92 GSXML.addParametersToList(doc, param_list, service_params);
93 }
94
95 }
96 Element mr_query_request = GSXML.createBasicRequest(doc, request_type_att, to, userContext);
97 if (param_list != null)
98 {
99 mr_query_request.appendChild(param_list);
100 }
101 mr_query_message.appendChild(mr_query_request);
102
103 Element mr_query_response = (Element) this.mr.process(mr_query_message);
104 Element result_response = (Element) GSXML.getChildByTagName(mr_query_response, GSXML.RESPONSE_ELEM);
105
106 if (response_only)
107 {
108 // just send the reponse as is
109 return result_response;
110 }
111
112 // else append the contents of the response to the page - just the status elem for now
113 Element status = (Element) GSXML.getChildByTagName(result_response, GSXML.STATUS_ELEM);
114 page_response.appendChild(doc.importNode(status, true));
115 }
116
117 // another part of the page is the service description
118
119 // request the service info for the selected service - should be cached
120 Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
121 Element mr_info_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, to, userContext);
122 mr_info_message.appendChild(mr_info_request);
123 Element mr_info_response = (Element) this.mr.process(mr_info_message);
124
125 String path = GSXML.RESPONSE_ELEM;
126 path = GSPath.appendLink(path, GSXML.SERVICE_ELEM);
127 Element description = (Element) doc.importNode(GSXML.getNodeByPath(mr_info_response, path), true);
128
129 page_response.appendChild(description);
130
131 return result;
132 }
133
134 protected Element getServiceParamList(Element cgi_param_list)
135 {
136 Document doc = cgi_param_list.getOwnerDocument();
137
138 Element new_param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
139 Element param;
140 NodeList cgi_params = cgi_param_list.getChildNodes();
141 for (int i = 0; i < cgi_params.getLength(); i++)
142 {
143 Element p = (Element) cgi_params.item(i);
144 String name = p.getAttribute(GSXML.NAME_ATT);
145 if (name.equals(GSParams.SERVICE) || name.equals(GSParams.REQUEST_TYPE) || name.equals(GSParams.CLUSTER))
146 {
147 continue;
148 }
149 // else add it in to the list
150 new_param_list.appendChild(doc.importNode(p, true));
151 }
152 return new_param_list;
153 }
154}
Note: See TracBrowser for help on using the repository browser.