BUG#: 7626
[tpot/pegasus/.git] / src / Pegasus / Common / CIMInstanceRep.cpp
index 7e6b98d4a300fbb9376e6dea346a042cffb007b7..b4b01a562f5240df4f73d80bca9bb113769cb663 100644 (file)
-//%/////////////////////////////////////////////////////////////////////////////
+//%LICENSE////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
+// Licensed to The Open Group (TOG) under one or more contributor license
+// agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
+// this work for additional information regarding copyright ownership.
+// Each contributor licenses this file to you under the OpenPegasus Open
+// Source License; you may not use this file except in compliance with the
+// License.
 //
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to 
-// deal in the Software without restriction, including without limitation the 
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN 
-// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
-// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
-// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
-// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
 //
-//==============================================================================
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
 //
-// Author: Mike Brasher (mbrasher@bmc.com)
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-// Modified By:
+//////////////////////////////////////////////////////////////////////////
 //
 //%/////////////////////////////////////////////////////////////////////////////
 
+#include "CIMInstanceRep.h"
 #include "CIMInstance.h"
+#include "CIMClassRep.h"
+#include "CIMScope.h"
 #include "DeclContext.h"
-#include "Indentor.h"
+#include "Resolver.h"
 #include "CIMName.h"
-#include "XmlWriter.h"
-
-PEGASUS_NAMESPACE_BEGIN
-
-CIMInstanceRep::CIMInstanceRep(const String& className)
-    : _className(className), _resolved(false)
-{
-    if (!CIMName::legal(className))
-       throw IllegalName();
-}
+#include "Constants.h"
+#include "StrLit.h"
 
-CIMInstanceRep::~CIMInstanceRep()
-{
-
-}
-
-void CIMInstanceRep::addProperty(const CIMProperty& x)
-{
-    if (!x)
-       throw UnitializedHandle();
+PEGASUS_USING_STD;
 
-    // Reject duplicate property names:
-
-    if (findProperty(x.getName()) != PEG_NOT_FOUND)
-       throw AlreadyExists();
-
-    // Note: class origin is resolved later:
-
-    // Append property:
-
-    _properties.append(x);
-}
+PEGASUS_NAMESPACE_BEGIN
 
-Uint32 CIMInstanceRep::findProperty(const String& name)
+CIMInstanceRep::CIMInstanceRep(const CIMObjectPath& reference)
+    : CIMObjectRep(reference)
 {
-    for (Uint32 i = 0, n = _properties.size(); i < n; i++)
-    {
-       if (CIMName::equal(_properties[i].getName(), name))
-           return i;
-    }
-
-    return PEG_NOT_FOUND;
-}
 
-Boolean CIMInstanceRep::existsProperty(const String& name)
-{
-    return (findProperty(name) != PEG_NOT_FOUND) ?
-                   true : false;
 }
 
-CIMProperty CIMInstanceRep::getProperty(Uint32 pos)
+CIMInstanceRep::~CIMInstanceRep()
 {
-    if (pos >= _properties.size())
-       throw OutOfBounds();
-
-    return _properties[pos];
-}
-
-void CIMInstanceRep::removeProperty(Uint32 pos)
-    {
-       if (pos >= _properties.size())
-           throw OutOfBounds();
 
-       _properties.remove(pos);
-    }
-
-
-Uint32 CIMInstanceRep::getPropertyCount() const
-{
-    return _properties.size();
 }
 
-
 void CIMInstanceRep::resolve(
     DeclContext* context,
-    const String& nameSpace,
-    CIMConstClass& cimClassOut)
+    const CIMNamespaceName& nameSpace,
+    CIMConstClass& cimClassOut,
+    Boolean propagateQualifiers)
 {
     // ATTN: Verify that references are initialized.
 
-#if 0
-    if (_resolved)
-       throw InstanceAlreadyResolved();
-#endif
-
     if (!context)
-       throw NullPointer();
+        throw NullPointer();
 
     //----------------------------------------------------------------------
     // First obtain the class:
     //----------------------------------------------------------------------
 
     CIMConstClass cimClass =
-       context->lookupClass(nameSpace, _className);
+        context->lookupClass(nameSpace, _reference.getClassName());
 
-    if (!cimClass)
-       throw PEGASUS_CIM_EXCEPTION(INVALID_CLASS, _className);
+    if (cimClass.isUninitialized())
+        throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_CLASS,
+            _reference.getClassName().getString ());
 
     cimClassOut = cimClass;
 
