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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2