1 /*
2 (C) Copyright IBM Corp. 2006, 2013
3
4 THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5 ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6 CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7
8 You can obtain a current copy of the Eclipse Public License from
9 http://www.opensource.org/licenses/eclipse-1.0.php
10
11 @author : Endre Bak, ebak@de.ibm.com
12 *
13 * Flag Date Prog Description
14 * -------------------------------------------------------------------------------
15 * 1565892 2006-10-06 ebak Make SBLIM client JSR48 compliant
16 * 1669961 2006-04-16 lupusalex CIMTypedElement.getType() =>getDataType()
17 * 1716991 2006-05-11 lupusalex FVT: CIMObjectPath.equals() should ignore host name
18 * 1737141 2007-06-18 ebak Sync up with JSR48 evolution
19 * 1917321 2008-05-29 rgummada javadoc update to constructors with 2 and more parms
20 * 2003590 2008-06-30 blaschke-oss Change licensing from CPL to EPL
21 * 2524131 2009-01-21 raman_arora Upgrade client to JDK 1.5 (Phase 1)
22 * 2763216 2009-04-14 blaschke-oss Code cleanup: visible spelling/grammar errors
23 * 2797550 2009-06-01 raman_arora JSR48 compliance - add Java Generics
24 * 2845128 2009-09-24 blaschke-oss CIMObjectPath.toString() misses host
25 * 2935258 2010-01-22 blaschke-oss Sync up javax.cim.* javadoc with JSR48 1.0.0
26 * 2944824 2010-02-08 blaschke-oss Missing getXmlSchemaName() in CIMObjectPath
27 * 2975975 2010-03-24 blaschke-oss TCK: CIMObjectPath(String) does not handle null
28 * 3023141 2010-07-01 blaschke-oss CIMObjectPath uses # constructor instead of valueOf
29 * 3496349 2012-03-02 blaschke-oss JSR48 1.0.0: add CIMObjectPath getKeyValue
30 * 3510090 2012-03-23 blaschke-oss Fix CIMObjectPath.toString() inconsistencies
31 * 3513343 2012-03-31 blaschke-oss TCK: CIMObjectPath must validate XML schema name
32 * 3513347 2012-03-31 blaschke-oss TCK: CIMObjectPath allows empty string
33 * 3521131 2012-04-24 blaschke-oss Sync up javax.* javadoc with JSR48 1.0.0 Final II
34 * 3521119 2012-04-24 blaschke-oss JSR48 1.0.0: remove CIMObjectPath 2/3/4-parm ctors
35 * 3529151 2012-08-22 blaschke-oss TCK: CIMInstance property APIs include keys from COP
36 * 2660 2013-09-04 blaschke-oss CIMObjectPath.equalsModelPath same as equals
37 * 2716 2013-12-11 blaschke-oss Sync up javax.* javadoc with JSR48 1.0.0 Final V
38 */
39
40 package org.metricshub.wbem.javax.cim;
41
42 /*-
43 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
44 * WBEM Java Client
45 * ჻჻჻჻჻჻
46 * Copyright 2023 - 2025 MetricsHub
47 * ჻჻჻჻჻჻
48 * Licensed under the Apache License, Version 2.0 (the "License");
49 * you may not use this file except in compliance with the License.
50 * You may obtain a copy of the License at
51 *
52 * http://www.apache.org/licenses/LICENSE-2.0
53 *
54 * Unless required by applicable law or agreed to in writing, software
55 * distributed under the License is distributed on an "AS IS" BASIS,
56 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
57 * See the License for the specific language governing permissions and
58 * limitations under the License.
59 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
60 */
61
62 import java.io.Serializable;
63 import java.net.MalformedURLException;
64 import java.net.URL;
65 import java.util.Arrays;
66 import org.metricshub.wbem.sblim.cimclient.internal.cim.CIMElementSorter;
67 import org.metricshub.wbem.sblim.cimclient.internal.uri.BooleanValue;
68 import org.metricshub.wbem.sblim.cimclient.internal.uri.CharValue;
69 import org.metricshub.wbem.sblim.cimclient.internal.uri.DateTimeValue;
70 import org.metricshub.wbem.sblim.cimclient.internal.uri.IntegerValue;
71 import org.metricshub.wbem.sblim.cimclient.internal.uri.KeyValuePair;
72 import org.metricshub.wbem.sblim.cimclient.internal.uri.KeyValuePairs;
73 import org.metricshub.wbem.sblim.cimclient.internal.uri.RealValue;
74 import org.metricshub.wbem.sblim.cimclient.internal.uri.ReferenceValue;
75 import org.metricshub.wbem.sblim.cimclient.internal.uri.StringValue;
76 import org.metricshub.wbem.sblim.cimclient.internal.uri.URI;
77 import org.metricshub.wbem.sblim.cimclient.internal.uri.URIString;
78 import org.metricshub.wbem.sblim.cimclient.internal.uri.Value;
79 import org.metricshub.wbem.sblim.cimclient.internal.util.MOF;
80
81 //Sync'd against JSR48 1.0.0 javadoc (version 1.7.0_03) on Tue Dec 10 07:02:50 EST 2013
82 /**
83 * This class represents the CIM Object Path as defined by the Distributed
84 * Management Task Force (<a href=http://www.dmtf.org>DMTF</a>) CIM
85 * Infrastructure Specification (<a href=
86 * "http://dmtf.org/sites/default/files/standards/documents/DSP0004_2.7.0.pdf"
87 * >DSP004</a>). In order to uniquely identify a given object, a CIM object path
88 * includes the host, namespace, object name and keys (if the object is an
89 * instance).<br>
90 * <br>
91 * For example, the object path:<br>
92 * <br>
93 * <code>
94 * http://myserver/root/cimv2:My_ComputerSystem.Name=mycomputer,
95 * CreationClassName=My_ComputerSystem
96 * </code><br>
97 * <br>
98 * has two parts:<br>
99 * <br>
100 * <ul><li>Namespace Path</li>
101 * <li style="list-style-type: none">
102 * http://myserver/root/cimv2
103 * JSR48 defines the namespace path to include the scheme, host, port (optional)
104 * and namespace
105 * The example specifies the <code>"root/cimv2"</code> namespace on the host
106 * <code>myserver</code>.</li> <li>Model Path</li>
107 * <li style="list-style-type: none"><code>My_ComputerSystem.Name=mycomputer,CreationClassName=My_ComputerSystem
108 * </code><br>
109 * DSP0004 defines the model path for a class or qualifier type as the name of
110 * the class/qualifier type<br>
111 * DSP0004 defines the model path for an instance as the class
112 * name.(key=value),*<br>
113 * The example specifies an instance for the class
114 * <code>My_ComputerSystem</code> which is uniquely identified by two key
115 * properties and values: </li><li><code>Name=mycomputer</code></li>
116 * <li>
117 * <code>CreationClassName=My_ComputerSystem</code></li> </ul>
118 */
119 public class CIMObjectPath implements Serializable {
120 private static final long serialVersionUID = 4593259690658425064L;
121
122 private String iScheme, iHost, iPort, iNamespace, iObjectName, iXmlSchemaName;
123
124 private CIMProperty<?>[] iKeys;
125
126 /**
127 * Class TypeValuePair represents a type-value pair with special
128 * identification functionality for integer and real numbers.
129 *
130 */
131 private static class TypeValuePair {
132 private CIMDataType iType;
133
134 private Object iValue;
135
136 /**
137 * Constructs a type-value pair with the specified type and value.
138 *
139 * @param pType
140 * Type.
141 * @param pValue
142 * Value.
143 */
144 public TypeValuePair(CIMDataType pType, Object pValue) {
145 this.iType = pType;
146 this.iValue = pValue;
147 }
148
149 /**
150 * Constructs a type-value pair with the specified integer value.
151 *
152 * @param intVal
153 * Integer value.
154 */
155 public TypeValuePair(IntegerValue intVal) {
156 if (intVal.isSigned()) {
157 switch (intVal.getBitWidth()) {
158 case 8:
159 this.iType = CIMDataType.SINT8_T;
160 this.iValue = Byte.valueOf(intVal.byteValue());
161 break;
162 case 16:
163 this.iType = CIMDataType.SINT16_T;
164 this.iValue = Short.valueOf(intVal.shortValue());
165 break;
166 case 32:
167 this.iType = CIMDataType.SINT32_T;
168 this.iValue = Integer.valueOf(intVal.intValue());
169 break;
170 default:
171 this.iType = CIMDataType.SINT64_T;
172 this.iValue = Long.valueOf(intVal.longValue());
173 }
174 } else { // unsigned integers
175 switch (intVal.getBitWidth()) {
176 case 8:
177 this.iType = CIMDataType.UINT8_T;
178 this.iValue = new UnsignedInteger8(intVal.shortValue());
179 break;
180 case 16:
181 this.iType = CIMDataType.UINT16_T;
182 this.iValue = new UnsignedInteger16(intVal.intValue());
183 break;
184 case 32:
185 this.iType = CIMDataType.UINT32_T;
186 this.iValue = new UnsignedInteger32(intVal.longValue());
187 break;
188 default:
189 this.iType = CIMDataType.UINT64_T;
190 this.iValue = new UnsignedInteger64(intVal.bigIntValue());
191 }
192 }
193 }
194
195 /**
196 * Constructs a type-value pair with the specified real value.
197 *
198 * @param pRealVal
199 * Real value.
200 */
201 public TypeValuePair(RealValue pRealVal) {
202 // TODO: handle precision
203 if (pRealVal.isDouble()) {
204 this.iType = CIMDataType.REAL64_T;
205 this.iValue = new Double(pRealVal.doubleValue());
206 } else {
207 this.iType = CIMDataType.REAL32_T;
208 this.iValue = new Float(pRealVal.floatValue());
209 }
210 }
211
212 /**
213 * Returns the type of the type-value pair.
214 *
215 * @return Type of type-value pair.
216 */
217 public CIMDataType getType() {
218 return this.iType;
219 }
220
221 /**
222 * Returns the value of the type-value pair.
223 *
224 * @return Value of type-value pair.
225 */
226 public Object getValue() {
227 return this.iValue;
228 }
229 }
230
231 /**
232 * Extracts and returns sorted list of key-value pairs from the URI.
233 *
234 * @param pURI
235 * The Uniform Resource Identifier.
236 * @return Sorted array of keys in URI.
237 */
238 private CIMProperty<?>[] getKeysFromURI(URI pURI) {
239 KeyValuePairs pairs = pURI.getKeyValuePairs();
240 if (pairs == null) return null;
241 CIMProperty<?>[] keys = new CIMProperty[pairs.size()];
242 for (int i = 0; i < pairs.size(); i++) {
243 KeyValuePair pair = (KeyValuePair) pairs.elementAt(i);
244 String name = pair.getKey();
245 Value uriVal = pair.getValue();
246 TypeValuePair typeValue;
247 if (uriVal instanceof StringValue) {
248 typeValue = new TypeValuePair(CIMDataType.STRING_T, uriVal.toString());
249 } else if (uriVal instanceof ReferenceValue) {
250 ReferenceValue refVal = (ReferenceValue) uriVal;
251 CIMObjectPath op = new CIMObjectPath(refVal.getRef());
252 typeValue = new TypeValuePair(new CIMDataType(op.getObjectName()), op);
253 } else if (uriVal instanceof BooleanValue) {
254 typeValue = new TypeValuePair(CIMDataType.BOOLEAN_T, ((BooleanValue) uriVal).getBoolean());
255 } else if (uriVal instanceof CharValue) {
256 typeValue = new TypeValuePair(CIMDataType.CHAR16_T, ((CharValue) uriVal).getCharacter());
257 } else if (uriVal instanceof IntegerValue) {
258 typeValue = new TypeValuePair((IntegerValue) uriVal);
259 } else if (uriVal instanceof RealValue) {
260 typeValue = new TypeValuePair((RealValue) uriVal);
261 } else if (uriVal instanceof DateTimeValue) {
262 typeValue = new TypeValuePair(CIMDataType.DATETIME_T, ((DateTimeValue) uriVal).getDateTime());
263 } else {
264 // TODO: error or warning tracing
265 typeValue = new TypeValuePair(CIMDataType.INVALID_T, null);
266 }
267 keys[i] = new CIMProperty<Object>(name, typeValue.getType(), typeValue.getValue(), true, false, null);
268 }
269 return (CIMProperty[]) CIMElementSorter.sort(keys);
270 }
271
272 /**
273 * Initializes the elements of the <code>CIMObjectPath</code> from the given
274 * URI.
275 *
276 * @param pURI
277 * The Uniform Resource Identifier.
278 */
279 private void setURI(URI pURI) {
280 this.iNamespace = pURI.getNamespaceName();
281 this.iScheme = pURI.getNamespaceType();
282 this.iHost = pURI.getHost();
283 this.iPort = pURI.getPort();
284 this.iObjectName = pURI.getClassName();
285 this.iKeys = getKeysFromURI(pURI);
286 }
287
288 /**
289 * Constructs a CIM Object Path referencing an instance of the specified CIM
290 * element in the given URI.
291 *
292 * @param pURI
293 * The Uniform Resource Identifier.
294 */
295 private CIMObjectPath(URI pURI) {
296 setURI(pURI);
297 }
298
299 /**
300 * Constructs a CIM Object Path referencing a CIM element. The name can
301 * refer to a class name or a qualifier type name, depending on the
302 * particular CIM element identified. In order to refer to an instance, the
303 * key properties and their corresponding values must be set.<br>
304 * <br>
305 * Should be able to handle strings, like:<br>
306 * <code>
307 * http://myserver.org:5066/root/cimv2:My_ComputerSystem.Name="mycmp",CreationClassName="My_ComputerSystem"
308 * <br>
309 * http://myserver.org/root/cimv2:My_ComputerSystem.Name="mycmp",CreationClassName="My_ComputerSystem"
310 * <br>
311 * //myserver.org/root/cimv2:My_ComputerSystem<br>
312 * /root/cimv2:My_ComputerSystem
313 * </code>
314 *
315 * @param pObjectPath
316 * The string representation of an object path for a CIM element
317 * that will be parsed and used to initialize the object.
318 * @throws IllegalArgumentException
319 * If the <code>pObjectPath</code> is <code>null</code> or an
320 * empty string.
321 */
322 public CIMObjectPath(String pObjectPath) {
323 URI uri;
324
325 if (pObjectPath == null) throw new IllegalArgumentException("ObjectPath is null!");
326 if (pObjectPath.trim().length() == 0) throw new IllegalArgumentException("ObjectPath is empty!");
327
328 try {
329 uri = URI.parse(pObjectPath);
330 } catch (IllegalArgumentException asURI) {
331 try {
332 uri = URI.parseRef(new URIString(pObjectPath), false);
333 } catch (IllegalArgumentException asUntypedRef) {
334 try {
335 uri = URI.parseRef(new URIString(pObjectPath), true);
336 } catch (IllegalArgumentException asTypedRef) {
337 String msg =
338 "Parsing of ObjectPath string has failed!\n" +
339 "Nested error messages:\n" +
340 "When parsing as normal URI string:\n" +
341 asURI.getMessage() +
342 "When parsing as untyped reference:\n" +
343 asUntypedRef.getMessage() +
344 "When parsing as typed reference:\n" +
345 asTypedRef.getMessage();
346 // TODO: tracing
347 throw new IllegalArgumentException(msg);
348 }
349 }
350 }
351 setURI(uri);
352 }
353
354 /**
355 * Constructs a CIM Object Path referencing an instance of the specified CIM
356 * element as defined in the specified namespace on the specified host and
357 * identified by the given key properties and their corresponding values.
358 * Note that the connection mechanism and the port number to which a client
359 * connection is established are also specified.<br>
360 * <br>
361 * NOTE: When using this API against OpenPegasus CIMOM, do not provide the
362 * preceding '/' in the namespace parameter. For example, OpenPegasus will
363 * accept <code>"root/cimv2"</code> as a namespace but will not accept
364 * <code>"/root/cimv2"</code>.
365 *
366 * @param pScheme
367 * The connection scheme to the host (e.g. http, https, ...)
368 * @param pHost
369 * The host name or IP Address.
370 * @param pPort
371 * The port on the host to which the connection was established.
372 * @param pNamespace
373 * The namepace in which the CIM element is defined.
374 * @param pObjectName
375 * The name of the CIM element referenced.
376 * @param pKeys
377 * The keys and their corresponding values that identify an
378 * instance of the CIM element.
379 */
380 public CIMObjectPath(
381 String pScheme,
382 String pHost,
383 String pPort,
384 String pNamespace,
385 String pObjectName,
386 CIMProperty<?>[] pKeys
387 ) {
388 this.iScheme = pScheme;
389 this.iHost = pHost;
390 this.iPort = pPort;
391 this.iNamespace = pNamespace;
392 this.iObjectName = pObjectName;
393 if (pKeys != null) {
394 for (int i = 0; i < pKeys.length; i++) if (!pKeys[i].isKey()) throw new IllegalArgumentException(
395 "All CIMObjectPath properties must be keys!"
396 );
397 }
398 this.iKeys = (CIMProperty[]) CIMElementSorter.sort(pKeys);
399 }
400
401 /**
402 * Constructs a CIM Object Path referencing an instance of the specified CIM
403 * element as defined in the specified namespace on the specified host and
404 * identified by the given key properties and their corresponding values.
405 * Note that the connection mechanism and the port number to which a client
406 * connection is established are also specified.<br>
407 * <br>
408 * NOTE: When using this API against OpenPegasus CIMOM, do not provide the
409 * preceding '/' in the namespace parameter. For example, OpenPegasus will
410 * accept <code>"root/cimv2"</code> as a namespace but will not accept
411 * <code>"/root/cimv2"</code>.
412 *
413 * @param pScheme
414 * The connection scheme to the host (e.g. http, https, ...)
415 * @param pHost
416 * The host name or IP Address.
417 * @param pPort
418 * The port on the host to which the connection was established.
419 * @param pNamespace
420 * The namepace in which the CIM element is defined.
421 * @param pObjectName
422 * The name of the CIM element referenced.
423 * @param pKeys
424 * The keys and their corresponding values that identify an
425 * instance of the CIM element.
426 * @param pXmlSchemaName
427 * The name of the XML Schema for this object. This is only
428 * needed for protocols that require this information.
429 */
430 public CIMObjectPath(
431 String pScheme,
432 String pHost,
433 String pPort,
434 String pNamespace,
435 String pObjectName,
436 CIMProperty<?>[] pKeys,
437 String pXmlSchemaName
438 ) {
439 this(pScheme, pHost, pPort, pNamespace, pObjectName, pKeys);
440 if (pXmlSchemaName != null) {
441 try {
442 new URL(pXmlSchemaName);
443 } catch (MalformedURLException e) {
444 throw new IllegalArgumentException(e);
445 }
446 }
447 this.iXmlSchemaName = pXmlSchemaName;
448 }
449
450 /**
451 * Compares this CIM object path with the specified CIM object path for
452 * equality.
453 *
454 * @param pObj
455 * The object to compare to this CIM object path. Only the model
456 * paths are compared.
457 * @return <code>true</code> if the specified path references the same
458 * object, otherwise <code>false</code> is returned.
459 */
460 @Override
461 public boolean equals(Object pObj) {
462 return equalsWorker(pObj, true);
463 }
464
465 private boolean equalsWorker(Object pObj, boolean pIncludeNamespacePath) {
466 if (!(pObj instanceof CIMObjectPath)) return false;
467 CIMObjectPath that = (CIMObjectPath) pObj;
468 // hostname information is not any longer part of the comparison, since
469 // there is no reliable way to attach hostnames
470 if (pIncludeNamespacePath) {
471 boolean namespaceEqual =
472 (this.iNamespace == null ? that.iNamespace == null : this.iNamespace.equalsIgnoreCase(that.iNamespace));
473 if (!namespaceEqual) return false;
474 }
475 return (
476 (this.iObjectName == null ? that.iObjectName == null : this.iObjectName.equalsIgnoreCase(that.iObjectName)) &&
477 keysEqual(that)
478 );
479 }
480
481 /**
482 * Compares this CIM object path's keys with the specified CIM object path's
483 * keys for equality.<br>
484 * <br>
485 * NOTE: <code>CIMProperty.equals()</code> shouldn't be used for keys,
486 * because the XML doesn't contain originClass and propagated information.
487 *
488 * @param pThat
489 * The object path whose keys are to be compared to this CIM
490 * object path's keys.
491 * @return <code>true</code> if the keys are the same, otherwise
492 * <code>false</code> is returned.
493 */
494 private boolean keysEqual(CIMObjectPath pThat) {
495 if (pThat == this) return true;
496 if (this.iKeys == null) return pThat.iKeys == null;
497 if (pThat.iKeys == null) return false;
498 if (this.iKeys.length != pThat.iKeys.length) return false;
499 for (int i = 0; i < this.iKeys.length; i++) {
500 CIMProperty<?> thisKey = this.iKeys[i], thatKey = pThat.iKeys[i];
501 if (!equals(thisKey, thatKey)) {
502 return false;
503 }
504 }
505 return true;
506 }
507
508 /**
509 * Compares two properties for equality.
510 *
511 * @param pThis
512 * First property.
513 * @param pThat
514 * Second property.
515 * @return <code>true</code> if the properties are equal, <code>false</code>
516 * otherwise.
517 */
518 private boolean equals(CIMProperty<?> pThis, CIMProperty<?> pThat) {
519 if (pThis.getDataType() != null && pThis.getDataType().isArray()) {
520 return (
521 ncEqualsIC(pThis.getName(), pThat.getName()) &&
522 ncEquals(pThis.getDataType(), pThat.getDataType()) &&
523 Arrays.equals((Object[]) pThis.getValue(), (Object[]) pThat.getValue())
524 );
525 }
526 return (
527 ncEqualsIC(pThis.getName(), pThat.getName()) &&
528 ncEquals(pThis.getDataType(), pThat.getDataType()) &&
529 ncEquals(pThis.getValue(), pThat.getValue())
530 );
531 }
532
533 /**
534 * Compares two objects for equality.
535 *
536 * @param pThis
537 * First object.
538 * @param pThat
539 * Second object.
540 * @return <code>true</code> if the objects are equal, <code>false</code>
541 * otherwise.
542 */
543 private boolean ncEquals(Object pThis, Object pThat) {
544 return pThis == null ? pThat == null : pThis.equals(pThat);
545 }
546
547 /**
548 * Compares two strings for equality, ignoring case.
549 *
550 * @param pThis
551 * First string.
552 * @param pThat
553 * Second string.
554 * @return <code>true</code> if the strings are equal, <code>false</code>
555 * otherwise.
556 */
557 private boolean ncEqualsIC(String pThis, String pThat) {
558 return pThis == null ? pThat == null : pThis.equalsIgnoreCase(pThat);
559 }
560
561 /**
562 * Compares this model path with the specified model path for equality. If
563 * the model path includes references, then the references will also be
564 * compared for the model path (i.e. the namespace part of the object path
565 * will be ignored).
566 *
567 * @param pModelPath
568 * The object to compare.
569 * @return <code>true</code> if the specified path references the same
570 * object, otherwise <code>false</code>.
571 */
572 public boolean equalsModelPath(CIMObjectPath pModelPath) {
573 return equalsWorker(pModelPath, false);
574 }
575
576 /**
577 * Gets the host.
578 *
579 * @return The name of the host.
580 */
581 public String getHost() {
582 return this.iHost;
583 }
584
585 /**
586 * Gets a key property by name.
587 *
588 * @param pName
589 * The name of the key property to retrieve.
590 * @return The <code>CIMProperty</code> with the given name, or
591 * <code>null</code> if it is not found.
592 */
593 public CIMProperty<?> getKey(String pName) {
594 return (CIMProperty<?>) CIMElementSorter.find(this.iKeys, pName);
595 }
596
597 /**
598 * Gets all key properties.
599 *
600 * @return The container of key properties.
601 */
602 public CIMProperty<?>[] getKeys() {
603 return this.iKeys == null ? new CIMProperty[0] : this.iKeys;
604 }
605
606 /**
607 * @param pName
608 * The name of the key property to retrieve.
609 * @return The value of the key property.
610 */
611 public Object getKeyValue(String pName) {
612 CIMProperty<?> prop = getKey(pName);
613 return prop == null ? prop : prop.getValue();
614 }
615
616 /**
617 * Gets the namespace.
618 *
619 * @return The name of the namespace.
620 */
621 public String getNamespace() {
622 return this.iNamespace;
623 }
624
625 /**
626 * Gets the object name. Depending on the type of CIM element referenced,
627 * this may be either a class name or a qualifier type name.
628 *
629 * @return The name of this CIM element.
630 */
631 public String getObjectName() {
632 return this.iObjectName;
633 }
634
635 /**
636 * Gets the the port on the host to which the connection was established.
637 *
638 * @return The port on the host.
639 */
640 public String getPort() {
641 return this.iPort;
642 }
643
644 /**
645 * Get the connection scheme.
646 *
647 * @return The connection scheme (e.g. http, https,...)
648 */
649 public String getScheme() {
650 return this.iScheme;
651 }
652
653 /**
654 * Get the XML Schema for this object (optional).
655 *
656 * @return The XML Schema name.
657 */
658 public String getXmlSchemaName() {
659 return this.iXmlSchemaName;
660 }
661
662 /**
663 * Computes the hash code for this object path.
664 *
665 * @return The integer representing the hash code for this object path.
666 */
667 @Override
668 public int hashCode() {
669 return toString().hashCode();
670 }
671
672 /**
673 * Returns a <code>String</code> representation of the CIM object path. This
674 * method is intended to be used only for debugging purposes. The format of
675 * the value returned may vary between implementations. The string returned
676 * may be empty but may not be <code>null</code>.
677 *
678 * @return A string representation of this CIM object path.
679 */
680 @Override
681 public String toString() {
682 return MOF.objectHandle(this, false, false);
683 }
684 }