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_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
00114
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
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
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
00429
00430
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
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
00553
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
00563
00564 int i = 0;
00565 int keystart = 0;
00566 while (i < valuesLen)
00567 {
00568 char ch = values[i];
00569
00570 if (i < valuesLen-1 && ch == '\\')
00571 {
00572 i += 2;
00573 continue;
00574 }
00575
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
00594 CIMProperty cp("test it");
00595
00596
00597
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
00626
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
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
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
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
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
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 }
00805