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

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

Need to store xpath data from the collectionConfig for debug purposes

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