(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.25 //
 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 mike          1.4  static Boolean _GetRecord(ifstream& is, Array<String>& fields)
 77                    {
 78                        fields.clear();
 79                        String line;
 80                    
 81                        for (Uint32 i = 0; i < NUM_FIELDS; i++)
 82                        {
 83 kumpf         1.24         if (!GetLine(is, line))
 84                                return false;
 85 mike          1.4  
 86 r.kieninger   1.19         fields.append(line);
 87                            //Association names are not supposed to contain escapes
 88                            //fields.append(_Unescape(line));
 89 mike          1.4      }
 90                    
 91                        // Skip the blank line:
 92                    
 93                        if (!GetLine(is, line))
 94 kumpf         1.24         return false;
 95 mike          1.4  
 96                        return true;
 97                    }
 98                    
 99                    static void _PutRecord(ofstream& os, Array<String>& fields)
100                    {
101                        for (Uint32 i = 0, n = fields.size(); i < n; i++)
102 chuck         1.17     {
103 kumpf         1.26         // Write the field in UTF-8.  Call write() to ensure no data
104                            // conversion by the stream.  Since all the fields contain CIM names,
105                            // it is not necessary to escape CR/LF characters.
106                            CString buffer = fields[i].getCString();
107 kumpf         1.20         os.write((const char *)buffer,
108                                static_cast<streamsize>(strlen((const char *)buffer)));
109 chuck         1.17         os << endl;
110                        }
111 mike          1.4      os << endl;
112                    }
113                    
114                    void AssocClassTable::append(
115                        PEGASUS_STD(ofstream)& os,
116 r.kieninger   1.19     const String& path,
117 kumpf         1.10     const CIMName& assocClassName,
118                        const CIMName& fromClassName,
119                        const CIMName& fromPropertyName,
120                        const CIMName& toClassName,
121                        const CIMName& toPropertyName)
122 mike          1.4  {
123                        Array<String> fields;
124 kumpf         1.7      fields.reserveCapacity(5);
125 kumpf         1.10     fields.append(assocClassName.getString());
126                        fields.append(fromClassName.getString());
127                        fields.append(fromPropertyName.getString());
128                        fields.append(toClassName.getString());
129                        fields.append(toPropertyName.getString());
130 mike          1.4  
131 r.kieninger   1.19 
132 mike          1.4      _PutRecord(os, fields);
133 r.kieninger   1.19 
134                        // Update cache
135 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
136 r.kieninger   1.19     if (cache != 0)
137                        {
138                            if (cache->isActive())
139                            {
140                                WriteLock lock(_classCacheLock);
141                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
142                                                 fields);
143                            }
144                        }
145 mike          1.4  }
146                    
147                    void AssocClassTable::append(
148                        const String& path,
149 kumpf         1.10     const CIMName& assocClassName,
150                        const CIMName& fromClassName,
151                        const CIMName& fromPropertyName,
152                        const CIMName& toClassName,
153                        const CIMName& toPropertyName)
154 mike          1.4  {
155                        // Open input file:
156 david.dillard 1.18 
157 mike          1.4      ofstream os;
158                    
159                        if (!OpenAppend(os, path))
160 kumpf         1.24         throw CannotOpenFile(path);
161 mike          1.4  
162                        // Insert the entry:
163                    
164                        Array<String> fields;
165 kumpf         1.7      fields.reserveCapacity(5);
166 kumpf         1.10     fields.append(assocClassName.getString());
167                        fields.append(fromClassName.getString());
168                        fields.append(fromPropertyName.getString());
169                        fields.append(toClassName.getString());
170                        fields.append(toPropertyName.getString());
171 mike          1.4  
172 r.kieninger   1.19 
173 mike          1.4      _PutRecord(os, fields);
174 r.kieninger   1.19 
175                        // Update cache
176 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
177 r.kieninger   1.19     if (cache != 0)
178                        {
179                            if (cache->isActive())
180                            {
181                                WriteLock lock(_classCacheLock);
182                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
183                                                 fields);
184                            }
185                        }
186 mike          1.4  }
187                    
188                    Boolean AssocClassTable::deleteAssociation(
189                        const String& path,
190 kumpf         1.10     const CIMName& assocClassName)
191 mike          1.4  {
192                        // Open input file:
193                    
194                        ifstream is;
195                    
196                        if (!Open(is, path))
197 kumpf         1.24         return false;
198 mike          1.4  
199                        // Open output file:
200                    
201                        String tmpPath = path + ".tmp";
202                        ofstream os;
203                    
204                        if (!Open(os, tmpPath))
205 kumpf         1.24         throw CannotOpenFile(tmpPath);
206 mike          1.4  
207                        // Copy over all lines except ones with the given association instance name:
208                    
209                        Array<String> fields;
210 r.kieninger   1.19     Array<String> fieldsToDelete;
211 mike          1.4      Boolean found = false;
212                    
213                        while (_GetRecord(is, fields))
214                        {
215 kumpf         1.24         if (assocClassName.getString() != fields[ASSOC_CLASS_NAME_INDEX])
216                            {
217                                _PutRecord(os, fields);
218                                found = true;
219                            }
220 r.kieninger   1.19         else
221                            {
222                                fieldsToDelete = fields;
223                            }
224 mike          1.4      }
225                    
226                        // Close both files:
227                    
228                        is.close();
229                        os.close();
230                    
231                        // Remove orginal file:
232                    
233                        if (!FileSystem::removeFile(path))
234 kumpf         1.24         throw CannotRemoveFile(path);
235 mike          1.4  
236                        // Rename back to original name:
237                    
238                        if (!FileSystem::renameFile(tmpPath, path))
239 kumpf         1.24         throw CannotRenameFile(path);
240 mike          1.4  
241 r.kieninger   1.19 
242                        // Update cache
243                        if (found)
244                        {
245 kumpf         1.24         AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
246 r.kieninger   1.19         if (cache != 0)
247                            {
248                                if (cache->isActive())
249                                {
250                                    WriteLock lock(_classCacheLock);
251                                    cache->removeRecord(fieldsToDelete[FROM_CLASS_NAME_INDEX],
252                                                        fieldsToDelete[ASSOC_CLASS_NAME_INDEX]);
253                                }
254                            }
255                        }
256                    
257 mike          1.4      return found;
258                    }
259                    
260                    Boolean AssocClassTable::getAssociatorNames(
261                        const String& path,
262 kumpf         1.13     const Array<CIMName>& classList,
263                        const Array<CIMName>& assocClassList,
264                        const Array<CIMName>& resultClassList,
265 mike          1.4      const String& role,
266                        const String& resultRole,
267                        Array<String>& associatorNames)
268                    {
269                        // Open input file:
270                        ifstream is;
271                    
272                        if (!Open(is, path))
273 kumpf         1.13         return false;
274 mike          1.4  
275                        Array<String> fields;
276                        Boolean found = false;
277                    
278 kumpf         1.13     // For each line in the associations table:
279 mike          1.4      while (_GetRecord(is, fields))
280                        {
281 kumpf         1.13         // Process associations from the right end class and with right roles
282                            if (_ContainsClass(classList, fields[FROM_CLASS_NAME_INDEX]) &&
283                                _MatchNoCase(fields[FROM_PROPERTY_NAME_INDEX], role) &&
284                                _MatchNoCase(fields[TO_PROPERTY_NAME_INDEX], resultRole))
285                            {
286                                // Skip classes that do not appear in the association class list
287                                if ((assocClassList.size() != 0) &&
288                                    (!_ContainsClass(assocClassList,
289                                                     fields[ASSOC_CLASS_NAME_INDEX])))
290                                {
291                                    continue;
292                                }
293                    
294                                // Skip classes that do not appear in the result class list
295                                if ((resultClassList.size() != 0) &&
296                                    (!_ContainsClass(resultClassList,
297                                                     fields[TO_CLASS_NAME_INDEX])))
298                                {
299                                    continue;
300                                }
301                    
302 kumpf         1.13             // This class qualifies; add it to the list (skipping duplicates)
303                                if (!Contains(associatorNames, fields[TO_CLASS_NAME_INDEX]))
304                                {
305                                    associatorNames.append(fields[TO_CLASS_NAME_INDEX]);
306                                }
307                                found = true;
308                            }
309 mike          1.4      }
310                    
311                        return found;
312                    }
313                    
314 kumpf         1.24 Boolean AssocClassTable::_InitializeCache(
315                        AssocClassCache* cache,
316                        const String& path)
317 r.kieninger   1.19 {
318                        WriteLock lock(_classCacheLock);
319                    
320                        if (!cache->isActive())
321                        {
322                    
323                            // Open input file:
324                            ifstream is;
325                    
326                            if (!Open(is, path))
327                                return false;
328                    
329                            Array<String> fields;
330                    
331                            // For each line in the associations table:
332                            while (_GetRecord(is, fields))
333                            {
334                                cache->addRecord(fields[FROM_CLASS_NAME_INDEX],
335                                                 fields);
336                            }
337                    
338 r.kieninger   1.19         cache->setActive(true);
339                        }
340                    
341                        return true;
342                    }
343                    
344                    void AssocClassTable::removeCaches()
345                    {
346                        WriteLock lock(_classCacheLock);
347                        AssocClassCache::cleanupAssocClassCaches();
348                    
349                        return;
350                    }
351                    
352 mike          1.4  Boolean AssocClassTable::getReferenceNames(
353                        const String& path,
354 karl          1.11     const Array<CIMName>& classList,
355 kumpf         1.13     const Array<CIMName>& resultClassList,
356 mike          1.4      const String& role,
357                        Array<String>& referenceNames)
358                    {
359                    
360 r.kieninger   1.19     // First see if we can get the information from the association class cache.
361 kumpf         1.24     AssocClassCache* cache = AssocClassCache::getAssocClassCache(path);
362 r.kieninger   1.19     if (cache == 0)
363 kumpf         1.13         return false;
364 mike          1.4  
365 r.kieninger   1.19     if (!cache->isActive())
366                        {
367                            if (!_InitializeCache(cache,path))
368                                return false;
369                        }
370                    
371                        Array< Array<String> > records;
372 karl          1.11     Boolean found = false;
373                    
374 r.kieninger   1.19 
375                        // For each of the target classes retrieve the list of matching
376                        // association classes from the cache.
377                        // The cache uses the from class name as an index and returns all
378                        // association class records having that from class.
379                    
380                        ReadLock lock(_classCacheLock);
381                        for (Uint16 idx=0; idx < classList.size(); idx++)
382 karl          1.11     {
383 r.kieninger   1.19         String fromClassName = classList[idx].getString();
384                            if (cache->getAssocClassEntry(fromClassName, records))
385                            {
386                                for (Uint16 rx=0; rx <records.size(); rx++)
387                                {
388                                    if (_MatchNoCase(records[rx][FROM_PROPERTY_NAME_INDEX], role))
389 kumpf         1.24                 {
390                                        // Skip classes that do not appear in the result class list
391                                        if ((resultClassList.size() != 0) &&
392                                            (!_ContainsClass(resultClassList,
393                                                 records[rx][ASSOC_CLASS_NAME_INDEX])))
394                                        {
395                                            continue;
396                                        }
397                    
398                                        // This class qualifies; add it to the list (skipping
399                                        // duplicates)
400                                        if (!Contains(referenceNames,
401                                                records[rx][ASSOC_CLASS_NAME_INDEX]))
402                                        {
403                                            referenceNames.append(
404                                                records[rx][ASSOC_CLASS_NAME_INDEX]);
405                                        }
406                                        found = true;
407                                    }
408 kumpf         1.13             }
409 r.kieninger   1.19         }
410                        }
411 mike          1.4  
412                        return found;
413                    }
414                    
415                    PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2