OW_ProviderManager.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_ProviderManager.hpp"
00038 #include "OW_ProviderProxies.hpp"
00039 #include "OW_Format.hpp"
00040 #include "OW_CppPolledProviderIFC.hpp"
00041 #include "OW_CppIndicationExportProviderIFC.hpp"
00042 #include "OW_Assertion.hpp"
00043 #include "OW_CIMValue.hpp"
00044 #include "OW_CIMQualifier.hpp"
00045 #include "OW_CIMClass.hpp"
00046 #include "OW_CIMMethod.hpp"
00047 #include "OW_CIMProperty.hpp"
00048 #include "OW_CppProviderIFC.hpp"
00049 #include "OW_OperationContext.hpp"
00050 #include "OW_Platform.hpp"
00051 #include "OW_RepositoryIFC.hpp"
00052 #include "OW_ServiceIFCNames.hpp"
00053 #include "OW_ConfigOpts.hpp"
00054 
00055 namespace OW_NAMESPACE
00056 {
00057 
00058 String ProviderManager::COMPONENT_NAME("ow.owcimomd.ProviderManager");
00059 
00061 String
00062 ProviderManager::getName() const
00063 {
00064    return ServiceIFCNames::ProviderManager;
00065 }
00067 void ProviderManager::load(const ProviderIFCLoaderRef& IFCLoader, const ServiceEnvironmentIFCRef& env)
00068 {
00069    IFCLoader->loadIFCs(m_IFCArray);
00070 
00071    // the config can disable this.
00072    if (env->getConfigItem(ConfigOpts::DISABLE_CPP_PROVIDER_INTERFACE_opt, OW_DEFAULT_DISABLE_CPP_PROVIDER_INTERFACE) != "true")
00073    {
00074       // now the CPP provider is linked to the cimom, not loaded dynamically, So
00075       // we have to create it here.
00076       ProviderIFCBaseIFCRef::element_type cpppi(new CppProviderIFC);
00077       // 0 because there is no shared library.
00078       m_IFCArray.push_back(ProviderIFCBaseIFCRef(SharedLibraryRef(0), cpppi));
00079    }
00080 }
00081 
00083 void ProviderManager::shutdown()
00084 {
00085    MutexLock lock(m_guard);
00086    
00087    m_registeredInstProvs.clear();
00088    m_registeredSecInstProvs.clear();
00089 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00090    m_registeredAssocProvs.clear();
00091 #endif
00092    m_registeredMethProvs.clear();
00093    m_registeredPropProvs.clear();
00094    m_registeredIndProvs.clear();
00095    m_IFCArray.clear();
00096 
00097    m_env = 0;
00098 }
00099 
00100 namespace
00101 {
00103 class ProviderEnvironmentServiceEnvironmentWrapper : public ProviderEnvironmentIFC
00104 {
00105 public:
00106    ProviderEnvironmentServiceEnvironmentWrapper(ServiceEnvironmentIFCRef env_)
00107       : env(env_)
00108       , m_context()
00109    {}
00110    virtual CIMOMHandleIFCRef getCIMOMHandle() const
00111    {
00112       return env->getCIMOMHandle(m_context);
00113    }
00114    
00115    virtual CIMOMHandleIFCRef getRepositoryCIMOMHandle() const
00116    {
00117       return env->getCIMOMHandle(m_context, ServiceEnvironmentIFC::E_BYPASS_PROVIDERS);
00118    }
00119    
00120    virtual RepositoryIFCRef getRepository() const
00121    {
00122       return env->getRepository();
00123    }
00124    virtual LoggerRef getLogger() const
00125    {
00126       return env->getLogger();
00127    }
00128    virtual LoggerRef getLogger(const String& componentName) const
00129    {
00130       return env->getLogger(componentName);
00131    }
00132    virtual String getConfigItem(const String &name, const String& defRetVal="") const
00133    {
00134       return env->getConfigItem(name, defRetVal);
00135    }
00136    virtual StringArray getMultiConfigItem(const String &itemName, 
00137       const StringArray& defRetVal, const char* tokenizeSeparator = 0) const
00138    {
00139       return env->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00140    }
00141    virtual String getUserName() const
00142    {
00143       return Platform::getCurrentUserName();
00144    }
00145    virtual OperationContext& getOperationContext()
00146    {
00147       return m_context;
00148    }
00149    virtual ProviderEnvironmentIFCRef clone() const
00150    {
00151       return ProviderEnvironmentIFCRef(new ProviderEnvironmentServiceEnvironmentWrapper(env));
00152    }
00153 private:
00154    ServiceEnvironmentIFCRef env;
00155    mutable OperationContext m_context;
00156 };
00157 
00158 } // end anonymous namespace
00159 
00161 void ProviderManager::shuttingDown()
00162 {
00163    ProviderEnvironmentIFCRef penv = ProviderEnvironmentIFCRef(
00164       new ProviderEnvironmentServiceEnvironmentWrapper(m_env));
00165 
00166    size_t const n = m_IFCArray.size();
00167    for (size_t i = 0; i < n; ++i)
00168    {
00169       m_IFCArray[i]->shuttingDown(penv);
00170    }
00171 }
00172 
00173 namespace {
00175 void registerProviderInfo(
00176    const ProviderEnvironmentIFCRef& env,
00177    const String& name_,
00178    const ProviderIFCBaseIFCRef& ifc,
00179    const String& providerName,
00180    ProviderManager::ProvRegMap_t& regMap)
00181 {
00182    String name(name_);
00183    name.toLowerCase();
00184    // search for duplicates
00185    ProviderManager::ProvRegMap_t::const_iterator ci = regMap.find(name);
00186    if (ci != regMap.end())
00187    {
00188       OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("More than one provider is registered to instrument class (%1). %2::%3 and %4::%5",
00189          name, ci->second.ifc->getName(), ci->second.provName, ifc->getName(), providerName));
00190       return;
00191    }
00192    OW_LOG_DEBUG(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Registering provider %1::%2 for %3", ifc->getName(), providerName, name));
00193    // now save it so we can look it up quickly when needed
00194    ProviderManager::ProvReg reg;
00195    reg.ifc = ifc;
00196    reg.provName = providerName;
00197    regMap.insert(std::make_pair(name, reg));
00198 }
00199 
00201 // Overloaded of the map type.  registrations use a multi-map, since
00202 // multiple providers can register for the same class.  This is applicable
00203 // for indication and secondary instance providers.
00204 void registerProviderInfo(
00205    const ProviderEnvironmentIFCRef& env,
00206    const String& name_,
00207    const ProviderIFCBaseIFCRef& ifc,
00208    const String& providerName,
00209    ProviderManager::MultiProvRegMap_t& regMap)
00210 {
00211    String name(name_);
00212    name.toLowerCase();
00213    OW_LOG_DEBUG(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Registering provider %1::%2 for %3", ifc->getName(), providerName, name));
00214    // now save it so we can look it up quickly when needed
00215    ProviderManager::ProvReg reg;
00216    reg.ifc = ifc;
00217    reg.provName = providerName;
00218    regMap.insert(std::make_pair(name, reg));
00219 }
00220 
00222 // This handles method & property names
00223 void processProviderClassExtraInfo(
00224    const ProviderEnvironmentIFCRef& env,
00225    const String& name,
00226    const StringArray& extra,
00227    const ProviderIFCBaseIFCRef& ifc,
00228    const String& providerName,
00229    ProviderManager::ProvRegMap_t& regMap)
00230 {
00231    if (extra.empty())
00232    {
00233       registerProviderInfo(env, name, ifc, providerName, regMap);
00234    }
00235    else
00236    {
00237       for (size_t i = 0; i < extra.size(); ++i)
00238       {
00239          String extraName = extra[i];
00240          if (extraName.empty())
00241          {
00242             OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Provider sub-name is "
00243                "empty for %1 by provider %2::%3",
00244                name, ifc->getName(), providerName));
00245             continue;
00246          }
00247          registerProviderInfo(env, name + "/" + extraName, ifc, providerName, regMap);
00248       }
00249    }
00250 }
00252 // This handles indication class names
00253 void processProviderClassExtraInfo(
00254    const ProviderEnvironmentIFCRef& env,
00255    const String& name,
00256    const StringArray& extra,
00257    const ProviderIFCBaseIFCRef& ifc,
00258    const String& providerName,
00259    ProviderManager::MultiProvRegMap_t& regMap)
00260 {
00261    if (!extra.empty())
00262    {
00263       // The "/*" identifies the registration as a lifecycle provider.
00264       registerProviderInfo(env, name + "/*", ifc, providerName, regMap);
00265       for (size_t i = 0; i < extra.size(); ++i)
00266       {
00267          String extraName = extra[i];
00268          if (extraName.empty())
00269          {
00270             OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Provider sub-name is "
00271                "empty for %1 by provider %2::%3",
00272                name, ifc->getName(), providerName));
00273             continue;
00274          }
00275          registerProviderInfo(env, name + '/' + extraName, ifc, providerName, regMap);
00276       }
00277    }
00278    else
00279    {
00280       // The lack of "/*" identifies the registration as a non-lifecycle provider.
00281       registerProviderInfo(env, name, ifc, providerName, regMap);
00282    }
00283 }
00285 template <typename ClassInfoT>
00286 inline String getClassName(const ClassInfoT& classInfo)
00287 {
00288    return classInfo.className;
00289 }
00290 inline String getClassName(const IndicationProviderInfoEntry& classInfo)
00291 {
00292    return classInfo.indicationName;
00293 }
00295 template <typename RegMapT, typename ClassInfoT>
00296 void processProviderClassInfo(
00297    const ProviderEnvironmentIFCRef& env,
00298    const ClassInfoT& classInfo,
00299    const ProviderIFCBaseIFCRef& ifc,
00300    const String& providerName,
00301    RegMapT& regMap)
00302 {
00303    if (classInfo.namespaces.empty())
00304    {
00305       registerProviderInfo(env, getClassName(classInfo), ifc, providerName, regMap);
00306    }
00307    else
00308    {
00309       for (size_t l = 0; l < classInfo.namespaces.size(); ++l)
00310       {
00311          String ns = classInfo.namespaces[l];
00312          if (ns.empty())
00313          {
00314             OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Provider namespace is "
00315                "empty for class %1 by provider %2::%3",
00316                getClassName(classInfo), ifc->getName(), providerName));
00317             continue;
00318          }
00319          String name = ns + ":" + getClassName(classInfo);
00320          registerProviderInfo(env, name, ifc, providerName, regMap);
00321       }
00322    }
00323 }
00325 void processProviderClassInfo(
00326    const ProviderEnvironmentIFCRef& env,
00327    const MethodProviderInfo::ClassInfo& classInfo,
00328    const ProviderIFCBaseIFCRef& ifc,
00329    const String& providerName,
00330    ProviderManager::ProvRegMap_t& regMap)
00331 {
00332    if (classInfo.namespaces.empty())
00333    {
00334       processProviderClassExtraInfo(env, classInfo.className, classInfo.methods, ifc, providerName, regMap);
00335    }
00336    else
00337    {
00338       for (size_t l = 0; l < classInfo.namespaces.size(); ++l)
00339       {
00340          String ns = classInfo.namespaces[l];
00341          if (ns.empty())
00342          {
00343             OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Provider namespace is "
00344                "empty for class %1 by provider %2::%3",
00345                classInfo.className, ifc->getName(), providerName));
00346             continue;
00347          }
00348          String name = ns + ":" + classInfo.className;
00349          processProviderClassExtraInfo(env, name, classInfo.methods, ifc, providerName, regMap);
00350       }
00351    }
00352 }
00354 void processProviderClassInfo(
00355    const ProviderEnvironmentIFCRef& env,
00356    const IndicationProviderInfo::ClassInfo& classInfo,
00357    const ProviderIFCBaseIFCRef& ifc,
00358    const String& providerName,
00359    ProviderManager::MultiProvRegMap_t& regMap)
00360 {
00361    if (classInfo.namespaces.empty())
00362    {
00363       processProviderClassExtraInfo(env, classInfo.indicationName, classInfo.classes, ifc, providerName, regMap);
00364    }
00365    else
00366    {
00367       for (size_t l = 0; l < classInfo.namespaces.size(); ++l)
00368       {
00369          String ns = classInfo.namespaces[l];
00370          if (ns.empty())
00371          {
00372             OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format("Provider namespace is "
00373                "empty for class %1 by provider %2::%3",
00374                classInfo.indicationName, ifc->getName(), providerName));
00375             continue;
00376          }
00377          String name = ns + ":" + classInfo.indicationName;
00378          processProviderClassExtraInfo(env, name, classInfo.classes, ifc, providerName, regMap);
00379       }
00380    }
00381 }
00383 template <typename ProviderInfoT, typename RegMapT>
00384 void processProviderInfo(
00385    const ProviderEnvironmentIFCRef& env,
00386    const Array<ProviderInfoT>& providerInfo,
00387    const ProviderIFCBaseIFCRef& ifc,
00388    RegMapT& regMap)
00389 {
00390    // process the provider info.  Each provider may have added an entry.
00391    for (size_t j = 0; j < providerInfo.size(); ++j)
00392    {
00393       // make sure the ifc or provider set a name.
00394       String providerName = providerInfo[j].getProviderName();
00395       if (providerName.empty())
00396       {
00397          OW_LOG_ERROR(env->getLogger(ProviderManager::COMPONENT_NAME), Format(
00398             "Provider name not supplied for provider class registrations from IFC %1", ifc->getName()));
00399          continue;
00400       }
00401       // now loop through all the classes the provider may support
00402       typedef typename ProviderInfoT::ClassInfo ClassInfo;
00403       typedef typename ProviderInfoT::ClassInfoArray ClassInfoArray;
00404       ClassInfoArray const& classInfos = providerInfo[j].getClassInfo();
00405       for (size_t k = 0; k < classInfos.size(); ++k)
00406       {
00407          ClassInfo classInfo(classInfos[k]);
00408          processProviderClassInfo(env, classInfo, ifc, providerName, regMap);
00409       }
00410    }
00411 }
00412 
00413 } // end anonymous namespace
00415 void ProviderManager::init(const ServiceEnvironmentIFCRef& env)
00416 {
00417    m_env = env;
00418 
00419    m_logger = env->getLogger(COMPONENT_NAME);
00420 
00421    ProviderEnvironmentIFCRef penv = ProviderEnvironmentIFCRef(
00422       new ProviderEnvironmentServiceEnvironmentWrapper(env));
00423 
00424    for (size_t i = 0; i < m_IFCArray.size(); ++i)
00425    {
00426       InstanceProviderInfoArray instanceProviderInfo;
00427       SecondaryInstanceProviderInfoArray secondaryInstanceProviderInfo;
00428 
00429 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00430       AssociatorProviderInfoArray associatorProviderInfo;
00431 #endif
00432 
00433       MethodProviderInfoArray methodProviderInfo;
00434       IndicationProviderInfoArray indicationProviderInfo;
00435 
00436       m_IFCArray[i]->init(penv,
00437          instanceProviderInfo,
00438          secondaryInstanceProviderInfo,
00439 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00440          associatorProviderInfo,
00441 #endif
00442          methodProviderInfo,
00443          indicationProviderInfo);
00444 
00445       processProviderInfo(penv, instanceProviderInfo, m_IFCArray[i], m_registeredInstProvs);
00446       processProviderInfo(penv, secondaryInstanceProviderInfo, m_IFCArray[i], m_registeredSecInstProvs);
00447 
00448 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00449       processProviderInfo(penv, associatorProviderInfo, m_IFCArray[i], m_registeredAssocProvs);
00450 #endif
00451 
00452       processProviderInfo(penv, methodProviderInfo, m_IFCArray[i], m_registeredMethProvs);
00453       processProviderInfo(penv, indicationProviderInfo, m_IFCArray[i], m_registeredIndProvs);
00454    }
00455 
00456    StringArray restrictedNamespaces = m_env->getMultiConfigItem(ConfigOpts::EXPLICIT_REGISTRATION_NAMESPACES_opt, StringArray(), " \t");
00457    m_restrictedNamespaces.insert(restrictedNamespaces.begin(), restrictedNamespaces.end());
00458 }
00459 
00461 bool
00462 ProviderManager::isRestrictedNamespace(const String& ns) const
00463 {
00464    String lns(ns);
00465    lns.toLowerCase();
00466    return (m_restrictedNamespaces.find(lns) != m_restrictedNamespaces.end());
00467 }
00468 
00469 namespace
00470 {
00471 
00472 #ifdef OW_THREADS_RUN_AS_USER
00473 
00474 inline InstanceProviderIFCRef
00475 wrapProvider(InstanceProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00476 {
00477    if (!pref)
00478    {
00479       return pref;
00480    }
00481    return InstanceProviderIFCRef(new InstanceProviderProxy(pref, env));
00482 }
00483 inline SecondaryInstanceProviderIFCRef
00484 wrapProvider(SecondaryInstanceProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00485 {
00486    if (!pref)
00487    {
00488       return pref;
00489    }
00490    return SecondaryInstanceProviderIFCRef(new SecondaryInstanceProviderProxy(pref, env));
00491 }
00492 inline MethodProviderIFCRef
00493 wrapProvider(MethodProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00494 {
00495    if (!pref)
00496    {
00497       return pref;
00498    }
00499    return MethodProviderIFCRef(new MethodProviderProxy(pref, env));
00500 }
00501 
00502 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00503 inline AssociatorProviderIFCRef
00504 wrapProvider(AssociatorProviderIFCRef pref,
00505    const ProviderEnvironmentIFCRef& env)
00506 {
00507    if (!pref)
00508    {
00509       return pref;
00510    }
00511    return AssociatorProviderIFCRef(new AssociatorProviderProxy(pref, env));
00512 }
00513 #endif
00514 
00515 #else // OW_SETUID_PROVIDERS
00516 
00517 inline InstanceProviderIFCRef
00518 wrapProvider(InstanceProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00519 {
00520    return pref;
00521 }
00522 inline SecondaryInstanceProviderIFCRef
00523 wrapProvider(SecondaryInstanceProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00524 {
00525    return pref;
00526 }
00527 inline MethodProviderIFCRef
00528 wrapProvider(MethodProviderIFCRef pref, const ProviderEnvironmentIFCRef& env)
00529 {
00530    return pref;
00531 }
00532 
00533 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00534 inline AssociatorProviderIFCRef
00535 wrapProvider(AssociatorProviderIFCRef pref,
00536    const ProviderEnvironmentIFCRef& env)
00537 {
00538    return pref;
00539 }
00540 #endif
00541 
00542 #endif   // OW_SETUID_PROVIDERS
00543 
00544 }
00545 
00547 InstanceProviderIFCRef
00548 ProviderManager::getInstanceProvider(const ProviderEnvironmentIFCRef& env,
00549    const String& ns, const CIMClass& cc) const
00550 {
00551    ProvRegMap_t::const_iterator ci;
00552    if(!isRestrictedNamespace(ns) || cc.getName().equalsIgnoreCase("__Namespace"))
00553    {
00554       // lookup just the class name to see if a provider registered for the
00555       // class in all namespaces.
00556       ci = m_registeredInstProvs.find(cc.getName().toLowerCase());
00557       if (ci != m_registeredInstProvs.end())
00558       {
00559          return wrapProvider(ci->second.ifc->getInstanceProvider(env,
00560             ci->second.provName.c_str()), env);
00561       }
00562    }
00563 
00564    // next lookup namespace:classname to see if we've got one for the
00565    // specific namespace
00566    String nsAndClassName = ns + ':' + cc.getName();
00567    nsAndClassName.toLowerCase();
00568    ci = m_registeredInstProvs.find(nsAndClassName);
00569    if (ci != m_registeredInstProvs.end())
00570    {
00571       return wrapProvider(ci->second.ifc->getInstanceProvider(env,
00572             ci->second.provName.c_str()), env);
00573    }
00574    // if we don't have a new registration, try the old method
00575    CIMQualifier qual = cc.getQualifier(
00576       CIMQualifier::CIM_QUAL_PROVIDER);
00577    if (qual)
00578    {
00579       String provStr;
00580       ProviderIFCBaseIFCRef theIFC = getProviderIFC(env, qual, provStr);
00581       if (theIFC)
00582       {
00583          return wrapProvider(theIFC->getInstanceProvider(env,
00584             provStr.c_str()), env);
00585       }
00586    }
00587    return InstanceProviderIFCRef(0);
00588 }
00589 
00591 SecondaryInstanceProviderIFCRefArray
00592 ProviderManager::getSecondaryInstanceProviders(const ProviderEnvironmentIFCRef& env,
00593    const String& ns, const CIMName& className) const
00594 {
00595    String lowerName = className.toString();
00596    lowerName.toLowerCase();
00597    MultiProvRegMap_t::const_iterator lci;
00598    MultiProvRegMap_t::const_iterator uci;
00599 
00600    std::pair<MultiProvRegMap_t::const_iterator, 
00601       MultiProvRegMap_t::const_iterator> range;
00602 
00603    lci =  m_registeredSecInstProvs.end();
00604    if(!isRestrictedNamespace(ns))
00605    {
00606       // lookup just the class name to see if a provider registered for the
00607       // class in all namespaces.
00608       range = m_registeredSecInstProvs.equal_range(lowerName);
00609       lci = range.first;
00610       uci = range.second;
00611    }
00612 
00613    if (lci == m_registeredSecInstProvs.end())
00614    {
00615       // lookup namespace:classname to see if we've got one for the
00616       // specific namespace
00617       String nsAndClassName = ns + ':' + lowerName;
00618       nsAndClassName.toLowerCase();
00619       range = m_registeredSecInstProvs.equal_range(nsAndClassName);
00620       lci = range.first;
00621       uci = range.second;
00622    }
00623 
00624    SecondaryInstanceProviderIFCRefArray rval;
00625    if (lci != m_registeredSecInstProvs.end())
00626    {
00627       // loop through the matching range and put them in rval
00628       for (MultiProvRegMap_t::const_iterator tci = lci; tci != uci; ++tci)
00629       {
00630          rval.push_back(wrapProvider(tci->second.ifc->getSecondaryInstanceProvider(env, tci->second.provName.c_str()), env));
00631       }
00632    }
00633    return rval;
00634 }
00635 
00637 MethodProviderIFCRef
00638 ProviderManager::getMethodProvider(const ProviderEnvironmentIFCRef& env,
00639    const String& ns, const CIMClass& cc, const CIMMethod& method) const
00640 {
00641    ProvRegMap_t::const_iterator ci;
00642    CIMName methodName = method.getName();
00643    
00644    if(!isRestrictedNamespace(ns))
00645    {
00646       // lookup just the class name to see if a provider registered for the
00647       // class in all namespaces.
00648       ci = m_registeredMethProvs.find(cc.getName().toLowerCase());
00649       if (ci != m_registeredMethProvs.end())
00650       {
00651          return wrapProvider(ci->second.ifc->getMethodProvider(env,
00652                ci->second.provName.c_str()), env);
00653       }
00654 
00655       // next lookup classname/methodname to see if we've got one for the
00656       // specific class/method for any namespace
00657       String classAndMethodName = cc.getName() + '/' + methodName.toString();
00658       classAndMethodName.toLowerCase();
00659       ci = m_registeredMethProvs.find(classAndMethodName);
00660       if (ci != m_registeredMethProvs.end())
00661       {
00662          return wrapProvider(ci->second.ifc->getMethodProvider(env,
00663                ci->second.provName.c_str()), env);
00664       }
00665    }
00666 
00667    // next lookup namespace:classname to see if we've got one for the
00668    // specific namespace/class & all methods
00669    String nsAndClassName = ns + ':' + cc.getName();
00670    nsAndClassName.toLowerCase();
00671    ci = m_registeredMethProvs.find(nsAndClassName);
00672    if (ci != m_registeredMethProvs.end())
00673    {
00674       return wrapProvider(ci->second.ifc->getMethodProvider(env,
00675             ci->second.provName.c_str()), env);
00676    }
00677    // next lookup namespace:classname/methodname to see if we've got one for the
00678    // specific namespace/class/method
00679    String name = ns + ':' + cc.getName() + '/' + methodName.toString();
00680    name.toLowerCase();
00681    ci = m_registeredMethProvs.find(name);
00682    if (ci != m_registeredMethProvs.end())
00683    {
00684       return wrapProvider(ci->second.ifc->getMethodProvider(env,
00685          ci->second.provName.c_str()), env);
00686    }
00687    // didn't find it, so try the old way by looking at the provider qualifier.
00688    CIMQualifier qual = method.getQualifier(
00689       CIMQualifier::CIM_QUAL_PROVIDER);
00690    if (qual)
00691    {
00692       String provStr;
00693       ProviderIFCBaseIFCRef theIFC = getProviderIFC(env, qual, provStr);
00694       if (theIFC)
00695       {
00696          return wrapProvider(theIFC->getMethodProvider(env,
00697             provStr.c_str()), env);
00698       }
00699    }
00700    // no method provider qualifier for the method, see if the class level
00701    // provider qualifier is a method provider
00702    qual = cc.getQualifier(
00703       CIMQualifier::CIM_QUAL_PROVIDER);
00704    if (qual)
00705    {
00706       String provStr;
00707       ProviderIFCBaseIFCRef theIFC = getProviderIFC(env, qual, provStr);
00708       if (theIFC)
00709       {
00710          return wrapProvider(theIFC->getMethodProvider(env,
00711             provStr.c_str()), env);
00712       }
00713    }
00714    return MethodProviderIFCRef(0);
00715 }
00716 
00717 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00718 
00719 AssociatorProviderIFCRef
00720 ProviderManager::getAssociatorProvider(const ProviderEnvironmentIFCRef& env,
00721    const String& ns, const CIMClass& cc) const
00722 {
00723    ProvRegMap_t::const_iterator ci;
00724    if(!isRestrictedNamespace(ns))
00725    {
00726       // lookup just the class name to see if a provider registered for the
00727       // class in all namespaces.
00728       ci = m_registeredAssocProvs.find(cc.getName().toLowerCase());
00729       if (ci != m_registeredAssocProvs.end())
00730       {
00731          return wrapProvider(ci->second.ifc->getAssociatorProvider(env,
00732                ci->second.provName.c_str()), env);
00733       }
00734    }
00735 
00736    // next lookup namespace:classname to see if we've got one for the
00737    // specific namespace
00738    String nsAndClassName = ns + ':' + cc.getName();
00739    nsAndClassName.toLowerCase();
00740    ci = m_registeredAssocProvs.find(nsAndClassName);
00741    if (ci != m_registeredAssocProvs.end())
00742    {
00743       return wrapProvider(ci->second.ifc->getAssociatorProvider(env,
00744             ci->second.provName.c_str()), env);
00745    }
00746    // if we don't have a new registration, try the old method
00747    CIMQualifier qual = cc.getQualifier(
00748       CIMQualifier::CIM_QUAL_PROVIDER);
00749    if (qual)
00750    {
00751       String provStr;
00752       ProviderIFCBaseIFCRef theIFC = getProviderIFC(env, qual, provStr);
00753       if (theIFC)
00754       {
00755          return wrapProvider(theIFC->getAssociatorProvider(env,
00756             provStr.c_str()), env);
00757       }
00758    }
00759    return AssociatorProviderIFCRef(0);
00760 }
00761 #endif // #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00762 
00763 IndicationExportProviderIFCRefArray
00764 ProviderManager::getIndicationExportProviders(
00765    const ProviderEnvironmentIFCRef& env) const
00766 {
00767    IndicationExportProviderIFCRefArray rv;
00768    for (size_t i = 0; i < m_IFCArray.size(); i++)
00769    {
00770       IndicationExportProviderIFCRefArray pra =
00771             m_IFCArray[i]->getIndicationExportProviders(env);
00772       if (pra.size() > 0)
00773       {
00774          rv.appendArray(pra);
00775       }
00776    }
00777    return rv;
00778 }
00780 PolledProviderIFCRefArray
00781 ProviderManager::getPolledProviders(
00782    const ProviderEnvironmentIFCRef& env) const
00783 {
00784    PolledProviderIFCRefArray rv;
00785    for (size_t i = 0; i < m_IFCArray.size(); i++)
00786    {
00787       PolledProviderIFCRefArray pra =
00788             m_IFCArray[i]->getPolledProviders(env);
00789       if (pra.size() > 0)
00790       {
00791          rv.appendArray(pra);
00792       }
00793    }
00794    return rv;
00795 }
00796 
00798 void 
00799 ProviderManager::findIndicationProviders(
00800    const ProviderEnvironmentIFCRef& env,
00801    const String& ns,
00802    const CIMName& className,
00803    const ProviderManager::MultiProvRegMap_t& indProvs,
00804    IndicationProviderIFCRefArray& rval) const
00805 {
00806    typedef ProviderManager::MultiProvRegMap_t::const_iterator citer_t;
00807    std::pair<citer_t, citer_t> range;
00808 
00809    range.first = indProvs.end();
00810 
00811    if(!isRestrictedNamespace(ns))
00812    {
00813       range = indProvs.equal_range(className.toString());
00814    }
00815 
00816    if (range.first == indProvs.end())
00817    {
00818       // didn't find any or restricted namespace, so
00819       // next lookup Namespace:className to see if we've got one for the
00820       // specific Namespace
00821       String nsAndClassName = ns + ':' + className.toString();
00822       nsAndClassName.toLowerCase();
00823       range = indProvs.equal_range(nsAndClassName);
00824    }
00825 
00826    if (range.first != indProvs.end())
00827    {
00828       // loop through the matching range and put them in rval
00829       for (citer_t tci = range.first; tci != range.second; ++tci)
00830       {
00831          rval.push_back(tci->second.ifc->getIndicationProvider(env, tci->second.provName.c_str()));
00832       }
00833    }
00834 }
00835 
00837 IndicationProviderIFCRefArray
00838 ProviderManager::getIndicationProviders(const ProviderEnvironmentIFCRef& env,
00839    const String& ns, const CIMName& indicationClassName,
00840    const CIMNameArray& monitoredClassNames) const
00841 {
00842    IndicationProviderIFCRefArray providers;
00843    String lowerName = indicationClassName.toString();
00844    lowerName.toLowerCase();
00845 
00846    // first get all the non-lifecycle indication providers
00847    findIndicationProviders(env, ns, lowerName, m_registeredIndProvs, providers);
00848 
00849    if (monitoredClassNames.empty())
00850    {
00851       // find any lifecycle indication providers which may match indicationClassName
00852       findIndicationProviders(env, ns, lowerName + "/*", m_registeredIndProvs, providers);
00853    }
00854    else
00855    {
00856       // find all the desired lifecycle indication providers
00857       for (size_t i = 0; i < monitoredClassNames.size(); ++i)
00858       {
00859          // lookup indicationClassName/monitoredClassName
00860          String key = lowerName + '/' + monitoredClassNames[i].toString();
00861          key.toLowerCase();
00862          findIndicationProviders(env, ns, key, m_registeredIndProvs, providers);
00863       }
00864 
00865    }
00866 
00867    // get rid of duplicate providers - unique() requires that the range be sorted
00868    std::sort(providers.begin(), providers.end());
00869    providers.erase(std::unique(providers.begin(), providers.end()), providers.end());
00870 
00871    return providers;
00872 }
00874 void
00875 ProviderManager::unloadProviders(const ProviderEnvironmentIFCRef& env)
00876 {
00877    for (size_t i = 0; i < m_IFCArray.size(); i++)
00878    {
00879       try
00880       {
00881          m_IFCArray[i]->unloadProviders(env);
00882       }
00883       catch (const Exception& e)
00884       {
00885          OW_LOG_ERROR(m_logger, Format("Caught exception while calling unloadProviders for provider interface %1: %2", m_IFCArray[i]->getName(), e));
00886       }
00887    }
00888 }
00890 ProviderIFCBaseIFCRef
00891 ProviderManager::getProviderIFC(const ProviderEnvironmentIFCRef& env,
00892    const CIMQualifier& qual,
00893    String& provStr) const
00894 {
00895    ProviderIFCBaseIFCRef rref;
00896    provStr = String();
00897    if (!qual.getName().equalsIgnoreCase(CIMQualifier::CIM_QUAL_PROVIDER))
00898    {
00899       OW_LOG_ERROR(m_logger, Format("Provider Manager - invalid provider qualifier: %1",
00900          qual.getName()));
00901       return rref;
00902    }
00903    CIMValue cv = qual.getValue();
00904    if (cv.getType() != CIMDataType::STRING || cv.isArray())
00905    {
00906       CIMDataType dt(cv.getType());
00907       if (cv.isArray())
00908       {
00909          dt.setToArrayType(cv.getArraySize());
00910       }
00911       OW_LOG_ERROR(m_logger, Format(
00912          "Provider Manager - qualifier has incompatible data type: %1",
00913          dt.toString()));
00914       return rref;
00915    }
00916    String qvstr;
00917    cv.get(qvstr);
00918    size_t ndxoffset = 2;
00919    size_t ndx = qvstr.indexOf("::");
00920    if (ndx == String::npos)
00921    {
00922       ndx = qvstr.indexOf(":");
00923       if (ndx == String::npos)
00924       {
00925          OW_LOG_ERROR(m_logger, Format(
00926             "Provider Manager - Invalid Format for provider string: %1", qvstr));
00927          return rref;
00928       }
00929       ndxoffset = 1;
00930    }
00931    String ifcStr = qvstr.substring(0, ndx);
00932    provStr = qvstr.substring(ndx+ndxoffset);
00933    for (size_t i = 0; i < m_IFCArray.size(); i++)
00934    {
00935       if (ifcStr.equalsIgnoreCase(m_IFCArray[i]->getName()))
00936       {
00937          rref = m_IFCArray[i];
00938          break;
00939       }
00940    }
00941    if (!rref)
00942    {
00943       OW_LOG_ERROR(m_logger, Format(
00944          "Provider Manager - Invalid provider interface identifier: %1",
00945          ifcStr));
00946    }
00947    return rref;
00948 }
00949 
00950 } // end namespace OW_NAMESPACE
00951 

Generated on Thu Feb 9 08:48:09 2006 for openwbem by  doxygen 1.4.6