OWBI1_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 "OWBI1_config.h"
00037 #include "OWBI1_CIMObjectPath.hpp"
00038 #include "OWBI1_CIMObjectPathRep.hpp"
00039 #include "OWBI1_CIMName.hpp"
00040 #include "OWBI1_CIMNameRep.hpp"
00041 #include "OWBI1_CIMDetail.hpp"
00042 #include "OW_Array.hpp"
00043 #include "OW_CIMProperty.hpp"
00044 #include "OWBI1_Array.hpp"
00045 #include "OWBI1_CIMProperty.hpp"
00046 #include "OWBI1_CIMPropertyRep.hpp"
00047 #include "OWBI1_CIMInstance.hpp"
00048 #include "OWBI1_CIMInstanceRep.hpp"
00049 #include "OWBI1_NoSuchPropertyException.hpp"
00050 #include "OWBI1_CIMValue.hpp"
00051 #include "OWBI1_CIMValueRep.hpp"
00052 #include "OW_Assertion.hpp"
00053 
00054 namespace OWBI1
00055 {
00056 
00057 using namespace detail;
00058 using std::istream;
00059 using std::ostream;
00061 CIMObjectPath::CIMObjectPath() 
00062    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath()))
00063 {
00064 }
00066 CIMObjectPath::CIMObjectPath(CIMNULL_t)
00067    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(OpenWBEM::CIMNULL)))
00068 {
00069 }
00071 CIMObjectPath::CIMObjectPath(const char* oname)
00072    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(oname)))
00073 {
00074 }
00076 CIMObjectPath::CIMObjectPath(const CIMName& oname)
00077    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(oname.getRep()->name)))
00078 {
00079 }
00081 CIMObjectPath::CIMObjectPath(const CIMName& oname, const String& nspace)
00082    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(oname.getRep()->name, nspace.c_str())))
00083 {
00084 }
00086 CIMObjectPath::CIMObjectPath(const CIMName& className, const CIMPropertyArray& keys)
00087    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(className.getRep()->name, unwrapArray<OpenWBEM::CIMPropertyArray>(keys))))
00088 {
00089 }
00091 CIMObjectPath::CIMObjectPath(const String& ns, const CIMInstance& inst)
00092    : m_rep(new CIMObjectPathRep(OpenWBEM::CIMObjectPath(ns.c_str(), inst.getRep()->inst)))
00093 {
00094 }
00096 CIMObjectPath::CIMObjectPath(const CIMObjectPath& arg) 
00097    : CIMBase(arg)
00098    , m_rep(arg.m_rep)
00099 {
00100 }
00102 CIMObjectPath::CIMObjectPath(const CIMObjectPathRepRef& rep)
00103    : m_rep(rep)
00104 {
00105 }
00106 
00108 CIMObjectPath::~CIMObjectPath()
00109 {
00110 }
00112 void
00113 CIMObjectPath::setNull()
00114 {
00115    m_rep->objectpath.setNull();
00116 }
00118 CIMObjectPath&
00119 CIMObjectPath::operator= (const CIMObjectPath& x)
00120 {
00121    m_rep = x.m_rep;
00122    return *this;
00123 }
00125 CIMPropertyArray
00126 CIMObjectPath::getKeys() const
00127 {
00128    return wrapArray<CIMPropertyArray>(m_rep->objectpath.getKeys());
00129 }
00131 CIMProperty
00132 CIMObjectPath::getKey(const CIMName& keyName) const
00133 {
00134    return CIMProperty(new CIMPropertyRep(m_rep->objectpath.getKey(keyName.getRep()->name)));
00135 }
00137 CIMProperty
00138 CIMObjectPath::getKeyT(const CIMName& keyName) const
00139 {
00140    CIMProperty p = getKey(keyName);
00141    if (!p)
00142    {
00143       OWBI1_THROW(NoSuchPropertyException, keyName.toString().c_str());
00144    }
00145    return p;
00146 }
00148 CIMValue
00149 CIMObjectPath::getKeyValue(const CIMName& name) const
00150 {
00151    return CIMValue(CIMValueRepRef(new CIMValueRep(m_rep->objectpath.getKeyValue(name.getRep()->name))));
00152 }
00154 bool
00155 CIMObjectPath::keyHasValue(const CIMName& name) const
00156 {
00157    return m_rep->objectpath.keyHasValue(name.getRep()->name);
00158 }
00160 CIMObjectPath&
00161 CIMObjectPath::setKeys(const CIMPropertyArray& newKeys)
00162 {
00163    m_rep->objectpath.setKeys(unwrapArray<OpenWBEM::CIMPropertyArray>(newKeys));
00164    return *this;
00165 }
00167 CIMObjectPath&
00168 CIMObjectPath::setKeys(const CIMInstance& instance)
00169 {
00170    OW_ASSERT(instance);
00171    setKeys(instance.getKeyValuePairs());
00172    return *this;
00173 }
00175 CIMObjectPath& 
00176 CIMObjectPath::setKeyValue(const CIMName& name, const CIMValue& value)
00177 {
00178    m_rep->objectpath.setKeyValue(name.getRep()->name, value.getRep()->value);
00179    return *this;
00180 }
00182 String
00183 CIMObjectPath::getNameSpace() const
00184 {
00185    return m_pdata->m_nameSpace.getNameSpace();
00186 }
00188 String
00189 CIMObjectPath::getHost() const
00190 {
00191    return m_pdata->m_nameSpace.getHost();
00192 }
00194 String
00195 CIMObjectPath::getClassName() const
00196 {
00197    return m_pdata->m_objectName.toString();
00198 }
00200 CIMObjectPath&
00201 CIMObjectPath::setHost(const String& host)
00202 {
00203    m_pdata->m_nameSpace.setHost(host);
00204    return *this;
00205 }
00207 CIMObjectPath&
00208 CIMObjectPath::setNameSpace(const String& ns)
00209 {
00210    m_pdata->m_nameSpace.setNameSpace(ns);
00211    return *this;
00212 }
00214 CIMObjectPath&
00215 CIMObjectPath::setClassName(const CIMName& className)
00216 {
00217    m_pdata->m_objectName = className;
00218    return *this;
00219 }
00221 bool
00222 CIMObjectPath::equals(const CIMObjectPath& cop) const
00223 {
00224    if (!m_pdata && !cop.m_pdata)
00225    {
00226       return true;
00227    }
00228    if (!m_pdata->m_nameSpace.getNameSpace().equalsIgnoreCase(
00229       cop.m_pdata->m_nameSpace.getNameSpace()))
00230    {
00231       return false;
00232    }
00233    if (m_pdata->m_objectName != cop.m_pdata->m_objectName)
00234    {
00235       return false;
00236    }
00237    //
00238    // An instance path
00239    //
00240    if (m_pdata->m_keys.size() != cop.m_pdata->m_keys.size())
00241    {
00242       return false;
00243    }
00244    int maxNoKeys = m_pdata->m_keys.size();
00245    for (int i = 0; i < maxNoKeys; i++)
00246    {
00247       CIMProperty cp1 = m_pdata->m_keys[i];
00248       bool found = false;
00249       for (int j = 0; j < maxNoKeys; j++)
00250       {
00251          CIMProperty cp2 = cop.m_pdata->m_keys[j];
00252          if (cp1.getName() == cp2.getName())
00253          {
00254             if (cp1.getValue().equal(cp2.getValue()))
00255             {
00256                found = true;
00257                break;
00258             }
00259          }
00260       }
00261       if (!found)
00262       {
00263          return false;
00264       }
00265    }
00266    return true;
00267 }
00269 CIMNameSpace
00270 CIMObjectPath::getFullNameSpace() const
00271 {
00272    return m_pdata->m_nameSpace;
00273 }
00275 String
00276 CIMObjectPath::modelPath() const
00277 {
00278    StringBuffer rv(m_pdata->m_objectName.toString());
00279    if (m_pdata->m_keys.size() > 0)
00280    {
00281       for (size_t i = 0; i < m_pdata->m_keys.size(); i++)
00282       {
00283          CIMProperty cp = m_pdata->m_keys[i];
00284          if (i > 0)
00285          {
00286             rv += ',';
00287          }
00288          else
00289          {
00290             rv += '.';
00291          }
00292          rv += cp.getName().toString();
00293          rv += "=\"";
00294          rv += (cp.getValue()
00295                ? escape(cp.getValue().toString())
00296                : String("null")) + "\"";
00297       }
00298    }
00299    return rv.releaseString();
00300 }
00302 String
00303 CIMObjectPath::toString() const
00304 {
00305    StringBuffer rv;
00306    CIMUrl url = getNameSpaceUrl();
00307    if (!url.isLocal())
00308    {
00309       rv += m_pdata->m_nameSpace.getProtocol();
00310       if (rv.length() == 0)
00311       {
00312          rv += "HTTP";
00313       }
00314       rv += "://";
00315       String str = m_pdata->m_nameSpace.getHost();
00316       if (str.empty())
00317       {
00318          str = "localhost";
00319       }
00320       rv += str;
00321       if (m_pdata->m_nameSpace.getPortNumber() != 5988)
00322       {
00323          rv += ":";
00324          rv += m_pdata->m_nameSpace.getPortNumber();
00325       }
00326    }
00327    rv += '/';
00328    String strns = m_pdata->m_nameSpace.getNameSpace();
00329 // if (strns.empty())
00330 // {
00331 //    strns = "root";
00332 // }
00333    rv += strns;
00334    rv += ':';
00335    rv += modelPath();
00336    return rv.releaseString();
00337 }
00339 String
00340 CIMObjectPath::toMOF() const
00341 {
00342    return escape(toString());
00343 }
00345 void
00346 CIMObjectPath::readObject(istream& istrm)
00347 {
00348    CIMNameSpace nameSpace(CIMNULL);
00349    CIMName objectName;
00350    CIMPropertyArray keys;
00351    CIMBase::readSig( istrm, OWBI1_CIMOBJECTPATHSIG );
00352    nameSpace.readObject(istrm);
00353    objectName.readObject(istrm);
00354    BinarySerialization::readArray(istrm, keys);
00355    if (!m_pdata)
00356    {
00357       m_pdata = new OPData;
00358    }
00359    m_pdata->m_nameSpace = nameSpace;
00360    m_pdata->m_objectName = objectName;
00361    m_pdata->m_keys = keys;
00362 }
00364 void
00365 CIMObjectPath::writeObject(ostream& ostrm) const
00366 {
00367    CIMBase::writeSig( ostrm, OWBI1_CIMOBJECTPATHSIG );
00368    m_pdata->m_nameSpace.writeObject(ostrm);
00369    m_pdata->m_objectName.writeObject(ostrm);
00370    BinarySerialization::writeArray(ostrm, m_pdata->m_keys);
00371 }
00373 CIMObjectPath
00374 CIMObjectPath::parse(const String& instanceNameArg)
00375 {
00376    String instanceName(instanceNameArg);
00377    instanceName.trim();
00378    if (instanceName.empty())
00379    {
00380       return CIMObjectPath(CIMNULL);
00381    }
00382    String protocol = "HTTP";
00383    String host = "localhost";
00384    Int32 port = 5988;
00385    size_t ndx = instanceName.indexOf("://");
00386    if (ndx != String::npos)
00387    {
00388       protocol = instanceName.substring(0, ndx);
00389       instanceName.erase(0, ndx+3);
00390       ndx = instanceName.indexOf('/');
00391       if (ndx == String::npos)
00392       {
00393          OWBI1_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00394             Format("Invalid instance name: %1", instanceNameArg).c_str());
00395       }
00396       host = instanceName.substring(0, ndx);
00397       instanceName.erase(0, ndx+1);
00398       ndx = host.indexOf(':');
00399       if (ndx != String::npos)
00400       {
00401          try
00402          {
00403             port = host.substring(ndx+1).toInt32();
00404          }
00405          catch (const StringConversionException&)
00406          {
00407             OWBI1_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00408                "Invalid port in Object Path");
00409          }
00410          host = host.substring(0, ndx);
00411       }
00412    }
00413    else
00414    {
00415       if (instanceName.charAt(0) == '/')
00416       {
00417          instanceName.erase(0, 1);
00418       }
00419    }
00420    String nameSpace = "root";
00421    ndx = instanceName.indexOf(':');
00422    if (ndx != String::npos)
00423    {
00424       nameSpace = instanceName.substring(0, ndx);
00425       instanceName.erase(0, ndx+1);
00426    }
00427    CIMName className;
00428    ndx = instanceName.indexOf('.');
00429    if (ndx == String::npos)
00430    {
00431       OWBI1_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00432          Format("class name not found in instance name: %1",
00433             instanceNameArg).c_str());
00434    }
00435    className = instanceName.substring(0, ndx);
00436    instanceName.erase(0, ndx+1);
00437    CIMUrl url(protocol, host, String(), port);
00438    CIMNameSpace ns(url, nameSpace);
00439    CIMObjectPath op(className);
00440    op.m_pdata->m_nameSpace = ns;
00441    //op.m_pdata->m_objectName = className;
00442    int valuesLen = instanceName.length();
00443    if (valuesLen == 0)
00444    {
00445       OWBI1_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00446          Format("No key values found in instance name: %1",
00447             instanceNameArg).c_str());
00448    }
00449    // set singleKey to TRUE if it is intended that a property value can be
00450    // specified without its name when there is only one key.
00451    bool singleKey = false;
00452    const char* values = instanceName.c_str();
00453    String keyvalue;
00454    bool inquote = false;
00455    int equalspos = 0;
00456    CIMPropertyArray tmpkeys;
00457    
00458    //
00459    // Now extract keys
00460    //
00461    int i = 0;
00462    int keystart = 0;
00463    while (i < valuesLen)
00464    {
00465       char ch = values[i];
00466       // Skip escaped characters
00467       if (i < valuesLen-1 && ch == '\\')
00468       {
00469          i += 2;
00470          continue;
00471       }
00472       // Check for quotes
00473       if (ch == '\"')
00474       {
00475          inquote = !inquote;
00476       }
00477       if (inquote)
00478       {
00479          ++i;
00480          continue;
00481       }
00482       if (ch == '=')
00483       {
00484          equalspos = i+1;
00485       }
00486       if (ch == ',' || (i+1 == valuesLen))
00487       {
00488          if ((i+1 == valuesLen) && equalspos == 0 && singleKey)
00489          {
00490             // This is the special case of when its classname.value
00491             CIMProperty cp("test it");
00492             //
00493             // Generally there will be quotes but for integer values
00494             // they are not strictly necessary so check for them
00495             //
00496             if (values[keystart] != '\"')
00497             {
00498                keyvalue = unEscape(String(&values[keystart],
00499                   i-keystart+1));
00500             }
00501             else
00502             {
00503                keyvalue = unEscape(String(&values[keystart+1],
00504                   i-keystart+1-2));
00505             }
00506             cp.setValue(CIMValue(keyvalue));
00507             cp.setDataType(CIMDataType::STRING);
00508             tmpkeys.append(cp);
00509             break;
00510          }
00511          if (i+1 == valuesLen)
00512          {
00513             i++;
00514          }
00515          if (equalspos == 0)
00516          {
00517             OWBI1_THROWCIMMSG(CIMException::NOT_FOUND,
00518                Format("Bad key in string (%1)", instanceName).c_str());
00519          }
00520          CIMName keyprop = String(&values[keystart], equalspos-keystart-1);
00521          //
00522          // Generally there will be quotes but for integer values
00523          // they are not strictly necessary so check for them
00524          //
00525          if (values[equalspos] != '\"')
00526          {
00527             keyvalue = unEscape(String(&values[equalspos], i-equalspos));
00528          }
00529          else
00530          {
00531             keyvalue = unEscape(String(&values[equalspos+1],
00532                i-equalspos-2));
00533          }
00534          i++;
00535          equalspos = 0;
00536          keystart = i;
00537          CIMProperty cp(keyprop);
00538          cp.setValue(CIMValue(keyvalue));
00539          cp.setDataType(CIMDataType::STRING);
00540          tmpkeys.append(cp);
00541          singleKey = false;
00542       }
00543       ++i;
00544    }
00545    //
00546    // Now assign the values to this instance
00547    //
00548    op.setKeys(tmpkeys);
00549    return op;
00550 }
00552 CIMUrl
00553 CIMObjectPath::getNameSpaceUrl() const
00554 {
00555    return m_pdata->m_nameSpace.getHostUrl();
00556 }
00558 // STATIC
00559 String
00560 CIMObjectPath::escape(const String& inString)
00561 {
00562    int valuesLen = static_cast<int>(inString.length());
00563    if (valuesLen == 0)
00564    {
00565       return inString;
00566    }
00567    StringBuffer rv(valuesLen);
00568    const char* values = inString.c_str();
00569    for (int i = 0; i < valuesLen; i++)
00570    {
00571       char ch = values[i];
00572       if (ch == '\\')
00573       {
00574          rv += '\\';
00575          rv += ch;
00576       }
00577       else if (ch == '"')
00578       {
00579          rv += '\\';
00580          rv += '"';
00581       }
00582       else if (ch == '\n')
00583       {
00584          rv += "\\n";
00585       }
00586       else
00587       {
00588          rv += ch;
00589       }
00590    }
00591    return rv.releaseString();
00592 }
00594 // STATIC
00595 String
00596 CIMObjectPath::unEscape(const String& inString)
00597 {
00598    int valuesLen = static_cast<int>(inString.length());
00599    if (valuesLen == 0)
00600    {
00601       return inString;
00602    }
00603    StringBuffer rv(valuesLen);
00604    const char* values = inString.c_str();
00605    int i = 0;
00606    while (i < valuesLen)
00607    {
00608       char ch = values[i];
00609       if (ch == '\\')
00610       {
00611          if (i+1 < valuesLen)
00612          {
00613             ++i;
00614             rv += values[i];
00615          }
00616       }
00617       else
00618       {
00619          rv += values[i];
00620       }
00621       ++i;
00622    }
00623    return rv.releaseString();
00624 }
00626 bool operator<(const CIMObjectPath& lhs, const CIMObjectPath& rhs)
00627 {
00628    return *lhs.m_pdata < *rhs.m_pdata;
00629 }
00631 bool CIMObjectPath::isClassPath() const
00632 {
00633    return getKeys().size() == 0;
00634 }
00636 bool CIMObjectPath::isInstancePath() const
00637 {
00638    return getKeys().size() != 0;
00639 }
00641 CIMObjectPath&
00642 CIMObjectPath::syncWithClass(const CIMClass& theClass)
00643 {
00644    if (!theClass || isClassPath())
00645    {
00646       return *this;
00647    }
00648    CIMName propName;
00649    CIMPropertyArray classProps = theClass.getKeys();
00650    CIMPropertyArray copProps = getKeys();
00651    // Remove properties that are not defined in the class
00652    size_t i = 0;
00653    while (i < copProps.size())
00654    {
00655       propName = copProps[i].getName();
00656       if (!theClass.getProperty(propName))
00657       {
00658          copProps.remove(i);
00659       }
00660       else
00661       {
00662          ++i;
00663       }
00664    }
00665    // Ensure existing properties have the right type
00666    for (size_t i = 0; i < classProps.size(); i++)
00667    {
00668       bool found = false;
00669       const CIMProperty& cprop = classProps[i];
00670       propName = cprop.getName();
00671       for (size_t j = 0; j < copProps.size(); j++)
00672       {
00673          CIMProperty iprop = copProps[j];
00674          if (iprop.getName() == propName)
00675          {
00676             CIMValue cv = iprop.getValue();
00677             iprop = cprop;
00678             if (cv)
00679             {
00680                if (cv.getType() != iprop.getDataType().getType())
00681                {
00682                   cv = CIMValueCast::castValueToDataType(cv,
00683                      iprop.getDataType());
00684                }
00685                iprop.setValue(cv);
00686             }
00687             copProps[j] = iprop;
00688             found = true;
00689             break;
00690          }
00691       }
00692       if (!found)
00693       {
00694          copProps.append(classProps[i]);
00695       }
00696    }
00697    setKeys(copProps);
00698    return *this;
00699 }
00700 
00702 CIMObjectPath::operator safe_bool () const
00703 {  
00704    return m_rep->objectpath ? &CIMObjectPath::m_rep : 0; 
00705 }
00706 
00708 bool 
00709 CIMObjectPath::operator!() const
00710 {  
00711    return !m_rep->objectpath; 
00712 }
00713 
00715 CIMObjectPathRepRef
00716 CIMObjectPath::getRep() const
00717 {
00718    return m_rep;
00719 }
00720 
00721 } // end namespace OWBI1
00722 

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