OW_NameSpaceProvider.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 
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             // it's a parent or the same namespace, so ignore it.
00078             return;
00079          }
00080          if (!deep && split.size() > ns.size() + 1)
00081          {
00082             // it's more than one deep, so ignore it.
00083             return;
00084          }
00085          for (size_t i = 0; i < ns.size(); ++i)
00086          {
00087             if (ns[i] != split[i])
00088             {
00089                // it's not under the requested namespace so return.
00090                return;
00091             }
00092          }
00093          // match, pass it on.
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    // deleteNameSpace doesn't automatically delete subnamespaces, so we need to do it.
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 } // end namespace OW_NAMESPACE
00377 
00378 OW_PROVIDERFACTORY(OW_NAMESPACE::NameSpaceProvider, owprovinstOW_NameSpace);
00379 

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