/* * 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) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.dynamo.module; import java.util.*; import com.silverwrist.dynamo.except.*; import com.silverwrist.dynamo.iface.*; import com.silverwrist.dynamo.util.*; class InstallServiceManager { /*-------------------------------------------------------------------------------- * Internal class implementing the install service provider *-------------------------------------------------------------------------------- */ private class Services extends BaseDelegatingServiceProvider { /*==================================================================== * Constructors *==================================================================== */ Services() { super("Module Initialization Services"); } // end constructor Services(ServiceProvider delegate) { super("Module Initialization Services",delegate); } // 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_service_cache.get(klass); if (rc!=null) return rc; for (int i=(m_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_service_hooks.get(i)); rc = sp.queryService(klass); m_service_cache.put(klass,rc); return rc; } // end try catch (NoSuchServiceException e) { // cycle around and keep trying } // end catch } // end for rc = m_services.get(klass); if (rc!=null) { // cache the service m_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_service_cache.get(key); if (rc!=null) return rc; for (int i=(m_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_service_hooks.get(i)); rc = sp.queryService(klass,serviceid); m_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_service_cache.put(key,rc); return rc; } // end catch } // end queryService } // end class Services /*-------------------------------------------------------------------------------- * Internal class for removing hooks *-------------------------------------------------------------------------------- */ private class RemoveHook implements ComponentShutdown { /*==================================================================== * Attributes *==================================================================== */ private ServiceProvider m_sp; /*==================================================================== * Constructor *==================================================================== */ RemoveHook(ServiceProvider sp) { m_sp = sp; } // end constructor /*==================================================================== * Implementations from interface ComponentShutdown *==================================================================== */ public void shutdown() { m_service_hooks.remove(m_sp); m_service_cache.clear(); } // end shutdown } // end class RemoveHook /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- */ private Hashtable m_services = new Hashtable(); private Vector m_service_hooks = new Vector(); private Hashtable m_service_cache = new Hashtable(); private ServiceProvider m_base = null; /*-------------------------------------------------------------------------------- * Constructor *-------------------------------------------------------------------------------- */ InstallServiceManager() { // do nothing } // end constructor /*-------------------------------------------------------------------------------- * External operations *-------------------------------------------------------------------------------- */ void addService(Class klass, Object svc) { m_services.put(klass,svc); } // end addService synchronized ServiceProvider getServiceProvider() { if (m_base==null) m_base = new Services(); return m_base; } // end getServiceProvider ServiceProvider getServiceProvider(ServiceProvider delegate) { if (delegate==null) return this.getServiceProvider(); else return new Services(delegate); } // end getServiceProvider ComponentShutdown hook(ServiceProvider sp) { m_service_hooks.add(sp); m_service_cache.clear(); return new RemoveHook(sp); } // end hook void dispose() { m_services.clear(); m_service_hooks.clear(); m_service_cache.clear(); m_base = null; } // end dispose } // end class InstallServiceManager