CIMProperty ObjectNormalizer::processProperty( CIMConstProperty& referenceProperty, CIMConstProperty& instProperty, Boolean includeQualifiers, Boolean includeClassOrigin, NormalizerContext* context, const CIMNamespaceName& nameSpace) { // check name if (!referenceProperty.getName().equal(instProperty.getName())) { MessageLoaderParms message( "Common.ObjectNormalizer.INVALID_PROPERTY_NAME", "Invalid property name: $0", instProperty.getName().getString()); throw CIMException(CIM_ERR_FAILED, message); } // check type CIMType referencePropType = referenceProperty.getType(); CIMType instPropType = instProperty.getType(); if (referencePropType != instPropType) { MessageLoaderParms message( "Common.ObjectNormalizer.INVALID_PROPERTY_TYPE", "Invalid property type: $0", instProperty.getName().getString()); throw CIMException(CIM_ERR_FAILED, message); } // TODO: check array size? CIMProperty normalizedProperty( referenceProperty.getName(), referenceProperty.getValue(), // default value referenceProperty.getArraySize(), referenceProperty.getReferenceClassName(), CIMName(), false); // TODO: check override (especially for references)? // update value if (!instProperty.getValue().isNull()) { normalizedProperty.setValue(instProperty.getValue()); } // update class origin if (includeClassOrigin) { normalizedProperty.setClassOrigin(referenceProperty.getClassOrigin()); } // add qualifiers if (includeQualifiers) { // propagate class property qualifiers for (Uint32 i=0, n = referenceProperty.getQualifierCount(); i < n; i++) { CIMConstQualifier referenceQualifier = referenceProperty.getQualifier(i); Uint32 pos = instProperty.findQualifier(referenceQualifier.getName()); // update value if qualifier is present in the specified property if (pos != PEG_NOT_FOUND) { CIMConstQualifier cimQualifier = instProperty.getQualifier(pos); CIMQualifier normalizedQualifier = _processQualifier( referenceQualifier, cimQualifier); normalizedProperty.addQualifier(normalizedQualifier); } else { normalizedProperty.addQualifier(referenceQualifier.clone()); } } } #ifdef PEGASUS_SNIA_INTEROP_COMPATIBILITY else if (referenceProperty.getType() == CIMTYPE_INSTANCE) { Uin32 refPos = referenceProperty.findQualifier( PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE); Uin32 cimPos = instProperty.findQualifier( PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE); if (refPos != PEG_NOT_FOUND && cimPos == PEG_NOT_FOUND) { instProperty.addQualifier(refProperty.getQualifier(pos)); } } #endif // Check the type of the embedded instance against the class specified by // the EmbeddedInstance qualifier. We can only do this if the context // is non-zero. if (context != 0) { if (referenceProperty.getType() == CIMTYPE_INSTANCE) { Uint32 pos = referenceProperty.findQualifier( PEGASUS_QUALIFIERNAME_EMBEDDEDINSTANCE); PEGASUS_ASSERT(pos != PEG_NOT_FOUND); String qualClassStr; referenceProperty.getQualifier(pos).getValue().get( qualClassStr); CIMName embedInstClassName(qualClassStr); Array<CIMName> embeddedInstSubclasses = context->enumerateClassNames(nameSpace, embedInstClassName, true); embeddedInstSubclasses.append(embedInstClassName); Array<CIMInstance> embeddedInstances; if (referenceProperty.isArray()) { instProperty.getValue().get(embeddedInstances); } else { CIMInstance embeddedInst; instProperty.getValue().get(embeddedInst); embeddedInstances.append(embeddedInst); } Array<CIMClass> embeddedClassDefs; for (Uint32 i = 0, n = embeddedInstances.size(); i < n; ++i) { CIMInstance& currentInstance = embeddedInstances[i]; CIMName currentClassName = currentInstance.getClassName(); if (Contains(embeddedInstSubclasses, currentClassName)) { CIMClass embeddedClassDef; bool found = false; for (Uint32 j = 0, m = embeddedClassDefs.size(); j < m; ++j) { CIMClass& tmpClassDef = embeddedClassDefs[j]; if (tmpClassDef.getClassName() == currentClassName) { embeddedClassDef = tmpClassDef; found = true; } } if (!found) { embeddedClassDef = context->getClass(nameSpace, currentClassName); embeddedClassDefs.append(embeddedClassDef); } SharedPtr<NormalizerContext> tmpContext(context->clone()); ObjectNormalizer tmpNormalizer(embeddedClassDef, includeQualifiers, includeClassOrigin, nameSpace, tmpContext); if (currentInstance.getPath().getKeyBindings().size()==0) { currentInstance.setPath( currentInstance.buildPath(embeddedClassDef)); } embeddedInstances[i] = tmpNormalizer.processInstance(currentInstance); } else { MessageLoaderParms message( "Common.ObjectNormalizer." "INVALID_EMBEDDED_INSTANCE_TYPE", "Found embedded instance of type $0: was expecting " "$1 for property $2", currentClassName.getString(), qualClassStr, instProperty.getName().getString()); throw CIMException(CIM_ERR_FAILED, message); } } if (referenceProperty.isArray()) { normalizedProperty.setValue(CIMValue(embeddedInstances)); } else { normalizedProperty.setValue(CIMValue(embeddedInstances[0])); } } } return normalizedProperty; }
// // Test of the Instance creation and instance filtering // void test04() { if (verbose) { cout << "Test04 - Create instance from Class. " << endl; } const CIMNamespaceName NAMESPACE = CIMNamespaceName("/zzz"); // Create and populate a declaration context: SimpleDeclContext* context = new SimpleDeclContext; context->addQualifierDecl( NAMESPACE, CIMQualifierDecl(CIMName("counter"), false, CIMScope::PROPERTY)); context->addQualifierDecl( NAMESPACE, CIMQualifierDecl(CIMName("classcounter"), false, CIMScope::CLASS)); context->addQualifierDecl( NAMESPACE, CIMQualifierDecl(CIMName("min"), String(), CIMScope::PROPERTY)); context->addQualifierDecl( NAMESPACE, CIMQualifierDecl(CIMName("max"), String(), CIMScope::PROPERTY)); context->addQualifierDecl(NAMESPACE, CIMQualifierDecl(CIMName("Description"), String(), CIMScope::PROPERTY)); CIMClass class1(CIMName("MyClass")); class1 .addProperty(CIMProperty(CIMName("count"), Uint32(55)) .addQualifier(CIMQualifier(CIMName("counter"), true)) .addQualifier(CIMQualifier(CIMName("min"), String("0"))) .addQualifier(CIMQualifier(CIMName("max"), String("1")))) .addProperty(CIMProperty(CIMName("message"), String("Hello")) .addQualifier(CIMQualifier(CIMName("description"), String("My Message")))) .addProperty(CIMProperty(CIMName("ratio"), Real32(1.5))); Resolver::resolveClass(class1, context, NAMESPACE); context->addClass(NAMESPACE, class1); if (verbose) { XmlWriter::printClassElement(class1); } // // Create instance with qualifiers, classorigin, and Null propertyList // { CIMInstance newInstance; newInstance = class1.buildInstance(true, true, CIMPropertyList()); if (verbose) { XmlWriter::printInstanceElement(newInstance); } assert(newInstance.getPropertyCount() == class1.getPropertyCount()); assert(newInstance.getQualifierCount() == class1.getQualifierCount()); assert(newInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(newInstance.findProperty("message") != PEG_NOT_FOUND); } // // Test with include qualifiers false. Should be no qualifiers in result // { CIMInstance newInstance = class1.buildInstance(false, true, CIMPropertyList()); assert(newInstance.getQualifierCount() == 0); assert(newInstance.getPropertyCount() == class1.getPropertyCount()); assert(newInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(newInstance.findProperty("message") != PEG_NOT_FOUND); } // // Test with empty property list. Should have no properties. // { Array<CIMName> pl1Array; CIMPropertyList pl1(pl1Array); CIMInstance newInstance = class1.buildInstance(false, true, pl1); assert(newInstance.getQualifierCount() == 0); assert(newInstance.getPropertyCount() == 0); } // // Test with a property that exists in property list. // { Array<CIMName> pl1Array; pl1Array.append("ratio"); CIMPropertyList pl1(pl1Array); CIMInstance newInstance = class1.buildInstance(false, true, pl1); if (verbose) { cout << "Test with one property in new instance" << endl; XmlWriter::printInstanceElement(newInstance); } assert(newInstance.getPropertyCount() == 1); assert(newInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(newInstance.findProperty("message") == PEG_NOT_FOUND); assert(newInstance.getQualifierCount() == 0); } // // Test with a property that does/does not exist in property list // { Array<CIMName> pl1Array; CIMPropertyList pl1(pl1Array); pl1.clear(); pl1Array.append("blob"); pl1Array.append("ratio"); pl1.set(pl1Array); CIMInstance newInstance = class1.buildInstance(false, true, pl1); assert(newInstance.getPropertyCount() == 1); assert(newInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(newInstance.findProperty("blob") == PEG_NOT_FOUND); assert(newInstance.findProperty("message") == PEG_NOT_FOUND); assert(newInstance.getQualifierCount() == 0); } /////////////////////////////////////////////////////////////////////// // // Instance Filtering function tests // /////////////////////////////////////////////////////////////////////// // build instance as starting point for tests. CIMInstance tstInstance = class1.buildInstance(true, true, CIMPropertyList()); // // Test complete copy, no change // { if (verbose) { cout << "Test1" << endl; } CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, CIMPropertyList()); assert(tstInstance.identical(filterInstance)); assert(filterInstance.getPropertyCount() == 3); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to one property, ratio // { if (verbose) { cout << "Test2" << endl; } Array<CIMName> pl1Array; pl1Array.append("ratio"); CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, pl1); if (verbose) { XmlWriter::printInstanceElement(filterInstance); } assert(filterInstance.getPropertyCount() == 1); assert(filterInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(_propertyIdentical("ratio", filterInstance, tstInstance)); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to one property, message // { if (verbose) { cout << "Test3" << endl; } Array<CIMName> pl1Array; pl1Array.append("message"); CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, pl1); if (verbose) { XmlWriter::printInstanceElement(filterInstance); } assert(filterInstance.getPropertyCount() == 1); assert(filterInstance.findProperty("message") != PEG_NOT_FOUND); assert(_propertyIdentical("message", filterInstance, tstInstance)); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to one property, count // { if (verbose) { cout << "Test4" << endl; } Array<CIMName> pl1Array; pl1Array.append("count"); CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, pl1); if (verbose) { XmlWriter::printInstanceElement(filterInstance); } assert(filterInstance.getPropertyCount() == 1); assert(filterInstance.findProperty("count") != PEG_NOT_FOUND); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to no properties // { if (verbose) { cout << "Test5a" << endl; } Array<CIMName> pl1Array; CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, pl1); assert(filterInstance.getPropertyCount() == 0); assert(filterInstance.findProperty("ratio") == PEG_NOT_FOUND); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to two properties // { if (verbose) { cout << "Test5b" << endl; } Array<CIMName> pl1Array; pl1Array.append("count"); pl1Array.append("message"); CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(true, true, pl1); assert(filterInstance.getPropertyCount() == 2); assert(filterInstance.findProperty("ratio") == PEG_NOT_FOUND); assert(filterInstance.findProperty("message") != PEG_NOT_FOUND); assert(_propertyIdentical("message", filterInstance, tstInstance)); assert(filterInstance.findProperty("count") != PEG_NOT_FOUND); assert(_propertyIdentical("count", filterInstance, tstInstance)); assert(filterInstance.getQualifierCount() == tstInstance.getQualifierCount()); } // // Filter to no qualifiers and all properties. // { if (verbose) { cout << "Test6" << endl; } CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(false, true, CIMPropertyList()); assert(filterInstance.getPropertyCount() == 3); assert(filterInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(filterInstance.getQualifierCount() == 0); for (Uint32 i = 0; i < filterInstance.getPropertyCount() ; i++) { CIMConstProperty p = filterInstance.getProperty(i); assert(p.getQualifierCount() == 0); } } // // Filter to no qualifiers and no properties. // { if (verbose) { cout << "Test6a" << endl; } Array<CIMName> pl1Array; CIMPropertyList pl1(pl1Array); CIMInstance filterInstance = tstInstance.clone(); filterInstance.filter(false, true, pl1); assert(filterInstance.getPropertyCount() == 0); assert(filterInstance.findProperty("ratio") == PEG_NOT_FOUND); assert(filterInstance.getQualifierCount() == 0); } // // Test Class Origin Filter // { if (verbose) { cout << "Test7 Class Origin" << endl; } // Create a subclass to do classOrigin testing CIMClass mySubClass(CIMName("subclass")); mySubClass.setSuperClassName(CIMName("MyClass")); Resolver::resolveClass(mySubClass, context, NAMESPACE); context->addClass(NAMESPACE, mySubClass); // build instance CIMInstance filterInstance = mySubClass.buildInstance(true, true, CIMPropertyList()); filterInstance.filter(false, true, CIMPropertyList()); assert(filterInstance.getPropertyCount() == 3); assert(filterInstance.findProperty("ratio") != PEG_NOT_FOUND); assert(filterInstance.getQualifierCount() == 0); for (Uint32 i = 0 ; i < filterInstance.getPropertyCount() ; i++) { CIMProperty p = filterInstance.getProperty(i); assert(!(p.getClassOrigin() == CIMName())); } filterInstance.filter(false, false, CIMPropertyList()); for (Uint32 i = 0 ; i < filterInstance.getPropertyCount() ; i++) { CIMProperty p = filterInstance.getProperty(i); assert(p.getClassOrigin() == CIMName()); } CIMInstance filterInstance2 = mySubClass.buildInstance(true, false, CIMPropertyList()); for (Uint32 i = 0 ; i < filterInstance2.getPropertyCount() ; i++) { CIMProperty p = filterInstance2.getProperty(i); assert(p.getClassOrigin() == CIMName()); } } delete context; }