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

  1 kumpf 1.2 //%/////////////////////////////////////////////////////////////////////////////
  2 chip  1.1 //
  3 kumpf 1.6 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4           // The Open Group, Tivoli Systems
  5 chip  1.1 //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // of this software and associated documentation files (the "Software"), to
  8           // deal in the Software without restriction, including without limitation the
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10           // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12 kumpf 1.6 // 
 13 chip  1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14           // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22           //==============================================================================
 23           //
 24 kumpf 1.2 // Author: Mike Brasher (mbrasher@bmc.com)
 25 chip  1.1 //
 26 kumpf 1.2 // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 27 chip  1.1 //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30 kumpf 1.2 #include <Pegasus/Common/Config.h>
 31           #include <cctype>
 32           #include <cstring>
 33           #include "HashTable.h"
 34           #include "CIMObjectPath.h"
 35           #include "Indentor.h"
 36           #include "CIMName.h"
 37           #include "Destroyer.h"
 38           #include "XmlWriter.h"
 39           #include "XmlReader.h"
 40           #include "Array.h"
 41           #include "CIMOMPort.h"
 42 chip  1.1 
 43           PEGASUS_NAMESPACE_BEGIN
 44 kumpf 1.2 
 45           #define PEGASUS_ARRAY_T KeyBinding
 46           # include "ArrayImpl.h"
 47           #undef PEGASUS_ARRAY_T
 48           
 49           #define PEGASUS_ARRAY_T CIMObjectPath
 50           # include "ArrayImpl.h"
 51           #undef PEGASUS_ARRAY_T
 52           
 53           // ATTN: KS May 2002 P0 Add resolve method to CIMObjectPath.
 54           // Add a resolve method to this class to verify that the
 55           // reference is correct (that the class name corresponds to a real
 56           // class and that the property names are really keys and that all keys
 57           // of the class or used. Also be sure that there is a valid conversion
 58           // between the string value and the value of that property).
 59           //
 60           // ATTN: also check to see that the reference refers to a class that is the
 61           // same or derived from the _className member.
 62           
 63           ////////////////////////////////////////////////////////////////////////////////
 64           //
 65 kumpf 1.2 // Local routines:
 66           //
 67           ////////////////////////////////////////////////////////////////////////////////
 68           
 69           static String _escapeSpecialCharacters(const String& str)
 70           {
 71               String result;
 72           
 73               for (Uint32 i = 0, n = str.size(); i < n; i++)
 74               {
 75                   switch (str[i])
 76                   {
 77                       case '\n':
 78                           result += "\\n";
 79                           break;
 80           
 81                       case '\r':
 82                           result += "\\r";
 83                           break;
 84           
 85                       case '\t':
 86 kumpf 1.2                 result += "\\t";
 87                           break;
 88           
 89                       case '"':
 90                           result += "\\\"";
 91                           break;
 92           
 93                       default:
 94                           result += str[i];
 95                   }
 96               }
 97           
 98               return result;
 99           }
