- Timestamp:
- 2011-08-12T09:57:26+12:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java
r21781 r24393 24 24 25 25 // xml classes 26 import org.w3c.dom.Node; 27 import org.w3c.dom.NodeList; 28 import org.w3c.dom.Element; 29 import org.w3c.dom.Document; 26 import org.w3c.dom.Node; 27 import org.w3c.dom.NodeList; 28 import org.w3c.dom.Element; 29 import org.w3c.dom.Document; 30 30 import org.xml.sax.InputSource; 31 31 import javax.xml.parsers.*; … … 45 45 /** 46 46 * ServiceRack - abstract base class for services 47 * 48 * A ServiceRack provides one or more Services. 49 * This base class implements the process method. 50 *Each service is invoked 51 * by a method called process<service name> which takes one parameter - the xml request Element, and returns an XML response Element. 52 * for example, the TextQuery service would be invoked by 47 * 48 * A ServiceRack provides one or more Services. This base class implements the 49 * process method. Each service is invoked by a method called process<service 50 * name> which takes one parameter - the xml request Element, and returns an XML 51 * response Element. for example, the TextQuery service would be invoked by 53 52 * processTextQuery(Element request) 54 * 53 * 55 54 * @author Katherine Don 56 55 */ 57 public abstract class ServiceRack 58 implements ModuleInterface 56 public abstract class ServiceRack implements ModuleInterface 59 57 { 60 58 61 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ServiceRack.class.getName()); 62 63 /** the absolute address of the site home */ 64 protected String site_home =null; 65 /** the http address of the site home */ 66 protected String site_http_address =null; 67 68 protected String library_name = null; 69 /** the name of the cluster (or collection) that this service 70 belongs to - if any */ 71 protected String cluster_name = null; 72 73 /** some services can talk back to the message router */ 74 protected MessageRouter router = null; 75 76 /** a converter class to create Documents etc */ 77 protected XMLConverter converter = null; 78 79 /** the original config info - if need to store it */ 80 protected Element config_info = null; 81 82 /** XML element for describe requests - the container doc */ 83 protected Document doc = null; 84 85 /** XML element for describe requests - list of supported services 86 - this is static */ 87 protected Element short_service_info = null; 88 89 /** XML element for stylesheet requests - map of service name to format 90 elem */ 91 protected HashMap format_info_map = null; 92 93 /** A class loader that knows about the collection resources directory 94 * can put properties files, dtds etc in here */ 95 CollectionClassLoader class_loader = null; 96 97 /** sets the cluster name */ 98 public void setClusterName(String cluster_name) { 99 this.cluster_name = cluster_name; 100 } 101 /** sets the collect name */ 102 public void setCollectionName(String coll_name) { 103 setClusterName(coll_name); 104 } 105 106 public void cleanUp() {} 107 108 /** sets the site home */ 109 public void setSiteHome(String site_home) { 110 this.site_home = site_home; 111 } 112 /** sets the site http address */ 113 public void setSiteAddress(String site_address) { 114 this.site_http_address = site_address; 115 } 116 117 public void setLibraryName(String library_name) { 118 this.library_name = library_name; 119 } 120 public String getLibraryName() { 121 return this.library_name; 122 } 123 /** sets the message router */ 124 public void setMessageRouter(MessageRouter m) { 125 this.router = m; 126 setLibraryName(m.getLibraryName()); 127 } 128 129 /** the no-args constructor */ 130 public ServiceRack() { 131 this.converter = new XMLConverter(); 132 this.doc = this.converter.newDOM(); 133 this.short_service_info = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER); 134 this.format_info_map = new HashMap(); 135 } 136 137 138 /** configure the service module 139 * 140 * @param info the XML node <serviceRack name="XXX"/> with name equal 141 * to the class name (of the subclass) 142 * 143 * must configure short_service_info_ and service_info_map_ 144 * @return true if configured ok 145 * must be implemented in subclasses 146 */ 147 public boolean configure(Element info) { 148 return configure(info, null); 149 } 150 151 public boolean configure(Element info, Element extra_info) { 152 // set up the class loader 153 this.class_loader = new CollectionClassLoader(this.getClass().getClassLoader(), this.site_home, this.cluster_name); 154 return true; 155 } 156 157 /** 158 * Process an XML document - convenience method that uses Strings rather than Elements. just calls process(Element). 159 * 160 * @param xml_in the Document to process - a string 161 * @return the resultant document as a string - contains any error messages 162 * @see String 163 */ 164 public String process(String xml_in) { 165 166 Document doc = this.converter.getDOM(xml_in); 167 if (doc == null) { 168 logger.error("Couldn't parse request"); 169 logger.error(xml_in); 170 return null; 171 } 172 Node res = process(doc); 173 return this.converter.getString(res); 174 175 } 176 177 /** process an XML request in DOM form 178 * 179 * @param message the Node node containing the request 180 * should be <message> 181 * @return an Node with the result XML 182 * @see Node/Element 183 */ 184 public Node process(Node message_node) { 185 186 Element message = this.converter.nodeToElement(message_node); 187 188 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM); 189 Document mess_doc = message.getOwnerDocument(); 190 Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM); 191 if (requests.getLength()==0) { 192 // no requests 193 return mainResult; // empty message for now 194 } 195 196 for (int i=0; i<requests.getLength(); i++) { 197 Element request = (Element)requests.item(i); 198 199 String type = request.getAttribute(GSXML.TYPE_ATT); 200 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) { 201 Element response = processDescribe(request); 202 if (response !=null) { 203 mainResult.appendChild(this.doc.importNode(response, true)); 204 } 205 206 } else if (type.equals(GSXML.REQUEST_TYPE_FORMAT)) { 207 Element response = processFormat(request); 208 mainResult.appendChild(this.doc.importNode(response, true)); 209 210 211 } else { 212 // other type of request, must be processed by the subclass - 213 // send to the service method 214 StringBuffer error_string = new StringBuffer(); 215 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 216 Element response = null; 217 try { 218 Class c = this.getClass(); 219 Class []params = {Class.forName("org.w3c.dom.Element")}; 220 221 String method_name = "process"+to; 222 Method m = null; 223 while (c != null) { 224 225 try { 226 m = c.getDeclaredMethod(method_name, params); 227 // if this has worked, break 228 break; 229 } catch (NoSuchMethodException e) { 230 c = c.getSuperclass(); 231 } catch (SecurityException e) { 232 logger.error("security exception for finding method "+method_name); 233 error_string.append("ServiceRack.process: security exception for finding method "+method_name); 59 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.ServiceRack.class.getName()); 60 61 /** the absolute address of the site home */ 62 protected String site_home = null; 63 /** the http address of the site home */ 64 protected String site_http_address = null; 65 66 protected String library_name = null; 67 /** 68 * the name of the cluster (or collection) that this service belongs to - if 69 * any 70 */ 71 protected String cluster_name = null; 72 73 /** some services can talk back to the message router */ 74 protected MessageRouter router = null; 75 76 /** a converter class to create Documents etc */ 77 protected XMLConverter converter = null; 78 79 /** the original config info - if need to store it */ 80 protected Element config_info = null; 81 82 /** XML element for describe requests - the container doc */ 83 protected Document doc = null; 84 85 /** 86 * XML element for describe requests - list of supported services - this is 87 * static 88 */ 89 protected Element short_service_info = null; 90 91 /** 92 * XML element for stylesheet requests - map of service name to format elem 93 */ 94 protected HashMap format_info_map = null; 95 96 /** 97 * A class loader that knows about the collection resources directory can 98 * put properties files, dtds etc in here 99 */ 100 CollectionClassLoader class_loader = null; 101 102 /** sets the cluster name */ 103 public void setClusterName(String cluster_name) 104 { 105 this.cluster_name = cluster_name; 106 } 107 108 /** sets the collect name */ 109 public void setCollectionName(String coll_name) 110 { 111 setClusterName(coll_name); 112 } 113 114 public void cleanUp() 115 { 116 } 117 118 /** sets the site home */ 119 public void setSiteHome(String site_home) 120 { 121 this.site_home = site_home; 122 } 123 124 /** sets the site http address */ 125 public void setSiteAddress(String site_address) 126 { 127 this.site_http_address = site_address; 128 } 129 130 public void setLibraryName(String library_name) 131 { 132 this.library_name = library_name; 133 } 134 135 public String getLibraryName() 136 { 137 return this.library_name; 138 } 139 140 /** sets the message router */ 141 public void setMessageRouter(MessageRouter m) 142 { 143 this.router = m; 144 setLibraryName(m.getLibraryName()); 145 } 146 147 /** the no-args constructor */ 148 public ServiceRack() 149 { 150 this.converter = new XMLConverter(); 151 this.doc = this.converter.newDOM(); 152 this.short_service_info = this.doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER); 153 this.format_info_map = new HashMap(); 154 } 155 156 /** 157 * configure the service module 158 * 159 * @param info 160 * the XML node <serviceRack name="XXX"/> with name equal to the 161 * class name (of the subclass) 162 * 163 * must configure short_service_info_ and service_info_map_ 164 * @return true if configured ok must be implemented in subclasses 165 */ 166 public boolean configure(Element info) 167 { 168 return configure(info, null); 169 } 170 171 public boolean configure(Element info, Element extra_info) 172 { 173 // set up the class loader 174 this.class_loader = new CollectionClassLoader(this.getClass().getClassLoader(), this.site_home, this.cluster_name); 175 return true; 176 } 177 178 /** 179 * Process an XML document - convenience method that uses Strings rather 180 * than Elements. just calls process(Element). 181 * 182 * @param xml_in 183 * the Document to process - a string 184 * @return the resultant document as a string - contains any error messages 185 * @see String 186 */ 187 public String process(String xml_in) 188 { 189 190 Document doc = this.converter.getDOM(xml_in); 191 if (doc == null) 192 { 193 logger.error("Couldn't parse request"); 194 logger.error(xml_in); 195 return null; 196 } 197 Node res = process(doc); 198 return this.converter.getString(res); 199 200 } 201 202 /** 203 * process an XML request in DOM form 204 * 205 * @param message 206 * the Node node containing the request should be <message> 207 * @return an Node with the result XML 208 * @see Node/Element 209 */ 210 public Node process(Node message_node) 211 { 212 213 Element message = this.converter.nodeToElement(message_node); 214 215 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM); 216 Document mess_doc = message.getOwnerDocument(); 217 Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM); 218 if (requests.getLength() == 0) 219 { 220 // no requests 221 return mainResult; // empty message for now 222 } 223 224 for (int i = 0; i < requests.getLength(); i++) 225 { 226 Element request = (Element) requests.item(i); 227 228 String type = request.getAttribute(GSXML.TYPE_ATT); 229 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) 230 { 231 Element response = processDescribe(request); 232 if (response != null) 233 { 234 mainResult.appendChild(this.doc.importNode(response, true)); 235 } 236 234 237 } 235 } // while 236 if (m != null) { 237 Object []args = {request}; 238 try { 239 response = (Element)m.invoke(this, args); 240 241 } catch (Exception e) { 242 logger.error("Trying to call a processService type method (process"+to+") on a subclass("+this.getClass().getName()+"), but an exception happened:"+e.toString(), e); 243 244 error_string.append("Trying to call a processService type method (process"+to+") on a subclass("+this.getClass().getName()+"), but an exception happened:"+e.toString()); 238 else if (type.equals(GSXML.REQUEST_TYPE_FORMAT)) 239 { 240 Element response = processFormat(request); 241 mainResult.appendChild(this.doc.importNode(response, true)); 242 245 243 } 246 } else { 247 logger.error("method "+method_name+" not found for class "+this.getClass().getName()); 248 error_string.append("ServiceRack.process: method "+method_name+" not found for class "+this.getClass().getName()); 249 } 250 251 } catch (ClassNotFoundException e) { 252 logger.error("Element class not found"); 253 error_string.append("Element class not found"); 254 } 255 if (response !=null) { 256 mainResult.appendChild(this.doc.importNode(response, true)); 257 } else { 258 // add in a dummy response 259 logger.error("adding in an error element\n"); 260 response = this.doc.createElement(GSXML.RESPONSE_ELEM); 261 GSXML.addError(this.doc, response, error_string.toString()); 262 mainResult.appendChild(response); 263 264 } 265 266 } // else process request 267 } // for each request 268 269 return mainResult; 270 271 } 272 273 274 275 /** process method for describe requests 276 */ 277 protected Element processDescribe(Element request) { 278 279 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 280 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE); 281 282 String lang = request.getAttribute(GSXML.LANG_ATT); 283 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 284 if (to.equals("")) { // return the service list 285 response.appendChild(getServiceList(lang)); 286 return response; 287 } 288 response.setAttribute(GSXML.FROM_ATT, to); 289 Element param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 290 Element description = null; 291 if (param_list == null) { 292 description = getServiceDescription(to, lang, null); 293 } else { 294 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 295 for (int i=0; i<params.getLength(); i++) { 296 297 Element param = (Element)params.item(i); 298 // Identify the structure information desired 299 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM )) { 300 String info = param.getAttribute(GSXML.VALUE_ATT); 301 if (description == null) { 302 description = getServiceDescription(to, lang, info); 303 } else { 304 Element temp = getServiceDescription(to, lang, info); 305 GSXML.mergeElements(description, temp); 306 } 307 } 308 } 309 } 310 if (description != null) { // may be null if non-existant service 311 response.appendChild(description); 312 } 313 return response; 314 315 } 316 317 /** process method for stylesheet requests 318 */ 319 protected Element processFormat(Element request) { 320 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 321 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_FORMAT); 322 323 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 324 325 if (to.equals("")) { // serviceRack query - is this appropriate?? 326 return response; 327 } 328 329 330 // describe a particular service 331 if (this.format_info_map.containsKey(to)) { 332 response.appendChild(getServiceFormat(to)); 333 response.setAttribute(GSXML.FROM_ATT, to); 334 return response; 335 } 336 // else no format info 337 logger.error("ServiceRack describe request: no format info for "+to+"."); 338 return response; 339 } 340 341 /** returns the service list for the subclass */ 342 protected Element getServiceList(String lang) { 343 // for now, it is static and has no language stuff 344 return (Element) this.short_service_info.cloneNode(true); 345 } 346 347 /** returns a specific service description */ 348 abstract protected Element getServiceDescription(String service, String lang, String subset); 349 350 protected Element getServiceFormat(String service) { 351 Element format = (Element)((Element)this.format_info_map.get(service)).cloneNode(true); 352 return format; 353 } 354 355 /** overloaded version for no args case */ 356 protected String getTextString(String key, String lang) { 357 return getTextString(key, lang, null, null); 358 } 359 360 protected String getTextString(String key, String lang, String dictionary) { 361 return getTextString(key, lang, dictionary, null); 362 } 363 protected String getTextString(String key, String lang, String [] args) { 364 return getTextString(key, lang, null, args); 365 } 366 367 /** getTextString - retrieves a language specific text string for the given 368 key and locale, from the specified resource_bundle (dictionary) 369 */ 370 protected String getTextString(String key, String lang, String dictionary, String[] args) { 371 372 // we want to use the collection class loader in case there are coll specific files 373 if (dictionary != null) { 374 // just try the one specified dictionary 375 Dictionary dict = new Dictionary(dictionary, lang, this.class_loader); 376 String result = dict.get(key, args); 377 if (result == null) { // not found 378 return "_"+key+"_"; 379 } 380 return result; 381 } 382 383 // now we try class names for dictionary names 384 String class_name = this.getClass().getName(); 385 class_name = class_name.substring(class_name.lastIndexOf('.')+1); 386 Dictionary dict = new Dictionary(class_name, lang, this.class_loader); 387 String result = dict.get(key, args); 388 if (result != null) { 389 return result; 390 } 391 392 // we have to try super classes 393 Class c = this.getClass().getSuperclass(); 394 while (result == null && c != null) { 395 class_name = c.getName(); 396 class_name = class_name.substring(class_name.lastIndexOf('.')+1); 397 if (class_name.equals("ServiceRack")) { 398 // this is as far as we go 399 break; 400 } 401 dict = new Dictionary(class_name, lang, this.class_loader); 402 result = dict.get(key, args); 403 c = c.getSuperclass(); 404 } 405 if (result == null) { 406 return "_"+key+"_"; 407 } 408 return result; 409 410 } 411 412 protected String getMetadataNameText(String key, String lang) { 413 414 String properties_name = "metadata_names"; 415 Dictionary dict = new Dictionary(properties_name, lang); 416 417 String result = dict.get(key); 418 if (result == null) { // not found 419 return null; 420 } 421 return result; 422 } 244 else 245 { 246 // other type of request, must be processed by the subclass - 247 // send to the service method 248 StringBuffer error_string = new StringBuffer(); 249 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 250 Element response = null; 251 try 252 { 253 Class c = this.getClass(); 254 Class[] params = { Class.forName("org.w3c.dom.Element") }; 255 256 String method_name = "process" + to; 257 Method m = null; 258 while (c != null) 259 { 260 261 try 262 { 263 m = c.getDeclaredMethod(method_name, params); 264 // if this has worked, break 265 break; 266 } 267 catch (NoSuchMethodException e) 268 { 269 c = c.getSuperclass(); 270 } 271 catch (SecurityException e) 272 { 273 logger.error("security exception for finding method " + method_name); 274 error_string.append("ServiceRack.process: security exception for finding method " + method_name); 275 } 276 } // while 277 if (m != null) 278 { 279 Object[] args = { request }; 280 try 281 { 282 response = (Element) m.invoke(this, args); 283 284 } 285 catch (Exception e) 286 { 287 logger.error("Trying to call a processService type method (process" + to + ") on a subclass(" + this.getClass().getName() + "), but an exception happened:" + e.toString(), e); 288 289 error_string.append("Trying to call a processService type method (process" + to + ") on a subclass(" + this.getClass().getName() + "), but an exception happened:" + e.toString()); 290 } 291 } 292 else 293 { 294 logger.error("method " + method_name + " not found for class " + this.getClass().getName()); 295 error_string.append("ServiceRack.process: method " + method_name + " not found for class " + this.getClass().getName()); 296 } 297 298 } 299 catch (ClassNotFoundException e) 300 { 301 logger.error("Element class not found"); 302 error_string.append("Element class not found"); 303 } 304 if (response != null) 305 { 306 mainResult.appendChild(this.doc.importNode(response, true)); 307 } 308 else 309 { 310 // add in a dummy response 311 logger.error("adding in an error element\n"); 312 response = this.doc.createElement(GSXML.RESPONSE_ELEM); 313 GSXML.addError(this.doc, response, error_string.toString()); 314 mainResult.appendChild(response); 315 316 } 317 318 } // else process request 319 } // for each request 320 321 return mainResult; 322 323 } 324 325 /** 326 * process method for describe requests 327 */ 328 protected Element processDescribe(Element request) 329 { 330 331 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 332 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE); 333 334 String lang = request.getAttribute(GSXML.LANG_ATT); 335 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 336 if (to.equals("")) 337 { // return the service list 338 response.appendChild(getServiceList(lang)); 339 return response; 340 } 341 response.setAttribute(GSXML.FROM_ATT, to); 342 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 343 Element description = null; 344 if (param_list == null) 345 { 346 description = getServiceDescription(to, lang, null); 347 } 348 else 349 { 350 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM); 351 for (int i = 0; i < params.getLength(); i++) 352 { 353 354 Element param = (Element) params.item(i); 355 // Identify the structure information desired 356 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM)) 357 { 358 String info = param.getAttribute(GSXML.VALUE_ATT); 359 if (description == null) 360 { 361 description = getServiceDescription(to, lang, info); 362 } 363 else 364 { 365 Element temp = getServiceDescription(to, lang, info); 366 GSXML.mergeElements(description, temp); 367 } 368 } 369 } 370 } 371 if (description != null) 372 { // may be null if non-existant service 373 response.appendChild(description); 374 } 375 return response; 376 377 } 378 379 /** 380 * process method for stylesheet requests 381 */ 382 protected Element processFormat(Element request) 383 { 384 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 385 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_FORMAT); 386 387 String to = GSPath.getFirstLink(request.getAttribute(GSXML.TO_ATT)); 388 389 if (to.equals("")) 390 { // serviceRack query - is this appropriate?? 391 return response; 392 } 393 394 // describe a particular service 395 if (this.format_info_map.containsKey(to)) 396 { 397 response.appendChild(getServiceFormat(to)); 398 response.setAttribute(GSXML.FROM_ATT, to); 399 return response; 400 } 401 // else no format info 402 logger.error("ServiceRack describe request: no format info for " + to + "."); 403 return response; 404 } 405 406 /** returns the service list for the subclass */ 407 protected Element getServiceList(String lang) 408 { 409 // for now, it is static and has no language stuff 410 return (Element) this.short_service_info.cloneNode(true); 411 } 412 413 /** returns a specific service description */ 414 abstract protected Element getServiceDescription(String service, String lang, String subset); 415 416 protected Element getServiceFormat(String service) 417 { 418 Element format = (Element) ((Element) this.format_info_map.get(service)).cloneNode(true); 419 return format; 420 } 421 422 /** overloaded version for no args case */ 423 protected String getTextString(String key, String lang) 424 { 425 return getTextString(key, lang, null, null); 426 } 427 428 protected String getTextString(String key, String lang, String dictionary) 429 { 430 return getTextString(key, lang, dictionary, null); 431 } 432 433 protected String getTextString(String key, String lang, String[] args) 434 { 435 return getTextString(key, lang, null, args); 436 } 437 438 /** 439 * getTextString - retrieves a language specific text string for the given 440 * key and locale, from the specified resource_bundle (dictionary) 441 */ 442 protected String getTextString(String key, String lang, String dictionary, String[] args) 443 { 444 445 // we want to use the collection class loader in case there are coll specific files 446 if (dictionary != null) 447 { 448 // just try the one specified dictionary 449 Dictionary dict = new Dictionary(dictionary, lang, this.class_loader); 450 String result = dict.get(key, args); 451 if (result == null) 452 { // not found 453 return "_" + key + "_"; 454 } 455 return result; 456 } 457 458 // now we try class names for dictionary names 459 String class_name = this.getClass().getName(); 460 class_name = class_name.substring(class_name.lastIndexOf('.') + 1); 461 Dictionary dict = new Dictionary(class_name, lang, this.class_loader); 462 String result = dict.get(key, args); 463 if (result != null) 464 { 465 return result; 466 } 467 468 // we have to try super classes 469 Class c = this.getClass().getSuperclass(); 470 while (result == null && c != null) 471 { 472 class_name = c.getName(); 473 class_name = class_name.substring(class_name.lastIndexOf('.') + 1); 474 if (class_name.equals("ServiceRack")) 475 { 476 // this is as far as we go 477 break; 478 } 479 dict = new Dictionary(class_name, lang, this.class_loader); 480 result = dict.get(key, args); 481 c = c.getSuperclass(); 482 } 483 if (result == null) 484 { 485 return "_" + key + "_"; 486 } 487 return result; 488 489 } 490 491 protected String getMetadataNameText(String key, String lang) 492 { 493 494 String properties_name = "metadata_names"; 495 Dictionary dict = new Dictionary(properties_name, lang); 496 497 String result = dict.get(key); 498 if (result == null) 499 { // not found 500 return null; 501 } 502 return result; 503 } 423 504 } 424
Note:
See TracChangeset
for help on using the changeset viewer.