WvStreams
servmgr.cc
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * XPLC - Cross-Platform Lightweight Components
00004  * Copyright (C) 2000-2004, Pierre Phaneuf
00005  * Copyright (C) 2000, Stéphane Lajoie
00006  * Copyright (C) 2002-2004, Net Integration Technologies, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA
00022  */
00023 
00024 #include <xplc/core.h>
00025 #include <xplc/utils.h>
00026 #include <xplc/factory.h>
00027 #include "servmgr.h"
00028 #include "catmgr.h"
00029 #include "statichandler.h"
00030 #include "moduleloader.h"
00031 #include "monikers.h"
00032 #include "new.h"
00033 #include "modulemgr.h"
00034 
00035 UUID_MAP_BEGIN(ServiceManager)
00036   UUID_MAP_ENTRY(IObject)
00037   UUID_MAP_ENTRY(IServiceManager)
00038   UUID_MAP_END
00039 
00040 static ServiceManager* singleton;
00041 
00042 IServiceManager* XPLC_getServiceManager() {
00043   if(singleton)
00044     singleton->addRef();
00045   else {
00046     IStaticServiceHandler* handler;
00047     IStaticServiceHandler* handler2;
00048     IMonikerService* monikers;
00049     IObject* obj;
00050 
00051     singleton = new ServiceManager;
00052 
00053     if(!singleton)
00054       return 0;
00055 
00056     handler = new StaticServiceHandler;
00057     if(!handler) {
00058       singleton->release();
00059       return 0;
00060     }
00061 
00062     /*
00063      * Populate the static service handler.
00064      */
00065 
00066     handler2 = new StaticServiceHandler;
00067     if(handler2) {
00068       handler->addObject(XPLC_staticServiceHandler, handler2);
00069       singleton->addHandler(handler2);
00070       handler2->release();
00071     } else {
00072       singleton->release();
00073       return 0;
00074     }
00075 
00076     obj = new NewMoniker;
00077     if(obj) {
00078       handler->addObject(XPLC_newMoniker, obj);
00079       obj->release();
00080     }
00081 
00082     obj = new CategoryManager;
00083     if(obj) {
00084       handler->addObject(XPLC_categoryManager, obj);
00085       obj->release();
00086     }
00087 
00088     obj = new ModuleLoader;
00089     if(obj) {
00090       handler->addObject(XPLC_moduleLoader, obj);
00091       obj->release();
00092     }
00093 
00094     obj = new ModuleManagerFactory;
00095     if(obj) {
00096       handler->addObject(XPLC_moduleManagerFactory, obj);
00097       obj->release();
00098     }
00099 
00100     monikers = new MonikerService;
00101     if(monikers) {
00102       monikers->registerObject("new", XPLC_newMoniker);
00103       handler->addObject(XPLC_monikers, monikers);
00104       monikers->release();
00105     }
00106 
00107     singleton->addHandler(handler);
00108 
00109     handler->release();
00110   }
00111 
00112   return singleton;
00113 }
00114 
00115 ServiceManager::~ServiceManager() {
00116   HandlerNode* next;
00117 
00118   while(handlers) {
00119     next = handlers->next;
00120     delete handlers;
00121     handlers = next;
00122   }
00123 
00124   if(singleton == this)
00125     singleton = 0;
00126 }
00127 
00128 void ServiceManager::addHandler(IServiceHandler* aHandler) {
00129   HandlerNode* node;
00130   HandlerNode** ptr;
00131 
00132   ptr = &handlers;
00133   node = *ptr;
00134   while(node) {
00135     if(node->handler == aHandler)
00136       break;
00137 
00138     if(node->intercept) {
00139       ptr = &node->next;
00140     }
00141     node = node->next;
00142   }
00143 
00144   /*
00145    * The handler is already there.
00146    */
00147   if(node)
00148     return;
00149 
00150   node = new HandlerNode(aHandler, *ptr, false);
00151   *ptr = node;
00152 }
00153 
00154 void ServiceManager::addFirstHandler(IServiceHandler* aHandler) {
00155   HandlerNode* node;
00156 
00157   node = handlers;
00158   while(node) {
00159     if(node->handler == aHandler)
00160       break;
00161 
00162     node = node->next;
00163   }
00164 
00165   /*
00166    * The handler is already there.
00167    */
00168   if(node)
00169     return;
00170 
00171   node = new HandlerNode(aHandler, handlers, true);
00172   handlers = node;
00173 }
00174 
00175 void ServiceManager::addLastHandler(IServiceHandler* aHandler) {
00176   HandlerNode* node;
00177   HandlerNode** ptr;
00178 
00179   ptr = &handlers;
00180   node = *ptr;
00181   while(node) {
00182     if(node->handler == aHandler)
00183       break;
00184 
00185     ptr = &node->next;
00186     node = *ptr;
00187   }
00188 
00189   /*
00190    * The handler is already there.
00191    */
00192   if(node)
00193     return;
00194 
00195   node = new HandlerNode(aHandler, *ptr, false);
00196   *ptr = node;
00197 }
00198 
00199 void ServiceManager::removeHandler(IServiceHandler* aHandler) {
00200   HandlerNode* node;
00201   HandlerNode** ptr;
00202 
00203   node = handlers;
00204   ptr = &handlers;
00205   while(node) {
00206     if(node->handler == aHandler) {
00207       *ptr = node->next;
00208       delete node;
00209       break;
00210     }
00211 
00212     ptr = &node->next;
00213     node = *ptr;
00214   }
00215 }
00216 
00217 IObject* ServiceManager::getObject(const UUID& aUuid) {
00218   IObject* obj;
00219   HandlerNode* handler;
00220 
00221   handler = handlers;
00222   while(handler) {
00223     obj = handler->handler->getObject(aUuid);
00224 
00225     /*
00226      * No need to addRef the object, the handler does it for us.
00227      */
00228     if(obj)
00229       return obj;
00230 
00231     handler = handler->next;
00232   }
00233 
00234   return 0;
00235 }
00236