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