1 karl 1.21 //%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.21 // 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.6 // 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 karl 1.25 //
|
21 kumpf 1.6 // 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.6 // 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 kumpf 1.8 #include <Pegasus/Common/InternalException.h>
|
36 mike 1.4 #include <Pegasus/Common/FileSystem.h>
37 #include <Pegasus/Common/Exception.h>
|
38 kumpf 1.31 #include <Pegasus/Common/CIMNameCast.h>
|
39 mike 1.4 #include "AssocClassTable.h"
40
41 PEGASUS_USING_STD;
42
43 PEGASUS_NAMESPACE_BEGIN
44
45 static inline Boolean _MatchNoCase(const String& x, const String& pattern)
46 {
47 return pattern.size() == 0 || String::equalNoCase(x, pattern);
48 }
49
|
50 kumpf 1.29 static Boolean _GetRecord(ifstream& is, ClassAssociation& record)
|
51 karl 1.11 {
|
52 kumpf 1.29 String line;
|
53 karl 1.11
|
54 kumpf 1.29 if (!GetLine(is, line))
55 return false;
|
56 mike 1.30 record.assocClassName = CIMNameCast(line);
|
57 karl 1.11
|
58 kumpf 1.29 if (!GetLine(is, line))
59 return false;
|
60 mike 1.30 record.fromClassName = CIMNameCast(line);
|
61 karl 1.11
|
62 kumpf 1.29 if (!GetLine(is, line))
63 return false;
|
64 mike 1.30 record.fromPropertyName = CIMNameCast(line);
|
65 mike 1.4
|
66 kumpf 1.29 if (!GetLine(is, line))
67 return false;
|
68 mike 1.30 record.toClassName = CIMNameCast(line);
|
69 mike 1.4
|
70 kumpf 1.29 if (!GetLine(is, line))
71 return false;
|
72 mike 1.30 record.toPropertyName = CIMNameCast(line);
|
73 mike 1.4
74 // Skip the blank line:
75
76 if (!GetLine(is, line))
|
77 kumpf 1.24 return false;
|
78 mike 1.4
79 return true;
80 }
81
|
82 kumpf 1.29 static inline void _PutField(ofstream& os, const CIMName& field)
|
83 mike 1.4 {
|
84 kumpf 1.29 // Write the field in UTF-8. Call write() to ensure no data
85 // conversion by the stream. Since all the fields contain CIM names,
86 // it is not necessary to escape CR/LF characters.
87 CString buffer = field.getString().getCString();
88 os.write((const char *)buffer,
89 static_cast<streamsize>(strlen((const char *)buffer)));
90 os << endl;
91 }
92
93 static void _PutRecord(ofstream& os, const ClassAssociation& record)
94 {
95 _PutField(os, record.assocClassName);
96 _PutField(os, record.fromClassName);
97 _PutField(os, record.fromPropertyName);
98 _PutField(os, record.toClassName);
99 _PutField(os, record.toPropertyName);
|
100 mike 1.4 os << endl;
101 }
102
103 void AssocClassTable::append(
104 PEGASUS_STD(ofstream)& os,
|
105 r.kieninger 1.19 const String& path,
|
106 kumpf 1.29 const ClassAssociation& classAssociation)
|
107 mike 1.4 {
|
108 kumpf 1.29 _PutRecord(os, classAssociation);
|
109 r.kieninger 1.19
110 // Update cache
|
111 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
112 if (cache->isActive())
|
113 r.kieninger 1.19 {
|
114 kumpf 1.29 cache->addRecord(classAssociation.fromClassName, classAssociation);
|
115 r.kieninger 1.19 }
|
116 mike 1.4 }
117
118 void AssocClassTable::append(
119 const String& path,
|
120 kumpf 1.29 const ClassAssociation& classAssociation)
|
121 mike 1.4 {
122 // Open input file:
|
123 david.dillard 1.18
|
124 mike 1.4 ofstream os;
125
126 if (!OpenAppend(os, path))
|
127 kumpf 1.24 throw CannotOpenFile(path);
|
128 mike 1.4
|
129 kumpf 1.29 _PutRecord(os, classAssociation);
|
130 r.kieninger 1.19
131 // Update cache
|
132 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
133 if (cache->isActive())
|
134 r.kieninger 1.19 {
|
135 kumpf 1.29 cache->addRecord(classAssociation.fromClassName, classAssociation);
|
136 r.kieninger 1.19 }
|
137 mike 1.4 }
138
139 Boolean AssocClassTable::deleteAssociation(
140 const String& path,
|
141 kumpf 1.10 const CIMName& assocClassName)
|
142 mike 1.4 {
143 // Open input file:
144
145 ifstream is;
|
146 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
147 {
148 return false;
149 }
|
150 mike 1.4
151 if (!Open(is, path))
|
152 dmitry.mikulin 1.27 {
153 throw CannotOpenFile(path);
154 }
|
155 mike 1.4
156 // Open output file:
157
158 String tmpPath = path + ".tmp";
159 ofstream os;
160 if (!Open(os, tmpPath))
|
161 dmitry.mikulin 1.27 {
|
162 kumpf 1.24 throw CannotOpenFile(tmpPath);
|
163 dmitry.mikulin 1.27 }
|
164 mike 1.4
165 // Copy over all lines except ones with the given association instance name:
166
|
167 kumpf 1.29 ClassAssociation classAssociation;
|
168 kumpf 1.32 Array<ClassAssociation> classAssociationsToDelete;
|
169 mike 1.4
|
170 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
171 mike 1.4 {
|
172 kumpf 1.29 if (assocClassName.getString() != classAssociation.assocClassName)
|
173 kumpf 1.24 {
|
174 kumpf 1.29 _PutRecord(os, classAssociation);
|
175 kumpf 1.24 }
|
176 r.kieninger 1.19 else
177 {
|
178 kumpf 1.32 classAssociationsToDelete.append(classAssociation);
|
179 r.kieninger 1.19 }
|
180 mike 1.4 }
181
182 // Close both files:
183
184 is.close();
185 os.close();
186
187 // Rename back to original name:
188
189 if (!FileSystem::renameFile(tmpPath, path))
|
190 kumpf 1.24 throw CannotRenameFile(path);
|
191 mike 1.4
|
192 r.kieninger 1.19
193 // Update cache
|
194 kumpf 1.32 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
195 for (Uint32 i = 0; i < classAssociationsToDelete.size(); i++)
|
196 r.kieninger 1.19 {
|
197 kumpf 1.29 if (cache->isActive())
|
198 r.kieninger 1.19 {
|
199 kumpf 1.32 cache->removeRecord(
200 classAssociationsToDelete[i].fromClassName,
201 classAssociationsToDelete[i].assocClassName);
|
202 r.kieninger 1.19 }
203 }
204
|
205 kumpf 1.32 return classAssociationsToDelete.size();
|
206 mike 1.4 }
207
208 Boolean AssocClassTable::getAssociatorNames(
209 const String& path,
|
210 kumpf 1.13 const Array<CIMName>& classList,
211 const Array<CIMName>& assocClassList,
212 const Array<CIMName>& resultClassList,
|
213 mike 1.4 const String& role,
214 const String& resultRole,
215 Array<String>& associatorNames)
216 {
217 // Open input file:
218 ifstream is;
|
219 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
220 {
221 return false;
222 }
|
223 mike 1.4
224 if (!Open(is, path))
|
225 dmitry.mikulin 1.27 {
226 throw CannotOpenFile(path);
227 }
|
228 mike 1.4
|
229 kumpf 1.29 ClassAssociation classAssociation;
|
230 mike 1.4 Boolean found = false;
231
|
232 kumpf 1.13 // For each line in the associations table:
|
233 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
234 mike 1.4 {
|
235 kumpf 1.13 // Process associations from the right end class and with right roles
|
236 kumpf 1.29 if (Contains(classList, classAssociation.fromClassName) &&
237 _MatchNoCase(classAssociation.fromPropertyName.getString(), role) &&
238 _MatchNoCase(
239 classAssociation.toPropertyName.getString(), resultRole))
|
240 kumpf 1.13 {
241 // Skip classes that do not appear in the association class list
242 if ((assocClassList.size() != 0) &&
|
243 kumpf 1.29 (!Contains(assocClassList, classAssociation.assocClassName)))
|
244 kumpf 1.13 {
245 continue;
246 }
247
248 // Skip classes that do not appear in the result class list
249 if ((resultClassList.size() != 0) &&
|
250 kumpf 1.29 (!Contains(resultClassList, classAssociation.toClassName)))
|
251 kumpf 1.13 {
252 continue;
253 }
254
255 // This class qualifies; add it to the list (skipping duplicates)
|
256 kumpf 1.29 if (!Contains(
257 associatorNames, classAssociation.toClassName.getString()))
|
258 kumpf 1.13 {
|
259 kumpf 1.29 associatorNames.append(
260 classAssociation.toClassName.getString());
|
261 kumpf 1.13 }
262 found = true;
263 }
|
264 mike 1.4 }
265
266 return found;
267 }
268
|
269 kumpf 1.24 Boolean AssocClassTable::_InitializeCache(
270 AssocClassCache* cache,
271 const String& path)
|
272 r.kieninger 1.19 {
273 if (!cache->isActive())
274 {
275
276 // Open input file:
277 ifstream is;
|
278 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
279 {
280 return false;
281 }
|
282 r.kieninger 1.19
283 if (!Open(is, path))
|
284 dmitry.mikulin 1.27 {
285 throw CannotOpenFile(path);
286 }
|
287 r.kieninger 1.19
|
288 kumpf 1.29 ClassAssociation classAssociation;
|
289 r.kieninger 1.19
290 // For each line in the associations table:
|
291 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
292 r.kieninger 1.19 {
|
293 kumpf 1.29 cache->addRecord(classAssociation.fromClassName,
294 classAssociation);
|
295 r.kieninger 1.19 }
296
297 cache->setActive(true);
298 }
299
300 return true;
301 }
302
|
303 mike 1.4 Boolean AssocClassTable::getReferenceNames(
304 const String& path,
|
305 karl 1.11 const Array<CIMName>& classList,
|
306 kumpf 1.13 const Array<CIMName>& resultClassList,
|
307 mike 1.4 const String& role,
308 Array<String>& referenceNames)
309 {
|
310 kumpf 1.33 // Get the information from the association class cache.
|
311 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
|
312 mike 1.4
|
313 r.kieninger 1.19 if (!cache->isActive())
314 {
315 if (!_InitializeCache(cache,path))
316 return false;
317 }
318
|
319 kumpf 1.33 return cache->getReferenceNames(
320 classList, resultClassList, role, referenceNames);
|
321 mike 1.4 }
322
323 PEGASUS_NAMESPACE_END
|