/* * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at . * * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT * WARRANTY OF ANY KIND, either express or implied. See the License for the specific * language governing rights and limitations under the License. * * The Original Code is the Venice Web Communities System. * * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.dynamo.app; import java.util.*; import org.apache.log4j.Logger; import com.silverwrist.dynamo.except.*; import com.silverwrist.dynamo.iface.*; import com.silverwrist.dynamo.util.*; class ApplicationServiceManager implements HookServiceProviders { /*-------------------------------------------------------------------------------- * Internal class implementing initialization services *-------------------------------------------------------------------------------- */ private class InitServices extends BaseDelegatingServiceProvider { /*==================================================================== * Constructors *==================================================================== */ InitServices() { super("Initialization Services"); } // end constructor InitServices(ServiceProvider sp) { super("Initialization Services",sp); } // end constructor /*==================================================================== * Overrides from class BaseDelegatingServiceProvider *==================================================================== */ /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass) { Object rc = m_init_service_cache.get(klass); if (rc!=null) // found in the cache! return rc; for (int i=(m_init_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i)); rc = sp.queryService(klass); m_init_service_cache.put(klass,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for rc = m_init_services.get(klass); if (rc!=null) { // cache the service m_init_service_cache.put(klass,rc); return rc; } // end if return super.queryService(klass); } // end queryService /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @param serviceid ID for the service to be requested, to further discriminate between requests. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass, String serviceid) { ServiceKey key = new ServiceKey(klass,serviceid); Object rc = m_init_service_cache.get(key); if (rc!=null) return rc; for (int i=(m_init_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_init_service_hooks.get(i)); rc = sp.queryService(klass,serviceid); m_init_service_cache.put(key,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for try { // call through to superclass return super.queryService(klass,serviceid); } // end try catch (NoSuchServiceException e) { // OK, try it without the service ID rc = queryService(klass); m_init_service_cache.put(key,rc); return rc; } // end catch } // end queryService } // end class InitServices /*-------------------------------------------------------------------------------- * Internal class implementing runtime services *-------------------------------------------------------------------------------- */ private class RuntimeServices extends BaseDelegatingServiceProvider { /*==================================================================== * Constructors *==================================================================== */ RuntimeServices() { super("Application Services"); } // end constructor RuntimeServices(ServiceProvider sp) { super("Application Services",sp); } // end constructor /*==================================================================== * Overrides from class BaseDelegatingServiceProvider *==================================================================== */ /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass) { Object rc = m_runtime_service_cache.get(klass); if (rc!=null) return rc; for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i)); rc = sp.queryService(klass); m_runtime_service_cache.put(klass,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for rc = m_runtime_services.get(klass); if (rc!=null) { // cache the service m_runtime_service_cache.put(klass,rc); return rc; } // end if return super.queryService(klass); } // end queryService /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @param serviceid ID for the service to be requested, to further discriminate between requests. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass, String serviceid) { ServiceKey key = new ServiceKey(klass,serviceid); Object rc = m_runtime_service_cache.get(key); if (rc!=null) return rc; for (int i=(m_runtime_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_runtime_service_hooks.get(i)); rc = sp.queryService(klass,serviceid); m_runtime_service_cache.put(key,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for try { // call through to superclass return super.queryService(klass,serviceid); } // end try catch (NoSuchServiceException e) { // OK, try it without the service ID rc = queryService(klass); m_runtime_service_cache.put(key,rc); return rc; } // end catch } // end queryService } // end class RuntimeServices /*-------------------------------------------------------------------------------- * Internal class implementing output services *-------------------------------------------------------------------------------- */ private class OutputServices extends BaseDelegatingServiceProvider { /*==================================================================== * Constructors *==================================================================== */ OutputServices() { super("Application Output Services"); } // end constructor OutputServices(ServiceProvider sp) { super("Application Output Services",sp); } // end constructor /*==================================================================== * Overrides from class BaseDelegatingServiceProvider *==================================================================== */ /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass) { Object rc = m_output_service_cache.get(klass); if (rc!=null) return rc; for (int i=(m_output_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i)); rc = sp.queryService(klass); m_output_service_cache.put(klass,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for rc = m_output_services.get(klass); if (rc!=null) { // cache the service m_output_service_cache.put(klass,rc); return rc; } // end if return super.queryService(klass); } // end queryService /** * Queries this object for a specified service. * * @param klass The class of the object that should be returned as a service. * @param serviceid ID for the service to be requested, to further discriminate between requests. * @return A service object. The service object is guaranteed to be of the class * specified by klass; that is, if queryService(klass) * yields some object x, then the expression klass.isInstance(x) * is true. * @exception com.silverwrist.dynamo.except.NoSuchServiceException If no service is available in * the specified class. */ public Object queryService(Class klass, String serviceid) { ServiceKey key = new ServiceKey(klass,serviceid); Object rc = m_output_service_cache.get(key); if (rc!=null) return rc; for (int i=(m_output_service_hooks.size()-1); i>=0; i--) { // call the hooks try { // get hooks in reverse order of installation and try them ServiceProvider sp = (ServiceProvider)(m_output_service_hooks.get(i)); rc = sp.queryService(klass,serviceid); m_output_service_cache.put(key,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for try { // call through to superclass return super.queryService(klass,serviceid); } // end try catch (NoSuchServiceException e) { // OK, try it without the service ID rc = queryService(klass); m_output_service_cache.put(key,rc); return rc; } // end catch } // end queryService } // end class OutputServices /*-------------------------------------------------------------------------------- * Internal class implementing removal of init service hook *-------------------------------------------------------------------------------- */ private class RemoveInitServiceHook implements ComponentShutdown { /*==================================================================== * Attributes *==================================================================== */ private ServiceProvider m_sp; /*==================================================================== * Constructor *==================================================================== */ RemoveInitServiceHook(ServiceProvider sp) { m_sp = sp; } // end constructor /*==================================================================== * Implementations from interface ComponentShutdown *==================================================================== */ public void shutdown() { m_init_service_hooks.remove(m_sp); m_init_service_cache.clear(); } // end shutdown } // end class RemoveInitServiceHook /*-------------------------------------------------------------------------------- * Internal class implementing removal of runtime service hook *-------------------------------------------------------------------------------- */ private class RemoveRuntimeServiceHook implements ComponentShutdown { /*==================================================================== * Attributes *==================================================================== */ private ServiceProvider m_sp; /*==================================================================== * Constructor *==================================================================== */ RemoveRuntimeServiceHook(ServiceProvider sp) { m_sp = sp; } // end constructor /*==================================================================== * Implementations from interface ComponentShutdown *==================================================================== */ public void shutdown() { m_runtime_service_hooks.remove(m_sp); m_runtime_service_cache.clear(); } // end shutdown } // end class RemoveRuntimeServiceHook /*-------------------------------------------------------------------------------- * Internal class implementing removal of output service hook *-------------------------------------------------------------------------------- */ private class RemoveOutputServiceHook implements ComponentShutdown { /*==================================================================== * Attributes *==================================================================== */ private ServiceProvider m_sp; /*==================================================================== * Constructor *==================================================================== */ RemoveOutputServiceHook(ServiceProvider sp) { m_sp = sp; } // end constructor /*==================================================================== * Implementations from interface ComponentShutdown *==================================================================== */ public void shutdown() { m_output_service_hooks.remove(m_sp); m_output_service_cache.clear(); } // end shutdown } // end class RemoveOutputServiceHook /*-------------------------------------------------------------------------------- * Static data members *-------------------------------------------------------------------------------- */ private static Logger logger = Logger.getLogger(ApplicationServiceManager.class); /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ private Hashtable m_init_services = new Hashtable(); // initializing services private Vector m_init_service_hooks = new Vector(); // hooks for initializing services private Hashtable m_init_service_cache = new Hashtable(); // cache of init services private Hashtable m_runtime_services = new Hashtable(); // runtime services private Vector m_runtime_service_hooks = new Vector(); // hooks for runtime services private Hashtable m_runtime_service_cache = new Hashtable(); // cache of runtime services private Hashtable m_output_services = new Hashtable(); // output services private Vector m_output_service_hooks = new Vector(); // hooks for output services private Hashtable m_output_service_cache = new Hashtable(); // cache of output services private InitServices m_solo_init = null; // only one "null" init service private RuntimeServices m_solo_runtime = null; // only one "null" runtime service private OutputServices m_solo_output = null; // only one "null" output service /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ ApplicationServiceManager() { // do nothing } // end constructor /*-------------------------------------------------------------------------------- * Implementations from interface HookServiceProviders *-------------------------------------------------------------------------------- */ public ServiceProvider getCurrentInitServices() { return createInitServices(); } // end getCurrentInitServices public ServiceProvider getCurrentRuntimeServices() { return createRuntimeServices(); } // end getCurrentRuntimeServices public ServiceProvider getCurrentOutputServices() { return createOutputServices(); } // end getCurrentOutputServices public ComponentShutdown hookInitServiceProvider(ServiceProvider sp) { m_init_service_hooks.add(sp); m_init_service_cache.clear(); return new RemoveInitServiceHook(sp); } // end hookInitServiceProvider public ComponentShutdown hookRuntimeServiceProvider(ServiceProvider sp) { m_runtime_service_hooks.add(sp); m_runtime_service_cache.clear(); return new RemoveRuntimeServiceHook(sp); } // end hookRuntimeServiceProvider public ComponentShutdown hookOutputServiceProvider(ServiceProvider sp) { m_output_service_hooks.add(sp); m_output_service_cache.clear(); return new RemoveOutputServiceHook(sp); } // end hookOutputServiceProvider /*-------------------------------------------------------------------------------- * External operations *-------------------------------------------------------------------------------- */ void addInitService(Class klass, Object svc) { m_init_services.put(klass,svc); } // end addInitService void addRuntimeService(Class klass, Object svc) { m_runtime_services.put(klass,svc); } // end addRuntimeService void addOutputService(Class klass, Object svc) { m_output_services.put(klass,svc); } // end addRuntimeService ServiceProvider createInitServices() { if (m_solo_init==null) m_solo_init = new InitServices(); return m_solo_init; } // end createInitServices ServiceProvider createInitServices(ServiceProvider sp) { if (sp==null) return createInitServices(); return new InitServices(sp); } // end createRuntimeServices ServiceProvider createRuntimeServices() { if (m_solo_runtime==null) m_solo_runtime = new RuntimeServices(); return m_solo_runtime; } // end createRuntimeServices ServiceProvider createRuntimeServices(ServiceProvider sp) { if (sp==null) return createRuntimeServices(); return new RuntimeServices(sp); } // end createRuntimeServices ServiceProvider createOutputServices() { if (m_solo_output==null) m_solo_output = new OutputServices(); return m_solo_output; } // end createOutputServices ServiceProvider createOutputServices(ServiceProvider sp) { if (sp==null) return createOutputServices(); return new OutputServices(sp); } // end createOutputServices } // end class ApplicationServiceManager