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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2