source: other-projects/trunk/gs3-webservices-democlient/src/GS3DemoClient/org/greenstone/gs3services/AdminSOAPServer.java@ 15222

Last change on this file since 15222 was 15222, checked in by ak19, 16 years ago

Greenstone3 web services demo-clientadded to GS3's other-projects

File size: 15.0 KB
Line 
1package org.greenstone.gs3services;
2
3import java.io.File;
4import java.io.InputStream;
5import java.util.Enumeration;
6import java.util.Properties;
7
8import org.apache.log4j.Logger;
9import org.greenstone.gsdl3.core.MessageRouter;
10import org.greenstone.gsdl3.util.GSFile;
11import org.greenstone.gsdl3.util.GSXML;
12import org.greenstone.gsdl3.util.GlobalProperties;
13import org.greenstone.gsdl3.util.XMLConverter;
14import org.w3c.dom.Document;
15import org.w3c.dom.Element;
16
17/**
18 * A beginning to the AdminSOAPServer class which will contain management/admin
19 * related web services such as adding new documents, creating, building and
20 * importing collections and configuring Greenstone modules.
21 *
22 * NOTE: to run this class, the folder containing this web service class'
23 * properties helpFile should be on the classpath.
24*/
25public class AdminSOAPServer {
26 /** The Logger for this class */
27 private static Logger LOG = Logger.getLogger(AdminSOAPServer.class);
28
29 /** Error message loading helpFile. Remains at "" if everything is fine */
30 protected static String helpErrormessage = "";
31 /** Properties map with mappings from methodname to help
32 * description string */
33 protected static Properties properties;
34 /** The help properties file describing the web service operations */
35 protected static String helpFile = "AdminWebServicesHelp.properties";
36
37 // static code block to initialise the help Properties from the helpFile
38 static {
39 properties = new Properties();
40 // load the properties file from a location with respect to the
41 // the Web Service .class file
42 InputStream input = null;
43 try {
44 // load the properties file from a location with respect to the
45 // the Web Service .class file
46 input = AdminSOAPServer.class.getClassLoader().getResourceAsStream(
47 helpFile);
48 if(input == null) {
49 helpErrormessage = "Cannot find file " + helpFile + " to load.";
50 LOG.warn(helpErrormessage);
51 } else {
52 properties.load(input);
53 input.close();
54 }
55 } catch(Exception e) {
56 helpErrormessage = "Exception loading properties from help file "
57 + helpFile + "\n" + e.getMessage();
58 LOG.warn("Exception loading properties from help file "
59 + helpFile + "\n" + e.getMessage());
60 }
61 }
62
63 /** site_name the MessageRouter works with, here set to "localsite" */
64 protected String site_name = "localsite";
65
66 /** Message Router object to pass requests messages to and which
67 * will process them.*/
68 protected MessageRouter mr = null;
69
70 /** Container Document to create XML Nodes */
71 protected Document doc=null;
72 /** A converter class to parse XML and create Docs */
73 protected XMLConverter converter=null;
74
75 /** Constructor that initializes the web services' MessageRouter object
76 * Reads from GlobalProperties to get gsdl3_home and set the sitename. */
77 public AdminSOAPServer() {
78 String gsdl3_home = GlobalProperties.getGSDL3Home();
79 if (gsdl3_home == null || gsdl3_home.equals("")) {
80 LOG.error(
81 "Couldn't access GSDL3Home from GlobalProperties.getGSDL3HOME,"
82 + "can't initialize the SOAP Server.");
83 return;
84 }
85
86 String site_home = GSFile.siteHome(gsdl3_home, this.site_name);
87
88 File site_file = new File(site_home);
89 if (!site_file.isDirectory()) {
90 LOG.error("The site directory "+site_file.getPath()
91 +" doesn't exist. Can't initialize the SOAP Server.");
92 return;
93 }
94 this.converter = new XMLConverter();
95 this.doc = this.converter.newDOM();
96
97 mr = new MessageRouter();
98 mr.setSiteName(this.site_name);
99 mr.configure();
100 }
101
102// (5) Status-type messages, manual pages 42, 43
103 /** Sends a status-type message to poll the status of a process that was
104 * initiated but which may not yet have terminated.
105 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - pages 42, 43</a>
106 * @param to - the processing service to send this status message to.
107 * @param language - the preferred language of the display content in the
108 * response.
109 * @param pid - the process id of the process whose status is requested.
110 */
111 public String status(String to, String language, String pid) {
112 // Create message element: <message></message>
113 Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
114 // <message><request lang="en" to="" type="status" uid="" /></message>
115 Element request = GSXML.createBasicRequest(this.doc,
116 GSXML.REQUEST_TYPE_STATUS, to, language, "");
117
118 // create the <paramlist></paramlist> element of param elements:
119 Element paramList = this.doc.createElement(
120 GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
121 paramList.appendChild(GSXML.createParameter(this.doc, "pid", pid));
122
123 // now finish constructing the request message:
124 request.appendChild(paramList);
125 message.appendChild(request);
126
127 // Send it off to the Message Router and return the response
128 return this.processInternal(message);
129 }
130
131 // (6) System-type messages, manual pages 41, 42
132 /** Sends a configure system-type message to configure all of the Message Router.
133 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - pp. 13, 41, 42</a>
134 */
135 public String reconfigureMessageRouter() {
136 return this.reconfigure(""); // subset=MessageRouter="", type=configure
137 // Not applicable: systemModuleName="", systemModuleType=""
138 //return this.system("", GSXML.SYSTEM_TYPE_CONFIGURE, subset, "", "");
139 }
140
141 /** Sends a configure system-type message to configure the Message Router.
142 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - pp. 13, 41, 42</a>
143 * @param subset - the particular subset of the module which is to be
144 * reconfigured. For a collection/serviceRack it can be metadataList,
145 * serviceList. For the MessageRouter this can be siteList, collectionList,
146 * clusterList, serviceList
147 */
148 public String reconfigure(String subset) {
149 // type=configure
150 // Not applicable: systemModuleName="", systemModuleType=""
151 return this.system(GSXML.SYSTEM_TYPE_CONFIGURE, subset, "", "");
152 }
153
154 /** Sends a (re-)activate system-type message to activate a Greenstone module.
155 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - pp. 13, 41, 42</a>
156 * @param systemModuleName - name of the module to be (re-)activated.
157 * @param systemModuleType - type of the module. For instance, this may be
158 * site or collection.
159 */
160 public String activate(String systemModuleType, String systemModuleName)
161 {
162 // type=activate
163 // Not applicable: subset=""
164 return this.system(GSXML.SYSTEM_TYPE_ACTIVATE, "",
165 systemModuleType, systemModuleName);
166 }
167
168 /** Sends a deactivate system-type message to activate a Greenstone module.
169 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - pp. 13, 41, 42</a>
170 * @param systemModuleName - name of the module to be deactivated.
171 * @param systemModuleType - type of the module. For instance, this may be
172 * site or collection.
173 */
174 public String deactivate(String systemModuleType, String systemModuleName)
175 {
176 // type=deactivate
177 // Not applicable: subset=""
178 return this.system(GSXML.SYSTEM_TYPE_DEACTIVATE, "",
179 systemModuleType, systemModuleName);
180 }
181
182 /** For sending system-type messages.
183 * For parameter type=configure, the subset value is set (or "").
184 * For parameter type=(de)activate, the systemModuleName and systemModuleType
185 * are set.
186 * @param type - one of GSXML.SYSTEM_TYPE_CONFIGURE,
187 * GSXML.SYSTEM_TYPE_ACTIVATE, GSXML.SYSTEM_TYPE_DEACTIVATE
188 * (configure, activate or deactivate, respectively).
189 * @param subset - for system type configure, this can specify the To module's
190 * subset that needs to be reconfigured.
191 * @param systemModuleName - for system type (de)activate, this specifies the
192 * name of the module to be (de)activated.
193 * @param systemModuleType - for system type (de)activate, this specifies the
194 * type of the module to be (de)activated. For instance, this may be
195 * site or collection.
196 */
197 protected String system(String type, String subset,
198 String systemModuleType, String systemModuleName)
199 {
200 // Create message element: <message></message>
201 Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
202 // <message><request lang="" to="" type="system" uid="" /></message>
203 Element request = GSXML.createBasicRequest(this.doc,
204 GSXML.REQUEST_TYPE_SYSTEM, "", "", ""); // no to, no language
205 // (to is the MessageRouter which deals with system requests)
206
207 Element system = this.doc.createElement(GSXML.SYSTEM_ELEM);
208 system.setAttribute(GSXML.TYPE_ATT, type);
209
210 if(type.equals(GSXML.SYSTEM_TYPE_CONFIGURE)) {
211 // EITHER: <system type='configure' subset=''/>, OR:
212 // <system type='configure' subset='collectionList'/>
213 system.setAttribute(GSXML.SYSTEM_SUBSET_ATT, subset);
214 } else { // GSXML.SYSTEM_TYPE_ACTIVATE || GSXML.SYSTEM_TYPE_DEACTIVATE
215 // For example:
216 // <system type='activate' moduleType='collection' moduleName='demo'/>
217 system.setAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT, systemModuleType);
218 system.setAttribute(GSXML.SYSTEM_MODULE_NAME_ATT, systemModuleName);
219 }
220 // now finish constructing the request message:
221 request.appendChild(system);
222 message.appendChild(request);
223
224 // Send it off to the Message Router and return the response
225 return this.processInternal(message);
226 }
227
228 /** Sends a format-type message to a Service containing format (Greenstone
229 * Format, GSF) XSLT statements to specify how a collection looks.
230 * @see <a href="http://wiki.greenstone.org/wiki/index.php/Greenstone3">The Greenstone 3 Developer's Manual - page 42</a>
231 * @param collection - the name of the collection this message is sent to.
232 * @param service - name of the service this format message is to be sent to.
233 * @param language - the preferred language of the display content in the
234 * response.
235 */
236 public String format(String collection, String service, String language)
237 {
238 String to = service;
239 if(!collection.equals(""))
240 to = collection+"/"+to; // prepend collection with slash to service
241
242 // Create message element: <message></message>
243 Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
244 // <message><request lang="" to="" type="system" uid="" /></message>
245 Element request = GSXML.createBasicRequest(this.doc,
246 GSXML.REQUEST_TYPE_FORMAT, to, language, ""); // no language
247 message.appendChild(request);
248
249 // Send it off to the Message Router and return the response
250 return this.processInternal(message);
251 }
252
253 /** Called by most other methods in order to send the constructed message
254 * to the Greenstone's MessageRouter, intercept the response and return it.
255 * @param message is the XML message Element to send to GS3's MessageRouter.
256 * @return the XML response in String format. */
257 protected String processInternal(Element message) {
258 // Let the messagerouter process the request message and get the response
259 LOG.debug(this.converter.getPrettyString(message));
260
261 // Let the messagerouter process the request message and get the response
262 Element response = mr.process(message);
263 // won't be null, MR always returns some XML response
264
265 // Return it as a String formatted for display
266 return this.converter.getPrettyString(response);
267 }
268
269 /** Creates a String response message to represent an XML error response
270 * message using the error specified in the message parameter. A String is
271 * created because this method ensures that a response message is reliably
272 * constructed (no exceptions are thrown) that can be sent to clients.
273 * @param errorMessage - the errormessage to be conveyed
274 * @return an XML response message containing an GS3 error element. */
275 protected String error(String errorMessage) {
276 StringBuffer buf = new StringBuffer("<" + GSXML.MESSAGE_ELEM + ">");
277 buf.append("<" + GSXML.RESPONSE_ELEM + " "
278 + GSXML.FROM_ATT + "=\"" + "Greenstone 3 Web Services\"" + ">");
279 buf.append("<" + GSXML.ERROR_ELEM + " "
280 + GSXML.ERROR_TYPE_ATT + "=\""+ GSXML.ERROR_TYPE_OTHER + "\"" + ">");
281 buf.append(errorMessage+"\n");
282 buf.append("</" + GSXML.ERROR_ELEM + ">");
283 buf.append("</" + GSXML.RESPONSE_ELEM + ">");
284 buf.append("</" + GSXML.MESSAGE_ELEM + ">");
285 return buf.toString();
286 }
287
288 /*
289 Look in the helpFile
290 - Have a properties file that maps methodname to help string specific
291 to the method.
292 - Read it all in statically at the start of the class, into a Properties Map.
293 - When this method is called, display the usage: "help methodname"
294 and list all the available methods by going over the keys in the Map.
295 - When the helpWithMethod(String methodname) method is called, return the
296 value of the Map for the methodname key. This value would be the help
297 description for that method.
298 */
299 /** @return a help string for listing all the web service methods. */
300 public static String help() {
301 if(!helpErrormessage.equals("")) {
302 return helpErrormessage;
303 }
304
305 StringBuffer helpString = new StringBuffer(
306 "USAGE: helpWithMethod(String <method name>)\n");
307 helpString.append(
308 "\nNearly all the web service operations return a String\n");
309 helpString.append(
310 "representing a Greenstone 3 XML response message.\n");
311 helpString.append("\nA list of all the method names: \n");
312
313 Enumeration props = properties.keys();
314 while(props.hasMoreElements()){
315 String methodName = (String)props.nextElement();
316 helpString.append("\t");
317 helpString.append(methodName);
318 helpString.append("\n");
319 }
320
321 return helpString.toString();
322 }
323
324 /** @param methodname is the name of the method to be described.
325 * @return a help string for the given method, explaining what the method
326 * does, what parameters it expects and their types and what it returns.
327 */
328 public static String helpWithMethod(String methodname) {
329 if(!helpErrormessage.equals("")) {
330 return helpErrormessage;
331 }
332 // else we can get the method's description from the properties
333 // map loaded from the QBRWebServicesHelp.properties file:
334 String helpString = properties.getProperty(methodname,
335 "No description for " + methodname); // if the method does not exist
336
337 return helpString;
338 }
339
340
341 // Here we just try calling some of the methods
342 public static void main(String[] args) {
343 AdminSOAPServer ws = new AdminSOAPServer();
344
345 // (1) activate, deactivate and the 2 reconfigures
346 System.out.println("activate:\n" + ws.activate("collection", "gs2mgppdemo"));
347 System.out.println("deactivate:\n" + ws.deactivate("site", "site1"));
348 System.out.println("configure MR:\n" + ws.reconfigureMessageRouter());
349 System.out.println("configure:\n" + ws.reconfigure("collectionList"));
350
351 // (2) 1 format
352 System.out.println("format:\n" + ws.format("gs2mgppdemo", "FieldQuery", ""));
353
354 // (3) How to test status(), especially when processType messages above don't work?
355 // System.out.println("status:\n" + ws.status(toProcess/service, language, pid));
356 System.out.println("status:\n" + ws.status("build/NewCollection", "", "1"));
357
358 // (4) try help
359 System.out.println(ws.help());
360 System.out.println(ws.helpWithMethod("describe"));
361 System.out.println(ws.helpWithMethod("help"));
362 System.out.println(ws.helpWithMethod("helpWithMethod"));
363
364 System.out.println("Finished executing");
365 }
366
367}
Note: See TracBrowser for help on using the repository browser.