OW_CIMObjectPath.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_CIMObjectPath.hpp"
00038 #include "OW_AutoPtr.hpp"
00039 #include "OW_Format.hpp"
00040 #include "OW_CIMNameSpace.hpp"
00041 #include "OW_CIMProperty.hpp"
00042 #include "OW_CIMValue.hpp"
00043 #include "OW_CIMDataType.hpp"
00044 #include "OW_CIMInstance.hpp"
00045 #include "OW_CIMUrl.hpp"
00046 #include "OW_Array.hpp"
00047 #include "OW_CIMException.hpp"
00048 #include "OW_BinarySerialization.hpp"
00049 #include "OW_NoSuchPropertyException.hpp"
00050 #include "OW_StrictWeakOrdering.hpp"
00051 #include "OW_Assertion.hpp"
00052 #include "OW_CIMValueCast.hpp"
00053 #include "OW_COWIntrusiveCountableBase.hpp"
00054 
00055 #include <cstring>
00056 #include <cctype>
00057 
00058 namespace OW_NAMESPACE
00059 {
00060 
00061 using std::istream;
00062 using std::ostream;
00064 struct CIMObjectPath::OPData : public COWIntrusiveCountableBase
00065 {
00066    CIMNameSpace m_nameSpace;
00067    CIMName m_objectName;
00068    CIMPropertyArray m_keys;
00069    OPData* clone() const { return new OPData(*this); }
00070 };
00071 bool operator<(const CIMObjectPath::OPData& x, const CIMObjectPath::OPData& y)
00072 {
00073    return StrictWeakOrdering(
00074       x.m_nameSpace, y.m_nameSpace,
00075       x.m_objectName, y.m_objectName,
00076       x.m_keys, y.m_keys);
00077 }
00079 CIMObjectPath::CIMObjectPath() :
00080    CIMBase(), m_pdata(new OPData)
00081 {
00082 }
00084 CIMObjectPath::CIMObjectPath(CIMNULL_t) :
00085    CIMBase(), m_pdata(0)
00086 {
00087 }
00089 CIMObjectPath::CIMObjectPath(const char* oname) :
00090    CIMBase(), m_pdata(new OPData)
00091 {
00092    m_pdata->m_objectName = oname;
00093 }
00095 CIMObjectPath::CIMObjectPath(const CIMName& oname) :
00096    CIMBase(), m_pdata(new OPData)
00097 {
00098    m_pdata->m_objectName = oname;
00099 }
00101 CIMObjectPath::CIMObjectPath(const CIMName& oname,
00102    const String& nspace) :
00103    CIMBase(), m_pdata(new OPData)
00104 {
00105    m_pdata->m_objectName = oname;
00106    m_pdata->m_nameSpace.setNameSpace(nspace);
00107 }
00109 CIMObjectPath::CIMObjectPath(const CIMName& className,
00110    const CIMPropertyArray& keys) :
00111    CIMBase(), m_pdata(new OPData)
00112 {
00113    // If there is a namespace but it will be set via CIMClient on
00114    // the next call
00115    m_pdata->m_objectName = className;
00116    setKeys(keys);
00117 }
00119 CIMObjectPath::CIMObjectPath(const String& ns,
00120    const CIMInstance& inst) :
00121    CIMBase(), m_pdata(new OPData)
00122 {
00123    m_pdata->m_nameSpace.setNameSpace(ns);
00124    m_pdata->m_objectName = inst.getClassName();
00125    setKeys(inst.getKeyValuePairs());
00126 }
00128 CIMObjectPath::CIMObjectPath(const CIMObjectPath& arg) :
00129    CIMBase(), m_pdata(arg.m_pdata)
00130 {
00131 }
00133 CIMObjectPath::~CIMObjectPath()
00134 {
00135 }
00137 void
00138 CIMObjectPath::setNull()
00139 {
00140    m_pdata = NULL;
00141 }
00143 CIMObjectPath&
00144 CIMObjectPath::operator= (const CIMObjectPath& x)
00145 {
00146    m_pdata = x.m_pdata;
00147    return *this;
00148 }
00150 CIMObjectPath&
00151 CIMObjectPath::addKey(const CIMName& keyname, const CIMValue& value)
00152 {
00153     if (value)
00154     {
00155         CIMProperty cp(keyname, value);
00156         cp.setDataType(value.getCIMDataType());
00157         m_pdata->m_keys.append(cp);
00158     }
00159     return *this;
00160 }
00162 CIMObjectPath&
00163 CIMObjectPath::addKey(const CIMProperty& key)
00164 {
00165     OW_ASSERT(key);
00166     OW_ASSERT(key.getValue());
00167    CIMProperty key2(key);
00168    key2.clearQualifiers();
00169     m_pdata->m_keys.append(key2);
00170     return *this;
00171 }
00173 CIMPropertyArray
00174 CIMObjectPath::getKeys() const
00175 {
00176    return m_pdata->m_keys;
00177 }
00179 CIMProperty
00180 CIMObjectPath::getKey(const CIMName& keyName) const
00181 {
00182    for (size_t i = 0; i < m_pdata->m_keys.size(); ++i)
00183    {
00184       if (m_pdata->m_keys[i].getName() == keyName)
00185       {
00186          return m_pdata->m_keys[i];
00187       }
00188    }
00189    return CIMProperty(CIMNULL);
00190 }
00192 CIMProperty
00193 CIMObjectPath::getKeyT(const CIMName& keyName) const
00194 {
00195    CIMProperty p = getKey(keyName);
00196    if (!p)
00197    {
00198       OW_THROW(NoSuchPropertyException, keyName.toString().c_str());
00199    }
00200    return p;
00201 }
00203 CIMValue
00204 CIMObjectPath::getKeyValue(const CIMName& name) const
00205 {
00206    CIMProperty p = this->getKey(name);
00207    if (p)
00208    {
00209       return p.getValue();
00210    }
00211    return CIMValue(CIMNULL);
00212 }
00214 bool
00215 CIMObjectPath::keyHasValue(const CIMName& name) const
00216 {
00217    CIMProperty p = this->getKey(name);
00218    if (p)
00219    {
00220       CIMValue v = p.getValue();
00221       if (v)
00222       {
00223          return true;
00224       }
00225       else
00226       {
00227          return false;
00228       }
00229    }
00230    return false;
00231 }
00233 CIMObjectPath&
00234 CIMObjectPath::setKeys(const CIMPropertyArray& newKeys)
00235 {
00236    m_pdata->m_keys = newKeys;
00237    for (size_t i = 0; i < m_pdata->m_keys.size(); ++i)
00238    {
00239       m_pdata->m_keys[i].clearQualifiers();
00240    }
00241    return *this;
00242 }
00244 CIMObjectPath&
00245 CIMObjectPath::setKeys(const CIMInstance& instance)
00246 {
00247    OW_ASSERT(instance);
00248    setKeys(instance.getKeyValuePairs());
00249    return *this;
00250 }
00252 CIMObjectPath& 
00253 CIMObjectPath::setKeyValue(const CIMName& name, const CIMValue& value)
00254 {
00255    OW_ASSERT(value);
00256    for (size_t i = 0; i < m_pdata->m_keys.size(); ++i)
00257    {
00258       if (m_pdata->m_keys[i].getName() == name)
00259       {
00260          m_pdata->m_keys[i].setValue(value);
00261          return *this;
00262       }
00263    }
00264    // didn't find it
00265     m_pdata->m_keys.append(CIMProperty(name, value));
00266    return *this;
00267 }
00269 String
00270 CIMObjectPath::getNameSpace() const
00271 {
00272    return m_pdata->m_nameSpace.getNameSpace();
00273 }
00275 String
00276 CIMObjectPath::getHost() const
00277 {
00278    return m_pdata->m_nameSpace.getHost();
00279 }
00281 String
00282 CIMObjectPath::getObjectName() const
00283 {
00284    return getClassName();
00285 }
00287 String
00288 CIMObjectPath::getClassName() const
00289 {
00290    return m_pdata->m_objectName.toString();
00291 }
00293 CIMObjectPath&
00294 CIMObjectPath::setHost(const String& host)
00295 {
00296    m_pdata->m_nameSpace.setHost(host);
00297    return *this;
00298 }
00300 CIMObjectPath&
00301 CIMObjectPath::setNameSpace(const String& ns)
00302 {
00303    m_pdata->m_nameSpace.setNameSpace(ns);
00304    return *this;
00305 }
00307 CIMObjectPath&
00308 CIMObjectPath::setObjectName(const CIMName& className)
00309 {
00310    return setClassName(className);
00311 }
00313 CIMObjectPath&
00314 CIMObjectPath::setClassName(const CIMName& className)
00315 {
00316    m_pdata->m_objectName = className;
00317    return *this;
00318 }
00320 bool
00321 CIMObjectPath::equals(const CIMObjectPath& cop) const
00322 {
00323    if (!m_pdata && !cop.m_pdata)
00324    {
00325       return true;
00326    }
00327    if (!m_pdata->m_nameSpace.getNameSpace().equalsIgnoreCase(
00328       cop.m_pdata->m_nameSpace.getNameSpace()))
00329    {
00330       return false;
00331    }
00332    if (m_pdata->m_objectName != cop.m_pdata->m_objectName)
00333    {
00334       return false;
00335    }
00336    //
00337    // An instance path
00338    //
00339    if (m_pdata->m_keys.size() != cop.m_pdata->m_keys.size())
00340    {
00341       return false;
00342    }
00343    int maxNoKeys = m_pdata->m_keys.size();
00344    for (int i = 0; i < maxNoKeys; i++)
00345    {
00346       CIMProperty cp1 = m_pdata->m_keys[i];
00347       bool found = false;
00348       for (int j = 0; j < maxNoKeys; j++)
00349       {
00350          CIMProperty cp2 = cop.m_pdata->m_keys[j];
00351          if (cp1.getName().equalsIgnoreCase(cp2.getName()))
00352          {
00353             if (cp1.getValue().equal(cp2.getValue()))
00354             {
00355                found = true;
00356                break;
00357             }
00358          }
00359       }
00360       if (!found)
00361       {
00362          return false;
00363       }
00364    }
00365    return true;
00366 }
00368 CIMNameSpace
00369 CIMObjectPath::getFullNameSpace() const
00370 {
00371    return m_pdata->m_nameSpace;
00372 }
00374 String
00375 CIMObjectPath::modelPath() const
00376 {
00377    StringBuffer rv(m_pdata->m_objectName.toString());
00378    if (m_pdata->m_keys.size() > 0)
00379    {
00380       for (size_t i = 0; i < m_pdata->m_keys.size(); i++)
00381       {
00382          CIMProperty cp = m_pdata->m_keys[i];
00383          if (i > 0)
00384          {
00385             rv += ',';
00386          }
00387          else
00388          {
00389             rv += '.';
00390          }
00391          rv += cp.getName();
00392          rv += "=\"";
00393          rv += (cp.getValue()
00394                ? escape(cp.getValue().toString())
00395                : String("null")) + "\"";
00396       }
00397    }
00398    return rv.releaseString();
00399 }
00401 String
00402 CIMObjectPath::toString() const
00403 {
00404    StringBuffer rv;
00405    CIMUrl url = getNameSpaceUrl();
00406    if (!url.isLocal())
00407    {
00408       rv += m_pdata->m_nameSpace.getProtocol();
00409       if (rv.length() == 0)
00410       {
00411          rv += "HTTP";
00412       }
00413       rv += "://";
00414       String str = m_pdata->m_nameSpace.getHost();
00415       if (str.empty())
00416       {
00417          str = "localhost";
00418       }
00419       rv += str;
00420       if (m_pdata->m_nameSpace.getPortNumber() != 5988)
00421       {
00422          rv += ":";
00423          rv += m_pdata->m_nameSpace.getPortNumber();
00424       }
00425    }
00426    rv += '/';
00427    String strns = m_pdata->m_nameSpace.getNameSpace();
00428 // if (strns.empty())
00429 // {
00430 //    strns = "root";
00431 // }
00432    rv += strns;
00433    rv += ':';
00434    rv += modelPath();
00435    return rv.releaseString();
00436 }
00438 String
00439 CIMObjectPath::toMOF() const
00440 {
00441    StringBuffer rv; 
00442    rv = "\""; 
00443    rv += escape(toString()); 
00444    rv += "\""; 
00445    return rv.releaseString(); 
00446 }
00448 void
00449 CIMObjectPath::readObject(istream& istrm)
00450 {
00451    CIMNameSpace nameSpace(CIMNULL);
00452    CIMName objectName;
00453    CIMPropertyArray keys;
00454    CIMBase::readSig( istrm, OW_CIMOBJECTPATHSIG );
00455    nameSpace.readObject(istrm);
00456    objectName.readObject(istrm);
00457    BinarySerialization::readArray(istrm, keys);
00458    if (!m_pdata)
00459    {
00460       m_pdata = new OPData;
00461    }
00462    m_pdata->m_nameSpace = nameSpace;
00463    m_pdata->m_objectName = objectName;
00464    m_pdata->m_keys = keys;
00465 }
00467 void
00468 CIMObjectPath::writeObject(ostream& ostrm) const
00469 {
00470    CIMBase::writeSig( ostrm, OW_CIMOBJECTPATHSIG );
00471    m_pdata->m_nameSpace.writeObject(ostrm);
00472    m_pdata->m_objectName.writeObject(ostrm);
00473    BinarySerialization::writeArray(ostrm, m_pdata->m_keys);
00474 }
00476 CIMObjectPath
00477 CIMObjectPath::parse(const String& instanceNameArg)
00478 {
00479    String instanceName(instanceNameArg);
00480    instanceName.trim();
00481    if (instanceName.empty())
00482    {
00483       return CIMObjectPath(CIMNULL);
00484    }
00485    String protocol = "HTTP";
00486    String host = "localhost";
00487    Int32 port = 5988;
00488    size_t ndx = instanceName.indexOf("://");
00489    if (ndx != String::npos)
00490    {
00491       protocol = instanceName.substring(0, ndx);
00492       instanceName.erase(0, ndx+3);
00493       ndx = instanceName.indexOf('/');
00494       if (ndx == String::npos)
00495       {
00496          OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00497             Format("Invalid instance name: %1", instanceNameArg).c_str());
00498       }
00499       host = instanceName.substring(0, ndx);
00500       instanceName.erase(0, ndx+1);
00501       ndx = host.indexOf(':');
00502       if (ndx != String::npos)
00503       {
00504          try
00505          {
00506             port = host.substring(ndx+1).toInt32();
00507          }
00508          catch (const StringConversionException&)
00509          {
00510             OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00511                "Invalid port in Object Path");
00512          }
00513          host = host.substring(0, ndx);
00514       }
00515    }
00516    else
00517    {
00518       if (instanceName.charAt(0) == '/')
00519       {
00520          instanceName.erase(0, 1);
00521       }
00522    }
00523    String nameSpace = "root";
00524    ndx = instanceName.indexOf(':');
00525    if (ndx != String::npos)
00526    {
00527       nameSpace = instanceName.substring(0, ndx);
00528       instanceName.erase(0, ndx+1);
00529    }
00530    CIMName className;
00531    ndx = instanceName.indexOf('.');
00532    if (ndx == String::npos)
00533    {
00534       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00535          Format("class name not found in instance name: %1",
00536             instanceNameArg).c_str());
00537    }
00538    className = instanceName.substring(0, ndx);
00539    instanceName.erase(0, ndx+1);
00540    CIMUrl url(protocol, host, String(), port);
00541    CIMNameSpace ns(url, nameSpace);
00542    CIMObjectPath op(className);
00543    op.m_pdata->m_nameSpace = ns;
00544    //op.m_pdata->m_objectName = className;
00545    int valuesLen = instanceName.length();
00546    if (valuesLen == 0)
00547    {
00548       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00549          Format("No key values found in instance name: %1",
00550             instanceNameArg).c_str());
00551    }
00552    // set singleKey to TRUE if it is intended that a property value can be
00553    // specified without its name when there is only one key.
00554    bool singleKey = false;
00555    const char* values = instanceName.c_str();
00556    String keyvalue;
00557    bool inquote = false;
00558    int equalspos = 0;
00559    CIMPropertyArray tmpkeys;
00560    
00561    //
00562    // Now extract keys
00563    //
00564    int i = 0;
00565    int keystart = 0;
00566    while (i < valuesLen)
00567    {
00568       char ch = values[i];
00569       // Skip escaped characters
00570       if (i < valuesLen-1 && ch == '\\')
00571       {
00572          i += 2;
00573          continue;
00574       }
00575       // Check for quotes
00576       if (ch == '\"')
00577       {
00578          inquote = !inquote;
00579       }
00580       if (inquote)
00581       {
00582          ++i;
00583          continue;
00584       }
00585       if (ch == '=')
00586       {
00587          equalspos = i+1;
00588       }
00589       if (ch == ',' || (i+1 == valuesLen))
00590       {
00591          if ((i+1 == valuesLen) && equalspos == 0 && singleKey)
00592          {
00593             // This is the special case of when its classname.value
00594             CIMProperty cp("test it");
00595             //
00596             // Generally there will be quotes but for integer values
00597             // they are not strictly necessary so check for them
00598             //
00599             if (values[keystart] != '\"')
00600             {
00601                keyvalue = unEscape(String(&values[keystart],
00602                   i-keystart+1));
00603             }
00604             else
00605             {
00606                keyvalue = unEscape(String(&values[keystart+1],
00607                   i-keystart+1-2));
00608             }
00609             cp.setValue(CIMValue(keyvalue));
00610             cp.setDataType(CIMDataType::STRING);
00611             tmpkeys.append(cp);
00612             break;
00613          }
00614          if (i+1 == valuesLen)
00615          {
00616             i++;
00617          }
00618          if (equalspos == 0)
00619          {
00620             OW_THROWCIMMSG(CIMException::NOT_FOUND,
00621                Format("Bad key in string (%1)", instanceName).c_str());
00622          }
00623          CIMName keyprop = String(&values[keystart], equalspos-keystart-1);
00624          //
00625          // Generally there will be quotes but for integer values
00626          // they are not strictly necessary so check for them
00627          //
00628          if (values[equalspos] != '\"')
00629          {
00630             keyvalue = unEscape(String(&values[equalspos], i-equalspos));
00631          }
00632          else
00633          {
00634             keyvalue = unEscape(String(&values[equalspos+1],
00635                i-equalspos-2));
00636          }
00637          i++;
00638          equalspos = 0;
00639          keystart = i;
00640          CIMProperty cp(keyprop);
00641          cp.setValue(CIMValue(keyvalue));
00642          cp.setDataType(CIMDataType::STRING);
00643          tmpkeys.append(cp);
00644          singleKey = false;
00645       }
00646       ++i;
00647    }
00648    //
00649    // Now assign the values to this instance
00650    //
00651    op.setKeys(tmpkeys);
00652    return op;
00653 }
00655 CIMUrl
00656 CIMObjectPath::getNameSpaceUrl() const
00657 {
00658    return m_pdata->m_nameSpace.getHostUrl();
00659 }
00661 // STATIC
00662 String
00663 CIMObjectPath::escape(const String& inString)
00664 {
00665    int valuesLen = static_cast<int>(inString.length());
00666    if (valuesLen == 0)
00667    {
00668       return inString;
00669    }
00670    StringBuffer rv(valuesLen);
00671    const char* values = inString.c_str();
00672    for (int i = 0; i < valuesLen; i++)
00673    {
00674       char ch = values[i];
00675       if (ch == '\\')
00676       {
00677          rv += '\\';
00678          rv += ch;
00679       }
00680       else if (ch == '"')
00681       {
00682          rv += '\\';
00683          rv += '"';
00684       }
00685       else if (ch == '\n')
00686       {
00687          rv += "\\n";
00688       }
00689       else
00690       {
00691          rv += ch;
00692       }
00693    }
00694    return rv.releaseString();
00695 }
00697 // STATIC
00698 String
00699 CIMObjectPath::unEscape(const String& inString)
00700 {
00701    int valuesLen = static_cast<int>(inString.length());
00702    if (valuesLen == 0)
00703    {
00704       return inString;
00705    }
00706    StringBuffer rv(valuesLen);
00707    const char* values = inString.c_str();
00708    int i = 0;
00709    while (i < valuesLen)
00710    {
00711       char ch = values[i];
00712       if (ch == '\\')
00713       {
00714          if (i+1 < valuesLen)
00715          {
00716             ++i;
00717             rv += values[i];
00718          }
00719       }
00720       else
00721       {
00722          rv += values[i];
00723       }
00724       ++i;
00725    }
00726    return rv.releaseString();
00727 }
00729 bool operator<(const CIMObjectPath& lhs, const CIMObjectPath& rhs)
00730 {
00731    return *lhs.m_pdata < *rhs.m_pdata;
00732 }
00734 bool CIMObjectPath::isClassPath() const
00735 {
00736    return getKeys().size() == 0;
00737 }
00739 bool CIMObjectPath::isInstancePath() const
00740 {
00741    return getKeys().size() != 0;
00742 }
00744 CIMObjectPath&
00745 CIMObjectPath::syncWithClass(const CIMClass& theClass)
00746 {
00747    if (!theClass || isClassPath())
00748    {
00749       return *this;
00750    }
00751    CIMName propName;
00752    CIMPropertyArray classProps = theClass.getKeys();
00753    CIMPropertyArray copProps = getKeys();
00754    // Remove properties that are not defined in the class
00755    size_t i = 0;
00756    while (i < copProps.size())
00757    {
00758       propName = copProps[i].getName();
00759       if (!theClass.getProperty(propName))
00760       {
00761          copProps.remove(i);
00762       }
00763       else
00764       {
00765          ++i;
00766       }
00767    }
00768    // Ensure existing properties have the right type
00769    for (size_t i = 0; i < classProps.size(); i++)
00770    {
00771       bool found = false;
00772       const CIMProperty& cprop = classProps[i];
00773       propName = cprop.getName();
00774       for (size_t j = 0; j < copProps.size(); j++)
00775       {
00776          CIMProperty iprop = copProps[j];
00777          if (iprop.getName() == propName)
00778          {
00779             CIMValue cv = iprop.getValue();
00780             iprop = cprop;
00781             if (cv)
00782             {
00783                if (cv.getType() != iprop.getDataType().getType())
00784                {
00785                   cv = CIMValueCast::castValueToDataType(cv,
00786                      iprop.getDataType());
00787                }
00788                iprop.setValue(cv);
00789             }
00790             copProps[j] = iprop;
00791             found = true;
00792             break;
00793          }
00794       }
00795       if (!found)
00796       {
00797          copProps.append(classProps[i]);
00798       }
00799    }
00800    setKeys(copProps);
00801    return *this;
00802 }
00803 
00804 } // end namespace OW_NAMESPACE
00805 

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