source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/ServicesImpl.java@ 3584

Last change on this file since 3584 was 3584, checked in by kjdon, 21 years ago

removed a couple of unnecessary printlns

  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/*
2 * ServicesImpl.java
3 * Copyright (C) 2002 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 */
19package org.greenstone.gsdl3.service;
20
21// greenstone classes
22import org.greenstone.gsdl3.util.*;
23import org.greenstone.gsdl3.core.*;
24
25// xml classes
26import org.w3c.dom.Node;
27import org.w3c.dom.NodeList;
28import org.w3c.dom.Element;
29import org.w3c.dom.Document;
30import org.xml.sax.InputSource;
31import javax.xml.parsers.*;
32import org.apache.xpath.XPathAPI;
33
34// general java classes
35import java.io.Reader;
36import java.io.StringReader;
37import java.io.File;
38import java.util.HashMap;
39
40import java.util.ResourceBundle;
41import java.util.Locale;
42
43/**
44 * ServicesImpl - abstract base class
45 *
46 * A ServicesImpl implements some Service modules -
47 * It may provide more than one Service. for eg
48 * MGGDBMServicesImpl may support "DocRetrieve", "TextQuery", "MetadataRetrieve" services
49 *
50 * @author <a href="mailto:[email protected]">Katherine Don</a>
51 * @version $Revision: 3584 $
52 */
53public abstract class ServicesImpl
54 implements ModuleInterface
55{
56
57
58 /** the absolute address of the site home */
59 protected String site_home_ =null;
60 /** the name of the cluster that this service belongs to -
61 if any */
62 protected String cluster_name_ = null;
63
64 /** some services can talk back to the message router */
65 protected ModuleInterface router_ = null;
66
67 /** a converter class to create Documents etc */
68 protected XMLConverter converter_ = null;
69
70 /** XML element for describe requests - the container doc */
71 protected Document doc_ = null;
72
73 /** XML element for describe requests - list of supported services */
74 protected Element short_service_info_ = null;
75
76 /** XML element for describe requests - map of service name to full
77 description */
78 protected HashMap service_info_map_ = null;
79
80 /** sets the cluster name */
81 public void setClusterName(String cluster_name) {
82 cluster_name_ = cluster_name;
83 }
84 /** sets the collect name */
85 public void setCollectionName(String coll_name) {
86 setClusterName(coll_name);
87 }
88
89 /** sets the site home */
90 public void setSiteHome(String site_home) {
91 site_home_ = site_home;
92 }
93
94 /** sets the message router */
95 public void setMessageRouter(ModuleInterface m) {
96 router_ = m;
97 }
98
99 /** the no-args constructor */
100 public ServicesImpl() {
101 converter_ = new XMLConverter();
102 doc_ = converter_.newDOM();
103 short_service_info_ = doc_.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
104 service_info_map_ = new HashMap();
105 }
106
107
108 /** configure the service module
109 *
110 * @param info the XML node <servicesImpl name="XXX"/> with name equal
111 * to the class name (of the subclass)
112 *
113 * must initialise short_service_info_ and service_info_map_
114 * @return true if configured ok
115 * must be implemented in subclasses
116 */
117 abstract public boolean configure(Element info);
118
119 /**
120 * Process an XML document - convenience method that uses Strings rather than Nodes. just calls process(Node).
121 *
122 * @param xml_in the Document to process - a string
123 * @return the resultant document as a string - contains any error messages
124 * @see String
125 */
126 public String process(String xml_in) {
127
128 Document doc = converter_.getDOM(xml_in);
129
130 Element res = process(doc.getDocumentElement());
131 return converter_.getString(res);
132
133 }
134
135 /** process an XML request in DOM form
136 *
137 * @param xml_in the Element node containing the request
138 * should be <message>
139 * @return an Element with the result XML
140 * @see Element
141 */
142 public Element process(Element message) {
143
144 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
145 Document mess_doc = message.getOwnerDocument();
146 Element mainResult = doc_.createElement(GSXML.MESSAGE_ELEM);
147 if (requests.getLength()==0) {
148 // no requests
149 return mainResult; // for now
150 }
151
152 for (int i=0; i<requests.getLength(); i++) {
153 Element request = (Element)requests.item(i);
154
155
156 String type = request.getAttribute(GSXML.TYPE_ATT);
157 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
158 Element response = processDescribe(request);
159 if (response !=null) {
160 mainResult.appendChild(doc_.importNode(response, true));
161 }
162
163 } else {
164 // other type of request, must be processed by the subclass -
165 // send to the service method
166
167 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
168 if (service_info_map_.containsKey(to)) {
169 Element response = processService(to, request);
170 if (response !=null) {
171 mainResult.appendChild(doc_.importNode(response, true));
172 }
173 } else {
174 // else error in to field
175 System.err.println("ServicesImpl describe request: error in 'to' field, to='"+to+"'.");
176 return null;
177 }
178 }
179 } // for each request
180
181 return mainResult;
182
183 }
184
185 /** process method for describe requests
186 */
187 protected Element processDescribe(Element request) {
188
189 Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
190 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
191
192 String lang = request.getAttribute(GSXML.LANG_ATT);
193 String info = request.getAttribute(GSXML.INFO_ATT);
194 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT));
195
196 if (to.equals("")) { // to="", look at info
197 if (info.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
198 //response.appendChild(short_service_info_);
199 response.appendChild(getServiceList(lang));
200 return response;
201 }
202 // else error in info field
203 System.err.println("ServicesImpl describe request: error in 'info' field, info='"+info+"'.");
204 return null;
205 }
206
207 // describe a particular service
208
209 if (service_info_map_.containsKey(to)) {
210 response.appendChild(getServiceDescription(to, lang));//(Element)service_info_map_.get(to));
211 return response;
212 }
213 // else error in to field
214 System.err.println("ServicesImpl describe request: error in 'to' field, to='"+to+"'.");
215 return null;
216
217 }
218 /** process method for specific services - must be implemented by all
219 * subclasses
220 * should implement all services supported by the servicesImpl except
221 * for describe, which is implemented by this base class
222 *
223 */
224 abstract protected Element processService(String service, Element request);
225
226 // the following two should be overwritten for info with any language stuff in it
227 /** returns the service list for the subclass */
228 protected Element getServiceList(String lang) {
229 // for now, it is static and there is no lang stuff
230 return short_service_info_;
231 }
232
233 /** returns a specific service description */
234 protected Element getServiceDescription(String service, String lang) {
235 Element descript = (Element)((Element)service_info_map_.get(service)).cloneNode(true);
236 // for now, create it on the fly - look at caching it later
237 Element display = createServiceDisplay(service, lang);
238 addServiceDisplay(descript, display);
239 return descript;
240 }
241
242 /** adds the display element into the description - appends to the root for now, but may do something fancy later */
243 protected boolean addServiceDisplay(Element descript, Element display) {
244 if (descript.getOwnerDocument() != display.getOwnerDocument()) {
245 display = (Element)descript.getOwnerDocument().importNode(display, true);
246 }
247 descript.appendChild(display);
248 return true;
249 }
250 /** creates a display element containing all the text strings needed to display the service page, in the language specified */
251 abstract protected Element createServiceDisplay(String service, String lang);
252 /** overloaded version for no args case */
253 protected String getTextString(String key, String lang) {
254 return getTextString(key, null, lang);
255 }
256 /** getTextString - retrieves a language specific text string for the given
257key and locale
258 */
259 protected String getTextString(String key, String[] args, String lang) {
260
261 String class_name = getClass().getName();
262 class_name = class_name.substring(class_name.lastIndexOf('.')+1);
263
264 Dictionary dict = new Dictionary(class_name, lang);
265 String result = dict.get(key, args);
266 if (result == null) { // not found
267 return "_"+key+"_";
268 }
269 return result;
270 }
271}
Note: See TracBrowser for help on using the repository browser.