source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java@ 29731

Last change on this file since 29731 was 29556, checked in by kjdon, 9 years ago

added in a getTextString method - to look up a string from the dictionary. copied from ServiceRack, but without the use of a collection class loader

  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Iterator;
6
7import org.apache.log4j.Logger;
8import org.greenstone.gsdl3.core.ModuleInterface;
9import org.greenstone.gsdl3.util.Dictionary;
10import org.greenstone.gsdl3.util.GSConstants;
11import org.greenstone.gsdl3.util.GSParams;
12import org.greenstone.gsdl3.util.GSXML;
13import org.greenstone.gsdl3.util.GSXSLT;
14import org.greenstone.gsdl3.util.UserContext;
15import org.greenstone.gsdl3.util.XMLConverter;
16import org.w3c.dom.Document;
17import org.w3c.dom.Element;
18import org.w3c.dom.Node;
19import org.w3c.dom.NodeList;
20
21/** base class for Actions */
22abstract public class Action
23{
24
25 /** the system set up variables */
26 protected HashMap<String, Object> config_params = null;
27
28
29 /** a converter class to parse XML and create Docs */
30 protected XMLConverter converter = null;
31 /**
32 * a reference to the message router that it must talk to to get info. it
33 * may be a communicator acting as a proxy, but it doesn't care about that
34 */
35 protected ModuleInterface mr = null;
36
37 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.Action.class.getName());
38
39 public Action()
40 {
41 this.converter = new XMLConverter();
42 }
43
44 /** the config variables must be set before configure is called */
45 public void setConfigParams(HashMap<String, Object> params)
46 {
47 this.config_params = params;
48 }
49
50 /** sets the message router */
51 public void setMessageRouter(ModuleInterface m)
52 {
53 this.mr = m;
54 }
55
56 public boolean configure()
57 {
58 // does nothing yet
59 return true;
60 }
61
62 /**
63 * process takes an xml representation of cgi args and returns the page of
64 * results - may be in html/xml/other depending on the output att of the
65 * request
66 */
67 public String process(String xml_in)
68 {
69
70 Document message_doc = this.converter.getDOM(xml_in);
71 if (message_doc == null)
72 {
73 logger.error("Couldn't parse request");
74 logger.error(xml_in);
75 return null;
76 }
77 Node result = process(message_doc);
78 return this.converter.getString(result);
79 }
80
81 /** the main process method - must be implemented in subclass */
82 abstract public Node process(Node xml_in);
83
84 /**
85 * tell the param class what its arguments are if an action has its own
86 * arguments, this should add them to the params object - particularly
87 * important for args that should not be saved
88 */
89 public boolean addActionParameters(GSParams params)
90 {
91 return true;
92 }
93
94 protected void getRequiredMetadataNames(Element format, HashSet<String> meta_names)
95 {
96 extractMetadataNames(format, meta_names);
97 addLinkMetadataNames(format, meta_names);
98 }
99
100 // should change to metadataList?? and use attributes for select rather than
101 // prepending parent_ etc
102 protected void extractMetadataNames(Element format, HashSet<String> meta_names)
103 {
104 NodeList metadata_nodes = format.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "metadata"); // gsf:metadata
105 for (int i = 0; i < metadata_nodes.getLength(); i++)
106 {
107 Element elem = (Element) metadata_nodes.item(i);
108 String full_name = elem.getAttribute("name");
109 String select = elem.getAttribute("select");
110
111 String []names = full_name.split(",");
112 for(int j=0; j<names.length; j++) {
113
114 String name = names[j];
115 if (!select.equals(""))
116 {
117 name = select + GSConstants.META_RELATION_SEP + name;
118 }
119 meta_names.add(name);
120 }
121 }
122
123 NodeList foreach_metadata_nodes = format.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "foreach-metadata"); // gsf:foreach-metadata
124 for (int i = 0; i < foreach_metadata_nodes.getLength(); i++)
125 {
126 Element elem = (Element) foreach_metadata_nodes.item(i);
127 String name = elem.getAttribute("name");
128 String select = elem.getAttribute("select");
129
130 if (!select.equals(""))
131 {
132 name = select + GSConstants.META_RELATION_SEP + name;
133 }
134 meta_names.add(name);
135 }
136 }
137
138 protected void addLinkMetadataNames(Element format, HashSet<String> meta_names)
139 {
140 // The XSL tranform for
141 // gsf:link type="source"
142 // makes use of 'assocfilepath' so need to make sure it's asked for
143
144 boolean getEquivLinkMeta = false;
145
146 NodeList link_nodes = format.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "link");
147 for (int i = 0; i < link_nodes.getLength(); i++)
148 {
149 Element elem = (Element) link_nodes.item(i);
150 String type = elem.getAttribute("type");
151 if (type.equals("source"))
152 {
153 meta_names.add("assocfilepath");
154 meta_names.add("srclinkFile");
155 }
156 else if (type.equals("web"))
157 {
158 meta_names.add("weblink");
159 meta_names.add("webicon");
160 meta_names.add("/weblink");
161 }
162 else if (type.equals("equivdoc"))
163 {
164 getEquivLinkMeta = true;
165 }
166 }
167
168 // get all the metadata necessary for when the user has used "gsf:equivlink"
169 // so that we can build up the equivlink from the metadata components it needs
170 link_nodes = format.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "equivlinkgs3");
171 if (getEquivLinkMeta || link_nodes.getLength() > 0)
172 {
173 String[] equivlink_metanames = { "equivDocIcon", "equivDocLink", "/equivDocLink" };
174
175 for (int i = 0; i < equivlink_metanames.length; i++)
176 {
177 StringBuffer metadata = new StringBuffer();
178 metadata.append("all"); // this means the attr multiple = true;
179 metadata.append(GSConstants.META_RELATION_SEP);
180
181 metadata.append(GSConstants.META_SEPARATOR_SEP);
182 metadata.append(','); // attr separator = ","
183 metadata.append(GSConstants.META_SEPARATOR_SEP);
184 metadata.append(GSConstants.META_RELATION_SEP);
185
186 // the name of the metadata we're retrieving
187 metadata.append(equivlink_metanames[i]);
188 meta_names.add(metadata.toString());
189 }
190 }
191
192 if (format.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "image").getLength() > 0)
193 {
194 meta_names.add("Thumb");
195 meta_names.add("Screen");
196 meta_names.add("SourceFile");
197 }
198 }
199
200 protected Element createMetadataParamList(Document doc, HashSet<String> metadata_names)
201 {
202 Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
203
204 Element param = null;
205 Iterator<String> i = metadata_names.iterator();
206 while (i.hasNext())
207 {
208 String name = i.next();
209 param = doc.createElement(GSXML.PARAM_ELEM);
210 param_list.appendChild(param);
211 param.setAttribute(GSXML.NAME_ATT, "metadata");
212 param.setAttribute(GSXML.VALUE_ATT, name);
213
214 }
215 return param_list;
216 }
217
218 protected boolean processErrorElements(Element message, Element page)
219 {
220 NodeList error_nodes = message.getElementsByTagName(GSXML.ERROR_ELEM);
221 if (error_nodes.getLength() == 0)
222 {
223 return false;
224 }
225 Document owner = page.getOwnerDocument();
226 for (int i = 0; i < error_nodes.getLength(); i++)
227 {
228 page.appendChild(owner.importNode(error_nodes.item(i), true));
229 }
230 return true;
231 }
232
233 /**
234 * Takes an XML element and adds the metadata of the current site to it.
235 * Useful for adding the current site's metadata to a response before
236 * sending it
237 *
238 * @param element
239 * the element to add site metadata to
240 * @param lang
241 * the current language
242 * @param uid
243 * the current user id
244 */
245 protected void addSiteMetadata(Element element, UserContext userContext)
246 {
247 Document doc = element.getOwnerDocument();
248
249 //ADD SITE METADATA
250 Element metadata_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
251 //create a hashmap of params
252 HashMap subset_params = new HashMap(1);
253 subset_params.put(GSXML.SUBSET_PARAM, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
254 //create the element to put the params in
255 Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
256 //put them in
257 GSXML.addParametersToList(param_list, subset_params);
258 metadata_request.appendChild(param_list);
259 //create the message
260 Element metadata_message = doc.createElement(GSXML.MESSAGE_ELEM);
261 metadata_message.appendChild(metadata_request);
262 //get response
263 Element metadata_response_message = (Element) this.mr.process(metadata_message);
264 //drill down to response
265 Element metadata_response = (Element) GSXML.getChildByTagName(metadata_response_message, GSXML.RESPONSE_ELEM);
266 //merge in metadata
267 GSXML.mergeMetadataLists(element, metadata_response);
268 }
269
270 protected void addInterfaceOptions(Element elem)
271 {
272 Document doc = elem.getOwnerDocument();
273
274 Element documentOptionList = doc.createElement("interfaceOptions");
275 for (Object key : this.config_params.keySet())
276 {
277 Element option = doc.createElement("option");
278 option.setAttribute(GSXML.NAME_ATT, (String) key);
279 option.setAttribute(GSXML.VALUE_ATT, this.config_params.get(key).toString());
280 documentOptionList.appendChild(option);
281 }
282 elem.appendChild(elem.getOwnerDocument().importNode(documentOptionList, true));
283 }
284
285 protected Element getFormatInfo(String to, UserContext userContext)
286 {
287 // Eclipse call hierarchy shows the element returned from this method is
288 // subsequently used in a 'importNode'. For this reason it is safe here
289 // for call up our own document DOM.
290 //
291 // If this pattern changes for any reason, then the DOM will need to be
292 // passed in as a parameter
293
294 Document doc = XMLConverter.newDOM();
295
296 Element mr_format_message = doc.createElement(GSXML.MESSAGE_ELEM);
297 Element mr_format_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_FORMAT, to, userContext);
298 mr_format_message.appendChild(mr_format_request);
299
300 // process the message
301 Element mr_response_message = (Element) this.mr.process(mr_format_message);
302 // the response
303
304 Element format_response = (Element) GSXML.getChildByTagName(mr_response_message, GSXML.RESPONSE_ELEM);
305
306 Element format_elem = (Element) GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
307 if (format_elem != null)
308 {
309 Element global_format_elem = (Element) GSXML.getChildByTagName(format_response, GSXML.GLOBAL_FORMAT_ELEM);
310 if (global_format_elem != null)
311 {
312 GSXSLT.mergeFormatElements(format_elem, global_format_elem, false);
313 }
314 }
315 return format_elem;
316 }
317
318 protected String getTextString(String key, String lang, String dictionary, String[] args)
319 {
320 logger.error("lang = "+lang);
321 if (dictionary != null)
322 {
323 // just try the one specified dictionary
324 Dictionary dict = new Dictionary(dictionary, lang);
325 String result = dict.get(key, args);
326 if (result == null)
327 { // not found
328 return "_" + key + "_";
329 }
330 return result;
331 }
332
333 // otherwise we try class names for dictionary names
334 String class_name = this.getClass().getName();
335 class_name = class_name.substring(class_name.lastIndexOf('.') + 1);
336 Dictionary dict = new Dictionary(class_name, lang);
337 String result = dict.get(key, args);
338 if (result != null)
339 {
340 return result;
341 }
342
343 // we have to try super classes
344 Class c = this.getClass().getSuperclass();
345 while (result == null && c != null)
346 {
347 class_name = c.getName();
348 class_name = class_name.substring(class_name.lastIndexOf('.') + 1);
349 if (class_name.equals("ServiceRack"))
350 {
351 // this is as far as we go
352 break;
353 }
354 dict = new Dictionary(class_name, lang);
355 result = dict.get(key, args);
356 c = c.getSuperclass();
357 }
358 if (result == null)
359 {
360 return "_" + key + "_";
361 }
362 return result;
363
364 }
365
366}
Note: See TracBrowser for help on using the repository browser.