-#if 0
-    if (!cimClass._rep->_resolved)
-       throw ClassNotResolved(_className);
-#endif
-
     //----------------------------------------------------------------------
     // Disallow instantiation of abstract classes.
     //----------------------------------------------------------------------
 
     if (cimClass.isAbstract())
-       throw InstantiatedAbstractClass();
+        throw InstantiatedAbstractClass(_reference.getClassName().getString ());
 
     //----------------------------------------------------------------------
-    // Validate the qualifiers of this class:
+    // Validate and propagate qualifiers.
     //----------------------------------------------------------------------
-
     _qualifiers.resolve(
-       context,
-       nameSpace,
-       CIMScope::CLASS,
-       false,
-       cimClass._rep->_qualifiers);
+        context,
+        nameSpace,
+        (cimClass.isAssociation()) ? CIMScope::ASSOCIATION : CIMScope::CLASS,
+        false,
+        cimClass._rep->_qualifiers,
+        propagateQualifiers);
 
     //----------------------------------------------------------------------
     // First iterate the properties of this instance and verify that
     // each one is defined in the class and then resolve each one.
-    // Also set the class origin.
     //----------------------------------------------------------------------
 
-    String classOrigin = cimClass.getClassName();
+    CIMName className = cimClass.getClassName();
 
     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
     {
-       CIMProperty& property = _properties[i];
-
-       Uint32 pos = cimClass.findProperty(property.getName());
-
-       if (pos == PEG_NOT_FOUND)
-           throw NoSuchProperty(property.getName());
-
-       property.resolve(context, nameSpace, true, cimClass.getProperty(pos));
-        property.setClassOrigin(classOrigin);
+        CIMProperty& property = _properties[i];
+
+        Uint32 index = cimClass.findProperty(property.getName());
+
+        if (index == PEG_NOT_FOUND)
+        {
+            //
+            //  Allow addition of Creator property to Indication Subscription,
+            //  Filter and Handler instances
+            //
+// l10n add language property support
+            if (!(((className.equal
+                    (CIMName (PEGASUS_CLASSNAME_INDSUBSCRIPTION))) ||
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))) ||
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_INDHANDLER_CIMXML))) ||
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_LSTNRDST_CIMXML))) ||
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_INDHANDLER_SNMP))) ||
+#ifdef  PEGASUS_ENABLE_SYSTEM_LOG_HANDLER
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG))) ||
+#endif
+#ifdef  PEGASUS_ENABLE_EMAIL_HANDLER
+                (className.equal
+                    (CIMName (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))) ||
+#endif
+                (className.equal (CIMName (PEGASUS_CLASSNAME_INDFILTER)))) &&
+                ((property.getName ().equal
+                    (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CREATOR))) ||
+                (property.getName ().equal
+                    (CIMName (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS))) ||
+                (property.getName ().equal
+                    (CIMName (PEGASUS_PROPERTYNAME_LSTNRDST_CREATIONTIME))) ||
+                (property.getName ().equal
+                    (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS))))))
+            {
+                throw NoSuchProperty(property.getName().getString ());
+            }
+        }
+        else
+        {
+            // resolve the property
+            Resolver::resolveProperty (property, context, nameSpace, true,
+                cimClass.getProperty (index), propagateQualifiers);
+        }
     }
 
     //----------------------------------------------------------------------
     // Inject all properties from the class that are not included in the
     // instance. Copy over the class-origin and set the propagated flag
