1 karl 1.19 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.4 //
|
3 karl 1.15 // 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 karl 1.14 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.15 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.16 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.19 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.4 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.7 // 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 mike 1.4 // 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 kumpf 1.7 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.4 // 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 kumpf 1.7 // 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 mike 1.4 // 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 mike 1.5 #include <Pegasus/Common/Config.h>
|
35 mike 1.4 #include <fstream>
|
36 kumpf 1.9 #include <Pegasus/Common/InternalException.h>
|
37 mike 1.4 #include <Pegasus/Common/FileSystem.h>
38 #include <Pegasus/Common/Exception.h>
39 #include "AssocInstTable.h"
40
41 PEGASUS_USING_STD;
42
43 PEGASUS_NAMESPACE_BEGIN
44
45 #define ASSOC_INSTANCE_NAME_INDEX 0
46 #define ASSOC_CLASS_NAME_INDEX 1
47 #define FROM_OBJECT_NAME_INDEX 2
48 #define FROM_CLASS_NAME_INDEX 3
49 #define FROM_PROPERTY_NAME_INDEX 4
50 #define TO_OBJECT_NAME_INDEX 5
|
51 kumpf 1.20 #define TO_CLASS_NAME_INDEX 6
|
52 mike 1.4 #define TO_PROPERTY_NAME_INDEX 7
53 #define NUM_FIELDS 8
54
55 static inline Boolean _MatchNoCase(const String& x, const String& pattern)
56 {
57 return pattern.size() == 0 || String::equalNoCase(x, pattern);
58 }
59
|
60 kumpf 1.20 static inline Boolean _ContainsClass(
61 const Array<CIMName>& classNames,
62 const String& match)
|
63 kumpf 1.13 {
64 Uint32 n = classNames.size();
65
66 for (Uint32 i = 0; i < n; i++)
67 {
68 if (_MatchNoCase(classNames[i].getString(), match))
69 return true;
70 }
71
72 return false;
73 }
74
|
75 mike 1.4 static String _Escape(const String& str)
76 {
77 String result;
78
79 for (Uint32 i = 0, n = str.size(); i < n; i++)
80 {
|
81 kumpf 1.20 Char16 c = str[i];
|
82 mike 1.4
|
83 kumpf 1.20 switch (c)
84 {
85 case '\n':
86 result.append("\\n");
87 break;
88
89 case '\r':
90 result.append("\\r");
91 break;
92
93 case '\t':
94 result.append("\\t");
95 break;
96
97 case '\f':
98 result.append("\\f");
99 break;
100
101 case '\\':
102 result.append("\\\\");
103 break;
104 kumpf 1.20
105 default:
106 result.append(c);
107 }
|
108 mike 1.4 }
109
110 return result;
111 }
112
113 static String _Unescape(const String& str)
114 {
115 String result;
116
117 for (Uint32 i = 0, n = str.size(); i < n; i++)
118 {
|
119 kumpf 1.20 Char16 c = str[i];
|
120 mike 1.4
|
121 kumpf 1.20 if (c == '\\')
122 {
123 if (i + 1 == n)
124 break;
125
126 c = str[i + 1];
127
128 switch (c)
129 {
130 case 'n':
131 result.append("\n");
132 break;
133
134 case 'r':
135 result.append("\r");
136 break;
137
138 case 't':
139 result.append("\t");
140 break;
141
142 kumpf 1.20 case 'f':
143 result.append("\f");
144 break;
145
146 default:
147 result.append(c);
148 }
149
150 i++;
151 }
152 else
153 result.append(c);
|
154 mike 1.4 }
155
156 return result;
157 }
158
159 static Boolean _GetRecord(ifstream& is, Array<String>& fields)
160 {
161 fields.clear();
162 String line;
163
164 for (Uint32 i = 0; i < NUM_FIELDS; i++)
165 {
|
166 kumpf 1.20 if (!GetLine(is, line))
167 return false;
|
168 mike 1.4
|
169 kumpf 1.20 fields.append(_Unescape(line));
|
170 mike 1.4 }
171
172 // Skip the blank line:
173
174 if (!GetLine(is, line))
|
175 kumpf 1.20 return false;
|
176 mike 1.4
177 return true;
178 }
179
180 static void _PutRecord(ofstream& os, Array<String>& fields)
181 {
182 for (Uint32 i = 0, n = fields.size(); i < n; i++)
|
183 chuck 1.17 {
184 // Calling getCString to ensure utf-8 goes to the file
185 // Calling write to ensure no data conversion by the stream
|
186 kumpf 1.20 CString buffer = _Escape(fields[i]).getCString();
|
187 kumpf 1.18 os.write((const char *)buffer,
188 static_cast<streamsize>(strlen((const char *)buffer)));
|
189 chuck 1.17 os << endl;
190 }
|
191 mike 1.4 os << endl;
192 }
193
194 void AssocInstTable::append(
195 PEGASUS_STD(ofstream)& os,
196 const String& assocInstanceName,
|
197 kumpf 1.11 const CIMName& assocClassName,
|
198 mike 1.4 const String& fromInstanceName,
|
199 kumpf 1.11 const CIMName& fromClassName,
200 const CIMName& fromPropertyName,
|
201 mike 1.4 const String& toInstanceName,
|
202 kumpf 1.11 const CIMName& toClassName,
203 const CIMName& toPropertyName)
|
204 mike 1.4 {
205 Array<String> fields;
|
206 kumpf 1.8 fields.reserveCapacity(8);
|
207 mike 1.4 fields.append(assocInstanceName);
|
208 kumpf 1.11 fields.append(assocClassName.getString());
|
209 mike 1.4 fields.append(fromInstanceName);
|
210 kumpf 1.11 fields.append(fromClassName.getString());
211 fields.append(fromPropertyName.getString());
|
212 mike 1.4 fields.append(toInstanceName);
|
213 kumpf 1.11 fields.append(toClassName.getString());
214 fields.append(toPropertyName.getString());
|
215 mike 1.4
216 _PutRecord(os, fields);
217 }
218
219 void AssocInstTable::append(
220 const String& path,
221 const String& assocInstanceName,
|
222 kumpf 1.11 const CIMName& assocClassName,
|
223 mike 1.4 const String& fromInstanceName,
|
224 kumpf 1.11 const CIMName& fromClassName,
225 const CIMName& fromPropertyName,
|
226 mike 1.4 const String& toInstanceName,
|
227 kumpf 1.11 const CIMName& toClassName,
228 const CIMName& toPropertyName)
|
229 mike 1.4 {
230 // Open input file:
|
231 kumpf 1.20
|
232 mike 1.4 ofstream os;
233
234 if (!OpenAppend(os, path))
|
235 kumpf 1.20 throw CannotOpenFile(path);
|
236 mike 1.4
237 // Insert the entry:
238
239 Array<String> fields;
|
240 kumpf 1.8 fields.reserveCapacity(8);
|
241 mike 1.4 fields.append(assocInstanceName);
|
242 kumpf 1.11 fields.append(assocClassName.getString());
|
243 mike 1.4 fields.append(fromInstanceName);
|
244 kumpf 1.11 fields.append(fromClassName.getString());
245 fields.append(fromPropertyName.getString());
|
246 mike 1.4 fields.append(toInstanceName);
|
247 kumpf 1.11 fields.append(toClassName.getString());
248 fields.append(toPropertyName.getString());
|
249 mike 1.4
250 _PutRecord(os, fields);
251 }
252
253 Boolean AssocInstTable::deleteAssociation(
254 const String& path,
|
255 kumpf 1.6 const CIMObjectPath& assocInstanceName)
|
256 mike 1.4 {
257 // Open input file:
258
259 ifstream is;
260
261 if (!Open(is, path))
|
262 kumpf 1.20 return false;
|
263 mike 1.4
264 // Open output file:
265
266 String tmpPath = path + ".tmp";
267 ofstream os;
268
269 if (!Open(os, tmpPath))
|
270 kumpf 1.20 throw CannotOpenFile(tmpPath);
|
271 mike 1.4
272 // Copy over all lines except ones with the given association instance name:
273
274 Array<String> fields;
275 Boolean found = false;
276
277 while (_GetRecord(is, fields))
278 {
|
279 kumpf 1.20 if (assocInstanceName != fields[ASSOC_INSTANCE_NAME_INDEX])
280 {
281 _PutRecord(os, fields);
282 found = true;
283 }
|
284 mike 1.4 }
285
286 // Close both files:
287
288 is.close();
289 os.close();
290
291 // Remove orginal file:
292
293 if (!FileSystem::removeFile(path))
|
294 kumpf 1.20 throw CannotRemoveFile(path);
|
295 mike 1.4
296 // Rename back to original name:
297
298 if (!FileSystem::renameFile(tmpPath, path))
|
299 kumpf 1.20 throw CannotRenameFile(path);
|
300 mike 1.4
301 return found;
302 }
303
304 Boolean AssocInstTable::getAssociatorNames(
305 const String& path,
|
306 kumpf 1.6 const CIMObjectPath& instanceName,
|
307 kumpf 1.13 const Array<CIMName>& assocClassList,
308 const Array<CIMName>& resultClassList,
|
309 mike 1.4 const String& role,
310 const String& resultRole,
311 Array<String>& associatorNames)
312 {
313 // Open input file:
314 ifstream is;
315
316 if (!Open(is, path))
|
317 kumpf 1.20 return false;
|
318 mike 1.4
319 Array<String> fields;
320 Boolean found = false;
321
|
322 kumpf 1.13 // For each line in the associations table:
|
323 mike 1.4 while (_GetRecord(is, fields))
324 {
|
325 kumpf 1.13 // Process associations from the right end object and with right roles
|
326 kumpf 1.20 if (instanceName == fields[FROM_OBJECT_NAME_INDEX] &&
327 _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role) &&
328 _MatchNoCase(fields[TO_PROPERTY_NAME_INDEX], resultRole))
329 {
|
330 kumpf 1.13 // Skip classes that do not appear in the association class list
331 if ((assocClassList.size() != 0) &&
332 (!_ContainsClass(assocClassList,
333 fields[ASSOC_CLASS_NAME_INDEX])))
334 {
335 continue;
336 }
337
338 // Skip classes that do not appear in the result class list
339 if ((resultClassList.size() != 0) &&
340 (!_ContainsClass(resultClassList,
341 fields[TO_CLASS_NAME_INDEX])))
342 {
343 continue;
344 }
345
346 // This class qualifies; add it to the list (skipping duplicates)
347 if (!Contains(associatorNames, fields[TO_OBJECT_NAME_INDEX]))
348 {
|
349 kumpf 1.20 associatorNames.append(fields[TO_OBJECT_NAME_INDEX]);
|
350 kumpf 1.13 }
|
351 kumpf 1.20 found = true;
352 }
|
353 mike 1.4 }
354
355 return found;
356 }
357
358 Boolean AssocInstTable::getReferenceNames(
359 const String& path,
|
360 kumpf 1.6 const CIMObjectPath& instanceName,
|
361 kumpf 1.13 const Array<CIMName>& resultClassList,
|
362 mike 1.4 const String& role,
363 Array<String>& referenceNames)
364 {
365 // Open input file:
366 ifstream is;
367
368 if (!Open(is, path))
|
369 kumpf 1.20 return false;
370
|
371 mike 1.4 Array<String> fields;
372 Boolean found = false;
373
|
374 kumpf 1.13 // For each line in the associations table:
|
375 mike 1.4 while (_GetRecord(is, fields))
376 {
|
377 kumpf 1.13 // Process associations from the right end class and with right role
|
378 kumpf 1.20 if (instanceName == fields[FROM_OBJECT_NAME_INDEX] &&
379 _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role))
380 {
|
381 kumpf 1.13 // Skip classes that do not appear in the result class list
382 if ((resultClassList.size() != 0) &&
383 (!_ContainsClass(resultClassList,
384 fields[ASSOC_CLASS_NAME_INDEX])))
385 {
386 continue;
387 }
388
389 // This instance qualifies; add it to the list (skipping duplicates)
|
390 kumpf 1.20 if (!Contains(referenceNames, fields[ASSOC_INSTANCE_NAME_INDEX]))
|
391 kumpf 1.13 {
|
392 kumpf 1.20 referenceNames.append(fields[ASSOC_INSTANCE_NAME_INDEX]);
|
393 kumpf 1.13 }
|
394 kumpf 1.20 found = true;
395 }
|
396 mike 1.4 }
397
398 return found;
399 }
400
401 PEGASUS_NAMESPACE_END
|