- Fixed EDKT240. Now the Blank.pad file for alignment purpose will no longer be needed.
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / fpd / PlatformBuildFileGenerator.java
1 /** @file
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 **/
12 package org.tianocore.build.fpd;
13
14 import java.io.File;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Set;
19
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.DocumentBuilderFactory;
22 import javax.xml.transform.OutputKeys;
23 import javax.xml.transform.Result;
24 import javax.xml.transform.Source;
25 import javax.xml.transform.Transformer;
26 import javax.xml.transform.TransformerFactory;
27 import javax.xml.transform.dom.DOMSource;
28 import javax.xml.transform.stream.StreamResult;
29
30 import org.apache.tools.ant.BuildException;
31 import org.apache.tools.ant.Project;
32 import org.tianocore.build.global.GlobalData;
33 import org.tianocore.build.global.SurfaceAreaQuery;
34 import org.tianocore.build.id.FpdModuleIdentification;
35 import org.tianocore.build.id.ModuleIdentification;
36 import org.w3c.dom.Comment;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.Element;
39 import org.w3c.dom.NamedNodeMap;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42
43 /**
44 class PlatformBuildFileGenerator is used to generate ${PLATFORM}_build.xml file.
45
46 @since GenBuild 1.0
47 **/
48 public class PlatformBuildFileGenerator {
49
50 ///
51 /// Mapping from modules identification to out put file name
52 ///
53 private Map<FpdModuleIdentification, String> outfiles;
54
55 ///
56 /// Mapping from FV name to its modules
57 ///
58 private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
59
60
61 private boolean isUnified = true;
62
63 private SurfaceAreaQuery saq = null;
64
65 private File platformBuildFile = null;
66
67 private Map<String, String> aprioriType = null;
68
69 private Project project;
70
71 private String info = "DO NOT EDIT \n"
72 + "This file is auto-generated by the build utility\n"
73 + "\n"
74 + "Abstract:\n"
75 + "Auto-generated ANT build file for building EFI Modules and Platforms\n";
76
77 public PlatformBuildFileGenerator(Project project, Map<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> fvs, boolean isUnified, SurfaceAreaQuery saq, String platformBuildFile, Map<String, String> aprioriType){
78 this.project = project;
79 this.outfiles = outfiles;
80 this.isUnified = isUnified;
81 this.fvs = fvs;
82 this.saq = saq;
83 this.platformBuildFile = new File(platformBuildFile);
84 this.aprioriType = aprioriType;
85 }
86
87 /**
88 Generate build.out.xml file.
89
90 @throws BuildException
91 build.out.xml XML document create error
92 **/
93 public void genBuildFile() throws BuildException {
94 DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
95 try {
96 DocumentBuilder dombuilder = domfac.newDocumentBuilder();
97 Document document = dombuilder.newDocument();
98 Comment rootComment = document.createComment(info);
99 //
100 // create root element and its attributes
101 //
102 Element root = document.createElement("project");
103 root.setAttribute("name", project.getProperty("PLATFORM"));
104 root.setAttribute("default", "all");
105 root.setAttribute("basedir", ".");
106
107 //
108 // element for External ANT tasks
109 //
110 root.appendChild(document.createComment("Apply external ANT tasks"));
111 Element ele = document.createElement("taskdef");
112 ele.setAttribute("resource", "GenBuild.tasks");
113 root.appendChild(ele);
114
115 ele = document.createElement("taskdef");
116 ele.setAttribute("resource", "frameworktasks.tasks");
117 root.appendChild(ele);
118
119 ele = document.createElement("taskdef");
120 ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
121 root.appendChild(ele);
122
123 ele = document.createElement("property");
124 ele.setAttribute("environment", "env");
125 root.appendChild(ele);
126
127 //
128 // Default Target
129 //
130 root.appendChild(document.createComment("Default target"));
131 ele = document.createElement("target");
132 ele.setAttribute("name", "all");
133 ele.setAttribute("depends", "prebuild, modules, fvs, postbuild");
134 root.appendChild(ele);
135
136 //
137 // Modules and Fvs Target
138 //
139 applyModules(document, root);
140
141 applyFvs(document, root);
142
143 //
144 // Clean Target
145 //
146 applyClean(document, root);
147
148 //
149 // Deep Clean Target
150 //
151 applyCleanall(document, root);
152
153 //
154 // User Extension pre build
155 //
156 applyUserExtensionsPreBuild(document, root);
157
158 //
159 // User Extension Post build
160 //
161 applyUserExtensionsPostBuild(document, root);
162 applyUserExtensions(document, root);
163
164 document.appendChild(rootComment);
165 document.appendChild(root);
166 //
167 // Prepare the DOM document for writing
168 //
169 Source source = new DOMSource(document);
170 //
171 // generate all directory path
172 //
173 (new File(platformBuildFile.getParent())).mkdirs();
174 Result result = new StreamResult(platformBuildFile);
175 //
176 // Write the DOM document to the file
177 //
178 Transformer xformer = TransformerFactory.newInstance().newTransformer();
179 xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
180 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
181 xformer.transform(source, result);
182 } catch (Exception ex) {
183 throw new BuildException("Generating platform build file [" + platformBuildFile.getPath() + "_build.xml] failed. \n" + ex.getMessage());
184 }
185 }
186
187 /**
188 1. Get All valid Fv Image Names in sequence
189 2. For each FV, get modules by sequences
190 3. Get other modules
191
192 @param document XML document
193 @param root Node
194 **/
195 private void applyModules(Document document, Node root) {
196 root.appendChild(document.createComment("Modules target"));
197 Element ele = document.createElement("target");
198 ele.setAttribute("name", "modules");
199
200 //
201 // Try to build apriori if necessary
202 //
203 //
204 // For every Target and ToolChain
205 //
206 String[] targetList = GlobalData.getToolChainInfo().getTargets();
207 for (int i = 0; i < targetList.length; i++){
208 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
209 for(int j = 0; j < toolchainList.length; j++){
210 //
211 // Prepare FV_DIR
212 //
213 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
214 + targetList[i] + "_"
215 + toolchainList[j];
216 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
217 Element fvEle = document.createElement("var");
218 fvEle.setAttribute("name", "FV_DIR");
219 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
220 ele.appendChild(fvEle);
221
222 Iterator<String> aprIter = aprioriType.keySet().iterator();
223 while (aprIter.hasNext()) {
224 String fvName = aprIter.next();
225 Element moduleEle = document.createElement("Build_Apriori");
226 moduleEle.setAttribute("FILENAME", fvName);
227 moduleEle.setAttribute("GUID", aprioriType.get(fvName));
228 ele.appendChild(moduleEle);
229 }
230 }
231 }
232
233 //
234 // Get all valid FV name
235 //
236 String[] validFv = saq.getFpdValidImageNames();
237
238 //
239 // For each valid FV, get all modules in sequence
240 //
241 for (int i = 0; i < validFv.length; i++) {
242 if (fvs.containsKey(validFv[i])) {
243 Set<FpdModuleIdentification> set = fvs.get(validFv[i]);
244 Iterator<FpdModuleIdentification> iter = set.iterator();
245 while (iter.hasNext()) {
246 FpdModuleIdentification fpdModuleId = iter.next();
247 applySingleModule(document, ele, fpdModuleId);
248 }
249 }
250 }
251
252 //
253 // Get all other modules
254 //
255 Iterator<String> fvsNameIter = fvs.keySet().iterator();
256
257 while (fvsNameIter.hasNext()) {
258 String fvName = fvsNameIter.next();
259 if (!isContain(validFv, fvName)) {
260 Set<FpdModuleIdentification> set = fvs.get(fvName);
261 Iterator iter = set.iterator();
262 while (iter.hasNext()) {
263 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
264 applySingleModule(document, ele, fpdModuleId);
265 }
266 }
267 }
268
269 root.appendChild(ele);
270 }
271
272 private void applySingleModule(Document document, Node root, FpdModuleIdentification fpdModuleId) {
273 ModuleIdentification moduleId = fpdModuleId.getModule();
274 Element moduleEle = document.createElement("GenBuild");
275 moduleEle.setAttribute("type", "build");
276 //
277 // Inherit Properties.
278 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
279 //
280
281 //
282 // ARCH
283 //
284 Element property = document.createElement("property");
285 property.setAttribute("name", "ARCH");
286 property.setAttribute("value", fpdModuleId.getArch());
287 moduleEle.appendChild(property);
288
289 //
290 // MODULE_GUID
291 //
292 property = document.createElement("property");
293 property.setAttribute("name", "MODULE_GUID");
294 property.setAttribute("value", moduleId.getGuid());
295 moduleEle.appendChild(property);
296
297 //
298 // MODULE_VERSION
299 //
300 property = document.createElement("property");
301 property.setAttribute("name", "MODULE_VERSION");
302 property.setAttribute("value", moduleId.getVersion());
303 moduleEle.appendChild(property);
304
305 //
306 // PACKAGE_GUID
307 //
308 property = document.createElement("property");
309 property.setAttribute("name", "PACKAGE_GUID");
310 property.setAttribute("value", moduleId.getPackage().getGuid());
311 moduleEle.appendChild(property);
312
313 //
314 // PACKAGE_VERSION
315 //
316 property = document.createElement("property");
317 property.setAttribute("name", "PACKAGE_VERSION");
318 property.setAttribute("value", moduleId.getPackage().getVersion());
319 moduleEle.appendChild(property);
320
321 root.appendChild(moduleEle);
322 }
323
324 private boolean isContain(String[] list, String item) {
325 for (int i = 0; i < list.length; i++) {
326 if (list[i].equalsIgnoreCase(item)) {
327 return true;
328 }
329 }
330 return false;
331 }
332
333 private void applyFvs(Document document, Node root) {
334 //
335 // FVS Target
336 //
337 root.appendChild(document.createComment("FVs target"));
338 Element ele = document.createElement("target");
339 ele.setAttribute("name", "fvs");
340
341 //
342 // For every Target and ToolChain
343 //
344 String[] targetList = GlobalData.getToolChainInfo().getTargets();
345 for (int i = 0; i < targetList.length; i++){
346 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
347 for(int j = 0; j < toolchainList.length; j++){
348 String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar
349 + targetList[i] + "_"
350 + toolchainList[j] + File.separatorChar + "FV";
351 String[] validFv = saq.getFpdValidImageNames();
352 for (int k = 0; k < validFv.length; k++) {
353 String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";
354 Element fvEle = document.createElement("genfvimage");
355 fvEle.setAttribute("infFile", inputFile);
356 fvEle.setAttribute("outputDir", fvOutputDir);
357 ele.appendChild(fvEle);
358 }
359 }
360 }
361 root.appendChild(ele);
362 }
363
364 private void applyClean(Document document, Node root) {
365 //
366 // Clean Target
367 //
368 root.appendChild(document.createComment("Clean target"));
369 Element ele = document.createElement("target");
370 ele.setAttribute("name", "clean");
371
372 if (isUnified) {
373 Element cleanEle = document.createElement("delete");
374 cleanEle.setAttribute("includeemptydirs", "true");
375 Element filesetEle = document.createElement("fileset");
376 filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
377 filesetEle.setAttribute("includes", "**\\OUTPUT\\**");
378 cleanEle.appendChild(filesetEle);
379 ele.appendChild(cleanEle);
380 } else {
381 Set set = outfiles.keySet();
382 Iterator iter = set.iterator();
383 while (iter.hasNext()) {
384 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
385 ModuleIdentification moduleId = fpdModuleId.getModule();
386
387 Element ifEle = document.createElement("if");
388 Element availableEle = document.createElement("available");
389 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
390 + "build.xml");
391 ifEle.appendChild(availableEle);
392 Element elseEle = document.createElement("then");
393
394 Element moduleEle = document.createElement("ant");
395 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
396 + "build.xml");
397 moduleEle.setAttribute("target", "clean");
398 //
399 // Inherit Properties.
400 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
401 //
402
403 //
404 // ARCH
405 //
406 Element property = document.createElement("property");
407 property.setAttribute("name", "ARCH");
408 property.setAttribute("value", fpdModuleId.getArch());
409 moduleEle.appendChild(property);
410
411 //
412 // PACKAGE
413 //
414 property = document.createElement("property");
415 property.setAttribute("name", "PACKAGE");
416 property.setAttribute("value", moduleId.getPackage().getName());
417 moduleEle.appendChild(property);
418
419 //
420 // PACKAGE_GUID
421 //
422 property = document.createElement("property");
423 property.setAttribute("name", "PACKAGE_GUID");
424 property.setAttribute("value", moduleId.getPackage().getGuid());
425 moduleEle.appendChild(property);
426
427 //
428 // PACKAGE_VERSION
429 //
430 property = document.createElement("property");
431 property.setAttribute("name", "PACKAGE_VERSION");
432 property.setAttribute("value", moduleId.getPackage().getVersion());
433 moduleEle.appendChild(property);
434
435 //
436 // MODULE_DIR
437 //
438 property = document.createElement("property");
439 property.setAttribute("name", "MODULE_DIR");
440 property.setAttribute("value", moduleId.getMsaFile().getParent());
441 moduleEle.appendChild(property);
442 elseEle.appendChild(moduleEle);
443 ifEle.appendChild(elseEle);
444 ele.appendChild(ifEle);
445 }
446 }
447 root.appendChild(ele);
448 }
449
450 private void applyCleanall(Document document, Node root) {
451 //
452 // Deep Clean Target
453 //
454 root.appendChild(document.createComment("Target: cleanall"));
455 Element ele = document.createElement("target");
456 ele.setAttribute("name", "cleanall");
457
458 if (isUnified) {
459 String[] targetList = GlobalData.getToolChainInfo().getTargets();
460 for (int i = 0; i < targetList.length; ++i) {
461 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
462 for(int j = 0; j < toolchainList.length; j++) {
463 Element cleanAllEle = document.createElement("delete");
464 cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR") + File.separatorChar + targetList[i] + "_" + toolchainList[j]);
465 ele.appendChild(cleanAllEle);
466 }
467 }
468 } else {
469 Set set = outfiles.keySet();
470 Iterator iter = set.iterator();
471 while (iter.hasNext()) {
472 FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
473 ModuleIdentification moduleId = fpdModuleId.getModule();
474
475 Element ifEle = document.createElement("if");
476 Element availableEle = document.createElement("available");
477 availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
478 + "build.xml");
479 ifEle.appendChild(availableEle);
480 Element elseEle = document.createElement("then");
481
482 Element moduleEle = document.createElement("ant");
483 moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
484 + "build.xml");
485 moduleEle.setAttribute("target", "cleanall");
486 //
487 // Inherit Properties.
488 //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
489 //
490
491 //
492 // ARCH
493 //
494 Element property = document.createElement("property");
495 property.setAttribute("name", "ARCH");
496 property.setAttribute("value", fpdModuleId.getArch());
497 moduleEle.appendChild(property);
498
499 //
500 // PACKAGE
501 //
502 property = document.createElement("property");
503 property.setAttribute("name", "PACKAGE");
504 property.setAttribute("value", moduleId.getPackage().getName());
505 moduleEle.appendChild(property);
506
507 //
508 // PACKAGE_GUID
509 //
510 property = document.createElement("property");
511 property.setAttribute("name", "PACKAGE_GUID");
512 property.setAttribute("value", moduleId.getPackage().getGuid());
513 moduleEle.appendChild(property);
514
515 //
516 // PACKAGE_VERSION
517 //
518 property = document.createElement("property");
519 property.setAttribute("name", "PACKAGE_VERSION");
520 property.setAttribute("value", moduleId.getPackage().getVersion());
521 moduleEle.appendChild(property);
522
523 //
524 // MODULE_DIR
525 //
526 property = document.createElement("property");
527 property.setAttribute("name", "MODULE_DIR");
528 property.setAttribute("value", moduleId.getMsaFile().getParent());
529 moduleEle.appendChild(property);
530 elseEle.appendChild(moduleEle);
531 ifEle.appendChild(elseEle);
532 ele.appendChild(ifEle);
533 }
534 }
535 root.appendChild(ele);
536 }
537
538 private void applyUserExtensionsPreBuild(Document document, Node root) {
539 //
540 // User Extensions
541 //
542 root.appendChild(document.createComment("Pre-Build Processing"));
543 Element ele = document.createElement("target");
544 ele.setAttribute("name", "prebuild");
545
546 Node node = saq.getFpdUserExtensionPreBuild();
547 if (node != null) {
548 //
549 // For every Target and ToolChain
550 //
551 String[] targetList = GlobalData.getToolChainInfo().getTargets();
552 for (int i = 0; i < targetList.length; i++){
553 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
554 for(int j = 0; j < toolchainList.length; j++){
555 //
556 // Prepare FV_DIR
557 //
558 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
559 + targetList[i] + "_"
560 + toolchainList[j];
561 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
562 Element fvEle = document.createElement("var");
563 fvEle.setAttribute("name", "FV_DIR");
564 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
565 ele.appendChild(fvEle);
566
567 Element targetDirEle = document.createElement("var");
568 targetDirEle.setAttribute("name", "TARGET_DIR");
569 targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/"));
570 ele.appendChild(targetDirEle);
571
572 NodeList childNodes = node.getChildNodes();
573 for (int k = 0; k < childNodes.getLength(); k++) {
574 Node childItem = childNodes.item(k);
575 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
576 ele.appendChild(recursiveNode(childItem, document));
577 }
578 }
579 }
580 }
581 }
582
583 root.appendChild(ele);
584 }
585
586 private void applyUserExtensionsPostBuild(Document document, Node root) {
587 //
588 // User Extensions
589 //
590 root.appendChild(document.createComment("Post-Build Processing"));
591 Element ele = document.createElement("target");
592 ele.setAttribute("name", "postbuild");
593
594 Node node = saq.getFpdUserExtensionPostBuild();
595 if (node != null) {
596 //
597 // For every Target and ToolChain
598 //
599 String[] targetList = GlobalData.getToolChainInfo().getTargets();
600 for (int i = 0; i < targetList.length; i++){
601 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
602 for(int j = 0; j < toolchainList.length; j++){
603 //
604 // Prepare FV_DIR
605 //
606 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
607 + targetList[i] + "_"
608 + toolchainList[j];
609 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
610 Element fvEle = document.createElement("var");
611 fvEle.setAttribute("name", "FV_DIR");
612 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
613 ele.appendChild(fvEle);
614
615 Element targetDirEle = document.createElement("var");
616 targetDirEle.setAttribute("name", "TARGET_DIR");
617 targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/"));
618 ele.appendChild(targetDirEle);
619
620 NodeList childNodes = node.getChildNodes();
621 for (int k = 0; k < childNodes.getLength(); k++) {
622 Node childItem = childNodes.item(k);
623 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
624 ele.appendChild(recursiveNode(childItem, document));
625 }
626 }
627
628 }
629 }
630 }
631
632 root.appendChild(ele);
633 }
634
635 private void applyUserExtensions(Document document, Node root) {
636 Node[] nodeList = saq.getFpdUserExtensions();
637 for (int nodeIndex = 0; nodeIndex < nodeList.length; ++nodeIndex) {
638 Node node = nodeList[nodeIndex];
639 //
640 // User Extensions
641 //
642 root.appendChild(document.createComment("User Defined Target"));
643 Element ele = document.createElement("target");
644 ele.setAttribute("name", node.getAttributes().getNamedItem("Identifier").getNodeValue());
645
646 if (node != null) {
647 //
648 // For every Target and ToolChain
649 //
650 String[] targetList = GlobalData.getToolChainInfo().getTargets();
651 for (int i = 0; i < targetList.length; i++){
652 String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
653 for(int j = 0; j < toolchainList.length; j++){
654 //
655 // Prepare FV_DIR
656 //
657 String ffsCommonDir = project.getProperty("BUILD_DIR") + File.separatorChar
658 + targetList[i] + "_"
659 + toolchainList[j];
660 File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
661 Element fvEle = document.createElement("var");
662 fvEle.setAttribute("name", "FV_DIR");
663 fvEle.setAttribute("value", fvDir.getPath().replaceAll("(\\\\)", "/"));
664 ele.appendChild(fvEle);
665
666 Element targetDirEle = document.createElement("var");
667 targetDirEle.setAttribute("name", "TARGET_DIR");
668 targetDirEle.setAttribute("value", ffsCommonDir.replaceAll("(\\\\)", "/"));
669 ele.appendChild(targetDirEle);
670
671 NodeList childNodes = node.getChildNodes();
672 for (int k = 0; k < childNodes.getLength(); k++) {
673 Node childItem = childNodes.item(k);
674 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
675 ele.appendChild(recursiveNode(childItem, document));
676 }
677 }
678
679 }
680 }
681 }
682
683 root.appendChild(ele);
684 }
685 }
686
687 private Element recursiveNode(Node node, Document document) {
688 Element root = document.createElement(node.getNodeName());
689 NamedNodeMap attr = node.getAttributes();
690 for (int i = 0; i < attr.getLength(); i++) {
691 Node attrItem = attr.item(i);
692 root.setAttribute(attrItem.getNodeName(), attrItem.getNodeValue());
693 }
694 NodeList childNodes = node.getChildNodes();
695 for (int i = 0; i < childNodes.getLength(); i++) {
696 Node childItem = childNodes.item(i);
697 if (childItem.getNodeType() == Node.ELEMENT_NODE) {
698 root.appendChild(recursiveNode(childItem, document));
699 }
700 else if (childItem.getNodeType() == Node.TEXT_NODE){
701 if (!childItem.getNodeValue().trim().equalsIgnoreCase("")) {
702 root.setTextContent(childItem.getNodeValue());
703 }
704 }
705 }
706 return root;
707 }
708 }