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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2