-    // to true.
+    // to true. NOTE: The propagated flag indicates that the property
+    // was not part of the property set input with the create and
+    // was inherited from the default in the class (see cimxml spec sect 3.1.5)
     //----------------------------------------------------------------------
 
     for (Uint32 i = 0, m = 0, n = cimClass.getPropertyCount(); i < n; i++)
     {
-       CIMConstProperty property = cimClass.getProperty(i);
-       const String& name = property.getName();
-
-       // See if this instance already contains a property with this name:
-
-       Boolean found = false;
-
-       for (Uint32 j = m, n = _properties.size(); j < n; j++)
-       {
-           if (CIMName::equal(_properties[j].getName(), name))
-           {
-               found = true;
-               break;
-           }
-       }
-
-       if (!found)
-       {
-           CIMProperty p = property.clone();
-           p.setPropagated(true);
-           _properties.insert(m++, p);
-       }
+        CIMConstProperty property = cimClass.getProperty(i);
+        const CIMName& name = property.getName();
+
+        // See if this instance already contains a property with this name:
+
+        Boolean found = false;
+
+        for (Uint32 j = m, s = _properties.size(); j < s; j++)
+        {
+            if (name.equal(_properties[j].getName()))
+            {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found)
+        {
+            CIMProperty p;
+            if (propagateQualifiers)
+            {
+                p = property.clone();
+            }
+            else
+            {
+                p = CIMProperty(
+                    property.getName(),
+                    property.getValue(),
+                    property.getArraySize(),
+                    property.getReferenceClassName(),
+                    property.getClassOrigin(),
+                    property.getPropagated());
+            }
+            p.setPropagated(true);
+            _properties.insert(m++, p);
+        }
     }
-
-#if 0
-    _resolved = true;
-#endif
 }
 
-CIMInstanceRep::CIMInstanceRep()
+CIMInstanceRep::CIMInstanceRep(const CIMInstanceRep& x) : CIMObjectRep(x)
 {
-
-}
-
-CIMInstanceRep::CIMInstanceRep(const CIMInstanceRep& x) :
-    Sharable(),
-    _className(x._className),
-    _resolved(x._resolved)
-{
-    x._qualifiers.cloneTo(_qualifiers);
-
-    _properties.reserve(x._properties.size());
-
-    for (Uint32 i = 0, n = x._properties.size(); i < n; i++)
-       _properties.append(x._properties[i].clone());
 }
 
