View Javadoc
1   /*
2     CIMXMLBuilderImpl.java
3   
4     (C) Copyright IBM Corp. 2005, 2013
5   
6     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
7     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
8     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
9   
10    You can obtain a current copy of the Eclipse Public License from
11    http://www.opensource.org/licenses/eclipse-1.0.php
12  
13    @author : Roberto Pineiro, IBM, roberto.pineiro@us.ibm.com
14   * @author : Chung-hao Tan, IBM, chungtan@us.ibm.com
15   * 
16   * 
17   * Change History
18   * Flag       Date        Prog         Description
19   *------------------------------------------------------------------------------ 
20   * 16627      2005-04-01  thschaef     Correct instantiation for Uint64 
21   * 17459      2005-06-24  thschaef     catch null within createMethod method
22   * 17459      2005-06-27  thschaef     further improvement to createMethod()
23   * 1535756    2006-08-07  lupusalex    Make code warning free
24   * 1610046    2006-07-12  ebak         Does not escape trailing spaces KEYVALUE
25   * 1631407    2007-01-11  lupusalex    VALUE.REFERENCE doesn't handle references without namespace
26   * 1656285    2007-02-12  ebak         IndicationHandler does not accept non-Integer message ID
27   * 1671505    2007-02-28  lupusalex    Wrong escaping of spaces in XML (Undo 1610046)
28   * 1660756    2007-03-02  ebak         Embedded object support
29   * 1689085    2007-04-10  ebak         Embedded object enhancements for Pegasus
30   * 1669961    2006-04-16  lupusalex    CIMTypedElement.getType() =>getDataType()
31   * 1719991    2007-05-16  ebak         FVT: regression ClassCastException in EmbObjHandler
32   * 1737141    2007-06-18  ebak         Sync up with JSR48 evolution
33   * 1820763    2007-10-29  ebak    	   Supporting the EmbeddedInstance qualifier
34   * 1827728    2007-11-12  ebak         embeddedInstances: attribute EmbeddedObject not set
35   * 1827728    2007-11-20  ebak         rework: embeddedInstances: attribute EmbeddedObject not set
36   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
37   * 2087969    2008-09-03  blaschke-oss VALUE.ARRAY used in request for array of references
38   * 2093708    2008-09-10  rgummada     HTTP 400 - Bad Request, CIMError: request-not-valid
39   * 2204488 	  2008-10-28  raman_arora  Fix code to remove compiler warnings
40   * 2210455    2008-10-30  blaschke-oss Enhance javadoc, fix potential null pointers
41   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
42   * 2763216    2009-04-14  blaschke-oss Code cleanup: visible spelling/grammar errors
43   * 2797550    2009-06-01  raman_arora  JSR48 compliance - add Java Generics
44   * 2823494    2009-08-03  rgummada     Change Boolean constructor to static
45   * 2849970    2009-09-03  blaschke-oss createVALUEARRAY fails to create reference array
46   * 2912490    2010-01-05  rgummada     NullPointerException when invoking getInstance
47   * 2957387    2010-03-03  blaschke-oss EmbededObject XML attribute must not be all uppercases
48   * 2970881    2010-03-15  blaschke-oss Add property to control EmbeddedObject case
49   * 3001333    2010-05-19  blaschke-oss CIMMethod class ignores propagated parameter
50   * 3304058    2011-05-20  blaschke-oss Use same date format in change history
51   * 3588558    2012-11-26  blaschke-oss An enhancement on Java CIM Client logging
52   *    2616    2013-02-23  blaschke-oss Add new API WBEMClientSBLIM.sendIndication()
53   *    2638    2013-05-09  blaschke-oss Do not build empty REFERENCECLASS
54   *    2689    2013-10-10  blaschke-oss createMETHODCALL should not add PARAMTYPE attribute
55   */
56  
57  package org.metricshub.wbem.sblim.cimclient.internal.cimxml;
58  
59  /*-
60   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
61   * WBEM Java Client
62   * ჻჻჻჻჻჻
63   * Copyright 2023 - 2025 MetricsHub
64   * ჻჻჻჻჻჻
65   * Licensed under the Apache License, Version 2.0 (the "License");
66   * you may not use this file except in compliance with the License.
67   * You may obtain a copy of the License at
68   *
69   *      http://www.apache.org/licenses/LICENSE-2.0
70   *
71   * Unless required by applicable law or agreed to in writing, software
72   * distributed under the License is distributed on an "AS IS" BASIS,
73   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74   * See the License for the specific language governing permissions and
75   * limitations under the License.
76   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
77   */
78  
79  import java.io.ByteArrayOutputStream;
80  import java.io.IOException;
81  import java.util.regex.Matcher;
82  import java.util.regex.Pattern;
83  import javax.xml.parsers.DocumentBuilder;
84  import javax.xml.parsers.DocumentBuilderFactory;
85  import javax.xml.parsers.ParserConfigurationException;
86  import org.metricshub.wbem.javax.cim.CIMArgument;
87  import org.metricshub.wbem.javax.cim.CIMClass;
88  import org.metricshub.wbem.javax.cim.CIMClassProperty;
89  import org.metricshub.wbem.javax.cim.CIMDataType;
90  import org.metricshub.wbem.javax.cim.CIMFlavor;
91  import org.metricshub.wbem.javax.cim.CIMInstance;
92  import org.metricshub.wbem.javax.cim.CIMMethod;
93  import org.metricshub.wbem.javax.cim.CIMNamedElementInterface;
94  import org.metricshub.wbem.javax.cim.CIMObjectPath;
95  import org.metricshub.wbem.javax.cim.CIMParameter;
96  import org.metricshub.wbem.javax.cim.CIMProperty;
97  import org.metricshub.wbem.javax.cim.CIMQualifiedElementInterface;
98  import org.metricshub.wbem.javax.cim.CIMQualifier;
99  import org.metricshub.wbem.javax.cim.CIMQualifierType;
100 import org.metricshub.wbem.javax.cim.CIMScope;
101 import org.metricshub.wbem.javax.cim.CIMTypedElement;
102 import org.metricshub.wbem.javax.cim.CIMValuedElement;
103 import org.metricshub.wbem.javax.wbem.WBEMException;
104 import org.metricshub.wbem.sblim.cimclient.internal.cim.CIMQualifiedElementInterfaceImpl;
105 import org.metricshub.wbem.sblim.cimclient.internal.util.MOF;
106 import org.metricshub.wbem.sblim.cimclient.internal.util.WBEMConfiguration;
107 import org.metricshub.wbem.sblim.cimclient.internal.wbem.CIMError;
108 import org.w3c.dom.Document;
109 import org.w3c.dom.Element;
110 import org.w3c.dom.Text;
111 
112 /**
113  * Class CIMXMLBuilderImpl is the core class for building CIM-XML documents.
114  */
115 public class CIMXMLBuilderImpl {
116 	private static final int MAJOR_CIM_VERSION = 2;
117 
118 	private static final int MINOR_CIM_VERSION = 0;
119 
120 	private static final int MAJOR_DTD_VERSION = 2;
121 
122 	private static final int MINOR_DTD_VERSION = 0;
123 
124 	/**
125 	 * createCIM
126 	 *
127 	 * @param pDoc
128 	 * @return Element
129 	 */
130 	public static Element createCIM(Document pDoc) {
131 		// <!ELEMENT CIM (MESSAGE|DECLARATION)>
132 		// <!ATTLIST CIM %CIMVERSION;%DTDVERSION;>
133 		Element e = pDoc.createElement("CIM");
134 		e.setAttribute("CIMVERSION", MAJOR_CIM_VERSION + "." + MINOR_CIM_VERSION);
135 		// required
136 		e.setAttribute("DTDVERSION", MAJOR_DTD_VERSION + "." + MINOR_DTD_VERSION);
137 		// required
138 		pDoc.appendChild(e); // root element
139 		return e;
140 	}
141 
142 	// ////////////////////////////////////////////////////////////////////////////////////////
143 	// Value Elements
144 	// ////////////////////////////////////////////////////////////////////////////////////////
145 
146 	/**
147 	 * createVALUE
148 	 *
149 	 * @param pDoc
150 	 * @param pParentE
151 	 * @return Element
152 	 */
153 	public static Element createVALUE(Document pDoc, Element pParentE) {
154 		// <! ELEMENT VALUE (#PCDATA)>
155 		Element e = pDoc.createElement("VALUE");
156 		pParentE.appendChild(e);
157 
158 		return e;
159 	}
160 
161 	/**
162 	 * createVALUE
163 	 *
164 	 * @param pDoc
165 	 * @param pParentE
166 	 * @param pValue
167 	 * @return Element
168 	 */
169 	public static Element createVALUE(Document pDoc, Element pParentE, String pValue) {
170 		// <! ELEMENT VALUE (#PCDATA)>
171 		Element e = pDoc.createElement("VALUE");
172 		pParentE.appendChild(e);
173 
174 		Text textE = pDoc.createTextNode(pValue);
175 		e.appendChild(textE);
176 		return e;
177 	}
178 
179 	/**
180 	 * createVALUE
181 	 *
182 	 * @param pDoc
183 	 * @param pParentE
184 	 * @param pValue
185 	 * @return Element
186 	 */
187 	public static Element createVALUE(Document pDoc, Element pParentE, boolean pValue) {
188 		return createVALUE(pDoc, pParentE, pValue ? MOF.TRUE : MOF.FALSE);
189 	}
190 
191 	/**
192 	 * createVALUEARRAY
193 	 *
194 	 * @param pDoc
195 	 * @param pParentE
196 	 * @return Element
197 	 */
198 	public static Element createVALUEARRAY(Document pDoc, Element pParentE) {
199 		// <! ELEMENT VALUE.ARRAY (VALUE*)>
200 		Element e = pDoc.createElement("VALUE.ARRAY");
201 		pParentE.appendChild(e);
202 		return e;
203 	}
204 
205 	/**
206 	 * createVALUEREFERENCE
207 	 *
208 	 * @param pDoc
209 	 * @param pParentE
210 	 * @return Element
211 	 */
212 	public static Element createVALUEREFERENCE(Document pDoc, Element pParentE) {
213 		// <!ELEMENT VALUE.REFERENCE
214 		// (CLASSPATH|LOCALCLASSPATH|CLASSNAME|INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
215 		Element e = pDoc.createElement("VALUE.REFERENCE");
216 		pParentE.appendChild(e);
217 		return e;
218 	}
219 
220 	/**
221 	 * createVALUEREFARRAY
222 	 *
223 	 * @param pDoc
224 	 * @param pParentE
225 	 * @return Element
226 	 */
227 	public static Element createVALUEREFARRAY(Document pDoc, Element pParentE) {
228 		// <! ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
229 		Element e = pDoc.createElement("VALUE.REFARRAY");
230 		pParentE.appendChild(e);
231 		return e;
232 	}
233 
234 	// ////////////////////////////////////////////////////////////////////////////////////////
235 	// Properties elements
236 	// ////////////////////////////////////////////////////////////////////////////////////////
237 	/**
238 	 * createPROPERTY
239 	 *
240 	 * @param pDoc
241 	 * @param pParentE
242 	 * @param pName
243 	 * @param pType
244 	 * @return Element
245 	 */
246 	public static Element createPROPERTY(Document pDoc, Element pParentE, String pName, String pType) {
247 		// <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
248 		// <!ATTLIST PROPERTY
249 		// %CIMName;
250 		// %CIMType; #REQUIRED
251 		// %ClassOrigin;
252 		// %Propagated;>
253 
254 		Element e = pDoc.createElement("PROPERTY");
255 		if (pName != null) e.setAttribute("NAME", pName);
256 		if (pType != null) e.setAttribute("TYPE", pType);
257 		// TODO: ClassOrigin, Propagated
258 		pParentE.appendChild(e);
259 		return e;
260 	}
261 
262 	/**
263 	 * createPROPERTYARRAY
264 	 *
265 	 * @param pDoc
266 	 * @param pParentE
267 	 * @param pName
268 	 * @param pType
269 	 * @return Element
270 	 */
271 	public static Element createPROPERTYARRAY(Document pDoc, Element pParentE, String pName, String pType) {
272 		// <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
273 		// <!ATTLIST PROPERTY.ARRAY
274 		// %CIMName;
275 		// %CIMType; #REQUIRED
276 		// %ArraySize;
277 		// %ClassOrigin;
278 		// %Propagated;>
279 
280 		Element e = pDoc.createElement("PROPERTY.ARRAY");
281 		if (pName != null) e.setAttribute("NAME", pName);
282 		if (pType != null) e.setAttribute("TYPE", pType);
283 		// TODO: ClassOrigin, Propagated
284 		pParentE.appendChild(e);
285 		return e;
286 	}
287 
288 	/**
289 	 * createPROPERTYREFERENCE
290 	 *
291 	 * @param pDoc
292 	 * @param pParentE
293 	 * @param pName
294 	 * @param pReferenceclass
295 	 * @return Element
296 	 */
297 	public static Element createPROPERTYREFERENCE(Document pDoc, Element pParentE, String pName, String pReferenceclass) {
298 		// <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,VALUE.REFERENCE?)>
299 		// <!ATTLIST PROPERTY.REFERENCE
300 		// %CIMName;
301 		// %ReferenceClass;
302 		// %ClassOrigin;
303 		// %Propagated;>
304 
305 		Element e = pDoc.createElement("PROPERTY.REFERENCE");
306 		if (pName != null) e.setAttribute("NAME", pName);
307 		if (pReferenceclass != null && pReferenceclass.length() > 0) e.setAttribute("REFERENCECLASS", pReferenceclass);
308 		pParentE.appendChild(e);
309 		return e;
310 	}
311 
312 	// ////////////////////////////////////////////////////////////////////////////////////////
313 	// Naming and Location elements
314 	// ////////////////////////////////////////////////////////////////////////////////////////
315 
316 	/**
317 	 * createNAMESPACE
318 	 *
319 	 * @param pDoc
320 	 * @param pParentE
321 	 * @param pName
322 	 * @return Element
323 	 */
324 	public static Element createNAMESPACE(Document pDoc, Element pParentE, String pName) {
325 		// <!ELEMENT NAMESPACE EMPTY>
326 		// <!ATTLIST NAMESPACE %NAME;>
327 		Element e = pDoc.createElement("NAMESPACE");
328 		if (pName != null) {
329 			e.setAttribute("NAME", pName);
330 		}
331 		pParentE.appendChild(e);
332 		return e;
333 	}
334 
335 	/**
336 	 * createLOCALINSTANCEPATH
337 	 *
338 	 * @param pDoc
339 	 * @param pParentE
340 	 * @return Element
341 	 */
342 	public static Element createLOCALINSTANCEPATH(Document pDoc, Element pParentE) {
343 		// <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
344 		Element e = pDoc.createElement("LOCALINSTANCEPATH");
345 		pParentE.appendChild(e);
346 		return e;
347 	}
348 
349 	/**
350 	 * createCLASSNAME
351 	 *
352 	 * @param pDoc
353 	 * @param pParentE
354 	 * @param pName
355 	 * @return Element
356 	 */
357 	public static Element createCLASSNAME(Document pDoc, Element pParentE, String pName) {
358 		// <!ELEMENT CLASSNAME EMPTY>
359 		// <!ATTLIST CLASSNAME %NAME;>
360 		Element e = pDoc.createElement("CLASSNAME");
361 		if (pName != null) {
362 			e.setAttribute("NAME", pName);
363 
364 			pParentE.appendChild(e);
365 		}
366 		return e;
367 	}
368 
369 	/**
370 	 * createCLASS
371 	 *
372 	 * @param pDoc
373 	 * @param pParentE
374 	 * @param pName
375 	 * @param pSuperClass
376 	 * @return Element
377 	 */
378 	public static Element createCLASS(Document pDoc, Element pParentE, String pName, String pSuperClass) {
379 		// <!ELEMENT CLASSNAME EMPTY>
380 		// <!ATTLIST CLASSNAME %NAME;>
381 		Element e = pDoc.createElement("CLASS");
382 		if (pName != null) {
383 			e.setAttribute("NAME", pName);
384 		}
385 		if (pSuperClass != null && pSuperClass.length() > 0) {
386 			e.setAttribute("SUPERCLASS", pSuperClass);
387 		}
388 		if (pParentE != null) pParentE.appendChild(e);
389 		return e;
390 	}
391 
392 	/**
393 	 * createINSTANCENAME
394 	 *
395 	 * @param pDoc
396 	 * @param pParentE
397 	 * @param pClassName
398 	 * @return Element
399 	 */
400 	public static Element createINSTANCENAME(Document pDoc, Element pParentE, String pClassName) {
401 		// <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERNCE?)>
402 		// <!ATTLIST INSTANCENAME %CLASSNAME;>
403 		Element e = pDoc.createElement("INSTANCENAME");
404 		if (pClassName != null) {
405 			e.setAttribute("CLASSNAME", pClassName);
406 		}
407 		pParentE.appendChild(e);
408 		return e;
409 	}
410 
411 	/**
412 	 * createKEYBINDING
413 	 *
414 	 * @param pDoc
415 	 * @param pParentE
416 	 * @param pName
417 	 * @return Element
418 	 */
419 	public static Element createKEYBINDING(Document pDoc, Element pParentE, String pName) {
420 		// <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE) >
421 		// <!ATTLIST KEYBINDING %NAME;>
422 		Element e = pDoc.createElement("KEYBINDING");
423 		if (pName != null) {
424 			e.setAttribute("NAME", pName);
425 		}
426 		pParentE.appendChild(e);
427 		return e;
428 	}
429 
430 	private static final Pattern NUM_PAT = Pattern.compile("^[su]int(8|16|32|64)$", Pattern.CASE_INSENSITIVE);
431 
432 	/**
433 	 * <!ATTLIST KEYVALUE VALUETYPE (string|boolean|numeric) 'string')>
434 	 * getValueTypeStr
435 	 *
436 	 * @param pTypeStr
437 	 * @return String
438 	 */
439 	private static String getValueTypeStr(String pTypeStr) {
440 		if (pTypeStr == null || MOF.DT_STR.equalsIgnoreCase(pTypeStr)) return MOF.DT_STR;
441 		if (MOF.DT_BOOL.equalsIgnoreCase(pTypeStr)) return MOF.DT_BOOL;
442 		Matcher m = NUM_PAT.matcher(pTypeStr);
443 		if (m.matches()) return "numeric";
444 		return MOF.DT_STR;
445 	}
446 
447 	/**
448 	 * createKEYVALUE
449 	 *
450 	 * @param pDoc
451 	 * @param pParentE
452 	 * @param pValueType
453 	 * @param pValue
454 	 * @return KEYVALUE
455 	 */
456 	public static Element createKEYVALUE(Document pDoc, Element pParentE, String pValueType, String pValue) {
457 		/*
458 		 * <!ELEMENT KEYVALUE (#PCDATA)> <!ATTLIST KEYVALUE VALUETYPE
459 		 * (string|boolean|numeric) 'string') %CIMType; #IMPLIED>
460 		 */
461 		if (pValueType == null) pValueType = "string";
462 		Element e = pDoc.createElement("KEYVALUE");
463 		// FIXME: ebak: TYPE attrib is more exact, easier to handle
464 		e.setAttribute("TYPE", pValueType);
465 		// ebak: maybe old CIMOMs won't understand the TYPE attrib
466 		e.setAttribute("VALUETYPE", getValueTypeStr(pValueType));
467 		pParentE.appendChild(e);
468 		Text valueE = pDoc.createTextNode(pValue);
469 		e.appendChild(valueE);
470 		return e;
471 	}
472 
473 	// ////////////////////////////////////////////////////////////////////////////////////////
474 	// Object Definition Elements
475 	// ////////////////////////////////////////////////////////////////////////////////////////
476 
477 	/**
478 	 * createINSTANCE
479 	 *
480 	 * @param pDoc
481 	 * @param pParentE
482 	 * @param pClassName
483 	 * @return Element
484 	 */
485 	public static Element createINSTANCE(Document pDoc, Element pParentE, String pClassName) {
486 		// <!ELEMENT INSTANCE
487 		// (QUALIFIER*,(PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*)>
488 		// <!ATTLIST INSTANCE %ClassName;>
489 
490 		Element e = pDoc.createElement("INSTANCE");
491 		if (pClassName != null) {
492 			e.setAttribute("CLASSNAME", pClassName);
493 		}
494 		if (pParentE != null) pParentE.appendChild(e);
495 		return e;
496 	}
497 
498 	/**
499 	 * createQUALIFIER
500 	 *
501 	 * @param pDoc
502 	 * @param pParentE
503 	 * @param pName
504 	 * @param pType
505 	 * @return Element
506 	 */
507 	public static Element createQUALIFIER(Document pDoc, Element pParentE, String pName, String pType) {
508 		// <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)>
509 		// <!ATTLIST QUALIFIER
510 		// %CIMName;
511 		// %CIMType; #REQUIRED
512 		// %Propagated;
513 		// %QualifierFlavor;>
514 
515 		Element e = pDoc.createElement("QUALIFIER");
516 		if (pName != null) {
517 			e.setAttribute("NAME", pName);
518 			// TODO: add additional attributes "propagated", "qualifierFlavod"
519 		}
520 		if (pType != null) e.setAttribute("TYPE", pType);
521 		pParentE.appendChild(e);
522 		return e;
523 	}
524 
525 	// ///////////////////////////////////////////////////////////////////////////////////////////
526 	// Message Elements
527 	// ///////////////////////////////////////////////////////////////////////////////////////////
528 
529 	/**
530 	 * createMESSAGE
531 	 *
532 	 * @param pDoc
533 	 * @param pParentE
534 	 * @param pId
535 	 * @param pProtocolVersion
536 	 * @return Element
537 	 */
538 	public static Element createMESSAGE(Document pDoc, Element pParentE, String pId, String pProtocolVersion) {
539 		// <!ELEMENT MESSAGE
540 		// (SIMPLEREQ|MULTIREQ|SIMPLERSP|MULTIRSP|SIMPLEEXPREQ|MULTIEXPREQ|SIMPLEEXPRSP|MULTIEXPRSP)>
541 		// <!ATTLIST MESSAGE %ID;%PROTOCOLVERSION;>
542 		Element e = pDoc.createElement("MESSAGE");
543 		e.setAttribute("ID", pId); // required
544 		e.setAttribute("PROTOCOLVERSION", pProtocolVersion); // required
545 		pParentE.appendChild(e);
546 		return e;
547 	}
548 
549 	/**
550 	 * createSIMPLEREQ
551 	 *
552 	 * @param pDoc
553 	 * @param pParentE
554 	 * @return Element
555 	 */
556 	public static Element createSIMPLEREQ(Document pDoc, Element pParentE) {
557 		// <!ELEMENT SIMPLEREQ (METHODCALL|IMETHODCALL)>
558 		Element e = pDoc.createElement("SIMPLEREQ");
559 		pParentE.appendChild(e);
560 		return e;
561 	}
562 
563 	/**
564 	 * createSIMPLEREQ
565 	 *
566 	 * @param pDoc
567 	 * @return Element
568 	 */
569 	public static Element createSIMPLEREQ(Document pDoc) {
570 		// <!ELEMENT SIMPLEREQ (METHODCALL|IMETHODCALL)>
571 		Element e = pDoc.createElement("SIMPLEREQ");
572 		return e;
573 	}
574 
575 	/**
576 	 * createMULTIREQ
577 	 *
578 	 * @param pDoc
579 	 * @return Element
580 	 */
581 	public static Element createMULTIREQ(Document pDoc) {
582 		// <!ELEMENT MULTIREQ (SIMPLEREQ|SIMPLEREQ+)>
583 		Element e = pDoc.createElement("MULTIREQ");
584 		return e;
585 	}
586 
587 	/**
588 	 * createMETHODCALL
589 	 *
590 	 * @param pDoc
591 	 * @param pParentE
592 	 * @param pName
593 	 * @return Element
594 	 */
595 	public static Element createMETHODCALL(Document pDoc, Element pParentE, String pName) {
596 		// <!ELEMENT METHODCALL
597 		// ((LOCALCLASSPATH|LOCALINSTANCEPATH),PARAMVALUE*)>
598 		// <!ATTLIST METHODCALL %NAME;>
599 		Element e = pDoc.createElement("METHODCALL");
600 		if (pName != null) {
601 			e.setAttribute("NAME", pName);
602 		}
603 		pParentE.appendChild(e);
604 		return e;
605 	}
606 
607 	/**
608 	 * createPARAMVALUE
609 	 *
610 	 * @param pDoc
611 	 * @param pParentE
612 	 * @param pArg
613 	 * @return Element
614 	 * @throws WBEMException
615 	 */
616 	public static Element createPARAMVALUE(Document pDoc, Element pParentE, CIMArgument<?> pArg) throws WBEMException {
617 		// <!ELEMENT PARAMVALUE
618 		// (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.REFARRAY)?>)
619 		// <!ATTLIST PARAMTYPE %NAME;%PARAMTYPE%>
620 		if (pArg == null) return null;
621 		Element e = pDoc.createElement("PARAMVALUE");
622 		EmbObjBuilder embObjBuilder = new EmbObjBuilder(pDoc, pArg);
623 		if (pArg.getName() != null) {
624 			e.setAttribute("NAME", pArg.getName());
625 		}
626 		e.setAttribute("PARAMTYPE", embObjBuilder.getTypeStr());
627 		embObjBuilder.addSign(e);
628 		embObjBuilder.addValue(e);
629 		pParentE.appendChild(e);
630 		return e;
631 	}
632 
633 	/**
634 	 * createSIMPLERSP
635 	 *
636 	 * @param pDoc
637 	 * @param pParentE
638 	 * @return Element
639 	 */
640 	public static Element createSIMPLERSP(Document pDoc, Element pParentE) {
641 		// <!ELEMENT SIMPLERSP (METHODRESPONSE|IMETHODRESPONSE)>
642 		Element e = pDoc.createElement("SIMPLERSP");
643 
644 		if (pParentE != null) pParentE.appendChild(e);
645 		return e;
646 	}
647 
648 	/**
649 	 * createSIMPLEEXPRSP
650 	 *
651 	 * @param pDoc
652 	 * @param pParentE
653 	 * @return Element
654 	 */
655 	public static Element createSIMPLEEXPRSP(Document pDoc, Element pParentE) {
656 		// <!ELEMENT SIMPLEEXPRSP (EXPMETHODRESPONSE) >
657 		Element e = pDoc.createElement("SIMPLEEXPRSP");
658 
659 		pParentE.appendChild(e);
660 		return e;
661 	}
662 
663 	/**
664 	 * createMETHODRESPONSE
665 	 *
666 	 * @param pDoc
667 	 * @param pParentE
668 	 * @param pName
669 	 * @return Element
670 	 */
671 	public static Element createMETHODRESPONSE(Document pDoc, Element pParentE, String pName) {
672 		// <!ELEMENT METHODRESPONSE (ERROR|(RETURNVALUE?,PARAMVALUE*))>
673 		// <!ATTLIST METHODRESPONSE
674 		// %CIMName;>
675 
676 		// %CIMName;>
677 		Element e = pDoc.createElement("METHODRESPONSE");
678 		if (pName != null) {
679 			e.setAttribute("NAME", pName);
680 		}
681 		pParentE.appendChild(e);
682 		return e;
683 	}
684 
685 	/**
686 	 * createIMETHODRESPONSE
687 	 *
688 	 * @param pDoc
689 	 * @param pParentE
690 	 * @param pName
691 	 * @return Element
692 	 */
693 	public static Element createIMETHODRESPONSE(Document pDoc, Element pParentE, String pName) {
694 		// <!ELEMENT IMETHODRESPONSE (ERROR|IRETURNVALUE?)>
695 		// <!ATTLIST IMETHODRESPONSE
696 		// %CIMName;>
697 		// %CIMName;>
698 		Element e = pDoc.createElement("IMETHODRESPONSE");
699 		if (pName != null) {
700 			e.setAttribute("NAME", pName);
701 		}
702 		pParentE.appendChild(e);
703 		return e;
704 	}
705 
706 	/**
707 	 * createEXPMETHODRESPONSE
708 	 *
709 	 * @param pDoc
710 	 * @param pParentE
711 	 * @param pName
712 	 * @return Element
713 	 */
714 	public static Element createEXPMETHODRESPONSE(Document pDoc, Element pParentE, String pName) {
715 		// <!ELEMENT EXPMETHODRESPONSE (ERROR|IRETURNVALUE?)>
716 		// <!ATTLIST EXPMETHODRESPONSE
717 		// %CIMName;>
718 		Element e = pDoc.createElement("EXPMETHODRESPONSE");
719 		if (pName != null) {
720 			e.setAttribute("NAME", pName);
721 		}
722 		pParentE.appendChild(e);
723 		return e;
724 	}
725 
726 	/**
727 	 * createIRETURNVALUE
728 	 *
729 	 * @param pDoc
730 	 * @param pParentE
731 	 * @return Element
732 	 */
733 	public static Element createIRETURNVALUE(Document pDoc, Element pParentE) {
734 		// <!ELEMENT IRETURNVALUE
735 		// (CLASSNAME*|INSTANCENAME*|VALUE*|VALUE.OBJECTWITHPATH*|VALUE.OBJECTWITHLOCALPATH*
736 		// VALUE.OBJECT*|OBJECTPATH*|QUALIFIER.DECLARATION*|VALUE.ARRAY?|VALUE.REFERENCE?|
737 		// CLASS*|INSTANCE*|VALUE.NAMEDINSTANCE*)>
738 		Element e = pDoc.createElement("IRETURNVALUE");
739 		pParentE.appendChild(e);
740 		return e;
741 	}
742 
743 	/**
744 	 * <pre>
745 	 * !ELEMENT RETURNVALUE (VALUE | VALUE.REFERENCE)
746 	 * !ATTLIST RETURNVALUE
747 	 * %ParamType;       #IMPLIED
748 	 * </pre>
749 	 *
750 	 * createRETURNVALUE
751 	 *
752 	 * @param pDoc
753 	 * @param pParentE
754 	 * @param pValue
755 	 * @return Element
756 	 * @throws WBEMException
757 	 */
758 	public static Element createRETURNVALUE(Document pDoc, Element pParentE, Object pValue) throws WBEMException {
759 		Element retValE = pDoc.createElement("RETURNVALUE");
760 		CIMDataType type = CIMDataType.getDataType(pValue);
761 		retValE.setAttribute("PARAMTYPE", getTypeStr(type));
762 		createVALUE(pDoc, retValE, pValue);
763 		pParentE.appendChild(retValE);
764 		return retValE;
765 	}
766 
767 	/**
768 	 * createIMETHODCALL
769 	 *
770 	 * @param pDoc
771 	 * @param pParentE
772 	 * @param pName
773 	 * @return Element
774 	 */
775 	public static Element createIMETHODCALL(Document pDoc, Element pParentE, String pName) {
776 		// <!ELEMENT IMETHODCALL (LOCALNAMESPACEPATH,IPARAMVALUE*)>
777 		// <!ATTLIST IMETHODCALL %NAME;>
778 		Element e = pDoc.createElement("IMETHODCALL");
779 		if (pName != null) {
780 			e.setAttribute("NAME", pName);
781 		}
782 		pParentE.appendChild(e);
783 		return e;
784 	}
785 
786 	/**
787 	 * createIPARAMVALUE
788 	 *
789 	 * @param pDoc
790 	 * @param pParentE
791 	 * @param pName
792 	 * @return Element
793 	 */
794 	public static Element createIPARAMVALUE(Document pDoc, Element pParentE, String pName) {
795 		// <!ELEMENT PARAMVALUE
796 		// (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.NAMEDINSTANCE
797 		// |CLASSNAME|INSTANCENAME|QUALIFIER.DECLARATION|CLASS|INSTANCE|?>)
798 		// <!ATTLIST PARAMTYPE %NAME;>
799 		Element e = pDoc.createElement("IPARAMVALUE");
800 		if (pName != null) {
801 			e.setAttribute("NAME", pName);
802 		}
803 		pParentE.appendChild(e);
804 		return e;
805 	}
806 
807 	/**
808 	 * createERROR
809 	 *
810 	 * @param doc
811 	 * @param parentE
812 	 * @param error
813 	 * @return Element
814 	 */
815 	public static Element createERROR(Document doc, Element parentE, CIMError error) {
816 		// <!ELEMENT ERROR EMPTY>
817 		// <!ATTLIST ERROR
818 		// CODE CDATA #REQUIRED
819 		// DESCRIPTION CDATA #IMPLIED>
820 		Element e = doc.createElement("ERROR");
821 		int code;
822 		if ((code = error.getCode()) > 0) {
823 			e.setAttribute("CODE", Integer.toString(code));
824 		}
825 		String description = error.getDescription();
826 		if (description != null) {
827 			e.setAttribute("DESCRIPTION", description);
828 		}
829 
830 		parentE.appendChild(e);
831 		return e;
832 	}
833 
834 	/**
835 	 * ENTITY % QualifierFlavor "OVERRIDABLE (true|false) 'true' TOSUBCLASS
836 	 * (true|false) 'true' TOINSTANCE (true|false) 'false' TRANSLATABLE
837 	 * (true|false) 'false'"
838 	 *
839 	 * @param pElement
840 	 * @param pFlavors
841 	 */
842 	private static void setFlavors(Element pElement, int pFlavors) {
843 		if ((pFlavors & CIMFlavor.TRANSLATE) > 0) {
844 			pElement.setAttribute("TRANSLATABLE", MOF.TRUE);
845 		}
846 		if ((pFlavors & CIMFlavor.DISABLEOVERRIDE) > 0) {
847 			pElement.setAttribute("OVERRIDABLE", MOF.FALSE);
848 		}
849 		if ((pFlavors & CIMFlavor.RESTRICTED) > 0) {
850 			pElement.setAttribute("TOSUBCLASS", MOF.FALSE);
851 		}
852 		/*
853 		 * if ((pFlavors & CIMFlavor.RESTRICTED)>0) {
854 		 * pElement.setAttribute("TOSUBCLASS", "true"); }
855 		 */
856 	}
857 
858 	/**
859 	 * createQUALIFIER_DECLARATION
860 	 *
861 	 * @param pDoc
862 	 * @param pParentE
863 	 * @param pQualifierType
864 	 * @return Element
865 	 * @throws WBEMException
866 	 */
867 	public static Element createQUALIFIER_DECLARATION(
868 		Document pDoc,
869 		Element pParentE,
870 		CIMQualifierType<?> pQualifierType
871 	)
872 		throws WBEMException {
873 		// <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
874 		// <!ATTLIST QUALIFIER.DECLARATION
875 		// %CIMName;
876 		// %CIMType; #REQUIRED
877 		// ISARRAY (true|false) #IMPLIED
878 		// %ArraySize;
879 		// %QualifierFlavor;>
880 
881 		String pValueTypeStr = getTypeStr(pQualifierType.getDataType());
882 		Element qualifierdeclarationE = pDoc.createElement("QUALIFIER.DECLARATION");
883 		qualifierdeclarationE.setAttribute("NAME", pQualifierType.getName());
884 		qualifierdeclarationE.setAttribute("TYPE", pValueTypeStr);
885 		qualifierdeclarationE.setAttribute("ISARRAY", pQualifierType.getDataType().isArray() ? MOF.TRUE : MOF.FALSE);
886 
887 		setFlavors(qualifierdeclarationE, pQualifierType.getFlavor());
888 
889 		int scopes = pQualifierType.getScope();
890 		if (scopes > 0) {
891 			Element scopeE = pDoc.createElement("SCOPE");
892 			if ((scopes & CIMScope.CLASS) > 0) scopeE.setAttribute("CLASS", MOF.TRUE);
893 			if ((scopes & CIMScope.ASSOCIATION) > 0) scopeE.setAttribute("ASSOCIATION", MOF.TRUE);
894 			if ((scopes & CIMScope.REFERENCE) > 0) scopeE.setAttribute("REFERENCE", MOF.TRUE);
895 			if ((scopes & CIMScope.PROPERTY) > 0) scopeE.setAttribute("PROPERTY", MOF.TRUE);
896 			if ((scopes & CIMScope.METHOD) > 0) scopeE.setAttribute("METHOD", MOF.TRUE);
897 			if ((scopes & CIMScope.PARAMETER) > 0) scopeE.setAttribute("PARAMETER", MOF.TRUE);
898 			if ((scopes & CIMScope.INDICATION) > 0) scopeE.setAttribute("INDICATION", MOF.TRUE);
899 			qualifierdeclarationE.appendChild(scopeE);
900 		}
901 
902 		createVALUE(pDoc, qualifierdeclarationE, pQualifierType.getValue());
903 
904 		pParentE.appendChild(qualifierdeclarationE);
905 		return qualifierdeclarationE;
906 	}
907 
908 	/**
909 	 * createQUALIFIER
910 	 *
911 	 * @param pDoc
912 	 * @param pParentE
913 	 * @param pQualifier
914 	 * @return Element
915 	 * @throws WBEMException
916 	 */
917 	public static Element createQUALIFIER(Document pDoc, Element pParentE, CIMQualifier<?> pQualifier)
918 		throws WBEMException {
919 		// <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)>
920 		// <!ATTLIST QUALIFIER
921 		// %CIMName;
922 		// %CIMType; #REQUIRED
923 		// %Propagated;
924 		// %QualifierFlavor;>
925 
926 		Object value = pQualifier.getValue();
927 		if (value == null) return null;
928 
929 		Element qualifierE = createQUALIFIER(pDoc, pParentE, pQualifier.getName(), getTypeStr(pQualifier.getDataType()));
930 
931 		if (pQualifier.isPropagated()) {
932 			qualifierE.setAttribute("PROPAGATED", "true");
933 		}
934 		setFlavors(qualifierE, pQualifier.getFlavor());
935 
936 		createVALUE(pDoc, qualifierE, value);
937 
938 		pParentE.appendChild(qualifierE);
939 		return qualifierE;
940 	}
941 
942 	/**
943 	 * createQUALIFIERS
944 	 *
945 	 * @param pDoc
946 	 * @param pParentE
947 	 * @param pQualifiersA
948 	 * @throws WBEMException
949 	 */
950 	public static void createQUALIFIERS(Document pDoc, Element pParentE, CIMQualifier<?>[] pQualifiersA)
951 		throws WBEMException {
952 		if (pQualifiersA == null) return;
953 		for (int i = 0; i < pQualifiersA.length; i++) {
954 			createQUALIFIER(pDoc, pParentE, pQualifiersA[i]);
955 		}
956 	}
957 
958 	/**
959 	 * createPROPERTIES
960 	 *
961 	 * @param pDoc
962 	 * @param pParentE
963 	 * @param pProperties
964 	 * @throws WBEMException
965 	 */
966 	public static void createPROPERTIES(Document pDoc, Element pParentE, CIMProperty<?>[] pProperties)
967 		throws WBEMException {
968 		if (pProperties == null) return;
969 		for (int i = 0; i < pProperties.length; i++) {
970 			createPROPERTY(pDoc, pParentE, pProperties[i]);
971 		}
972 	}
973 
974 	private static final CIMQualifiedElementInterfaceImpl KEYQUALIFIERS_IMPL = new CIMQualifiedElementInterfaceImpl(
975 		null,
976 		true
977 	);
978 
979 	static final CIMQualifier<Boolean> EMB_OBJ_QUALI = new CIMQualifier<Boolean>(
980 		"EmbeddedObject",
981 		CIMDataType.BOOLEAN_T,
982 		Boolean.TRUE,
983 		CIMFlavor.DISABLEOVERRIDE
984 	);
985 
986 	// ebak: embedded object: CLASS_T or INSTANCE_T?
987 
988 	/**
989 	 * isCIMObject
990 	 *
991 	 * @param typeCode
992 	 * @return boolean
993 	 */
994 	public static boolean isCIMObject(int typeCode) {
995 		return typeCode == CIMDataType.CLASS || typeCode == CIMDataType.OBJECT;
996 	}
997 
998 	/**
999 	 * isCIMObject
1000 	 *
1001 	 * @param pType
1002 	 * @return boolean
1003 	 */
1004 	public static boolean isCIMObject(CIMDataType pType) {
1005 		return pType == null ? false : isCIMObject(pType.getType());
1006 	}
1007 
1008 	/**
1009 	 * getEmbObjTypeStr
1010 	 *
1011 	 * @param pType
1012 	 * @return String
1013 	 */
1014 	public static String getEmbObjTypeStr(CIMDataType pType) {
1015 		return isCIMObject(pType) ? MOF.DT_STR : getTypeStr(pType);
1016 	}
1017 
1018 	private static Document getDoc() {
1019 		try {
1020 			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1021 			DocumentBuilder docBuilder = factory.newDocumentBuilder();
1022 			return docBuilder.newDocument();
1023 		} catch (ParserConfigurationException e) {
1024 			throw new RuntimeException(e);
1025 		}
1026 	}
1027 
1028 	/**
1029 	 * cimObjectToXMLString - for embedded object support
1030 	 *
1031 	 * @param pObj
1032 	 * @return String
1033 	 * @throws WBEMException
1034 	 */
1035 	public static String cimObjectToXMLString(Object pObj) throws WBEMException {
1036 		if (pObj == null) return null;
1037 		Document doc;
1038 		Element e;
1039 		if (pObj instanceof CIMClass) {
1040 			doc = getDoc();
1041 			e = createCLASS(doc, null, (CIMClass) pObj);
1042 		} else if (pObj instanceof CIMInstance) {
1043 			doc = getDoc();
1044 			e = createINSTANCE(doc, null, (CIMInstance) pObj);
1045 		} else {
1046 			throw new WBEMException(
1047 				WBEMException.CIM_ERR_FAILED,
1048 				pObj.getClass().getName() + " parameter is not suitable for this method!"
1049 			);
1050 		}
1051 		doc.appendChild(e);
1052 		ByteArrayOutputStream os = new ByteArrayOutputStream();
1053 		try {
1054 			CimXmlSerializer.serialize(os, doc.getDocumentElement(), false);
1055 		} catch (IOException ex) {
1056 			throw new WBEMException(WBEMException.CIM_ERR_FAILED, "XML serialization failed with IOException!", null, ex);
1057 		}
1058 		return os.toString();
1059 	}
1060 
1061 	/**
1062 	 * cimObjectArrayToXMLString - for embedded object support
1063 	 *
1064 	 * @param pObj
1065 	 * @return String[]
1066 	 * @throws WBEMException
1067 	 */
1068 	public static String[] cimObjectArrayToXMLString(Object pObj) throws WBEMException {
1069 		if (pObj == null) return null;
1070 		if (!(pObj instanceof Object[])) throw new WBEMException(
1071 			WBEMException.CIM_ERR_FAILED,
1072 			"Object[] parameter is required for this method!"
1073 		);
1074 		Object[] objA = (Object[]) pObj;
1075 		String[] strA = new String[objA.length];
1076 		// here we don't deal with the consistency check of the Object[]
1077 		for (int i = 0; i < objA.length; i++) strA[i] = cimObjectToXMLString(objA[i]);
1078 		return strA;
1079 	}
1080 
1081 	static boolean embObjQualified(CIMQualifiedElementInterface pQualid) {
1082 		return pQualid.hasQualifier("EmbeddedObject") || pQualid.hasQualifier("EmbeddedInstance");
1083 	}
1084 
1085 	static class EmbObjBuilder {
1086 		private static final int ATTRIB_ONLY = 0, EO_QUALI = 1, EO_AND_EI_QUALI = 2;
1087 
1088 		private int iSignMethod;
1089 
1090 		private Document iDoc;
1091 
1092 		private CIMTypedElement iTypedE;
1093 
1094 		private boolean iXMLQualified;
1095 
1096 		private static final boolean iUpperCaseEmbObjEntities = WBEMConfiguration
1097 			.getGlobalConfiguration()
1098 			.upperCaseEmbObjEntities();
1099 
1100 		/**
1101 		 * Ctor.
1102 		 *
1103 		 * @param pDoc
1104 		 * @param pTypedE
1105 		 */
1106 		public EmbObjBuilder(Document pDoc, CIMTypedElement pTypedE) {
1107 			this(pDoc, pTypedE, false);
1108 		}
1109 
1110 		/**
1111 		 * Ctor.
1112 		 *
1113 		 * @param pDoc
1114 		 * @param pTypedE
1115 		 * @param pXMLQualified
1116 		 *            - e.g. CIMProperty is not qualified in JSR48, but
1117 		 *            qualified in CIM-XML
1118 		 */
1119 		public EmbObjBuilder(Document pDoc, CIMTypedElement pTypedE, boolean pXMLQualified) {
1120 			this.iDoc = pDoc;
1121 			this.iTypedE = pTypedE;
1122 			this.iXMLQualified = pXMLQualified;
1123 			String builderCfg = WBEMConfiguration.getGlobalConfiguration().getCimXmlEmbObjBuilder();
1124 			if ("EmbObjQuali".equalsIgnoreCase(builderCfg)) {
1125 				this.iSignMethod = EO_QUALI;
1126 			} else if ("EmbObjAndEmbInstQuali".equalsIgnoreCase(builderCfg)) {
1127 				this.iSignMethod = EO_AND_EI_QUALI;
1128 			} else {
1129 				this.iSignMethod = ATTRIB_ONLY;
1130 			}
1131 		}
1132 
1133 		/**
1134 		 * getTypeStr
1135 		 *
1136 		 * @return String
1137 		 */
1138 		public String getTypeStr() {
1139 			return getEmbObjTypeStr(this.iTypedE.getDataType());
1140 		}
1141 
1142 		/**
1143 		 * isArray
1144 		 *
1145 		 * @return String
1146 		 */
1147 		public boolean isArray() {
1148 			return this.iTypedE.getDataType().isArray();
1149 		}
1150 
1151 		private Object getValue() {
1152 			if (!(this.iTypedE instanceof CIMValuedElement)) return null;
1153 			return ((CIMValuedElement<?>) this.iTypedE).getValue();
1154 		}
1155 
1156 		/**
1157 		 * addSign
1158 		 *
1159 		 * @param pElement
1160 		 * @throws WBEMException
1161 		 */
1162 		public void addSign(Element pElement) throws WBEMException {
1163 			if (!isCIMObject(this.iTypedE.getDataType())) return;
1164 			CIMQualifiedElementInterface qualified;
1165 			if (this.iTypedE instanceof CIMQualifiedElementInterface) {
1166 				qualified = (CIMQualifiedElementInterface) this.iTypedE;
1167 				if (embObjQualified(qualified)) return;
1168 			} else {
1169 				qualified = null;
1170 			}
1171 			if (this.iSignMethod == ATTRIB_ONLY || (qualified == null && !this.iXMLQualified)) {
1172 				pElement.setAttribute(
1173 					iUpperCaseEmbObjEntities ? "EMBEDDEDOBJECT" : "EmbeddedObject",
1174 					this.iTypedE.getDataType().getType() == CIMDataType.OBJECT ? "instance" : "object"
1175 				);
1176 			} else {
1177 				if (this.iSignMethod == EO_AND_EI_QUALI) {
1178 					addEmbObjOrEmbInstQuali(pElement);
1179 				} else { // EO_QUALI
1180 					createQUALIFIER(this.iDoc, pElement, EMB_OBJ_QUALI);
1181 				}
1182 			}
1183 		}
1184 
1185 		private void addEmbObjOrEmbInstQuali(Element pElement) throws WBEMException {
1186 			CIMQualifier<?> signQuali;
1187 			if (this.iTypedE.getDataType().getType() == CIMDataType.OBJECT) {
1188 				CIMInstance inst;
1189 				if (isArray()) {
1190 					CIMInstance[] instA = (CIMInstance[]) getValue();
1191 					inst = instA == null ? null : instA[0];
1192 				} else {
1193 					inst = (CIMInstance) getValue();
1194 				}
1195 				String className = inst == null ? "" : inst.getClassName();
1196 				signQuali =
1197 					new CIMQualifier<String>("EmbeddedInstance", CIMDataType.STRING_T, className, CIMFlavor.DISABLEOVERRIDE);
1198 			} else { // class
1199 				signQuali = EMB_OBJ_QUALI;
1200 			}
1201 			createQUALIFIER(this.iDoc, pElement, signQuali);
1202 		}
1203 
1204 		/**
1205 		 * addValue
1206 		 *
1207 		 * @param pElement
1208 		 * @throws WBEMException
1209 		 */
1210 		public void addValue(Element pElement) throws WBEMException {
1211 			Object value = getValue();
1212 			if (value == null) return;
1213 			if (isCIMObject(this.iTypedE.getDataType())) {
1214 				if (isArray()) {
1215 					value = cimObjectArrayToXMLString(value);
1216 				} else {
1217 					value = cimObjectToXMLString(value);
1218 				}
1219 			}
1220 			createVALUE(this.iDoc, pElement, value);
1221 		}
1222 	}
1223 
1224 	/**
1225 	 * createPROPERTY
1226 	 *
1227 	 * @param pDoc
1228 	 * @param pParentE
1229 	 * @param pProperty
1230 	 * @return Element
1231 	 * @throws WBEMException
1232 	 */
1233 	public static Element createPROPERTY(Document pDoc, Element pParentE, CIMProperty<?> pProperty) throws WBEMException {
1234 		CIMDataType propType = pProperty.getDataType();
1235 		Element propertyE;
1236 		EmbObjBuilder embObjBuilder = new EmbObjBuilder(pDoc, pProperty, true);
1237 		String typeStr = embObjBuilder.getTypeStr();
1238 		if (propType.isArray()) {
1239 			propertyE = createPROPERTYARRAY(pDoc, pParentE, pProperty.getName(), typeStr);
1240 		} else if (propType.getType() == CIMDataType.REFERENCE) {
1241 			propertyE = createPROPERTYREFERENCE(pDoc, pParentE, pProperty.getName(), propType.getRefClassName());
1242 		} else {
1243 			propertyE = createPROPERTY(pDoc, pParentE, pProperty.getName(), typeStr);
1244 		}
1245 
1246 		String classorigin = pProperty.getOriginClass();
1247 		if (classorigin != null && classorigin.length() > 0) propertyE.setAttribute("CLASSORIGIN", classorigin);
1248 
1249 		if (pProperty.isPropagated()) propertyE.setAttribute("PROPAGATED", MOF.TRUE);
1250 		// FIXME: here key qualifier should be added if the property is a key
1251 		embObjBuilder.addSign(propertyE);
1252 		if (pProperty instanceof CIMClassProperty) {
1253 			createQUALIFIERS(pDoc, propertyE, ((CIMClassProperty<?>) pProperty).getQualifiers());
1254 		} else { // CIMProperty
1255 			if (pProperty.isKey()) createQUALIFIERS(pDoc, propertyE, KEYQUALIFIERS_IMPL.getQualifiers());
1256 		}
1257 		embObjBuilder.addValue(propertyE);
1258 		return propertyE;
1259 	}
1260 
1261 	/**
1262 	 * createVALUEARRAY
1263 	 *
1264 	 * @param pDoc
1265 	 * @param pParentE
1266 	 * @param pValA
1267 	 * @return Element
1268 	 * @throws WBEMException
1269 	 */
1270 	public static Element createVALUEARRAY(Document pDoc, Element pParentE, Object[] pValA) throws WBEMException {
1271 		Element valuearrayE = (
1272 				pValA != null && pValA.length > 0 && (pValA[0] instanceof CIMObjectPath || pValA[0] instanceof CIMInstance)
1273 			)
1274 			? createVALUEREFARRAY(pDoc, pParentE)
1275 			: createVALUEARRAY(pDoc, pParentE);
1276 
1277 		if (pValA != null) for (int i = 0; i < pValA.length; i++) {
1278 			createVALUE(pDoc, valuearrayE, pValA[i]);
1279 		}
1280 		pParentE.appendChild(valuearrayE);
1281 		return valuearrayE;
1282 	}
1283 
1284 	/**
1285 	 * createVALUE
1286 	 *
1287 	 * @param pDoc
1288 	 * @param pParentE
1289 	 * @param pArgValue
1290 	 * @return Element
1291 	 * @throws WBEMException
1292 	 */
1293 	public static Element createVALUE(Document pDoc, Element pParentE, Object pArgValue) throws WBEMException {
1294 		if (pArgValue == null) return null;
1295 
1296 		Element valueE = null;
1297 		if (pArgValue instanceof Object[]) {
1298 			valueE = createVALUEARRAY(pDoc, pParentE, (Object[]) pArgValue);
1299 		} else {
1300 			CIMDataType type = CIMDataType.getDataType(pArgValue);
1301 			if (type != null && type.getType() == CIMDataType.REFERENCE) {
1302 				valueE = createVALUEREFERENCE(pDoc, pParentE);
1303 
1304 				CIMObjectPath op = (CIMObjectPath) pArgValue;
1305 				CIMProperty<?>[] keys = op.getKeys();
1306 				if (op.getHost() == null || "".equals(op.getHost())) {
1307 					if (op.getNamespace() == null || "".equals(op.getNamespace())) {
1308 						if (keys.length > 0) {
1309 							createINSTANCENAME(pDoc, valueE, op);
1310 						} else {
1311 							createCLASSNAME(pDoc, valueE, op.getObjectName());
1312 						}
1313 					} else {
1314 						if (keys.length > 0) {
1315 							createLOCALINSTANCEPATH(pDoc, valueE, op);
1316 						} else {
1317 							createLOCALCLASSPATH(pDoc, valueE, op);
1318 						}
1319 					}
1320 				} else {
1321 					if (keys.length > 0) {
1322 						createINSTANCEPATH(pDoc, valueE, op);
1323 					} else {
1324 						createCLASSPATH(pDoc, valueE, op);
1325 					}
1326 				}
1327 				// createOBJECTPATH(doc, valueE, (CIMObjectPath) obj);
1328 			} else {
1329 				if (pArgValue instanceof CIMInstance) {
1330 					valueE = createVALUEREFERENCE(pDoc, pParentE);
1331 					CIMObjectPath cop = ((CIMInstance) pArgValue).getObjectPath();
1332 					createINSTANCENAME(pDoc, valueE, cop);
1333 				} else if (pArgValue instanceof CIMClass) {
1334 					valueE = createVALUE(pDoc, pParentE);
1335 					createCLASS(pDoc, valueE, (CIMClass) pArgValue);
1336 				} else {
1337 					createVALUE(pDoc, pParentE, pArgValue.toString());
1338 				}
1339 			}
1340 		}
1341 
1342 		return valueE;
1343 	}
1344 
1345 	/**
1346 	 * createINSTANCE
1347 	 *
1348 	 * @param pDoc
1349 	 * @param pParentE
1350 	 * @param pInstance
1351 	 * @return Element
1352 	 * @throws WBEMException
1353 	 */
1354 	public static Element createINSTANCE(Document pDoc, Element pParentE, CIMInstance pInstance) throws WBEMException {
1355 		// <!ELEMENT INSTANCE
1356 		// (QUALIFIER*,(PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*)>
1357 		// <!ATTLIST INSTANCE
1358 		// %ClassName;>
1359 
1360 		String className = pInstance.getObjectPath().getObjectName();
1361 		if (className == null) throw new WBEMException(WBEMException.CIM_ERR_FAILED, "null class name");
1362 
1363 		Element instanceE = createINSTANCE(pDoc, pParentE, className);
1364 
1365 		// FIXME: in JSR48 CIMInstance doesn't have qualifiers
1366 		// createQUALIFIERS(pDoc, instanceE, pInstance.getQualifiers());
1367 		createPROPERTIES(pDoc, instanceE, pInstance.getProperties());
1368 
1369 		if (pParentE != null) pParentE.appendChild(instanceE);
1370 
1371 		return instanceE;
1372 	}
1373 
1374 	/**
1375 	 * createOBJECTPATH
1376 	 *
1377 	 * @param pDoc
1378 	 * @param pParentE
1379 	 * @param pPath
1380 	 * @return Element
1381 	 * @throws WBEMException
1382 	 */
1383 	public static Element createOBJECTPATH(Document pDoc, Element pParentE, CIMObjectPath pPath) throws WBEMException {
1384 		Element objectpathE = pDoc.createElement("OBJECTPATH");
1385 
1386 		CIMProperty<?>[] keys = pPath.getKeys();
1387 		if (keys.length > 0) {
1388 			createINSTANCEPATH(pDoc, objectpathE, pPath);
1389 		} else {
1390 			createCLASSPATH(pDoc, objectpathE, pPath);
1391 		}
1392 
1393 		pParentE.appendChild(objectpathE);
1394 		return objectpathE;
1395 	}
1396 
1397 	/**
1398 	 * createOBJECTNAME
1399 	 *
1400 	 * @param pDoc
1401 	 * @param pParentE
1402 	 * @param pPath
1403 	 * @return Element
1404 	 * @throws WBEMException
1405 	 */
1406 	public static Element createOBJECTNAME(Document pDoc, Element pParentE, CIMObjectPath pPath) throws WBEMException {
1407 		CIMProperty<?>[] keys = pPath.getKeys();
1408 		if (keys.length > 0) {
1409 			return createINSTANCENAME(pDoc, pParentE, pPath);
1410 		}
1411 		if (pPath.getObjectName() == null) throw new WBEMException(
1412 			WBEMException.CIM_ERR_INVALID_PARAMETER,
1413 			"null class name"
1414 		);
1415 		return createCLASSNAME(pDoc, pParentE, pPath.getObjectName());
1416 	}
1417 
1418 	/**
1419 	 * createLOCALINSTANCEPATH
1420 	 *
1421 	 * @param pDoc
1422 	 * @param pParentE
1423 	 * @param pPath
1424 	 * @return Element
1425 	 * @throws WBEMException
1426 	 */
1427 	public static Element createLOCALINSTANCEPATH(Document pDoc, Element pParentE, CIMObjectPath pPath)
1428 		throws WBEMException {
1429 		Element localinstancepathE = pDoc.createElement("LOCALINSTANCEPATH");
1430 
1431 		createLOCALNAMESPACEPATH(pDoc, localinstancepathE, pPath);
1432 		createINSTANCENAME(pDoc, localinstancepathE, pPath);
1433 
1434 		pParentE.appendChild(localinstancepathE);
1435 		return localinstancepathE;
1436 	}
1437 
1438 	/**
1439 	 * createLOCALCLASSPATH
1440 	 *
1441 	 * @param pDoc
1442 	 * @param pParentE
1443 	 * @param pPath
1444 	 * @return Element
1445 	 * @throws WBEMException
1446 	 */
1447 	public static Element createLOCALCLASSPATH(Document pDoc, Element pParentE, CIMObjectPath pPath)
1448 		throws WBEMException {
1449 		Element localinstancepathE = pDoc.createElement("LOCALCLASSPATH");
1450 
1451 		createLOCALNAMESPACEPATH(pDoc, localinstancepathE, pPath);
1452 
1453 		if (pPath.getObjectName() == null) throw new WBEMException(
1454 			WBEMException.CIM_ERR_INVALID_PARAMETER,
1455 			"null class name"
1456 		);
1457 		createCLASSNAME(pDoc, localinstancepathE, pPath.getObjectName());
1458 
1459 		pParentE.appendChild(localinstancepathE);
1460 		return localinstancepathE;
1461 	}
1462 
1463 	/**
1464 	 * createLOCALOBJECTPATH
1465 	 *
1466 	 * @param pDoc
1467 	 * @param pParentE
1468 	 * @param pPath
1469 	 * @return Element
1470 	 * @throws WBEMException
1471 	 */
1472 	public static Element createLOCALOBJECTPATH(Document pDoc, Element pParentE, CIMObjectPath pPath)
1473 		throws WBEMException {
1474 		CIMProperty<?>[] keys = pPath.getKeys();
1475 		if (keys.length > 0) {
1476 			return createLOCALINSTANCEPATH(pDoc, pParentE, pPath);
1477 		}
1478 		return createLOCALCLASSPATH(pDoc, pParentE, pPath);
1479 	}
1480 
1481 	/**
1482 	 * createVALUEREFERENCE
1483 	 *
1484 	 * @param pDoc
1485 	 * @param pParentE
1486 	 * @param pPath
1487 	 * @return Element
1488 	 * @throws WBEMException
1489 	 */
1490 	public static Element createVALUEREFERENCE(Document pDoc, Element pParentE, CIMObjectPath pPath)
1491 		throws WBEMException {
1492 		Element objectpathE = pDoc.createElement("VALUE.REFERENCE");
1493 
1494 		String ns = pPath.getNamespace();
1495 		if (pPath.getHost() == null || "".equals(pPath.getHost())) {
1496 			if (pPath.getNamespace() == null || "".equals(ns)) {
1497 				createINSTANCENAME(pDoc, objectpathE, pPath);
1498 			} else {
1499 				createLOCALOBJECTPATH(pDoc, objectpathE, pPath);
1500 			}
1501 		} else {
1502 			CIMProperty<?>[] keys = pPath.getKeys();
1503 			if (keys.length > 0) {
1504 				createINSTANCEPATH(pDoc, objectpathE, pPath);
1505 			} else {
1506 				createCLASSPATH(pDoc, objectpathE, pPath);
1507 			}
1508 		}
1509 
1510 		pParentE.appendChild(objectpathE);
1511 		return objectpathE;
1512 	}
1513 
1514 	/**
1515 	 * createINSTANCENAME
1516 	 *
1517 	 * @param doc
1518 	 * @param parentE
1519 	 * @param instanceOP
1520 	 * @return Element
1521 	 * @throws WBEMException
1522 	 */
1523 	public static Element createINSTANCENAME(Document doc, Element parentE, CIMObjectPath instanceOP)
1524 		throws WBEMException {
1525 		Element instancenameE = doc.createElement("INSTANCENAME");
1526 		String classname = instanceOP.getObjectName();
1527 		if (classname != null) {
1528 			instancenameE.setAttribute("CLASSNAME", classname);
1529 		}
1530 
1531 		CIMProperty<?>[] keysA = instanceOP.getKeys();
1532 		for (int ii = 0; ii < keysA.length; ii++) {
1533 			CIMProperty<?> prop = keysA[ii];
1534 			String propName = prop.getName();
1535 			CIMDataType propType = prop.getDataType();
1536 			Object propValue = prop.getValue();
1537 			// if (_pValue == null) TODO what happened when a KeyBinding has a
1538 			// null property value?
1539 			/*
1540 			 * ebak: test support for #1666336 EnumInstance has attributes
1541 			 * filled from others <!ELEMENT INSTANCENAME (KEYBINDING* |
1542 			 * KEYVALUE? | VALUE.REFERENCE?)> Handling direct KEYVALUE and
1543 			 * VALUE.REFERENCE children is difficult, KEYBINDING can wrap them
1544 			 * -> dropping out KEYVALUE? | VALUE.REFERENCE?.
1545 			 *
1546 			 * <!ELEMENT KEYBINDING (KEYVALUE | VALUE.REFERENCE)> <!ATTLIST
1547 			 * KEYBINDING %CIMName; >
1548 			 *
1549 			 * <!ELEMENT KEYVALUE (#PCDATA)> <!ATTLIST KEYVALUE VALUETYPE
1550 			 * (string | boolean | numeric) "string" %CIMType; #IMPLIED> - non
1551 			 * reference values can be null
1552 			 *
1553 			 * <!ELEMENT VALUE.REFERENCE (CLASSPATH | LOCALCLASSPATH | CLASSNAME
1554 			 * | INSTANCEPATH | LOCALINSTANCEPATH | INSTANCENAME)> - reference
1555 			 * value shouldn't be null
1556 			 */
1557 			if (propType == null) {
1558 				throw new WBEMException(
1559 					WBEMException.CIM_ERR_INVALID_PARAMETER,
1560 					"Type of property or key cannot be a null! " +
1561 					propName +
1562 					" in ObjectPath " +
1563 					instanceOP.toString() +
1564 					" has null type."
1565 				);
1566 			}
1567 
1568 			if (propValue == null) {
1569 				if (propType.getType() == CIMDataType.REFERENCE) {
1570 					throw new WBEMException(
1571 						WBEMException.CIM_ERR_INVALID_PARAMETER,
1572 						"Value of reference cannot be null! " +
1573 						propName +
1574 						" in ObjectPath " +
1575 						instanceOP.toString() +
1576 						" has null value."
1577 					);
1578 				}
1579 			}
1580 
1581 			Element keybindingE = createKEYBINDING(doc, instancenameE, propName);
1582 			if (propType.getType() == CIMDataType.REFERENCE) {
1583 				CIMObjectPath refOP = (CIMObjectPath) propValue;
1584 
1585 				createVALUEREFERENCE(doc, keybindingE, refOP);
1586 			} else {
1587 				String valueStr = propValue == null ? null : propValue.toString();
1588 				String valueTypeStr = getTypeStr(propType);
1589 				createKEYVALUE(doc, keybindingE, valueTypeStr, valueStr);
1590 			}
1591 		}
1592 
1593 		parentE.appendChild(instancenameE);
1594 		return instancenameE;
1595 	}
1596 
1597 	/**
1598 	 * createCLASSPATH
1599 	 *
1600 	 * @param pDoc
1601 	 * @param pParentE
1602 	 * @param pPath
1603 	 * @return Element
1604 	 */
1605 	public static Element createCLASSPATH(Document pDoc, Element pParentE, CIMObjectPath pPath) {
1606 		Element classpathE = pDoc.createElement("CLASSPATH");
1607 
1608 		// ebak: NAMESPACEPATH is necessary
1609 		createNAMESPACEPATH(pDoc, classpathE, pPath);
1610 		createCLASSNAME(pDoc, classpathE, pPath.getObjectName());
1611 
1612 		pParentE.appendChild(classpathE);
1613 		return classpathE;
1614 	}
1615 
1616 	/**
1617 	 * createPARAMETERS
1618 	 *
1619 	 * @param pDoc
1620 	 * @param pParentE
1621 	 * @param pParameters
1622 	 * @throws WBEMException
1623 	 */
1624 	public static void createPARAMETERS(Document pDoc, Element pParentE, CIMParameter<?>[] pParameters)
1625 		throws WBEMException {
1626 		if (pParameters == null) return;
1627 		for (int i = 0; i < pParameters.length; i++) {
1628 			createPARAMETER(pDoc, pParentE, pParameters[i]);
1629 		}
1630 	}
1631 
1632 	/**
1633 	 * createPARAMETER
1634 	 *
1635 	 * @param pDoc
1636 	 * @param pParentE
1637 	 * @param pParameter
1638 	 * @return Element
1639 	 * @throws WBEMException
1640 	 */
1641 	public static Element createPARAMETER(Document pDoc, Element pParentE, CIMParameter<?> pParameter)
1642 		throws WBEMException {
1643 		Element parameterE;
1644 		CIMDataType type = pParameter.getDataType();
1645 		int typeCode = type.getType();
1646 		EmbObjBuilder embObjBuilder = new EmbObjBuilder(pDoc, pParameter);
1647 		String typeStr = embObjBuilder.getTypeStr();
1648 		if (type.isArray()) {
1649 			if (typeCode == CIMDataType.REFERENCE) {
1650 				parameterE = pDoc.createElement("PARAMETER.REFARRAY");
1651 				String refclass = type.getRefClassName();
1652 				if (refclass != null && refclass.length() > 0) parameterE.setAttribute(
1653 					"REFERENCECLASS",
1654 					type.getRefClassName()
1655 				);
1656 			} else {
1657 				parameterE = pDoc.createElement("PARAMETER.ARRAY");
1658 				parameterE.setAttribute("TYPE", typeStr);
1659 			}
1660 		} else {
1661 			if (typeCode == CIMDataType.REFERENCE) {
1662 				parameterE = pDoc.createElement("PARAMETER.REFERENCE");
1663 				String refclass = type.getRefClassName();
1664 				if (refclass != null && refclass.length() > 0) parameterE.setAttribute(
1665 					"REFERENCECLASS",
1666 					type.getRefClassName()
1667 				);
1668 			} else {
1669 				parameterE = pDoc.createElement("PARAMETER");
1670 				parameterE.setAttribute("TYPE", typeStr);
1671 			}
1672 		}
1673 		parameterE.setAttribute("NAME", pParameter.getName());
1674 		embObjBuilder.addSign(parameterE);
1675 		createQUALIFIERS(pDoc, parameterE, pParameter.getQualifiers());
1676 
1677 		pParentE.appendChild(parameterE);
1678 		return parameterE;
1679 	}
1680 
1681 	/**
1682 	 * createMETHODS
1683 	 *
1684 	 * @param pDoc
1685 	 * @param pParentE
1686 	 * @param pMethods
1687 	 * @param pClassName
1688 	 * @throws WBEMException
1689 	 */
1690 	public static void createMETHODS(Document pDoc, Element pParentE, CIMMethod<?>[] pMethods, String pClassName)
1691 		throws WBEMException {
1692 		for (int i = 0; i < pMethods.length; i++) {
1693 			createMETHOD(pDoc, pParentE, pMethods[i], pClassName);
1694 		}
1695 	}
1696 
1697 	/**
1698 	 * createMETHOD
1699 	 *
1700 	 * @param pDoc
1701 	 * @param pParentE
1702 	 * @param pMethod
1703 	 * @param pClassName
1704 	 * @return Element
1705 	 * @throws WBEMException
1706 	 */
1707 	public static Element createMETHOD(Document pDoc, Element pParentE, CIMMethod<?> pMethod, String pClassName)
1708 		throws WBEMException {
1709 		Element methodE = pDoc.createElement("METHOD");
1710 
1711 		methodE.setAttribute("NAME", pMethod.getName());
1712 		EmbObjBuilder embObjBuilder = new EmbObjBuilder(pDoc, pMethod);
1713 		String typeStr = embObjBuilder.getTypeStr();
1714 		methodE.setAttribute("TYPE", typeStr);
1715 		String classorigin = pMethod.getOriginClass();
1716 
1717 		if (classorigin != null && classorigin.length() != 0) methodE.setAttribute("CLASSORIGIN", classorigin);
1718 
1719 		// 17459
1720 		if (pMethod.isPropagated()) {
1721 			methodE.setAttribute("PROPAGATED", MOF.TRUE);
1722 		} else {
1723 			methodE.setAttribute("PROPAGATED", MOF.FALSE);
1724 		}
1725 		// ebak: embedded object support
1726 		embObjBuilder.addSign(methodE);
1727 
1728 		createQUALIFIERS(pDoc, methodE, pMethod.getQualifiers());
1729 		createPARAMETERS(pDoc, methodE, pMethod.getParameters());
1730 
1731 		pParentE.appendChild(methodE);
1732 		return methodE;
1733 	}
1734 
1735 	/*
1736 	 * private static String elementStr(Element pE) { try {
1737 	 * ByteArrayOutputStream os = new ByteArrayOutputStream();
1738 	 * CimXmlSerializer.serialize(os, pE, true); return new
1739 	 * String(os.toByteArray()); } catch (RuntimeException e) { throw e; } catch
1740 	 * (Exception e) { throw new RuntimeException(e); } }
1741 	 */
1742 
1743 	/**
1744 	 * createCLASS
1745 	 *
1746 	 * @param pDoc
1747 	 * @param pParentE
1748 	 * @param pClass
1749 	 * @return Element
1750 	 * @throws WBEMException
1751 	 */
1752 	public static Element createCLASS(Document pDoc, Element pParentE, CIMClass pClass) throws WBEMException {
1753 		Element classE = createCLASS(pDoc, pParentE, pClass.getName(), pClass.getSuperClassName());
1754 
1755 		createQUALIFIERS(pDoc, classE, pClass.getQualifiers());
1756 		createPROPERTIES(pDoc, classE, pClass.getProperties());
1757 		createMETHODS(pDoc, classE, pClass.getMethods(), pClass.getName());
1758 
1759 		// parentE.appendChild(classE);
1760 		return classE;
1761 	}
1762 
1763 	/**
1764 	 * createHOST
1765 	 *
1766 	 * @param pDoc
1767 	 * @param pParentE
1768 	 * @param pHost
1769 	 * @return Element
1770 	 */
1771 	public static Element createHOST(Document pDoc, Element pParentE, String pHost) {
1772 		Element hostE = pDoc.createElement("HOST");
1773 
1774 		Text hostT = pDoc.createTextNode(pHost);
1775 		hostE.appendChild(hostT);
1776 
1777 		pParentE.appendChild(hostE);
1778 		return hostE;
1779 	}
1780 
1781 	/**
1782 	 * createNAMESPACEPATH
1783 	 *
1784 	 * @param pDoc
1785 	 * @param pParentE
1786 	 * @param pPath
1787 	 * @return Element
1788 	 */
1789 	public static Element createNAMESPACEPATH(Document pDoc, Element pParentE, CIMObjectPath pPath) {
1790 		Element namespacepathE = pDoc.createElement("NAMESPACEPATH");
1791 
1792 		String host = pPath.getHost();
1793 		if (host == null) {
1794 			// try {
1795 			// host = InetAddress.getLocalHost().getHostAddress();
1796 			// } catch (Exception e) {
1797 			// throw new CIMXMLBuilderException("Error while resolving
1798 			// hostname");
1799 			// }
1800 			host = "unassigned-hostname";
1801 		}
1802 		createHOST(pDoc, namespacepathE, host);
1803 		createLOCALNAMESPACEPATH(pDoc, namespacepathE, pPath);
1804 
1805 		pParentE.appendChild(namespacepathE);
1806 		return namespacepathE;
1807 	}
1808 
1809 	/**
1810 	 * createINSTANCEPATH
1811 	 *
1812 	 * @param pDoc
1813 	 * @param pParentE
1814 	 * @param pPath
1815 	 * @return Element
1816 	 * @throws WBEMException
1817 	 */
1818 	public static Element createINSTANCEPATH(Document pDoc, Element pParentE, CIMObjectPath pPath) throws WBEMException {
1819 		Element instancepathE = pDoc.createElement("INSTANCEPATH");
1820 
1821 		createNAMESPACEPATH(pDoc, instancepathE, pPath);
1822 		createINSTANCENAME(pDoc, instancepathE, pPath);
1823 		pParentE.appendChild(instancepathE);
1824 		return instancepathE;
1825 	}
1826 
1827 	/**
1828 	 * createVALUENAMEDINSTANCE
1829 	 *
1830 	 * @param pDoc
1831 	 * @param pParentE
1832 	 * @param pPath
1833 	 * @param pInst
1834 	 * @return Element
1835 	 * @throws WBEMException
1836 	 */
1837 	public static Element createVALUENAMEDINSTANCE(
1838 		Document pDoc,
1839 		Element pParentE,
1840 		CIMObjectPath pPath,
1841 		CIMInstance pInst
1842 	)
1843 		throws WBEMException {
1844 		Element valuenamedinstanceE = pDoc.createElement("VALUE.NAMEDINSTANCE");
1845 		createINSTANCENAME(pDoc, valuenamedinstanceE, pPath);
1846 		createINSTANCE(pDoc, valuenamedinstanceE, pInst);
1847 
1848 		pParentE.appendChild(valuenamedinstanceE);
1849 		return valuenamedinstanceE;
1850 	}
1851 
1852 	/**
1853 	 * createVALUENAMEDINSTANCE
1854 	 *
1855 	 * @param pDoc
1856 	 * @param pParentE
1857 	 * @param pInst
1858 	 * @return Element
1859 	 * @throws WBEMException
1860 	 */
1861 	public static Element createVALUENAMEDINSTANCE(Document pDoc, Element pParentE, CIMInstance pInst)
1862 		throws WBEMException {
1863 		Element valuenamedinstanceE = pDoc.createElement("VALUE.NAMEDINSTANCE");
1864 		createINSTANCENAME(pDoc, valuenamedinstanceE, pInst.getObjectPath());
1865 		createINSTANCE(pDoc, valuenamedinstanceE, pInst);
1866 
1867 		pParentE.appendChild(valuenamedinstanceE);
1868 		return valuenamedinstanceE;
1869 	}
1870 
1871 	private static CIMObjectPath changeNameSpace(CIMNamedElementInterface pNamedElement, String pNameSpace) {
1872 		CIMObjectPath path = pNamedElement.getObjectPath();
1873 		return new CIMObjectPath(
1874 			path.getScheme(),
1875 			path.getHost(),
1876 			path.getPort(),
1877 			pNameSpace,
1878 			path.getObjectName(),
1879 			path.getKeys()
1880 		);
1881 	}
1882 
1883 	private static CIMClass changeClassNameSpace(CIMClass pClass, String pNameSpace) {
1884 		CIMObjectPath newOp = changeNameSpace(pClass, pNameSpace);
1885 		return new CIMClass(
1886 			newOp,
1887 			pClass.getSuperClassName(),
1888 			pClass.getQualifiers(),
1889 			pClass.getProperties(),
1890 			pClass.getMethods(),
1891 			pClass.isAssociation(),
1892 			pClass.isKeyed()
1893 		);
1894 	}
1895 
1896 	private static CIMInstance changeInstanceNameSpace(CIMInstance pInst, String pNameSpace) {
1897 		CIMObjectPath newOp = changeNameSpace(pInst, pNameSpace);
1898 		return new CIMInstance(newOp, pInst.getProperties());
1899 	}
1900 
1901 	/**
1902 	 * createVALUEOBJECTWITHPATH
1903 	 *
1904 	 * @param pDoc
1905 	 * @param pParentE
1906 	 * @param pObj
1907 	 * @param pNameSpace
1908 	 * @return Element
1909 	 * @throws WBEMException
1910 	 */
1911 	public static Element createVALUEOBJECTWITHPATH(Document pDoc, Element pParentE, Object pObj, String pNameSpace)
1912 		throws WBEMException {
1913 		Element valueobjectwithpathE = pDoc.createElement("VALUE.OBJECTWITHPATH");
1914 		if (pObj instanceof CIMClass) {
1915 			CIMClass clazz = (CIMClass) pObj;
1916 
1917 			if (clazz.getObjectPath().getNamespace() == null || clazz.getObjectPath().getNamespace().length() == 0) {
1918 				// ebak: changing the namespace in clazz's objectPath
1919 				// clazz.getObjectPath().setNameSpace(pNameSpace);
1920 				clazz = changeClassNameSpace(clazz, pNameSpace);
1921 			}
1922 
1923 			createCLASSPATH(pDoc, valueobjectwithpathE, clazz.getObjectPath());
1924 			createCLASS(pDoc, valueobjectwithpathE, clazz);
1925 		} else if (pObj instanceof CIMInstance) {
1926 			CIMInstance inst = (CIMInstance) pObj;
1927 			if (inst.getObjectPath().getNamespace() == null || inst.getObjectPath().getNamespace().length() == 0) {
1928 				// ebak: changing the namespace ins inst's objectPath
1929 				// inst.getObjectPath().setNameSpace(pNameSpace);
1930 				inst = changeInstanceNameSpace(inst, pNameSpace);
1931 			}
1932 			createINSTANCEPATH(pDoc, valueobjectwithpathE, inst.getObjectPath());
1933 			createINSTANCE(pDoc, valueobjectwithpathE, inst);
1934 		}
1935 
1936 		pParentE.appendChild(valueobjectwithpathE);
1937 		return valueobjectwithpathE;
1938 	}
1939 
1940 	/**
1941 	 * createVALUEOBJECTWITHLOCALPATH
1942 	 *
1943 	 * @param pDoc
1944 	 * @param pParentE
1945 	 * @param pObj
1946 	 * @param pNameSpace
1947 	 * @return Element
1948 	 * @throws WBEMException
1949 	 */
1950 	public static Element createVALUEOBJECTWITHLOCALPATH(Document pDoc, Element pParentE, Object pObj, String pNameSpace)
1951 		throws WBEMException {
1952 		Element valueobjectwithpathE = pDoc.createElement("VALUE.OBJECTWITHLOCALPATH");
1953 		if (pObj instanceof CIMClass) {
1954 			CIMClass clazz = (CIMClass) pObj;
1955 
1956 			if (clazz.getObjectPath().getNamespace() == null || clazz.getObjectPath().getNamespace().length() == 0) {
1957 				// ebak: changing clazz's objectPath
1958 				// clazz.getObjectPath().setNameSpace(pNameSpace);
1959 				clazz = changeClassNameSpace(clazz, pNameSpace);
1960 			}
1961 			createLOCALCLASSPATH(pDoc, valueobjectwithpathE, clazz.getObjectPath());
1962 			createCLASS(pDoc, valueobjectwithpathE, clazz);
1963 		} else if (pObj instanceof CIMInstance) {
1964 			CIMInstance inst = (CIMInstance) pObj;
1965 			if (inst.getObjectPath().getNamespace() == null || inst.getObjectPath().getNamespace().length() == 0) {
1966 				// inst.getObjectPath().setNameSpace(pNameSpace);
1967 				inst = changeInstanceNameSpace(inst, pNameSpace);
1968 			}
1969 			createLOCALINSTANCEPATH(pDoc, valueobjectwithpathE, inst.getObjectPath());
1970 			createINSTANCE(pDoc, valueobjectwithpathE, inst);
1971 		}
1972 
1973 		pParentE.appendChild(valueobjectwithpathE);
1974 		return valueobjectwithpathE;
1975 	}
1976 
1977 	/**
1978 	 * createIRETURNVALUE_ERROR
1979 	 *
1980 	 * @param doc
1981 	 * @param parentE
1982 	 * @param error
1983 	 * @return Element
1984 	 */
1985 	public static Element createIRETURNVALUE_ERROR(Document doc, Element parentE, CIMError error) {
1986 		Element ireturnvalueE = doc.createElement("IRETURNVALUE");
1987 
1988 		parentE.appendChild(ireturnvalueE);
1989 		return ireturnvalueE;
1990 	}
1991 
1992 	/**
1993 	 * createIRETURNVALUE_GETINSTANCE
1994 	 *
1995 	 * @param pDoc
1996 	 * @param pParentE
1997 	 * @param pInst
1998 	 * @return Element
1999 	 * @throws WBEMException
2000 	 */
2001 	public static Element createIRETURNVALUE_GETINSTANCE(Document pDoc, Element pParentE, CIMInstance pInst)
2002 		throws WBEMException {
2003 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2004 		createINSTANCENAME(pDoc, ireturnvalueE, pInst.getObjectPath());
2005 
2006 		return ireturnvalueE;
2007 	}
2008 
2009 	/**
2010 	 * createIRETURNVALUE_ASSOCIATORS_NAMES
2011 	 *
2012 	 * @param pDoc
2013 	 * @param pParentE
2014 	 * @param pResultSet
2015 	 * @return Element
2016 	 * @throws Exception
2017 	 */
2018 	public static Element createIRETURNVALUE_ASSOCIATORS_NAMES(
2019 		Document pDoc,
2020 		Element pParentE,
2021 		CIMObjectPath[] pResultSet
2022 	)
2023 		throws Exception {
2024 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2025 
2026 		if (pResultSet != null) {
2027 			for (int i = 0; i < pResultSet.length; i++) {
2028 				CIMObjectPath path = pResultSet[i];
2029 
2030 				if (path.getHost() == null || "".equals(path.getHost())) createLOCALOBJECTPATH(
2031 					pDoc,
2032 					ireturnvalueE,
2033 					path
2034 				); else createOBJECTPATH(pDoc, ireturnvalueE, path);
2035 			}
2036 		}
2037 		pParentE.appendChild(ireturnvalueE);
2038 		return ireturnvalueE;
2039 	}
2040 
2041 	/**
2042 	 * createIRETURNVALUE_ASSOCIATORS
2043 	 *
2044 	 * @param pDoc
2045 	 * @param pParentE
2046 	 * @param pResultSet
2047 	 * @param pNameSpace
2048 	 * @return Element
2049 	 * @throws Exception
2050 	 */
2051 	public static Element createIRETURNVALUE_ASSOCIATORS(
2052 		Document pDoc,
2053 		Element pParentE,
2054 		Object[] pResultSet,
2055 		String pNameSpace
2056 	)
2057 		throws Exception {
2058 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2059 		if (pResultSet != null) {
2060 			for (int i = 0; i < pResultSet.length; i++) {
2061 				Object obj = pResultSet[i];
2062 				CIMObjectPath op = null;
2063 				if (obj instanceof CIMClass) {
2064 					op = ((CIMClass) obj).getObjectPath();
2065 				} else if (obj instanceof CIMInstance) {
2066 					op = ((CIMInstance) obj).getObjectPath();
2067 				} else {
2068 					throw new WBEMException(WBEMException.CIM_ERR_FAILED, "object in result set neither class nor instance!");
2069 				}
2070 				if (op.getHost() == null || "".equals(op.getHost())) {
2071 					createVALUEOBJECTWITHLOCALPATH(pDoc, ireturnvalueE, obj, pNameSpace);
2072 				} else {
2073 					createVALUEOBJECTWITHPATH(pDoc, ireturnvalueE, obj, pNameSpace);
2074 				}
2075 			}
2076 		}
2077 		pParentE.appendChild(ireturnvalueE);
2078 		return ireturnvalueE;
2079 	}
2080 
2081 	/**
2082 	 * createIRETURNVALUE_ENUMERATE_INSTANCENAME
2083 	 *
2084 	 * @param pDoc
2085 	 * @param pParentE
2086 	 * @param pResultSet
2087 	 * @param pNameSpace
2088 	 * @return Element
2089 	 * @throws Exception
2090 	 */
2091 	public static Element createIRETURNVALUE_ENUMERATE_INSTANCENAME(
2092 		Document pDoc,
2093 		Element pParentE,
2094 		Object[] pResultSet,
2095 		String pNameSpace
2096 	)
2097 		throws Exception {
2098 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2099 		if (pResultSet != null) {
2100 			for (int i = 0; i < pResultSet.length; i++) {
2101 				Object obj = pResultSet[i];
2102 				CIMObjectPath op = null;
2103 				if (obj instanceof CIMClass) {
2104 					op = ((CIMClass) obj).getObjectPath();
2105 				} else if (obj instanceof CIMInstance) {
2106 					op = ((CIMInstance) obj).getObjectPath();
2107 				} else {
2108 					throw new WBEMException(WBEMException.CIM_ERR_FAILED, "object in result set neither class nor instance!");
2109 				}
2110 				if (op.getHost() == null || "".equals(op.getHost())) {
2111 					createVALUEOBJECTWITHLOCALPATH(pDoc, ireturnvalueE, obj, pNameSpace);
2112 				} else {
2113 					createVALUEOBJECTWITHPATH(pDoc, ireturnvalueE, obj, pNameSpace);
2114 				}
2115 			}
2116 		}
2117 		pParentE.appendChild(ireturnvalueE);
2118 		return ireturnvalueE;
2119 	}
2120 
2121 	/**
2122 	 * createIRETURNVALUE
2123 	 *
2124 	 * @param pDoc
2125 	 * @param pParentE
2126 	 * @param pResultSet
2127 	 * @return Element
2128 	 * @throws WBEMException
2129 	 */
2130 	public static Element createIRETURNVALUE(Document pDoc, Element pParentE, Object[] pResultSet) throws WBEMException {
2131 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2132 		if (pResultSet != null && pResultSet.length > 0) {
2133 			Object obj = pResultSet[0];
2134 			if (obj instanceof CIMClass) {
2135 				for (int i = 0; i < pResultSet.length; i++) {
2136 					CIMClass clazz = (CIMClass) pResultSet[i];
2137 					Element classnameE = pDoc.createElement("CLASSNAME");
2138 					ireturnvalueE.appendChild(classnameE);
2139 					if (clazz.getName() != null) classnameE.setAttribute("NAME", clazz.getName());
2140 				}
2141 			} else if (obj instanceof CIMInstance) {
2142 				for (int i = 0; i < pResultSet.length; i++) {
2143 					CIMInstance inst = (CIMInstance) pResultSet[i];
2144 					createVALUENAMEDINSTANCE(pDoc, ireturnvalueE, inst);
2145 				}
2146 			}
2147 		}
2148 		pParentE.appendChild(ireturnvalueE);
2149 		return ireturnvalueE;
2150 	}
2151 
2152 	/**
2153 	 * createIRETURNVALUE_ENUMERATE_CLASSNAME
2154 	 *
2155 	 * @param pDoc
2156 	 * @param pParentE
2157 	 * @param pResultSet
2158 	 * @return Element
2159 	 */
2160 	public static Element createIRETURNVALUE_ENUMERATE_CLASSNAME(Document pDoc, Element pParentE, CIMClass[] pResultSet) {
2161 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2162 		if (pResultSet != null && pResultSet.length > 0) {
2163 			for (int i = 0; i < pResultSet.length; i++) {
2164 				CIMClass clazz = pResultSet[i];
2165 
2166 				Element classnameE = pDoc.createElement("CLASSNAME");
2167 				ireturnvalueE.appendChild(classnameE);
2168 				if (clazz.getName() != null) classnameE.setAttribute("NAME", clazz.getName());
2169 			}
2170 		}
2171 		pParentE.appendChild(ireturnvalueE);
2172 		return ireturnvalueE;
2173 	}
2174 
2175 	/**
2176 	 * createIndication_response
2177 	 *
2178 	 * @param doc
2179 	 * @param ID
2180 	 * @param error
2181 	 * @return Element
2182 	 */
2183 	// ebak: [ 1656285 ] IndicationHandler does not accept non-Integer message
2184 	// ID
2185 	public static Element createIndication_response(Document doc, String ID, CIMError error) {
2186 		// xmlBuilder.create XML
2187 		Element cimE = createCIM(doc);
2188 		Element messageE = createMESSAGE(doc, cimE, ID, "1.0");
2189 		Element simpleexprspE = createSIMPLEEXPRSP(doc, messageE);
2190 		Element expmethodresponseE = createEXPMETHODRESPONSE(doc, simpleexprspE, "ExportIndication");
2191 		if (error == null) {
2192 			createIRETURNVALUE(doc, expmethodresponseE);
2193 		} else {
2194 			createERROR(doc, expmethodresponseE, error);
2195 		}
2196 		// Element
2197 		return cimE;
2198 	}
2199 
2200 	/**
2201 	 * createIRETURNVALUE_ENUMERATE_INSTANCE
2202 	 *
2203 	 * @param pDoc
2204 	 * @param pParentE
2205 	 * @param pResultSet
2206 	 * @return Element
2207 	 * @throws WBEMException
2208 	 */
2209 	public static Element createIRETURNVALUE_ENUMERATE_INSTANCE(
2210 		Document pDoc,
2211 		Element pParentE,
2212 		CIMInstance[] pResultSet
2213 	)
2214 		throws WBEMException {
2215 		Element ireturnvalueE = pDoc.createElement("IRETURNVALUE");
2216 		if (pResultSet != null && pResultSet.length > 0) {
2217 			for (int i = 0; i < pResultSet.length; i++) {
2218 				createVALUENAMEDINSTANCE(pDoc, ireturnvalueE, pResultSet[i]);
2219 			}
2220 		}
2221 		pParentE.appendChild(ireturnvalueE);
2222 		return ireturnvalueE;
2223 	}
2224 
2225 	/**
2226 	 * getTypeStr
2227 	 *
2228 	 * @param pType
2229 	 * @return String
2230 	 */
2231 	public static String getTypeStr(CIMDataType pType) {
2232 		if (pType == null) return "string";
2233 		if (pType.getType() == CIMDataType.REFERENCE) return MOF.REFERENCE;
2234 		return MOF.dataType(pType);
2235 	}
2236 
2237 	/**
2238 	 * getOpTypeStr
2239 	 *
2240 	 * @param pType
2241 	 * @return String
2242 	 */
2243 	public static String getOpTypeStr(CIMDataType pType) {
2244 		return getTypeStr(pType);
2245 	}
2246 
2247 	private static final Pattern NAMESPACE_SPLIT_PATTERN = Pattern.compile("/+");
2248 
2249 	/**
2250 	 * createLOCALNAMESPACEPATH
2251 	 *
2252 	 * @param pDoc
2253 	 * @param pParentE
2254 	 * @param pName
2255 	 * @return Element
2256 	 */
2257 	public static Element createLOCALNAMESPACEPATH(Document pDoc, Element pParentE, CIMObjectPath pName) {
2258 		if (pName == null) return null;
2259 		// TODO: name(ObjectPath) should not be null, should an exception be
2260 		// thrown?
2261 		// This assumes that the NameSpace does not consist exclusively of
2262 		// empties like "////"
2263 		Element localnamespacepathE = pDoc.createElement("LOCALNAMESPACEPATH");
2264 		String nameSpace = pName.getNamespace();
2265 		if (nameSpace != null) {
2266 			String[] nsA = NAMESPACE_SPLIT_PATTERN.split(nameSpace);
2267 			for (int i = 0; i < nsA.length; i++) if (nsA[i] != null && nsA[i].length() > 0) createNAMESPACE(
2268 				pDoc,
2269 				localnamespacepathE,
2270 				nsA[i]
2271 			);
2272 		}
2273 		pParentE.appendChild(localnamespacepathE);
2274 
2275 		return localnamespacepathE;
2276 	}
2277 
2278 	/**
2279 	 * createSIMPLEEXPREQ
2280 	 *
2281 	 * @param pDoc
2282 	 * @return Element
2283 	 */
2284 	public static Element createSIMPLEEXPREQ(Document pDoc) {
2285 		// <!ELEMENT SIMPLEEXPREQ (EXPMETHODCALL)>
2286 		Element e = pDoc.createElement("SIMPLEEXPREQ");
2287 		return e;
2288 	}
2289 
2290 	/**
2291 	 * createEXPMETHODCALL
2292 	 *
2293 	 * @param pDoc
2294 	 * @param pParentE
2295 	 * @param pName
2296 	 * @return Element
2297 	 */
2298 	public static Element createEXPMETHODCALL(Document pDoc, Element pParentE, String pName) {
2299 		// <!ELEMENT EXPMETHODCALL (EXPPARAMVALUE*)>
2300 		// <!ATTLIST EXPMETHODCALL %NAME>
2301 		Element e = pDoc.createElement("EXPMETHODCALL");
2302 		if (pName != null) {
2303 			e.setAttribute("NAME", pName);
2304 		}
2305 		pParentE.appendChild(e);
2306 		return e;
2307 	}
2308 
2309 	/**
2310 	 * createEXPPARAMVALUE
2311 	 *
2312 	 * @param pDoc
2313 	 * @param pParentE
2314 	 * @param pName
2315 	 * @return Element
2316 	 */
2317 	public static Element createEXPPARAMVALUE(Document pDoc, Element pParentE, String pName) {
2318 		// <!ELEMENT EXPPARAMVALUE (INSTANCE? | VALUE? | METHODRESPONSE? |
2319 		// IMETHODRESPONSE?)>
2320 		// <!ATTLIST EXPPARAMVALUE %NAME>
2321 		Element e = pDoc.createElement("EXPPARAMVALUE");
2322 		if (pName != null) {
2323 			e.setAttribute("NAME", pName);
2324 		}
2325 		pParentE.appendChild(e);
2326 		return e;
2327 	}
2328 }