BUG#: 4691
[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 // Author: Mike Brasher (mbrasher@bmc.com)
33 //
34 // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
35 //              Sushma Fernandes, Hewlett-Packard Company 
36 //              (sushma_fernandes@hp.com)
37 //              Carol Ann Krug Graves, Hewlett-Packard Company
38 //                  (carolann_graves@hp.com)
39 //              David Dillard, VERITAS Software Corp.
40 //                  (david.dillard@veritas.com)
41 //              Yi Zhou, Hewlett-Packard Company (yi.zhou@hp.com)
42 //
43 //%/////////////////////////////////////////////////////////////////////////////
44
45 #include "CIMInstanceRep.h"
46 #include "CIMInstance.h"
47 #include "CIMClassRep.h"
48 #include "CIMScope.h"
49 #include "DeclContext.h"
50 #include "Resolver.h"
51 #include "Indentor.h"
52 #include "CIMName.h"
53 #include "Constants.h"
54 #include "XmlWriter.h"
55 #include "MofWriter.h"
56 #include "StrLit.h"
57
58 PEGASUS_USING_STD;
59
60 PEGASUS_NAMESPACE_BEGIN
61
62 CIMInstanceRep::CIMInstanceRep(const CIMObjectPath& reference)
63     : CIMObjectRep(reference)
64 {
65
66 }
67
68 CIMInstanceRep::~CIMInstanceRep()
69 {
70
71 }
72
73 void CIMInstanceRep::resolve(
74     DeclContext* context,
75     const CIMNamespaceName& nameSpace,
76     CIMConstClass& cimClassOut,
77     Boolean propagateQualifiers)
78 {
79     // ATTN: Verify that references are initialized.
80
81 #if 0
82     if (_resolved)
83         throw InstanceAlreadyResolved();
84 #endif
85
86     if (!context)
87         throw NullPointer();
88
89     //----------------------------------------------------------------------
90     // First obtain the class:
91     //----------------------------------------------------------------------
92
93     CIMConstClass cimClass =
94         context->lookupClass(nameSpace, _reference.getClassName());
95
96     if (cimClass.isUninitialized())
97         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_CLASS, 
98             _reference.getClassName().getString ());
99
100     cimClassOut = cimClass;
101
102 #if 0
103     if (!cimClass._rep->_resolved)
104         throw ClassNotResolved(_reference.getClassName());
105 #endif
106
107     //----------------------------------------------------------------------
108     // Disallow instantiation of abstract classes.
109     //----------------------------------------------------------------------
110
111     if (cimClass.isAbstract())
112         throw InstantiatedAbstractClass(_reference.getClassName().getString ());
113
114     //----------------------------------------------------------------------
115     // Validate and propagate qualifiers.
116     //----------------------------------------------------------------------
117     _qualifiers.resolve(
118         context,
119         nameSpace,
120         (cimClass.isAssociation()) ? CIMScope::ASSOCIATION : CIMScope::CLASS,
121         false,
122         cimClass._rep->_qualifiers,
123         propagateQualifiers);
124
125     //----------------------------------------------------------------------
126     // First iterate the properties of this instance and verify that
127     // each one is defined in the class and then resolve each one.
128     //----------------------------------------------------------------------
129
130     CIMName className = cimClass.getClassName();
131
132     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
133     {
134         CIMProperty& property = _properties[i];
135
136         Uint32 index = cimClass.findProperty(property.getName());
137
138         if (index == PEG_NOT_FOUND)
139         {
140             //
141             //  Allow addition of Creator property to Indication Subscription,
142             //  Filter and Handler instances
143             //
144 // l10n add language property support           
145             if (!(((className.equal 
146                     (CIMName (PEGASUS_CLASSNAME_INDSUBSCRIPTION))) ||
147                 (className.equal 
148                     (CIMName (PEGASUS_CLASSNAME_FORMATTEDINDSUBSCRIPTION))) ||
149                 (className.equal 
150                     (CIMName (PEGASUS_CLASSNAME_INDHANDLER_CIMXML))) ||
151                                                                 (className.equal 
152                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_CIMXML))) ||
153                 (className.equal 
154                     (CIMName (PEGASUS_CLASSNAME_INDHANDLER_SNMP))) ||
155 #ifdef  PEGASUS_ENABLE_SYSTEM_LOG_HANDLER
156                 (className.equal 
157                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG))) ||
158 #endif
159 #ifdef  PEGASUS_ENABLE_EMAIL_HANDLER
160                 (className.equal 
161                     (CIMName (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))) ||
162 #endif
163                 (className.equal (CIMName (PEGASUS_CLASSNAME_INDFILTER)))) &&
164                 ((property.getName ().equal 
165                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CREATOR))) ||
166                 (property.getName ().equal 
167                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_ACCEPTLANGS))) ||
168                 (property.getName ().equal 
169                     (CIMName (PEGASUS_PROPERTYNAME_INDSUB_CONTENTLANGS))))))
170             {
171                 throw NoSuchProperty(property.getName().getString ());
172             }
173         }
174         else
175         {
176             // resolve the property
177             Resolver::resolveProperty (property, context, nameSpace, true, 
178                 cimClass.getProperty (index), propagateQualifiers);
179         // Ensure that the PROPAGATED attribute is false
180         property.setPropagated(false);
181         }
182     }
183
184     //----------------------------------------------------------------------
185     // Inject all properties from the class that are not included in the
186     // instance. Copy over the class-origin and set the propagated flag
187     // to true. NOTE: The propagated flag indicates that the property
188     // was not part of the property set input with the create and
189     // was inherited from the default in the class (see cimxml spec sect 3.1.5) 
190     //----------------------------------------------------------------------
191
192     for (Uint32 i = 0, m = 0, n = cimClass.getPropertyCount(); i < n; i++)
193     {
194         CIMConstProperty property = cimClass.getProperty(i);
195         const CIMName& name = property.getName();
196     
197         // See if this instance already contains a property with this name:
198     
199         Boolean found = false;
200     
201         for (Uint32 j = m, n = _properties.size(); j < n; j++)
202         {
203             if (name.equal(_properties[j].getName()))
204             {
205                         found = true;
206                         break;
207             }
208         }
209
210                 if (!found)
211                 {
212                         CIMProperty p = property.clone();
213                         p.setPropagated(true);
214                         _properties.insert(m++, p);
215                 }
216     }
217
218 #if 0
219     _resolved = true;
220 #endif
221 }
222
223 CIMInstanceRep::CIMInstanceRep()
224 {
225
226 }
227
228 CIMInstanceRep::CIMInstanceRep(const CIMInstanceRep& x) : CIMObjectRep(x)
229 {
230
231 }
232
233 void CIMInstanceRep::toXml(Buffer& out) const
234 {
235     // Class opening element:
236
237     out << STRLIT("<INSTANCE ");
238     out << STRLIT(" CLASSNAME=\"") << _reference.getClassName();
239     out << STRLIT("\" ");
240     out << STRLIT(">\n");
241
242     // Qualifiers:
243
244     _qualifiers.toXml(out);
245
246     // Parameters:
247
248     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
249         XmlWriter::appendPropertyElement(out, _properties[i]);
250
251     // Class closing element:
252
253     out << STRLIT("</INSTANCE>\n");
254 }
255
256 void CIMInstanceRep::toMof(Buffer& out) const
257 {
258     // Get and format the class qualifiers
259     out << STRLIT("\n//Instance of Class ") << _reference.getClassName();
260     if (_qualifiers.getCount())
261         out.append('\n');
262     _qualifiers.toMof(out);
263
264     // Separate qualifiers from Class Name
265     out.append('\n');
266
267     // output class statement
268     out << STRLIT("instance of class ") << _reference.getClassName();
269
270     out << STRLIT("\n{");
271
272     // format the Properties:
273     for (Uint32 i = 0, n = _properties.size(); i < n; i++)
274     {
275         // Generate MOF if this property not propagated
276         // Note that the test is required only because
277         // there is an error in getclass that does not
278         // test the localOnly flag.
279         if (!_properties[i].getPropagated())
280             MofWriter::appendPropertyElement(out, _properties[i]);
281     }
282
283     // Class closing element:
284     out << STRLIT("\n};\n");
285 }
286
287 CIMObjectPath CIMInstanceRep::buildPath(
288     const CIMConstClass& cimClass) const
289 {
290     //--------------------------------------------------------------------------
291     // Get class name:
292     //--------------------------------------------------------------------------
293
294     CIMName className = getClassName();
295
296     //--------------------------------------------------------------------------
297     // Get key names:
298     //--------------------------------------------------------------------------
299
300     Array<CIMName> keyNames;
301     cimClass.getKeyNames(keyNames);
302
303     if (keyNames.size() == 0)
304         return CIMObjectPath("", CIMNamespaceName(), className);
305
306     //--------------------------------------------------------------------------
307     // Get type and value for each key (building up key bindings):
308     //--------------------------------------------------------------------------
309
310     Array<CIMKeyBinding> keyBindings;
311
312     for (Uint32 i = 0, n = keyNames.size(); i < n; i++)
313     {
314         const CIMName& keyName = keyNames[i];
315
316         Uint32 index = findProperty(keyName);
317         if (index == PEG_NOT_FOUND)
318         {
319             throw NoSuchProperty(keyName.getString());
320         }
321
322         CIMConstProperty tmp = getProperty(index);
323
324         if (keyName.equal(tmp.getName()))
325         {
326             keyBindings.append(CIMKeyBinding(keyName, tmp.getValue()));
327         }
328     }
329
330     return CIMObjectPath(String(), CIMNamespaceName(), className, keyBindings);
331 }
332
333 // KS Mar 05 - The following removal functions are very inefficient and should
334 // be optimized to avoid the multiple memory moves.  Actually, the remove
335 // qualifiers should be added as a function and optimized that once.
336 void CIMInstanceRep::filter(Boolean includeQualifiers, Boolean includeClassOrigin,
337                         const CIMPropertyList& propertyList)
338 {
339     // Filter any qualifiers from this instance.
340     if (!includeQualifiers && _qualifiers.getCount() > 0)
341     {
342         while( _qualifiers.getCount() )
343         {
344             _qualifiers.removeQualifier(0);
345         }
346     }
347
348     // For each property, remove if not in propertylist
349     for (Uint32 i = 0 ; i < _properties.size(); i++)
350     {
351         CIMConstProperty p = getProperty(i);
352         CIMName name = p.getName();
353         Array<CIMName> pl = propertyList.getPropertyNameArray();
354         if (propertyList.isNull() || Contains(pl, name))
355         {
356             // test ClassOrigin and possibly remove
357             if (!includeClassOrigin)
358             {
359                 _properties[i].setClassOrigin(CIMName());
360             }
361             // remove qualifiers if required.
362             if (!includeQualifiers && _properties[i].getQualifierCount() > 0)
363             {
364                 while( _properties[i].getQualifierCount() > 0 )
365                 {
366                     _properties[i].removeQualifier(0);
367                 }
368             }
369         }
370         else
371         {
372             _properties.remove(i--);
373         }
374     }
375     return;
376 }
377
378 PEGASUS_NAMESPACE_END