source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/ServiceModule.java@ 3222

Last change on this file since 3222 was 3222, checked in by kjdon, 22 years ago

Initial revision

  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1package org.greenstone.gsdl3.service;
2
3// greenstone classes
4import org.greenstone.gsdl3.util.*;
5import org.greenstone.gsdl3.core.*;
6
7// xml classes
8import org.w3c.dom.Node;
9import org.w3c.dom.Element;
10import org.w3c.dom.Document;
11import org.xml.sax.InputSource;
12import javax.xml.parsers.*;
13import org.apache.xpath.XPathAPI;
14
15// general java classes
16import java.io.Reader;
17import java.io.StringReader;
18import java.io.File;
19import java.util.HashMap;
20
21/**
22 * ServiceModule - abstract base class
23 *
24 * A ServiceModule provides Services to a collection/system.
25 * It may provide more than one Service. for eg
26 * MGGDBMServiceModule may support "DocRetrieve", "TextQuery", "MetadataRetrieve" services
27 *
28 */
29public abstract class ServiceModule
30 implements ModuleInterface
31{
32 /** the absolute address of the site home */
33 protected String site_home_ =null;
34 /** the name of the collection directory that this service belongs to -
35 if any */
36 protected String collection_name_ = null;
37
38 /** some services can talk back to the message router */
39 protected ModuleInterface router_ = null;
40
41 /** a converter class to create Documents etc */
42 protected XMLConverter converter_ = null;
43
44 /** XML element for describe requests - the container doc */
45 protected Document doc_ = null;
46
47 /** XML element for describe requests - list of supported services */
48 protected Element short_service_info_ = null;
49
50 /** XML element for describe requests - map of service name to full
51 description */
52 protected HashMap service_info_map_ = null;
53
54 public void setCollectionName(String coll_name) {
55 collection_name_ = coll_name;
56 }
57
58 public void setSiteHome(String site_home) {
59 site_home_ = site_home;
60 }
61
62 public void setMessageRouter(ModuleInterface m) {
63 router_ = m;
64 }
65
66 public ServiceModule() {
67 converter_ = new XMLConverter();
68 doc_ = converter_.newDOM();
69 short_service_info_ = doc_.createElement("serviceList");
70 service_info_map_ = new HashMap();
71 }
72
73 /**
74 * Configure the object. - default method for service modules
75 *
76 * reads either collection (if a collection name has been set), or system
77 * configuration file, and configures itself
78 * this calls configure(Element) with the XML element node from the config
79 * file.
80 * configure(Element) should be used if the config file has already been
81 * parsed. This method will work with any subclass.
82 *
83 * @return true if configure successful, false otherwise.
84 */
85 public boolean configure(){
86
87 if (site_home_==null) {
88 System.err.println("setSiteHome() must be called before configure()");
89 return false;
90 }
91
92 File config_file=null;
93 if (collection_name_ !=null) {
94
95 config_file = GSFile.collectionBuildConfigFile(site_home_, collection_name_);
96 }
97 else {
98 config_file = GSFile.siteConfigFile(site_home_);
99 }
100
101 if (config_file.exists() ) {
102
103 Document doc = converter_.getDOM(config_file);
104
105 try {
106 // get the service list and look for own service
107 // Note: XPathAPI is slow apparently
108 String xpath = "//ServiceModule[@name='"+this.getClass().getName()+"']";
109 System.out.println("xpath="+xpath);
110 Node n = XPathAPI.selectSingleNode(doc, xpath);
111 if (n !=null) {
112 return this.configure((Element)n);
113 }
114 } catch (Exception e) {
115 System.err.println("ServiceModule configure exception: "+e.getMessage());
116 return false;
117 }
118 }
119 System.err.println("ServiceModule error: unable to configure ServiceModule " + this.getClass().getName() );
120 return false;
121
122
123 }
124
125 /** The configure method that does the real work
126 *
127 * @param info the XML node <serviceModule name="XXX"/> with name equal
128 * to the class name (of the subclass)
129 *
130 * must initialise short_service_info_ and service_info_map_
131 * @return true if configured ok
132 * must be implemented in subclasses
133 */
134 abstract public boolean configure(Element info);
135
136 /**
137 * Process an XML document - convenience method that uses Strings rather than Nodes. just calls process(Node).
138 *
139 * @param xml_in the Document to process - a string
140 * @return the resultant document as a string - contains any error messages
141 * @see String
142 */
143 public String process(String xml_in) {
144
145 Document doc = converter_.getDOM(xml_in);
146
147 Node res = process(doc);
148 return converter_.getString(res);
149
150 }
151
152 /** process an XML request in DOM form
153 *
154 * @param xml_in the Element node containing the request
155 * should be <request> or maybe <multipleRequest>?? if more than one
156 * request coming at once
157 * @return an Element with the result XML
158 * @see Element
159 */
160 public Node process(Node xml_in) {
161
162 // check if request is Element or Document - we want to work
163 // with an Element
164 Element request=null;
165
166 short node_type = xml_in.getNodeType();
167 if (node_type == Node.DOCUMENT_NODE) {
168 request = ((Document)xml_in).getDocumentElement();
169 } else if (node_type == Node.ELEMENT_NODE) {
170 request = (Element)xml_in;
171 } else {
172 System.err.println("ServiceModule:process error: input should be an Element or Document!");
173 }
174
175 String req = request.getNodeName();
176 if (!req.equals("request")) {
177 System.err.println("ServiceModule:process - should have been passed a request element, instead was given a "+req+" element!");
178 return null;
179 }
180
181 String type = request.getAttribute("type");
182 String to = GSPath.getFirstLink(request.getAttribute("to"));
183 String info = request.getAttribute("info");
184 if (type.equals("describe")) { // process here, not by subclass
185 if (to.equals("")) { // to="", look at info
186 if (info.equals("serviceList")) {
187 return short_service_info_;
188 }
189 // else error in info field
190 System.err.println("ServiceModule describe request: error in 'info' field, info='"+info+"'.");
191 return null;
192 } else { // describe a particular service
193 if (service_info_map_.containsKey(to)) {
194 return (Element)service_info_map_.get(to);
195 }
196 // else error in to field
197 System.err.println("ServiceModule describe request: error in 'to' field, to='"+to+"'.");
198 return null;
199 }
200 } else { // other type of request, must be processed by the subclass -
201 // send to the service method
202 if (service_info_map_.containsKey(to)) {
203 return processService(to, request);
204 }
205 else {
206 // else error in to field
207 System.err.println("ServiceModule describe request: error in 'to' field, to='"+to+"'.");
208 return null;
209 }
210 }
211
212 }
213
214 /** process method for specific services - must be implemented by all
215 * subclasses
216 * should implement all services supported by the serviceModule except
217 * for describe, which is implemented by this base class
218 *
219 */
220 abstract protected Element processService(String service, Element request);
221
222
223}
Note: See TracBrowser for help on using the repository browser.