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

Last change on this file since 25635 was 25635, checked in by sjm84, 12 years ago

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 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 org.w3c.dom.Node;
22import org.w3c.dom.Element;
23import org.w3c.dom.NodeList;
24import org.w3c.dom.Document;
25
26import java.util.Vector;
27import java.util.ArrayList;
28
29/** various functions for manipulating Greenstone xslt */
30public class GSXSLT
31{
32 /**
33 * takes a stylesheet Document, and adds in any child nodes from extra_xsl
34 * named templates overwrite any existing one, while match templates are
35 * just added to the end of teh stylesheet
36 */
37 public static void mergeStylesheets(Document main_xsl, Element extra_xsl)
38 {
39 Element main = main_xsl.getDocumentElement();
40
41 NodeList children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "import");
42 for (int i = 0; i < children.getLength(); i++) {
43 Node node = children.item(i);
44 // If the new xsl:import element is identical (in terms of href attr value)
45 // to any in the merged document, don't copy it over
46 if(!isDuplicateElement(main, node, "xsl:import", "href")) {
47 // Import statements should be the first children of an xsl:stylesheet element
48 // If firstchild is null, then this xsl:import element will be inserted at the "end"
49 // Although Node.insertBefore() will first remove identical nodes before inserting, we check
50 // only the href attribute to see if they're "identical" to any pre-existing <xsl:import>
51 main.insertBefore(main_xsl.importNode(node, true), main.getFirstChild());
52 }
53 }
54
55 children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "include");
56 for (int i = 0; i < children.getLength(); i++) {
57 Node node = children.item(i);
58 // If the new xsl:include element is identical (in terms of href attr value)
59 // to any in the merged document, don't copy it over
60 // Although Node.appendChild() will first remove identical nodes before appending, we check
61 // only the href attribute to see if they're "identical" to any pre-existing <xsl:include>
62 if(!isDuplicateElement(main, node, "xsl:include", "href")) {
63 main.appendChild(main_xsl.importNode(node, true));
64 }
65 }
66
67 children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "output");
68 for (int i = 0; i < children.getLength(); i++) {
69 Node node = children.item(i);
70 // If the new xsl:output element is identical (in terms of the value for the method attr)
71 // to any in the merged document, don't copy it over
72 if(!isDuplicateElement(main, node, "xsl:output", "method")) {
73 main.appendChild(main_xsl.importNode(node, true));
74 }
75 }
76
77 children = extra_xsl.getElementsByTagNameNS("http://www.w3.org/1999/XSL/Transform", "template");
78 for (int i = 0; i < children.getLength(); i++)
79 {
80 Node node = children.item(i);
81 // remove any previous occurrences of xsl:template with the same value for name
82 // or even the same value for match (should we use priorities for match?)
83 removeDuplicateElementsFrom(main, node, "xsl:template", "name");
84 removeDuplicateElementsFrom(main, node, "xsl:template", "match");
85 main.appendChild(main_xsl.importNode(node, true));
86 }
87 }
88
89 // In element main, tries to find any previous occurrence of elements with xsl-template-name=templateName,
90 // and whose named attribute (attributeName) has the same value as the same attribute in node.
91 // If this is the case, such a previous occurrence is removed from element main, since
92 // the new node will contain a more specific redefinition of this element.
93 public static void removeDuplicateElementsFrom(Element main, Node node, String templateName, String attrName) {
94 String attr = ((Element) node).getAttribute(attrName);
95 if (!attr.equals(""))
96 {
97 Element old_template = GSXML.getNamedElement(main, templateName, attrName, attr);
98 if (old_template != null)
99 {
100 main.removeChild(old_template);
101 }
102 }
103 }
104
105 // Call this method on elements like xsl:include, xsl:import and xsl:output
106 // In element main, tries to find any previous occurrence of elements with xsl-element-name=xslName,
107 // and whose named attribute (attributeName) has the same value as the same attribute in node.
108 // If this is the case, it returns true, since the element would a complete duplicate for our intents.
109 public static boolean isDuplicateElement(Element main, Node node, String xslName, String attrName) {
110 String attr = ((Element) node).getAttribute(attrName);
111 if (!attr.equals(""))
112 {
113 Element old_element = GSXML.getNamedElement(main, xslName, attrName, attr);
114 if (old_element != null)
115 {
116 return true;
117 }
118 }
119 return false;
120 }
121
122 /**
123 * takes any import or include nodes, and creates absolute path names for
124 * the files
125 */
126 public static void absoluteIncludePaths(Document stylesheet, String gsdl3_home, String site_name, String collection, String interface_name, ArrayList<String> base_interfaces)
127 {
128
129 Element base_node = stylesheet.getDocumentElement();
130 if (base_node == null)
131 {
132 return;
133 }
134 Node child = base_node.getFirstChild();
135 while (child != null)
136 {
137 String name = child.getNodeName();
138 if (name.equals("xsl:import") || name.equals("xsl:include"))
139 {
140 ((Element) child).setAttribute("href", GSFile.stylesheetFile(gsdl3_home, site_name, collection, interface_name, base_interfaces, ((Element) child).getAttribute("href")));
141 }
142 child = child.getNextSibling();
143 }
144
145 }
146
147 /**
148 * looks through a stylesheet for <xxx:template match='template_name'>
149 * inside this template it looks for any <xxx:value-of
150 * select='metadataList/metadata[@name=yyy]> elements, and extracts the
151 * metadata names into a Vector
152 */
153 public static Vector<String> extractWantedMetadata(Document stylesheet, String template_name)
154 {
155
156 Vector<String> metadata = new Vector<String>();
157 Element base_node = stylesheet.getDocumentElement();
158 NodeList templates = base_node.getElementsByTagNameNS("*", "template");
159 for (int i = 0; i < templates.getLength(); i++)
160 {
161 Element template = (Element) templates.item(i);
162 String match_name = template.getAttribute("match");
163 if (!match_name.equals(template_name))
164 {
165 continue; // we're only looking for specific templates
166 }
167 String mode = template.getAttribute("mode");
168 if (!mode.equals(""))
169 {
170 continue; // we only want ones without modes - these are processing ones, not display ones
171 }
172 // we have one that we want to look through
173 NodeList values = template.getElementsByTagNameNS("*", "value-of");
174 for (int v = 0; v < values.getLength(); v++)
175 {
176 String select = ((Element) values.item(v)).getAttribute("select");
177 if (select.startsWith("metadataList/metadata[@name="))
178 {
179 String[] bits = select.split("'|\"");
180 // there should be two quotes in teh string, therefore 3 items, and the second one is teh one we want
181 String name = bits[1];
182 metadata.add(name);
183 }
184 }
185 }
186 return metadata;
187 }
188
189}
Note: See TracBrowser for help on using the repository browser.