OW_MetaRepository.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_MetaRepository.hpp"
00038 #include "OW_DataStreams.hpp"
00039 #include "OW_CIMObjectPath.hpp"
00040 #include "OW_CIMProperty.hpp"
00041 #include "OW_CIMFlavor.hpp"
00042 #include "OW_CIMMethod.hpp"
00043 #include "OW_CIMClass.hpp"
00044 #include "OW_CIMValue.hpp"
00045 #include "OW_CIMQualifierType.hpp"
00046 #include "OW_CIMQualifier.hpp"
00047 #include "OW_Format.hpp"
00048 #include "OW_Assertion.hpp"
00049 #include "OW_Array.hpp"
00050 #include "OW_ConfigOpts.hpp"
00051 
00052 namespace OW_NAMESPACE
00053 {
00054 
00055 using namespace WBEMFlags;
00056 
00057 namespace
00058 {
00059 const String QUAL_CONTAINER("q");
00060 const String CLASS_CONTAINER("c");
00061 const char NS_SEPARATOR_C(':');
00062 
00063 }
00065 MetaRepository::~MetaRepository()
00066 {
00067 }
00069 static void createRootNode(const String& qcontk, HDBHandleLock& hdl)
00070 {
00071    HDBNode rnode = hdl->getNode(qcontk);
00072    if (!rnode)
00073    {
00074       rnode = HDBNode(qcontk, qcontk.length()+1,
00075          reinterpret_cast<const unsigned char*>(qcontk.c_str()));
00076       hdl->turnFlagsOn(rnode, HDBNSNODE_FLAG);
00077       hdl->addRootNode(rnode);
00078    }
00079 }
00081 void
00082 MetaRepository::open(const String& path)
00083 {
00084    GenericHDBRepository::open(path);
00085    OW_LOG_INFO(m_env->getLogger(COMPONENT_NAME), Format("Using MetaRepository: %1", path));
00086 
00087    // Create root qualifier container
00088    HDBHandleLock hdl(this, getHandle());
00089    StringBuffer qcontk(QUAL_CONTAINER);
00090    createRootNode(qcontk.toString(), hdl);
00091    qcontk += NS_SEPARATOR_C;
00092    qcontk += String("root");
00093    createRootNode(qcontk.releaseString(), hdl);
00094 
00095    // Create root class container
00096    StringBuffer ccontk = CLASS_CONTAINER;
00097    createRootNode(ccontk.toString(), hdl);
00098    ccontk += NS_SEPARATOR_C;
00099    ccontk += String("root");
00100    createRootNode(ccontk.releaseString(), hdl);
00101 }
00103 HDBNode
00104 MetaRepository::_getQualContainer(HDBHandleLock& hdl, const String& ns)
00105 {
00106    StringBuffer qcontk(QUAL_CONTAINER);
00107    if (!ns.empty())
00108    {
00109       qcontk += NS_SEPARATOR_C;
00110       qcontk += ns;
00111    }
00112    return getNameSpaceNode(hdl, qcontk.releaseString());
00113 }
00115 String
00116 MetaRepository::_makeQualPath(const String& ns_, const CIMName& qualName)
00117 {
00118    String ns(ns_);
00119    StringBuffer qp(QUAL_CONTAINER);
00120    qp += NS_SEPARATOR_C;
00121    qp += ns;
00122    if (qualName != CIMName())
00123    {
00124       qp += NS_SEPARATOR_C;
00125       String qname(qualName.toString());
00126       qname.toLowerCase();
00127       qp += qname;
00128    }
00129    return qp.releaseString();
00130 }
00132 String
00133 MetaRepository::_makeClassPath(const String& ns,
00134    const CIMName& className)
00135 {
00136    StringBuffer cp(CLASS_CONTAINER);
00137    cp += NS_SEPARATOR_C;
00138    cp += ns;
00139    cp += NS_SEPARATOR_C;
00140    String clsname(className.toString());
00141    clsname.toLowerCase();
00142    cp += clsname;
00143    return cp.releaseString();
00144 }
00146 CIMQualifierType
00147 MetaRepository::getQualifierType(const String& ns,
00148    const CIMName& qualName, HDBHandle* phdl)
00149 {
00150    throwIfNotOpen();
00151    String qkey = _makeQualPath(ns, qualName);
00152    CIMQualifierType qualType = m_qualCache.getFromCache(qkey);
00153    if (qualType)
00154    {
00155       return qualType;
00156    }
00157    GenericHDBRepository* prep;
00158    HDBHandle lhdl;
00159    if (phdl)
00160    {
00161       prep = NULL;
00162       lhdl = *phdl;
00163    }
00164    else
00165    {
00166       prep = this;
00167       lhdl = getHandle();
00168    }
00169    HDBHandleLock hdl(prep, lhdl);
00170    getCIMObject(qualType, qkey, hdl.getHandle());
00171    if (!qualType)
00172    {
00173       if (nameSpaceExists(QUAL_CONTAINER + NS_SEPARATOR_C + ns))
00174       {
00175          OW_THROWCIMMSG(CIMException::NOT_FOUND,
00176                Format("CIM QualifierType \"%1\" not found in namespace: %2",
00177                   qualName, ns).c_str());
00178       }
00179       else
00180       {
00181          OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE,
00182                ns.c_str());
00183       }
00184    }
00185    m_qualCache.addToCache(qualType, qkey);
00186    return qualType;
00187 }
00188 #ifndef OW_DISABLE_QUALIFIER_DECLARATION
00189 
00190 void
00191 MetaRepository::enumQualifierTypes(const String& ns,
00192    CIMQualifierTypeResultHandlerIFC& result)
00193 {
00194    throwIfNotOpen();
00195    String nskey = _makeQualPath(ns, String());
00196    HDBHandleLock hdl(this, getHandle());
00197    HDBNode node = hdl->getNode(nskey);
00198    if (!node)
00199    {
00200       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00201    }
00202    if (!node.areAllFlagsOn(HDBNSNODE_FLAG))
00203    {
00204       OW_THROW(HDBException, "Expected namespace node");
00205    }
00206    node = hdl->getFirstChild(node);
00207    while (node)
00208    {
00209       // If this is not a namespace node, assume it's a qualifier
00210       if (!node.areAllFlagsOn(HDBNSNODE_FLAG))
00211       {
00212          CIMQualifierType qual(CIMNULL);
00213          nodeToCIMObject(qual, node);
00214          result.handle(qual);
00215       }
00216       node = hdl->getNextSibling(node);
00217    }
00218 }
00220 bool
00221 MetaRepository::deleteQualifierType(const String& ns,
00222    const CIMName& qualName)
00223 {
00224    throwIfNotOpen();
00225    String qkey = _makeQualPath(ns, qualName);
00226    HDBHandleLock hdl(this, getHandle());
00227    HDBNode node = hdl->getNode(qkey);
00228    if (!node)
00229    {
00230       // Didn't find a node associated with the key
00231       return false;
00232    }
00233    // To ensure the node is a qualifier type, we create a qualifier
00234    // type from the node. If the node is not a qualifier type, an
00235    // exception will be thrown
00236    CIMQualifierType qt(CIMNULL);
00237    nodeToCIMObject(qt, node);
00238    // If we've hit this point, we know this is a qualifier
00239    hdl->removeNode(node);
00240    m_qualCache.removeFromCache(qkey);
00241    return true;
00242 }
00244 void
00245 MetaRepository::_addQualifierType(const String& ns,
00246    const CIMQualifierType& qt, HDBHandle* phdl)
00247 {
00248    throwIfNotOpen();
00249    if (!qt)
00250    {
00251       OW_THROWCIM(CIMException::INVALID_PARAMETER);
00252    }
00253    GenericHDBRepository* prep;
00254    HDBHandle lhdl;
00255    if (phdl)
00256    {
00257       prep = 0;
00258       lhdl = *phdl;
00259    }
00260    else
00261    {
00262       prep = this;
00263       lhdl = getHandle();
00264    }
00265    HDBHandleLock hdl(prep, lhdl);
00266    String qkey = _makeQualPath(ns, qt.getName());
00267    HDBNode node = hdl->getNode(qkey);
00268    if (node)
00269    {
00270       String msg(ns);
00271       if (!ns.empty())
00272       {
00273          msg += "/";
00274       }
00275       msg += qt.getName();
00276       OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, msg.c_str());
00277    }
00278    HDBNode pnode = _getQualContainer(hdl, ns);
00279    if (!pnode)
00280    {
00281       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00282    }
00283    addCIMObject(qt, qkey, pnode, hdl.getHandle());
00284    m_qualCache.addToCache(qt, qkey);
00285 }
00287 void
00288 MetaRepository::setQualifierType(const String& ns,
00289    const CIMQualifierType& qt)
00290 {
00291    throwIfNotOpen();
00292    String qkey = _makeQualPath(ns, qt.getName());
00293    HDBHandleLock hdl(this, getHandle());
00294    HDBNode node = hdl->getNode(qkey);
00295    if (!node)
00296    {
00297       HDBHandle lhdl = hdl.getHandle();
00298       _addQualifierType(ns, qt, &lhdl);
00299    }
00300    else
00301    {
00302       // No ensure the node is a qualifier type before we delete it
00303       //CIMQualifierType tqt(CIMNULL);
00304       //nodeToCIMObject(tqt, node);
00305       // If we made it to this point, we know we have a qualifier type
00306       // So go ahead and update it.
00307       updateCIMObject(qt, node, hdl.getHandle());
00308       m_qualCache.removeFromCache(qkey);
00309       m_qualCache.addToCache(qt, qkey);
00310    }
00311 }
00312 #endif // #ifndef OW_DISABLE_QUALIFIER_DECLARATION
00313 
00314 CIMException::ErrNoType
00315 MetaRepository::getCIMClass(const String& ns, const CIMName& className,
00316    ELocalOnlyFlag localOnly,
00317    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00318    const StringArray* propertyList,
00319    CIMClass& cc)
00320 {
00321    throwIfNotOpen();
00322    String ckey = _makeClassPath(ns, className);
00323    cc = m_classCache.getFromCache(ckey);
00324    if (!cc)
00325    {
00326       HDBHandleLock hdl(this, getHandle());
00327       HDBNode node = hdl->getNode(ckey);
00328       if (node)
00329       {
00330          // _getClassFromNode throws if unable to get class.
00331          cc = _getClassFromNode(node, hdl.getHandle(), ns);
00332          if (!cc)
00333          {
00334             return CIMException::FAILED;
00335          }
00336          m_classCache.addToCache(cc, ckey);
00337       }
00338       else
00339       {
00340          return CIMException::NOT_FOUND;
00341       }
00342    }
00343    // now do some filtering
00344    if (propertyList
00345       || localOnly == E_LOCAL_ONLY
00346       || includeQualifiers == E_EXCLUDE_QUALIFIERS
00347       || includeClassOrigin == E_EXCLUDE_CLASS_ORIGIN)
00348    { // only clone if we have to
00349       StringArray lpropList;
00350       bool noProps = false;
00351       if (propertyList)
00352       {
00353          if (propertyList->size() == 0)
00354          {
00355             noProps = true;
00356          }
00357          else
00358          {
00359             lpropList = *propertyList;
00360          }
00361       }
00362       cc = cc.clone(localOnly, includeQualifiers, includeClassOrigin,
00363          lpropList, noProps);
00364       if (!cc) // clone doesn't throw
00365       {
00366          return CIMException::FAILED;
00367       }
00368    }
00369    return CIMException::SUCCESS;
00370 }
00372 CIMClass
00373 MetaRepository::_getClassFromNode(HDBNode& node, HDBHandle hdl,
00374    const String& ns)
00375 {
00376    CIMClass theClass(CIMNULL);
00377    nodeToCIMObject(theClass, node);
00378    if (!theClass)
00379    {
00380       return theClass;
00381    }
00382    _resolveClass(theClass, node, hdl, ns);
00383    return theClass;
00384 }
00386 CIMName
00387 MetaRepository::_getClassNameFromNode(HDBNode& node)
00388 {
00389    CIMName name;
00390    DataIStream istrm(node.getDataLen(), node.getData());
00391    // Not going to do this, it's too slow! cimObj.readObject(istrm);
00392    // This is breaking abstraction, and may bite us later if CIMClass::readObject() ever changes..., but in some cases efficiency wins out.
00393    CIMBase::readSig( istrm, OW_CIMCLASSSIG, OW_CIMCLASSSIG_V, CIMClass::SERIALIZATION_VERSION );
00394    name.readObject(istrm);
00395    return name;
00396 }
00398 void
00399 MetaRepository::_resolveClass(CIMClass& child, HDBNode& node,
00400    HDBHandle& hdl, const String& ns)
00401 {
00402    // If this class has an association qualifier, then ensure
00403    // the association flag is on
00404 //     CIMQualifier childAssocQual = child.getQualifier(CIMQualifier::CIM_QUAL_ASSOCIATION);
00405 //     if (childAssocQual)
00406 //     {
00407 //         if (!childAssocQual.getValue()
00408 //             || childAssocQual.getValue() != CIMValue(false))
00409 //         {
00410 //             child.setIsAssociation(true);
00411 //         }
00412 //     }
00413    // Determine if any properties are keys
00414    CIMPropertyArray propArray = child.getAllProperties();
00415    for (size_t i = 0; i < propArray.size(); i++)
00416    {
00417       if (propArray[i].isKey())
00418       {
00419          child.setIsKeyed(true);
00420          break;
00421       }
00422    }
00423    HDBNode pnode;
00424    CIMClass parentClass(CIMNULL);
00425    CIMName superID = child.getSuperClass();
00426    // If class doesn't have a super class - don't propagate anything
00427    // Should always have a parent because of namespaces
00428    if (superID == CIMName())
00429    {
00430       return;
00431    }
00432    String pkey = _makeClassPath(ns, superID);
00433    parentClass = m_classCache.getFromCache(pkey);
00434    if (!parentClass)
00435    {
00436       // If there is no node or the parent node is a namespace
00437       // then we have a base class and there is nothing to propagate.
00438       pnode = hdl.getParent(node);
00439       if (!pnode || pnode.areAllFlagsOn(HDBNSNODE_FLAG))
00440       {
00441          return;
00442       }
00443       nodeToCIMObject(parentClass, pnode);
00444       _resolveClass(parentClass, pnode, hdl, ns);
00445       m_classCache.addToCache(parentClass, pkey);
00446    }
00447    //if (parentClass.isAssociation())
00448    //{
00449    // child.setIsAssociation(true);
00450    //}
00451    if (parentClass.isKeyed())
00452    {
00453       child.setIsKeyed(true);
00454    }
00455    // Propagate appropriate class qualifiers
00456    CIMQualifierArray qualArray = parentClass.getQualifiers();
00457    for (size_t i = 0; i < qualArray.size(); i++)
00458    {
00459       CIMQualifier qual = qualArray[i];
00460       if (!qual.hasFlavor(CIMFlavor::RESTRICTED))
00461       //if (qual.hasFlavor(CIMFlavor::TOSUBCLASS))
00462       {
00463          if (!child.hasQualifier(qual))
00464          {
00465             qual.setPropagated(true);
00466             child.addQualifier(qual);
00467          }
00468       }
00469    }
00470    // Propagate Properties from parent class.
00471    //
00472    // TODO: Regardless of whether there is an override
00473    // this will perform override like behavior - probably
00474    // need to add validation code...
00475    //
00476    propArray = parentClass.getAllProperties();
00477    for (size_t i = 0; i < propArray.size(); i++)
00478    {
00479       CIMProperty parentProp = propArray[i];
00480       CIMProperty childProp = child.getProperty(parentProp.getName());
00481       if (!childProp)
00482       {
00483          parentProp.setPropagated(true);
00484          child.addProperty(parentProp);
00485       }
00486       else if (!childProp.getQualifier(CIMQualifier::CIM_QUAL_OVERRIDE))
00487       {
00488          //
00489          // Propagate any qualifiers that have not been
00490          // re-defined
00491          //
00492          qualArray = parentProp.getQualifiers();
00493          for (size_t qi = 0; qi < qualArray.size(); qi++)
00494          {
00495             CIMQualifier parentQual = qualArray[qi];
00496             if (!childProp.getQualifier(parentQual.getName()))
00497             {
00498                //
00499                // Qualifier not defined on child property
00500                // so propagate it
00501                //
00502                parentQual.setPropagated(true);
00503                childProp.addQualifier(parentQual);
00504             }
00505          }
00506          child.setProperty(childProp);
00507       }
00508    }
00509    // Propagate methods from parent class
00510    CIMMethodArray methods = parentClass.getAllMethods();
00511    for (size_t i = 0; i < methods.size(); i++)
00512    {
00513       CIMMethod cm = methods[i];
00514       CIMMethod childMethod = child.getMethod(methods[i].getName());
00515       if (!childMethod)
00516       {
00517          cm.setPropagated(true);
00518          child.addMethod(cm);
00519       }
00520       else if (!childMethod.getQualifier(CIMQualifier::CIM_QUAL_OVERRIDE))
00521       {
00522          //
00523          // Propagate any qualifiers that have not been
00524          // re-defined by the method declaration
00525          //
00526          qualArray = cm.getQualifiers();
00527          for (size_t mi = 0; mi < qualArray.size(); mi++)
00528          {
00529             CIMQualifier methQual = qualArray[mi];
00530             if (!childMethod.getQualifier(methQual.getName()))
00531             {
00532                methQual.setPropagated(true);
00533                childMethod.addQualifier(methQual);
00534             }
00535          }
00536          child.setMethod(childMethod);
00537       }
00538    }
00539 }
00540 #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00541 
00542 bool
00543 MetaRepository::deleteClass(const String& ns, const CIMName& className)
00544 {
00545    throwIfNotOpen();
00546    String ckey = _makeClassPath(ns, className);
00547    HDBHandleLock hdl(this, getHandle());
00548    HDBNode node = hdl->getNode(ckey);
00549    if (!node)
00550    {
00551       return false;
00552    }
00553    // Just to be safe, we will attempt to create an CIMClass object
00554    // from the node. If the node is not for an CIMClass, an exception
00555    // will be thrown.
00556    CIMClass theClassToDelete(CIMNULL);
00557    nodeToCIMObject(theClassToDelete, node);
00558    m_classCache.removeFromCache(ckey);    // Ensure class is not in the cache
00559    return hdl->removeNode(node);
00560 }
00562 void
00563 MetaRepository::createClass(const String& ns, CIMClass& cimClass)
00564 {
00565    throwIfNotOpen();
00566    HDBHandleLock hdl(this, getHandle());
00567    CIMQualifierArray qra = cimClass.getQualifiers();
00568    _resolveQualifiers(ns, qra, hdl.getHandle());
00569    cimClass.setQualifiers(qra);
00570    // Ensure integrity with any super classes
00571    HDBNode pnode = adjustClass(ns, cimClass, hdl.getHandle());
00572    // pnode is null if there is no parent class, so get namespace node
00573    if (!pnode)
00574    {
00575       if (!(pnode = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns)))
00576       {
00577          OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE,
00578             ns.c_str());
00579       }
00580    }
00581    String ckey = _makeClassPath(ns, cimClass.getName());
00582    HDBNode node = hdl->getNode(ckey);
00583    if (node)
00584    {
00585       OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, ckey.c_str());
00586    }
00587    UInt32 flags = (cimClass.isAssociation()) ? HDBCLSASSOCNODE_FLAG
00588       : 0;
00589    addCIMObject(cimClass, ckey, pnode, hdl.getHandle(), flags);
00590 }
00592 void
00593 MetaRepository::modifyClass(const String& ns,
00594    const CIMClass& cimClass_)
00595 {
00596    throwIfNotOpen();
00597    HDBHandleLock hdl(this, getHandle());
00598    CIMClass cimClass(cimClass_);
00599    adjustClass(ns, cimClass, hdl.getHandle());
00600    String ckey = _makeClassPath(ns, cimClass.getName());
00601    HDBNode node = hdl->getNode(ckey);
00602    if (!node)
00603    {
00604       OW_THROWCIMMSG(CIMException::NOT_FOUND, ckey.c_str());
00605    }
00606    // Create an CIMClass object out of the node we just read to ensure
00607    // the data belongs to an CIMClass.
00608    CIMClass clsToUpdate(CIMNULL);
00609    nodeToCIMObject(clsToUpdate, node);
00610    // At this point we know we are updating an CIMClass
00611    m_classCache.removeFromCache(ckey);
00612    updateCIMObject(cimClass, node, hdl.getHandle());
00613 }
00615 HDBNode
00616 MetaRepository::adjustClass(const String& ns, CIMClass& childClass,
00617    HDBHandle hdl)
00618 {
00619    CIMName childName = childClass.getName();
00620    CIMName parentName = childClass.getSuperClass();
00621    CIMClass parentClass(CIMNULL);
00622    HDBNode parentNode;
00623    if (parentName != CIMName())
00624    {
00625       // Get the parent class
00626       String superID = _makeClassPath(ns, parentName);
00627       //parentClass = m_classCache.getFromCache(superID);
00628       if (!parentClass)
00629       {
00630          parentNode = hdl.getNode(superID);
00631          if (!parentNode)
00632          {
00633             OW_THROWCIMMSG(CIMException::INVALID_SUPERCLASS,
00634                   parentName.toString().c_str());
00635          }
00636          parentClass = _getClassFromNode(parentNode, hdl, ns);
00637          if (!parentClass)
00638          {
00639             OW_THROWCIMMSG(CIMException::INVALID_SUPERCLASS,
00640                   parentName.toString().c_str());
00641          }
00642       }
00643    }
00644    if (!parentClass)
00645    {
00646       // No parent class. Must be a base class
00647       CIMQualifierArray qualArray = childClass.getQualifiers();
00648       for (size_t i = 0; i < qualArray.size(); i++)
00649       {
00650          qualArray[i].setPropagated(false);
00651       }
00652       CIMPropertyArray propArray = childClass.getAllProperties();
00653       for (size_t i = 0; i < propArray.size(); i++)
00654       {
00655          propArray[i].setPropagated(false);
00656          propArray[i].setOriginClass(childName);
00657       }
00658       childClass.setProperties(propArray);
00659       CIMMethodArray methArray = childClass.getAllMethods();
00660       for (size_t i = 0; i < methArray.size(); i++)
00661       {
00662          methArray[i].setPropagated(false);
00663          methArray[i].setOriginClass(childName);
00664       }
00665       childClass.setMethods(methArray);
00666       //_throwIfBadClass(childClass, parentClass);
00667       return parentNode;
00668    }
00670    // At this point we know we have a parent class
00671    CIMQualifierArray newQuals;
00672    CIMQualifierArray qualArray = childClass.getQualifiers();
00673    for (size_t i = 0; i < qualArray.size(); i++)
00674    {
00675       CIMQualifier qual = qualArray[i];
00676       CIMQualifier pqual = parentClass.getQualifier(qual.getName());
00677       if (pqual)
00678       {
00679          if (pqual.getValue().equal(qual.getValue()))
00680          {
00681             if (pqual.hasFlavor(CIMFlavor::RESTRICTED))
00682             {
00683                // NOT PROPAGATED.  qual.setPropagated(true);
00684                newQuals.append(qual);
00685             }
00686          }
00687          else
00688          {
00689             if (pqual.hasFlavor(CIMFlavor::DISABLEOVERRIDE))
00690             {
00691                OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00692                      Format("Parent class qualifier %1 has DISABLEOVERRIDE flavor. "
00693                         "Child cannot override it.", pqual.getName()).c_str());
00694             }
00695             newQuals.append(qual);
00696          }
00697       }
00698       else
00699       {
00700          newQuals.push_back(qual);
00701       }
00702    }
00703    childClass.setQualifiers(newQuals);
00704    CIMPropertyArray propArray = childClass.getAllProperties();
00705    for (size_t i = 0; i < propArray.size(); i++)
00706    {
00707       CIMProperty parentProp = parentClass.getProperty(propArray[i].getName());
00708       if (parentProp)
00709       {
00710          if (propArray[i].getQualifier(CIMQualifier::CIM_QUAL_OVERRIDE))
00711          {
00712             if (propArray[i].getOriginClass().empty())
00713             {
00714                propArray[i].setOriginClass(childName);
00715                propArray[i].setPropagated(false);
00716             }
00717             else
00718             {
00719                propArray[i].setPropagated(true);
00720             }
00721             // now make sure any qualifiers are properly set
00722             CIMQualifierArray parentQuals = parentProp.getQualifiers();
00723             for (size_t j = 0; j < parentQuals.size(); ++j)
00724             {
00725                CIMQualifier& qual = parentQuals[j];
00726                // If the qualifier has DisableOverride flavor, the
00727                // subclass can't change it.  (e.g. Key). It gets the
00728                // parent qualifier.
00729                if (qual.hasFlavor(CIMFlavor::DISABLEOVERRIDE))
00730                {
00731                   if (!propArray[i].getQualifier(qual.getName()))
00732                   {
00733                      propArray[i].addQualifier(qual);
00734                   }
00735                   else
00736                   {
00737                      // TODO: look at this message, it seems the dmtf cim schema causes it quite often.
00738                      // maybe we should only output it if the value is different?
00739                      OW_LOG_INFO(m_env->getLogger(COMPONENT_NAME), Format("Warning: %1.%2: qualifier %3 was "
00740                               "overridden, but the qualifier can't be "
00741                               "overridden because it has DisableOverride flavor",
00742                               childClass.getName(), propArray[i].getName(),
00743                               qual.getName()));
00744                      propArray[i].setQualifier(qual);
00745                   }
00746                }
00747                // If the qualifier has ToSubclass (not Restricted), then
00748                // only propagate it down if it's not overridden in the
00749                // subclass.
00750                else if (!qual.hasFlavor(CIMFlavor::RESTRICTED))
00751                {
00752                   if (!propArray[i].getQualifier(qual.getName()))
00753                   {
00754                      propArray[i].addQualifier(qual);
00755                   }
00756                }
00757             }
00758          }
00759          else
00760          {
00761             propArray[i].setOriginClass(parentProp.getOriginClass());
00762             propArray[i].setPropagated(true);
00763          }
00764       }
00765       else
00766       {
00767          // According to the 2.2 spec. If the parent class has key properties,
00768          // the child class cannot declare additional key properties.
00769          if (propArray[i].isKey())
00770          {
00771             // This is a key property, so the parent class better not be a
00772             // keyed class.
00773             if (parentClass.isKeyed())
00774             {
00775                OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00776                      Format("Parent class has keys. Child cannot have additional"
00777                         " key properties: %1", childClass.getName()).c_str());
00778             }
00779          }
00780          propArray[i].setOriginClass(childName);
00781          propArray[i].setPropagated(false);
00782       }
00783    }
00784    childClass.setProperties(propArray);
00785    CIMMethodArray methArray = childClass.getAllMethods();
00786    for (size_t i = 0; i < methArray.size(); i++)
00787    {
00788       if (parentClass.getMethod(methArray[i].getName()) &&
00789             !methArray[i].getQualifier(CIMQualifier::CIM_QUAL_OVERRIDE))
00790       {
00791          methArray[i].setOriginClass(parentName);
00792          methArray[i].setPropagated(true);
00793       }
00794       else
00795       {
00796          methArray[i].setOriginClass(childName);
00797          methArray[i].setPropagated(false);
00798       }
00799    }
00800    childClass.setMethods(methArray);
00801    if (parentClass.isKeyed())
00802    {
00803       childClass.setIsKeyed();
00804    }
00805    // Don't allow the child class to be an association if the parent class isn't.
00806    // This shouldn't normally happen, because the association qualifier has
00807    // a DISABLEOVERRIDE flavor, so it will be caught in an earlier test.
00808    if (childClass.isAssociation() && !parentClass.isAssociation())
00809    {
00810       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00811             Format("Association class is derived from non-association class: %1",
00812                childClass.getName()).c_str());
00813    }
00814    //_throwIfBadClass(childClass, parentClass);
00815    return parentNode;
00816 }
00818 void
00819 MetaRepository::_resolveQualifiers(const String& ns,
00820    CIMQualifierArray& quals, HDBHandle hdl)
00821 {
00822    for (size_t i = 0; i < quals.size(); i++)
00823    {
00824       CIMQualifierType qt = getQualifierType(ns, quals[i].getName(), &hdl);
00825       if (qt)
00826       {
00827          CIMFlavorArray fra = qt.getFlavors();
00828          for (size_t j = 0; j < fra.size(); j++)
00829          {
00830             quals[i].addFlavor(fra[j]);
00831          }
00832       }
00833       else
00834       {
00835          OW_LOG_ERROR(m_env->getLogger(COMPONENT_NAME), Format("Unable to find qualifier: %1",
00836             quals[i].getName()));
00837          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00838             Format("Unable to find qualifier: %1",
00839             quals[i].getName()).c_str());
00840       }
00841    }
00842 }
00843 #endif // #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00844 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00845 
00846 void
00847 MetaRepository::getTopLevelAssociations(const String& ns,
00848    CIMClassResultHandlerIFC& result)
00849 {
00850    throwIfNotOpen();
00851    HDBHandleLock hdl(this, getHandle());
00852    HDBNode node = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns);
00853    if (!node)
00854    {
00855       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00856    }
00857    node = hdl->getFirstChild(node);
00858    while (node)
00859    {
00860       if (!node.areAllFlagsOn(HDBNSNODE_FLAG)
00861          && node.areAllFlagsOn(HDBCLSASSOCNODE_FLAG))
00862       {
00863          CIMClass cc(CIMNULL);
00864          nodeToCIMObject(cc, node);
00865          OW_ASSERT(cc.isAssociation());
00866          result.handle(cc);
00867       }
00868       node = hdl->getNextSibling(node);
00869    }
00870 }
00871 #endif
00872 
00873 void
00874 MetaRepository::enumClass(const String& ns, const CIMName& className,
00875    CIMClassResultHandlerIFC& result,
00876    EDeepFlag deep, ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers,
00877    EIncludeClassOriginFlag includeClassOrigin)
00878 {
00879    throwIfNotOpen();
00880    HDBHandleLock hdl(this, getHandle());
00881    HDBNode pnode;
00882    if (className != CIMName())
00883    {
00884       String ckey = _makeClassPath(ns, className);
00885       pnode = hdl->getNode(ckey);
00886       if (!pnode)
00887       {
00888          pnode = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns);
00889          if (!pnode)
00890          {
00891             OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00892          }
00893          else
00894          {
00895             OW_THROWCIMMSG(CIMException::INVALID_CLASS, className.toString().c_str());
00896          }
00897       }
00898    }
00899    else
00900    {
00901       pnode = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns);
00902       if (!pnode)
00903       {
00904          OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00905       }
00906    }
00907    pnode = hdl->getFirstChild(pnode);
00908    while (pnode)
00909    {
00910       if (!pnode.areAllFlagsOn(HDBNSNODE_FLAG))
00911       {
00912          _getClassNodes(ns, result, pnode, hdl.getHandle(), deep, localOnly,
00913             includeQualifiers, includeClassOrigin);
00914       }
00915       pnode = hdl->getNextSibling(pnode);
00916    }
00917 }
00919 void
00920 MetaRepository::_getClassNodes(const String& ns, CIMClassResultHandlerIFC& result, HDBNode node,
00921    HDBHandle hdl, EDeepFlag deep, ELocalOnlyFlag localOnly,
00922    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin)
00923 {
00924    CIMClass cimCls = _getClassFromNode(node, hdl, ns);
00925    // TODO: Check cimCls for NULL?
00926    result.handle(cimCls.clone(localOnly, includeQualifiers,
00927       includeClassOrigin));
00928    if (deep)
00929    {
00930       node = hdl.getFirstChild(node);
00931       while (node)
00932       {
00933          _getClassNodes(ns, result, node, hdl, deep, localOnly, includeQualifiers,
00934             includeClassOrigin);
00935          node = hdl.getNextSibling(node);
00936       }
00937    }
00938 }
00940 void
00941 MetaRepository::enumClassNames(const String& ns, const CIMName& className,
00942    StringResultHandlerIFC& result,
00943    EDeepFlag deep)
00944 {
00945    throwIfNotOpen();
00946    HDBHandleLock hdl(this, getHandle());
00947    HDBNode pnode;
00948    if (className != CIMName())
00949    {
00950       String ckey = _makeClassPath(ns, className);
00951       pnode = hdl->getNode(ckey);
00952       if (!pnode)
00953       {
00954          pnode = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns);
00955          if (!pnode)
00956          {
00957             OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00958          }
00959          else
00960          {
00961             OW_THROWCIMMSG(CIMException::INVALID_CLASS, className.toString().c_str());
00962          }
00963       }
00964    }
00965    else
00966    {
00967       pnode = getNameSpaceNode(hdl, CLASS_CONTAINER + NS_SEPARATOR_C + ns);
00968       if (!pnode)
00969       {
00970          OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE, ns.c_str());
00971       }
00972    }
00973    pnode = hdl->getFirstChild(pnode);
00974    while (pnode)
00975    {
00976       if (!pnode.areAllFlagsOn(HDBNSNODE_FLAG))
00977       {
00978          _getClassNameNodes(result, pnode, hdl.getHandle(), deep);
00979       }
00980       pnode = hdl->getNextSibling(pnode);
00981    }
00982 }
00984 void
00985 MetaRepository::_getClassNameNodes(StringResultHandlerIFC& result, HDBNode node,
00986    HDBHandle hdl, EDeepFlag deep)
00987 {
00988    CIMName cimClsName = _getClassNameFromNode(node);
00989    result.handle(cimClsName.toString());
00990    if (deep)
00991    {
00992       node = hdl.getFirstChild(node);
00993       while (node)
00994       {
00995          _getClassNameNodes(result, node, hdl, deep);
00996          node = hdl.getNextSibling(node);
00997       }
00998    }
00999 }
01000 #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
01001 
01002 void
01003 MetaRepository::deleteNameSpace(const String& nsName)
01004 {
01005    throwIfNotOpen();
01006    // ATTN: Do we need to do more later? Associations?
01007    GenericHDBRepository::deleteNameSpace(QUAL_CONTAINER + NS_SEPARATOR_C + nsName);
01008    GenericHDBRepository::deleteNameSpace(CLASS_CONTAINER + NS_SEPARATOR_C + nsName);
01009    /*
01010    HDBHandleLock hdl(this, getHandle());
01011    HDBNode node = _getQualContainer(hdl, nsName);
01012    if (node)
01013    {
01014       hdl->removeNode(node);
01015    }
01016     */
01017    m_classCache.clearCache();
01018 }
01020 int
01021 MetaRepository::createNameSpace(const String& ns)
01022 {
01023    // First create the name space in the class container.
01024    if (GenericHDBRepository::createNameSpace(CLASS_CONTAINER + NS_SEPARATOR_C + ns) == -1)
01025    {
01026       return -1;
01027    }
01028    // Now create the same name space in the qualifier container.
01029    // TODO: If the second create fails, we need to undo the first one.
01030    return GenericHDBRepository::createNameSpace(QUAL_CONTAINER + NS_SEPARATOR_C + ns);
01031 }
01032 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
01033 
01034 MetaRepository::MetaRepository()
01035 {
01036 }
01037 
01039 void
01040 MetaRepository::init(const ServiceEnvironmentIFCRef& env)
01041 {
01042    this->GenericHDBRepository::init(env);
01043    String maxCacheSizeOpt = env->getConfigItem(ConfigOpts::MAX_CLASS_CACHE_SIZE_opt, OW_DEFAULT_MAX_CLASS_CACHE_SIZE);
01044    try
01045    {
01046       m_classCache.setMaxCacheSize(maxCacheSizeOpt.toUInt32());
01047    }
01048    catch (const StringConversionException&)
01049    {
01050       m_classCache.setMaxCacheSize(OW_DEFAULT_MAX_CLASS_CACHE_SIZE_I);
01051    }
01052 }
01053 
01054 } // end namespace OW_NAMESPACE
01055 

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