OW_CIMProperty.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_CIMProperty.hpp"
00038 #include "OW_StringBuffer.hpp"
00039 #include "OW_CIMValueCast.hpp"
00040 #include "OW_BinarySerialization.hpp"
00041 #include "OW_NULLValueException.hpp"
00042 #include "OW_StrictWeakOrdering.hpp"
00043 #include "OW_NoSuchQualifierException.hpp"
00044 #include "OW_CIMDataType.hpp"
00045 #include "OW_CIMQualifier.hpp"
00046 #include "OW_CIMException.hpp"
00047 #include "OW_COWIntrusiveCountableBase.hpp"
00048 
00049 namespace OW_NAMESPACE
00050 {
00051 
00052 using std::istream;
00053 using std::ostream;
00054 using namespace WBEMFlags;
00055 struct CIMProperty::PROPData : public COWIntrusiveCountableBase
00056 {
00057    PROPData();
00058    CIMName m_name;
00059    CIMQualifierArray m_qualifiers;
00060    //
00061    // Note that we can't rely on the cimValue's datatype
00062    // because that is determined by what gets stored  as
00063    // a value rather than what the MOF declared which is
00064    // what is stored in propertyDataType.
00065    //
00066    CIMDataType m_propertyDataType;
00067    //
00068    // For an array type property this states how large it
00069    // was declared as
00070    //
00071    Int32 m_sizeDataType;
00072    CIMName m_override;
00073    CIMName m_originClass;
00074    CIMValue m_cimValue;
00075    // propagated means inherited without change
00076    Bool m_propagated;
00077    PROPData* clone() const { return new PROPData(*this); }
00078 };
00079 CIMProperty::PROPData::PROPData() :
00080    m_sizeDataType(-1), m_cimValue(CIMNULL), m_propagated(false)
00081 {
00082 }
00083 bool operator<(const CIMProperty::PROPData& x, const CIMProperty::PROPData& y)
00084 {
00085    return StrictWeakOrdering(
00086       x.m_name, y.m_name,
00087       x.m_cimValue, y.m_cimValue,
00088       x.m_qualifiers, y.m_qualifiers,
00089       x.m_propertyDataType, y.m_propertyDataType,
00090       x.m_sizeDataType, y.m_sizeDataType,
00091       x.m_override, y.m_override,
00092       x.m_originClass, y.m_originClass,
00093       x.m_propagated, y.m_propagated);
00094 }
00096 CIMProperty::CIMProperty() :
00097    CIMElement(), m_pdata(new PROPData)
00098 {
00099 }
00101 CIMProperty::CIMProperty(CIMNULL_t) :
00102    CIMElement(), m_pdata(0)
00103 {
00104 }
00106 CIMProperty::CIMProperty(const CIMName& name) :
00107    CIMElement(), m_pdata(new PROPData)
00108 {
00109    m_pdata->m_name = name;
00110 }
00112 CIMProperty::CIMProperty(const char* name) :
00113    CIMElement(), m_pdata(new PROPData)
00114 {
00115    m_pdata->m_name = name;
00116 }
00118 CIMProperty::CIMProperty(const CIMName& name,
00119    const CIMValue& value) :
00120    CIMElement(), m_pdata(new PROPData)
00121 {
00122    m_pdata->m_name = name;
00123    m_pdata->m_cimValue = value;
00124    m_pdata->m_propertyDataType = value.getCIMDataType();
00125 }
00127 CIMProperty::CIMProperty(const CIMName& name,
00128    const CIMDataType& dt) :
00129    CIMElement(), m_pdata(new PROPData)
00130 {
00131    m_pdata->m_name = name;
00132    m_pdata->m_propertyDataType = dt;
00133 }
00135 CIMProperty::CIMProperty(const CIMProperty& x) :
00136    CIMElement(), m_pdata(x.m_pdata)
00137 {
00138 }
00140 CIMProperty::~CIMProperty()
00141 {
00142 }
00144 void
00145 CIMProperty::setNull()
00146 {
00147    m_pdata = NULL;
00148 }
00150 CIMProperty&
00151 CIMProperty::operator= (const CIMProperty& x)
00152 {
00153    m_pdata = x.m_pdata;
00154    return *this;
00155 }
00157 CIMProperty
00158 CIMProperty::clone(EIncludeQualifiersFlag includeQualifiers,
00159    EIncludeClassOriginFlag includeClassOrigin) const
00160 {
00161    CIMProperty cp;
00162    if (includeQualifiers)
00163    {
00164       cp.m_pdata->m_qualifiers = m_pdata->m_qualifiers;
00165    }
00166    if (includeClassOrigin)
00167    {
00168       cp.m_pdata->m_originClass = m_pdata->m_originClass;
00169    }
00170    cp.m_pdata->m_propertyDataType = m_pdata->m_propertyDataType;
00171    cp.m_pdata->m_sizeDataType = m_pdata->m_sizeDataType;
00172    cp.m_pdata->m_name = m_pdata->m_name;
00173    cp.m_pdata->m_override = m_pdata->m_override;
00174    if (m_pdata->m_cimValue && m_pdata->m_cimValue.getType() == CIMDataType::EMBEDDEDINSTANCE)
00175    {
00176       if (m_pdata->m_cimValue.getCIMDataType().isArrayType())
00177       {
00178          CIMInstanceArray array = m_pdata->m_cimValue.toCIMInstanceArray();
00179          for(CIMInstanceArray::iterator i = array.begin(); i != array.end(); i++ )
00180          {
00181             *i = i->clone(E_NOT_LOCAL_ONLY, includeQualifiers, includeClassOrigin);
00182          }
00183          cp.m_pdata->m_cimValue = CIMValue(array);
00184       }
00185       else
00186       {
00187          cp.m_pdata->m_cimValue = CIMValue(m_pdata->m_cimValue.toCIMInstance().clone(E_NOT_LOCAL_ONLY, includeQualifiers, includeClassOrigin));
00188       }
00189    }
00190    else
00191    {
00192       cp.m_pdata->m_cimValue = m_pdata->m_cimValue;
00193    }
00194    cp.m_pdata->m_propagated = m_pdata->m_propagated;
00195    return cp;
00196 }
00198 CIMQualifierArray
00199 CIMProperty::getQualifiers() const
00200 {
00201    return m_pdata->m_qualifiers;
00202 }
00204 CIMProperty&
00205 CIMProperty::setQualifiers(const CIMQualifierArray& quals)
00206 {
00207    m_pdata->m_qualifiers = quals;
00208    return *this;
00209 }
00211 String
00212 CIMProperty::getOriginClass() const
00213 {
00214    return m_pdata->m_originClass.toString();
00215 }
00217 CIMProperty&
00218 CIMProperty::setOriginClass(const CIMName& originCls)
00219 {
00220    m_pdata->m_originClass = originCls;
00221    return *this;
00222 }
00224 CIMProperty&
00225 CIMProperty::setValue(const CIMValue& val)
00226 {
00227    if (m_pdata->m_propertyDataType && val && val.getCIMDataType() != m_pdata->m_propertyDataType &&
00228       val.getType() != CIMDataType::EMBEDDEDCLASS && val.getType() != CIMDataType::EMBEDDEDINSTANCE)
00229    {
00230       m_pdata->m_cimValue = CIMValueCast::castValueToDataType(val, m_pdata->m_propertyDataType);
00231    }
00232    else
00233    {
00234       m_pdata->m_cimValue = val;
00235    }
00236    return *this;
00237 }
00239 CIMValue
00240 CIMProperty::getValue() const
00241 {
00242    return m_pdata->m_cimValue;
00243 }
00245 CIMValue
00246 CIMProperty::getValueT() const
00247 {
00248    if (!m_pdata->m_cimValue)
00249    {
00250       OW_THROW(NULLValueException, m_pdata->m_name.toString().c_str());
00251    }
00252    return m_pdata->m_cimValue;
00253 }
00255 CIMProperty&
00256 CIMProperty::setDataType(const CIMDataType& type)
00257 {
00258    m_pdata->m_propertyDataType = type;
00259    if (m_pdata->m_cimValue)
00260    {
00261       if (m_pdata->m_propertyDataType.getType() != m_pdata->m_cimValue.getType()
00262          || m_pdata->m_propertyDataType.isArrayType() !=
00263          m_pdata->m_cimValue.isArray())
00264       {
00265          if (m_pdata->m_cimValue.getType() != CIMDataType::EMBEDDEDCLASS &&
00266             m_pdata->m_cimValue.getType() != CIMDataType::EMBEDDEDINSTANCE)
00267          {
00268             m_pdata->m_cimValue = CIMValueCast::castValueToDataType(
00269                m_pdata->m_cimValue, m_pdata->m_propertyDataType);
00270          }
00271       }
00272    }
00273    return *this;
00274 }
00276 CIMProperty&
00277 CIMProperty::setDataType(const CIMDataType::Type& type)
00278 {
00279    return setDataType(CIMDataType(type));
00280 }
00282 CIMDataType
00283 CIMProperty::getDataType() const
00284 {
00285    return m_pdata->m_propertyDataType;
00286 }
00288 Int32
00289 CIMProperty::getSize() const
00290 {
00291    return m_pdata->m_sizeDataType;
00292 }
00294 CIMProperty&
00295 CIMProperty::setDataSize(Int32 size)
00296 {
00297    m_pdata->m_sizeDataType = size;
00298    return *this;
00299 }
00301 CIMProperty&
00302 CIMProperty::setOverridingProperty(const CIMName& opname)
00303 {
00304    m_pdata->m_override = opname;
00305    return *this;
00306 }
00308 String
00309 CIMProperty::getOverridingProperty() const
00310 {
00311    return m_pdata->m_override.toString();
00312 }
00314 bool
00315 CIMProperty::isReference() const
00316 {
00317    return m_pdata->m_propertyDataType.isReferenceType();
00318 }
00320 CIMQualifier
00321 CIMProperty::getQualifier(const CIMName& name) const
00322 {
00323    size_t tsize = m_pdata->m_qualifiers.size();
00324    for (size_t i = 0; i < tsize; i++)
00325    {
00326       CIMQualifier nq = m_pdata->m_qualifiers[i];
00327       if (nq.getName() == name)
00328       {
00329          return nq;
00330       }
00331    }
00332    return CIMQualifier(CIMNULL);
00333 }
00335 CIMQualifier
00336 CIMProperty::getQualifierT(const CIMName& name) const
00337 {
00338    CIMQualifier rval = getQualifier(name);
00339    if (!rval)
00340    {
00341       OW_THROW(NoSuchQualifierException, name.toString().c_str());
00342    }
00343    return rval;
00344 }
00346 CIMProperty&
00347 CIMProperty::setQualifier(const CIMQualifier& qual)
00348 {
00349    if (qual)
00350    {
00351       CIMName qualName = qual.getName();
00352       for (size_t i = 0; i < m_pdata->m_qualifiers.size(); i++)
00353       {
00354          if (m_pdata->m_qualifiers[i].getName() == qualName)
00355          {
00356             m_pdata->m_qualifiers[i] = qual;
00357             return *this;
00358          }
00359       }
00360       m_pdata->m_qualifiers.append(qual);
00361    }
00362    return *this;
00363 }
00365 CIMProperty&
00366 CIMProperty::addQualifier(const CIMQualifier& qual)
00367 {
00368    size_t tsize = m_pdata->m_qualifiers.size();
00369    for (size_t i = 0; i < tsize; i++)
00370    {
00371       CIMQualifier nq = m_pdata->m_qualifiers[i];
00372       if (nq.getName().equalsIgnoreCase(qual.getName()))
00373       {
00374          String msg("Qualifier ");
00375          msg += qual.getName();
00376          msg += " already exists";
00377          OW_THROWCIMMSG(CIMException::ALREADY_EXISTS, msg.c_str());
00378       }
00379    }
00380    m_pdata->m_qualifiers.append(qual);
00381    return *this;
00382 }
00384 bool
00385 CIMProperty::removeQualifier(const CIMName& name)
00386 {
00387    size_t tsize = m_pdata->m_qualifiers.size();
00388    for (size_t i = 0; i < tsize; i++)
00389    {
00390       CIMQualifier nq = m_pdata->m_qualifiers[i];
00391       if (nq.getName() == name)
00392       {
00393          m_pdata->m_qualifiers.remove(i);
00394          return true;
00395       }
00396    }
00397    return false;
00398 }
00400 bool
00401 CIMProperty::isKey() const
00402 {
00403    // TODO: Evaluate this.  It's not necessarily true that a REF is a key.  That's just the DMTF CIM Schema convention.
00404    if (getDataType().isReferenceType()
00405       || hasTrueQualifier(CIMQualifier::CIM_QUAL_KEY))
00406    {
00407       return true;
00408    }
00409    return false;
00410 }
00412 CIMProperty
00413 CIMProperty::filter(ELocalOnlyFlag localOnly, EIncludeQualifiersFlag includeQualifiers) const
00414 {
00415    //
00416    // If only local definitions are required and this is a propagated
00417    // property then nothing to return
00418    //
00419    if (localOnly && m_pdata->m_propagated)
00420    {
00421       return CIMProperty(CIMNULL);
00422    }
00423    CIMProperty cp;
00424    cp.m_pdata->m_propertyDataType = m_pdata->m_propertyDataType;
00425    cp.m_pdata->m_sizeDataType = m_pdata->m_sizeDataType;
00426    cp.m_pdata->m_name = m_pdata->m_name;
00427    cp.m_pdata->m_override = m_pdata->m_override;
00428    cp.m_pdata->m_originClass = m_pdata->m_originClass;
00429    cp.m_pdata->m_cimValue = m_pdata->m_cimValue;
00430    cp.m_pdata->m_propagated = m_pdata->m_propagated;
00431    if (includeQualifiers)
00432    {
00433       cp.m_pdata->m_qualifiers = m_pdata->m_qualifiers;
00434    }
00435    return cp;
00436 }
00438 CIMProperty&
00439 CIMProperty::setPropagated(bool propagated)
00440 {
00441    m_pdata->m_propagated = propagated;
00442    return *this;
00443 }
00445 bool
00446 CIMProperty::getPropagated() const
00447 {
00448    return m_pdata->m_propagated;
00449 }
00451 String
00452 CIMProperty::getName() const
00453 {
00454    return m_pdata->m_name.toString();
00455 }
00457 void
00458 CIMProperty::setName(const CIMName& name)
00459 {
00460    m_pdata->m_name = name;
00461 }
00463 CIMProperty&
00464 CIMProperty::clearQualifiers()
00465 {
00466    m_pdata->m_qualifiers.clear();
00467    return *this;
00468 }
00470 CIMProperty&
00471 CIMProperty::clearNonKeyQualifiers()
00472 {
00473    CIMQualifier key = getQualifier(CIMQualifier::CIM_QUAL_KEY);
00474    m_pdata->m_qualifiers.clear();
00475    if (key)
00476    {
00477       addQualifier(key);
00478    }
00479    return *this;
00480 }
00482 void
00483 CIMProperty::writeObject(ostream &ostrm) const
00484 {
00485    writeObject(ostrm, E_INCLUDE_QUALIFIERS);
00486 }
00488 void
00489 CIMProperty::writeObject(ostream &ostrm, EIncludeQualifiersFlag includeQualifiers) const
00490 {
00491    CIMBase::writeSig( ostrm, OW_CIMPROPERTYSIG );
00492    m_pdata->m_name.writeObject(ostrm);
00493    m_pdata->m_override.writeObject(ostrm);
00494    m_pdata->m_originClass.writeObject(ostrm);
00495    m_pdata->m_propertyDataType.writeObject(ostrm);
00496    BinarySerialization::writeLen(ostrm, m_pdata->m_sizeDataType);
00497    m_pdata->m_propagated.writeObject(ostrm);
00498    if (includeQualifiers)
00499    {
00500       BinarySerialization::writeArray(ostrm, m_pdata->m_qualifiers);
00501    }
00502    else
00503    {
00504       BinarySerialization::writeArray(ostrm, CIMQualifierArray());
00505    }
00506    if (m_pdata->m_cimValue)
00507    {
00508       Bool(true).writeObject(ostrm);
00509       m_pdata->m_cimValue.writeObject(ostrm);
00510    }
00511    else
00512    {
00513       Bool(false).writeObject(ostrm);
00514    }
00515 }
00517 void
00518 CIMProperty::readObject(istream &istrm)
00519 {
00520    CIMName name;
00521    CIMName override;
00522    CIMName originClass;
00523    CIMValue cimValue(CIMNULL);
00524    CIMDataType propertyDataType(CIMNULL);
00525    UInt32 sizeDataType;
00526    Bool propagated;
00527    CIMQualifierArray qualifiers;
00528    CIMBase::readSig( istrm, OW_CIMPROPERTYSIG );
00529    name.readObject(istrm);
00530    override.readObject(istrm);
00531    originClass.readObject(istrm);
00532    propertyDataType.readObject(istrm);
00533    BinarySerialization::readLen(istrm, sizeDataType);
00534    propagated.readObject(istrm);
00535    BinarySerialization::readArray(istrm, qualifiers);
00536    Bool isValue;
00537    isValue.readObject(istrm);
00538    if (isValue)
00539    {
00540       cimValue.readObject(istrm);
00541    }
00542    if (!m_pdata)
00543    {
00544       m_pdata = new PROPData;
00545    }
00546    m_pdata->m_name = name;
00547    m_pdata->m_override = override;
00548    m_pdata->m_originClass = originClass;
00549    m_pdata->m_cimValue = cimValue;
00550    m_pdata->m_propertyDataType = propertyDataType;
00551    m_pdata->m_sizeDataType = sizeDataType;
00552    m_pdata->m_propagated = propagated;
00553    m_pdata->m_qualifiers = qualifiers;
00554 }
00556 String
00557 CIMProperty::toString() const
00558 {
00559    StringBuffer rv = m_pdata->m_propertyDataType.toString() + ":"
00560       + m_pdata->m_name.toString() + "=";
00561    if (m_pdata->m_cimValue)
00562    {
00563       rv += m_pdata->m_cimValue.toString();
00564    }
00565    else
00566    {
00567       rv += "null";
00568    }
00569    return rv.releaseString();
00570 }
00572 String
00573 CIMProperty::toMOF() const
00574 {
00575    // this outputs a property suitable for a CIM class.
00576    StringBuffer rv;
00577    if (m_pdata->m_qualifiers.size() > 0)
00578    {
00579       rv += "  [";
00580       for (size_t i = 0; i < m_pdata->m_qualifiers.size(); i++)
00581       {
00582          CIMQualifier nq = m_pdata->m_qualifiers[i];
00583          if (i > 0)
00584          {
00585             rv += ',';
00586 // TODO:          rv += ",\n   ";
00587          }
00588          rv += nq.toMOF();
00589       }
00590       rv += "]\n";
00591    }
00592    rv += "  ";
00593    rv += m_pdata->m_propertyDataType.toMOF();
00594    rv += ' ';
00595    rv += m_pdata->m_name.toString();
00596    // If it is an array, show it.
00597    rv += m_pdata->m_propertyDataType.getArrayMOF();
00598    if (m_pdata->m_cimValue)
00599    {
00600       rv += '=';
00601       rv += m_pdata->m_cimValue.toMOF();
00602    }
00603    rv += ";\n";
00604    return rv.releaseString();
00605 }
00607 const char* const CIMProperty::NAME_PROPERTY = "Name";
00609 bool operator<(const CIMProperty& x, const CIMProperty& y)
00610 {
00611    return *x.m_pdata < *y.m_pdata;
00612 }
00614 bool
00615 CIMProperty::hasTrueQualifier(const CIMName& name) const
00616 {
00617    CIMQualifier q = getQualifier(name);
00618    if (!q)
00619    {
00620       return false;
00621    }
00622    CIMValue v = q.getValue();
00623    if (!v)
00624    {
00625       return false;
00626    }
00627    if (v.getType() != CIMDataType::BOOLEAN)
00628    {
00629       return false;
00630    }
00631    Bool b;
00632    v.get(b);
00633    return b;
00634 }
00635 
00636 } // end namespace OW_NAMESPACE
00637 

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