(file) Return to AssocClassTable.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

  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.21 // 
 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 mike  1.23 #include <Pegasus/Common/ReadWriteSem.h>
 39 mike  1.4  #include "AssocClassTable.h"
 40            
 41            PEGASUS_USING_STD;
 42            
 43            PEGASUS_NAMESPACE_BEGIN
 44            
 45            #define ASSOC_CLASS_NAME_INDEX 0
 46            #define FROM_CLASS_NAME_INDEX 1
 47            #define FROM_PROPERTY_NAME_INDEX 2
 48            #define TO_CLASS_NAME_INDEX 3
 49            #define TO_PROPERTY_NAME_INDEX 4
 50            #define NUM_FIELDS 5
 51            
 52 r.kieninger 1.19 
 53                  ReadWriteSem AssocClassTable::_classCacheLock;
 54                  
 55                  
 56 mike        1.4  static inline Boolean _MatchNoCase(const String& x, const String& pattern)
 57                  {
 58                      return pattern.size() == 0 || String::equalNoCase(x, pattern);
 59                  }
 60                  
 61 kumpf       1.24 static inline Boolean _ContainsClass(
 62                      const Array<CIMName>& classNames,
 63                      const String& match)
 64 karl        1.11 {
 65                      Uint32 n = classNames.size();
 66                  
 67                      for (Uint32 i = 0; i < n; i++)
 68                      {
 69 david.dillard 1.18         if (_MatchNoCase(classNames[i].getString(), match))
 70                                return true;
 71 karl          1.11     }
 72                    
 73                        return false;
 74                    }
 75                    
 76                    
 77 mike          1.4  static String _Escape(const String& str)
 78                    {
 79                        String result;
 80                    
 81                        for (Uint32 i = 0, n = str.size(); i < n; i++)
 82                        {
 83 kumpf         1.24         Char16 c = str[i];
 84 mike          1.4  
 85 kumpf         1.24         switch (c)
 86                            {
 87                                case '\n':
 88                                    result.append("\\n");
 89                                    break;
 90                    
 91                                case '\r':
 92                                    result.append("\\r");
 93                                    break;
 94                    
 95                                case '\t':
 96                                    result.append("\\t");
 97                                    break;
 98                    
 99                                case '\f':
100                                    result.append("\\f");
101                                    break;
102                    
103                                case '\\':
104                                    result.append("\\\\");
105                                    break;
106 kumpf         1.24 
107                                default:
108                                    result.append(c);
109                            }
110 mike          1.4      }
111                    
112                        return result;
113                    }
114                    
115                    static String _Unescape(const String& str)
116                    {
117                        String result;
118                    
119                        for (Uint32 i = 0, n = str.size(); i < n; i++)
120                        {
121 kumpf         1.24         Char16 c = str[i];
122                    
123                            if (c == '\\')
124                            {
125                                if (i + 1 == n)
126                                    break;
127                    
128                                c = str[i + 1];
129                    
130                                switch (c)
131                                {
132                                    case 'n':
133                                        result.append("\n");
134                                        break;
135                    
136                                    case 'r':
137                                        result.append("\r");
138                                        break;
139                    
140                                    case 't':
141                                        result.append("\t");
142 kumpf         1.24                     break;
143                    
144                                    case 'f':
145                                        result.append("\f");
146                                        break;
147 mike          1.4  
148 kumpf         1.24                 default:
149                                        result.append(c);
150                                }
151                    
152                                i++;
153                            }
154                            else
155                                result.append(c);
156 mike          1.4      }
157                    
158                        return result;
159                    }
160                    
161                    static Boolean _GetRecord(ifstream& is, Array<String>& fields)
162                    {
163                        fields.clear();
164                        String line;
165                    
166                        for (Uint32 i = 0; i < NUM_FIELDS; i++)
167                        {
168 kumpf         1.24         if (!GetLine(is, line))
169                                return false;
170 mike          1.4  
171 r.kieninger   1.19         fields.append(line);
172                            //Association names are not supposed to contain escapes
173                            //fields.append(_Unescape(line));
174 mike          1.4      }
175                    
176                        // Skip the blank line:
177                    
178                        if (!GetLine(is, line))
179 kumpf         1.24         return false;
180 mike          1.4  
181                        return true;
182                    }
183                    
184                    static void _PutRecord(ofstream& os, Array<String>& fields)
185                    {
186                        for (Uint32 i = 0, n = fields.size(); i < n; i++)
187 chuck         1.17     {
188                            // Calling getCString to ensure utf-8 goes to the file
189                            // Calling write to ensure no data conversion by the stream
190 david.dillard 1.18         CString  buffer = _Escape(fields[i]).getCString();
191 kumpf         1.20         os.write((const char *)buffer,
192                                static_cast<streamsize>(strlen((const char *)buffer)));
193 chuck         1.17         os << endl;
194                        }
195 mike          1.4      os << endl;
196                    }
197                    
198                    void AssocClassTable::append(
199                        PEGASUS_STD(ofstream)& os,
200 r.kieninger   1.19     const String& path,
201 kumpf         1.10     const CIMName& assocClassName,
202                        const CIMName& fromClassName,
203                        const CIMName& fromPropertyName,
204                        const CIMName& toClassName,
205                        const CIMName& toPropertyName)
206 mike          1.4  {
207                        Array<String> fields;
208 kumpf         1.7      fields.reserveCapacity(5);
209 kumpf         1.10     fields.append(assocClassName.getString());
210                        fields.append(fromClassName.getString());
211                        fields.append(fromPropertyName.getString());
212                        fields.append(toClassName.getString());
213                        fields.append(toPropertyName.getString());
214 mike          1.4  
215 r.kieninger   1.19 
216 mike          1.4      _PutRecord(os, fields);
217 r.kieninger   1.19 
218                        // Update cache
219 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
220 r.kieninger   1.19     if (cache != 0)
221                        {
222                            if (cache->isActive())
223                            {
224                                WriteLock lock(_classCacheLock);
225                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
226                                                 fields);
227                            }
228                        }
229 mike          1.4  }
230                    
231                    void AssocClassTable::append(
232                        const String& path,
233 kumpf         1.10     const CIMName& assocClassName,
234                        const CIMName& fromClassName,
235                        const CIMName& fromPropertyName,
236                        const CIMName& toClassName,
237                        const CIMName& toPropertyName)
238 mike          1.4  {
239                        // Open input file:
240 david.dillard 1.18 
241 mike          1.4      ofstream os;
242                    
243                        if (!OpenAppend(os, path))
244 kumpf         1.24         throw CannotOpenFile(path);
245 mike          1.4  
246                        // Insert the entry:
247                    
248                        Array<String> fields;
249 kumpf         1.7      fields.reserveCapacity(5);
250 kumpf         1.10     fields.append(assocClassName.getString());
251                        fields.append(fromClassName.getString());
252                        fields.append(fromPropertyName.getString());
253                        fields.append(toClassName.getString());
254                        fields.append(toPropertyName.getString());
255 mike          1.4  
256 r.kieninger   1.19 
257 mike          1.4      _PutRecord(os, fields);
258 r.kieninger   1.19 
259                        // Update cache
260 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
261 r.kieninger   1.19     if (cache != 0)
262                        {
263                            if (cache->isActive())
264                            {
265                                WriteLock lock(_classCacheLock);
266                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
267                                                 fields);
268                            }
269                        }
270 mike          1.4  }
271                    
272                    Boolean AssocClassTable::deleteAssociation(
273                        const String& path,
274 kumpf         1.10     const CIMName& assocClassName)
275 mike          1.4  {
276                        // Open input file:
277                    
278                        ifstream is;
279                    
280                        if (!Open(is, path))
281 kumpf         1.24         return false;
282 mike          1.4  
283                        // Open output file:
284                    
285                        String tmpPath = path + ".tmp";
286                        ofstream os;
287                    
288                        if (!Open(os, tmpPath))
289 kumpf         1.24         throw CannotOpenFile(tmpPath);
290 mike          1.4  
291                        // Copy over all lines except ones with the given association instance name:
292                    
293                        Array<String> fields;
294 r.kieninger   1.19     Array<String> fieldsToDelete;
295 mike          1.4      Boolean found = false;
296                    
297                        while (_GetRecord(is, fields))
298                        {
299 kumpf         1.24         if (assocClassName.getString() != fields[ASSOC_CLASS_NAME_INDEX])
300                            {
301                                _PutRecord(os, fields);
302                                found = true;
303                            }
304 r.kieninger   1.19         else
305                            {
306                                fieldsToDelete = fields;
307                            }
308 mike          1.4      }
309                    
310                        // Close both files:
311                    
312                        is.close();
313                        os.close();
314                    
315                        // Remove orginal file:
316                    
317                        if (!FileSystem::removeFile(path))
318 kumpf         1.24         throw CannotRemoveFile(path);
319 mike          1.4  
320                        // Rename back to original name:
321                    
322                        if (!FileSystem::renameFile(tmpPath, path))
323 kumpf         1.24         throw CannotRenameFile(path);
324 mike          1.4  
325 r.kieninger   1.19 
326                        // Update cache
327                        if (found)
328                        {
329 kumpf         1.24         AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
330 r.kieninger   1.19         if (cache != 0)
331                            {
332                                if (cache->isActive())
333                                {
334                                    WriteLock lock(_classCacheLock);
335                                    cache->removeRecord(fieldsToDelete[FROM_CLASS_NAME_INDEX],
336                                                        fieldsToDelete[ASSOC_CLASS_NAME_INDEX]);
337                                }
338                            }
339                        }
340                    
341 mike          1.4      return found;
342                    }
343                    
344                    Boolean AssocClassTable::getAssociatorNames(
345                        const String& path,
346 kumpf         1.13     const Array<CIMName>& classList,
347                        const Array<CIMName>& assocClassList,
348                        const Array<CIMName>& resultClassList,
349 mike          1.4      const String& role,
350                        const String& resultRole,
351                        Array<String>& associatorNames)
352                    {
353                        // Open input file:
354                        ifstream is;
355                    
356                        if (!Open(is, path))
357 kumpf         1.13         return false;
358 mike          1.4  
359                        Array<String> fields;
360                        Boolean found = false;
361                    
362 kumpf         1.13     // For each line in the associations table:
363 mike          1.4      while (_GetRecord(is, fields))
364                        {
365 kumpf         1.13         // Process associations from the right end class and with right roles
366                            if (_ContainsClass(classList, fields[FROM_CLASS_NAME_INDEX]) &&
367                                _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role) &&
368                                _MatchNoCase(fields[TO_PROPERTY_NAME_INDEX], resultRole))
369                            {
370                                // Skip classes that do not appear in the association class list
371                                if ((assocClassList.size() != 0) &&
372                                    (!_ContainsClass(assocClassList,
373                                                     fields[ASSOC_CLASS_NAME_INDEX])))
374                                {
375                                    continue;
376                                }
377                    
378                                // Skip classes that do not appear in the result class list
379                                if ((resultClassList.size() != 0) &&
380                                    (!_ContainsClass(resultClassList,
381                                                     fields[TO_CLASS_NAME_INDEX])))
382                                {
383                                    continue;
384                                }
385                    
386 kumpf         1.13             // This class qualifies; add it to the list (skipping duplicates)
387                                if (!Contains(associatorNames, fields[TO_CLASS_NAME_INDEX]))
388                                {
389                                    associatorNames.append(fields[TO_CLASS_NAME_INDEX]);
390                                }
391                                found = true;
392                            }
393 mike          1.4      }
394                    
395                        return found;
396                    }
397                    
398 kumpf         1.24 Boolean AssocClassTable::_InitializeCache(
399                        AssocClassCache* cache,
400                        const String& path)
401 r.kieninger   1.19 {
402                        WriteLock lock(_classCacheLock);
403                    
404                        if (!cache->isActive())
405                        {
406                    
407                            // Open input file:
408                            ifstream is;
409                    
410                            if (!Open(is, path))
411                                return false;
412                    
413                            Array<String> fields;
414                    
415                            // For each line in the associations table:
416                            while (_GetRecord(is, fields))
417                            {
418                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
419                                                 fields);
420                            }
421                    
422 r.kieninger   1.19         cache->setActive(true);
423                        }
424                    
425                        return true;
426                    }
427                    
428                    void AssocClassTable::removeCaches()
429                    {
430                        WriteLock lock(_classCacheLock);
431                        AssocClassCache::cleanupAssocClassCaches();
432                    
433                        return;
434                    }
435                    
436 mike          1.4  Boolean AssocClassTable::getReferenceNames(
437                        const String& path,
438 karl          1.11     const Array<CIMName>& classList,
439 kumpf         1.13     const Array<CIMName>& resultClassList,
440 mike          1.4      const String& role,
441                        Array<String>& referenceNames)
442                    {
443                    
444 r.kieninger   1.19     // First see if we can get the information from the association class cache.
445 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
446 r.kieninger   1.19     if (cache == 0)
447 kumpf         1.13         return false;
448 mike          1.4  
449 r.kieninger   1.19     if (!cache->isActive())
450                        {
451                            if (!_InitializeCache(cache,path))
452                                return false;
453                        }
454                    
455                        Array< Array<String> > records;
456 karl          1.11     Boolean found = false;
457                    
458 r.kieninger   1.19 
459                        // For each of the target classes retrieve the list of matching
460                        // association classes from the cache.
461                        // The cache uses the from class name as an index and returns all
462                        // association class records having that from class.
463                    
464                        ReadLock lock(_classCacheLock);
465                        for (Uint16 idx=0; idx < classList.size(); idx++)
466 karl          1.11     {
467 r.kieninger   1.19         String fromClassName = classList[idx].getString();
468                            if (cache->getAssocClassEntry(fromClassName, records))
469                            {
470                                for (Uint16 rx=0; rx <records.size(); rx++)
471                                {
472                                    if (_MatchNoCase(records[rx][FROM_PROPERTY_NAME_INDEX], role))
473 kumpf         1.24                 {
474                                        // Skip classes that do not appear in the result class list
475                                        if ((resultClassList.size() != 0) &&
476                                            (!_ContainsClass(resultClassList,
477                                                 records[rx][ASSOC_CLASS_NAME_INDEX])))
478                                        {
479                                            continue;
480                                        }
481                    
482                                        // This class qualifies; add it to the list (skipping
483                                        // duplicates)
484                                        if (!Contains(referenceNames,
485                                                records[rx][ASSOC_CLASS_NAME_INDEX]))
486                                        {
487                                            referenceNames.append(
488                                                records[rx][ASSOC_CLASS_NAME_INDEX]);
489                                        }
490                                        found = true;
491                                    }
492 kumpf         1.13             }
493 r.kieninger   1.19         }
494                        }
495 mike          1.4  
496                        return found;
497                    }
498                    
499                    PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2