1 martin 1.34 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.35 //
|
3 martin 1.34 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.35 //
|
10 martin 1.34 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.35 //
|
17 martin 1.34 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.35 //
|
20 martin 1.34 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.35 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.35 //
|
28 martin 1.34 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.4 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 mike 1.5 #include <Pegasus/Common/Config.h>
|
33 kumpf 1.8 #include <Pegasus/Common/InternalException.h>
|
34 mike 1.4 #include <Pegasus/Common/FileSystem.h>
35 #include <Pegasus/Common/Exception.h>
|
36 kumpf 1.31 #include <Pegasus/Common/CIMNameCast.h>
|
37 mike 1.4 #include "AssocClassTable.h"
38
39 PEGASUS_USING_STD;
40
41 PEGASUS_NAMESPACE_BEGIN
42
43 static inline Boolean _MatchNoCase(const String& x, const String& pattern)
44 {
45 return pattern.size() == 0 || String::equalNoCase(x, pattern);
46 }
47
|
48 kumpf 1.29 static Boolean _GetRecord(ifstream& is, ClassAssociation& record)
|
49 karl 1.11 {
|
50 kumpf 1.29 String line;
|
51 karl 1.11
|
52 kumpf 1.29 if (!GetLine(is, line))
53 return false;
|
54 mike 1.30 record.assocClassName = CIMNameCast(line);
|
55 karl 1.11
|
56 kumpf 1.29 if (!GetLine(is, line))
57 return false;
|
58 mike 1.30 record.fromClassName = CIMNameCast(line);
|
59 karl 1.11
|
60 kumpf 1.29 if (!GetLine(is, line))
61 return false;
|
62 mike 1.30 record.fromPropertyName = CIMNameCast(line);
|
63 mike 1.4
|
64 kumpf 1.29 if (!GetLine(is, line))
65 return false;
|
66 mike 1.30 record.toClassName = CIMNameCast(line);
|
67 mike 1.4
|
68 kumpf 1.29 if (!GetLine(is, line))
69 return false;
|
70 mike 1.30 record.toPropertyName = CIMNameCast(line);
|
71 mike 1.4
72 // Skip the blank line:
73
74 if (!GetLine(is, line))
|
75 kumpf 1.24 return false;
|
76 mike 1.4
77 return true;
78 }
79
|
80 kumpf 1.29 static inline void _PutField(ofstream& os, const CIMName& field)
|
81 mike 1.4 {
|
82 kumpf 1.29 // Write the field in UTF-8. Call write() to ensure no data
83 // conversion by the stream. Since all the fields contain CIM names,
84 // it is not necessary to escape CR/LF characters.
85 CString buffer = field.getString().getCString();
86 os.write((const char *)buffer,
87 static_cast<streamsize>(strlen((const char *)buffer)));
88 os << endl;
89 }
90
91 static void _PutRecord(ofstream& os, const ClassAssociation& record)
92 {
93 _PutField(os, record.assocClassName);
94 _PutField(os, record.fromClassName);
95 _PutField(os, record.fromPropertyName);
96 _PutField(os, record.toClassName);
97 _PutField(os, record.toPropertyName);
|
98 mike 1.4 os << endl;
99 }
100
101 void AssocClassTable::append(
102 PEGASUS_STD(ofstream)& os,
|
103 r.kieninger 1.19 const String& path,
|
104 kumpf 1.29 const ClassAssociation& classAssociation)
|
105 mike 1.4 {
|
106 kumpf 1.29 _PutRecord(os, classAssociation);
|
107 r.kieninger 1.19
108 // Update cache
|
109 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
110 if (cache->isActive())
|
111 r.kieninger 1.19 {
|
112 kumpf 1.29 cache->addRecord(classAssociation.fromClassName, classAssociation);
|
113 r.kieninger 1.19 }
|
114 mike 1.4 }
115
116 void AssocClassTable::append(
117 const String& path,
|
118 kumpf 1.29 const ClassAssociation& classAssociation)
|
119 mike 1.4 {
120 // Open input file:
|
121 david.dillard 1.18
|
122 mike 1.4 ofstream os;
123
124 if (!OpenAppend(os, path))
|
125 kumpf 1.24 throw CannotOpenFile(path);
|
126 mike 1.4
|
127 kumpf 1.29 _PutRecord(os, classAssociation);
|
128 r.kieninger 1.19
129 // Update cache
|
130 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
131 if (cache->isActive())
|
132 r.kieninger 1.19 {
|
133 kumpf 1.29 cache->addRecord(classAssociation.fromClassName, classAssociation);
|
134 r.kieninger 1.19 }
|
135 mike 1.4 }
136
137 Boolean AssocClassTable::deleteAssociation(
138 const String& path,
|
139 kumpf 1.10 const CIMName& assocClassName)
|
140 mike 1.4 {
141 // Open input file:
142
143 ifstream is;
|
144 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
145 {
146 return false;
147 }
|
148 mike 1.4
149 if (!Open(is, path))
|
150 dmitry.mikulin 1.27 {
151 throw CannotOpenFile(path);
152 }
|
153 mike 1.4
154 // Open output file:
155
156 String tmpPath = path + ".tmp";
157 ofstream os;
158 if (!Open(os, tmpPath))
|
159 dmitry.mikulin 1.27 {
|
160 kumpf 1.24 throw CannotOpenFile(tmpPath);
|
161 dmitry.mikulin 1.27 }
|
162 mike 1.4
163 // Copy over all lines except ones with the given association instance name:
164
|
165 kumpf 1.29 ClassAssociation classAssociation;
|
166 kumpf 1.32 Array<ClassAssociation> classAssociationsToDelete;
|
167 mike 1.4
|
168 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
169 mike 1.4 {
|
170 kumpf 1.29 if (assocClassName.getString() != classAssociation.assocClassName)
|
171 kumpf 1.24 {
|
172 kumpf 1.29 _PutRecord(os, classAssociation);
|
173 kumpf 1.24 }
|
174 r.kieninger 1.19 else
175 {
|
176 kumpf 1.32 classAssociationsToDelete.append(classAssociation);
|
177 r.kieninger 1.19 }
|
178 mike 1.4 }
179
180 // Close both files:
181
182 is.close();
183 os.close();
184
|
185 venkat.puvvada 1.36 // Rename back to original if tmp file is not empty
186 Uint32 size = 0;
187 Boolean gotFileSize = FileSystem::getFileSize(tmpPath, size);
188 if (size || !gotFileSize)
189 {
190 if (!FileSystem::renameFile(tmpPath, path))
191 {
192 throw CannotRenameFile(path);
193 }
194 }
195 else
196 {
197 // Delete tmp and original files
198 FileSystem::removeFile(tmpPath);
199 FileSystem::removeFile(path);
200 }
|
201 r.kieninger 1.19
202 // Update cache
|
203 kumpf 1.32 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
204 for (Uint32 i = 0; i < classAssociationsToDelete.size(); i++)
|
205 r.kieninger 1.19 {
|
206 kumpf 1.29 if (cache->isActive())
|
207 r.kieninger 1.19 {
|
208 kumpf 1.32 cache->removeRecord(
209 classAssociationsToDelete[i].fromClassName,
210 classAssociationsToDelete[i].assocClassName);
|
211 r.kieninger 1.19 }
212 }
213
|
214 kumpf 1.32 return classAssociationsToDelete.size();
|
215 mike 1.4 }
216
217 Boolean AssocClassTable::getAssociatorNames(
218 const String& path,
|
219 kumpf 1.13 const Array<CIMName>& classList,
220 const Array<CIMName>& assocClassList,
221 const Array<CIMName>& resultClassList,
|
222 mike 1.4 const String& role,
223 const String& resultRole,
224 Array<String>& associatorNames)
225 {
226 // Open input file:
227 ifstream is;
|
228 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
229 {
230 return false;
231 }
|
232 mike 1.4
233 if (!Open(is, path))
|
234 dmitry.mikulin 1.27 {
235 throw CannotOpenFile(path);
236 }
|
237 mike 1.4
|
238 kumpf 1.29 ClassAssociation classAssociation;
|
239 mike 1.4 Boolean found = false;
240
|
241 kumpf 1.13 // For each line in the associations table:
|
242 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
243 mike 1.4 {
|
244 kumpf 1.13 // Process associations from the right end class and with right roles
|
245 kumpf 1.29 if (Contains(classList, classAssociation.fromClassName) &&
246 _MatchNoCase(classAssociation.fromPropertyName.getString(), role) &&
247 _MatchNoCase(
248 classAssociation.toPropertyName.getString(), resultRole))
|
249 kumpf 1.13 {
250 // Skip classes that do not appear in the association class list
251 if ((assocClassList.size() != 0) &&
|
252 kumpf 1.29 (!Contains(assocClassList, classAssociation.assocClassName)))
|
253 kumpf 1.13 {
254 continue;
255 }
256
257 // Skip classes that do not appear in the result class list
258 if ((resultClassList.size() != 0) &&
|
259 kumpf 1.29 (!Contains(resultClassList, classAssociation.toClassName)))
|
260 kumpf 1.13 {
261 continue;
262 }
263
264 // This class qualifies; add it to the list (skipping duplicates)
|
265 kumpf 1.29 if (!Contains(
266 associatorNames, classAssociation.toClassName.getString()))
|
267 kumpf 1.13 {
|
268 kumpf 1.29 associatorNames.append(
269 classAssociation.toClassName.getString());
|
270 kumpf 1.13 }
271 found = true;
272 }
|
273 mike 1.4 }
274
275 return found;
276 }
277
|
278 kumpf 1.24 Boolean AssocClassTable::_InitializeCache(
279 AssocClassCache* cache,
280 const String& path)
|
281 r.kieninger 1.19 {
282 if (!cache->isActive())
283 {
284
285 // Open input file:
286 ifstream is;
|
287 dmitry.mikulin 1.27 if (!FileSystem::exists(path))
288 {
289 return false;
290 }
|
291 r.kieninger 1.19
292 if (!Open(is, path))
|
293 dmitry.mikulin 1.27 {
294 throw CannotOpenFile(path);
295 }
|
296 r.kieninger 1.19
|
297 kumpf 1.29 ClassAssociation classAssociation;
|
298 r.kieninger 1.19
299 // For each line in the associations table:
|
300 kumpf 1.29 while (_GetRecord(is, classAssociation))
|
301 r.kieninger 1.19 {
|
302 kumpf 1.29 cache->addRecord(classAssociation.fromClassName,
303 classAssociation);
|
304 r.kieninger 1.19 }
305
306 cache->setActive(true);
307 }
308
309 return true;
310 }
311
|
312 mike 1.4 Boolean AssocClassTable::getReferenceNames(
313 const String& path,
|
314 karl 1.11 const Array<CIMName>& classList,
|
315 kumpf 1.13 const Array<CIMName>& resultClassList,
|
316 mike 1.4 const String& role,
317 Array<String>& referenceNames)
318 {
|
319 kumpf 1.33 // Get the information from the association class cache.
|
320 kumpf 1.29 AssocClassCache* cache = _assocClassCacheManager.getAssocClassCache(path);
|
321 mike 1.4
|
322 r.kieninger 1.19 if (!cache->isActive())
323 {
324 if (!_InitializeCache(cache,path))
325 return false;
326 }
327
|
328 kumpf 1.33 return cache->getReferenceNames(
329 classList, resultClassList, role, referenceNames);
|
330 mike 1.4 }
331
332 PEGASUS_NAMESPACE_END
|