/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.xsl; import com.caucho.VersionFactory; import com.caucho.java.JavaCompiler; import com.caucho.java.JavaWriter; import com.caucho.loader.DynamicClassLoader; import com.caucho.server.util.CauchoSystem; import com.caucho.util.CharBuffer; import com.caucho.util.IntArray; import com.caucho.util.IntMap; import com.caucho.vfs.Depend; import com.caucho.vfs.Path; import com.caucho.vfs.WriteStream; import com.caucho.xml.QAbstractNode; import com.caucho.xml.QAttr; import com.caucho.xml.QElement; import com.caucho.xml.QName; import com.caucho.xml.XmlChar; import com.caucho.xpath.Expr; import com.caucho.xpath.NamespaceContext; import com.caucho.xpath.expr.NumericExpr; import com.caucho.xpath.pattern.*; import com.caucho.xsl.fun.KeyFun; import com.caucho.xsl.java.*; import org.w3c.dom.*; import java.io.IOException; import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.logging.Logger; /** * Generates code for a Java based stylesheet. * * <pre> * package work.xsl; * public class foo extends JavaStylesheet { * } * </pre> */ public class JavaGenerator extends Generator { private static final Logger log = Logger.getLogger(JavaGenerator.class.getName()); private static HashMap<QName,Class> _tagMap; private static HashMap<QName,Class> _topTagMap; private static int _count; Path _path; WriteStream _s; JavaWriter _out; ArrayList<AbstractPattern> _matchPatterns = new ArrayList<AbstractPattern>(); IntMap _matchMap = new IntMap(); ArrayList<AbstractPattern> _selectPatterns = new ArrayList<AbstractPattern>(); IntMap _selectMap = new IntMap(); ArrayList<Expr> _exprs = new ArrayList<Expr>(); IntMap _exprMap = new IntMap(); ArrayList<Sort[]> _sorts = new ArrayList<Sort[]>(); ArrayList<NamespaceContext> _namespaces = new ArrayList<NamespaceContext>(); ArrayList<XslNumberFormat> _formats = new ArrayList<XslNumberFormat>(); ArrayList<String> _functions = new ArrayList<String>(); ArrayList<Template> _templateList = new ArrayList<Template>(); ArrayList<String> _stylesheets = new ArrayList<String>(); int _templateCount = 0; // integer counting unique identifier int _unique; HashMap<String,String> _macros = new HashMap<String,String>(); ArrayList<Object> _fragments = new ArrayList<Object>(); ArrayList<String> _strings = new ArrayList<String>(); IntMap _stringMap = new IntMap(); IntArray _envDepth = new IntArray(); ArrayList<String> _modes = new ArrayList<String>(); private XslNode _xslNode; private boolean _isLineBegin; private int _depth; private int _callDepth; // integer counting the depth of nested selects private int _selectDepth; private int _selectLoopDepth; private int _flagCount; private String _className; private String _pkg; private String _currentPos; private ClassLoader _parentLoader; private JavaCompiler _compiler; private boolean _disableEscaping; private boolean _printLocation = true; private String _oldFilename = null; private int _oldLine = -1; private boolean _hasHeader; /** * Creates a new XSL generator for Java. * * @param xslGenerator the owning factory. * @param className the name of the generated class * @param encoding the generated output encoding. */ JavaGenerator(AbstractStylesheetFactory xslGenerator, String className, String encoding) throws IOException { super(xslGenerator); _parentLoader = xslGenerator.getClassLoader(); ArrayList pathDepends = new ArrayList(); _compiler = JavaCompiler.create(_parentLoader); _compiler.setClassDir(_workPath); if (encoding == null) { } else if (encoding.equalsIgnoreCase("UTF-16")) { // utf-16 isn't supported by some javac encoding = "UTF-8"; _compiler.setEncoding(encoding); } else { _compiler.setEncoding(encoding); } int p = className.lastIndexOf('.'); if (p >= 0) { _pkg = className.substring(0, p); className = className.substring(p + 1); } else { _pkg = "_xsl"; className = className; } _className = className; init((_pkg + "." + className).replace('.', '/') + ".java"); String fileName = (_pkg + "." + className).replace('.', '/') + ".java"; _path = _workPath.lookup(fileName); _path.getParent().mkdirs(); _s = _path.openWrite(); if (encoding != null) _s.setEncoding(encoding); if (_s.getEncoding() == null || _s.getEncoding().equals("ISO-8859-1")) _s.setEncoding("JAVA"); _out = new JavaWriter(_s); _out.setLineMap(_lineMap); _matchPatterns = new ArrayList<AbstractPattern>(); _selectPatterns = new ArrayList<AbstractPattern>(); _modes = new ArrayList<String>(); _modes.add(""); } protected JavaWriter getOut() { return _out; } public int getSelectDepth() { return _selectDepth; } public void setSelectDepth(int depth) { _selectDepth = depth; } public int pushSelectDepth() { return ++_selectDepth; } public int popSelectDepth() { return _selectDepth--; } public int getSelectLoopDepth() { return _selectLoopDepth; } public int pushSelectLoopDepth() { return ++_selectLoopDepth; } public int popSelectLoopDepth() { return _selectLoopDepth--; } public void setSelectLoopDepth(int depth) { _selectLoopDepth = depth; } public int generateId() { return _unique++; } public void clearUnique() { _unique = 0; } /** * Prints the generated header. */ protected void printHeader() throws IOException { if (_hasHeader) return; _hasHeader = true; println("/*"); println(" * Generated by " + VersionFactory.getFullVersion()); println(" */"); println(); println("package " + _pkg + ";"); println(); println("import java.io.*;"); println("import java.util.*;"); println("import org.w3c.dom.*;"); println("import org.xml.sax.*;"); println("import com.caucho.util.*;"); println("import com.caucho.xml.*;"); println("import com.caucho.xpath.*;"); println("import com.caucho.xpath.expr.*;"); println("import com.caucho.xpath.pattern.*;"); println("import com.caucho.xsl.*;"); try { Class.forName("javax.servlet.Servlet"); println("import javax.servlet.*;"); println("import javax.servlet.jsp.*;"); println("import javax.servlet.http.*;"); } catch (Throwable e) { } for (int i = 0; i < _imports.size(); i++) println("import " + _imports.get(i) + ";"); println(); println("public class " + _className + " extends JavaStylesheet {"); pushDepth(); println("private StylesheetEnv stylesheets[];"); } protected void generateChild(Node child) throws Exception { XslNode node = createChild(child); if (node != null) node.generate(_out); } protected XslNode createChild(XslNode parent, Node childNode) throws Exception { XslNode xslNode = _xslNode; _xslNode = parent; XslNode child = createChild(childNode); _xslNode = xslNode; return child; } protected XslNode createChild(Node child) throws Exception { XslNode xslNode = null; if (child instanceof QElement) { QElement elt = (QElement) child; Class cl = _tagMap.get(elt.getQName()); if (cl != null) { xslNode = (XslNode) cl.newInstance(); xslNode.setGenerator(this); xslNode.setParent(_xslNode); xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(), ((QAbstractNode) child).getFilename(), ((QAbstractNode) child).getLine()); QAttr attr = (QAttr) elt.getFirstAttribute(); for (; attr != null; attr = (QAttr) attr.getNextSibling()) { xslNode.addAttribute(attr.getQName(), attr.getNodeValue()); } xslNode.endAttributes(); XslNode oldNode = _xslNode; _xslNode = xslNode; Node node = elt.getFirstChild(); for (; node != null; node = node.getNextSibling()) { XslNode xslChild = createChild(node); if (xslChild != null) xslNode.addChild(xslChild); } xslNode.endElement(); _xslNode = oldNode; } /* else if (elt.getNodeName().equals("jsp:decl") || elt.getNodeName().equals("jsp:declaration") || elt.getNodeName().startsWith("jsp:directive")) { } */ else if (child.getNodeName().startsWith("xsl:") && ! XSLNS.equals(child.getNamespaceURI())) { throw error(child, L.l("<{0}> has an xsl: prefix, but is not in the {1} namespace. XSL requires an xmlns:xsl=\"{1}\" namespace attribute.", child.getNodeName(), XSLNS)); } else if (! XSLNS.equals(child.getNamespaceURI()) && ! XTPNS.equals(child.getNamespaceURI())) { xslNode = new XslElementNode(elt.getQName()); xslNode.setGenerator(this); xslNode.setParent(_xslNode); xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(), ((QAbstractNode) child).getFilename(), ((QAbstractNode) child).getLine()); QAttr attr = (QAttr) elt.getFirstAttribute(); for (; attr != null; attr = (QAttr) attr.getNextSibling()) xslNode.addAttribute(attr.getQName(), attr.getNodeValue()); xslNode.endAttributes(); XslNode oldNode = _xslNode; _xslNode = xslNode; Node node = elt.getFirstChild(); for (; node != null; node = node.getNextSibling()) { XslNode xslChild = createChild(node); xslNode.addChild(xslChild); } xslNode.endElement(); _xslNode = oldNode; } else { throw error(child, L.l("<{0}> is an unknown XSL tag.", child.getNodeName())); /* XslWrapperNode wrapNode = new XslWrapperNode(); wrapNode.setNode(child); xslNode = wrapNode; xslNode.setGenerator(this); */ } } else if (child instanceof Text) { xslNode = new TextNode(((Text) child).getData()); xslNode.setGenerator(this); xslNode.setParent(_xslNode); } else if (child instanceof Comment) { } else if (child instanceof ProcessingInstruction) { } else throw new UnsupportedOperationException(String.valueOf(child)); if (xslNode != null) { xslNode.setStartLocation(((QAbstractNode) child).getBaseURI(), ((QAbstractNode) child).getFilename(), ((QAbstractNode) child).getLine()); } return xslNode; } /** * Generates code for a template * * @param absNode the XSL node for the emplace * @param name the template name * @param pattern the pattern string * @param mode the template's mode * @param priority the template's priority */ protected void printTemplate(Element absNode, String name, String pattern, String mode, double priority) throws Exception { throw new RuntimeException(); /* QElement node = (QElement) absNode; if (name != null && ! name.equals("")) addMacro(name, node); if (! pattern.equals("")) { String fun = createTemplatePattern(name, pattern, mode, priority); print("// '" + pattern.replace('\n', ' ') + "'"); if (mode != null && mode != "") { if (! _modes.contains(mode)) _modes.add(mode); println(" mode '" + mode + "'"); } else println(); printString("// " + node.getFilename() + ":" + node.getLine()); println(); println("private void " + fun + "(XslWriter out, Node inputNode, Env env)"); println(" throws Exception"); println("{"); pushDepth(); println("Object _xsl_tmp;"); println("Node node = inputNode;"); println("int _xsl_top = env.getTop();"); if (_isRawText) println("boolean oldEscaping = out.disableEscaping(true);"); else println("boolean oldEscaping = out.disableEscaping(false);"); String filename = node.getBaseURI(); if (filename != null) { int pos = _stylesheets.indexOf(filename); if (pos < 0) { pos = _stylesheets.size(); _stylesheets.add(filename); } println("env.setStylesheetEnv(stylesheets[" + pos + "]);"); } _selectDepth = 0; _unique = 0; if (node.getLocalName().equals("template") || node.getLocalName().equals("xsl:template")) generateChildren(node); else generateChild((QAbstractNode) node); if (! _isCacheable) println("out.setNotCacheable();"); println("out.disableEscaping(oldEscaping);"); println("env.popToTop(_xsl_top);"); popDepth(); println("}"); println(); } */ } public void addMacro(String name, String functionName) { _macros.put(name, functionName); } /* public void addMacro(String name) { addMacro(name, "_xsl_macro_" + toJavaIdentifier(name); } */ public boolean hasMacro(String name) { return _macros.keySet().contains(name); } /** * Generates the pattern for a matching pattern * * @param name the mangled name of the function * @param match the XPath match pattern * @param mode the template mode * @param priority the template priority * @param node the source XML node from the XSL file * * @return the name of the function */ public String createTemplatePattern(String name, AbstractPattern match, String mode, double priority) throws Exception { String tagName; if (name != null) tagName = getName(name); else tagName = getName(match.toString()); String function = "_xsl_template_" + tagName; _functions.add(function); if (match != null) { Template template = addPattern(match, mode, priority, function, _functions.size()); _templateList.add(template); } else _templateList.add(null); return function; } protected void startDisableEscaping() throws IOException { if (! _isRawText) println("out.disableEscaping(true);"); } protected void endDisableEscaping() throws IOException { if (! _isRawText) println("out.disableEscaping(false);"); } /** * Creates Java code to print plain text. */ protected void writeText(String text) throws Exception { if (text == null || text.length() == 0) return; int index = _stringMap.get(text); if (index < 0) { index = _strings.size(); _stringMap.put(text, index); _strings.add(text); } printLocation(_systemId, _filename, _line); println("out.write(_xsl_string" + index + ", 0, " + text.length() + ");"); } protected void printElement(Node node) throws Exception { QElement elt = (QElement) node; String name = node.getNodeName(); if (name.equals("jsp:decl") || name.equals("jsp:declaration")) { println("if (out.isFlagFirst(" + _flagCount++ + ")) {"); pushDepth(); } String prefix = elt.getPrefix(); String local = elt.getLocalName(); String namespace = elt.getNamespaceURI(); String []postPrefix = (String []) _namespaceAliases.get(namespace); if (postPrefix != null) { prefix = postPrefix[0]; namespace = postPrefix[1]; if (prefix == null || prefix.equals("")) name = local; else name = prefix + ":" + local; } if (_excludedNamespaces.get(namespace) != null) namespace = null; printLocation(_systemId, _filename, _line); if (namespace == null || namespace.equals("")) { print("out.pushElement("); print(name == null ? "null" : ("\"" + name + "\"")); println(");"); } else { print("out.pushElement("); print(namespace == null ? "null" : ("\"" + namespace + "\"")); print(prefix == null ? ", null" : (", \"" + prefix + "\"")); print(local == null ? ", null" : (", \"" + local + "\"")); print(name == null ? ", null" : (", \"" + name + "\"")); println(");"); } printUseAttributeSet((QElement) node, false); NamedNodeMap list = node.getAttributes(); for (int i = 0; i < list.getLength(); i++) { QAbstractNode attr = (QAbstractNode) list.item(i); printAttribute(attr, elt); } generateChildren(node); println("out.popElement();"); if (node.getNodeName().equals("jsp:decl") || node.getNodeName().equals("jsp:declaration")) { popDepth(); println("}"); } } /** * Prints a command to set the current file and line into the * generated document. * * @param filename the source filename * @param line the source line number. */ public void printLocation(String systemId, String filename, int line) throws Exception { if (_printLocation && filename != null && ! _isSpecial) { print("out.setLocation("); if (systemId != null) { print("\""); printString(systemId); print("\""); } else print("null"); print(", \""); printString(filename); println("\", " + line + ");"); _oldFilename = filename; _oldLine = line; } } /** * Prints code for an element's attributes. */ private void printAttribute(QAbstractNode attr, QElement elt) throws Exception { if (attr.getNodeName().equals("xsl:use-attribute-sets")) { } else if (XSLNS.equals(elt.getNamespace(attr.getPrefix()))) { } else if (XTPNS.equals(elt.getNamespace(attr.getPrefix()))) { } else { QAbstractNode qnode = (QAbstractNode) attr; String prefix = qnode.getPrefix(); String local = qnode.getLocalName(); String namespace = qnode.getNamespaceURI(); String value = attr.getNodeValue(); String []postSuffix = (String []) _namespaceAliases.get(namespace); if (postSuffix != null) { prefix = postSuffix[0]; namespace = postSuffix[1]; } else if (value.equals(XSLNS) && prefix.equals("xmlns")) return; else if (value.equals(XTPNS) && prefix.equals("xmlns")) return; if (_excludedNamespaces.get(namespace) != null) namespace = null; if ("".equals(prefix) && ("".equals(namespace) || namespace == null)) { String var = generateStringVar(value, elt); println("out.setAttribute(\"" + local + "\", " + var + ");"); } else { print("out.pushAttribute("); print(prefix == null ? "null" : ("\"" + prefix + "\"")); print(local == null ? ", null" : (", \"" + local + "\"")); print(namespace == null ? ", null" : (", \"" + namespace + "\"")); println(");"); generateString(value, ',', elt); println("out.popAttribute();"); } } } protected void pushCall() throws IOException { println("{"); pushDepth(); _callDepth++; println("Env _xsl_arg" + _callDepth + " = XPath.createCall(env);"); } public int pushCallDepth() { return ++_callDepth; } public int popCallDepth() { return _callDepth--; } public int getCallDepth() { return _callDepth; } protected void popCall() throws IOException { //println("_xsl_arg" + callDepth + ".free();"); _callDepth--; popDepth(); println("}"); } /** * Prints code for xsl:apply-templates * * @param select the select pattern * @param mode the template mode * @param sort the sort expressions */ protected void printApplyTemplates(AbstractPattern select, String mode, Sort []sort) throws Exception { int min = 0; int max = Integer.MAX_VALUE; String applyName = "applyNode" + getModeName(mode); String env = "_xsl_arg" + _callDepth; if (select == null && sort == null) { println("for (Node _xsl_node = node.getFirstChild();"); println(" _xsl_node != null;"); println(" _xsl_node = _xsl_node.getNextSibling()) {"); println(" " + env + ".setSelect(node, null);"); println(" " + env + ".setCurrentNode(_xsl_node);"); println(" " + applyName + "(out, _xsl_node, " + env + ", " + min + ", " + max + ");"); println("}"); } else if (sort == null) { int oldSelectDepth = _selectDepth; println(env + ".setSelect(node, _select_patterns[" + addSelect(select) + "]);"); String name = printSelectBegin(select, false, null); println(env + ".setCurrentNode(" + name + ");"); println(applyName + "(out, " + name + ", " + env + ", " + min + ", " + max + ");"); for (; _selectDepth > oldSelectDepth; _selectDepth--) { popDepth(); println("}"); } } else { println("{"); pushDepth(); println("ArrayList _xsl_list = xslSort(node, env" + ", _select_patterns[" + addSelect(select) + "]" + ", _xsl_sorts[" + _sorts.size() + "]);"); println(env + ".setContextSize(_xsl_list.size());"); println("for (int _xsl_i = 0; _xsl_i < _xsl_list.size(); _xsl_i++) {"); println(" " + env + ".setContextPosition(_xsl_i + 1);"); println(" " + applyName + "(out, (Node) _xsl_list.get(_xsl_i)" + ", " + env + ", " + min + ", " + max + ");"); println("}"); popDepth(); println("}"); _sorts.add(sort); } } public int addSort(Sort []sort) { int index = _sorts.size(); _sorts.add(sort); return index; } /** * Prints code to implement xsl:apply-imports * * @param mode the mode of the imported files * @param min the min importance * @param max the max importance */ protected void printApplyImports(String mode, int min, int max) throws Exception { } protected void printCallTemplate(String name, String mode) throws Exception { println(getMacroName(name) + "(out, node, _xsl_arg" + _callDepth + ");"); } public String getMacroName(String name) { return _macros.get(name); //return "_xsl_macro_" + toJavaIdentifier(name); } /** * Prints the value for a parameter. */ protected void printParam(String name, String value, Element elt) throws Exception { print("_xsl_arg" + _callDepth + ".addVar(\"" + name + "\", "); generateString(value, '+', elt); println(");"); } protected void printParam(String name, Object value) throws Exception { if (value instanceof Expr) { print("_exprs[" + addExpr((Expr) value) + "]"); println(".addVar(_xsl_arg" + _callDepth + ", \"" + name + "\", " + "node, env);"); } else { print("_xsl_arg" + _callDepth + ".addVar(\""); print(name); print("\", "); printVariableValue(value); println(");"); } } /** * Prints code to add the value of an expression as a parameter. */ protected void printParamVariable(String name, Expr value) throws Exception { print("_exprs[" + addExpr(value) + "]"); println(".addParam(env, \"" + name + "\", " + "node, env);"); } protected void printParamVariable(String name, Element value) throws Exception { if (value.getFirstChild() != null) { println("_xsl_tmp = env.getVar(\"" + name + "\");"); println("if (_xsl_tmp == null)"); print(" _xsl_tmp = "); printVariableValue(value); println(";"); println("env.addVar(\"" + name + "\", _xsl_tmp);"); } } protected void printVariable(String name, Object value) throws Exception { if (value instanceof Expr) { print("_exprs[" + addExpr((Expr) value) + "]"); println(".addVar(env, \"" + name + "\", node, env);"); } else { print("env.addVar(\""); print(name); print("\", "); printVariableValue(value); println(");"); } } protected void printAssign(String name, Object value) throws Exception { if (value instanceof Expr) { print("_exprs[" + addExpr((Expr) value) + "]"); println(".setVar(\"" + name + "\", node, env, node);"); } else { print("env.setVar(\""); print(name); print("\", "); printVariableValue(value); println(");"); } } private void printVariableValue(Object value) throws Exception { if (value instanceof Expr) { print("_exprs[" + addExpr((Expr) value) + "].evalObject(node, env)"); } else if (value instanceof Node) { print("_xsl_fragment" + _fragments.size() + "(out, node, env)"); _fragments.add(value); } else throw new RuntimeException(); } protected void printPopScope(int count) throws Exception { if (count > 0) println("env.popVars(" + count + ");"); } protected void printCopyOf(String select, Element elt) throws Exception { println("out.copyOf(_exprs[ " + addExpr(select) + "].evalObject(node, env));"); } protected void printSelectValue(String select, Element elt) throws Exception { printStringExpr(select, elt); } protected void printForEach(Element element, String select) throws Exception { println("{"); pushDepth(); AbstractPattern selectPattern = null; try { selectPattern = parseSelect(select); } catch (Exception e) { } boolean hasExprEnv = ! allowJavaSelect(selectPattern); int id = _unique++; String sel = "_xsl_sel" + id; String oldCxt = "_xsl_cxt" + id; String oldCur = "_xsl_cur" + id; String oldSel = "_xsl_old_sel" + id; String oldEnv = "_xsl_env" + id; println("com.caucho.xpath.pattern.AbstractPattern " + sel + ";"); print(sel + " = _select_patterns["); print(createNodeSet(select, element)); println("];"); println("Node " + oldCxt + " = env.getContextNode();"); println("Node " + oldCur + " = env.getCurrentNode();"); if (! hasExprEnv) { println("AbstractPattern " + oldSel + " = env.setSelect(node, " + sel + ");"); } // String pos = "_xsl_pos" + unique++; String iter = "_xsl_iter" + _unique++; int oldSelectDepth = _selectDepth; // println("int " + pos + " = 0;"); boolean hasEnv = false; if (allowJavaSelect(selectPattern)) { println("ExprEnvironment " + oldEnv + " = env.setExprEnv(null);"); String ptr = printSelectBegin(selectPattern, true, null); pushLoop(); println("Node " + getElement() + " = node;"); println("node = " + ptr + ";"); } else { print("NodeIterator " + iter + " = " + sel); println(".select(node, " + getEnv() + ");"); println("ExprEnvironment " + oldEnv + " = env.setExprEnv(" + iter + ");"); println("while (" + iter + ".hasNext()) {"); pushDepth(); _selectDepth++; pushLoop(); println("Node " + getElement() + " = node;"); println("node = " + iter + ".nextNode();"); } println("env.setCurrentNode(node);"); // println(pos + "++;"); // String oldPos = currentPos; // currentPos = pos; AbstractPattern oldNodeListContext = _nodeListContext; _nodeListContext = parseMatch(select); generateChildren(element); _nodeListContext = oldNodeListContext; // currentPos = oldPos; println("node = " + getElement() + ";"); println("env.setCurrentNode(" + oldCur + ");"); for (; _selectDepth > oldSelectDepth; _selectDepth--) { popDepth(); println("}"); } println("env.setExprEnv(" + oldEnv + ");"); if (! hasExprEnv) { println("env.setSelect(" + oldCxt + ", " + oldSel + ");"); //println("env.setCurrentNode(node);"); } popDepth(); println("}"); popLoop(); } /** * Prints code for xsl:for-each when the for-each has any xsl:sort. */ protected void printForEach(Element element, String select, Sort []sort) throws Exception { println("{"); pushDepth(); println("env.setCurrentNode(node);"); String pos = "_xsl_pos" + _unique++; String list = "_xsl_list" + _unique++; println("ArrayList " + list + " = xslSort(node, env" + ", _select_patterns[" + addSelect(select) + "]" + ", _xsl_sorts[" + _sorts.size() + "]);"); println("env.setContextSize(" + list + ".size());"); println("for (int " + pos + " = 1; " + pos + " <= " + list + ".size(); " + pos + "++) {"); pushLoop(); pushDepth(); println("Node " + getElement() + " = node;"); println("node = (Node) " + list + ".get(" + pos + " - 1);"); String oldPos = _currentPos; _currentPos = pos; println("env.setPosition(" + _currentPos + ");"); _sorts.add(sort); AbstractPattern oldNodeListContext = _nodeListContext; _nodeListContext = parseMatch(select); generateChildren(element); _currentPos = oldPos; _nodeListContext = oldNodeListContext; println("node = " + getElement() + ";"); popDepth(); println("}"); popLoop(); popDepth(); println("}"); } public String getCurrentPosition() { return _currentPos; } public void setCurrentPosition(String pos) { _currentPos = pos; } public AbstractPattern getNodeListContext() { return _nodeListContext; } public void setNodeListContext(AbstractPattern context) { _nodeListContext = context; } protected void printIf(Element element, Expr test) throws Exception { print("if ("); printExprTest(test, "node"); println(") {"); pushDepth(); generateChildren(element); popDepth(); println("}"); } protected void printChoose(Element element, Expr expr, boolean first) throws Exception { if (! first) print("else if ("); else print("if ("); printExprTest(expr, "node"); println(") {"); pushDepth(); generateChildren(element); popDepth(); println("}"); } protected void printOtherwise(Element element, boolean first) throws Exception { if (! first) print("else "); println("{"); pushDepth(); generateChildren(element); popDepth(); println("}"); } void printNumber(Expr expr, XslNumberFormat format) throws Exception { print("exprNumber(out, node, env, _exprs[" + addExpr(expr) + "]"); print(", _xsl_formats[" + _formats.size() + "]"); println(");"); _formats.add(format); } void printNumber(String level, AbstractPattern countPattern, AbstractPattern fromPattern, XslNumberFormat format) throws Exception { if (level.equals("single")) print("singleNumber(out, "); else if (level.equals("multiple")) print("multiNumber(out, "); else if (level.equals("any")) print("anyNumber(out, "); else throw error("xsl:number cannot understand level=`" + level + "'"); print("node, env, "); printPattern(countPattern); print(", "); printPattern(fromPattern); print(", _xsl_formats[" + _formats.size() + "]"); println(");"); _formats.add(format); } public int addFormat(XslNumberFormat format) { int index = _formats.size(); _formats.add(format); return index; } protected void printCopy(Element element) throws Exception { println("out.pushCopy(node);"); printUseAttributeSet(element, true); generateChildren(element); println("out.popCopy(node);"); } protected void printResultDocument(Element element, String href, String format) throws Exception { println("XslWriter oldOut = out;"); println("OutputStream os = null;"); println("try {"); pushDepth(); print("os = out.openWrite(env, "); generateString(href, '+', element); println(");"); println("out = out.openResultDocument(os);"); generateChildren(element); println("out.close();"); popDepth(); println("} finally {"); println(" if (os != null)"); println(" os.close();"); println(" out = oldOut;"); println("}"); } protected void printElement(Element element, String name) throws Exception { print("out.pushElement("); generateString(name, '+', element); if (_namespace != null) { print(", "); printNamespace(_namespace); } println(");"); printUseAttributeSet(element, true); generateChildren(element); println("out.popElement();"); } protected void printElement(Element element, String name, String namespace) throws Exception { print("out.pushElementNs("); generateString(name, '+', element); print(", "); generateString(namespace, '+', element); println(");"); printUseAttributeSet(element, true); generateChildren(element); print("out.popElement();"); } /** * Prints the attributes in a use-attribute-set. */ private void printUseAttributeSet(Element element, boolean isXSL) throws Exception { Attr attr = (Attr) ((QElement) element).getFirstAttribute(); for (; attr != null; attr = (Attr) attr.getNextSibling()) { if (isXSL && attr.getNodeName().equals("use-attribute-sets") || ! isXSL && attr.getNodeName().equals("xsl:use-attribute-sets")) { HashMap set = getAttributeSet(attr.getNodeValue()); if (set == null) continue; Iterator iter = set.keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); String value = (String) set.get(key); printAttributeValue(key, value, element); } } } } /** * Returns the named attribute set. */ public HashMap<String,String> getAttributeSet(String name) { CharBuffer cb = CharBuffer.allocate(); int i = 0; int len = name.length(); HashMap<String,String> map = new HashMap<String,String>(); while (i < len) { for (; i < len && name.charAt(i) == ' '; i++) { } cb.clear(); for (; i < len && name.charAt(i) != ' '; i++) cb.append(name.charAt(i)); if (cb.length() > 0) { XslAttributeSet newSet = _attributeSets.get(cb.toString()); if (newSet != null) { ArrayList<XslAttribute> attrList = newSet.getAttributes(); for (int j = 0; j < attrList.size(); j++) { XslAttribute attr = attrList.get(j); map.put(attr.getName(), attr.getValue()); } } } } return map; } /** * Returns the named attribute set. */ public ArrayList<XslAttribute> getAttributeSetList(String name) { CharBuffer cb = CharBuffer.allocate(); int i = 0; int len = name.length(); ArrayList<XslAttribute> set = new ArrayList<XslAttribute>(); while (i < len) { for (; i < len && name.charAt(i) == ' '; i++) { } cb.clear(); for (; i < len && name.charAt(i) != ' '; i++) cb.append(name.charAt(i)); if (cb.length() > 0) { XslAttributeSet newSet = _attributeSets.get(cb.toString()); if (newSet != null) { set.addAll(newSet.getAttributes()); } } } return set; } /** * Prints an xsl:attribute */ protected void printAttribute(Element element, String name) throws Exception { print("out.pushAttribute("); generateString(name, '+', element); if (_namespace != null) { print(", "); printNamespace(_namespace); } println(");"); generateChildren(element); println("out.popAttribute();"); } /** * Prints a single attribute value. */ private void printAttributeValue(String key, String value, Element elt) throws Exception { if (_namespace == null && ! attributeHasSpecial(key) && ! attributeHasSpecial(value)) { print("out.setAttribute("); generateString(key, '+', elt); print(", "); generateString(value, '+', elt); println(");"); } else { print("out.pushAttribute("); generateString(key, '+', elt); if (_namespace != null) { print(", "); printNamespace(_namespace); } println(");"); generateString(value, ',', elt); println("out.popAttribute();"); } } public void printNamespace(NamespaceContext namespace) throws Exception { for (int i = 0; i < _namespaces.size(); i++) { if (_namespaces.get(i).equals(namespace)) { print("_namespaces[" + i + "]"); return; } } print("_namespaces[" + _namespaces.size() + "]"); _namespaces.add(namespace); } public int addNamespace(NamespaceContext namespace) throws Exception { for (int i = 0; i < _namespaces.size(); i++) { if (_namespaces.get(i).equals(namespace)) { return i; } } _namespaces.add(namespace); return _namespaces.size() - 1; } protected void printAttribute(Element element, String name, String namespace) throws Exception { print("out.pushAttributeNs("); generateString(name, '+', element); print(", "); generateString(namespace, '+', element); println(");"); generateChildren(element); println("out.popAttribute();"); } protected void printPi(Element element) throws Exception { String name = element.getAttribute("name"); if (name.equals("")) throw error("xsl:pi expected `name' attribute."); print("out.pushPi();"); generateChildren(element); println("out.popPi("); generateString(name, '+', element); println(");"); } protected void printComment(Element element) throws Exception { println("out.pushComment();"); generateChildren(element); println("out.popComment();"); } protected void printError(String msg) throws Exception { println("if (true) throw new javax.xml.transform.TransformerException(\"" + msg + "\");"); } protected void printMessage(Element msg) throws Exception { int unique = _unique++; println("XMLWriter frag" + unique + " = out.pushFragment();"); generateChildren(msg); String terminate = msg.getAttribute("terminate"); if (terminate.equals("yes")) println("if (true) throw new javax.xml.transform.TransformerException(((QAbstractNode) out.popFragment(frag" + unique + ")).getTextValue());"); else println("System.err.println(((QAbstractNode) out.popFragment(frag" + unique + ")).getTextValue());"); } /** * Prints code to implement the xtp:expression tag, i.e. print * the value of the Java expression. */ protected void printExpression(Element element) throws Exception { String expr = element.getAttribute("expr"); if (! expr.equals("")) { print("out.print("); print(expr); println(");"); } else { print("out.print("); print(((QAbstractNode) element).getTextValue()); println(");"); } } protected void printScriptlet(Element element) throws Exception { println(((QAbstractNode) element).getTextValue()); } protected void printWhile(Element element, Expr test) throws Exception { print("while ("); printExprTest(test, "node"); println(") {"); pushDepth(); generateChildren(element); popDepth(); println("}"); } protected void printDeclaration(Element element) throws Exception { println(((QAbstractNode) element).getTextValue()); } protected void printCacheDepends(String name) throws Exception { print("out.addCacheDepend(((com.caucho.vfs.Path) out.getProperty(\"caucho.pwd\")).lookup(\""); printString(name); println("\"));"); } public String getElement() { return "node" + _loopDepth; } public void pushLoop() { _loopDepth++; } public void popLoop() { _loopDepth--; } public String getEnv() { return "env"; } void pushEnv() { _envDepth.add(0); } void popEnv() { _envDepth.pop(); } void printPattern(AbstractPattern pattern) throws Exception { if (pattern == null) print("null"); else { print("_match_patterns[" + _matchPatterns.size() + "]"); _matchPatterns.add(pattern); } } private int createNodeSet(String select, Element element) throws Exception { return addSelect(select); } int createSelectPattern(AbstractPattern pattern) throws Exception { return addSelect(pattern); } int createMatchPattern(String select, Element element) throws Exception { AbstractPattern pattern = parseMatch(select); _matchPatterns.add(pattern); return _matchPatterns.size() - 1; } String getName(String tag) { CharBuffer newTag = new CharBuffer(); for (int i = 0; i < tag.length(); i++) { int ch = tag.charAt(i); switch (ch) { case ' ': case '\t': case '\r': case '\n': case '(': case ')': break; case ':': case '.': case '|': newTag.append('_'); break; default: if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') newTag.append((char) ch); } } tag = newTag.toString(); if (_names.get(tag) == null) { _names.put(tag, tag); return tag; } int i = 0; while (true) { String subname = tag + i; if (_names.get(subname) == null) { _names.put(subname, subname); return subname; } i++; } } void printExprTest(Expr expr, String element) throws Exception { print("_exprs[" + addExpr(expr) + "].evalBoolean(" + element + ", " + getEnv() + ")"); } public void printExprTest(int exprId, String element) throws Exception { print("_exprs[" + exprId + "].evalBoolean(" + element + ", " + getEnv() + ")"); } private boolean attributeHasSpecial(String string) { int length = string.length(); for (int i = 0; i < length; i++) { char ch = string.charAt(i); if (ch == '{' && i + 1 < length) { // {{ is treated as a single { if (string.charAt(i + 1) == '{') { i++; continue; } return true; } // <#= interpolates else if (i + 2 < length && ch == '<' && string.charAt(i + 1) == '#' && string.charAt(i + 2) == '=') return true; } return false; } /** * Produces code to generate an attribute value template. The same * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of * print statements (','). * * @param string the source template * @param mode separator: either '+' or ',' * @param elt the containing element. Needed for namespaces. */ void generateString(String string, int mode, Element elt) throws Exception { CharBuffer cb = new CharBuffer(); int i = 0; boolean first = true; int length = string.length(); for (; i < length; i++) { char ch = string.charAt(i); if (ch == '\n') { cb.append("\\n"); } else if (ch == '"') { cb.append("\\\""); } else if (ch == '{' && i + 1 < length) { // {{ is treated as a single { if (string.charAt(i + 1) == '{') { cb.append('{'); i++; } // the value is computed from an XPath expr else { // print the gathered text if any if (mode == ',') { if (cb.length() > 0) println("out.print(\"" + cb.toString() + "\");"); } else { if (! first) print((char) mode); if (cb.length() > 0) { print("\""); print(cb.toString()); print("\""); print((char) mode); } } // scan the contents of '{' ... '}' cb.clear(); for (i++; i < length && string.charAt(i) != '}'; i++) cb.append(string.charAt(i)); // and add the results if (mode == ',') printStringExpr(cb.toString(), elt); else stringExpr(cb.toString(), elt); cb.clear(); first = false; } } // }} is treated as a single } else if (ch == '}' && i + 1 < length) { if (string.charAt(i + 1) == '}') { cb.append('}'); i++; } else cb.append('}'); } // <#= interpolates else if (i + 2 < length && ch == '<' && string.charAt(i + 1) == '#' && string.charAt(i + 2) == '=') { // print the gathered text if any if (mode == ',') { if (cb.length() > 0) println("out.print(\"" + cb.toString() + "\");"); } else { if (! first) print((char) mode); if (cb.length() > 0) { print("\""); print(cb.toString()); print("\""); print((char) mode); } } // scan the contents of '{' ... '}' cb.clear(); for (i += 3; i + 1 < length && string.charAt(i) != '#' && string.charAt(i + 1) != '>'; i++) cb.append(string.charAt(i)); i++; // and add the results if (mode == ',') println("out.print(" + cb + ");"); else { print("(" + cb + ")"); } cb.clear(); first = false; } else cb.append((char) ch); } // add any trailing text if (cb.length() > 0) { if (mode == ',') println("out.print(\"" + cb + "\");"); else { if (! first) print((char) mode); print("\"" + cb + "\""); } } else if (first && mode == '+') print("\"\""); } /** * Produces code to generate an attribute value template. The same * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of * print statements (','). * * @param string the source template * @param elt the containing element. Needed for namespaces. * * @return the variable storing the generated string. */ String generateStringVar(String string, Element elt) throws Exception { CharBuffer cb = new CharBuffer(); int i = 0; boolean first = true; int length = string.length(); String strVar = "_xsl_str" + _unique++; if (string.indexOf('{') < 0 && string.indexOf('}') < 0) { print("String " + strVar + " = \""); printString(string); println("\";"); return strVar; } else if (string.lastIndexOf('{') == 0 && string.indexOf('}') == string.length() - 1) { println("String " + strVar + " = \"\";"); string = string.substring(1, string.length() - 1); addStringExpr(strVar, string, elt, true); return strVar; } String cbVar = "_xsl_cb" + _unique++; println("com.caucho.util.CharBuffer " + cbVar + " = com.caucho.util.CharBuffer.allocate();"); for (; i < length; i++) { char ch = string.charAt(i); if (ch == '\n') { cb.append("\\n"); } else if (ch == '"') { cb.append("\\\""); } else if (ch == '{' && i + 1 < length) { // {{ is treated as a single { if (string.charAt(i + 1) == '{') { cb.append('{'); i++; } // the value is computed from an XPath expr else { // print the gathered text if any if (cb.length() > 0) println(cbVar + ".append(\"" + cb.toString() + "\");"); // scan the contents of '{' ... '}' cb.clear(); for (i++; i < length && string.charAt(i) != '}'; i++) cb.append(string.charAt(i)); // and add the results addStringExpr(cbVar, cb.toString(), elt, false); cb.clear(); first = false; } } // }} is treated as a single } else if (ch == '}' && i + 1 < length) { if (string.charAt(i + 1) == '}') { cb.append('}'); i++; } else cb.append('}'); } // <#= interpolates else if (i + 2 < length && ch == '<' && string.charAt(i + 1) == '#' && string.charAt(i + 2) == '=') { // print the gathered text if any if (cb.length() > 0) println(cbVar + ".append(\"" + cb.toString() + "\");"); // scan the contents of '<#=' ... '#>' cb.clear(); for (i += 3; i + 1 < length && string.charAt(i) != '#' && string.charAt(i + 1) != '>'; i++) cb.append(string.charAt(i)); i++; // and add the results println(cbVar + ".append(" + cb + ");"); cb.clear(); first = false; } else cb.append((char) ch); } // add any trailing text if (cb.length() > 0) println(cbVar + ".append(\"" + cb + "\");"); println("String " + strVar + " = " + cbVar + ".close();"); return strVar; } /** * Prints a value-of expression */ private void printStringExpr(String exprString, Element elt) throws Exception { int length = exprString.length(); if (length == 0) return; AbstractPattern select = null; try { select = parseSelect(exprString); } catch (Exception e) { } if (exprString.equals(".")) { println("out.valueOf(node);"); return; } else if (exprString.charAt(0) == '@') { boolean isSimple = true; for (int i = 1; i < length; i++) { char ch = exprString.charAt(i); if (! XmlChar.isNameChar(ch) || ch == ':') isSimple = false; } if (isSimple) { println("if (node instanceof Element)"); print(" out.print(((Element) node).getAttribute(\""); print(exprString.substring(1)); println("\"));"); return; } } else if (allowJavaSelect(select)) { int oldSelectDepth = _selectDepth; String loop = "_xsl_loop" + _unique++; _selectLoopDepth = 0; String ptr = printSelectBegin(select, true, loop); println("out.valueOf(" + ptr + ");"); println("break " + loop + ";"); for (; _selectDepth > oldSelectDepth; _selectDepth--) { popDepth(); println("}"); } return; } println("out.valueOf(_exprs[" + addExpr(exprString) + "].evalObject(node, " + getEnv() + "));"); } /** * Prints a value-of expression */ private void addStringExpr(String var, String exprString, Element elt, boolean isSingleString) throws Exception { int length = exprString.length(); if (length == 0) return; AbstractPattern select = null; try { select = parseSelect(exprString); } catch (Exception e) { } if (exprString.equals(".")) { if (isSingleString) println(var + " = XmlUtil.textValue(node);"); else println("XmlUtil.textValue(" + var + ", node);"); return; } else if (exprString.charAt(0) == '@') { boolean isSimple = true; for (int i = 1; i < length; i++) { char ch = exprString.charAt(i); if (! XmlChar.isNameChar(ch) || ch == ':') isSimple = false; } if (isSimple) { println("if (node instanceof Element)"); if (isSingleString) { print(" " + var + " = ((Element) node).getAttribute(\""); print(exprString.substring(1)); println("\");"); } else { print(" " + var + ".append(((Element) node).getAttribute(\""); print(exprString.substring(1)); println("\"));"); } return; } } else if (allowJavaSelect(select)) { int oldSelectDepth = _selectDepth; String loopVar = "_xsl_loop" + _unique++; _selectLoopDepth = 0; String ptr = printSelectBegin(select, true, loopVar); if (isSingleString) println(var + " = XmlUtil.textValue(" + ptr + ");"); else println("XmlUtil.textValue(" + var + ", " + ptr + ");"); println("break " + loopVar + ";"); for (; _selectDepth > oldSelectDepth; _selectDepth--) { popDepth(); println("}"); } return; } if (isSingleString) { println(var + " = _exprs[" + addExpr(exprString) + "].evalString(node, " + getEnv() + ");"); } else { println("_exprs[" + addExpr(exprString) + "].evalString(" + var + ", node, " + getEnv() + ");"); } } /** * Prints iterator code to start a select. */ private String printSelectBegin(AbstractPattern select, boolean isForEach, String loopVar) throws IOException, XslParseException { if (select == null) throw new NullPointerException(); if (select instanceof FromContext && ((FromContext) select).getCount() == 0) return "node"; else if (select instanceof FromRoot) return "ownerDocument(node)"; boolean useXPath = allowJavaSelect(select); String name = "node"; if (! useXPath) { // punt and let XPath handle it. String iterName = "_xsl_iter" + _unique++; String ptrName = "_xsl_ptr" + _unique++; if (isForEach) println("env.setCurrentNode(node);"); println("Iterator " + iterName + " = _select_patterns[" + addSelect(select) + "].select(" + name + ", env);"); if (loopVar != null && _selectLoopDepth == 0) println(loopVar + ":"); println("while (" + iterName + ".hasNext()) {"); pushDepth(); _selectDepth++; _selectLoopDepth++; println("Node " + ptrName + " = (Node) " + iterName + ".next();"); return ptrName; } if (select instanceof FromChildren) { name = printSelectBegin(select.getParent(), isForEach, loopVar); String ptrName = "_xsl_ptr" + _unique++; if (loopVar != null && _selectLoopDepth == 0) println(loopVar + ":"); println("for (Node " + ptrName + " = " + name + ".getFirstChild();"); println(" " + ptrName + " != null;"); println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {"); pushDepth(); _selectDepth++; _selectLoopDepth++; return ptrName; } else if (select instanceof FromNextSibling) { name = printSelectBegin(select.getParent(), isForEach, loopVar); String ptrName = "_xsl_ptr" + _unique++; if (loopVar != null && _selectLoopDepth == 0) println(loopVar + ":"); println("for (Node " + ptrName + " = " + name + ".getNextSibling();"); println(" " + ptrName + " != null;"); println(" " + ptrName + " = " + ptrName + ".getNextSibling()) {"); pushDepth(); _selectDepth++; _selectLoopDepth++; return ptrName; } else if (select instanceof NodePattern) { name = printSelectBegin(select.getParent(), isForEach, loopVar); NodePattern pat = (NodePattern) select; println("if (" + name + ".getNodeName() == \"" + pat.getNodeName() + "\" &&"); println(" " + name + " instanceof Element) {"); pushDepth(); _selectDepth++; return name; } else if (select instanceof NodeTypePattern) { name = printSelectBegin(select.getParent(), isForEach, loopVar); NodeTypePattern pat = (NodeTypePattern) select; if (pat.getNodeType() >= 0) { println("if (" + name + ".getNodeType() == " + pat.getNodeType() + ") {"); pushDepth(); _selectDepth++; } return name; } else if (select instanceof FilterPattern) { String posId = "_xsl_pos" + _unique++; println("int " + posId + " = 0;"); name = printSelectBegin(select.getParent(), isForEach, loopVar); println(posId + "++;"); FilterPattern pat = (FilterPattern) select; Expr expr = pat.getExpr(); if (expr instanceof NumericExpr) { NumericExpr num = (NumericExpr) expr; if (num.isConstant()) { println("if (" + posId + " > " + (int) num.getValue() + ")"); println(" break;"); println("else if (" + posId + " == " + (int) num.getValue() + ") {"); pushDepth(); _selectDepth++; return name; } } throw new RuntimeException(); } throw new RuntimeException(String.valueOf(select)); } /** * Returns true if we can compile in the java select. */ private boolean allowJavaSelect(AbstractPattern select) { if (select == null) return false; else if (! select.isStrictlyAscending()) return false; else if (select instanceof FromContext) return ((FromContext) select).getCount() == 0; else if (select instanceof FromRoot) return true; else if (select instanceof NodePattern) return allowJavaSelect(select.getParent()); else if (select instanceof NodeTypePattern) return allowJavaSelect(select.getParent()); else if (select instanceof FromChildren) return allowJavaSelect(select.getParent()); else if (select instanceof FromNextSibling) return allowJavaSelect(select.getParent()); else if (select instanceof FilterPattern) { if (! allowJavaSelect(select.getParent())) return false; Expr expr = ((FilterPattern) select).getExpr(); return ((expr instanceof NumericExpr) && ((NumericExpr) expr).isConstant()); } else return false; } private void stringExpr(String exprString, Element element) throws Exception, XslParseException { print("_exprs[" + addExpr(exprString) + "].evalString(node, " + getEnv() + ")"); } /** * Adds an expression constant returning its index. * * @param expr the expression to add. * * @return the index into the runtime expression array */ public int addExpr(Expr expr) throws XslParseException { String exprStr = expr.toString(); int i = _exprMap.get(exprStr); if (i >= 0) return i; i = _exprs.size(); _exprMap.put(exprStr, i); _exprs.add(expr); return i; } /** * Adds an expression constant returning its index. * * @param exprString the expression to add. * * @return the index into the runtime expression array */ public int addExpr(String exprString) throws XslParseException { int i = _exprMap.get(exprString); if (i >= 0) return i; Expr expr = parseExpr(exprString); i = _exprs.size(); _exprs.add(expr); _exprMap.put(exprString, i); return i; } /** * Adds a select pattern returning its index. * * @param select the select pattern to add. * * @return the index into the runtime expression array */ public int addSelect(AbstractPattern select) throws IOException, XslParseException { String selectStr = select.toString(); int i = _selectMap.get(selectStr); if (i >= 0) return i; i = _selectPatterns.size(); _selectMap.put(selectStr, i); _selectPatterns.add(select); return i; } /** * Adds a select pattern, returning its index. * * @param selectString the expression to add. * * @return the index into the runtime select pattern array */ public int addSelect(String selectString) throws IOException, XslParseException { int i = _selectMap.get(selectString); if (i >= 0) return i; AbstractPattern select = parseSelect(selectString); i = _selectPatterns.size(); _selectPatterns.add(select); _selectMap.put(selectString, i); return i; } /** * Adds a match pattern, returning its index. * * @param pattern the expression to add. * * @return the index into the runtime expression array */ public int addMatch(AbstractPattern pattern) throws XslParseException { int index = _matchPatterns.size(); _matchPatterns.add(pattern); return index; } protected StylesheetImpl completeGenerate(ArrayList<XslNode> inits, ArrayList globals) throws Exception { printTemplates(); printMacros(); printInitVars(inits); printFragments(); printInit(); printStrings(); printExpressions(); printPatterns(); popDepth(); println("}"); _s.close(); _s = null; /* if (dbg.canWrite()) { ReadStream is = path.openRead(); dbg.writeStream(is); is.close(); } */ if (_parentLoader instanceof DynamicClassLoader) ((DynamicClassLoader) _parentLoader).make(); _compiler.compile(_path.getPath(), _lineMap); StylesheetImpl stylesheet; stylesheet = (StylesheetImpl) _xslGenerator.loadStylesheet(_path.getFullPath(), _pkg + "." + _className); //if (stylesheet != null) // stylesheet.init(context); return stylesheet; } private long getLastModified() { long lastModified = 0; for (int i = 0; i < _depends.size(); i++) { Path path = _depends.get(i); if (path.getLastModified() > lastModified) lastModified = path.getLastModified(); } return lastModified; } /** * Generate code executed for all transformations. * <ul> * <li>Add the stylesheet namespaces to the generated document. * <li>Assign the global variables. * <li>Initialize the cache dependencies. */ protected void printInitVars(ArrayList<XslNode> inits) throws Exception { println("private void _xsl_init_vars(XslWriter out, Node node, Env env)"); println(" throws Exception"); println("{"); pushDepth(); // Add the stylesheet namespaces to the generated document. HashMap namespaces = _qDoc.getNamespaces(); if (namespaces != null) { Iterator prefixes = namespaces.keySet().iterator(); while (prefixes.hasNext()) { String prefix = (String) prefixes.next(); String url = (String) namespaces.get(prefix); if (url.startsWith("http://www.w3.org/XSL/Transform/") || url.startsWith("http://www.w3.org/1999/XSL/Transform") || url.startsWith("http://www.w3.org/XML/2000/xmlns") || url.startsWith("http://www.w3.org/2000/xmlns") || url.equals(XTPNS)) continue; else if (_excludedNamespaces.get(url) != null) continue; else if (_namespaceAliases.get(url) != null) continue; if (prefix == null) println("out.addNamespace(\"\", \"" + url + "\");"); else println("out.addNamespace(\"" + prefix + "\", \"" + url + "\");"); } } // Initialize the global stylesheet variables println("Object _xsl_tmp;"); for (int i = 0; i < inits.size(); i++) { XslNode node = inits.get(i); // NamespaceContext oldNamespace = addNamespace(elt); node.generate(getOut()); /* if ("variable".equals(getXslLocal(elt)) || "assign".equals(getXslLocal(elt))) { String name = elt.getAttribute("name"); String expr = elt.getAttribute("select"); print("env.setGlobal(\"" + name + "\", "); if (! expr.equals("")) printVariableValue(parseExpr(expr)); else printVariableValue(elt); println(");"); } else if ("param".equals(getXslLocal(elt))) { String name = elt.getAttribute("name"); String expr = elt.getAttribute("select"); print("env.setGlobal(\"" + name + "\", "); if (! expr.equals("")) printVariableValue(parseExpr(expr)); else printVariableValue(elt); println(");"); println("_xsl_tmp = out.getParameter(\"" + name + "\");"); println("if (_xsl_tmp != null)"); println(" env.setGlobal(\"" + name + "\", _xsl_tmp);"); } */ // oldNamespace = _namespace; } // Initialize the cache dependencies. println("com.caucho.vfs.Path pwd;"); println("pwd = (com.caucho.vfs.Path) out.getProperty(\"caucho.pwd\");"); for (int i = 0; i < _cacheDepends.size(); i++) { String depend = (String) _cacheDepends.get(i); print("out.addCacheDepend(pwd.lookup(\""); printString(depend); println("\"));"); } popDepth(); println("}"); } protected void printInit() throws Exception { println("protected void _xsl_init(XslWriter out, Node node, Env env)"); println(" throws Exception"); println("{"); pushDepth(); println("Object _xsl_tmp;"); println("_xsl_init_vars(out, node, env);"); // Generic init vars // println("templates = _staticTemplates;"); for (int i = 0; _globalActions != null && i < _globalActions.size(); i++) { QAbstractNode node = (QAbstractNode) _globalActions.get(i); generateChild(node); } popDepth(); println("}"); // depends println("public boolean isModified()"); println("{"); pushDepth(); println("return com.caucho.server.util.CauchoSystem.getVersionId() != " + CauchoSystem.getVersionId() + "L ||"); println(" super.isModified();"); popDepth(); println("}"); println("public void init(com.caucho.vfs.Path path)"); println(" throws Exception"); println("{"); pushDepth(); println("super.init(path);"); println("com.caucho.vfs.Path pwd = path.getParent();"); for (int i = 0; i < _depends.size(); i++) { Path path = _depends.get(i); if (path.canRead() && ! path.isDirectory()) { Depend depend = new Depend(path); print("addDepend(new com.caucho.vfs.Depend(pwd.lookup(\""); printString(path.getRelativePath()); println("\"), " + depend.getDigest() + "L));"); } } println("stylesheets = new StylesheetEnv[" + _stylesheets.size() + "];"); println("StylesheetEnv env;"); for (int i = 0; i < _stylesheets.size(); i++) { String ss = _stylesheets.get(i); println("env = new StylesheetEnv();"); println("stylesheets[" + i + "] = env;"); print("env.setPath(pwd.lookup(\""); printString(ss); println("\"));"); } if (! _strip.isEmpty()) { println("HashMap preserve = new HashMap();"); println("HashMap preservePrefix = new HashMap();"); Iterator iter = _preserve.keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); if (key.endsWith(":*")) { String prefix = key.substring(0, key.length() - 2); println("preservePrefix.put(\"" + prefix + "\", \"true\");"); } else println("preserve.put(\"" + key + "\", \"true\");"); } println("HashMap strip = new HashMap();"); println("HashMap stripPrefix = new HashMap();"); iter = _strip.keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); if (key.endsWith(":*")) { String prefix = key.substring(0, key.length() - 2); println("stripPrefix.put(\"" + prefix + "\", \"true\");"); } else println("strip.put(\"" + key + "\", \"true\");"); } println("setSpaces(preserve, preservePrefix, strip, stripPrefix);"); } printOutput(); if (_errorPage != null) { print("setProperty(\"caucho.error.page\", \""); printString(_errorPage); println("\");"); } if (_globalParameters != null && _globalParameters.size() > 0) { println("ArrayList params = new ArrayList();"); for (int i = 0; i < _globalParameters.size(); i++) { String param = _globalParameters.get(i); println("params.add(\"" + param + "\");"); } print("setProperty(\"caucho.global.param\", params);"); } String disable = null; /* if (_outputAttributes != null) disable = (String) _outputAttributes.get("disable-output-escaping"); if (disable != null && ! disable.equals("no") && ! disable.equals("false")) println("defaultDisableEscaping = true;"); */ if (_isRawText) println("_defaultDisableEscaping = true;"); printNamespaces(); printFunctions(); printSorts(); printFormats(); popDepth(); println("}"); } /** * Sets the property for the xsl:output keys. */ private void printOutput() throws Exception { Iterator iter = _outputAttributes.keySet().iterator(); if (_outputAttributes.get("encoding") == null) println("_output.put(\"encoding\", \"utf-8\");"); while (iter.hasNext()) { String key = (String) iter.next(); String value = (String) _outputAttributes.get(key); println("_output.put(\"" + key + "\", \"" + value + "\");"); } } private void printSorts() throws Exception { if (_sorts.size() == 0) return; println(); println("_xsl_sorts = new com.caucho.xsl.Sort[][] { "); pushDepth(); for (int i = 0; i < _sorts.size(); i++) { Sort []sorts = _sorts.get(i); print("new com.caucho.xsl.Sort[] {"); for (int j = 0; j < sorts.length; j++) { Sort sort = sorts[j]; Expr lang = sort.getLang(); Expr caseOrder = sort.getCaseOrder(); if (lang != null || caseOrder != null) { print("new com.caucho.xsl.Sort(\"" + sort.getExpr() + "\", " + "\"" + sort.getAscending() + "\", " + (lang == null ? "null, " : "\"" + lang + "\", ") + (caseOrder == null ? "null), " : "\"" + caseOrder + "\"), ")); } else print("new com.caucho.xsl.Sort(\"" + sort.getExpr() + "\", " + "\"" + sort.getAscending() + "\", " + sort.isText() + "), "); } println("},"); } popDepth(); println("};"); } private void printLocale(Locale locale) throws Exception { String language = locale.getLanguage(); String country = locale.getCountry(); String variant = locale.getVariant(); if (variant != null && country != null) { print("new java.util.Locale(\"" + language + "\", " + "\"" + country + "\", \"" + variant + "\")"); } else if (country != null) { print("new java.util.Locale(\"" + language + "\", " + "\"" + country + "\")"); } else { print("new java.util.Locale(\"" + language + "\")"); } } private void printFormats() throws Exception { if (_formats.size() == 0) return; println(); println("_xsl_formats = new XslNumberFormat[] { "); pushDepth(); for (int i = 0; i < _formats.size(); i++) { XslNumberFormat format = (XslNumberFormat) _formats.get(i); println("new XslNumberFormat(\"" + format.getFormat() + "\", \"" + format.getLang() + "\", " + format.isAlphabetic() + ", \"" + format.getGroupSeparator() + "\", " + format.getGroupSize() + "),"); } popDepth(); println("};"); } private void printNamespaces() throws Exception { if (_namespaces.size() == 0) return; println(); println("_namespaces = new NamespaceContext[] { "); pushDepth(); for (int i = 0; i < _namespaces.size(); i++) { NamespaceContext ns = _namespaces.get(i); printNamespaceDef(ns); println(","); } popDepth(); println("};"); } private void printNamespaceDef(NamespaceContext ns) throws Exception { if (ns == null) { print("null"); return; } print("new NamespaceContext("); printNamespaceDef(ns.getPrev()); print(", \"" + ns.getPrefix() + "\", \"" + ns.getUrl() + "\")"); } private void printFunctions() throws Exception { println(); println("com.caucho.xsl.fun.KeyFun keyFun = new com.caucho.xsl.fun.KeyFun();"); HashMap keys = _keyFun.getKeys(); Iterator iter = keys.keySet().iterator(); while (iter.hasNext()) { String name = (String) iter.next(); KeyFun.Key key = (KeyFun.Key) keys.get(name); println("keyFun.add(\"" + name + "\", XPath.parseMatch(\"" + key.getMatch() + "\").getPattern(), XPath.parseExpr(\"" + key.getUse() + "\"));"); } println("addFunction(\"key\", keyFun);"); println(); println("com.caucho.xsl.fun.FormatNumberFun formatFun = new com.caucho.xsl.fun.FormatNumberFun();"); println("java.text.DecimalFormatSymbols symbols;"); JavaWriter out = _out; HashMap locales = _formatNumberFun.getLocales(); iter = locales.keySet().iterator(); while (iter.hasNext()) { String name = (String) iter.next(); DecimalFormatSymbols symbols = (DecimalFormatSymbols) locales.get(name); out.println("symbols = new java.text.DecimalFormatSymbols();"); out.print("symbols.setDecimalSeparator(\'"); out.printJavaChar(symbols.getDecimalSeparator()); out.println("\');"); out.print("symbols.setGroupingSeparator(\'"); out.printJavaChar(symbols.getGroupingSeparator()); out.println("\');"); out.print("symbols.setInfinity(\""); out.printJavaString(symbols.getInfinity()); out.println("\");"); out.print("symbols.setMinusSign(\'"); out.printJavaChar(symbols.getMinusSign()); out.println("\');"); out.print("symbols.setNaN(\""); out.printJavaString(symbols.getNaN()); out.println("\");"); out.print("symbols.setPercent(\'"); out.printJavaChar(symbols.getPercent()); out.println("\');"); out.print("symbols.setPerMill(\'"); out.printJavaChar(symbols.getPerMill()); out.println("\');"); out.print("symbols.setZeroDigit(\'"); out.printJavaChar(symbols.getZeroDigit()); out.println("\');"); out.print("symbols.setDigit(\'"); out.printJavaChar(symbols.getDigit()); out.println("\');"); out.print("symbols.setPatternSeparator(\'"); out.printJavaChar(symbols.getPatternSeparator()); out.println("\');"); println("formatFun.addLocale(\"" + name + "\", symbols);"); } println("addFunction(\"format-number\", formatFun);"); } private void printMacros() throws Exception { /* for (int i = 0; i < _macros.size(); i++) { Macro macro = _macros.get(i); println("void " + getMacroName(macro.getName()) + "(XslWriter out, Node inputNode, Env env)"); println(" throws Exception"); println("{"); pushDepth(); println("Object _xsl_tmp;"); println("Node node = inputNode;"); generateChildren(macro.getElement()); popDepth(); println("}"); } */ } private void printFragments() throws Exception { for (int i = 0; i < _fragments.size(); i++) { Element elt = (Element) _fragments.get(i); println("Object _xsl_fragment" + i + "(XslWriter out, Node inputNode, Env env )"); println(" throws Exception"); println("{"); pushDepth(); println("Object _xsl_tmp;"); println("Node node = inputNode;"); println("XMLWriter _xsl_frag = out.pushFragment();"); generateChildren(elt); println("return out.popFragment(_xsl_frag);"); popDepth(); println("}"); } } /** * Prints the template definitions, i.e. the set of XPath * match patterns to test a node. */ private void printTemplates() throws Exception { for (int j = 0; j < _modes.size(); j++) { String mode = _modes.get(j); String modeName = getModeName(mode); printApplyNode(mode); println(); println("static HashMap _static_templates" + modeName + ";"); println(); println("static {"); pushDepth(); println("_static_templates" + modeName + " = new HashMap();"); println("Template []values;"); println("try {"); pushDepth(); ArrayList defaultTemplateList = (ArrayList) _templates.get("*"); if (defaultTemplateList == null) defaultTemplateList = new ArrayList(); println("Template []star = new Template[] {"); pushDepth(); for (int i = 0; i < defaultTemplateList.size(); i++) { Template template = (Template) defaultTemplateList.get(i); if (template.getMode().equals(mode)) { printTemplate(template); println(","); } } popDepth(); println("};"); println(); println("_static_templates" + modeName + ".put(\"*\", star);"); int count = _templates.size(); for (int i = 0; i < count; i += 64) println("_init_templates" + modeName + "_" + i + "(star);"); popDepth(); println("} catch (Exception e) {"); println(" e.printStackTrace();"); println("}"); popDepth(); println("}"); for (int i = 0; i < count; i += 64) printTemplateInitFun(mode, i, 64, defaultTemplateList); } } /** * Prints a function to initialize some of the templates. */ private void printApplyNode(String mode) throws Exception { String modeName = getModeName(mode); print("protected void applyNode" + modeName); println("(XslWriter out, Node node, Env env, int _xsl_min, int _xsl_max)"); println(" throws Exception"); println("{"); pushDepth(); println("Object _xsl_tmp;"); println(); println("switch (getTemplateId(_static_templates" + modeName + ", " + "node, env, _xsl_min, _xsl_max)) {"); // XXX: name issue below functions/templateList for (int i = 0; i < _functions.size(); i++) { Template template = (Template) _templateList.get(i); if (template == null || ! template.getMode().equals(mode)) continue; println("case " + (i + 1) + ":"); println(" " + _functions.get(i) + "(out, node, env);"); println(" break;"); } println("default:"); println(" switch (node.getNodeType()) {"); println(" case Node.ELEMENT_NODE:"); println(" case Node.DOCUMENT_NODE:"); println(" case Node.DOCUMENT_FRAGMENT_NODE:"); println(" env.setSelect(node, null);"); println(" for (Node child = node.getFirstChild();"); println(" child != null;"); println(" child = child.getNextSibling()) {"); println(" env.setCurrentNode(child);"); println(" applyNode" + modeName + "(out, child, env, 0, " + Integer.MAX_VALUE + ");"); println(" }"); println(" break;"); println(" default:"); println(" applyNodeDefault(out, node, env);"); println(" break;"); println(" }"); println(" break;"); println("}"); popDepth(); println("}"); } /** * Prints a function to initialize some of the templates. */ private void printTemplateInitFun(String mode, int offset, int length, ArrayList defaultTemplateList) throws Exception { String modeName = getModeName(mode); println("private static void _init_templates" + modeName + "_" + offset + "(Template []star)"); println(" throws Exception"); println("{"); pushDepth(); Iterator<String> iter = _templates.keySet().iterator(); while (iter.hasNext() && length > 0) { String name = iter.next(); if (name.equals("*")) continue; ArrayList templateList = (ArrayList) _templates.get(name); if (modeTemplateCount(mode, templateList) == 0) continue; if (offset > 0) { offset--; continue; } println("_static_templates" + modeName + ".put(\"" + name + "\", "); println(" mergeTemplates(star, new Template[] {"); pushDepth(); pushDepth(); for (int i = 0; i < templateList.size(); i++) { Template template = (Template) templateList.get(i); if (template.getMode().equals(mode)) { printTemplate(template); println(","); } } popDepth(); popDepth(); println("}));"); length--; } popDepth(); println("}"); } /** * Returns true if the template list contains a template with the given * mode. */ private int modeTemplateCount(String mode, ArrayList templateList) { int count = 0; for (int i = 0; i < templateList.size(); i++) { Template template = (Template) templateList.get(i); if (template.getMode().equals(mode)) count++; } return count; } /** * Prints initialization code for a single template. */ private void printTemplate(Template template) throws IOException { print("new Template("); AbstractPattern pattern = template.getPattern(); print("XPath.parseMatch(\"" + template.getPattern().toPatternString() + "\").getPattern(), "); print("\"" + template.getMode() + "\", "); print(template.getMin() + ", "); print(template.getMax() + ", "); print(template.getPriority() + ", "); print(template.getCount() + ", "); print("\"" + template.getFunction() + "\", "); print("" + template.getId() + ")"); } /** * Prints the constant strings. */ private void printStrings() throws Exception { for (int j = 0; j < _strings.size(); j++) { String text = (String) _strings.get(j); print("static char[] _xsl_string" + j + " = \""); printString(text); println("\".toCharArray();"); } } /** * Prints the precompiled XPath expressions as static variables. */ private void printExpressions() throws Exception { if (_exprs.size() == 0) return; println("private static Expr []_exprs;"); println("static {"); pushDepth(); println("try {"); pushDepth(); println("_exprs = new Expr[] { "); pushDepth(); for (int i = 0; i < _exprs.size(); i++) { Expr expr = _exprs.get(i); println("XPath.parseExpr(\"" + expr + "\"),"); // System.out.println("EXPR: " + expr + " " + expr.getListContext()); /* if (expr.getListContext() == null) // || currentPos != null) println("XPath.parseExpr(\"" + expr + "\"),"); else { print("XPath.parseExpr(\"" + expr + "\", null,"); println("XPath.parseMatch(\"" + expr.getListContext() +"\").getPattern()),"); } */ } popDepth(); println("};"); popDepth(); println("} catch (Exception e) {"); println(" e.printStackTrace();"); println("}"); popDepth(); println("}"); } /** * Prints the precompiled XPath select and match patterns as static * variables. */ private void printPatterns() throws Exception { if (_selectPatterns.size() == 0 && _matchPatterns.size() == 0) return; println("private static com.caucho.xpath.pattern.AbstractPattern []_select_patterns;"); println("private static com.caucho.xpath.pattern.AbstractPattern []_match_patterns;"); println("static {"); pushDepth(); println("try {"); pushDepth(); println("_select_patterns = new com.caucho.xpath.pattern.AbstractPattern[] { "); pushDepth(); for (int i = 0; i < _selectPatterns.size(); i++) { AbstractPattern pattern = _selectPatterns.get(i); println("XPath.parseSelect(\"" + pattern + "\").getPattern(),"); } popDepth(); println("};"); println("_match_patterns = new com.caucho.xpath.pattern.AbstractPattern[] { "); pushDepth(); for (int i = 0; i < _matchPatterns.size(); i++) { AbstractPattern pattern = _matchPatterns.get(i); println("XPath.parseMatch(\"" + pattern + "\").getPattern(),"); } popDepth(); println("};"); popDepth(); println("} catch (Exception e) {"); println(" e.printStackTrace();"); println("}"); popDepth(); println("}"); } private boolean isSingleStylesheet() { // return stylesheets.size() < 2; return false; } /** * Prints a character to the generated Java. */ private void print(char ch) throws IOException { _out.print(ch); } /** * Prints a string to the generated Java. */ private void print(String string) throws IOException { _out.print(string); } /** * Prints an integer to the generated Java. */ private void print(int i) throws IOException { _out.print(i); } /** * Prints a new line. */ private void println() throws IOException { _out.println(); } private void println(char ch) throws IOException { _out.println(ch); } private void println(String s) throws IOException { _out.println(s); } /** * Pushes the pretty-printed depth of the generated java. */ private void pushDepth() throws IOException { _out.pushDepth(); } /** * Pops the pretty-printed depth of the generated java. */ private void popDepth() throws IOException { _out.popDepth(); } /** * Prints the contents of a string, taking care of escapes. */ protected void printString(String str) throws IOException { _out.printJavaString(str); } /** * Returns the name of the applyNode method. * * @param mode the template's mode. */ public String getModeName(String mode) { if (mode != null && ! _modes.contains(mode)) _modes.add(mode); if (mode == null || mode.equals("")) return ""; else return "_" + toJavaIdentifier(mode); } public void addMode(String mode) { if (! _modes.contains(mode)) _modes.add(mode); } public int addStylesheet(String filename) { int pos = _stylesheets.indexOf(filename); if (pos < 0) { pos = _stylesheets.size(); _stylesheets.add(filename); } return pos; } /** * Converts a string to a Java identifier, encoding unknown characters * as "_" */ public String toJavaIdentifier(String name) { CharBuffer cb = new CharBuffer(); char ch = name.charAt(0); if (Character.isJavaIdentifierStart(ch)) cb.append(ch); else cb.append("_"); for (int i = 1; i < name.length(); i++) { ch = name.charAt(i); if (Character.isJavaIdentifierPart(ch)) cb.append(ch); else { cb.append("_"); cb.append((char) ((ch & 0xf) + 'a')); cb.append((char) ((ch / 16 & 0xf) + 'a')); } } return cb.toString(); } /** * Close call when an error occurs. */ public void close() throws IOException { if (_s != null) _s.close(); } static class Macro { String _name; Element _elt; Macro(String name, Element elt) { _name = name; _elt = elt; } public Element getElement() { return _elt; } public String getName() { return _name; } } static { _tagMap = new HashMap<QName,Class>(); _tagMap.put(new QName("xsl", "attribute", XSLNS), XslAttribute.class); _tagMap.put(new QName("xsl", "attribute-set", XSLNS), XslAttributeSet.class); _tagMap.put(new QName("xsl", "apply-imports", XSLNS), XslApplyImports.class); _tagMap.put(new QName("xsl", "apply-templates", XSLNS), XslApplyTemplates.class); _tagMap.put(new QName("xsl", "call-template", XSLNS), XslCallTemplate.class); _tagMap.put(new QName("xsl", "choose", XSLNS), XslChoose.class); _tagMap.put(new QName("xsl", "comment", XSLNS), XslComment.class); _tagMap.put(new QName("xsl", "copy", XSLNS), XslCopy.class); _tagMap.put(new QName("xsl", "copy-of", XSLNS), XslCopyOf.class); _tagMap.put(new QName("xsl", "decimal-format", XSLNS), XslDecimalFormat.class); _tagMap.put(new QName("xsl", "element", XSLNS), XslElement.class); _tagMap.put(new QName("xsl", "for-each", XSLNS), XslForEach.class); _tagMap.put(new QName("xsl", "if", XSLNS), XslIf.class); _tagMap.put(new QName("xsl", "import", XSLNS), XslImport.class); _tagMap.put(new QName("xsl", "include", XSLNS), XslInclude.class); _tagMap.put(new QName("xsl", "key", XSLNS), XslKey.class); _tagMap.put(new QName("xsl", "message", XSLNS), XslMessage.class); _tagMap.put(new QName("xsl", "namespace-alias", XSLNS), XslNamespaceAlias.class); _tagMap.put(new QName("xsl", "number", XSLNS), XslNumber.class); _tagMap.put(new QName("xsl", "otherwise", XSLNS), XslOtherwise.class); _tagMap.put(new QName("xsl", "output", XSLNS), XslOutput.class); _tagMap.put(new QName("xsl", "param", XSLNS), XslParam.class); _tagMap.put(new QName("xsl", "processing-instruction", XSLNS), XslProcessingInstruction.class); _tagMap.put(new QName("xsl", "sort", XSLNS), XslSort.class); _tagMap.put(new QName("xsl", "stylesheet", XSLNS), XslStylesheet.class); _tagMap.put(new QName("xsl", "text", XSLNS), XslText.class); _tagMap.put(new QName("xsl", "transform", XSLNS), XslTransform.class); _tagMap.put(new QName("xsl", "value-of", XSLNS), XslValueOf.class); _tagMap.put(new QName("xsl", "variable", XSLNS), XslVariable.class); _tagMap.put(new QName("xsl", "when", XSLNS), XslWhen.class); _tagMap.put(new QName("xsl", "with-param", XSLNS), XslWithParam.class); _tagMap.put(new QName("xsl", "template", XSLNS), XslTemplate.class); _tagMap.put(new QName("xsl", "strip-space", XSLNS), XslStripSpace.class); _tagMap.put(new QName("xsl", "preserve-space", XSLNS), XslPreserveSpace.class); _tagMap.put(new QName("xsl", "result-document", XSLNS), XslResultDocument.class); _tagMap.put(new QName("xtp", "expression", XTPNS), XtpExpression.class); _tagMap.put(new QName("xtp:expression", null), XtpExpression.class); _tagMap.put(new QName("xtp", "eval", XTPNS), XtpExpression.class); _tagMap.put(new QName("xtp:eval", null), XtpExpression.class); _tagMap.put(new QName("xtp", "expr", XTPNS), XtpExpression.class); _tagMap.put(new QName("xtp:expr", null), XtpExpression.class); _tagMap.put(new QName("xtp", "scriptlet", XTPNS), XtpScriptlet.class); _tagMap.put(new QName("xtp:scriptlet", null), XtpScriptlet.class); _tagMap.put(new QName("xtp", "declaration", XTPNS), XtpDeclaration.class); _tagMap.put(new QName("xtp", "decl", XTPNS), XtpDeclaration.class); _tagMap.put(new QName("xtp:declaration", null), XtpDeclaration.class); _tagMap.put(new QName("xtp:decl", null), XtpDeclaration.class); _tagMap.put(new QName("xtp:directive.page", null), XtpDirectivePage.class); _tagMap.put(new QName("xtp", "directive.page", XTPNS), XtpDirectivePage.class); _tagMap.put(new QName("xtp:directive.cache", null), XtpDirectiveCache.class); _tagMap.put(new QName("xtp", "directive.cache", XTPNS), XtpDirectiveCache.class); _tagMap.put(new QName("xtp:assign", null), XslVariable.class); _tagMap.put(new QName("xtp", "assign", XTPNS), XslVariable.class); } }