Source Code Cross Referenced for BaseServiceBroker.java in  » Web-Framework » TURBINE » org » apache » turbine » services » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » TURBINE » org.apache.turbine.services 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.turbine.services;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.
020:         */
021:
022:        import java.util.ArrayList;
023:        import java.util.Hashtable;
024:        import java.util.Iterator;
025:
026:        import org.apache.commons.configuration.BaseConfiguration;
027:        import org.apache.commons.configuration.Configuration;
028:        import org.apache.commons.lang.StringUtils;
029:        import org.apache.commons.logging.Log;
030:        import org.apache.commons.logging.LogFactory;
031:
032:        /**
033:         * A generic implementation of a <code>ServiceBroker</code> which
034:         * provides:
035:         *
036:         * <ul>
037:         * <li>Maintaining service name to class name mapping, allowing
038:         * plugable service implementations.</li>
039:         * <li>Providing <code>Services</code> with a configuration based on
040:         * system wide configuration mechanism.</li>
041:         * </ul>
042:         *
043:         * @author <a href="mailto:burton@apache.org">Kevin Burton</a>
044:         * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
045:         * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
046:         * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
047:         * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
048:         * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
049:         * @version $Id: BaseServiceBroker.java 534527 2007-05-02 16:10:59Z tv $
050:         */
051:        public abstract class BaseServiceBroker implements  ServiceBroker {
052:            /**
053:             * Mapping of Service names to class names.
054:             */
055:            protected Configuration mapping = new BaseConfiguration();
056:
057:            /**
058:             * A repository of Service instances.
059:             */
060:            protected Hashtable services = new Hashtable();
061:
062:            /**
063:             * Configuration for the services broker.
064:             * The configuration should be set by the application
065:             * in which the services framework is running.
066:             */
067:            protected Configuration configuration;
068:
069:            /**
070:             * A prefix for <code>Service</code> properties in
071:             * TurbineResource.properties.
072:             */
073:            public static final String SERVICE_PREFIX = "services.";
074:
075:            /**
076:             * A <code>Service</code> property determining its implementing
077:             * class name .
078:             */
079:            public static final String CLASSNAME_SUFFIX = ".classname";
080:
081:            /**
082:             * These are objects that the parent application
083:             * can provide so that application specific
084:             * services have a mechanism to retrieve specialized
085:             * information. For example, in Turbine there are services
086:             * that require the RunData object: these services can
087:             * retrieve the RunData object that Turbine has placed
088:             * in the service manager. This alleviates us of
089:             * the requirement of having init(Object) all
090:             * together.
091:             */
092:            protected Hashtable serviceObjects = new Hashtable();
093:
094:            /** Logging */
095:            private static Log log = LogFactory.getLog(BaseServiceBroker.class);
096:
097:            /**
098:             * Application root path as set by the
099:             * parent application.
100:             */
101:            protected String applicationRoot;
102:
103:            /**
104:             * Default constructor, protected as to only be useable by subclasses.
105:             *
106:             * This constructor does nothing.
107:             */
108:            protected BaseServiceBroker() {
109:            }
110:
111:            /**
112:             * Set the configuration object for the services broker.
113:             * This is the configuration that contains information
114:             * about all services in the care of this service
115:             * manager.
116:             *
117:             * @param configuration Broker configuration.
118:             */
119:            public void setConfiguration(Configuration configuration) {
120:                this .configuration = configuration;
121:            }
122:
123:            /**
124:             * Get the configuration for this service manager.
125:             *
126:             * @return Broker configuration.
127:             */
128:            public Configuration getConfiguration() {
129:                return configuration;
130:            }
131:
132:            /**
133:             * Initialize this service manager.
134:             */
135:            public void init() throws InitializationException {
136:                // Check:
137:                //
138:                // 1. The configuration has been set.
139:                // 2. Make sure the application root has been set.
140:
141:                // FIXME: Make some service framework exceptions to throw in
142:                // the event these requirements aren't satisfied.
143:
144:                // Create the mapping between service names
145:                // and their classes.
146:                initMapping();
147:
148:                // Start services that have their 'earlyInit'
149:                // property set to 'true'.
150:                initServices(false);
151:            }
152:
153:            /**
154:             * Set an application specific service object
155:             * that can be used by application specific
156:             * services.
157:             *
158:             * @param name name of service object
159:             * @param value value of service object
160:             */
161:            public void setServiceObject(String name, Object value) {
162:                serviceObjects.put(name, value);
163:            }
164:
165:            /**
166:             * Get an application specific service object.
167:             *
168:             * @return Object application specific service object
169:             */
170:            public Object getServiceObject(String name) {
171:                return serviceObjects.get(name);
172:            }
173:
174:            /**
175:             * Creates a mapping between Service names and class names.
176:             *
177:             * The mapping is built according to settings present in
178:             * TurbineResources.properties.  The entries should have the
179:             * following form:
180:             *
181:             * <pre>
182:             * services.MyService.classname=com.mycompany.MyServiceImpl
183:             * services.MyOtherService.classname=com.mycompany.MyOtherServiceImpl
184:             * </pre>
185:             *
186:             * <br>
187:             *
188:             * Generic ServiceBroker provides no Services.
189:             */
190:            protected void initMapping() {
191:                /*
192:                 * These keys returned in an order that corresponds
193:                 * to the order the services are listed in
194:                 * the TR.props.
195:                 *
196:                 * When the mapping is created we use a Configuration
197:                 * object to ensure that the we retain the order
198:                 * in which the order the keys are returned.
199:                 *
200:                 * There's no point in retrieving an ordered set
201:                 * of keys if they aren't kept in order :-)
202:                 */
203:                for (Iterator keys = configuration.getKeys(); keys.hasNext();) {
204:                    String key = (String) keys.next();
205:                    String[] keyParts = StringUtils.split(key, ".");
206:
207:                    if ((keyParts.length == 3)
208:                            && (keyParts[0] + ".").equals(SERVICE_PREFIX)
209:                            && ("." + keyParts[2]).equals(CLASSNAME_SUFFIX)) {
210:                        String serviceKey = keyParts[1];
211:                        log.info("Added Mapping for Service: " + serviceKey);
212:
213:                        if (!mapping.containsKey(serviceKey)) {
214:                            mapping.setProperty(serviceKey, configuration
215:                                    .getString(key));
216:                        }
217:                    }
218:                }
219:            }
220:
221:            /**
222:             * Determines whether a service is registered in the configured
223:             * <code>TurbineResources.properties</code>.
224:             *
225:             * @param serviceName The name of the service whose existance to check.
226:             * @return Registration predicate for the desired services.
227:             */
228:            public boolean isRegistered(String serviceName) {
229:                return (services.get(serviceName) != null);
230:            }
231:
232:            /**
233:             * Returns an Iterator over all known service names.
234:             *
235:             * @return An Iterator of service names.
236:             */
237:            public Iterator getServiceNames() {
238:                return mapping.getKeys();
239:            }
240:
241:            /**
242:             * Returns an Iterator over all known service names beginning with
243:             * the provided prefix.
244:             *
245:             * @param prefix The prefix against which to test.
246:             * @return An Iterator of service names which match the prefix.
247:             */
248:            public Iterator getServiceNames(String prefix) {
249:                return mapping.getKeys(prefix);
250:            }
251:
252:            /**
253:             * Performs early initialization of specified service.
254:             *
255:             * @param name The name of the service (generally the
256:             * <code>SERVICE_NAME</code> constant of the service's interface
257:             * definition).
258:             * @exception InitializationException Initialization of this
259:             * service was not successful.
260:             */
261:            public synchronized void initService(String name)
262:                    throws InitializationException {
263:                // Calling getServiceInstance(name) assures that the Service
264:                // implementation has its name and broker reference set before
265:                // initialization.
266:                Service instance = getServiceInstance(name);
267:
268:                if (!instance.getInit()) {
269:                    // this call might result in an indirect recursion
270:                    instance.init();
271:                }
272:            }
273:
274:            /**
275:             * Performs early initialization of all services.  Failed early
276:             * initialization of a Service may be non-fatal to the system,
277:             * thus any exceptions are logged and the initialization process
278:             * continues.
279:             */
280:            public void initServices() {
281:                try {
282:                    initServices(false);
283:                } catch (InstantiationException notThrown) {
284:                    log.debug("Caught non fatal exception", notThrown);
285:                } catch (InitializationException notThrown) {
286:                    log.debug("Caught non fatal exception", notThrown);
287:                }
288:            }
289:
290:            /**
291:             * Performs early initialization of all services. You can decide
292:             * to handle failed initializations if you wish, but then
293:             * after one service fails, the other will not have the chance
294:             * to initialize.
295:             *
296:             * @param report <code>true</code> if you want exceptions thrown.
297:             */
298:            public void initServices(boolean report)
299:                    throws InstantiationException, InitializationException {
300:                if (report) {
301:                    // Throw exceptions
302:                    for (Iterator names = getServiceNames(); names.hasNext();) {
303:                        doInitService((String) names.next());
304:                    }
305:                } else {
306:                    // Eat exceptions
307:                    for (Iterator names = getServiceNames(); names.hasNext();) {
308:                        try {
309:                            doInitService((String) names.next());
310:                        }
311:                        // In case of an exception, file an error message; the
312:                        // system may be still functional, though.
313:                        catch (InstantiationException e) {
314:                            log.error(e);
315:                        } catch (InitializationException e) {
316:                            log.error(e);
317:                        }
318:                    }
319:                }
320:                log.info("Finished initializing all services!");
321:            }
322:
323:            /**
324:             * Internal utility method for use in {@link #initServices(boolean)}
325:             * to prevent duplication of code.
326:             */
327:            private void doInitService(String name)
328:                    throws InstantiationException, InitializationException {
329:                // Only start up services that have their earlyInit flag set.
330:                if (getConfiguration(name).getBoolean("earlyInit", false)) {
331:                    log.info("Start Initializing service (early): " + name);
332:                    initService(name);
333:                    log.info("Finish Initializing service (early): " + name);
334:                }
335:            }
336:
337:            /**
338:             * Shuts down a <code>Service</code>, releasing resources
339:             * allocated by an <code>Service</code>, and returns it to its
340:             * initial (uninitialized) state.
341:             *
342:             * @param name The name of the <code>Service</code> to be
343:             * uninitialized.
344:             */
345:            public synchronized void shutdownService(String name) {
346:                try {
347:                    Service service = getServiceInstance(name);
348:                    if (service != null && service.getInit()) {
349:                        service.shutdown();
350:                        if (service.getInit() && service instanceof  BaseService) {
351:                            // BaseService::shutdown() does this by default,
352:                            // but could've been overriden poorly.
353:                            ((BaseService) service).setInit(false);
354:                        }
355:                    }
356:                } catch (InstantiationException e) {
357:                    // Assuming harmless -- log the error and continue.
358:                    log.error("Shutdown of a nonexistent Service '" + name
359:                            + "' was requested", e);
360:                }
361:            }
362:
363:            /**
364:             * Shuts down all Turbine services, releasing allocated resources and
365:             * returning them to their initial (uninitialized) state.
366:             */
367:            public void shutdownServices() {
368:                log.info("Shutting down all services!");
369:
370:                String serviceName = null;
371:
372:                /*
373:                 * Now we want to reverse the order of
374:                 * this list. This functionality should be added to
375:                 * the ExtendedProperties in the commons but
376:                 * this will fix the problem for now.
377:                 */
378:
379:                ArrayList reverseServicesList = new ArrayList();
380:
381:                for (Iterator serviceNames = getServiceNames(); serviceNames
382:                        .hasNext();) {
383:                    serviceName = (String) serviceNames.next();
384:                    reverseServicesList.add(0, serviceName);
385:                }
386:
387:                for (Iterator serviceNames = reverseServicesList.iterator(); serviceNames
388:                        .hasNext();) {
389:                    serviceName = (String) serviceNames.next();
390:                    log.info("Shutting down service: " + serviceName);
391:                    shutdownService(serviceName);
392:                }
393:            }
394:
395:            /**
396:             * Returns an instance of requested Service.
397:             *
398:             * @param name The name of the Service requested.
399:             * @return An instance of requested Service.
400:             * @exception InstantiationException if the service is unknown or
401:             * can't be initialized.
402:             */
403:            public Service getService(String name)
404:                    throws InstantiationException {
405:                Service service;
406:                try {
407:                    service = getServiceInstance(name);
408:                    if (!service.getInit()) {
409:                        synchronized (service.getClass()) {
410:                            if (!service.getInit()) {
411:                                log.info("Start Initializing service (late): "
412:                                        + name);
413:                                service.init();
414:                                log.info("Finish Initializing service (late): "
415:                                        + name);
416:                            }
417:                        }
418:                    }
419:                    if (!service.getInit()) {
420:                        // this exception will be caught & rethrown by this very method.
421:                        // getInit() returning false indicates some initialization issue,
422:                        // which in turn prevents the InitableBroker from passing a
423:                        // reference to a working instance of the initable to the client.
424:                        throw new InitializationException(
425:                                "init() failed to initialize service " + name);
426:                    }
427:                    return service;
428:                } catch (InitializationException e) {
429:                    throw new InstantiationException("Service " + name
430:                            + " failed to initialize", e);
431:                }
432:            }
433:
434:            /**
435:             * Retrieves an instance of a Service without triggering late
436:             * initialization.
437:             *
438:             * Early initialization of a Service can require access to Service
439:             * properties.  The Service must have its name and serviceBroker
440:             * set by then.  Therefore, before calling
441:             * Initable.initClass(Object), the class must be instantiated with
442:             * InitableBroker.getInitableInstance(), and
443:             * Service.setServiceBroker() and Service.setName() must be
444:             * called.  This calls for two - level accessing the Services
445:             * instances.
446:             *
447:             * @param name The name of the service requested.
448:             * @exception InstantiationException The service is unknown or
449:             * can't be initialized.
450:             */
451:            protected Service getServiceInstance(String name)
452:                    throws InstantiationException {
453:                Service service = (Service) services.get(name);
454:
455:                if (service == null) {
456:                    String className = mapping.getString(name);
457:                    if (StringUtils.isEmpty(className)) {
458:                        throw new InstantiationException(
459:                                "ServiceBroker: unknown service " + name
460:                                        + " requested");
461:                    }
462:                    try {
463:                        service = (Service) services.get(className);
464:
465:                        if (service == null) {
466:                            try {
467:                                service = (Service) Class.forName(className)
468:                                        .newInstance();
469:                            }
470:                            // those two errors must be passed to the VM
471:                            catch (ThreadDeath t) {
472:                                throw t;
473:                            } catch (OutOfMemoryError t) {
474:                                throw t;
475:                            } catch (Throwable t) {
476:                                // Used to indicate error condition.
477:                                String msg = null;
478:
479:                                if (t instanceof  NoClassDefFoundError) {
480:                                    msg = "A class referenced by "
481:                                            + className
482:                                            + " is unavailable. Check your jars and classes.";
483:                                } else if (t instanceof  ClassNotFoundException) {
484:                                    msg = "Class "
485:                                            + className
486:                                            + " is unavailable. Check your jars and classes.";
487:                                } else if (t instanceof  ClassCastException) {
488:                                    msg = "Class "
489:                                            + className
490:                                            + " doesn't implement the Service interface";
491:                                } else {
492:                                    msg = "Failed to instantiate " + className;
493:                                }
494:
495:                                throw new InstantiationException(msg, t);
496:                            }
497:                        }
498:                    } catch (ClassCastException e) {
499:                        throw new InstantiationException(
500:                                "ServiceBroker: Class "
501:                                        + className
502:                                        + " does not implement Service interface.",
503:                                e);
504:                    } catch (InstantiationException e) {
505:                        throw new InstantiationException(
506:                                "Failed to instantiate service " + name, e);
507:                    }
508:                    service.setServiceBroker(this );
509:                    service.setName(name);
510:                    services.put(name, service);
511:                }
512:
513:                return service;
514:            }
515:
516:            /**
517:             * Returns the configuration for the specified service.
518:             *
519:             * @param name The name of the service.
520:             * @return Configuration of requested Service.
521:             */
522:            public Configuration getConfiguration(String name) {
523:                return configuration.subset(SERVICE_PREFIX + name);
524:            }
525:
526:            /**
527:             * Set the application root.
528:             *
529:             * @param applicationRoot application root
530:             */
531:            public void setApplicationRoot(String applicationRoot) {
532:                this .applicationRoot = applicationRoot;
533:            }
534:
535:            /**
536:             * Get the application root as set by
537:             * the parent application.
538:             *
539:             * @return String application root
540:             */
541:            public String getApplicationRoot() {
542:                return applicationRoot;
543:            }
544:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.