View Javadoc
1 package org.apache.turbine.services; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 import java.util.ArrayList; 58 import java.util.Hashtable; 59 import java.util.Iterator; 60 import java.util.Properties; 61 import org.apache.commons.configuration.BaseConfiguration; 62 import org.apache.commons.configuration.Configuration; 63 import org.apache.turbine.util.StringUtils; 64 65 66 /*** 67 * A generic implementation of a <code>ServiceBroker</code>. 68 * 69 * Functionality that <code>ServiceBroker</code> provides in addition 70 * to <code>InitableBroker</code> functionality includes: 71 * 72 * <ul> 73 * 74 * <li>Maintaining service name to class name mapping, allowing 75 * plugable service implementations.</li> 76 * 77 * <li>Providing <code>Services</code> with <code>Properties</code> 78 * based on system wide configuration mechanism.</li> 79 * 80 * </ul> 81 * 82 * @author <a href="mailto:burton@apache.org">Kevin Burton</a> 83 * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a> 84 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 85 * @version $Id: BaseServiceBroker.java,v 1.4 2002/07/11 16:53:29 mpoeschl Exp $ 86 */ 87 public abstract class BaseServiceBroker 88 extends BaseInitableBroker 89 implements ServiceBroker 90 { 91 /*** Mapping of Service names to class names. */ 92 //protected Hashtable mapping = new Hashtable(); 93 protected Configuration mapping = (Configuration) new BaseConfiguration(); 94 95 /*** A repository of Service instances. */ 96 protected Hashtable services = new Hashtable(); 97 98 /*** 99 * Default constructor of InitableBorker. 100 * 101 * This constructor does nothing. 102 */ 103 protected BaseServiceBroker() 104 { 105 } 106 107 /*** 108 * Determines whether a service is registered in the configured 109 * <code>TurbineResources.properties</code>. 110 * 111 * @param serviceName The name of the service whose existance to check. 112 * @return Registration predicate for the desired services. 113 */ 114 public boolean isRegistered(String serviceName) 115 { 116 return (services.get(serviceName) != null); 117 } 118 119 /*** 120 * Performs early initialization of specified service. 121 * 122 * @param name The name of the service (generally the 123 * <code>SERVICE_NAME</code> constant of the service's interface 124 * definition). 125 * @param data An object to use for initialization activities. 126 * @exception InitializationException Initilaization of this 127 * service was not successful. 128 */ 129 public void initService( String name, Object data ) 130 throws InitializationException 131 { 132 String className = mapping.getString(name); 133 if (StringUtils.isEmpty(className)) 134 { 135 throw new InitializationException( 136 "ServiceBroker: initialization of unknown service " + 137 name + " requested."); 138 } 139 initClass(className, data); 140 } 141 142 /*** 143 * Performs early initialization of all services. Failed early 144 * initialization of a Service may be non-fatal to the system, 145 * thuss the exceptions are logged and then discarded. 146 * 147 * @param data An Object to use for initialization activities. 148 */ 149 public void initServices( Object data ) 150 { 151 try 152 { 153 initServices(data, false); 154 } 155 catch(InstantiationException notThrown) 156 { 157 } 158 catch(InitializationException notThrown) 159 { 160 } 161 } 162 163 /*** 164 * Performs early initiailzation of all services. You can decide 165 * to handle failed initizalizations if you wish, but then 166 * after one service fails, the other will not have the chance 167 * to initialize. 168 * 169 * @param data An Object to use for initialization activities. 170 * @param report <code>true</code> if you want exceptions thrown. 171 */ 172 public void initServices( Object data, boolean report ) 173 throws InstantiationException, InitializationException 174 { 175 notice("Initializing all services using: " + 176 data.getClass().getName()); 177 Iterator names = mapping.getKeys(); 178 // throw exceptions 179 if(report) 180 { 181 while(names.hasNext()) 182 { 183 doInitService(data, (String)names.next()); 184 } 185 } 186 // eat exceptions 187 else 188 { 189 while(names.hasNext()) 190 { 191 try 192 { 193 doInitService(data, (String)names.next()); 194 } 195 // In case of an exception, file an error message; the 196 // system may be still functional, though. 197 catch(InstantiationException e) 198 { 199 error(e); 200 } 201 catch(InitializationException e) 202 { 203 error(e); 204 } 205 } 206 } 207 notice("Finished initializing all services!"); 208 } 209 210 /*** 211 * Internal utility method for use in initServices() 212 * to prevent duplication of code. 213 */ 214 private void doInitService(Object data, String name) 215 throws InstantiationException, InitializationException 216 { 217 notice("Start Initializing service (early): " + name); 218 219 // Make sure the service has it's name and broker 220 // reference set before initialization. 221 getServiceInstance(name); 222 223 // Perform early initialization. 224 initClass(mapping.getString(name), data); 225 226 notice("Finish Initializing service (early): " + name); 227 } 228 229 /*** 230 * Shuts down a <code>Service</code>. 231 * 232 * This method is used to release resources allocated by a 233 * Service, and return it to its initial (uninitailized) state. 234 * 235 * @param name The name of the <code>Service</code> to be uninitialized. 236 */ 237 public void shutdownService( String name ) 238 { 239 String className = mapping.getString(name); 240 if (className != null) 241 { 242 shutdownClass(className); 243 } 244 } 245 246 /*** 247 * Shuts down all Turbine services, releasing allocated resources and 248 * returning them to their initial (uninitailized) state. 249 */ 250 public void shutdownServices( ) 251 { 252 notice("Shutting down all services!"); 253 254 Iterator serviceNames = mapping.getKeys(); 255 String serviceName = null; 256 257 /* 258 * Now we want to reverse the order of 259 * this list. This functionality should be added to 260 * the ExtendedProperties in the commons but 261 * this will fix the problem for now. 262 */ 263 264 ArrayList reverseServicesList = new ArrayList(); 265 266 while (serviceNames.hasNext()) 267 { 268 serviceName = (String)serviceNames.next(); 269 reverseServicesList.add(0, serviceName); 270 } 271 272 serviceNames = reverseServicesList.iterator(); 273 274 while (serviceNames.hasNext()) 275 { 276 serviceName = (String)serviceNames.next(); 277 notice("Shutting down service: " + serviceName); 278 shutdownService(serviceName); 279 } 280 } 281 282 /*** 283 * Returns an instance of requested Service. 284 * 285 * @param name The name of the Service requested. 286 * @return An instance of requested Service. 287 * @exception InstantiationException, if the service is unknown or 288 * can't be initialized. 289 */ 290 public Service getService( String name ) 291 throws InstantiationException 292 { 293 Service service; 294 try 295 { 296 service = getServiceInstance(name); 297 if(!service.getInit()) 298 { 299 synchronized(service.getClass()) 300 { 301 if(!service.getInit()) 302 { 303 notice("Start Initializing service (late): " + name); 304 service.init(); 305 notice("Finish Initializing service (late): " + name); 306 } 307 } 308 } 309 if(!service.getInit()) 310 { 311 // this exception will be caught & rethrown by this very method. 312 // getInit() returning false indicates some initialization issue, 313 // which in turn prevents the InitableBroker from passing a 314 // reference to a working instance of the initable to the client. 315 throw new InitializationException( 316 "init() failed to initialize service " + name); 317 } 318 return service; 319 } 320 catch( InitializationException e ) 321 { 322 throw new InstantiationException("Service " + name + 323 " failed to initialize", e); 324 } 325 } 326 327 /*** 328 * Retrieves an instance of a Service without triggering late 329 * initialization. 330 * 331 * Early initialization of a Service can require access to Service 332 * properties. The Service must have its name and serviceBroker 333 * set by then. Therefore, before calling 334 * Initable.initClass(Object), the class must be instantiated with 335 * InitableBroker.getInitableInstance(), and 336 * Service.setServiceBroker() and Service.setName() must be 337 * called. This calls for two - level accesing the Services 338 * instances. 339 * 340 * @param name The name of the service requested. 341 * @exception InstantiationException, if the service is unknown or 342 * can't be initialized. 343 */ 344 protected Service getServiceInstance( String name ) 345 throws InstantiationException 346 { 347 Service service = (Service)services.get(name); 348 349 if(service == null) 350 { 351 String className = mapping.getString(name); 352 if(className == null) 353 { 354 throw new InstantiationException( 355 "ServiceBroker: unknown service " + name + " requested"); 356 } 357 try 358 { 359 service = (Service)getInitableInstance(className); 360 } 361 catch(ClassCastException e) 362 { 363 throw new InstantiationException( 364 "ServiceBroker: class " + className + 365 " does not implement Service interface.", e); 366 } 367 catch(InstantiationException e) 368 { 369 throw new InstantiationException( 370 "Failed to instantiate service " + name, e); 371 } 372 service.setServiceBroker(this); 373 service.setName(name); 374 services.put(name, service); 375 } 376 377 return service; 378 } 379 380 /*** 381 * Returns the properites of a specific service. 382 * 383 * Generic ServiceBroker returns empty set of Properties. 384 * 385 * @param name The name of the service. 386 * @return Properties of requested Service. 387 */ 388 public Properties getProperties( String name ) 389 { 390 return new Properties(); 391 } 392 393 /*** 394 * Returns the Configuration of a specific service. 395 * 396 * Generic ServiceBroker returns empty Configuration 397 * 398 * @param name The name of the service. 399 * @return Properties of requested Service. 400 */ 401 public Configuration getConfiguration( String name ) 402 { 403 return (Configuration) new BaseConfiguration(); 404 } 405 }

This page was automatically generated by Maven