00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00036 #include "OW_config.h"
00037 #include "OW_InstanceRepository.hpp"
00038 #include "OW_DataStreams.hpp"
00039 #include "OW_StringBuffer.hpp"
00040 #include "OW_CIMException.hpp"
00041 #include "OW_CIMProperty.hpp"
00042 #include "OW_CIMInstance.hpp"
00043 #include "OW_CIMClass.hpp"
00044 #include "OW_CIMObjectPath.hpp"
00045 #include "OW_CIMValue.hpp"
00046 #include "OW_CIMQualifier.hpp"
00047 #include "OW_CIMFlavor.hpp"
00048 #include "OW_Format.hpp"
00049 #include "OW_CIMValueCast.hpp"
00050 #include "OW_IOException.hpp"
00051 
00052 namespace OW_NAMESPACE
00053 {
00054 
00055 using namespace WBEMFlags;
00056 
00057 namespace
00058 {
00059 
00060 const char NS_SEPARATOR_C(':');
00061 
00062 } 
00064 String
00065 InstanceRepository::makeInstanceKey(const String& ns, const CIMObjectPath& cop,
00066    const CIMClass& theClass)
00067 {
00068    if (!cop)
00069    {
00070       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, "no object path");
00071    }
00072    
00073    StringBuffer rv(makeClassKey(ns, cop.getClassName()));
00074    rv += NS_SEPARATOR_C;
00075    CIMPropertyArray kprops = theClass.getKeys();
00076    if (kprops.size() == 0)
00077    {
00078       rv += cop.getClassName();
00079       return rv.releaseString();
00080       
00081       
00082       
00083    }
00084    String oclass = kprops[0].getOriginClass().toLowerCase();
00085    if (oclass.empty())
00086    {
00087       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00088          Format("No orgin class for key property on class: %1",
00089             theClass.getName()).c_str());
00090    }
00091    rv += oclass;
00092    
00093    CIMPropertyArray pra = cop.getKeys();
00094    if (pra.size() == 0)
00095    {
00096       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00097          "object path has no keys");
00098    }
00099    for (size_t i = 0; i < pra.size(); i++)
00100    {
00101       if (!pra[i].getValue())
00102       {
00103          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00104             Format("object path (%1) has key (%2) with NULL value", cop, pra[i].getName()).c_str());
00105       }
00106    }
00107    
00108    if (pra.size() < kprops.size())
00109    {
00110       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00111          Format("Model path is missing keys: %1", cop.toString()).c_str());
00112    }
00113    
00114    if (pra.size() == 1)
00115    {
00116       
00117       
00118       String pname = pra[0].getName().toLowerCase();
00119       if (!pname.empty() && !pname.equalsIgnoreCase(kprops[0].getName()))
00120       {
00121          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00122             Format("Property in model path is not a key: %1", pname).c_str());
00123       }
00124       rv += '.';
00125       rv += pname;
00126       rv += '=';
00127       CIMValue cv = CIMValueCast::castValueToDataType(pra[0].getValue(),
00128          kprops[0].getDataType());
00129       if (cv.getType() == CIMDataType::REFERENCE)
00130       {
00131          CIMObjectPath cop(cv.toCIMObjectPath());
00132          if (cop.getNameSpace().empty())
00133          {
00134             cop.setNameSpace(ns);
00135             cv = CIMValue(cop);
00136          }
00137       }
00138       rv += cv.toString();
00139       return rv.releaseString();
00140    }
00141    
00142    
00143    for (size_t i = 0; i < pra.size(); i++)
00144    {
00145       String pname = pra[i].getName();
00146       size_t j = 0;
00147       for (; j < kprops.size(); j++)
00148       {
00149          if (pname.equalsIgnoreCase(kprops[j].getName()))
00150          {
00151             CIMValue cv = CIMValueCast::castValueToDataType(
00152                pra[i].getValue(), kprops[j].getDataType());
00153             if (cv.getType() == CIMDataType::REFERENCE)
00154             {
00155                CIMObjectPath cop(cv.toCIMObjectPath());
00156                if (cop.getNameSpace().empty())
00157                {
00158                   cop.setNameSpace(ns);
00159                   cv = CIMValue(cop);
00160                }
00161             }
00162             pra[i].setValue(cv);
00163             break;
00164          }
00165       }
00166       if (j == kprops.size())
00167       {
00168          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00169             Format("Property in model path is not a key: %1", pname).c_str());
00170       }
00171    }
00172 
00173    HDBUtilKeyArray kra(pra);
00174    kra.toString(rv);
00175    return rv.releaseString();
00176 }
00178 String
00179 InstanceRepository::makeClassKey(const String& ns,
00180    const String& className)
00181 {
00182    String rv(ns);
00183    rv += NS_SEPARATOR_C;
00184    rv += className;
00185    return rv.toLowerCase();
00186 }
00188 void
00189 InstanceRepository::getInstanceNames(const String& ns,
00190    const CIMClass& theClass, CIMObjectPathResultHandlerIFC& result)
00191 {
00192    throwIfNotOpen();
00193    String className = theClass.getName();
00194    HDBHandleLock hdl(this, getHandle());
00195    String ckey = makeClassKey(ns, className);
00196    HDBNode clsNode = hdl->getNode(ckey);
00197    if (!clsNode)
00198    {
00199       OW_THROWCIM(CIMException::INVALID_CLASS);
00200    }
00201    if (!clsNode.areAllFlagsOn(HDBCLSNODE_FLAG))
00202    {
00203       OW_THROW(IOException, "Expected class name node for instances");
00204    }
00205    HDBNode node = hdl->getFirstChild(clsNode);
00206    while (node)
00207    {
00208       CIMInstance ci(CIMNULL);
00209       nodeToCIMObject(ci, node);
00210       ci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS); 
00211       CIMObjectPath op(ci.getClassName(), ns);
00212       op.setKeys(ci.getKeyValuePairs());
00213       result.handle(op);
00214       node = hdl->getNextSibling(node);
00215    }
00216 }
00217 
00219 void
00220 InstanceRepository::getCIMInstances(
00221    const String& ns,
00222    const String& className,
00223    const CIMClass& requestedClass,
00224    const CIMClass& theClass, CIMInstanceResultHandlerIFC& result,
00225    EDeepFlag deep, ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers,
00226    EIncludeClassOriginFlag includeClassOrigin, const StringArray* propertyList)
00227 {
00228    throwIfNotOpen();
00229    HDBHandleLock hdl(this, getHandle());
00230    String ckey = makeClassKey(ns, className);
00231    HDBNode clsNode = hdl->getNode(ckey);
00232    if (!clsNode)
00233    {
00234       OW_THROWCIM(CIMException::INVALID_CLASS);
00235    }
00236    if (!clsNode.areAllFlagsOn(HDBCLSNODE_FLAG))
00237    {
00238       OW_THROW(IOException, "Expected class name node for instances");
00239    }
00240    HDBNode node = hdl->getFirstChild(clsNode);
00241    while (node)
00242    {
00243       CIMInstance ci(CIMNULL);
00244       nodeToCIMObject(ci, node);
00245       ci = ci.clone(localOnly,deep,includeQualifiers,includeClassOrigin,propertyList,requestedClass,theClass);
00246       result.handle(ci);
00247       node = hdl->getNextSibling(node);
00248    }
00249 }
00251 CIMInstance
00252 InstanceRepository::getCIMInstance(
00253    const String& ns,
00254    const CIMObjectPath& instanceName,
00255    const CIMClass& theClass, ELocalOnlyFlag localOnly,
00256    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00257    const StringArray* propertyList)
00258 {
00259    throwIfNotOpen();
00260    String instanceKey = makeInstanceKey(ns, instanceName, theClass);
00261    HDBHandleLock hdl(this, getHandle());
00262    HDBNode node = hdl->getNode(instanceKey);
00263    if (!node)
00264    {
00265       CIMObjectPath cop(instanceName);
00266       cop.setNameSpace(ns);
00267       OW_THROWCIMMSG(CIMException::NOT_FOUND, cop.toString().c_str());
00268    }
00269    CIMInstance ci(CIMNULL);
00270    nodeToCIMObject(ci, node);
00271    ci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS);
00272    
00273    
00274    if (propertyList
00275       || localOnly == E_LOCAL_ONLY
00276       || includeQualifiers == E_EXCLUDE_QUALIFIERS
00277       || includeClassOrigin == E_EXCLUDE_CLASS_ORIGIN)
00278    {
00279       ci = ci.clone(localOnly, includeQualifiers, includeClassOrigin,
00280          propertyList);
00281    }
00282    
00283    return ci;
00284 }
00285 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00286 
00287 void
00288 InstanceRepository::deleteInstance(const String& ns, const CIMObjectPath& cop,
00289    const CIMClass& theClass)
00290 {
00291    throwIfNotOpen();
00292    String instanceKey = makeInstanceKey(ns, cop, theClass);
00293    HDBHandleLock hdl(this, getHandle());
00294    HDBNode node = hdl->getNode(instanceKey);
00295    if (!node)
00296    {
00297       CIMObjectPath cop2(cop);
00298       cop2.setNameSpace(ns);
00299       OW_THROWCIMMSG(CIMException::NOT_FOUND, cop2.toString().c_str());
00300    }
00301    
00302    
00303    CIMInstance ci(CIMNULL);
00304    nodeToCIMObject(ci, node);
00305    hdl->removeNode(node);
00306 }
00308 void
00309 InstanceRepository::createInstance(const String& ns,
00310    const CIMClass& theClass, const CIMInstance& ci_)
00311 {
00312    throwIfNotOpen();
00313    HDBHandleLock hdl(this, getHandle());
00314    CIMInstance ci(ci_);
00315    String ckey = makeClassKey(ns, ci.getClassName());
00316    HDBNode clsNode = getNameSpaceNode(hdl, ckey);
00317    if (!clsNode)
00318    {
00319       
00320       OW_THROWCIMMSG(CIMException::INVALID_CLASS, ci.getClassName().c_str());
00321    }
00322    
00323    CIMObjectPath icop(ns, ci);
00324    String instanceKey = makeInstanceKey(ns, icop, theClass);
00325    HDBNode node = hdl->getNode(instanceKey);
00326    if (node)
00327    {
00328       OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, instanceKey.c_str());
00329    }
00330    _removeDuplicatedQualifiers(ci, theClass);
00331    DataOStream ostrm;
00332    ci.writeObject(ostrm);
00333    node = HDBNode(instanceKey, ostrm.length(), ostrm.getData());
00334    hdl.getHandle().addChild(clsNode, node);
00335 }
00337 
00338 bool
00339 InstanceRepository::classHasInstances(const CIMObjectPath& classPath)
00340 {
00341    bool cc = false;
00342    throwIfNotOpen();
00343    HDBHandleLock hdl(this, getHandle());
00344    String ckey = makeClassKey(classPath.getNameSpace(),
00345       classPath.getClassName());
00346    HDBNode node = hdl->getNode(ckey);
00347    if (node)
00348    {
00349       if (!node.areAllFlagsOn(HDBCLSNODE_FLAG))
00350       {
00351          OW_THROW(IOException, "Expected class name node for instances");
00352       }
00353       cc = node.hasChildren();
00354    }
00355    return cc;
00356 }
00358 void
00359 InstanceRepository::modifyInstance(const String& ns,
00360    const CIMObjectPath& cop,
00361    const CIMClass& theClass, const CIMInstance& ci_,
00362    const CIMInstance& oldInst,
00363    EIncludeQualifiersFlag includeQualifiers,
00364    const StringArray* propertyList)
00365 {
00366    throwIfNotOpen();
00367    HDBHandleLock hdl(this, getHandle());
00368    CIMInstance ci(ci_.createModifiedInstance(oldInst,includeQualifiers,propertyList,theClass));
00369    
00370    
00371    
00372    ci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS);
00373    
00374    CIMPropertyArray oldKeys = oldInst.getKeyValuePairs();
00375    for (size_t i = 0; i < oldKeys.size(); i++)
00376    {
00377       CIMProperty kprop = ci.getProperty(oldKeys[i].getName());
00378       if (!kprop)
00379       {
00380          String msg("Missing key value: ");
00381          msg += oldKeys[i].getName();
00382          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00383       }
00384       CIMValue cv1 = kprop.getValue();
00385       if (!cv1)
00386       {
00387          String msg("Missing key value: ");
00388          msg += kprop.getName();
00389          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00390       }
00391       CIMValue cv2 = oldKeys[i].getValue();
00392       if (!cv2)
00393       {
00394          String msg("Missing key value in object path: ");
00395          msg += oldKeys[i].getName();
00396          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00397       }
00398       if (!cv1.sameType(cv2))
00399       {
00400          String msg("Data type for key property changed! property: ");
00401          msg += kprop.getName();
00402          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00403       }
00404       if (!cv1.equal(cv2))
00405       {
00406          String msg("key value for instance changed: ");
00407          msg += kprop.getName();
00408          OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
00409       }
00410    }
00411    _removeDuplicatedQualifiers(ci, theClass);
00412    DataOStream ostrm;
00413    ci.writeObject(ostrm);
00414    String instanceKey = makeInstanceKey(ns, cop, theClass);
00415    HDBNode node = hdl->getNode(instanceKey);
00416    if (!node)
00417    {
00418       OW_THROWCIMMSG(CIMException::NOT_FOUND, cop.toString().c_str());
00419    }
00420    hdl.getHandle().updateNode(node, ostrm.length(), ostrm.getData());
00421 }
00422 #endif
00423 
00424 #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
00425 
00426 void
00427 InstanceRepository::deleteNameSpace(const String& nsName)
00428 {
00429    throwIfNotOpen();
00430    
00431    GenericHDBRepository::deleteNameSpace(nsName);
00432 }
00434 int
00435 InstanceRepository::createNameSpace(const String& ns)
00436 {
00437    return GenericHDBRepository::createNameSpace(ns);
00438 }
00439 #endif // #if !defined(OW_DISABLE_INSTANCE_MANIPULATION) && !defined(OW_DISABLE_NAMESPACE_MANIPULATION)
00440 
00441 #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00442 
00443 void
00444 InstanceRepository::createClass(const String& ns,
00445    const CIMClass& cimClass)
00446 {
00447    throwIfNotOpen();
00448    HDBHandleLock hdl(this, getHandle());
00449    HDBNode pnode = getNameSpaceNode(hdl, ns);
00450    if (!pnode)
00451    {
00452       OW_THROWCIMMSG(CIMException::INVALID_NAMESPACE,
00453          ns.c_str());
00454    }
00455    String ckey = makeClassKey(ns, cimClass.getName());
00456    HDBNode node = hdl->getNode(ckey);
00457    if (node)
00458    {
00459       OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, ckey.c_str());
00460    }
00461    node = HDBNode(ckey, ckey.length()+1,
00462       reinterpret_cast<const unsigned char*>(ckey.c_str()));
00463    hdl->turnFlagsOn(node, HDBNSNODE_FLAG | HDBCLSNODE_FLAG);
00464    hdl->addChild(pnode, node);
00465 }
00467 void
00468 InstanceRepository::deleteClass(const String& ns,
00469    const String& className)
00470 {
00471    throwIfNotOpen();
00472    HDBHandleLock hdl(this, getHandle());
00473    String ckey = makeClassKey(ns, className);
00474    HDBNode node = hdl->getNode(ckey);
00475    if (node)
00476    {
00477       if (!node.areAllFlagsOn(HDBCLSNODE_FLAG))
00478       {
00479          OW_THROW(IOException, "Expected class name node for instances");
00480       }
00481    }
00482    hdl->removeNode(ckey);
00483 }
00484 #endif // #ifndef OW_DISABLE_SCHEMA_MANIPULATION
00485 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00486 
00487 void InstanceRepository::_removeDuplicatedQualifiers(CIMInstance& inst,
00488    const CIMClass& theClass)
00489 {
00490    CIMQualifierArray quals(inst.getQualifiers());
00491    CIMQualifierArray newQuals;
00492    for (size_t i = 0; i < quals.size(); ++i)
00493    {
00494       CIMQualifier& iq = quals[i];
00495       CIMQualifier cq = theClass.getQualifier(iq.getName());
00496       if (!cq)
00497       {
00498          newQuals.push_back(iq);
00499          continue;
00500       }
00501       if (iq.getValue() != cq.getValue())
00502       {
00503          newQuals.push_back(iq);
00504          continue;
00505       }
00506    }
00507    inst.setQualifiers(newQuals);
00508    CIMPropertyArray props = inst.getProperties();
00509    for (size_t i = 0; i < props.size(); ++i)
00510    {
00511       CIMProperty& p = props[i];
00512       CIMProperty clsp = theClass.getProperty(p.getName());
00513       CIMQualifierArray quals(p.getQualifiers());
00514       CIMQualifierArray newQuals;
00515       for (size_t j = 0; j < quals.size(); ++j)
00516       {
00517          CIMQualifier& ipq = quals[j];
00518          CIMQualifier cpq = clsp.getQualifier(ipq.getName());
00519          if (!cpq)
00520          {
00521             newQuals.push_back(ipq);
00522             continue;
00523          }
00524          if (ipq.getValue() != cpq.getValue())
00525          {
00526             newQuals.push_back(ipq);
00527             continue;
00528          }
00529       }
00530       p.setQualifiers(newQuals);
00531    }
00532    inst.setProperties(props);
00533 }
00534 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00535 
00536 } 
00537