OW_AssocDb2.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_AssocDb2.hpp"
00032 #include "OW_DataStreams.hpp"
00033 #include "OW_IOException.hpp"
00034 #include "OW_Format.hpp"
00035 #include "OW_AutoPtr.hpp"
00036 #include "OW_CIMObjectPath.hpp"
00037 #include "OW_CIMInstance.hpp"
00038 #include "OW_CIMProperty.hpp"
00039 #include "OW_CIMValue.hpp"
00040 #include "OW_CIMClass.hpp"
00041 #include "OW_BinarySerialization.hpp"
00042 #include "OW_Assertion.hpp"
00043 #include "OW_Logger.hpp"
00044 
00045 #include <cstdio> // for SEEK_END
00046 #include <db.h>
00047 
00048 namespace OW_NAMESPACE
00049 {
00050 
00051 using std::istream;
00052 using std::ostream;
00053 using std::endl;
00055 AssocDbEntry2::AssocDbEntry2(istream& istrm)
00056    : m_objectName(CIMNULL)
00057    , m_offset(-1L)
00058 {
00059    readObject(istrm);
00060 }
00062 AssocDbEntry2::AssocDbEntry2(const CIMObjectPath& objectName,
00063       const String& role,
00064       const String& resultRole) :
00065    m_objectName(objectName), m_role(role), m_resultRole(resultRole),
00066    m_offset(-1L)
00067 {
00068 }
00070 void
00071 AssocDbEntry2::writeObject(ostream& ostrm) const
00072 {
00073    m_objectName.writeObject(ostrm);
00074    m_role.writeObject(ostrm);
00075    m_resultRole.writeObject(ostrm);
00076    BinarySerialization::writeArray(ostrm, m_entries);
00077 }
00079 void
00080 AssocDbEntry2::entry::writeObject(ostream& ostrm) const
00081 {
00082    m_assocClass.writeObject(ostrm);
00083    m_resultClass.writeObject(ostrm);
00084    m_associatedObject.writeObject(ostrm);
00085    m_associationPath.writeObject(ostrm);
00086 }
00088 void
00089 AssocDbEntry2::readObject(istream& istrm)
00090 {
00091    m_objectName.readObject(istrm);
00092    m_role.readObject(istrm);
00093    m_resultRole.readObject(istrm);
00094    BinarySerialization::readArray(istrm, m_entries);
00095 }
00097 void
00098 AssocDbEntry2::entry::readObject(istream& istrm)
00099 {
00100    m_assocClass.readObject(istrm);
00101    m_resultClass.readObject(istrm);
00102    m_associatedObject.readObject(istrm);
00103    m_associationPath.readObject(istrm);
00104 }
00106 String
00107 AssocDbEntry2::makeKey(const CIMObjectPath& objectName, const String& role,
00108    const String& resultRole)
00109 {
00110    // use # as the separator, because that's not a valid character in an
00111    // object path or any CIM identifier
00112    String lowerName = objectName.toString();
00113    lowerName.toLowerCase();
00114    String lowerRole = role;
00115    lowerRole.toLowerCase();
00116    String lowerResultRole = resultRole;
00117    lowerResultRole.toLowerCase();
00118    return lowerName + "#" + lowerRole + "#" + lowerResultRole;
00119 }
00121 String
00122 AssocDbEntry2::makeKey() const
00123 {
00124    // use # as the separator, because that's not a valid character in an
00125    // object path or any CIM identifier
00126    return makeKey(m_objectName, m_role, m_resultRole);
00127 }
00129 ostream&
00130 operator << (ostream& ostrm, const AssocDbEntry2& arg)
00131 {
00132    ostrm
00133       << "\tobjectName: " << arg.m_objectName.toString() << endl
00134       << "\trole: " << arg.m_role << endl
00135       << "\tresultRole: " << arg.m_resultRole << endl
00136       << "\tkey: " << arg.makeKey() << endl;
00137    return ostrm;
00138 }
00140 bool
00141 AssocDb2::hasAssocEntries(const String& ns, const CIMObjectPath& instanceName)
00142 {
00143    CIMObjectPath pathWithNS(instanceName);
00144    pathWithNS.setNameSpace(ns);
00145    String targetObject = pathWithNS.toString();
00146    return (findEntry(targetObject)) ? true : false;
00147 }
00149 void
00150 AssocDb2::addEntries(const String& ns, const CIMInstance& assocInstance)
00151 {
00152    addOrDeleteEntries(ns, assocInstance, true);
00153 }
00155 void
00156 AssocDb2::deleteEntries(const String& ns, const CIMInstance& assocInstance)
00157 {
00158    addOrDeleteEntries(ns, assocInstance, false);
00159 }
00161 void
00162 AssocDb2::addOrDeleteEntries(const String& ns, const CIMInstance& assocInstance, bool add)
00163 {
00164    String assocClass = assocInstance.getClassName();
00165    CIMObjectPath assocPath(assocClass, ns);
00166    assocPath.setKeys(assocInstance);
00167    // search for references
00168    CIMPropertyArray propRa = assocInstance.getProperties();
00169    for (size_t i = 0; i < propRa.size(); i++)
00170    {
00171       CIMValue propValue1 = propRa[i].getValue();
00172       if (propValue1 && propValue1.getType() == CIMDataType::REFERENCE)
00173       {
00174          // found first reference, search for second
00175          for (size_t j = 0; j < propRa.size(); ++j)
00176          {
00177             if (j == i)
00178             {
00179                continue; // don't bother with same ones.
00180             }
00181             CIMValue propValue2 = propRa[j].getValue();
00182             if (propValue2 && propValue2.getType() == CIMDataType::REFERENCE)
00183             {
00184                // found a second reference, now set up the vars we need
00185                // and create index entries.
00186                CIMObjectPath objectName(CIMNULL);
00187                propValue1.get(objectName);
00188                if (objectName.getNameSpace().empty())
00189                {
00190                   objectName.setNameSpace(ns);
00191                }
00192                CIMObjectPath associatedObject(CIMNULL);
00193                propValue2.get(associatedObject);
00194                if (associatedObject.getNameSpace().empty())
00195                {
00196                   objectName.setNameSpace(ns);
00197                }
00198                CIMName resultClass = associatedObject.getClassName();
00199                CIMName role = propRa[i].getName();
00200                CIMName resultRole = propRa[j].getName();
00201                if (add)
00202                {
00203                   addEntry(objectName, assocClass, resultClass,
00204                      role, resultRole, associatedObject, assocPath);
00205                   addEntry(objectName, assocClass, resultClass,
00206                      String(), resultRole, associatedObject, assocPath);
00207                   addEntry(objectName, assocClass, resultClass,
00208                      role, String(), associatedObject, assocPath);
00209                   addEntry(objectName, assocClass, resultClass,
00210                      String(), String(), associatedObject, assocPath);
00211                }
00212                else
00213                {
00214                   deleteEntry(objectName, assocClass, resultClass,
00215                      role, resultRole, associatedObject, assocPath);
00216                   deleteEntry(objectName, assocClass, resultClass,
00217                      String(), resultRole, associatedObject, assocPath);
00218                   deleteEntry(objectName, assocClass, resultClass,
00219                      role, String(), associatedObject, assocPath);
00220                   deleteEntry(objectName, assocClass, resultClass,
00221                      String(), String(), associatedObject, assocPath);
00222                }
00223             }
00224          }
00225       }
00226    }
00227 }
00229 void
00230 AssocDb2::addEntries(const String& ns, const CIMClass& assocClass)
00231 {
00232    addOrDeleteEntries(ns, assocClass, true);
00233 }
00235 void
00236 AssocDb2::deleteEntries(const String& ns, const CIMClass& assocClass)
00237 {
00238    addOrDeleteEntries(ns, assocClass, false);
00239 }
00241 void
00242 AssocDb2::addOrDeleteEntries(const String& ns, const CIMClass& assocClass, bool add)
00243 {
00244    CIMName assocClassName = assocClass.getName();
00245    CIMObjectPath assocClassPath(assocClassName, ns);
00246    // search for references
00247    CIMPropertyArray propRa = assocClass.getAllProperties();
00248    for (size_t i = 0; i < propRa.size(); i++)
00249    {
00250       CIMProperty p1 = propRa[i];
00251       if (p1.getDataType().getType() == CIMDataType::REFERENCE)
00252       {
00253          // found first reference, search for others
00254          for (size_t j = 0; j < propRa.size(); ++j)
00255          {
00256             if (j == i)
00257             {
00258                continue; // don't bother with same ones.
00259             }
00260             CIMProperty p2 = propRa[j];
00261             if (p2.getDataType().getType() == CIMDataType::REFERENCE)
00262             {
00263                // found another reference, now set up the vars we need
00264                // and create index entries.
00265                CIMObjectPath objectName(p1.getDataType().getRefClassName(), ns);
00266                CIMName resultClass = p2.getDataType().getRefClassName();
00267                CIMName role = p1.getName();
00268                CIMName resultRole = p2.getName();
00269                CIMObjectPath associatedObject(resultClass, ns);
00270                if (add)
00271                {
00272                   addEntry(objectName, assocClassName, resultClass,
00273                      role, resultRole, associatedObject, assocClassPath);
00274                   addEntry(objectName, assocClassName, resultClass,
00275                      String(), resultRole, associatedObject, assocClassPath);
00276                   addEntry(objectName, assocClassName, resultClass,
00277                      role, String(), associatedObject, assocClassPath);
00278                   addEntry(objectName, assocClassName, resultClass,
00279                      String(), String(), associatedObject, assocClassPath);
00280                }
00281                else
00282                {
00283                   deleteEntry(objectName, assocClassName, resultClass,
00284                      role, resultRole, associatedObject, assocClassPath);
00285                   deleteEntry(objectName, assocClassName, resultClass,
00286                      String(), resultRole, associatedObject, assocClassPath);
00287                   deleteEntry(objectName, assocClassName, resultClass,
00288                      role, String(), associatedObject, assocClassPath);
00289                   deleteEntry(objectName, assocClassName, resultClass,
00290                      String(), String(), associatedObject, assocClassPath);
00291                }
00292             }
00293          }
00294       }
00295    }
00296 }
00298 void
00299 AssocDb2::getAllEntries(const CIMObjectPath& objectName,
00300       const SortedVectorSet<String>* passocClasses,
00301       const SortedVectorSet<String>* presultClasses,
00302       const String& role,
00303       const String& resultRole,
00304       AssocDbEntry2ResultHandlerIFC& result)
00305 {
00306    if ((passocClasses && passocClasses->size() == 0)
00307       || presultClasses && presultClasses->size() == 0)
00308    {
00309       return; // one of the filters will reject everything, so don't even bother
00310    }
00311    String key = AssocDbEntry2::makeKey(objectName, role, resultRole);
00312    AssocDbEntry2 dbentry = findEntry(key);
00313    if (dbentry)
00314    {
00315       for (size_t i = 0; i < dbentry.m_entries.size(); ++i)
00316       {
00317          AssocDbEntry2::entry& e = dbentry.m_entries[i];
00318          if (((passocClasses == 0) || (passocClasses->count(e.m_assocClass) > 0))
00319             && ((presultClasses == 0) || (presultClasses->count(e.m_resultClass) > 0)))
00320          {
00321             result.handle(e);
00322          }
00323       }
00324    }
00325 }
00327 AssocDb2::AssocDb2(ServiceEnvironmentIFCRef env)
00328    : m_env(env)
00329 {
00330 }
00332 AssocDb2::~AssocDb2()
00333 {
00334    try
00335    {
00336       close();
00337    }
00338    catch (...)
00339    {
00340       // logDebug or close could throw.
00341    }
00342 }
00344 void
00345 AssocDb2::open(const String& name, ::DB_ENV* env, ::DB_TXN* txn)
00346 {
00347    m_db.open(name.c_str(), env, txn);
00348 }
00350 void
00351 AssocDb2::close()
00352 {
00353    m_db.close();
00354 }
00356 // PRIVATE - AssocDb2 uses
00357 AssocDbEntry2
00358 AssocDb2::findEntry(const String& objectKey)
00359 {
00360    AssocDbEntry2 dbentry;
00361 //     IndexEntry ie = m_pIndex->findFirst(objectKey.c_str());
00362 //     if (ie && ie.key.equals(objectKey))
00363 //     {
00364 //         dbentry = readEntry(ie.offset, hdl);
00365 //     }
00366    return dbentry;
00367 }
00368 // PRIVATE - AssocDb2 uses
00369 void
00370 AssocDb2::deleteEntry(const CIMObjectPath& objectName,
00371    const String& assocClassName, const String& resultClass,
00372    const String& role, const String& resultRole,
00373    const CIMObjectPath& associatedObject,
00374    const CIMObjectPath& assocClassPath)
00375 {
00376 //     String key = AssocDbEntry2::makeKey(objectName, role, resultRole);
00377 //     AssocDbEntry2 dbentry;
00378 //     MutexLock l = getDbLock();
00379 //     IndexEntry ie = m_pIndex->findFirst(key.c_str());
00380 //     if (ie)
00381 //     {
00382 //         dbentry = readEntry(ie.offset, hdl);
00383 //
00384 //         OW_ASSERT(dbentry.makeKey().equals(key));
00385 //         AssocDbEntry2::entry e;
00386 //         e.m_assocClass = assocClassName;
00387 //         e.m_resultClass = resultClass;
00388 //         e.m_associatedObject = associatedObject;
00389 //         e.m_associationPath = assocClassPath;
00390 //         Array<AssocDbEntry2::entry>::iterator iter = find(dbentry.m_entries.begin(), dbentry.m_entries.end(), e);
00391 //         OW_ASSERT(iter != dbentry.m_entries.end());
00392 //         if (iter != dbentry.m_entries.end())
00393 //         {
00394 //             dbentry.m_entries.erase(iter);
00395 //         }
00396 //
00397 //         if (dbentry.m_entries.size() == 0)
00398 //         {
00399 //             m_pIndex->remove(key.c_str(), dbentry.getOffset());
00400 //             addToFreeList(dbentry.getOffset(), hdl);
00401 //         }
00402 //         else
00403 //         {
00404 //             deleteEntry(dbentry, hdl);
00405 //             addEntry(dbentry, hdl);
00406 //         }
00407 //     }
00408 //     else
00409 //     {
00410 //         // TODO: Log this OW_ASSERT(0 == "AssocDb2::deleteEntry failed to find key.  Database may be corrupt");
00411 //     }
00412 }
00414 // PRIVATE - AssocDb2 uses
00415 void
00416 AssocDb2::deleteEntry(const AssocDbEntry2& entry)
00417 {
00418 //     MutexLock l = getDbLock();
00419 //     String key = entry.makeKey();
00420 //     AssocDbEntry2 dbentry;
00421 //     IndexEntry ie = m_pIndex->findFirst(key.c_str());
00422 //     while (ie)
00423 //     {
00424 //         dbentry = readEntry(ie.offset, hdl);
00425 //         if (!dbentry.makeKey().equals(key))
00426 //         {
00427 //             break;
00428 //         }
00429 //         if (dbentry == entry)
00430 //         {
00431 //             m_pIndex->remove(key.c_str(), dbentry.getOffset());
00432 //             addToFreeList(dbentry.getOffset(), hdl);
00433 //             break;
00434 //         }
00435 //         ie = m_pIndex->findNext();
00436 //     }
00437 }
00439 // PRIVATE - AssocDb2 uses
00440 void
00441 AssocDb2::addEntry(const AssocDbEntry2& nentry)
00442 {
00443 //     MutexLock l = getDbLock();
00444 //     DataOStream ostrm;
00445 //     nentry.writeObject(ostrm);
00446 //     UInt32 blkSize = ostrm.length() + sizeof(AssocDbRecHeader2);
00447 //     Int32 offset;
00448 //     AssocDbRecHeader2 rh = getNewBlock(offset, blkSize, hdl);
00449 //     rh.dataSize = ostrm.length();
00450 //     writeRecHeader(rh, offset, hdl.getFile());
00451 //
00452 //     if (hdl.getFile().write(ostrm.getData(), ostrm.length()) !=
00453 //         size_t(ostrm.length()))
00454 //     {
00455 //         OW_THROW(IOException, "Failed to write data assoc db");
00456 //     }
00457 //
00458 //     if (!m_pIndex->add(nentry.makeKey().c_str(), offset))
00459 //     {
00460 //         OW_LOG_ERROR(m_env->getLogger(COMPONENT_NAME), format("AssocDb2::addEntry failed to add entry to"
00461 //             " association index: ", nentry.makeKey()));
00462 //         OW_THROW(IOException, "Failed to add entry to association index");
00463 //     }
00464 }
00466 // PRIVATE - AssocDb2 uses
00467 void
00468 AssocDb2::addEntry(const CIMObjectPath& objectName,
00469       const String& assocClassName, const String& resultClass,
00470       const String& role, const String& resultRole,
00471       const CIMObjectPath& associatedObject,
00472       const CIMObjectPath& assocClassPath)
00473 {
00474    String key = AssocDbEntry2::makeKey(objectName, role, resultRole);
00475    AssocDbEntry2 dbentry = findEntry(key);
00476    if (dbentry)
00477    {
00478       deleteEntry(dbentry);
00479    }
00480    else
00481    {
00482       dbentry = AssocDbEntry2(objectName, role, resultRole);
00483    }
00484    AssocDbEntry2::entry e;
00485    e.m_assocClass = assocClassName;
00486    e.m_resultClass = resultClass;
00487    e.m_associatedObject = associatedObject;
00488    e.m_associationPath = assocClassPath;
00489    dbentry.m_entries.push_back(e);
00490    addEntry(dbentry);
00491 }
00493 bool operator==(const AssocDbEntry2::entry& lhs, const AssocDbEntry2::entry& rhs)
00494 {
00495    return lhs.m_assocClass.equalsIgnoreCase(rhs.m_assocClass) &&
00496       lhs.m_resultClass.equalsIgnoreCase(rhs.m_resultClass) &&
00497       lhs.m_associatedObject.equals(rhs.m_associatedObject) &&
00498       lhs.m_associationPath.equals(rhs.m_associationPath);
00499 }
00500 
00501 } // end namespace OW_NAMESPACE
00502 

Generated on Thu Feb 9 08:47:52 2006 for openwbem by  doxygen 1.4.6