BUG#: 5840
[tpot/pegasus/.git] / src / Pegasus / Common / CIMInstanceRep.cpp
1 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 // 
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "CIMInstanceRep.h"
35 #include "CIMInstance.h"
36 #include "CIMClassRep.h"
37 #include "CIMScope.h"
38 #include "DeclContext.h"
39 #include "Resolver.h"
40 #include "Indentor.h"
41 #include "CIMName.h"
42 #include "Constants.h"
43 #include "XmlWriter.h"
44 #include "MofWriter.h"
45 #include "StrLit.h"
46
47 PEGASUS_USING_STD;
48
49 PEGASUS_NAMESPACE_BEGIN
50
51 CIMInstanceRep::CIMInstanceRep(const CIMObjectPath& reference)
52     : CIMObjectRep(reference)
53 {
54
55 }
56
57 CIMInstanceRep::~CIMInstanceRep()
58 {
59
60 }
61
62 void CIMInstanceRep::resolve(
63     DeclContext* context,
64     const CIMNamespaceName& nameSpace,
65     CIMConstClass& cimClassOut,
66     Boolean propagateQualifiers)
67 {
68     // ATTN: Verify that references are initialized.
69
70 #if 0
71     if (_resolved)
72         throw InstanceAlreadyResolved();
73 #endif
74
75     if (!context)
76         throw NullPointer();
77
78     //----------------------------------------------------------------------
79     // First obtain the class:
80     //----------------------------------------------------------------------
81
82     CIMConstClass cimClass =
83         context->lookupClass(nameSpace, _reference.getClassName());
84
85     if (cimClass.isUninitialized())
86         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_CLASS,
87             _reference.getClassName().getString ());
88
89     cimClassOut = cimClass;
90
91 #if 0
92     if (!cimClass._rep->_resolved)
93         throw ClassNotResolved(_reference.getClassName());
94 #endif
95
96     //----------------------------------------------------------------------
97     // Disallow instantiation of abstract classes.
98     //----------------------------------------------------------------------
99
100     if (cimClass.isAbstract())
101         throw InstantiatedAbstractClass(_reference.getClassName().getString ());
102
103     //----------------------------------------------------------------------
104     // Validate and propagate qualifiers.
105     //----------------------------------------------------------------------
106     _qualifiers.resolve(
107         context,
108         nameSpace,
109         (cimClass.isAssociation()) ? CIMScope::ASSOCIATION : CIMScope::CLASS,
110         false,
111         cimClass._rep->_qualifiers,
112         propagateQualifiers);
113
114     //----------------------------------------------------------------------
115     // First iterate the properties of this instance and verify that
116     // each one is defined in the class and then resolve each one.
117     //----------------------------------------------------------------------
118
119     CIMName className = cimClass.getClassName();
120
121     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
122     {
123         CIMProperty& property = _properties[i];
124
125         Uint32 index = cimClass.findProperty(property.getName());
126
127         if (index == PEG_NOT_FOUND)
128         {
129             //
130             //  Allow addition of Creator property to Indication Subscription,
131             //  Filter and Handler instances
132             //
133 // l10n add language property support
134             if (!(((className.equal
135                     (CIMName (PEGASUS_CLASSNAME_INDSUBSCRIPTION))) ||
136                 (className.equal
137                     (CIMName (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))) ||
138                 (className.equal
139                     (CIMName (PEGASUS_CLASSNAME_INDHANDLER_CIMXML))) ||
140                 (className.equal
141                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_CIMXML))) ||
142                 (className.equal
143                     (CIMName (PEGASUS_CLASSNAME_INDHANDLER_SNMP))) ||
144 #ifdef  PEGASUS_ENABLE_SYSTEM_LOG_HANDLER
145                 (className.equal
146                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG))) ||
147 #endif
148 #ifdef  PEGASUS_ENABLE_EMAIL_HANDLER
149                 (className.equal
150                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))) ||
151 #endif
152                 (className.equal (CIMName (PEGASUS_CLASSNAME_INDFILTER)))) &&
153                 ((property.getName ().equal
154                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CREATOR))) ||
155                 (property.getName ().equal
156                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS))) ||
157                 (property.getName ().equal
158                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS))))))
159             {
160                 throw NoSuchProperty(property.getName().getString ());
161             }
162         }
163         else
164         {
165             // resolve the property
166             Resolver::resolveProperty (property, context, nameSpace, true,
167                 cimClass.getProperty (index), propagateQualifiers);
168         // Ensure that the PROPAGATED attribute is false
169         property.setPropagated(false);
170         }
171     }
172
173     //----------------------------------------------------------------------
174     // Inject all properties from the class that are not included in the
175     // instance. Copy over the class-origin and set the propagated flag
176     // to true. NOTE: The propagated flag indicates that the property
177     // was not part of the property set input with the create and
178     // was inherited from the default in the class (see cimxml spec sect 3.1.5)
179     //----------------------------------------------------------------------
180
181     for (Uint32 i = 0, m = 0, n = cimClass.getPropertyCount(); i < n; i++)
182     {
183         CIMConstProperty property = cimClass.getProperty(i);
184         const CIMName& name = property.getName();
185
186         // See if this instance already contains a property with this name:
187
188         Boolean found = false;
189
190         for (Uint32 j = m, n = _properties.size(); j < n; j++)
191         {
192             if (name.equal(_properties[j].getName()))
193             {
194                 found = true;
195                 break;
196             }
197         }
198
199         if (!found)
200         {
201             CIMProperty p = property.clone();
202             p.setPropagated(true);
203             _properties.insert(m++, p);
204         }
205     }
206
207 #if 0
208     _resolved = true;
209 #endif
210 }
211
212 CIMInstanceRep::CIMInstanceRep()
213 {
214
215 }
216
217 CIMInstanceRep::CIMInstanceRep(const CIMInstanceRep& x) : CIMObjectRep(x)
218 {
219
220 }
221
222 void CIMInstanceRep::toXml(Buffer& out) const
223 {
224     // Class opening element:
225
226     out << STRLIT("<INSTANCE ");
227     out << STRLIT(" CLASSNAME=\"") << _reference.getClassName();
228     out << STRLIT("\" ");
229     out << STRLIT(">\n");
230
231     // Qualifiers:
232
233     _qualifiers.toXml(out);
234
235     // Parameters:
236
237     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
238         XmlWriter::appendPropertyElement(out, _properties[i]);
239
240     // Class closing element:
241
242     out << STRLIT("</INSTANCE>\n");
243 }
244
245 void CIMInstanceRep::toMof(Buffer& out) const
246 {
247     // Get and format the class qualifiers
248     out << STRLIT("\n//Instance of ") << _reference.getClassName();
249     if (_qualifiers.getCount())
250         out.append('\n');
251     _qualifiers.toMof(out);
252
253     // Separate qualifiers from Class Name
254     out.append('\n');
255
256     // output class statement
257     out << STRLIT("instance of ") << _reference.getClassName();
258
259     out << STRLIT("\n{");
260
261     // format the Properties:
262     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
263     {
264         // Generate MOF if this property not propagated
265         // Note that the test is required only because
266         // there is an error in getclass that does not
267         // test the localOnly flag.
268         // The false identifies this as value initializer, not
269         // property definition.
270         if (!_properties[i].getPropagated())
271             MofWriter::appendPropertyElement(false,out, _properties[i]);
272     }
273
274     // Class closing element:
275     out << STRLIT("\n};\n");
276 }
277
278 CIMObjectPath CIMInstanceRep::buildPath(
279     const CIMConstClass& cimClass) const
280 {
281     //--------------------------------------------------------------------------
282     // Get class name:
283     //--------------------------------------------------------------------------
284
285     CIMName className = getClassName();
286
287     //--------------------------------------------------------------------------
288     // Get key names:
289     //--------------------------------------------------------------------------
290
291     Array<CIMName> keyNames;
292     cimClass.getKeyNames(keyNames);
293
294     if (keyNames.size() == 0)
295         return CIMObjectPath("", CIMNamespaceName(), className);
296
297     //--------------------------------------------------------------------------
298     // Get type and value for each key (building up key bindings):
299     //--------------------------------------------------------------------------
300
301     Array<CIMKeyBinding> keyBindings;
302
303     for (Uint32 i = 0, n = keyNames.size(); i < n; i++)
304     {
305         const CIMName& keyName = keyNames[i];
306
307         Uint32 index = findProperty(keyName);
308         if (index == PEG_NOT_FOUND)
309         {
310             throw NoSuchProperty(keyName.getString());
311         }
312
313         CIMConstProperty tmp = getProperty(index);
314
315         if (keyName.equal(tmp.getName()))
316         {
317             keyBindings.append(CIMKeyBinding(keyName, tmp.getValue()));
318         }
319     }
320
321     return CIMObjectPath(String(), CIMNamespaceName(), className, keyBindings);
322 }
323
324 // KS Mar 05 - The following removal functions are very inefficient and should
325 // be optimized to avoid the multiple memory moves.  Actually, the remove
326 // qualifiers should be added as a function and optimized that once.
327 void CIMInstanceRep::filter(
328     Boolean includeQualifiers,
329     Boolean includeClassOrigin,
330     const CIMPropertyList& propertyList)
331 {
332     // Filter any qualifiers from this instance.
333     if (!includeQualifiers && _qualifiers.getCount() > 0)
334     {
335         while (_qualifiers.getCount())
336         {
337             _qualifiers.removeQualifier(0);
338         }
339     }
340
341     // For each property, remove if not in propertylist
342     for (Uint32 i = 0 ; i < _properties.size(); i++)
343     {
344         CIMConstProperty p = getProperty(i);
345         CIMName name = p.getName();
346         Array<CIMName> pl = propertyList.getPropertyNameArray();
347         if (propertyList.isNull() || Contains(pl, name))
348         {
349             // test ClassOrigin and possibly remove
350             if (!includeClassOrigin)
351             {
352                 _properties[i].setClassOrigin(CIMName());
353             }
354             // remove qualifiers if required.
355             if (!includeQualifiers && _properties[i].getQualifierCount() > 0)
356             {
357                 while (_properties[i].getQualifierCount() > 0)
358                 {
359                     _properties[i].removeQualifier(0);
360                 }
361             }
362         }
363         else
364         {
365             _properties.remove(i--);
366         }
367     }
368     return;
369 }
370
371 PEGASUS_NAMESPACE_END