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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2