00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00036 #include "OW_config.h"
00037 #include "OW_CppProviderIFC.hpp"
00038 #include "OW_SharedLibraryException.hpp"
00039 #include "OW_SharedLibraryLoader.hpp"
00040 #include "OW_Format.hpp"
00041 #include "OW_SignalScope.hpp"
00042 #include "OW_ConfigOpts.hpp"
00043 #include "OW_FileSystem.hpp"
00044 #include "OW_CppProxyProvider.hpp"
00045 #include "OW_NoSuchProviderException.hpp"
00046 #include "OW_Assertion.hpp"
00047 #include "OW_IntrusiveCountableBase.hpp"
00048 #include "OW_NonRecursiveMutex.hpp"
00049 #include "OW_NonRecursiveMutexLock.hpp"
00050 #include "OW_Condition.hpp"
00051 #include "OW_ExceptionIds.hpp"
00052 #include "OW_RepositoryIFC.hpp"
00053 
00054 namespace OW_NAMESPACE
00055 {
00056 
00057 OW_DECLARE_EXCEPTION(CppProviderIFC);
00058 OW_DEFINE_EXCEPTION_WITH_ID(CppProviderIFC);
00059 
00060 
00061 typedef CppProviderBaseIFC* (*ProviderCreationFunc)();
00062 typedef const char* (*versionFunc_t)();
00063 namespace
00064 {
00065 const String COMPONENT_NAME("ow.provider.cpp.ifc");
00066 
00067 class ProvRegEnv : public ProviderRegistrationEnvironmentIFC
00068 {
00069 public:
00070    ProvRegEnv(const ProviderEnvironmentIFCRef& env)
00071       : ProviderRegistrationEnvironmentIFC()
00072       , m_env(env)
00073    {
00074    }
00075 
00076    virtual ~ProvRegEnv()
00077    {
00078    }
00079 
00080    virtual RepositoryIFCRef getRepository() const
00081    {
00082       return m_env->getRepository();
00083    }
00084 
00085    virtual LoggerRef getLogger(const String& componentName) const
00086    {
00087       return m_env->getLogger(componentName);
00088    }
00089 
00090    virtual String getConfigItem(const String &name, const String& defRetVal="") const
00091    {
00092       return m_env->getConfigItem(name, defRetVal);
00093    }
00094 
00095    virtual StringArray getMultiConfigItem(const String &itemName, 
00096       const StringArray& defRetVal, const char* tokenizeSeparator = 0) const
00097    {
00098       return m_env->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00099    }
00100 
00101    virtual ProviderRegistrationEnvironmentIFCRef clone() const
00102    {
00103       return ProviderRegistrationEnvironmentIFCRef(new ProvRegEnv(m_env));
00104    }
00105 
00106 private:
00107    ProviderEnvironmentIFCRef m_env;
00108 };
00109 
00110 ProviderRegistrationEnvironmentIFCRef
00111 createProvRegEnv(const ProviderEnvironmentIFCRef& env)
00112 {
00113    return ProviderRegistrationEnvironmentIFCRef(new ProvRegEnv(env));
00114 }
00115 
00116 }     
00117 
00118 const char* const CppProviderIFC::CREATIONFUNC = "createProvider";
00119 
00121 class CppProviderIFC::CppProviderInitializationHelper : public IntrusiveCountableBase
00122 {
00123 public:
00124 
00125    explicit CppProviderInitializationHelper(const CppProviderBaseIFCRef& provider)
00126       : m_initialized(false)
00127       , m_initializeFailed(false)
00128       , m_provider(provider)
00129    {
00130 
00131    }
00132 
00133    
00134    bool waitUntilInitialized() const
00135    {
00136       NonRecursiveMutexLock l(m_initializedGuard);
00137       while (!m_initialized && !m_initializeFailed)
00138       {
00139          m_initializedCond.wait(l);
00140       }
00141       return !m_initializeFailed;
00142    }
00143    
00144    void initialize(const ProviderEnvironmentIFCRef& env)
00145    {
00146       try
00147       {
00148          m_provider->initialize(env);
00149       }
00150       catch (...)
00151       {
00152          NonRecursiveMutexLock l(m_initializedGuard);
00153          m_initializeFailed = true;
00154          m_initializedCond.notifyAll();
00155          throw;
00156       }
00157 
00158       NonRecursiveMutexLock l(m_initializedGuard);
00159       m_initialized = true;
00160       m_initializedCond.notifyAll();
00161    }
00162 
00163    CppProviderBaseIFCRef getProvider() const
00164    {
00165       return m_provider;
00166    }
00167 private:
00168    bool m_initialized;
00169    bool m_initializeFailed;
00170    mutable NonRecursiveMutex m_initializedGuard;
00171    mutable Condition m_initializedCond;
00172    CppProviderBaseIFCRef m_provider;
00173 };
00174 
00176 CppProviderIFC::CppProviderIFC()
00177    : ProviderIFCBaseIFC()
00178    , m_provs()
00179    , m_guard()
00180    , m_noUnloadProviders()
00181    , m_loadDone(false)
00182 {
00183 }
00185 CppProviderIFC::~CppProviderIFC()
00186 {
00187    try
00188    {
00189       ProviderMap::iterator it = m_provs.begin();
00190       while (it != m_provs.end())
00191       {
00192          it->second = 0;
00193          it++;
00194       }
00195    
00196       m_provs.clear();
00197    
00198       for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00199       {
00200          m_noUnloadProviders[i].setNull();
00201       }
00202    
00203       m_noUnloadProviders.clear();
00204    }
00205    catch (...)
00206    {
00207       
00208    }
00209 }
00211 void
00212 CppProviderIFC::doInit(const ProviderEnvironmentIFCRef& env,
00213    InstanceProviderInfoArray& i,
00214    SecondaryInstanceProviderInfoArray& si,
00215 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00216    AssociatorProviderInfoArray& a,
00217 #endif
00218    MethodProviderInfoArray& m,
00219    IndicationProviderInfoArray& ind)
00220 {
00221    loadProviders(env, i,
00222       si,
00223 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00224       a,
00225 #endif
00226       m,
00227       ind);
00228 }
00230 InstanceProviderIFCRef
00231 CppProviderIFC::doGetInstanceProvider(const ProviderEnvironmentIFCRef& env,
00232    const char* provIdString)
00233 {
00234    CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00235    if (pProv)
00236    {
00237       CppInstanceProviderIFC* pIP = pProv->getInstanceProvider();
00238       if (pIP)
00239       {
00240          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00241             Format("CPPProviderIFC found instance provider %1", provIdString));
00242          CppInstanceProviderIFCRef ipRef(pProv.getLibRef(), pIP);
00243 
00244          return InstanceProviderIFCRef(new CppInstanceProviderProxy(ipRef));
00245       }
00246       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an instance provider",
00247          provIdString));
00248    }
00249    OW_THROW(NoSuchProviderException, provIdString);
00250 }
00252 SecondaryInstanceProviderIFCRef
00253 CppProviderIFC::doGetSecondaryInstanceProvider(const ProviderEnvironmentIFCRef& env,
00254    const char* provIdString)
00255 {
00256    CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00257    if (pProv)
00258    {
00259       CppSecondaryInstanceProviderIFC* pIP = pProv->getSecondaryInstanceProvider();
00260       if (pIP)
00261       {
00262          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00263             Format("CPPProviderIFC found secondary instance provider %1", provIdString));
00264          CppSecondaryInstanceProviderIFCRef ipRef(pProv.getLibRef(), pIP);
00265 
00266          return SecondaryInstanceProviderIFCRef(new CppSecondaryInstanceProviderProxy(ipRef));
00267       }
00268       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not a secondary instance provider",
00269          provIdString));
00270    }
00271    OW_THROW(NoSuchProviderException, provIdString);
00272 }
00274 IndicationExportProviderIFCRefArray
00275 CppProviderIFC::doGetIndicationExportProviders(const ProviderEnvironmentIFCRef&)
00276 {
00277    IndicationExportProviderIFCRefArray rvra;
00278    for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00279    {
00280       CppProviderBaseIFCRef pProv = m_noUnloadProviders[i];
00281       CppIndicationExportProviderIFC* pIEP =
00282          pProv->getIndicationExportProvider();
00283       if (pIEP)
00284       {
00285          CppIndicationExportProviderIFCRef iepRef(pProv.getLibRef(), pIEP);
00286 
00287          rvra.append(
00288             IndicationExportProviderIFCRef(new
00289                CppIndicationExportProviderProxy(iepRef)));
00290       }
00291    }
00292    return rvra;
00293 }
00295 PolledProviderIFCRefArray
00296 CppProviderIFC::doGetPolledProviders(const ProviderEnvironmentIFCRef&)
00297 {
00298    PolledProviderIFCRefArray rvra;
00299    for (size_t i = 0; i < m_noUnloadProviders.size(); i++)
00300    {
00301       CppProviderBaseIFCRef pProv = m_noUnloadProviders[i];
00302       CppPolledProviderIFC* pPP = pProv->getPolledProvider();
00303       if (pPP)
00304       {
00305          CppPolledProviderIFCRef ppRef(pProv.getLibRef(), pPP);
00306 
00307          rvra.append(
00308             PolledProviderIFCRef(new
00309                CppPolledProviderProxy(ppRef)));
00310       }
00311    }
00312    return rvra;
00313 }
00315 MethodProviderIFCRef
00316 CppProviderIFC::doGetMethodProvider(const ProviderEnvironmentIFCRef& env,
00317    const char* provIdString)
00318 {
00319    CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00320    if (pProv)
00321    {
00322       CppMethodProviderIFC* pMP = pProv->getMethodProvider();
00323       if (pMP)
00324       {
00325          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found method provider %1",
00326             provIdString));
00327          CppMethodProviderIFCRef mpRef(pProv.getLibRef(), pMP);
00328 
00329          return MethodProviderIFCRef(
00330             new CppMethodProviderProxy(mpRef));
00331       }
00332       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not a method provider",
00333          provIdString));
00334    }
00335    OW_THROW(NoSuchProviderException, provIdString);
00336 }
00337 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00338 
00339 AssociatorProviderIFCRef
00340 CppProviderIFC::doGetAssociatorProvider(const ProviderEnvironmentIFCRef& env,
00341    const char* provIdString)
00342 {
00343    CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00344    if (pProv)
00345    {
00346       CppAssociatorProviderIFC* pAP = pProv->getAssociatorProvider();
00347       if (pAP)
00348       {
00349          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found associator provider %1",
00350             provIdString));
00351          CppAssociatorProviderIFCRef apRef(pProv.getLibRef(), pAP);
00352 
00353          return AssociatorProviderIFCRef(new
00354             CppAssociatorProviderProxy(apRef));
00355       }
00356       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an associator provider",
00357          provIdString));
00358    }
00359    OW_THROW(NoSuchProviderException, provIdString);
00360 }
00361 #endif
00362 
00363 IndicationProviderIFCRef
00364 CppProviderIFC::doGetIndicationProvider(const ProviderEnvironmentIFCRef& env,
00365    const char* provIdString)
00366 {
00367    CppProviderBaseIFCRef pProv = getProvider(env, provIdString);
00368    if (pProv)
00369    {
00370       CppIndicationProviderIFC* pAP = pProv->getIndicationProvider();
00371       if (pAP)
00372       {
00373          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("CPPProviderIFC found indication provider %1",
00374             provIdString));
00375 
00376          IndicationProviderMap::const_iterator ci = m_indicationProviders.find(provIdString);
00377          if (ci != m_indicationProviders.end())
00378          {
00379             return ci->second;
00380          }
00381 
00382          CppIndicationProviderIFCRef apRef(pProv.getLibRef(), pAP);
00383 
00384          IndicationProviderIFCRef rv(new
00385             CppIndicationProviderProxy(apRef));
00386          
00387          m_indicationProviders.insert(IndicationProviderMap::value_type(provIdString, rv));
00388 
00389          return rv;
00390       }
00391       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an indication provider",
00392          provIdString));
00393    }
00394    OW_THROW(NoSuchProviderException, provIdString);
00395 }
00397 void
00398 CppProviderIFC::loadProviders(const ProviderEnvironmentIFCRef& env,
00399    InstanceProviderInfoArray& instanceProviderInfo,
00400    SecondaryInstanceProviderInfoArray& secondaryInstanceProviderInfo,
00401 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00402    AssociatorProviderInfoArray& associatorProviderInfo,
00403 #endif
00404    MethodProviderInfoArray& methodProviderInfo,
00405    IndicationProviderInfoArray& indicationProviderInfo)
00406 {
00407    MutexLock ml(m_guard);
00408    if (m_loadDone)
00409    {
00410       return;
00411    }
00412    m_loadDone = true;
00413 
00414    
00415 
00416    SharedLibraryLoaderRef ldr =
00417       SharedLibraryLoader::createSharedLibraryLoader();
00418    if (!ldr)
00419    {
00420       const char* msg = "C++ provider ifc failed to get shared lib loader";
00421       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00422       OW_THROW(CppProviderIFCException, msg);
00423    }
00424 
00425    StringArray paths = env->getMultiConfigItem(
00426       ConfigOpts::CPPPROVIFC_PROV_LOCATION_opt, 
00427       String(OW_DEFAULT_CPPPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR), 
00428       OW_PATHNAME_SEPARATOR);
00429    for (StringArray::size_type i1 = 0; i1 < paths.size(); i1++)
00430    {
00431       StringArray dirEntries;
00432       if (!FileSystem::getDirectoryContents(paths[i1], dirEntries))
00433       {
00434          String msg(Format("C++ provider ifc failed getting contents of directory: %1", paths[i1]));
00435          OW_LOG_INFO(env->getLogger(COMPONENT_NAME), msg);
00436          continue; 
00437       }
00438       for (size_t i = 0; i < dirEntries.size(); i++)
00439       {
00440          if (!dirEntries[i].endsWith(OW_SHAREDLIB_EXTENSION))
00441          {
00442             continue;
00443          }
00444          String libName = paths[i1];
00445          libName += OW_FILENAME_SEPARATOR;
00446          libName += dirEntries[i];
00447 
00448 #ifdef OW_DARWIN
00449          if (!FileSystem::isLink(libName))
00450          {
00451             continue;
00452          }
00453 #endif // OW_DARWIN
00454    
00455          SharedLibraryRef theLib = ldr->loadSharedLibrary(libName,
00456             env->getLogger(COMPONENT_NAME));
00457          if (!theLib)
00458          {
00459             String msg(Format("C++ provider ifc failed to load library: %1", libName));
00460             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00461             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00462             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00463             OW_THROW(CppProviderIFCException, msg.c_str());
00464          }
00465          versionFunc_t versFunc;
00466          if (!theLib->getFunctionPointer("getOWVersion",
00467             versFunc))
00468          {
00469             String msg(Format("C++ provider ifc failed getting function pointer to \"getOWVersion\" from"
00470                " library: %1", libName));
00471             OW_LOG_INFO(env->getLogger(COMPONENT_NAME), msg);
00472             
00473             
00474             
00475             continue;
00476          }
00477          const char* strVer = (*versFunc)();
00478          if (strcmp(strVer, OW_VERSION))
00479          {
00480             String msg(Format("C++ provider ifc got invalid version from provider: %1", strVer));
00481             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00482             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00483             msg = Format("C++ provider ifc version: %1  provider version: %2  library: %3",
00484                OW_VERSION, strVer, libName);
00485             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00486             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00487             OW_THROW(CppProviderIFCException, msg.c_str());
00488          }
00489          ProviderCreationFunc createProvider;
00490          String creationFuncName = String(CREATIONFUNC) + "NO_ID";
00491          if (!theLib->getFunctionPointer(creationFuncName,
00492             createProvider))
00493          {
00494             
00495             
00496             String providerid = dirEntries[i];
00497             
00498             providerid = providerid.substring(3,
00499                providerid.length() - (strlen(OW_SHAREDLIB_EXTENSION) + 3));
00500 
00501             CppProviderBaseIFCRef p = getProvider(env, providerid.c_str(),
00502                dontStoreProvider, dontInitializeProvider);
00503 
00504             if (!p)
00505             {
00506                String msg(Format("C++ provider ifc: Libary %1 does not load", libName));
00507                OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), "****************************************");
00508                OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), msg);
00509                OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), "****************************************");
00510                OW_THROW(CppProviderIFCException, msg.c_str());
00511             }
00512 
00513             
00514             
00515             
00516             
00517             
00518             CppPolledProviderIFC* p_polledProv = p->getPolledProvider();
00519             CppIndicationExportProviderIFC* p_indExpProv =
00520                p->getIndicationExportProvider();
00521             if (p_polledProv || p_indExpProv)
00522             {
00523                if (p_indExpProv)
00524                {
00525                   OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00526                      Format("C++ provider ifc loaded indication export provider from lib: %1 - initializing", libName));
00527                }
00528 
00529                if (p_polledProv)
00530                {
00531                   OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00532                      Format("C++ provider ifc loaded polled provider from lib: %1 - initializing", libName));
00533                }
00534                CppProviderInitializationHelperRef p2(new CppProviderInitializationHelper(p));
00535                p2->initialize(env);
00536                p->setPersist(true);
00537                m_noUnloadProviders.append(p);
00538                m_provs[providerid] = p2;
00539             }
00540 
00541             CppInstanceProviderIFC* p_ip = p->getInstanceProvider();
00542             if (p_ip)
00543             {
00544                InstanceProviderInfo info;
00545                info.setProviderName(providerid);
00546                p_ip->getInstanceProviderInfoWithEnv(
00547                   createProvRegEnv(env), info);
00548                instanceProviderInfo.push_back(info);
00549             }
00550 
00551             CppSecondaryInstanceProviderIFC* p_sip =
00552                p->getSecondaryInstanceProvider();
00553 
00554             if (p_sip)
00555             {
00556                SecondaryInstanceProviderInfo info;
00557                info.setProviderName(providerid);
00558                p_sip->getSecondaryInstanceProviderInfoWithEnv(
00559                   createProvRegEnv(env), info);
00560                secondaryInstanceProviderInfo.push_back(info);
00561             }
00562 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00563             CppAssociatorProviderIFC* p_ap = p->getAssociatorProvider();
00564             if (p_ap)
00565             {
00566                AssociatorProviderInfo info;
00567                info.setProviderName(providerid);
00568                p_ap->getAssociatorProviderInfoWithEnv(
00569                   createProvRegEnv(env), info);
00570                associatorProviderInfo.push_back(info);
00571             }
00572 #endif
00573             CppMethodProviderIFC* p_mp = p->getMethodProvider();
00574             if (p_mp)
00575             {
00576                MethodProviderInfo info;
00577                info.setProviderName(providerid);
00578                p_mp->getMethodProviderInfoWithEnv(
00579                   createProvRegEnv(env), info);
00580                methodProviderInfo.push_back(info);
00581             }
00582             CppIndicationProviderIFC* p_indp = p->getIndicationProvider();
00583             if (p_indp)
00584             {
00585                IndicationProviderInfo info;
00586                info.setProviderName(providerid);
00587                p_indp->getIndicationProviderInfoWithEnv(
00588                   createProvRegEnv(env), info);
00589                indicationProviderInfo.push_back(info);
00590             }
00591 
00592             continue;
00593          }
00594 
00595          
00596          
00597          
00598          AutoPtr<CppProviderBaseIFC> pProv((*createProvider)());
00599          if (!pProv.get())
00600          {
00601             String msg(Format("C++ provider ifc: Libary %1 - %2 returned null provider", libName, creationFuncName));
00602             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00603             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), msg);
00604             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "****************************************");
00605             OW_THROW(CppProviderIFCException, msg.c_str());
00606          }
00607          CppPolledProviderIFC* p_itp = pProv->getPolledProvider();
00608          CppIndicationExportProviderIFC* p_iep =
00609             pProv->getIndicationExportProvider();
00610          if (p_itp || p_iep)
00611          {
00612             if (p_iep)
00613             {
00614                OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00615                   Format("C++ provider ifc loaded indication export provider from lib: %1 - initializing", libName));
00616             }
00617             if (p_itp)
00618             {
00619                OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00620                   Format("C++ provider ifc loaded  polled provider from lib: %1 - initializing",
00621                   libName));
00622             }
00623 
00624             pProv->initialize(env);
00625             m_noUnloadProviders.append(CppProviderBaseIFCRef(theLib,
00626                pProv.release()));
00627          }
00628       }
00629    }
00630 }
00631 
00633 
00634 CppProviderBaseIFCRef
00635 CppProviderIFC::loadProvider(const String& libName, LoggerRef logger)
00636 {
00637    String provId = libName.substring(libName.lastIndexOf(OW_FILENAME_SEPARATOR)+1);
00638    
00639    provId = provId.substring(3, provId.length() - (strlen(OW_SHAREDLIB_EXTENSION) + 3));
00640 
00641    SharedLibraryLoaderRef ldr = SharedLibraryLoader::createSharedLibraryLoader();
00642    if (!ldr)
00643    {
00644       OW_LOG_ERROR(logger, "C++ provider ifc FAILED to get shared lib loader");
00645       return CppProviderBaseIFCRef();
00646    }
00647 
00648    OW_LOG_DEBUG(logger, Format("CppProviderIFC::loadProvider loading library: %1", libName));
00649 
00650    SharedLibraryRef theLib = ldr->loadSharedLibrary(libName, logger);
00651 
00652    versionFunc_t versFunc;
00653    if (!theLib->getFunctionPointer("getOWVersion", versFunc))
00654    {
00655       OW_LOG_ERROR(logger, Format("C++ provider ifc failed getting function pointer to \"getOWVersion\" from library %1.", libName));
00656       return CppProviderBaseIFCRef();
00657    }
00658    const char* strVer = (*versFunc)();
00659    if (strcmp(strVer, OW_VERSION))
00660    {
00661       OW_LOG_ERROR(logger, "C++ provider ifc got invalid version from provider");
00662       OW_LOG_ERROR(logger, Format("C++ provider ifc version: %1  provider version: %2  library: %3",
00663                OW_VERSION, strVer, libName));
00664       return CppProviderBaseIFCRef();
00665    }
00666 
00667    ProviderCreationFunc createProvider;
00668    String creationFuncName = String(CREATIONFUNC) + provId;
00669    if (!theLib->getFunctionPointer(creationFuncName, createProvider))
00670    {
00671       OW_LOG_ERROR(logger, Format("C++ provider ifc: Libary %1 does not contain %2 function.",
00672          libName, creationFuncName));
00673       return CppProviderBaseIFCRef();
00674    }
00675 
00676    CppProviderBaseIFC* pProv = (*createProvider)();
00677 
00678    if (!pProv)
00679    {
00680       OW_LOG_ERROR(logger, Format("C++ provider ifc: Libary %1 -"
00681          " %2 returned null provider. Not loaded.", libName, creationFuncName));
00682       return CppProviderBaseIFCRef();
00683    }
00684 
00685    CppProviderBaseIFCRef rval(theLib, pProv);
00686 
00687    OW_LOG_DEBUG(logger, Format("C++ provider ifc successfully loaded library %1 for provider %2", libName, provId));
00688 
00689    return rval;
00690 }
00691 
00693 CppProviderBaseIFCRef
00694 CppProviderIFC::getProvider(
00695    const ProviderEnvironmentIFCRef& env, const char* provIdString,
00696    StoreProviderFlag storeP, InitializeProviderFlag initP)
00697 {
00698    OW_ASSERT((initP == initializeProvider && storeP == storeProvider) || (initP == dontInitializeProvider && storeP == dontStoreProvider));
00699 
00700    MutexLock ml(m_guard);
00701 
00702    String provId(provIdString);
00703    ProviderMap::iterator it = m_provs.find(provId);
00704    if (it != m_provs.end())
00705    {
00706       
00707       CppProviderInitializationHelperRef prov(it->second);
00708       
00709       ml.release();
00710 
00711       
00712       if (prov->waitUntilInitialized())
00713       {
00714          return prov->getProvider();
00715       }
00716       else
00717       {
00718          
00719          return CppProviderBaseIFCRef();
00720       }
00721    }
00722 
00723    String libName;
00724    CppProviderBaseIFCRef rval;
00725 
00726    StringArray paths = env->getMultiConfigItem(
00727       ConfigOpts::CPPPROVIFC_PROV_LOCATION_opt, 
00728       String(OW_DEFAULT_CPPPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR), 
00729       OW_PATHNAME_SEPARATOR);
00730    for (StringArray::size_type i = 0; i < paths.size(); i++)
00731    {
00732       libName = paths[i];
00733       libName += OW_FILENAME_SEPARATOR;
00734       libName += "lib";
00735       libName += provId;
00736       libName += OW_SHAREDLIB_EXTENSION;
00737 
00738       if (!FileSystem::exists(libName))
00739       {
00740          continue;
00741       }
00742 
00743       rval = loadProvider(libName, env->getLogger(COMPONENT_NAME));
00744 
00745       if (rval)
00746       {
00747          break;
00748       }
00749 
00750    }
00751 
00752    if (!rval)
00753    {
00754       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), 
00755          Format("C++ provider ifc failed to load library: %1 for provider id %2.", libName, provId));
00756       return rval;
00757    }
00758 
00759    if (initP == initializeProvider && storeP == storeProvider)
00760    {
00761       CppProviderInitializationHelperRef provInitHelper(new CppProviderInitializationHelper(rval));
00762 
00763       m_provs[provId] = provInitHelper;
00764       
00765       
00766       ml.release();
00767 
00768       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00769          Format("C++ provider ifc calling initialize for provider %1", provId));
00770 
00771       try
00772       {
00773          provInitHelper->initialize(env); 
00774       }
00775       catch (...)
00776       {
00777          
00778          MutexLock lock(m_guard);
00779          m_provs.erase(provId);
00780          throw;
00781       }
00782 
00783       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00784          Format("C++ provider ifc: provider %1 loaded and initialized", provId));
00785 
00786    }
00787    else
00788    {
00789       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), 
00790          Format("C++ provider ifc: provider %1 loaded but not initialized", provId));
00791    }
00792 
00793    return rval;
00794 }
00796 void
00797 CppProviderIFC::doUnloadProviders(const ProviderEnvironmentIFCRef& env)
00798 {
00799    String timeWindow = env->getConfigItem(ConfigOpts::CPPPROVIFC_PROV_TTL_opt, OW_DEFAULT_CPPPROVIFC_PROV_TTL);
00800    Int32 iTimeWindow;
00801    try
00802    {
00803       iTimeWindow = timeWindow.toInt32();
00804    }
00805    catch (const StringConversionException&)
00806    {
00807       iTimeWindow = String(OW_DEFAULT_CPPPROVIFC_PROV_TTL).toInt32();
00808    }
00809    if (iTimeWindow < 0)
00810    {
00811       return;
00812    }
00813    DateTime dt;
00814    dt.setToCurrent();
00815    MutexLock l(m_guard);
00816    for (ProviderMap::iterator iter = m_provs.begin();
00817         iter != m_provs.end();)
00818    {
00819       
00820       if (!iter->second->getProvider()->getPersist())
00821       {
00822          DateTime provDt = iter->second->getProvider()->getLastAccessTime();
00823          provDt.addMinutes(iTimeWindow);
00824          if (provDt < dt && iter->second->getProvider()->canUnload())
00825          {
00826             OW_LOG_INFO(env->getLogger(COMPONENT_NAME), Format("Unloading Provider %1",
00827                iter->first));
00828             iter->second = 0;
00829             m_provs.erase(iter++);
00830             continue;
00831          }
00832       }
00833 
00834       ++iter;
00835    }
00836 }
00837 
00838 void CppProviderIFC::doShuttingDown(const ProviderEnvironmentIFCRef& env)
00839 {
00840    
00841    
00842    MutexLock l(m_guard);
00843    ProviderMap provsCopy(m_provs);
00844    LoadedProviderArray noUnloadProvidersCopy(m_noUnloadProviders);
00845    l.release();
00846 
00847    ProviderMap::iterator it, itend = provsCopy.end();
00848    for (it = provsCopy.begin(); it != itend; ++it)
00849    {
00850       try
00851       {
00852          it->second->getProvider()->shuttingDown(env);
00853       }
00854       catch (Exception& e)
00855       {
00856          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Caught exception while calling shuttingDown() on provider: %1", e));
00857       }
00858    }
00859 
00860    
00861    
00862    for (LoadedProviderArray::iterator curProv = noUnloadProvidersCopy.begin(); curProv != noUnloadProvidersCopy.end(); ++curProv)
00863    {
00864       bool found(false);
00865 
00866       for (it = provsCopy.begin(); it != itend; ++it)
00867       {
00868          if (it->second->getProvider() == *curProv)
00869          {
00870             found = true;
00871             break;
00872          }
00873       }
00874 
00875       if (!found)
00876       {
00877          try
00878          {
00879             (*curProv)->shuttingDown(env);
00880          }
00881          catch (Exception& e)
00882          {
00883             OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Caught exception while calling shuttingDown() on provider: %1", e));
00884          }
00885       }
00886    }
00887 }
00888 
00889 } 
00890