OW_InstanceRepository2.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001 Center 7, 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 Center 7 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 Center 7, 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 #include "OW_config.h"
00031 #include "OW_InstanceRepository2.hpp"
00032 #include "OW_DataStreams.hpp"
00033 #include "OW_StringBuffer.hpp"
00034 #include "OW_CIMException.hpp"
00035 #include "OW_CIMProperty.hpp"
00036 #include "OW_CIMInstance.hpp"
00037 #include "OW_CIMClass.hpp"
00038 #include "OW_CIMObjectPath.hpp"
00039 #include "OW_CIMValue.hpp"
00040 #include "OW_CIMQualifier.hpp"
00041 #include "OW_CIMFlavor.hpp"
00042 #include "OW_Format.hpp"
00043 #include "OW_CIMValueCast.hpp"
00044 #include "OW_IOException.hpp"
00045 
00046 namespace OW_NAMESPACE
00047 {
00048 
00049 using namespace WBEMFlags;
00050 
00052 InstanceRepository2::~InstanceRepository2()
00053 {
00054    try
00055    {
00056       close();
00057    }
00058    catch (...)
00059    {
00060       // logDebug or close could throw.
00061    }
00062 }
00063 
00065 void
00066 InstanceRepository2::close()
00067 {
00068    m_instanceNameLists.close();
00069    m_instances.close();
00070 }
00071 
00073 void
00074 InstanceRepository2::open(::DB_ENV* env, ::DB_TXN* txn)
00075 {
00076    m_instanceNameLists.open("instancenamelists", env, txn, dbDatabase::E_DUPLICATES);
00077    m_instances.open("instances", env, txn, dbDatabase::E_NO_DUPLICATES);
00078 }
00079 
00081 class UtilKeyArray
00082 {
00083 public:
00084    UtilKeyArray() : m_names(), m_properties() {}
00085    void addElement(const CIMProperty& prop);
00086    String toString(const String& className);
00087 private:
00088    StringArray m_names;
00089    StringArray m_properties;
00090 };
00092 void
00093 UtilKeyArray::addElement(const CIMProperty& prop)
00094 {
00095    String propName = prop.getName().toLowerCase();
00096    for (size_t i = 0; i < m_names.size(); i++)
00097    {
00098       int cc = m_names[i].compareTo(propName);
00099       if (cc == 0)
00100       {
00101          m_properties[i] = prop.getValue().toString();
00102          return;
00103       }
00104       else if (cc > 0)
00105       {
00106          m_names.insert(i, propName);
00107          m_properties.insert(i, prop.getValue().toString());
00108          return;
00109       }
00110    }
00111    m_names.append(propName);
00112    m_properties.append(prop.getValue().toString());
00113 }
00115 String
00116 UtilKeyArray::toString(const String& className)
00117 {
00118    StringBuffer rv(className.toString().toLowerCase());
00119    for (size_t i = 0; i < m_names.size(); i++)
00120    {
00121       char c = (i == 0) ? '.' : ',';
00122       rv += c;
00123       rv += m_names[i];
00124       rv += '=';
00125       rv += m_properties[i];
00126    }
00127    return rv.releaseString();
00128 }
00130 String
00131 InstanceRepository2::makeInstanceKey(const String& ns, const CIMObjectPath& cop,
00132    const CIMClass& theClass)
00133 {
00134    if (!cop)
00135    {
00136       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, "no object path");
00137    }
00138    // Start return value with the namespace
00139    StringBuffer rv(makeClassKey(ns, cop.getClassName()));
00140    rv += '/';
00141    CIMPropertyArray kprops = theClass.getKeys();
00142    if (kprops.size() == 0)
00143    {
00144       rv += cop.getClassName();
00145       return rv.releaseString();
00146       // don't do this to allow for singleton classes without keys.
00147       //OW_THROWCIMMSG(CIMException::INVALID_CLASS,
00148       // format("No key properties for class: %1", theClass.getName()).c_str());
00149    }
00150    String oclass = kprops[0].getOriginClass().toLowerCase();
00151    if (oclass.empty())
00152    {
00153       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00154          format("No orgin class for key property on class: %1",
00155             theClass.getName()).c_str());
00156    }
00157    rv += oclass;
00158    // Get keys from object path
00159    CIMPropertyArray pra = cop.getKeys();
00160    if (pra.size() == 0)
00161    {
00162       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00163          "object path has no keys");
00164    }
00165    for (size_t i = 0; i < pra.size(); i++)
00166    {
00167       if (!pra[i].getValue())
00168       {
00169          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00170             "object path has key with missing value");
00171       }
00172    }
00173    // If not all the key properties were specified, throw an exception
00174    if (pra.size() < kprops.size())
00175    {
00176       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00177          format("Model path is missing keys: %1", cop.toString()).c_str());
00178    }
00179    // TODO: Is this necessary?
00180    if (pra.size() == 1)
00181    {
00182       // If only one key property in object path, ensure it is
00183       // a key property in the class
00184       String pname = pra[0].getName().toLowerCase();
00185       if (!pname.empty() && !pname.equalsIgnoreCase(kprops[0].getName()))
00186       {
00187          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00188             format("Property in model path is not a key: %1", pname).c_str());
00189       }
00190       rv += '.';
00191       rv += pname;
00192       rv += '=';
00193       CIMValue cv = CIMValueCast::castValueToDataType(pra[0].getValue(),
00194          kprops[0].getDataType());
00195       if (cv.getType() == CIMDataType::REFERENCE)
00196       {
00197          CIMObjectPath cop(cv.toCIMObjectPath());
00198          if (cop.getNameSpace().empty())
00199          {
00200             cop.setNameSpace(ns);
00201             cv = CIMValue(cop);
00202          }
00203       }
00204       rv += cv.toString();
00205       return rv.releaseString();
00206    }
00207    // TODO: Is this necessary?
00208    // Ensure no non-key properties were specified in the path
00209    for (size_t i = 0; i < pra.size(); i++)
00210    {
00211       String pname = pra[i].getName();
00212       size_t j = 0;
00213       for (; j < kprops.size(); j++)
00214       {
00215          if (pname.equalsIgnoreCase(kprops[j].getName()))
00216          {
00217             CIMValue cv = CIMValueCast::castValueToDataType(
00218                pra[i].getValue(), kprops[j].getDataType());
00219             if (cv.getType() == CIMDataType::REFERENCE)
00220             {
00221                CIMObjectPath cop(cv.toCIMObjectPath());
00222                if (cop.getNameSpace().empty())
00223                {
00224                   cop.setNameSpace(ns);
00225                   cv = CIMValue(cop);
00226                }
00227             }
00228             pra[i].setValue(cv);
00229             break;
00230          }
00231       }
00232       if (j == kprops.size())
00233       {
00234          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00235             format("Property in model path is not a key: %1", pname).c_str());
00236       }
00237    }
00238    UtilKeyArray kra;
00239    for (size_t i = 0; i < pra.size(); i++)
00240    {
00241       kra.addElement(pra[i]);
00242    }
00243    return kra.toString(rv.releaseString());
00244 }
00246 String
00247 InstanceRepository2::makeClassKey(const String& ns,
00248    const String& className)
00249 {
00250    String rv(ns);
00251    while (!rv.empty() && rv[0] == '/')
00252    {
00253       rv = rv.substring(1);
00254    }
00255    rv += "/";
00256    rv += className;
00257    return rv.toLowerCase();
00258 }
00260 void
00261 InstanceRepository2::getInstanceNames(const String& ns,
00262    const CIMClass& theClass, CIMObjectPathResultHandlerIFC& result)
00263 {
00264 //     String className = theClass.getName();
00265 //     HDBHandleLock hdl(this, getHandle());
00266 //     String ckey = makeClassKey(ns, className);
00267 //     HDBNode clsNode = hdl->getNode(ckey);
00268 //     if (!clsNode)
00269 //     {
00270 //         OW_THROWCIM(CIMException::INVALID_CLASS);
00271 //     }
00272 //     if (!clsNode.areAllFlagsOn(HDBCLSNODE_FLAG))
00273 //     {
00274 //         OW_THROW(IOException, "Expected class name node for instances");
00275 //     }
00276 //     HDBNode node = hdl->getFirstChild(clsNode);
00277 //     while (node)
00278 //     {
00279 //         CIMInstance ci(CIMNULL);
00280 //         nodeToCIMObject(ci, node);
00281 //         ci.syncWithClass(theClass); // need to do this to set up the keys
00282 //         CIMObjectPath op(ci.getClassName(), ns);
00283 //         op.setKeys(ci.getKeyValuePairs());
00284 //         result.handle(op);
00285 //         node = hdl->getNextSibling(node);
00286 //     }
00287 }
00288 
00290 void
00291 InstanceRepository2::getCIMInstances(
00292    const String& ns,
00293    const String& className,
00294    const CIMClass& requestedClass,
00295    const CIMClass& theClass, CIMInstanceResultHandlerIFC& result,
00296    EDeepFlag deep, ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers,
00297    EIncludeClassOriginFlag includeClassOrigin, const StringArray* propertyList)
00298 {
00299 //     throwIfNotOpen();
00300 //     HDBHandleLock hdl(this, getHandle());
00301 //     String ckey = makeClassKey(ns, className);
00302 //     HDBNode clsNode = hdl->getNode(ckey);
00303 //     if (!clsNode)
00304 //     {
00305 //         OW_THROWCIM(CIMException::INVALID_CLASS);
00306 //     }
00307 //     if (!clsNode.areAllFlagsOn(HDBCLSNODE_FLAG))
00308 //     {
00309 //         OW_THROW(IOException, "Expected class name node for instances");
00310 //     }
00311 //     HDBNode node = hdl->getFirstChild(clsNode);
00312 //     while (node)
00313 //     {
00314 //         CIMInstance ci(CIMNULL);
00315 //         nodeToCIMObject(ci, node);
00316 //         ci = ci.clone(localOnly,deep,includeQualifiers,includeClassOrigin,propertyList,requestedClass,theClass);
00317 //         result.handle(ci);
00318 //         node = hdl->getNextSibling(node);
00319 //     }
00320 }
00322 CIMInstance
00323 InstanceRepository2::getCIMInstance(
00324    const String& ns,
00325    const CIMObjectPath& instanceName,
00326    const CIMClass& theClass, ELocalOnlyFlag localOnly,
00327    EIncludeQualifiersFlag includeQualifiers, EIncludeClassOriginFlag includeClassOrigin,
00328    const StringArray* propertyList)
00329 {
00330 //     throwIfNotOpen();
00331 //     String instanceKey = makeInstanceKey(ns, instanceName, theClass);
00332 //     HDBHandleLock hdl(this, getHandle());
00333 //     HDBNode node = hdl->getNode(instanceKey);
00334 //     if (!node)
00335 //     {
00336 //         CIMObjectPath cop(instanceName);
00337 //         cop.setNameSpace(ns);
00338 //         OW_THROWCIMMSG(CIMException::NOT_FOUND, cop.toString().c_str());
00339 //     }
00340 //     CIMInstance ci(CIMNULL);
00341 //     nodeToCIMObject(ci, node);
00342 //     ci.syncWithClass(theClass, E_INCLUDE_QUALIFIERS);
00343 //
00344 //     // only filter if we need to
00345 //     if (propertyList || localOnly == true || includeQualifiers == false || includeClassOrigin == false)
00346 //     {
00347 //         ci = ci.clone(localOnly, includeQualifiers, includeClassOrigin,
00348 //             propertyList);
00349 //     }
00350    
00351     CIMInstance ci(CIMNULL);
00352    return ci;
00353 }
00354 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00355 
00356 void
00357 InstanceRepository2::deleteInstance(const String& ns, const CIMObjectPath& cop,
00358    const CIMClass& theClass)
00359 {
00360 //     throwIfNotOpen();
00361 //     String instanceKey = makeInstanceKey(ns, cop, theClass);
00362 //     HDBHandleLock hdl(this, getHandle());
00363 //     HDBNode node = hdl->getNode(instanceKey);
00364 //     if (!node)
00365 //     {
00366 //         CIMObjectPath cop2(cop);
00367 //         cop2.setNameSpace(ns);
00368 //         OW_THROWCIMMSG(CIMException::NOT_FOUND, cop2.toString().c_str());
00369 //     }
00370 //     // Ensure the node belongs to an CIMInstance before we delete it.
00371 //     // If it's not, an exception will be thrown
00372 //     CIMInstance ci(CIMNULL);
00373 //     nodeToCIMObject(ci, node);
00374 //     hdl->removeNode(node);
00375 }
00377 void
00378 InstanceRepository2::createInstance(const String& ns,
00379    const CIMClass& theClass, const CIMInstance& ci_)
00380 {
00381 //     throwIfNotOpen();
00382 //     HDBHandleLock hdl(this, getHandle());
00383 //     CIMInstance ci(ci_);
00384 //     String ckey = makeClassKey(ns, ci.getClassName());
00385 //     HDBNode clsNode = getNameSpaceNode(hdl, ckey);
00386 //     if (!clsNode)
00387 //     {
00388 //         // Theoretically this should never happen, but just in case...
00389 //         OW_THROWCIMMSG(CIMException::INVALID_CLASS, ci.getClassName().c_str());
00390 //     }
00391 //     // Create object path with keys from new instance
00392 //     CIMObjectPath icop(ns, ci);
00393 //     String instanceKey = makeInstanceKey(ns, icop, theClass);
00394 //     HDBNode node = hdl->getNode(instanceKey);
00395 //     if (node)
00396 //     {
00397 //         OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, instanceKey.c_str());
00398 //     }
00399 //     _removeDuplicatedQualifiers(ci, theClass);
00400 //     DataOStream ostrm;
00401 //     ci.writeObject(ostrm);
00402 //     node = HDBNode(instanceKey, ostrm.length(), ostrm.getData());
00403 //     hdl.getHandle().addChild(clsNode, node);
00404 }
00406 // TODO: Is this function actually used?
00407 bool
00408 InstanceRepository2::classHasInstances(const CIMObjectPath& classPath)
00409 {
00410    bool cc = false;
00411 //     throwIfNotOpen();
00412 //     HDBHandleLock hdl(this, getHandle());
00413 //     String ckey = makeClassKey(classPath.getNameSpace(),
00414 //         classPath.getClassName());
00415 //     HDBNode node = hdl->getNode(ckey);
00416 //     if (node)
00417 //     {
00418 //         if (!node.areAllFlagsOn(HDBCLSNODE_FLAG))
00419 //         {
00420 //             OW_THROW(IOException, "Expected class name node for instances");
00421 //         }
00422 //         cc = node.hasChildren();
00423 //     }
00424    return cc;
00425 }
00427 void
00428 InstanceRepository2::modifyInstance(const String& ns,
00429    const CIMObjectPath& cop,
00430    const CIMClass& theClass, const CIMInstance& ci_,
00431    const CIMInstance& oldInst,
00432    EIncludeQualifiersFlag includeQualifiers,
00433    const StringArray* propertyList)
00434 {
00435 //     throwIfNotOpen();
00436 //     HDBHandleLock hdl(this, getHandle());
00437 //     CIMInstance ci(ci_.createModifiedInstance(oldInst,includeQualifiers,propertyList,theClass));
00438 //     // Now sync the new instance with the class. This will remove any properties
00439 //     // that shouldn't be on the instance and add properties that should be
00440 //     // there.
00441 //     ci.syncWithClass(theClass, E_EXCLUDE_QUALIFIERS);
00442 //     // Ensure key values haven't changed
00443 //     CIMPropertyArray oldKeys = oldInst.getKeyValuePairs();
00444 //     for (size_t i = 0; i < oldKeys.size(); i++)
00445 //     {
00446 //         CIMProperty kprop = ci.getProperty(oldKeys[i].getName());
00447 //         if (!kprop)
00448 //         {
00449 //             String msg("Missing key value: ");
00450 //             msg += oldKeys[i].getName();
00451 //             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00452 //         }
00453 //         CIMValue cv1 = kprop.getValue();
00454 //         if (!cv1)
00455 //         {
00456 //             String msg("Missing key value: ");
00457 //             msg += kprop.getName();
00458 //             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00459 //         }
00460 //         CIMValue cv2 = oldKeys[i].getValue();
00461 //         if (!cv2)
00462 //         {
00463 //             String msg("Missing key value in object path: ");
00464 //             msg += oldKeys[i].getName();
00465 //             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00466 //         }
00467 //         if (!cv1.sameType(cv2))
00468 //         {
00469 //             String msg("Data type for key property changed! property: ");
00470 //             msg += kprop.getName();
00471 //             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, msg.c_str());
00472 //         }
00473 //         if (!cv1.equal(cv2))
00474 //         {
00475 //             String msg("key value for instance changed: ");
00476 //             msg += kprop.getName();
00477 //             OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
00478 //         }
00479 //     }
00480 //     _removeDuplicatedQualifiers(ci, theClass);
00481 //     DataOStream ostrm;
00482 //     ci.writeObject(ostrm);
00483 //     String instanceKey = makeInstanceKey(ns, cop, theClass);
00484 //     HDBNode node = hdl->getNode(instanceKey);
00485 //     if (!node)
00486 //     {
00487 //         OW_THROWCIMMSG(CIMException::NOT_FOUND, cop.toString().c_str());
00488 //     }
00489 //     hdl.getHandle().updateNode(node, ostrm.length(), ostrm.getData());
00490 }
00491 #endif
00492 #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00493 
00494 void InstanceRepository2::_removeDuplicatedQualifiers(CIMInstance& inst,
00495    const CIMClass& theClass)
00496 {
00497    CIMQualifierArray quals(inst.getQualifiers());
00498    CIMQualifierArray newQuals;
00499    for (size_t i = 0; i < quals.size(); ++i)
00500    {
00501       CIMQualifier& iq = quals[i];
00502       CIMQualifier cq = theClass.getQualifier(iq.getName());
00503       if (!cq)
00504       {
00505          newQuals.push_back(iq);
00506          continue;
00507       }
00508       if (iq.getValue() != cq.getValue())
00509       {
00510          newQuals.push_back(iq);
00511          continue;
00512       }
00513    }
00514    inst.setQualifiers(newQuals);
00515    CIMPropertyArray props = inst.getProperties();
00516    for (size_t i = 0; i < props.size(); ++i)
00517    {
00518       CIMProperty& p = props[i];
00519       CIMProperty clsp = theClass.getProperty(p.getName());
00520       CIMQualifierArray quals(p.getQualifiers());
00521       CIMQualifierArray newQuals;
00522       for (size_t j = 0; j < quals.size(); ++j)
00523       {
00524          CIMQualifier& ipq = quals[j];
00525          CIMQualifier cpq = clsp.getQualifier(ipq.getName());
00526          if (!cpq)
00527          {
00528             newQuals.push_back(ipq);
00529             continue;
00530          }
00531          if (ipq.getValue() != cpq.getValue())
00532          {
00533             newQuals.push_back(ipq);
00534             continue;
00535          }
00536       }
00537       p.setQualifiers(newQuals);
00538    }
00539    inst.setProperties(props);
00540 }
00541 #endif // #ifndef OW_DISABLE_INSTANCE_MANIPULATION
00542 
00543 } // end namespace OW_NAMESPACE
00544 

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