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 
00035 #include "OW_config.h"
00036 #include "OW_NameSpaceProvider.hpp"
00037 #include "OW_Exception.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_CIMException.hpp"
00040 #include "OW_CIMNameSpace.hpp"
00041 #include "OW_CIMProperty.hpp"
00042 #include "OW_CIMValue.hpp"
00043 #include "OW_CIMUrl.hpp"
00044 #include "OW_CIMClass.hpp"
00045 #include "OW_CIMInstance.hpp"
00046 #include "OW_CIMInstanceEnumeration.hpp"
00047 #include "OW_CIMObjectPath.hpp"
00048 #include "OW_ResultHandlerIFC.hpp"
00049 #include "OW_RepositoryIFC.hpp"
00050 #include "OW_Logger.hpp"
00051 
00052 namespace OW_NAMESPACE
00053 {
00054 
00055 namespace
00056 {
00057    const String COMPONENT_NAME("ow.provider.__Namespace");
00058 }
00059 
00060 using namespace WBEMFlags;
00062 namespace
00063 {
00064    class namespaceFilterer : public StringResultHandlerIFC
00065    {
00066    public:
00067       namespaceFilterer(const String& ns_, bool deep_, StringResultHandlerIFC& result_)
00068          : ns(ns_.tokenize("/"))
00069          , deep(deep_)
00070          , result(result_)
00071       {}
00072       void doHandle(const String& s)
00073       {
00074          StringArray split(s.tokenize("/"));
00075          if (split.size() <= ns.size())
00076          {
00077             
00078             return;
00079          }
00080          if (!deep && split.size() > ns.size() + 1)
00081          {
00082             
00083             return;
00084          }
00085          for (size_t i = 0; i < ns.size(); ++i)
00086          {
00087             if (ns[i] != split[i])
00088             {
00089                
00090                return;
00091             }
00092          }
00093          
00094          result.handle(s);
00095       }
00096    private:
00097       StringArray ns;
00098       bool deep;
00099       StringResultHandlerIFC& result;
00100    };
00101 }
00103 NameSpaceProvider::~NameSpaceProvider()
00104 {
00105 }
00106 namespace
00107 {
00108    class StringArrayBuilder : public StringResultHandlerIFC
00109    {
00110    public:
00111       StringArrayBuilder(StringArray& a) : m_a(a) {}
00112    protected:
00113       virtual void doHandle(const String &s)
00114       {
00115          m_a.push_back(s);
00116       }
00117    private:
00118       StringArray& m_a;
00119    };
00120    
00121    StringArray enumNameSpaceE(const ProviderEnvironmentIFCRef& env, const String& ns)
00122    {
00123       RepositoryIFCRef rep = env->getRepository();
00124       StringArray rval;
00125       StringArrayBuilder arrayBuilder(rval);
00126       namespaceFilterer handler(ns, true, arrayBuilder);
00127       rep->enumNameSpace(handler, env->getOperationContext());
00128       return rval;
00129    }
00130    void enumNameSpace(const ProviderEnvironmentIFCRef& env, const String& ns, StringResultHandlerIFC& result, bool deep)
00131    {
00132       RepositoryIFCRef rep = env->getRepository();
00133       namespaceFilterer handler(ns, deep, result);
00134       rep->enumNameSpace(handler, env->getOperationContext());
00135    }
00136 }
00137 #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
00138 
00139 void
00140 NameSpaceProvider::deleteInstance(
00141       const ProviderEnvironmentIFCRef& env,
00142       const String& ns,
00143       const CIMObjectPath& cop)
00144 {
00145    CIMPropertyArray pra = cop.getKeys();
00146    if (pra.size() == 0)
00147    {
00148       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE,
00149          "root namespace cannot be deleted");
00150    }
00151    CIMProperty nameProp = cop.getKey(CIMProperty::NAME_PROPERTY);
00152    if (!nameProp)
00153    {
00154       OW_THROWCIMMSG(CIMException::FAILED,
00155          "Name property not found");
00156    }
00157    
00158    CIMValue cv = nameProp.getValue();
00159    if (!cv)
00160    {
00161       OW_THROWCIMMSG(CIMException::FAILED,
00162          "Name property doesn't have a value");
00163    }
00164    String nsName;
00165    cv.get(nsName);
00166    if (nsName.empty())
00167    {
00168       OW_THROWCIMMSG(CIMException::FAILED,
00169          "Name property contains an empty value");
00170    }
00171    String newns = ns + "/" + nsName;
00172    
00173    StringArray nstodel = enumNameSpaceE(env, newns);
00174    for (size_t i = 0; i < nstodel.size(); ++i)
00175    {
00176       env->getRepository()->deleteNameSpace(nstodel[i], env->getOperationContext());
00177    }
00178    env->getRepository()->deleteNameSpace(newns, env->getOperationContext());
00179 }
00180 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00181 namespace
00182 {
00183    class CIMInstanceToObjectPath : public CIMInstanceResultHandlerIFC
00184    {
00185    public:
00186       CIMInstanceToObjectPath(CIMObjectPathResultHandlerIFC& h,
00187          const String& ns_,
00188          const String& className_) : m_h(h), cop(className_, ns_) {}
00189    protected:
00190       virtual void doHandle(const CIMInstance &ci)
00191       {
00192          cop.setKeys(ci.getKeyValuePairs());
00193          m_h.handle(cop);
00194       }
00195    private:
00196       CIMObjectPathResultHandlerIFC& m_h;
00197       CIMObjectPath cop;
00198    };
00199 }
00201 void
00202 NameSpaceProvider::enumInstanceNames(
00203       const ProviderEnvironmentIFCRef& env,
00204       const String& ns,
00205       const String& className,
00206       CIMObjectPathResultHandlerIFC& result,
00207       const CIMClass& cimClass)
00208 {
00209    CIMInstanceToObjectPath handler(result, ns, className);
00210    enumInstances(env, ns, className, handler, E_NOT_LOCAL_ONLY, E_SHALLOW, E_EXCLUDE_QUALIFIERS, E_EXCLUDE_CLASS_ORIGIN, 0, cimClass, cimClass);
00211 }
00213 namespace
00214 {
00215    class NameSpaceEnumBuilder : public StringResultHandlerIFC
00216    {
00217    public:
00218       NameSpaceEnumBuilder(CIMInstanceResultHandlerIFC& handler_,
00219          const CIMClass& cimClass_)
00220       : handler(handler_)
00221       , cimClass(cimClass_)
00222       {}
00223    protected:
00224       virtual void doHandle(const String &s)
00225       {
00226          String nameSpaceName = s;
00227          size_t ndx = nameSpaceName.lastIndexOf('/');
00228          if (ndx != String::npos)
00229          {
00230             nameSpaceName = nameSpaceName.substring(ndx+1);
00231          }
00232          CIMInstance ci = cimClass.newInstance();
00233          ci.setProperty("Name", CIMValue(nameSpaceName));
00234          handler.handle(ci);
00235       }
00236    private:
00237       CIMInstanceResultHandlerIFC& handler;
00238       const CIMClass& cimClass;
00239    };
00240    class CIMInstanceEnumBuilder : public CIMInstanceResultHandlerIFC
00241    {
00242    public:
00243       CIMInstanceEnumBuilder(CIMInstanceEnumeration& e) : m_e(e) {}
00244    protected:
00245       virtual void doHandle(const CIMInstance &ci)
00246       {
00247          m_e.addElement(ci);
00248       }
00249    private:
00250       CIMInstanceEnumeration& m_e;
00251    };
00252 }
00254 void
00255 NameSpaceProvider::enumInstances(
00256       const ProviderEnvironmentIFCRef& env,
00257       const String& ns,
00258       const String& className,
00259       CIMInstanceResultHandlerIFC& result,
00260       ELocalOnlyFlag localOnly,
00261       EDeepFlag deep,
00262       EIncludeQualifiersFlag includeQualifiers,
00263       EIncludeClassOriginFlag includeClassOrigin,
00264       const StringArray* propertyList,
00265       const CIMClass& requestedClass,
00266       const CIMClass& cimClass)
00267 {
00268    NameSpaceEnumBuilder handler(result, cimClass);
00269    enumNameSpace(env, ns, handler, false);
00270 }
00272 CIMInstance
00273 NameSpaceProvider::getInstance(
00274       const ProviderEnvironmentIFCRef& env,
00275       const String& ns,
00276       const CIMObjectPath& instanceName,
00277       ELocalOnlyFlag localOnly,
00278       EIncludeQualifiersFlag includeQualifiers,
00279       EIncludeClassOriginFlag includeClassOrigin,
00280       const StringArray* propertyList,
00281       const CIMClass& cimClass)
00282 {
00283    CIMProperty cp = instanceName.getKey(CIMProperty::NAME_PROPERTY);
00284    CIMValue nsVal(CIMNULL);
00285    if (cp)
00286    {
00287       nsVal = cp.getValue();
00288    }
00289    if (nsVal && nsVal.getType() == CIMDataType::STRING)
00290    {
00291       CIMInstanceEnumeration cie;
00292       CIMInstanceEnumBuilder handler(cie);
00293       enumInstances(env, ns, instanceName.getClassName(), handler,
00294          E_NOT_LOCAL_ONLY, E_SHALLOW, E_EXCLUDE_QUALIFIERS, E_EXCLUDE_CLASS_ORIGIN, 0, cimClass,
00295          cimClass);
00296       
00297       while (cie.hasMoreElements())
00298       {
00299          CIMInstance ci = cie.nextElement();
00300          if (ci)
00301          {
00302             CIMProperty cp = ci.getProperty(CIMProperty::NAME_PROPERTY);
00303             if (cp)
00304             {
00305                CIMValue v = cp.getValue();
00306                if (v && v.getType() == CIMDataType::STRING)
00307                {
00308                   String vval;
00309                   v.get(vval);
00310                   String nsValStr;
00311                   nsVal.get(nsValStr);
00312                   if (vval == nsValStr)
00313                   {
00314                      return ci;
00315                   }
00316                }
00317             }
00318          }
00319       }
00320    }
00321    OW_THROWCIM(CIMException::NOT_FOUND);
00322 }
00323 #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
00324 
00325 CIMObjectPath
00326 NameSpaceProvider::createInstance(
00327       const ProviderEnvironmentIFCRef& env,
00328       const String& ns,
00329       const CIMInstance& cimInstance)
00330 {
00331    CIMProperty cp = cimInstance.getProperty(CIMProperty::NAME_PROPERTY);
00332    if (!cp)
00333    {
00334       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE,
00335          "Instance \"Name\" property is not set");
00336    }
00337    CIMValue cv = cp.getValue();
00338    String newName;
00339    cv.get(newName);
00340    newName = newName.substring(newName.indexOf('=') + 1);
00341    String newNameSpace = ns;
00342    newNameSpace += "/";
00343    newNameSpace += newName;
00344    OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NameSpaceProvider::createInstance calling"
00345          " createNameSpace with %1", newNameSpace));
00346    env->getRepository()->createNameSpace(newNameSpace, env->getOperationContext());
00347    return CIMObjectPath(ns, cimInstance);
00348 }
00350 void
00351 NameSpaceProvider::modifyInstance(
00352       const ProviderEnvironmentIFCRef& env,
00353       const String& ns,
00354       const CIMInstance& modifiedInstance,
00355       const CIMInstance& previousInstance,
00356       EIncludeQualifiersFlag includeQualifiers,
00357       const StringArray* propertyList,
00358       const CIMClass& theClass)
00359 {
00360    OW_THROWCIMMSG(CIMException::FAILED, "Modifying a __Namespace instance is not allowed");
00361 }
00362 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00363 
00364 void
00365 NameSpaceProvider::initialize(const ProviderEnvironmentIFCRef& env)
00366 {
00367    OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), "NameSpaceProvider initialize called");
00368 }
00370 void
00371 NameSpaceProvider::getInstanceProviderInfo(InstanceProviderInfo& info)
00372 {
00373    info.addInstrumentedClass("__Namespace");
00374 }
00375 
00376 } 
00377 
00378 OW_PROVIDERFACTORY(OW_NAMESPACE::NameSpaceProvider, owprovinstOW_NameSpace);
00379