source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXSLT.java@ 26558

Last change on this file since 26558 was 26558, checked in by sjm84, 11 years ago

Fixing the problem where multiple debug elements are between a table and a tr tag or between a tr tag and a td tag

  • Property svn:keywords set to Author Date Id Revision
File size: 22.5 KB
Line 
1/*
2 * GSXSLT.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import java.io.File;
22import java.util.ArrayList;
23import java.util.HashMap;
24import java.util.Vector;
25
26import org.apache.log4j.Logger;
27import org.greenstone.util.GlobalProperties;
28import org.w3c.dom.Document;
29import org.w3c.dom.Element;
30import org.w3c.dom.NamedNodeMap;
31import org.w3c.dom.Node;
32import org.w3c.dom.NodeList;
33
34/** various functions for manipulating Greenstone xslt */
35public class GSXSLT
36{
37
38 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXSLT.class.getName());
39
40 public static void mergeStylesheets(Document main_xsl, Element extra_xsl, boolean overwrite)
41 {
42 mergeStylesheetsDebug(main_xsl, extra_xsl, overwrite, false, null, null);
43 }
44
45 /**
46 * takes a stylesheet Document, and adds in any child nodes from extra_xsl
47 * named templates overwrite any existing one, while match templates are
48 * just added to the end of the stylesheet
49 *
50 * elements are added in following order, and added to preserve original
51 * order with imported ones coming after existing ones import, include,
52 * output, variable, template
53 */
54 public static void mergeStylesheetsDebug(Document main_xsl, Element extra_xsl, boolean overwrite, boolean debug, String firstDocFileName, String secondDocFileName)
55 {
56 if (debug)
57 {
58 insertDebugElements(main_xsl, firstDocFileName);
59 }
60
61 Element main = main_xsl.getDocumentElement();
62 Node insertion_point = null;
63 Element last_import = GSXML.getLastElementByTagNameNS(main, GSXML.XSL_NAMESPACE, "import");
64 if (last_import != null)
65 {
66 insertion_point = last_import.getNextSibling();
67 }
68 else
69 {
70 insertion_point = main.getFirstChild();
71 }
72
73 // imports
74 NodeList children = extra_xsl.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "import");
75 for (int i = 0; i < children.getLength(); i++)
76 {
77 Element node = (Element) children.item(i);
78 // If the new xsl:import element is identical (in terms of href attr value)
79 // to any in the merged document, don't copy it over
80 if (GSXML.getNamedElementNS(main, GSXML.XSL_NAMESPACE, "import", "href", node.getAttribute("href")) == null)
81 {
82 // Import statements should be the first children of an xsl:stylesheet element
83 // If firstchild is null, then this xsl:import element will be inserted at the "end"
84 // Although Node.insertBefore() will first remove identical nodes before inserting, we check
85 // only the href attribute to see if they're "identical" to any pre-existing <xsl:import>
86 //main.insertBefore(main_xsl.importNode(node, true), main.getFirstChild());
87 main.insertBefore(main_xsl.importNode(node, true), insertion_point);
88 }
89 }
90
91 // do we have a new insertion point??
92 Element last_include = GSXML.getLastElementByTagNameNS(main, GSXML.XSL_NAMESPACE, "include");
93 if (last_include != null)
94 {
95 insertion_point = last_include.getNextSibling();
96 }
97
98 // includes
99 children = extra_xsl.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "include");
100 for (int i = 0; i < children.getLength(); i++)
101 {
102 Element node = (Element) children.item(i);
103 // If the new xsl:include element is identical (in terms of href attr value)
104 // to any in the merged document, don't copy it over
105 // Although Node.appendChild() will first remove identical nodes before appending, we check
106 // only the href attribute to see if they're "identical" to any pre-existing <xsl:include>
107 if (GSXML.getNamedElementNS(main, GSXML.XSL_NAMESPACE, "include", "href", node.getAttribute("href")) == null)
108 {
109 //main.appendChild(main_xsl.importNode(node, true));
110 main.insertBefore(main_xsl.importNode(node, true), insertion_point);
111 }
112 } // for each include
113
114 if (main.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "output").getLength() == 0)
115 {
116 // outputs
117 children = extra_xsl.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "output");
118 for (int i = 0; i < children.getLength(); i++)
119 {
120 Element node = (Element) children.item(i);
121 // If the new xsl:output element is identical (in terms of the value for the method attr)
122 // to any in the merged document, don't copy it over
123
124 main.insertBefore(main_xsl.importNode(node, true), insertion_point);
125 }
126 }
127
128 // variables - only top level ones!!
129 // append to end of document
130 children = GSXML.getChildrenByTagNameNS(extra_xsl, GSXML.XSL_NAMESPACE, "variable");
131 for (int i = 0; i < children.getLength(); i++)
132 {
133 Element node = (Element) children.item(i);
134 // If the new xsl:import element is identical (in terms of href attr value)
135 // to any in the merged document, don't copy it over
136 if (GSXML.getNamedElementNS(main, GSXML.XSL_NAMESPACE, "variable", "name", node.getAttribute("name")) == null)
137 {
138 main.appendChild(main_xsl.importNode(node, true));
139 }
140 }
141
142 // params - only top level ones!!
143 // append to end of document
144 children = GSXML.getChildrenByTagNameNS(extra_xsl, GSXML.XSL_NAMESPACE, "param");
145 for (int i = 0; i < children.getLength(); i++)
146 {
147 Element node = (Element) children.item(i);
148 // If the new xsl:import element is identical (in terms of href attr value)
149 // to any in the merged document, don't copy it over
150 if (GSXML.getNamedElementNS(main, GSXML.XSL_NAMESPACE, "param", "name", node.getAttribute("name")) == null)
151 {
152 main.appendChild(main_xsl.importNode(node, true));
153 }
154 }
155
156 // key -- xsl:key elements need to be defined at the top level
157 children = GSXML.getChildrenByTagNameNS(extra_xsl, GSXML.XSL_NAMESPACE, "key");
158 for (int i = 0; i < children.getLength(); i++)
159 {
160 Element node = (Element) children.item(i);
161 // If the new xsl:key element is identical (in terms of name attr value)
162 // to any in the merged document, don't copy it over
163 if (GSXML.getNamedElementNS(main, GSXML.XSL_NAMESPACE, "key", "name", node.getAttribute("name")) == null)
164 {
165 main.appendChild(main_xsl.importNode(node, true));
166 }
167 }
168
169 // templates
170 // append to end of document
171 children = extra_xsl.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "template");
172 for (int i = 0; i < children.getLength(); i++)
173 {
174 Element node = (Element) children.item(i);
175 // remove any previous occurrences of xsl:template with the same value for name or match
176 String template_match = node.getAttribute("match");
177 String template_name = node.getAttribute("name");
178 String template_mode = node.getAttribute("mode");
179
180 if (overwrite)
181 {
182 // if we have a name attribute, remove any other similarly named template
183 GSXML.removeElementsWithAttributesNS(main, GSXML.XSL_NAMESPACE, "template", new String[] { "name", "match", "mode" }, new String[] { template_name, template_match, template_mode });
184
185 // now add our good template in
186 main.appendChild(main_xsl.importNode(node, true));
187 }
188 else
189 {
190 // if overwrite is false, then we only add in templates if they don't match something else.
191 // In this case (eg from expanding imported stylesheets)
192 // there can't be any duplicate named templates, so just look for matches
193 // we already have the one with highest import precedence (from the top most level) so don't add any more in
194 if (GSXML.getElementsWithAttributesNS(main, GSXML.XSL_NAMESPACE, "template", new String[] { "name", "match", "mode" }, new String[] { template_name, template_match, template_mode }).getLength() == 0)
195 {
196 main.appendChild(main_xsl.importNode(node, true));
197 }
198 }
199 }
200
201 if (debug)
202 {
203 insertDebugElements(main_xsl, secondDocFileName);
204 }
205 }
206
207 public static void insertDebugElements(Document doc, String filename)
208 {
209 NodeList xslTemplates = doc.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "template");
210 NodeList gsfTemplates = doc.getElementsByTagNameNS(GSXML.GSF_NAMESPACE, "template");
211
212 for (int i = 0; i < xslTemplates.getLength() + gsfTemplates.getLength(); i++)
213 {
214 boolean gsf = (i >= xslTemplates.getLength());
215 Element currentTemplate = (Element) (!gsf ? xslTemplates.item(i) : gsfTemplates.item(i - xslTemplates.getLength()));
216
217 NodeList childNodes = currentTemplate.getChildNodes();
218 boolean debugInformationAlreadyExists = false;
219 for (int j = 0; j < childNodes.getLength(); j++)
220 {
221 Node current = childNodes.item(j);
222 if (current instanceof Element && ((Element) current).getNodeName().equals("debug") && (!((Element) current).getAttribute("nodename").startsWith("gsf:") || ((Element) current).getAttribute("nodename").equals("gsf:template")))
223 {
224 debugInformationAlreadyExists = true;
225 break;
226 }
227 }
228
229 if (debugInformationAlreadyExists)
230 {
231 continue;
232 }
233
234 Element debugElement = doc.createElement("debug");
235 debugElement.setAttribute("filename", filename);
236 debugElement.setAttribute("nodename", gsf ? "gsf:template" : "xsl:template");
237
238 if (currentTemplate.getAttribute("match").length() > 0)
239 {
240 debugElement.setAttribute("match", currentTemplate.getAttribute("match"));
241 }
242 if (currentTemplate.getAttribute("name").length() > 0)
243 {
244 debugElement.setAttribute("name", currentTemplate.getAttribute("name"));
245 }
246
247 if (childNodes.getLength() > 0)
248 {
249 int paramCount = 0;
250 while (childNodes.getLength() > paramCount)
251 {
252 Node currentNode = childNodes.item(paramCount);
253 if (currentNode instanceof Element)
254 {
255 if (((Element) currentNode).getNodeName().equals("xsl:param") || ((Element) currentNode).getNodeName().equals("xslt:param") || (((Element) currentNode).getNodeName().equals("param") && ((Element) currentNode).getNamespaceURI().equals(GSXML.XSL_NAMESPACE)))
256 {
257 paramCount++;
258 }
259 else
260 {
261 debugElement.appendChild(currentNode);
262 }
263 }
264 else
265 {
266 debugElement.appendChild(currentNode);
267 }
268 }
269 currentTemplate.appendChild(debugElement);
270 }
271 else
272 {
273 currentTemplate.appendChild(debugElement);
274 }
275
276 Element textElement = doc.createElementNS(GSXML.XSL_NAMESPACE, "text");
277 textElement.appendChild(doc.createTextNode(" "));
278 debugElement.appendChild(textElement);
279 }
280 }
281
282 public static void inlineImportAndIncludeFiles(Document doc, String pathExtra, String site, String collection, String interface_name, ArrayList<String> base_interfaces)
283 {
284 inlineImportAndIncludeFilesDebug(doc, pathExtra, false, null, site, collection, interface_name, base_interfaces);
285 }
286
287 public static void inlineImportAndIncludeFilesDebug(Document doc, String pathExtra, boolean debug, String docFileName, String site, String collection, String interface_name, ArrayList<String> base_interfaces)
288 {
289 String path = (pathExtra == null) ? "" : pathExtra;
290
291 NodeList importList = doc.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "import");
292 NodeList includeList = doc.getElementsByTagNameNS(GSXML.XSL_NAMESPACE, "include");
293
294 for (int i = 0; i < importList.getLength() + includeList.getLength(); i++)
295 {
296 Element current = (Element) ((i < importList.getLength()) ? importList.item(i) : includeList.item(i - importList.getLength()));
297 String href = current.getAttribute("href");
298
299 try
300 {
301 //Document inlineDoc = converter.getDOM(new File(filePath), "UTF-8");
302 Document inlineDoc = mergedXSLTDocumentCascade(path + href, site, collection, interface_name, base_interfaces, debug);
303 String newPath = path;
304 int lastSepIndex = href.lastIndexOf("/");
305 if (lastSepIndex != -1)
306 {
307 newPath += href.substring(0, lastSepIndex + 1);
308 }
309
310 //Do this recursively
311 inlineImportAndIncludeFilesDebug(inlineDoc, newPath, debug, "merged " + href/* filePath */, site, collection, interface_name, base_interfaces);
312 GSXSLT.mergeStylesheetsDebug(doc, inlineDoc.getDocumentElement(), false, debug, docFileName, /* filePath */"merged " + href);
313 }
314 catch (Exception ex)
315 {
316 ex.printStackTrace();
317 return;
318 }
319 }
320
321 while (importList.getLength() > 0)
322 {
323 Element importElem = (Element) importList.item(0);
324 importElem.getParentNode().removeChild(importElem);
325 }
326 while (includeList.getLength() > 0)
327 {
328 Element includeElem = (Element) includeList.item(0);
329 includeElem.getParentNode().removeChild(includeElem);
330 }
331 }
332
333 public static Document mergedXSLTDocumentCascade(String xslt_filename, String site, String collection, String this_interface, ArrayList<String> base_interfaces, boolean debug)
334 {
335 XMLConverter converter = new XMLConverter();
336 // find the list of stylesheets with this name
337 ArrayList<File> stylesheets = GSFile.getStylesheetFiles(GlobalProperties.getGSDL3Home(), site, collection, this_interface, base_interfaces, xslt_filename);
338 if (stylesheets.size() == 0)
339 {
340 logger.error(" Can't find stylesheet for " + xslt_filename);
341 return null;
342 }
343 logger.debug("Stylesheet: " + xslt_filename);
344
345 Document finalDoc = converter.getDOM(stylesheets.get(stylesheets.size() - 1), "UTF-8");
346 if (finalDoc == null)
347 {
348 return null;
349 }
350
351 for (int i = stylesheets.size() - 2; i >= 0; i--)
352 {
353 Document currentDoc = converter.getDOM(stylesheets.get(i), "UTF-8");
354 if (currentDoc == null)
355 {
356 return null;
357 }
358
359 if (debug)
360 {
361 GSXSLT.mergeStylesheetsDebug(finalDoc, currentDoc.getDocumentElement(), true, true, stylesheets.get(stylesheets.size() - 1).getAbsolutePath(), stylesheets.get(i).getAbsolutePath());
362 }
363 else
364 {
365 GSXSLT.mergeStylesheets(finalDoc, currentDoc.getDocumentElement(), true);
366 }
367 }
368
369 if (stylesheets.size() == 1 && debug)
370 {
371 insertDebugElements(finalDoc, stylesheets.get(0).getAbsolutePath());
372 }
373
374 return finalDoc;
375 }
376
377 /**
378 * takes any import or include nodes, and creates absolute path names for
379 * the files
380 */
381 public static void absoluteIncludePaths(Document stylesheet, String gsdl3_home, String site_name, String collection, String interface_name, ArrayList<String> base_interfaces)
382 {
383 Element base_node = stylesheet.getDocumentElement();
384 if (base_node == null)
385 {
386 return;
387 }
388 Node child = base_node.getFirstChild();
389 while (child != null)
390 {
391 String name = child.getNodeName();
392 if (name.equals("xsl:import") || name.equals("xsl:include"))
393 {
394 ((Element) child).setAttribute("href", GSFile.stylesheetFile(gsdl3_home, site_name, collection, interface_name, base_interfaces, ((Element) child).getAttribute("href")));
395 }
396 child = child.getNextSibling();
397 }
398 }
399
400 /**
401 * looks through a stylesheet for <xxx:template match='template_name'>
402 * inside this template it looks for any <xxx:value-of
403 * select='metadataList/metadata[@name=yyy]> elements, and extracts the
404 * metadata names into a Vector
405 */
406 public static Vector<String> extractWantedMetadata(Document stylesheet, String template_name)
407 {
408
409 Vector<String> metadata = new Vector<String>();
410 Element base_node = stylesheet.getDocumentElement();
411 NodeList templates = base_node.getElementsByTagNameNS("*", "template");
412 for (int i = 0; i < templates.getLength(); i++)
413 {
414 Element template = (Element) templates.item(i);
415 String match_name = template.getAttribute("match");
416 if (!match_name.equals(template_name))
417 {
418 continue; // we're only looking for specific templates
419 }
420 String mode = template.getAttribute("mode");
421 if (!mode.equals(""))
422 {
423 continue; // we only want ones without modes - these are processing ones, not display ones
424 }
425 // we have one that we want to look through
426 NodeList values = template.getElementsByTagNameNS("*", "value-of");
427 for (int v = 0; v < values.getLength(); v++)
428 {
429 String select = ((Element) values.item(v)).getAttribute("select");
430 if (select.startsWith("metadataList/metadata[@name="))
431 {
432 String[] bits = select.split("'|\"");
433 // there should be two quotes in teh string, therefore 3 items, and the second one is teh one we want
434 String name = bits[1];
435 metadata.add(name);
436 }
437 }
438 }
439 return metadata;
440 }
441
442 public static void mergeFormatElements(Element mainFormat, Element secondaryFormat, boolean overwrite)
443 {
444 NodeList xslChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.XSL_NAMESPACE, "variable");
445 NodeList gsfChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.GSF_NAMESPACE, "variable");
446 for (int i = 0; i < xslChildren.getLength() + gsfChildren.getLength(); i++)
447 {
448 Element node = (Element) ((i < xslChildren.getLength()) ? xslChildren.item(i) : gsfChildren.item(i - xslChildren.getLength()));
449 if (GSXML.getNamedElementNS(mainFormat, "http://www.w3.org/1999/XSL/Transform", "variable", "name", node.getAttribute("name")) == null && GSXML.getNamedElementNS(mainFormat, "http://www.greenstone.org/greenstone3/schema/ConfigFormat", "variable", "name", node.getAttribute("name")) == null)
450 {
451 mainFormat.appendChild(node);
452 }
453 }
454
455 xslChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.XSL_NAMESPACE, "param");
456 gsfChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.GSF_NAMESPACE, "param");
457 for (int i = 0; i < xslChildren.getLength() + gsfChildren.getLength(); i++)
458 {
459 Element node = (Element) ((i < xslChildren.getLength()) ? xslChildren.item(i) : gsfChildren.item(i - xslChildren.getLength()));
460 if (GSXML.getNamedElementNS(mainFormat, "http://www.w3.org/1999/XSL/Transform", "param", "name", node.getAttribute("name")) == null && GSXML.getNamedElementNS(mainFormat, "http://www.greenstone.org/greenstone3/schema/ConfigFormat", "param", "name", node.getAttribute("name")) == null)
461 {
462 mainFormat.appendChild(node);
463 }
464 }
465
466 xslChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.XSL_NAMESPACE, "template");
467 gsfChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.GSF_NAMESPACE, "template");
468 for (int i = 0; i < xslChildren.getLength() + gsfChildren.getLength(); i++)
469 {
470 Element node = (Element) ((i < xslChildren.getLength()) ? xslChildren.item(i) : gsfChildren.item(i - xslChildren.getLength()));
471 // remove any previous occurrences of xsl:template with the same value for name or match
472 String template_match = node.getAttribute("match");
473 String template_name = node.getAttribute("name");
474 String template_mode = node.getAttribute("mode");
475
476 String[] attributeNames = new String[] { "name", "match", "mode" };
477 String[] attributeValues = new String[] { template_name, template_match, template_mode };
478
479 if (overwrite)
480 {
481 // if we have a name attribute, remove any other similarly named template
482 GSXML.removeElementsWithAttributesNS(mainFormat, GSXML.XSL_NAMESPACE, "template", attributeNames, attributeValues);
483 GSXML.removeElementsWithAttributesNS(mainFormat, GSXML.GSF_NAMESPACE, "template", attributeNames, attributeValues);
484
485 // now add our good template in
486 mainFormat.appendChild(node);
487 }
488 else
489 {
490 // if overwrite is false, then we only add in templates if they don't match something else.
491 // In this case (eg from expanding imported stylesheets)
492 // there can't be any duplicate named templates, so just look for matches
493 // we already have the one with highest import precedence (from the top most level) so don't add any more in
494 if (GSXML.getElementsWithAttributesNS(mainFormat, "http://www.w3.org/1999/XSL/Transform", "template", attributeNames, attributeValues).getLength() == 0 && GSXML.getElementsWithAttributesNS(mainFormat, "http://www.greenstone.org/greenstone3/schema/ConfigFormat", "template", attributeNames, attributeValues).getLength() == 0)
495 {
496 mainFormat.appendChild(node);
497 }
498 }
499 }
500
501 gsfChildren = GSXML.getChildrenByTagNameNS(secondaryFormat, GSXML.GSF_NAMESPACE, "option");
502 for (int i = 0; i < gsfChildren.getLength(); i++)
503 {
504 Element node = (Element) gsfChildren.item(i);
505 if (GSXML.getNamedElementNS(mainFormat, GSXML.GSF_NAMESPACE, "option", "name", node.getAttribute("name")) == null)
506 {
507 mainFormat.appendChild(node);
508 }
509 }
510 }
511
512 public static void fixTables(Document doc)
513 {
514 NodeList debugElements = doc.getElementsByTagName("debug");
515
516 HashMap<Element, ArrayList<Element>> tracker = new HashMap<Element, ArrayList<Element>>();
517 for (int i = 0; i < debugElements.getLength(); i++)
518 {
519 Element currentElement = (Element) debugElements.item(i);
520
521 boolean hasChildElements = false;
522 NodeList children = currentElement.getChildNodes();
523 for (int j = 0; j < children.getLength(); j++)
524 {
525 Node current = children.item(j);
526 if (current instanceof Element)
527 {
528 hasChildElements = true;
529 }
530 }
531
532 if (hasChildElements && currentElement.getParentNode() != null && currentElement.getParentNode() instanceof Element)
533 {
534 Element parent = findNonDebugParent(currentElement);
535 if (parent == null)
536 {
537 continue;
538 }
539
540 if (parent.getNodeName().toLowerCase().equals("table") || parent.getNodeName().toLowerCase().equals("tr"))
541 {
542 if (tracker.get(parent) == null)
543 {
544 ArrayList<Element> debugElems = new ArrayList<Element>();
545 debugElems.add(currentElement);
546 tracker.put(parent, debugElems);
547 }
548 else
549 {
550 ArrayList<Element> debugElems = tracker.get(parent);
551 debugElems.add(currentElement);
552 }
553 }
554 }
555 }
556
557 for (Element tableElem : tracker.keySet())
558 {
559 ArrayList<Element> debugElems = tracker.get(tableElem);
560 ArrayList<String> attrNames = new ArrayList<String>();
561
562 for (Element debugElem : debugElems)
563 {
564 NamedNodeMap attributes = debugElem.getAttributes();
565 for (int i = 0; i < attributes.getLength(); i++)
566 {
567 attrNames.add(attributes.item(i).getNodeName());
568 }
569 }
570
571 for (String name : attrNames)
572 {
573 String attrValueString = "[";
574 for (int i = debugElems.size() - 1; i >= 0; i--)
575 {
576 Element current = debugElems.get(i);
577 attrValueString += "\'" + current.getAttribute(name).replace("\\", "\\\\").replace("'", "\\'") + "\'";
578 if (i != 0)
579 {
580 attrValueString += ",";
581 }
582 }
583 attrValueString += "]";
584
585 tableElem.setAttribute(name, attrValueString);
586 }
587 tableElem.setAttribute("debug", "true");
588 tableElem.setAttribute("debugSize", "" + debugElems.size());
589 }
590 }
591
592 private static Element findNonDebugParent(Element elem)
593 {
594 Node parent = elem.getParentNode();
595 while (parent instanceof Element && parent.getNodeName().equals("debug"))
596 {
597 parent = parent.getParentNode();
598 }
599
600 if (parent instanceof Element)
601 {
602 return (Element) parent;
603 }
604 return null;
605 }
606}
Note: See TracBrowser for help on using the repository browser.