source: trunk/gsdl3/src/java/org/greenstone/gsdl3/collection/ServiceCluster.java@ 3585

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

Removed some debug prints, changed some error messages

  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
Line 
1/*
2 * ServiceCluster.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 */
19// leave the package name as is for now - should be changed to something better
20// cluster? groups?
21package org.greenstone.gsdl3.collection;
22
23
24import org.greenstone.gsdl3.util.*;
25import org.greenstone.gsdl3.core.*;
26import org.greenstone.gsdl3.service.*;
27
28// java XML classes we're using
29import org.w3c.dom.Document;
30import org.w3c.dom.Node;
31import org.w3c.dom.Element;
32import org.w3c.dom.NodeList;
33
34import java.io.File;
35import java.util.HashMap;
36
37/* ServiceCluster - a groups of services that are related in some way
38 * Implements ModuleInterface. Contains a list of services provided by the cluster, along with metadata about the cluster itself.
39 * a collection is a special type of cluster
40 * @author <a href="mailto:[email protected]">Katherine Don</a>
41 * @version $Revision: 3585 $
42 * @see ModuleInterface
43 */
44public class ServiceCluster
45 implements ModuleInterface {
46
47
48 /** base directory for the site that this cluster belongs to*/
49 protected String site_home_ = null;
50
51 /** The name of the cluster - for a collection, this is the collection name*/
52 protected String cluster_name_ = null;
53
54 /** a reference to the message router */
55 protected MessageRouter router_ = null;
56 /** The map of services.
57 *
58 * Maps Services to ServicesImpl objects
59 * @see ServicesImpl
60 *
61 */
62 protected HashMap service_map_=null;
63
64 /** XML converter for String to DOM and vice versa */
65 protected XMLConverter converter_=null;
66
67 /** container doc for description elements */
68 protected Document doc_ = null;
69 /** list of services */
70 protected Element service_info_ = null;
71 /** list of Metadata */
72 protected Element meta_info_ = null;
73 /** full description */
74 protected Element description_ = null;
75
76 public void setSiteHome(String home) {
77 site_home_ = home;
78 }
79
80 public void setClusterName(String name) {
81 cluster_name_ = name;
82 description_.setAttribute(GSXML.NAME_ATT, name);
83 }
84
85 public void setMessageRouter(MessageRouter m) {
86 router_ = m;
87 }
88
89 public ServiceCluster() {
90 service_map_ = new HashMap();
91 converter_ = new XMLConverter();
92 doc_ = converter_.newDOM();
93 description_ = doc_.createElement(GSXML.CLUSTER_ELEM);
94 service_info_ = doc_.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
95 meta_info_ = doc_.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
96
97 }
98
99 /**
100 * Configures the cluster.
101 *
102 * gsdlHome and clusterName must be set before configure is called.
103 *
104 * reads the site configuration file, and configures itself
105 * this calls configure(Element) with the XML element node from the config
106 * file.
107 * configure(Element) should be used if the config file has already been
108 * parsed. This method will work with any subclass.
109 *
110 * @return true if configure successful, false otherwise.
111 */
112 public boolean configure() {
113
114 if (site_home_ == null || cluster_name_== null) {
115 System.err.println("site_home_ and cluster_name_ must be set before configure called!");
116 return false;
117 }
118 System.out.println("configuring service cluster");
119 // read the site configuration file
120 File config_file_ = new File(GSFile.siteConfigFile(site_home_));
121
122 if (!config_file_.exists()) {
123 System.err.println(config_file_+" does not exist");
124 System.err.println("couldn't configure cluster: "+cluster_name_);
125 return false;
126 }
127
128 Document doc = converter_.getDOM(config_file_);
129
130 // get the appropriate service cluster element
131 Element cluster_list = (Element)GSXML.getChildByTagName(doc.getDocumentElement(), GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
132 Element sc = GSXML.getNamedElement(cluster_list, GSXML.CLUSTER_ELEM,
133 GSXML.NAME_ATT, cluster_name_);
134
135 return this.configure(sc);
136 }
137
138 public boolean configure(Element cluster_info) {
139
140 // create all the services
141 NodeList nodes = cluster_info.getElementsByTagName(GSXML.SERVICE_IMPL_ELEM);
142 if (nodes.getLength()==0) {
143 System.err.println("Cluster configuration error: cluster "+cluster_name_+" has no service modules!");
144 return false;
145 }
146
147 for(int i=0; i<nodes.getLength(); i++) {
148
149 // the xml request to send to the servicesImpl to query what
150 // services it provides
151 Element message = doc_.createElement(GSXML.MESSAGE_ELEM);
152 Element request = doc_.createElement(GSXML.REQUEST_ELEM);
153 message.appendChild(request);
154 request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
155 request.setAttribute(GSXML.INFO_ATT, GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
156
157
158 Element n = (Element)nodes.item(i);
159 String servicetype = n.getAttribute(GSXML.NAME_ATT);
160
161 try {
162 ServicesImpl s = (ServicesImpl)Class.forName("org.greenstone.gsdl3.service."+servicetype).newInstance();
163
164 s.setSiteHome(site_home_);
165 s.setClusterName(cluster_name_);
166 s.setMessageRouter(router_);
167 // pass the xml node to the service for configuration
168 s.configure(n);
169
170 // find out the supported service types for this service module
171 Node types = s.process(message);
172 NodeList typenodes = ((Element)types).getElementsByTagName(GSXML.SERVICE_ELEM);
173
174 for (int j=0; j<typenodes.getLength();j++) {
175 String service = ((Element) typenodes.item(j)).getAttribute(GSXML.NAME_ATT);
176 service_map_.put(service, s);
177
178 // also add info to the ServiceInfo XML element
179 service_info_.appendChild(doc_.importNode(typenodes.item(j), true));
180 }
181 } catch (Exception e) {
182 System.err.println("ServiceCluster Error: configure exception: couldn't create service module:org.greenstone.gsdl3.service."+servicetype+"\n"+e.getMessage() + e.getClass() );
183 e.printStackTrace();
184 //return false;
185 }
186
187 }
188
189 // get the metadata - for now just add it to the list
190 Element meta_list = (Element) GSXML.getChildByTagName(cluster_info, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
191 NodeList metanodes = meta_list.getElementsByTagName(GSXML.METADATA_ELEM);
192
193 if (metanodes.getLength()>0) {
194 for(int k=0; k<metanodes.getLength(); k++) {
195 meta_info_.appendChild(doc_.importNode(metanodes.item(k),true));
196 }
197 }
198
199 // add elements to description
200 description_.appendChild(service_info_);
201 description_.appendChild(meta_info_);
202 return true;
203
204
205 }
206
207 /**
208 * Process an XML document - uses Strings
209 * just calls process(Node).
210 *
211 * @param in the Document to process - a string
212 * @return the resultant document as a string - contains any error messages
213 * @see String
214 */
215 public String process(String in) {
216
217 Document doc = converter_.getDOM(in);
218 Element e = doc.getDocumentElement();
219
220 Element res = process(e);
221 return converter_.getString(res);
222
223 }
224
225 /** process XML as Node
226 *
227 */
228 public Element process(Element message) {
229
230 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
231 Document mess_doc = message.getOwnerDocument();
232 Element mainResult = doc_.createElement(GSXML.MESSAGE_ELEM);
233 if (requests.getLength()==0) {
234 System.out.println("no requests for cluster:"+cluster_name_);
235 // no requests
236 return mainResult; // for now
237 }
238 for (int i=0; i<requests.getLength(); i++) {
239 Element request = (Element)requests.item(i);
240 String to = request.getAttribute(GSXML.TO_ATT);
241
242 // the cluster name should be first, check, then remove
243 String clustername = GSPath.getFirstLink(to);
244 if (!clustername.equals(cluster_name_)){
245 System.err.println("ServiceCluster Error: cluster name wrong! was "+clustername+" should have been "+cluster_name_);
246 continue; // ignore this request
247 }
248 to = GSPath.removeFirstLink(to);
249 request.setAttribute(GSXML.TO_ATT, to);
250
251 if (to.equals("")) { // this command is for me
252 String type = request.getAttribute(GSXML.TYPE_ATT);
253 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
254 // create a response with the description inside it
255 Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
256 response.setAttribute(GSXML.FROM_ATT, cluster_name_);
257 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
258 response.appendChild(description_);
259 mainResult.appendChild(response);
260
261 } else {
262 System.err.println("ServiceCluster Error: cant handle request of type "+ type);
263
264 }
265
266 } else { // the request is for one of my services
267 String service = GSPath.getFirstLink(to);
268
269 if (!service_map_.containsKey(service)) {
270 System.err.println("ServiceCluster Error: non-existant service, "+service+", specified!");
271 continue;
272 }
273 // have to pass the request to the service
274 Element single_message = mess_doc.createElement(GSXML.MESSAGE_ELEM);
275 single_message.appendChild(request);
276 Element response = ((ModuleInterface)service_map_.get(service)).process(single_message);
277 if (response != null) {
278 mainResult.appendChild(doc_.importNode(GSXML.getChildByTagName(response, "response"), true));
279 }
280
281 } // else
282
283
284 } // for each request
285 return mainResult;
286 }
287
288}
289
290
291
292
293
294
Note: See TracBrowser for help on using the repository browser.