-CIMInstanceRep& CIMInstanceRep::operator=(const CIMInstanceRep& x)
-{
-    return *this;
-}
-
-Boolean CIMInstanceRep::identical(const CIMInstanceRep* x) const
-{
-    if (_className != x->_className)
-       return false;
-
-    if (!_qualifiers.identical(x->_qualifiers))
-       return false;
-
-    // Compare properties:
-
-    {
-       const Array<CIMProperty>& tmp1 = _properties;
-       const Array<CIMProperty>& tmp2 = x->_properties;
-
-       if (tmp1.size() != tmp2.size())
-           return false;
-
-       for (Uint32 i = 0, n = tmp1.size(); i < n; i++)
-       {
-           if (!tmp1[i].identical(tmp2[i]))
-               return false;
-       }
-    }
-
-    if (_resolved != x->_resolved)
-       return false;
-
-    return true;
-}
-
-void CIMInstanceRep::toXml(Array<Sint8>& out) const
-{
-    // Class opening element:
-
-    out << "<INSTANCE ";
-    out << " CLASSNAME=\"" << _className << "\" ";
-    out << ">\n";
-
-    // Qualifiers:
-
-    _qualifiers.toXml(out);
-
-    // Parameters:
-
-    for (Uint32 i = 0, n = _properties.size(); i < n; i++)
-       _properties[i].toXml(out);
-
-    // Class closing element:
-
-    out << "</INSTANCE>\n";
-}
-
-void CIMInstanceRep::print(PEGASUS_STD(ostream) &os) const
-{
-    Array<Sint8> tmp;
-    toXml(tmp);
-    tmp.append('\0');
-    os << tmp.getData() << PEGASUS_STD(endl);
-}
-
-CIMReference CIMInstanceRep::getInstanceName(
+CIMObjectPath CIMInstanceRep::buildPath(
     const CIMConstClass& cimClass) const
 {
     //--------------------------------------------------------------------------
     // Get class name:
     //--------------------------------------------------------------------------
 
-    String className = getClassName();
+    CIMName className = getClassName();
 
     //--------------------------------------------------------------------------
     // Get key names:
     //--------------------------------------------------------------------------
 
-    Array<String> keyNames;
+    Array<CIMName> keyNames;
     cimClass.getKeyNames(keyNames);
 
     if (keyNames.size() == 0)
-       return CIMReference();
+        return CIMObjectPath("", CIMNamespaceName(), className);
 
     //--------------------------------------------------------------------------
     // Get type and value for each key (building up key bindings):
     //--------------------------------------------------------------------------
 
-    KeyBindingArray keyBindings;
+    Array<CIMKeyBinding> keyBindings;
 
     for (Uint32 i = 0, n = keyNames.size(); i < n; i++)
     {
-       const String& keyName = keyNames[i];
-
-       Uint32 pos = findProperty(keyName);
-       PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
-
-       CIMConstProperty tmp = getProperty(pos);
-
-       if (CIMName::equal(tmp.getName(), keyName))
-       {
-           const CIMValue& value = tmp.getValue();
-
-           // ATTN-A: for now just assert:
-           if (value.isArray())
-               PEGASUS_ASSERT(false);
-
-           CIMType type = value.getType();
-           String valueStr;
-
-           KeyBinding::Type kbType = KeyBinding::STRING;
-
-           switch (type)
-           {
-               case CIMType::BOOLEAN:
-                   kbType = KeyBinding::BOOLEAN;
-                   valueStr = value.toString();
-                   break;
-
-               case CIMType::UINT8:
-               case CIMType::SINT8:
-               case CIMType::UINT16:
-               case CIMType::SINT16:
-               case CIMType::UINT32:
-               case CIMType::SINT32:
-               case CIMType::UINT64:
-               case CIMType::SINT64:
-               case CIMType::CHAR16:
-                   kbType = KeyBinding::NUMERIC;
-                   valueStr = value.toString();
-                   break;
-
-               case CIMType::STRING:
-               case CIMType::DATETIME:
-                   kbType = KeyBinding::STRING;
-                   valueStr = value.toString();
-                   break;
-
-               case CIMType::REFERENCE:
-               {
-                   kbType = KeyBinding::STRING;
-
-                   CIMReference tmpRef = value.toString();
-                   valueStr = tmpRef.toStringCanonical();
-                   break;
-               }
-
-               case CIMType::REAL32:
-               case CIMType::REAL64:
-                   PEGASUS_ASSERT(false);
-           }
-
-           keyBindings.append(KeyBinding(keyName, valueStr, kbType));
-       }
+        const CIMName& keyName = keyNames[i];
+
+        Uint32 index = findProperty(keyName);
+        if (index == PEG_NOT_FOUND)
+        {
+            throw NoSuchProperty(keyName.getString());
+        }
+
+        CIMConstProperty tmp = getProperty(index);
+        keyBindings.append(CIMKeyBinding(keyName, tmp.getValue()));
     }
 
-    return CIMReference(String(), String(), className, keyBindings);
+    return CIMObjectPath(String(), CIMNamespaceName(), className, keyBindings);
+}
+
+// KS Mar 05 - The following removal functions are very inefficient and should
+// be optimized to avoid the multiple memory moves.  Actually, the remove
+// qualifiers should be added as a function and optimized that once.
+void CIMInstanceRep::filter(
+    Boolean includeQualifiers,
+    Boolean includeClassOrigin,
+    const CIMPropertyList& propertyList)
+{
+    // Filter any qualifiers from this instance.
+    if (!includeQualifiers && _qualifiers.getCount() > 0)
+    {
+        while (_qualifiers.getCount())
+        {
+            _qualifiers.removeQualifier(0);
+        }
+    }
+
+    // For each property, remove if not in propertylist
+    for (Uint32 i = 0 ; i < _properties.size(); i++)
+    {
+        CIMConstProperty p = getProperty(i);
+        CIMName name = p.getName();
+        Array<CIMName> pl = propertyList.getPropertyNameArray();
+        if (propertyList.isNull() || Contains(pl, name))
+        {
+            // test ClassOrigin and possibly remove
+            if (!includeClassOrigin)
+            {
+                _properties[i].setClassOrigin(CIMName());
+            }
+            // remove qualifiers if required.
+            if (!includeQualifiers && _properties[i].getQualifierCount() > 0)
+            {
+                while (_properties[i].getQualifierCount() > 0)
+                {
+                    _properties[i].removeQualifier(0);
+                }
+            }
+        }
+        else
+        {
+            _properties.remove(i--);
+        }
+    }
+    return;
 }
 
 PEGASUS_NAMESPACE_END