100           
101           static void _BubbleSort(Array<KeyBinding>& x)
102           {
103               Uint32 n = x.size();
104           
105               if (n < 2)
106                   return;
107 kumpf 1.2 
108               for (Uint32 i = 0; i < n - 1; i++)
109               {
110                   for (Uint32 j = 0; j < n - 1; j++)
111                   {
112                       if (String::compareNoCase(x[j].getName(), x[j+1].getName()) > 0)
113                       {
114                           KeyBinding t = x[j];
115                           x[j] = x[j+1];
116                           x[j+1] = t;
117                       }
118                   }
119               }
120           }
121           
122           ////////////////////////////////////////////////////////////////////////////////
123           //
124           // KeyBinding
125           //
126           ////////////////////////////////////////////////////////////////////////////////
127           
128 kumpf 1.2 class KeyBindingRep
129           {
130           public:
131               KeyBindingRep()
132               {
133               }
134           
135               KeyBindingRep(const KeyBindingRep& x)
136                   : _name(x._name), _value(x._value), _type(x._type)
137               {
138               }
139           
140               KeyBindingRep(
141 kumpf 1.7         const CIMName& name,
142 kumpf 1.2         const String& value,
143                   KeyBinding::Type type)
144                   : _name(name), _value(value), _type(type)
145               {
146               }
147           
148               ~KeyBindingRep()
149               {
150               }
151           
152               KeyBindingRep& operator=(const KeyBindingRep& x)
153               {
154                   if (&x != this)
155                   {
156                       _name = x._name;
157                       _value = x._value;
158                       _type = x._type;
159                   }
160                   return *this;
161               }
162           
163 kumpf 1.7     CIMName _name;
164 kumpf 1.2     String _value;
165               KeyBinding::Type _type;
166           };
167           
168           
169           KeyBinding::KeyBinding()
170           {
171               _rep = new KeyBindingRep();
172           }
173           
174           KeyBinding::KeyBinding(const KeyBinding& x)
175           {
176               _rep = new KeyBindingRep(*x._rep);
177           }
178           
179 kumpf 1.7 KeyBinding::KeyBinding(const CIMName& name, const String& value, Type type)
180 kumpf 1.2 {
181               _rep = new KeyBindingRep(name, value, type);
182           }
183           
184           KeyBinding::~KeyBinding()
185           {
186               delete _rep;
187           }
188           
189           KeyBinding& KeyBinding::operator=(const KeyBinding& x)
190           {
191               *_rep = *x._rep;
192               return *this;
193           }
194           
195 kumpf 1.7 const CIMName& KeyBinding::getName() const
196 kumpf 1.2 {
197               return _rep->_name;
198           }
199           
200 kumpf 1.7 void KeyBinding::setName(const CIMName& name)
201 kumpf 1.2 {
202               _rep->_name = name;
203           }
204           
205           const String& KeyBinding::getValue() const
206           {
207               return _rep->_value;
208           }
209           
210           void KeyBinding::setValue(const String& value)
211           {
212               _rep->_value = value;
213           }
214           
215           KeyBinding::Type KeyBinding::getType() const
216           {
217               return _rep->_type;
218           }
219           
220           void KeyBinding::setType(KeyBinding::Type type)
221           {
222 kumpf 1.2     _rep->_type = type;
223           }
224           
225           const char* KeyBinding::typeToString(KeyBinding::Type type)
226           {
227               switch (type)
228               {
229                   case KeyBinding::BOOLEAN:
230                       return "boolean";
231           
232                   case KeyBinding::STRING:
233                       return "string";
234           
235                   case KeyBinding::NUMERIC:
236                       return "numeric";
237           
238                   case KeyBinding::REFERENCE:
239                   default:
240                       PEGASUS_ASSERT(false);
241               }
242           
243 kumpf 1.2     return "unknown";
244           }
245           
246           Boolean operator==(const KeyBinding& x, const KeyBinding& y)
247           {
248               return
249 kumpf 1.7         x.getName().equal(y.getName()) &&
250 kumpf 1.2         String::equal(x.getValue(), y.getValue()) &&
251                   x.getType() == y.getType();
252           }
253           
254           
255           ////////////////////////////////////////////////////////////////////////////////
256           //
257           // CIMObjectPath
258           //
259           ////////////////////////////////////////////////////////////////////////////////
260           
261           class CIMObjectPathRep
262           {
263           public:
264               CIMObjectPathRep()
265               {
266               }
267           
268               CIMObjectPathRep(const CIMObjectPathRep& x)
269                   : _host(x._host), _nameSpace(x._nameSpace),
270                   _className(x._className), _keyBindings(x._keyBindings)
271 kumpf 1.2     {
272               }
273           
274               CIMObjectPathRep(
275                   const String& host,
276 kumpf 1.7         const CIMNamespaceName& nameSpace,
277                   const CIMName& className,
278 kumpf 1.2         const Array<KeyBinding>& keyBindings)
279                   : _host(host), _nameSpace(nameSpace),
280                   _className(className), _keyBindings(keyBindings)
281               {
282               }
283           
284               ~CIMObjectPathRep()
285               {
286               }
287           
288               CIMObjectPathRep& operator=(const CIMObjectPathRep& x)
289               {
290                   if (&x != this)
291                   {
292                       _host = x._host;
293                       _nameSpace = x._nameSpace;
294                       _className = x._className;
295                       _keyBindings = x._keyBindings;
296                   }
297                   return *this;
298               }
299 kumpf 1.2 
300               //
301               // Contains port as well (e.g., myhost:1234).
302               //
303               String _host;
304           
305 kumpf 1.7     CIMNamespaceName _nameSpace;
306               CIMName _className;
307 kumpf 1.2     Array<KeyBinding> _keyBindings;
308           };
309           
310           
311           CIMObjectPath::CIMObjectPath()
312           {
313               _rep = new CIMObjectPathRep();
314           }
315           
316           CIMObjectPath::CIMObjectPath(const CIMObjectPath& x)
317           {
318               _rep = new CIMObjectPathRep(*x._rep);
319           }
320           
321           CIMObjectPath::CIMObjectPath(const String& objectName)
322           {
323               // Test the objectName out to see if we get an exception
324               CIMObjectPath tmpRef;
325               tmpRef.set(objectName);
326           
327               _rep = new CIMObjectPathRep(*tmpRef._rep);
328 kumpf 1.2 }
329           
330           CIMObjectPath::CIMObjectPath(const char* objectName)
331           {
332               // Test the objectName out to see if we get an exception
333               CIMObjectPath tmpRef;
334               tmpRef.set(objectName);
335           
336               _rep = new CIMObjectPathRep(*tmpRef._rep);
337           }
338           
339           CIMObjectPath::CIMObjectPath(
340               const String& host,
341 kumpf 1.7     const CIMNamespaceName& nameSpace,
342               const CIMName& className,
343 kumpf 1.2     const Array<KeyBinding>& keyBindings)
344           {
345               // Test the objectName out to see if we get an exception
346               CIMObjectPath tmpRef;
347               tmpRef.set(host, nameSpace, className, keyBindings);
348           
349               _rep = new CIMObjectPathRep(*tmpRef._rep);
350           }
351           
352           CIMObjectPath::~CIMObjectPath()
353           {
354               delete _rep;
355           }
356           
357           CIMObjectPath& CIMObjectPath::operator=(const CIMObjectPath& x)
358           {
359               *_rep = *x._rep;
360               return *this;
361           }
362           
363           void CIMObjectPath::clear()
364 kumpf 1.2 {
365               _rep->_host.clear();
366               _rep->_nameSpace.clear();
367               _rep->_className.clear();
368               _rep->_keyBindings.clear();
369           }
370           
371           void CIMObjectPath::set(
372               const String& host,
373 kumpf 1.7     const CIMNamespaceName& nameSpace,
374               const CIMName& className,
375 kumpf 1.8     const Array<KeyBinding>& keyBindings)
376 kumpf 1.2 {
377              setHost(host);
378              setNameSpace(nameSpace);
379              setClassName(className);
380              setKeyBindings(keyBindings);
381           }
382           
383           Boolean CIMObjectPath::_parseHostElement(
384               const String& objectName,
385               char*& p,
386               String& host) throw(IllformedObjectName)
387           {
388               // See if there is a host name (true if it begins with "//"):
389               // Host is of the from <hostname>-<port> and begins with "//"
390               // and ends with "/":
391           
392               if (p[0] != '/' || p[1] != '/')
393               {
394                   return false;
395               }
396           
397 kumpf 1.2     p += 2;
398           
399               //----------------------------------------------------------------------
400               // Validate the hostname. Hostnames must match the following
401               // regular expression: "[A-Za-z][A-Za-z0-9-]*"
402               //----------------------------------------------------------------------
403           
404               char* q = p;
405           
406               if (!isalpha(*q))
407                   throw IllformedObjectName(objectName);
408           
409               q++;
410           
411               while (isalnum(*q) || *q == '-')
412                   q++;
413           
414               // We now expect a port (or default the port).
415           
416               if (*q == ':')
417               {
418 kumpf 1.2         q++;
419                   // Check for a port number:
420           
421                   if (!isdigit(*q))
422                       throw IllformedObjectName(objectName);
423                   
424                   while (isdigit(*q))
425                       q++;
426           
427                   // Finally, assign the host name:
428           
429                   host.assign(p, q - p);
430               }
431               else
432               {
433                   host.assign(p, q - p);
434           
435                   // Assign the default port number:
436           
437                   host.append(":");
438                   host.append(PEGASUS_CIMOM_DEFAULT_PORT_STRING);
439 kumpf 1.2     }
440           
441               // Check for slash terminating the entire sequence:
442           
443               if (*q != '/')
444               {
445                   host.clear();
446                   throw IllformedObjectName(objectName);
447               }
448           
449               p = ++q;
450           
451               return true;
452           }
453           
454           Boolean CIMObjectPath::_parseNamespaceElement(
455               const String& objectName,
456               char*& p,
457 kumpf 1.7     CIMNamespaceName& nameSpace)
458 kumpf 1.2 {
459               // If we don't find a valid namespace name followed by a ':', we
460               // assume we're not looking at a namespace name.
461           
462 kumpf 1.7     char* colon = strchr(p, ':');
463               if (!colon)
464               {
465                   return false;
466               }
467           
468 kumpf 1.2     //----------------------------------------------------------------------
469               // Validate the namespace path.  Namespaces must match the following
470               // regular expression: "[A-Za-z_]+(/[A-Za-z_]+)*"
471               //----------------------------------------------------------------------
472           
473 kumpf 1.7     String namespaceName = String(p, colon - p);
474               if (!CIMNamespaceName::legal(namespaceName))
475 kumpf 1.2     {
476 kumpf 1.7         throw IllformedObjectName(objectName);
477 kumpf 1.2     }
478 kumpf 1.7     nameSpace = namespaceName;
479 kumpf 1.2 
480 kumpf 1.7     p = colon+1;
481 kumpf 1.2     return true;
482           }
483           
484           /**
485               ATTN: RK - Association classes have keys whose types are
486               references.  These reference values must be treated specially
487               in the XML encoding, using the VALUE.REFERENCE tag structure.
488           
489               Pegasus had been passing reference values simply as String
490               values.  For example, EnumerateInstanceNames returned
491               KEYVALUEs of string type rather than VALUE.REFERENCEs.
492           
493               I've modified the XmlReader::getKeyBindingElement() and
494               XmlWriter::appendInstanceNameElement() methods to read and write
495               the XML in the proper format.  However, making that change
496               required that a CIMObjectPath object be able to distinguish
497               between a key of String type and a key of reference type.
498           
499               I've modified the String format of CIMObjectPaths slightly to
500               allow efficient processing of references whose keys are also
501               of reference type.  The "official" form uses the same
502 kumpf 1.2     encoding for key values of String type and of reference type,
503               and so it would be necessary to retrieve the class definition
504               and look up the types of the key properties to determine how
505               to treat the key values.  This is clearly too inefficient for
506               internal transformations between CIMObjectPaths and String
507               values.
508           
509               The workaround is to encode a 'R' at the beginning of the
510               value for a key of reference type (before the opening '"').
511               This allows the parser to know a priori whether the key is of
512               String or reference type.
513           
514               In this example:
515           
516                   MyClass.Key1="StringValue",Key2=R"RefClass.KeyA="StringA",KeyB=10"
517           
518               Property Key1 of class MyClass is of String type, and so it
519               gets the usual encoding.  Key2 is a reference property, so
520               the extra 'R' is inserted before its encoded value.  Note
521               that this algorithm is recursive, such that RefClass could
522               include KeyC of reference type, which would also get encoded
523 kumpf 1.2     with the 'R' notation.
524           
525               The toString() method inserts the 'R' to provide symmetry.  A
526               new KeyBinding type (REFERENCE) has been defined to denote
527               keys in a CIMObjectPath that are of reference type.  This
528               KeyBinding type must be used appropriately for
529               CIMObjectPath::toString() to behave correctly.
530           
531               A result of this change is that instances names in the
532               instance repository will include this extra 'R' character.
533               Note that for user-facing uses of the String encoding of
534               instance names (such as might appear in MOF for static
535               association instances or in the CGI client), this solution
536               is non-standard and therefore unacceptable.  It is likely
537               that these points will need to process the more expensive
538               operation of retrieving the class definition to determine
539               the key property types.
540           */
541           void CIMObjectPath::_parseKeyBindingPairs(
542               const String& objectName,
543               char*& p,
544 kumpf 1.2     Array<KeyBinding>& keyBindings)  throw(IllformedObjectName)
545           {
546               // Get the key-value pairs:
547           
548               while (*p)
549               {
550                   // Get key part:
551           
552 kumpf 1.5         char* equalsign = strchr(p, '=');
553                   if (!equalsign)
554 kumpf 1.2         {
555                       throw IllformedObjectName(objectName);
556                   }
557           
558 kumpf 1.5         *equalsign = 0;
559 kumpf 1.7         CIMName keyString(p);
560 kumpf 1.2 
561                   if (!CIMName::legal(keyString))
562                       throw IllformedObjectName(objectName);
563           
564                   // Get the value part:
565           
566                   String valueString;
567 kumpf 1.5         p = equalsign + 1;
568 kumpf 1.2         KeyBinding::Type type;
569           
570                   if (*p == 'R')
571                   {
572                       p++;
573           
574                       type = KeyBinding::REFERENCE;
575           
576                       if (*p++ != '"')
577                           throw IllformedObjectName(objectName);
578           
579                       while (*p && *p != '"')
580                       {
581                           // ATTN: need to handle special characters here:
582           
583                           if (*p == '\\')
584                               *p++;
585           
586                           valueString.append(*p++);
587                       }
588           
589 kumpf 1.2             if (*p++ != '"')
590                           throw IllformedObjectName(objectName);
591                   }
592                   else if (*p == '"')
593                   {
594                       p++;
595           
596                       type = KeyBinding::STRING;
597           
598                       while (*p && *p != '"')
599                       {
600                           // ATTN: need to handle special characters here:
601           
602                           if (*p == '\\')
603                               *p++;
604           
605                           valueString.append(*p++);
606                       }
607           
608                       if (*p++ != '"')
609                           throw IllformedObjectName(objectName);
610 kumpf 1.2         }
611                   else if (toupper(*p) == 'T' || toupper(*p) == 'F')
612                   {
613                       type = KeyBinding::BOOLEAN;
614           
615                       char* r = p;
616                       Uint32 n = 0;
617           
618                       while (*r && *r != ',')
619                       {
620                           *r = toupper(*r);
621                           r++;
622                           n++;
623                       }
624           
625                       if (!(((strncmp(p, "TRUE", n) == 0) && n == 4) ||
626                             ((strncmp(p, "FALSE", n) == 0) && n == 5)))
627                           throw IllformedObjectName(objectName);
628           
629                       valueString.assign(p, n);
630           
631 kumpf 1.2             p = p + n;
632                   }
633                   else
634                   {
635                       type = KeyBinding::NUMERIC;
636           
637                       char* r = p;
638                       Uint32 n = 0;
639           
640                       while (*r && *r != ',')
641                       {
642                           r++;
643                           n++;
644                       }
645           
646                       Boolean isComma = false;
647                       if (*r)
648                       {
649                           *r = '\0';
650                           isComma = true;
651                       }
652 kumpf 1.2 
653                       Sint64 x;
654           
655                       if (!XmlReader::stringToSignedInteger(p, x))
656                           throw IllformedObjectName(objectName);
657           
658                       valueString.assign(p, n);
659           
660                       if (isComma)
661                       {
662                           *r = ',';
663                       }
664           
665                       p = p + n;
666                   }
667           
668                   keyBindings.append(KeyBinding(keyString, valueString, type));
669           
670                   if (*p)
671                   {
672                       if (*p++ != ',')
673 kumpf 1.2             {
674                           throw IllformedObjectName(objectName);
675                       }
676                   }
677               }
678           
679               _BubbleSort(keyBindings);
680           }
681           
682           void CIMObjectPath::set(const String& objectName)  throw(IllformedObjectName)
683           {
684               clear();
685           
686               //--------------------------------------------------------------------------
687               // We will extract components from an object name. Here is an sample
688               // object name:
689               //
690               //     //atp:9999/root/cimv25:TennisPlayer.first="Patrick",last="Rafter"
691               //--------------------------------------------------------------------------
692           
693               // Convert to a C String first:
694 kumpf 1.2 
695 kumpf 1.4     char* p = objectName.allocateCString();
696 kumpf 1.2     ArrayDestroyer<char> destroyer(p);
697               Boolean gotHost;
698               Boolean gotNamespace;
699           
700               gotHost = _parseHostElement(objectName, p, _rep->_host);
701               gotNamespace = _parseNamespaceElement(objectName, p, _rep->_nameSpace);
702           
703               if (gotHost && !gotNamespace)
704               {
705                   throw IllformedObjectName(objectName);
706               }
707           
708               // Extract the class name:
709           
710               char* dot = strchr(p, '.');
711           
712               if (!dot)
713               {
714                   if (!CIMName::legal(p))
715                   {
716                       throw IllformedObjectName(objectName);
717 kumpf 1.2         }
718           
719                   // ATTN: remove this later: a reference should only be able to hold
720                   // an instance name.
721           
722 kumpf 1.7         _rep->_className = p;
723 kumpf 1.2         return;
724               }
725           
726 kumpf 1.7     String className = String(p, dot - p);
727               if (!CIMName::legal(className))
728               {
729                   throw IllformedObjectName(objectName);
730               }
731               _rep->_className = className;
732 kumpf 1.2 
733               // Advance past dot:
734           
735               p = dot + 1;
736           
737               _parseKeyBindingPairs(objectName, p, _rep->_keyBindings);
738           }
739           
740           CIMObjectPath& CIMObjectPath::operator=(const String& objectName)
741           {
742               set(objectName);
743               return *this;
744           }
745           
746           CIMObjectPath& CIMObjectPath::operator=(const char* objectName)
747           {
748               set(objectName);
749               return *this;
750           }
751           
752           const String& CIMObjectPath::getHost() const
753 kumpf 1.2 {
754               return _rep->_host;
755           }
756           
757           void CIMObjectPath::setHost(const String& host)
758           {
759               _rep->_host = host;
760           }
761           
762 kumpf 1.7 const CIMNamespaceName& CIMObjectPath::getNameSpace() const
763 kumpf 1.2 {
764               return _rep->_nameSpace;
765           }
766           
767 kumpf 1.7 void CIMObjectPath::setNameSpace(const CIMNamespaceName& nameSpace)
768 kumpf 1.2 {
769              _rep->_nameSpace = nameSpace;
770           }
771           
772 kumpf 1.7 const CIMName& CIMObjectPath::getClassName() const
773 kumpf 1.2 {
774               return _rep->_className;
775           }
776           
777 kumpf 1.7 void CIMObjectPath::setClassName(const CIMName& className)
778 kumpf 1.2 {
779               _rep->_className = className;
780           }
781           
782           const Array<KeyBinding>& CIMObjectPath::getKeyBindings() const
783           {
784               return _rep->_keyBindings;
785           }
786           
787           void CIMObjectPath::setKeyBindings(const Array<KeyBinding>& keyBindings)
788           {
789               _rep->_keyBindings = keyBindings;
790               _BubbleSort(_rep->_keyBindings);
791           }
792           
793           String CIMObjectPath::toString(Boolean includeHost) const
794           {
795               String objectName;
796           
797               // Get the host:
798           
799 kumpf 1.2     if (_rep->_host.size() && includeHost)
800               {
801                   objectName = "//";
802                   objectName += _rep->_host;
803                   objectName += "/";
804               }
805           
806               // Get the namespace (if we have a host name, we must write namespace):
807           
808 kumpf 1.7     if (!_rep->_nameSpace.isNull() || _rep->_host.size())
809 kumpf 1.2     {
810                   objectName += _rep->_nameSpace;
811                   objectName += ":";
812               }
813           
814               // Get the class name:
815           
816               objectName.append(getClassName());
817           
818               if (isInstanceName())
819               {
820                   objectName.append('.');
821           
822                   // Append each key-value pair:
823           
824                   const Array<KeyBinding>& keyBindings = getKeyBindings();
825           
826                   for (Uint32 i = 0, n = keyBindings.size(); i < n; i++)
827                   {
828                       objectName.append(keyBindings[i].getName());
829                       objectName.append('=');
830 kumpf 1.2 
831                       const String& value = _escapeSpecialCharacters(
832                           keyBindings[i].getValue());
833           
834                       KeyBinding::Type type = keyBindings[i].getType();
835                   
836                       if (type == KeyBinding::REFERENCE)
837                           objectName.append('R');
838           
839                       if (type == KeyBinding::STRING || type == KeyBinding::REFERENCE)
840                           objectName.append('"');
841           
842                       objectName.append(value);
843           
844                       if (type == KeyBinding::STRING || type == KeyBinding::REFERENCE)
845                           objectName.append('"');
846           
847                       if (i + 1 != n)
848                           objectName.append(',');
849                   }
850               }
851 kumpf 1.2 
852               return objectName;
853           }
854           
855           String CIMObjectPath::toStringCanonical(Boolean includeHost) const
856           {
857               CIMObjectPath ref = *this;
858           
859               // ATTN-RK-P2-20020510: Need to make hostname and namespace lower case?
860           
861 kumpf 1.7     String classNameLower = ref._rep->_className;
862               classNameLower.toLower();
863               ref._rep->_className = classNameLower;
864 kumpf 1.2 
865               for (Uint32 i = 0, n = ref._rep->_keyBindings.size(); i < n; i++)
866               {
867 kumpf 1.7         String keyBindingNameLower = ref._rep->_keyBindings[i]._rep->_name;
868                   keyBindingNameLower.toLower();
869                   ref._rep->_keyBindings[i]._rep->_name = keyBindingNameLower;
870 kumpf 1.2     }
871           
872               return ref.toString(includeHost);
873           }
874           
875           CIMObjectPath CIMObjectPath::clone() const
876           {
877               return CIMObjectPath(*this);
878           }
879           
880           Boolean CIMObjectPath::identical(const CIMObjectPath& x) const
881           {
882               return
883                   String::equal(_rep->_host, x._rep->_host) &&
884 kumpf 1.7         _rep->_nameSpace.equal(x._rep->_nameSpace) &&
885                   _rep->_className.equal(x._rep->_className) &&
886 kumpf 1.2         _rep->_keyBindings == x._rep->_keyBindings;
887           }
888           
889           Uint32 CIMObjectPath::makeHashCode() const
890           {
891               return HashFunc<String>::hash(toStringCanonical());
892           }
893           
894           Boolean CIMObjectPath::isInstanceName() const
895           {
896               return _rep->_keyBindings.size() != 0;
897           }
898           
899           KeyBindingArray CIMObjectPath::getKeyBindingArray()
900           {
901               return KeyBindingArray();
902           }
903           
904           
905           Boolean operator==(const CIMObjectPath& x, const CIMObjectPath& y)
906           {
907 kumpf 1.2     return x.identical(y);
908           }
909           
910           Boolean operator!=(const CIMObjectPath& x, const CIMObjectPath& y)
911           {
912               return !operator==(x, y);
913           }
914           
915           PEGASUS_STD(ostream)& operator<<(
916               PEGASUS_STD(ostream)& os,
917               const CIMObjectPath& x)
918           {
919               return os << x.toString();
920           }
921 chip  1.1 
922           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2