1 mike 1.4 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
14 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 //==============================================================================
22 mike 1.4 //
23 // Author: Mike Brasher (mbrasher@bmc.com)
24 //
25 // Modified By:
26 //
27 //%/////////////////////////////////////////////////////////////////////////////
28
|
30 mike 1.4 #include <fstream>
31 #include <Pegasus/Common/Exception.h>
32 #include <Pegasus/Common/FileSystem.h>
33 #include <Pegasus/Common/Exception.h>
34 #include "AssocClassTable.h"
35
36 PEGASUS_USING_STD;
37
38 PEGASUS_NAMESPACE_BEGIN
39
40 #define ASSOC_CLASS_NAME_INDEX 0
41 #define FROM_CLASS_NAME_INDEX 1
42 #define FROM_PROPERTY_NAME_INDEX 2
43 #define TO_CLASS_NAME_INDEX 3
44 #define TO_PROPERTY_NAME_INDEX 4
45 #define NUM_FIELDS 5
46
47 static inline Boolean _MatchNoCase(const String& x, const String& pattern)
48 {
49 return pattern.size() == 0 || String::equalNoCase(x, pattern);
50 }
51 mike 1.4
52 static String _Escape(const String& str)
53 {
54 String result;
55
56 for (Uint32 i = 0, n = str.size(); i < n; i++)
57 {
58 Char16 c = str[i];
59
60 switch (c)
61 {
62 case '\n':
63 result += "\\n";
64 break;
65
66 case '\r':
67 result += "\\r";
68 break;
69
70 case '\t':
71 result += "\\t";
72 mike 1.4 break;
73
74 case '\f':
75 result += "\\f";
76 break;
77
78 case '\\':
79 result += "\\\\";
80 break;
81
82 default:
83 result += c;
84 }
85 }
86
87 return result;
88 }
89
90 static String _Unescape(const String& str)
91 {
92 String result;
93 mike 1.4
94 for (Uint32 i = 0, n = str.size(); i < n; i++)
95 {
96 Char16 c = str[i];
97
98 if (c == '\\')
99 {
100 if (i + 1 == n)
101 break;
102
103 c = str[i + 1];
104
105 switch (c)
106 {
107 case 'n':
108 result += "\n";
109 break;
110
111 case 'r':
112 result += "\r";
113 break;
114 mike 1.4
115 case 't':
116 result += "\t";
117 break;
118
119 case 'f':
120 result += "\f";
121 break;
122
123 default:
124 result += c;
125 }
126
127 i++;
128 }
129 else
130 result += c;
131 }
132
133 return result;
134 }
135 mike 1.4
136 static Boolean _GetRecord(ifstream& is, Array<String>& fields)
137 {
138 fields.clear();
139 String line;
140
141 for (Uint32 i = 0; i < NUM_FIELDS; i++)
142 {
143 if (!GetLine(is, line))
144 return false;
145
146 fields.append(_Unescape(line));
147 }
148
149 // Skip the blank line:
150
151 if (!GetLine(is, line))
152 return false;
153
154 return true;
155 }
156 mike 1.4
157 static void _PutRecord(ofstream& os, Array<String>& fields)
158 {
159 for (Uint32 i = 0, n = fields.size(); i < n; i++)
160 os << _Escape(fields[i]) << endl;
161 os << endl;
162 }
163
164 void AssocClassTable::append(
165 PEGASUS_STD(ofstream)& os,
166 const String& assocClassName,
167 const String& fromClassName,
168 const String& fromPropertyName,
169 const String& toClassName,
170 const String& toPropertyName)
171 {
172 Array<String> fields;
173 fields.reserve(5);
174 fields.append(assocClassName);
175 fields.append(fromClassName);
176 fields.append(fromPropertyName);
177 mike 1.4 fields.append(toClassName);
178 fields.append(toPropertyName);
179
180 _PutRecord(os, fields);
181 }
182
183 void AssocClassTable::append(
184 const String& path,
185 const String& assocClassName,
186 const String& fromClassName,
187 const String& fromPropertyName,
188 const String& toClassName,
189 const String& toPropertyName)
190 {
191 // Open input file:
192
193 ofstream os;
194
195 if (!OpenAppend(os, path))
196 throw CannotOpenFile(path);
197
198 mike 1.4 // Insert the entry:
199
200 Array<String> fields;
201 fields.reserve(5);
202 fields.append(assocClassName);
203 fields.append(fromClassName);
204 fields.append(fromPropertyName);
205 fields.append(toClassName);
206 fields.append(toPropertyName);
207
208 _PutRecord(os, fields);
209 }
210
211 Boolean AssocClassTable::deleteAssociation(
212 const String& path,
213 const String& assocClassName)
214 {
215 // Open input file:
216
217 ifstream is;
218
219 mike 1.4 if (!Open(is, path))
220 return false;
221
222 // Open output file:
223
224 String tmpPath = path + ".tmp";
225 ofstream os;
226
227 if (!Open(os, tmpPath))
228 throw CannotOpenFile(tmpPath);
229
230 // Copy over all lines except ones with the given association instance name:
231
232 Array<String> fields;
233 Boolean found = false;
234
235 while (_GetRecord(is, fields))
236 {
237 if (assocClassName != fields[ASSOC_CLASS_NAME_INDEX])
238 {
239 _PutRecord(os, fields);
240 mike 1.4 found = true;
241 }
242 }
243
244 // Close both files:
245
246 is.close();
247 os.close();
248
249 // Remove orginal file:
250
251 if (!FileSystem::removeFile(path))
252 throw CannotRemoveFile(path);
253
254 // Rename back to original name:
255
256 if (!FileSystem::renameFile(tmpPath, path))
257 throw CannotRenameFile(path);
258
259 return found;
260 }
261 mike 1.4
262 Boolean AssocClassTable::getAssociatorNames(
263 const String& path,
264 const String& className,
265 const String& assocClass,
266 const String& resultClass,
267 const String& role,
268 const String& resultRole,
269 Array<String>& associatorNames)
270 {
271 // Open input file:
272
273 ifstream is;
274
275 if (!Open(is, path))
276 return false;
277
278 // For each line:
279
280 Array<String> fields;
281 Boolean found = false;
282 mike 1.4
283
284 while (_GetRecord(is, fields))
285 {
286 if (_MatchNoCase(className, fields[FROM_CLASS_NAME_INDEX]) &&
287 _MatchNoCase(fields[ASSOC_CLASS_NAME_INDEX], assocClass) &&
288 _MatchNoCase(fields[TO_CLASS_NAME_INDEX], resultClass) &&
289 _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role) &&
290 _MatchNoCase(fields[TO_PROPERTY_NAME_INDEX], resultRole))
291 {
292 associatorNames.append(fields[TO_CLASS_NAME_INDEX]);
293 found = true;
294 }
295 }
296
297 return found;
298 }
299
300 Boolean AssocClassTable::getReferenceNames(
301 const String& path,
302 const String& className,
303 mike 1.4 const String& resultClass,
304 const String& role,
305 Array<String>& referenceNames)
306 {
307 // Open input file:
308
309 ifstream is;
310
311 if (!Open(is, path))
312 return false;
313
314 // For each line:
315
316 Array<String> fields;
317 Boolean found = false;
318
319 while (_GetRecord(is, fields))
320 {
321 if (_MatchNoCase(className, fields[FROM_CLASS_NAME_INDEX]) &&
322 _MatchNoCase(fields[ASSOC_CLASS_NAME_INDEX], resultClass) &&
323 _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role))
324 mike 1.4 {
325 if (!Contains(referenceNames, fields[ASSOC_CLASS_NAME_INDEX]))
326 referenceNames.append(fields[ASSOC_CLASS_NAME_INDEX]);
327 found = true;
328 }
329 }
330
331 return found;
332 }
333
334 PEGASUS_NAMESPACE_END
|