Source Code Cross Referenced for Generator.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » xsl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » resin » com.caucho.xsl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *   Free SoftwareFoundation, Inc.
0023:         *   59 Temple Place, Suite 330
0024:         *   Boston, MA 02111-1307  USA
0025:         *
0026:         * @author Scott Ferguson
0027:         */
0028:
0029:        package com.caucho.xsl;
0030:
0031:        import com.caucho.java.JavaWriter;
0032:        import com.caucho.java.LineMap;
0033:        import com.caucho.log.Log;
0034:        import com.caucho.util.CharBuffer;
0035:        import com.caucho.util.CharScanner;
0036:        import com.caucho.util.IntArray;
0037:        import com.caucho.util.IntMap;
0038:        import com.caucho.util.L10N;
0039:        import com.caucho.util.StringCharCursor;
0040:        import com.caucho.vfs.Path;
0041:        import com.caucho.vfs.ReadStream;
0042:        import com.caucho.xml.CauchoDocument;
0043:        import com.caucho.xml.QAbstractNode;
0044:        import com.caucho.xml.QElement;
0045:        import com.caucho.xml.QName;
0046:        import com.caucho.xml.Xml;
0047:        import com.caucho.xml.XmlChar;
0048:        import com.caucho.xpath.Expr;
0049:        import com.caucho.xpath.NamespaceContext;
0050:        import com.caucho.xpath.XPath;
0051:        import com.caucho.xpath.pattern.AbstractPattern;
0052:        import com.caucho.xpath.pattern.UnionPattern;
0053:        import com.caucho.xsl.fun.FormatNumberFun;
0054:        import com.caucho.xsl.fun.KeyFun;
0055:        import com.caucho.xsl.java.XslAttributeSet;
0056:        import com.caucho.xsl.java.XslNode;
0057:        import com.caucho.xsl.java.XslStylesheet;
0058:        import com.caucho.xsl.java.XslTemplate;
0059:
0060:        import org.w3c.dom.Attr;
0061:        import org.w3c.dom.Document;
0062:        import org.w3c.dom.DocumentType;
0063:        import org.w3c.dom.Element;
0064:        import org.w3c.dom.Node;
0065:        import org.w3c.dom.Text;
0066:
0067:        import java.io.FileNotFoundException;
0068:        import java.io.IOException;
0069:        import java.text.DecimalFormatSymbols;
0070:        import java.util.ArrayList;
0071:        import java.util.HashMap;
0072:        import java.util.Iterator;
0073:        import java.util.logging.Level;
0074:        import java.util.logging.Logger;
0075:
0076:        /**
0077:         * Base class for generating code from an XSL tree.  JavaGenerator and
0078:         * JavaScriptGenerator extend this class for language-specific code
0079:         * generation.
0080:         */
0081:        abstract class Generator {
0082:            private static final Logger log = Log.open(Generator.class);
0083:            protected static final L10N L = new L10N(Generator.class);
0084:
0085:            public static final String XSLNS = "http://www.w3.org/1999/XSL/Transform";
0086:            public static final String XTPNS = "http://www.caucho.com/XTP/1.0";
0087:
0088:            private static final int STYLESHEET = 0;
0089:            private static final int OUTPUT = STYLESHEET + 1;
0090:            private static final int IMPORT = OUTPUT + 1;
0091:            private static final int INCLUDE = IMPORT + 1;
0092:            private static final int TEMPLATE = INCLUDE + 1;
0093:            private static final int STRIP_SPACE = TEMPLATE + 1;
0094:            private static final int PRESERVE_SPACE = STRIP_SPACE + 1;
0095:            private static final int KEY = PRESERVE_SPACE + 1;
0096:            private static final int LOCALE = KEY + 1;
0097:            private static final int ATTRIBUTE_SET = LOCALE + 1;
0098:            private static final int NAMESPACE_ALIAS = ATTRIBUTE_SET + 1;
0099:
0100:            private static final int APPLY_TEMPLATES = NAMESPACE_ALIAS + 1;
0101:            private static final int APPLY_IMPORTS = APPLY_TEMPLATES + 1;
0102:            private static final int CALL_TEMPLATE = APPLY_IMPORTS + 1;
0103:            private static final int PARAM = CALL_TEMPLATE + 1;
0104:            private static final int VARIABLE = PARAM + 1;
0105:            private static final int VALUE_OF = VARIABLE + 1;
0106:            private static final int COPY_OF = VALUE_OF + 1;
0107:            private static final int FOR_EACH = COPY_OF + 1;
0108:            private static final int IF = FOR_EACH + 1;
0109:            private static final int CHOOSE = IF + 1;
0110:
0111:            private static final int TEXT = CHOOSE + 1;
0112:            private static final int XSL_TEXT = TEXT + 1;
0113:            private static final int NUMBER = XSL_TEXT + 1;
0114:            private static final int COPY = NUMBER + 1;
0115:            private static final int COPY_ELEMENT = COPY + 1;
0116:            private static final int ELEMENT = COPY_ELEMENT + 1;
0117:            private static final int ATTRIBUTE = ELEMENT + 1;
0118:            private static final int PI = ATTRIBUTE + 1;
0119:            private static final int COMMENT = PI + 1;
0120:
0121:            private static final int MESSAGE = COMMENT + 1;
0122:
0123:            private static final int EXPRESSION = MESSAGE + 1;
0124:            private static final int SCRIPTLET = EXPRESSION + 1;
0125:            private static final int DECLARATION = SCRIPTLET + 1;
0126:            private static final int DIRECTIVE_CACHE = DECLARATION + 1;
0127:            private static final int DIRECTIVE_PAGE = DIRECTIVE_CACHE + 1;
0128:            private static final int WHILE = DIRECTIVE_PAGE + 1;
0129:
0130:            private static final int ASSIGN = WHILE + 1;
0131:            private static final int IGNORE = ASSIGN + 1;
0132:
0133:            // xslt 2.0
0134:            private static final int RESULT_DOCUMENT = IGNORE + 1;
0135:
0136:            private static IntMap _tags;
0137:            private static IntMap _xtpTags;
0138:            private String _version = "1.0";
0139:
0140:            String _xslName;
0141:            // the root context
0142:            Path _topContext;
0143:            // the pwd for the file
0144:            Path _baseURL;
0145:            Path _context;
0146:            CharBuffer _text;
0147:            HashMap<String, String> _names = new HashMap<String, String>();
0148:            int _loopDepth;
0149:            Path _workPath;
0150:            int _uniqueId;
0151:
0152:            protected HashMap<String, String> _preserve = new HashMap<String, String>();
0153:            protected HashMap<String, String> _strip = new HashMap<String, String>();
0154:
0155:            HashMap<String, XslAttributeSet> _attributeSets = new HashMap<String, XslAttributeSet>();
0156:
0157:            protected HashMap<String, String[]> _namespaceAliases = new HashMap<String, String[]>();
0158:            protected HashMap<String, String> _excludedNamespaces = new HashMap<String, String>();
0159:            protected KeyFun _keyFun;
0160:            protected FormatNumberFun _formatNumberFun;
0161:
0162:            protected NamespaceContext _namespace;
0163:            protected ArrayList _globalActions = new ArrayList();
0164:            protected ArrayList<String> _globalParameters = new ArrayList<String>();
0165:
0166:            protected Document _doc;
0167:            protected CauchoDocument _qDoc;
0168:
0169:            protected Path _path;
0170:
0171:            boolean _lineContent;
0172:            int _lineWs;
0173:            String _systemId;
0174:            String _filename;
0175:            int _line;
0176:            protected LineMap _lineMap;
0177:            private ArrayList _frags;
0178:            protected int _destLine = 1;
0179:            boolean _defaultCacheable = true;
0180:            boolean _isCacheable;
0181:            protected String _encoding;
0182:
0183:            HashMap<String, ArrayList<Template>> _templates = new HashMap<String, ArrayList<Template>>();
0184:            int _minImportance; // for included files, the minimum importance
0185:            int _importance;
0186:            int _templateCount;
0187:            private IntArray _vars = new IntArray();
0188:            private ArrayList<XslNode> _inits = new ArrayList<XslNode>();
0189:            protected ArrayList<Path> _depends = new ArrayList<Path>();
0190:            protected ArrayList<String> _cacheDepends = new ArrayList<String>();
0191:
0192:            private boolean _isCauchoXsl;
0193:            protected boolean _isRawText;
0194:            protected String _errorPage;
0195:            boolean _hasSession;
0196:            protected AbstractPattern _nodeListContext;
0197:            private boolean _isTop;
0198:            private ClassLoader _loader;
0199:
0200:            protected boolean _isSpecial;
0201:            protected boolean _isStyleScript;
0202:
0203:            HashMap<String, String> _outputAttributes = new HashMap<String, String>();
0204:            HashMap<String, String> _macros;
0205:            HashMap<String, Document> _files;
0206:
0207:            protected AbstractStylesheetFactory _xslGenerator;
0208:
0209:            protected ArrayList<String> _imports = new ArrayList<String>();
0210:
0211:            Generator(AbstractStylesheetFactory xslGenerator) {
0212:                _xslGenerator = xslGenerator;
0213:
0214:                _workPath = xslGenerator.getWorkPath();
0215:
0216:                Path path = xslGenerator.getStylePath();
0217:
0218:                _context = path;
0219:                _topContext = _context;
0220:                _loader = xslGenerator.getClassLoader();
0221:                if (_loader == null)
0222:                    _loader = Thread.currentThread().getContextClassLoader();
0223:
0224:                _text = new CharBuffer();
0225:                _frags = new ArrayList();
0226:                _macros = new HashMap<String, String>();
0227:
0228:                _keyFun = new KeyFun();
0229:                _formatNumberFun = new FormatNumberFun();
0230:            }
0231:
0232:            void init(String filename) {
0233:                _lineMap = new LineMap(filename);
0234:            }
0235:
0236:            public void setErrorPage(String errorPage) {
0237:                _errorPage = errorPage;
0238:            }
0239:
0240:            public void setStyleScript(boolean stylescript) {
0241:                _isStyleScript = stylescript;
0242:            }
0243:
0244:            /**
0245:             * Adds a Java import to the generated stylesheet.
0246:             */
0247:            public void addImport(String pkg) {
0248:                if (!_imports.contains(pkg))
0249:                    _imports.add(pkg);
0250:            }
0251:
0252:            public void setContentType(String type) {
0253:                // contentType = type;
0254:            }
0255:
0256:            void setPath(Path path) {
0257:                _path = path;
0258:                _context = path;
0259:            }
0260:
0261:            void setWorkPath(Path path) {
0262:                _workPath = path;
0263:            }
0264:
0265:            public int getMinImportance() {
0266:                return _minImportance;
0267:            }
0268:
0269:            public int getMaxImportance() {
0270:                return _importance;
0271:            }
0272:
0273:            public NamespaceContext getNamespace() {
0274:                return _namespace;
0275:            }
0276:
0277:            public AbstractPattern getNodeListContext() {
0278:                return _nodeListContext;
0279:            }
0280:
0281:            public void addLocale(String name, DecimalFormatSymbols format) {
0282:                _formatNumberFun.addLocale(name, format);
0283:            }
0284:
0285:            /**
0286:             * Generates a uniqueId
0287:             */
0288:            public int uniqueId() {
0289:                return _uniqueId++;
0290:            }
0291:
0292:            /**
0293:             * Starts the generation from the top of the document.
0294:             *
0295:             * @param xsl the stylesheet document.
0296:             */
0297:            public StylesheetImpl generate(Node node) throws Exception {
0298:                Document xsl = node.getOwnerDocument();
0299:                if (xsl == null)
0300:                    xsl = (Document) node;
0301:
0302:                DocumentType dtd = xsl.getDoctype();
0303:
0304:                if (dtd != null && dtd.getSystemId() != null) {
0305:                    _context = _path.lookup(dtd.getSystemId());
0306:                    _topContext = _context;
0307:                }
0308:
0309:                Element top = (Element) xsl.getDocumentElement();
0310:
0311:                if (top == null)
0312:                    throw error(xsl, L.l("xsl:stylesheet must be top element."));
0313:
0314:                _doc = xsl;
0315:                if (_doc instanceof  CauchoDocument)
0316:                    _qDoc = (CauchoDocument) _doc;
0317:
0318:                QElement qTop = null;
0319:                if (top instanceof  QElement)
0320:                    qTop = (QElement) top;
0321:
0322:                /*
0323:                if (qTop != null && qTop.getFilename() != null)
0324:                  context = topContext.lookup(qTop.getFilename()).getParent();
0325:                 */
0326:
0327:                _isTop = true;
0328:                _files = new HashMap<String, Document>();
0329:                scanFiles(top);
0330:
0331:                if (_qDoc != null) {
0332:                    ArrayList depends = (ArrayList) _qDoc
0333:                            .getProperty(CauchoDocument.DEPENDS);
0334:                    for (int i = 0; depends != null && i < depends.size(); i++) {
0335:                        Path path = (Path) depends.get(i);
0336:                        addDepend(path);
0337:                    }
0338:                } else {
0339:                    addDepend(_path);
0340:                }
0341:
0342:                if ("stylesheet".equals(getXslLocal(top))
0343:                        || "transform".equals(getXslLocal(top))) {
0344:                    generateStylesheet(top, true);
0345:                } else {
0346:                    // literal result element
0347:                    printHeader();
0348:                    boolean oldCacheable = _isCacheable;
0349:                    boolean oldDefaultCacheable = _defaultCacheable;
0350:                    _isCacheable = true;
0351:
0352:                    XslNode literal = createChild(top);
0353:
0354:                    XslTemplate template = new XslTemplate();
0355:                    template.setGenerator((JavaGenerator) this );
0356:                    template.addAttribute(new QName("match"), "/");
0357:                    template.addChild(literal);
0358:
0359:                    template.generateDeclaration(getOut());
0360:
0361:                    template.generate(getOut());
0362:
0363:                    // printTemplate(top, null, "/", null, 0.0/0.0);
0364:
0365:                    _isCacheable = oldCacheable;
0366:                    _defaultCacheable = oldDefaultCacheable;
0367:                }
0368:
0369:                addNamespace(top);
0370:                StylesheetImpl stylesheet = completeGenerate(_inits,
0371:                        _globalActions);
0372:
0373:                return stylesheet;
0374:            }
0375:
0376:            private static CharScanner commaDelimScanner = new CharScanner(
0377:                    " \t\n\r,");
0378:
0379:            /**
0380:             * Scan the stylesheet for imported packages and files.  The imported
0381:             * stylesheets will be read and stored in the 'files' HashMap for when
0382:             * they're actually needed.
0383:             */
0384:            private void scanFiles(Element top) throws XslParseException,
0385:                    IOException {
0386:                _isCauchoXsl = !top.getAttribute("xsl-caucho").equals("");
0387:
0388:                Iterator iter;
0389:                try {
0390:                    iter = XPath.select("//xtp:directive.page/@*", top);
0391:                } catch (Exception e) {
0392:                    throw new XslParseException(e);
0393:                }
0394:                while (iter.hasNext()) {
0395:                    Attr attr = (Attr) iter.next();
0396:                    String name = attr.getNodeName();
0397:                    String value = attr.getNodeValue();
0398:
0399:                    if (name.equals("import")) {
0400:                        StringCharCursor cursor = new StringCharCursor(value);
0401:                        CharBuffer cb = new CharBuffer();
0402:                        while (cursor.current() != cursor.DONE) {
0403:                            char ch;
0404:                            commaDelimScanner.skip(cursor);
0405:
0406:                            cb.clear();
0407:                            ch = commaDelimScanner.scan(cursor, cb);
0408:
0409:                            if (cb.length() != 0) {
0410:                                addImport(cb.toString());
0411:                            } else if (ch != cursor.DONE)
0412:                                throw new IOException(L
0413:                                        .l("illegal `import' directive"));
0414:                        }
0415:                    }
0416:                }
0417:
0418:                try {
0419:                    iter = XPath.select("//xsl:import|xsl:include", top);
0420:                } catch (Exception e) {
0421:                    throw new XslParseException(e);
0422:                }
0423:                while (iter.hasNext()) {
0424:                    Element elt = (Element) iter.next();
0425:                    String href = elt.getAttribute("href");
0426:
0427:                    ReadStream rs;
0428:
0429:                    try {
0430:                        rs = _xslGenerator.openPath(href, _context.getURL());
0431:                    } catch (Exception e) {
0432:                        throw new XslParseException(e);
0433:                    }
0434:
0435:                    Path path = rs.getPath();
0436:
0437:                    Document xsl = readXsl(rs);
0438:                    Element subtop = xsl.getDocumentElement();
0439:
0440:                    if (subtop == null)
0441:                        throw error(elt, L.l("xsl:import file {0} is empty",
0442:                                path.getFullPath()));
0443:
0444:                    Path oldContext = _context;
0445:
0446:                    Path virtualPath = _context.getParent().lookup(href);
0447:                    _context = virtualPath;
0448:
0449:                    _files.put(virtualPath.getPath(), xsl);
0450:
0451:                    scanFiles(subtop);
0452:                    _context = oldContext;
0453:                }
0454:            }
0455:
0456:            public void addImportList(String value) throws XslParseException {
0457:                StringCharCursor cursor = new StringCharCursor(value);
0458:                CharBuffer cb = new CharBuffer();
0459:                while (cursor.current() != cursor.DONE) {
0460:                    char ch;
0461:                    commaDelimScanner.skip(cursor);
0462:
0463:                    cb.clear();
0464:                    ch = commaDelimScanner.scan(cursor, cb);
0465:
0466:                    if (cb.length() != 0) {
0467:                        addImport(cb.toString());
0468:                    } else if (ch != cursor.DONE)
0469:                        throw error(L.l("illegal `import' directive"));
0470:                }
0471:            }
0472:
0473:            /**
0474:             * Read in an imported or included XSL file.
0475:             *
0476:             * @param path Path to the include files.
0477:             *
0478:             * @return XML tree describing the XSL.
0479:             */
0480:            Document readXsl(Path path) throws IOException, XslParseException {
0481:                return readXsl(path.openRead());
0482:            }
0483:
0484:            /**
0485:             * Read in an imported or included XSL file.
0486:             *
0487:             * @param path Path to the include files.
0488:             *
0489:             * @return XML tree describing the XSL.
0490:             */
0491:            Document readXsl(ReadStream file) throws IOException,
0492:                    XslParseException {
0493:                try {
0494:                    addDepend(file.getPath());
0495:
0496:                    if (_isStyleScript) {
0497:                        XslParser parser = new XslParser();
0498:
0499:                        return parser.parse(file);
0500:                    } else
0501:                        return new Xml().parseDocument(file);
0502:                } catch (org.xml.sax.SAXException e) {
0503:                    throw new XslParseException(e);
0504:                } finally {
0505:                    file.close();
0506:                }
0507:            }
0508:
0509:            /**
0510:             * Start the top-level stylesheet generation.
0511:             */
0512:            private void generateStylesheet(Element elt, boolean isTop)
0513:                    throws Exception {
0514:                QElement element = (QElement) elt;
0515:                _isCauchoXsl = !element.getAttribute("xsl-caucho").equals("");
0516:
0517:                String systemId = element.getBaseURI();
0518:                Path oldContext = _context;
0519:
0520:                if (systemId != null)
0521:                    _context = _context.lookup(systemId);
0522:
0523:                XslNode stylesheet = createChild(element);
0524:
0525:                addNamespace(element);
0526:
0527:                if (isTop)
0528:                    printHeader();
0529:
0530:                stylesheet.generateDeclaration(getOut());
0531:
0532:                stylesheet.generate(getOut());
0533:
0534:                _context = oldContext;
0535:
0536:                /*
0537:                _version = element.getAttribute("version");
0538:                if (_version.equals(""))
0539:                  _version = "1.0";
0540:                
0541:                // generateAttributeSets(element);
0542:
0543:                excludeNamespaces(element);
0544:
0545:                String xslSpace = element.getAttribute("xsl-space");
0546:                ArrayList<XslNode> children = new ArrayList<XslNode>();
0547:                for (Node child = element.getFirstChild();
0548:                 child != null;
0549:                 child = child.getNextSibling()) {
0550:                  if (! (child instanceof Element))
0551:                    continue;
0552:                  
0553:                  int code = -1;
0554:                  String name = getXslLocal(child);
0555:                  if (name != null)
0556:                code = _tags.get(name);
0557:                  else if ((name = getXtpLocal(child)) != null)
0558:                code = _xtpTags.get(name);
0559:                  else {
0560:                    String childName = child.getNodeName();
0561:                    
0562:                    if (childName.startsWith("jsp:directive.") ||
0563:                        childName.equals("jsp:declaration") ||
0564:                        childName.equals("jsp:scriptlet"))
0565:                      addGlobalAction((Element) child);
0566:                continue;
0567:                  }
0568:
0569:                  NamespaceContext oldNamespace = addNamespace((Element) child);
0570:                  // generateTopLevelNode(code, (Element) child);
0571:                  XslNode node = createChild(child);
0572:
0573:                  children.add(node);
0574:                  _namespace = oldNamespace;
0575:                }
0576:
0577:                for (int i = 0; i < children.size(); i++) {
0578:                  XslNode node = children.get(i);
0579:                  
0580:                  node.generate(getOut());
0581:                }
0582:                 */
0583:            }
0584:
0585:            abstract protected JavaWriter getOut();
0586:
0587:            abstract protected XslNode createChild(Node child) throws Exception;
0588:
0589:            abstract protected XslNode createChild(XslNode parent, Node child)
0590:                    throws Exception;
0591:
0592:            private void addGlobalAction(Element elt) {
0593:                _globalActions.add(elt);
0594:            }
0595:
0596:            /**
0597:             * Converts the exclude-result-prefixes into the "excludedNamespaces"
0598:             * hashMap for later use.
0599:             */
0600:            private void excludeNamespaces(Element element) throws Exception {
0601:                if (!(element instanceof  QElement))
0602:                    return;
0603:
0604:                QElement elt = (QElement) element;
0605:                String excludeNamespace;
0606:                excludeNamespace = element
0607:                        .getAttribute("exclude-result-prefixes");
0608:                if (!excludeNamespace.equals("")) {
0609:                    for (String prefix : excludeNamespace.split("[,\\s]+")) {
0610:
0611:                        String ns = elt.getNamespace(prefix);
0612:                        if (ns == null)
0613:                            throw error(elt, L.l(
0614:                                    "`{0}' must be a namespace prefix", prefix));
0615:                        _excludedNamespaces.put(ns, "");
0616:                    }
0617:                }
0618:            }
0619:
0620:            public void addExcludedNamespace(String ns) {
0621:                _excludedNamespaces.put(ns, "");
0622:            }
0623:
0624:            public void addInit(XslNode node) {
0625:                _inits.add(node);
0626:            }
0627:
0628:            public void addGlobalParameter(String param) {
0629:                _globalParameters.add(param);
0630:            }
0631:
0632:            /**
0633:             * Adds a file dependency for cacheable references to the output of
0634:             * the stylesheet.
0635:             */
0636:            private void addCacheDepends(String attr) {
0637:                if (attr.equals(""))
0638:                    return;
0639:
0640:                int i = 0;
0641:                int ch = 0;
0642:                int len = attr.length();
0643:                for (; i < len && XmlChar.isWhitespace((ch = attr.charAt(i)))
0644:                        || ch == ','; i++) {
0645:                }
0646:                CharBuffer cb = new CharBuffer();
0647:                while (i < len) {
0648:                    cb.clear();
0649:                    for (; i < len
0650:                            && !XmlChar.isWhitespace((ch = attr.charAt(i)))
0651:                            && ch != ','; i++) {
0652:                        cb.append((char) ch);
0653:                    }
0654:
0655:                    _cacheDepends.add(cb.toString());
0656:
0657:                    for (; i < len
0658:                            && XmlChar.isWhitespace((ch = attr.charAt(i)))
0659:                            || ch == ','; i++) {
0660:                    }
0661:                }
0662:            }
0663:
0664:            private void generateCacheDepends(String attr) throws Exception {
0665:                if (attr.equals(""))
0666:                    return;
0667:
0668:                int i = 0;
0669:                int ch = 0;
0670:                int len = attr.length();
0671:                for (; i < len && XmlChar.isWhitespace((ch = attr.charAt(i)))
0672:                        || ch == ','; i++) {
0673:                }
0674:                CharBuffer cb = new CharBuffer();
0675:                while (i < len) {
0676:                    cb.clear();
0677:                    for (; i < len
0678:                            && !XmlChar.isWhitespace((ch = attr.charAt(i)))
0679:                            && ch != ','; i++) {
0680:                        cb.append((char) ch);
0681:                    }
0682:
0683:                    printCacheDepends(cb.toString());
0684:
0685:                    for (; i < len
0686:                            && XmlChar.isWhitespace((ch = attr.charAt(i)))
0687:                            || ch == ','; i++) {
0688:                    }
0689:                }
0690:            }
0691:
0692:            /**
0693:             * Generate code for xsl:template
0694:             */
0695:            void generateTemplate(Element element) throws Exception {
0696:                String name = element.getAttribute("name");
0697:                String patternString = element.getAttribute("match");
0698:                String mode = element.getAttribute("mode");
0699:                String priority = element.getAttribute("priority");
0700:                double dPriority = 0.0 / 0.0;
0701:
0702:                if (!name.equals(""))
0703:                    _macros.put(name, name);
0704:
0705:                if (name.equals("") && patternString.equals(""))
0706:                    throw error("xsl:template expects a `name' or a `match' attribute.");
0707:
0708:                if (!priority.equals("")) {
0709:                    try {
0710:                        dPriority = Double.valueOf(priority).doubleValue();
0711:                    } catch (Exception e) {
0712:                        throw error("xsl:template expects `priority' must be a double.");
0713:                    }
0714:                }
0715:
0716:                boolean oldCacheable = _isCacheable;
0717:                boolean oldDefaultCacheable = _defaultCacheable;
0718:                AbstractPattern oldNodeListContext = _nodeListContext;
0719:                if (!patternString.equals(""))
0720:                    _nodeListContext = parseMatch(patternString);
0721:
0722:                _isCacheable = true;
0723:                printTemplate(element, name, patternString, mode, dPriority);
0724:                _nodeListContext = oldNodeListContext;
0725:                _isCacheable = oldCacheable;
0726:                _defaultCacheable = oldDefaultCacheable;
0727:            }
0728:
0729:            public XslNode generateImport(String href) throws Exception {
0730:                Path path = lookupPath(href);
0731:
0732:                if (_files.get(path.getPath()) != null)
0733:                    return null;
0734:
0735:                Document xsl = readFile(href, path);
0736:
0737:                if (xsl == null)
0738:                    throw new FileNotFoundException(href);
0739:
0740:                QElement top = (QElement) xsl.getDocumentElement();
0741:                if (top == null || !"stylesheet".equals(getXslLocal(top))
0742:                        && !"transform".equals(getXslLocal(top))) {
0743:                    throw error("imported stylesheet `" + href
0744:                            + "' missing xsl:stylesheet.");
0745:                }
0746:
0747:                int oldMinImportance = _minImportance;
0748:                Path oldContext = _context;
0749:                Path virtualPath = _context.getParent().lookup(href);
0750:                _context = virtualPath;
0751:                _minImportance = _importance;
0752:                boolean oldTop = _isTop;
0753:                boolean oldRaw = _isRawText;
0754:                _isTop = false;
0755:                _isRawText = false;
0756:
0757:                String systemId = top.getBaseURI();
0758:
0759:                if (systemId != null)
0760:                    _context = _context.lookup(systemId);
0761:
0762:                XslStylesheet stylesheet = (XslStylesheet) createChild(top);
0763:
0764:                _isRawText = oldRaw;
0765:                _isTop = oldTop;
0766:                _minImportance = oldMinImportance;
0767:                _context = oldContext;
0768:
0769:                incrementImportance();
0770:
0771:                return stylesheet;
0772:            }
0773:
0774:            /**
0775:             * Generates code for xsl:include.  The included file has the same
0776:             * importance as the containing file.
0777:             */
0778:            void generateInclude(Element element) throws Exception {
0779:                String href = element.getAttribute("href");
0780:                if (href.equals(""))
0781:                    throw error("xsl:include expects `href' attribute.");
0782:
0783:                if (element.getFirstChild() != null)
0784:                    throw error("xsl:include must be empty");
0785:            }
0786:
0787:            public void generateInclude(XslNode parent, String href)
0788:                    throws Exception {
0789:                Path path = lookupPath(href);
0790:
0791:                if (_files.get(path.getPath()) != null)
0792:                    return;
0793:
0794:                Document xsl = readFile(href, path);
0795:
0796:                Element top = (Element) xsl.getDocumentElement();
0797:                if (top == null || !"stylesheet".equals(getXslLocal(top))
0798:                        && !"transform".equals(getXslLocal(top))) {
0799:                    throw error("imported stylesheet `" + href
0800:                            + "' missing xsl:stylesheet.");
0801:                }
0802:
0803:                Path oldContext = _context;
0804:                _context = path;
0805:
0806:                for (Node node = top.getFirstChild(); node != null; node = node
0807:                        .getNextSibling()) {
0808:                    XslNode child = createChild(parent, node);
0809:
0810:                    if (child != null)
0811:                        parent.addChild(child);
0812:                }
0813:
0814:                // generateStylesheet(top, false);
0815:
0816:                _context = oldContext;
0817:            }
0818:
0819:            /**
0820:             * Returns the actual path for the relative href.
0821:             */
0822:            private Path lookupPath(String href) {
0823:                return _context.getParent().lookup(href);
0824:            }
0825:
0826:            private Document readFile(String href, Path virtualPath)
0827:                    throws Exception {
0828:                Document xsl = (Document) _files.get(virtualPath.getPath());
0829:
0830:                if (xsl != null)
0831:                    throw new IllegalStateException(L
0832:                            .l("'{0}' is a duplicated path", virtualPath
0833:                                    .getPath()));
0834:
0835:                ReadStream rs;
0836:
0837:                try {
0838:                    rs = _xslGenerator.openPath(href, _context.getURL());
0839:                } catch (Exception e) {
0840:                    throw new XslParseException(e);
0841:                }
0842:
0843:                Path path = rs.getPath();
0844:
0845:                xsl = readXsl(rs);
0846:                Element subtop = xsl.getDocumentElement();
0847:
0848:                if (subtop == null)
0849:                    throw error(L.l("xsl:import file {0} is empty", path
0850:                            .getFullPath()));
0851:
0852:                Path oldContext = _context;
0853:
0854:                _context = virtualPath;
0855:
0856:                _files.put(virtualPath.getPath(), xsl);
0857:
0858:                _context = oldContext;
0859:
0860:                return xsl;
0861:            }
0862:
0863:            void generateKey(Element element) throws Exception {
0864:                String name = element.getAttribute("name");
0865:                if (name.equals(""))
0866:                    throw error("xsl:key expects `name' attribute.");
0867:                String match = element.getAttribute("match");
0868:                if (match.equals(""))
0869:                    throw error("xsl:key expects `match' attribute.");
0870:                String use = element.getAttribute("use");
0871:                if (use.equals(""))
0872:                    throw error("xsl:key expects `use' attribute.");
0873:
0874:                if (element.getFirstChild() != null)
0875:                    throw error("xsl:key must be empty");
0876:
0877:                _keyFun.add(name, parseMatch(match), parseExpr(use));
0878:            }
0879:
0880:            public void addKey(String name, AbstractPattern match, Expr use) {
0881:                _keyFun.add(name, match, use);
0882:            }
0883:
0884:            void generateLocale(Element element) throws Exception {
0885:                String name = element.getAttribute("name");
0886:                if (name.equals(""))
0887:                    name = "*";
0888:
0889:                DecimalFormatSymbols format = new DecimalFormatSymbols();
0890:
0891:                String value = element.getAttribute("decimal-separator");
0892:                if (value.length() > 0)
0893:                    format.setDecimalSeparator(value.charAt(0));
0894:
0895:                value = element.getAttribute("grouping-separator");
0896:                if (value.length() > 0)
0897:                    format.setGroupingSeparator(value.charAt(0));
0898:
0899:                value = element.getAttribute("infinity");
0900:                if (!value.equals(""))
0901:                    format.setInfinity(value);
0902:
0903:                value = element.getAttribute("minus-sign");
0904:                if (value.length() > 0)
0905:                    format.setMinusSign(value.charAt(0));
0906:
0907:                value = element.getAttribute("NaN");
0908:                if (!value.equals(""))
0909:                    format.setNaN(value);
0910:
0911:                value = element.getAttribute("percent");
0912:                if (value.length() > 0)
0913:                    format.setPercent(value.charAt(0));
0914:
0915:                value = element.getAttribute("per-mille");
0916:                if (value.length() > 0)
0917:                    format.setPerMill(value.charAt(0));
0918:
0919:                value = element.getAttribute("zero-digit");
0920:                if (value.length() > 0)
0921:                    format.setZeroDigit(value.charAt(0));
0922:
0923:                value = element.getAttribute("digit");
0924:                if (value.length() > 0)
0925:                    format.setDigit(value.charAt(0));
0926:
0927:                value = element.getAttribute("pattern-separator");
0928:                if (value.length() > 0)
0929:                    format.setPatternSeparator(value.charAt(0));
0930:
0931:                _formatNumberFun.addLocale(name, format);
0932:            }
0933:
0934:            void generateNamespaceAlias(Element element) throws Exception {
0935:                if (!(element instanceof  QElement))
0936:                    return;
0937:
0938:                QElement elt = (QElement) element;
0939:                String stylesheetPrefix;
0940:                String resultPrefix;
0941:
0942:                stylesheetPrefix = (String) element
0943:                        .getAttribute("stylesheet-prefix");
0944:                resultPrefix = (String) element.getAttribute("result-prefix");
0945:
0946:                if (stylesheetPrefix.equals(""))
0947:                    throw error(element,
0948:                            "xsl:namespace-alias needs `stylesheet-prefix'");
0949:                if (resultPrefix.equals(""))
0950:                    throw error(element,
0951:                            "xsl:namespace-alias needs `result-prefix'");
0952:            }
0953:
0954:            public void addNamespaceAlias(String stylesheetPrefix,
0955:                    String resultPrefix) {
0956:                /*
0957:                String stylesheetNs = getNamespace(stylesheetPrefix);
0958:                if (stylesheetPrefix.equals("#default"))
0959:                  stylesheetNs = "";
0960:                else if (stylesheetNs.equals(""))
0961:                  throw error("`" + stylesheetPrefix + "' is not a valid namespace prefix");
0962:                String resultNs =  getNamespace(resultPrefix);
0963:                if (resultPrefix.equals("#default")) {
0964:                  resultPrefix = "";
0965:                  resultNs = "";
0966:                }
0967:                else if (resultNs.equals(""))
0968:                  throw error("`" + resultPrefix + "' is not a valid namespace prefix");
0969:                
0970:                String result[] = new String[] { resultPrefix, resultNs };
0971:                _namespaceAliases.put(stylesheetNs, result);
0972:                 */
0973:            }
0974:
0975:            public void addNamespaceAlias(String namespace, String[] result) {
0976:                _namespaceAliases.put(namespace, result);
0977:            }
0978:
0979:            public String[] getNamespaceAlias(String namespace) {
0980:                return _namespaceAliases.get(namespace);
0981:            }
0982:
0983:            /**
0984:             * Scans through the stylesheet, grabbing the attribute set
0985:             * definitions.
0986:             *
0987:             * @param element the current nost
0988:             */
0989:            /*
0990:            void generateAttributeSets(Element element)
0991:              throws Exception
0992:            {
0993:              Node child = element.getFirstChild();
0994:
0995:              for (; child != null; child = child.getNextSibling()) {
0996:                if (! "attribute-set".equals(getXslLocal(child)))
0997:            continue;
0998:
0999:                QElement elt = (QElement) child;
1000:                String name = elt.getAttribute("name");
1001:                if (name.equals(""))
1002:            throw error(L.l("xsl:attribute-set expects `name' attribute."));
1003:
1004:                generateAttributeSet(element, name);
1005:              }
1006:            }
1007:             */
1008:
1009:            /**
1010:             * Scans through the stylesheet, grabbing the attribute set
1011:             * definitions.
1012:             *
1013:             * @param element the current node
1014:             */
1015:            /*
1016:            HashMap<String,String> generateAttributeSet(Element element, String setName)
1017:              throws Exception
1018:            {
1019:              Node child = element.getFirstChild();
1020:
1021:              for (; child != null; child = child.getNextSibling()) {
1022:                if (! "attribute-set".equals(getXslLocal(child)))
1023:            continue;
1024:
1025:                QElement elt = (QElement) child;
1026:                String name = elt.getAttribute("name");
1027:                if (name.equals(""))
1028:            throw error(L.l("xsl:attribute-set expects `name' attribute."));
1029:
1030:                if (! name.equals(setName))
1031:                  continue;
1032:
1033:                HashMap<String,String> set = _attributeSets.get(name);
1034:                if (set != null)
1035:                  return set;
1036:
1037:                set = new HashMap<String,String>();
1038:                _attributeSets.put(name, set);
1039:
1040:                // add any attributes from use-attribute-sets
1041:                for (Node attr = elt.getFirstAttribute();
1042:               attr != null;
1043:               attr = attr.getNextSibling()) {
1044:            if (attr.getNodeName().equals("use-attribute-sets")) {
1045:              HashMap<String,String> subset = generateAttributeSet(element, attr.getNodeValue());
1046:                    
1047:              if (subset == null)
1048:                throw error(elt, L.l("Unknown attribute-set `{0}'.  Each use-attribute-sets needs a matching xsl:attribute-set.", attr.getNodeValue()));
1049:              Iterator<String> iter = subset.keySet().iterator();
1050:              while (iter.hasNext()) {
1051:                String key = iter.next();
1052:                set.put(key, subset.get(key));
1053:              }
1054:            }
1055:                }
1056:
1057:                for (Node attr = elt.getFirstChild();
1058:               attr != null;
1059:               attr = attr.getNextSibling()) {
1060:            if (! "attribute".equals(getXslLocal(attr)))
1061:              continue;
1062:            Element attrElt = (Element) attr;
1063:            String attrName = attrElt.getAttribute("name");
1064:            if (attrName.equals(""))
1065:              throw error(L.l("xsl:attribute expects `name' attribute."));
1066:
1067:            set.put(attrName, ((QElement) attr).getTextValue());
1068:                }
1069:
1070:                for (Attr attr = ((QElement) elt).getFirstAttribute();
1071:               attr != null;
1072:               attr = (Attr) attr.getNextSibling()) {
1073:            if (attr.getNodeName().equals("name") ||
1074:                attr.getNodeName().equals("use-attribute-sets"))
1075:              continue;
1076:
1077:            set.put(attr.getNodeName(), attr.getNodeValue());
1078:                }
1079:
1080:                return set;
1081:              }
1082:
1083:              return null;
1084:            }
1085:             */
1086:
1087:            public void addAttributeSet(String name,
1088:                    XslAttributeSet attributeSet) {
1089:                _attributeSets.put(name, attributeSet);
1090:            }
1091:
1092:            /*
1093:            public XslAttributeSet getAttributeSet(String name)
1094:            {
1095:              return _attributeSets.get(name);
1096:            }
1097:             */
1098:
1099:            public void setDisableOutputEscaping(boolean disable) {
1100:                _isRawText = disable;
1101:            }
1102:
1103:            public boolean getDisableOutputEscaping() {
1104:                return _isRawText;
1105:            }
1106:
1107:            private void generateOutput(Element element) throws Exception {
1108:                Node attr = ((QElement) element).getFirstAttribute();
1109:
1110:                if (element.getFirstChild() != null)
1111:                    throw error("xsl:output must be empty");
1112:
1113:                String disableEscaping;
1114:                disableEscaping = element
1115:                        .getAttribute("resin:disable-output-escaping");
1116:                if (disableEscaping.equals(""))
1117:                    disableEscaping = element
1118:                            .getAttribute("disable-output-escaping");
1119:                if (disableEscaping.equals("no")
1120:                        || disableEscaping.equals("false"))
1121:                    _isRawText = false;
1122:                else if (!disableEscaping.equals(""))
1123:                    _isRawText = true;
1124:
1125:                // Only top-level xsl:output matters (XXX: spec?)
1126:                if (!_isTop)
1127:                    return;
1128:
1129:                if (_outputAttributes == null)
1130:                    _outputAttributes = new HashMap<String, String>();
1131:
1132:                for (; attr != null; attr = attr.getNextSibling()) {
1133:                    _outputAttributes.put(attr.getNodeName(), attr
1134:                            .getNodeValue());
1135:                }
1136:            }
1137:
1138:            public void setOutputAttribute(String name, String value) {
1139:                _outputAttributes.put(name, value);
1140:            }
1141:
1142:            private void generatePreserveSpace(Element element)
1143:                    throws Exception {
1144:                String elements = element.getAttribute("elements");
1145:                if (elements.equals(""))
1146:                    throw error("xsl:preserve-space expects `elements' attribute.");
1147:
1148:                if (element.getFirstChild() != null)
1149:                    throw error("xsl:preserve-space must be empty");
1150:
1151:                int i = 0;
1152:                int len = elements.length();
1153:                for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1154:                }
1155:                CharBuffer cb = new CharBuffer();
1156:                while (i < len) {
1157:                    cb.clear();
1158:
1159:                    for (; i < len && !XmlChar.isWhitespace(elements.charAt(i)); i++)
1160:                        cb.append(elements.charAt(i));
1161:
1162:                    _preserve.put(cb.toString(), "true");
1163:
1164:                    for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1165:                    }
1166:                }
1167:            }
1168:
1169:            private void generateStripSpace(Element element) throws Exception {
1170:                throw new UnsupportedOperationException();
1171:                /*
1172:                String elements = element.getAttribute("elements");
1173:                if (elements.equals(""))
1174:                  throw error("xsl:strip-space expects `elements' attribute.");
1175:                
1176:                if (element.getFirstChild() != null)
1177:                  throw error("xsl:strip-space must be empty");
1178:                 */
1179:            }
1180:
1181:            public void addStripSpace(String elements) {
1182:                int i = 0;
1183:                int len = elements.length();
1184:                for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1185:                }
1186:                CharBuffer cb = new CharBuffer();
1187:                while (i < len) {
1188:                    cb.clear();
1189:
1190:                    for (; i < len && !XmlChar.isWhitespace(elements.charAt(i)); i++) {
1191:                        cb.append(elements.charAt(i));
1192:                    }
1193:
1194:                    _strip.put(cb.toString(), "true");
1195:
1196:                    for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1197:                    }
1198:                }
1199:            }
1200:
1201:            public void addPreserveSpace(String elements) {
1202:                int i = 0;
1203:                int len = elements.length();
1204:                for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1205:                }
1206:                CharBuffer cb = new CharBuffer();
1207:                while (i < len) {
1208:                    cb.clear();
1209:
1210:                    for (; i < len && !XmlChar.isWhitespace(elements.charAt(i)); i++) {
1211:                        cb.append(elements.charAt(i));
1212:                    }
1213:
1214:                    _preserve.put(cb.toString(), "true");
1215:
1216:                    for (; i < len && XmlChar.isWhitespace(elements.charAt(i)); i++) {
1217:                    }
1218:                }
1219:            }
1220:
1221:            protected void generateChildren(Node node) throws Exception {
1222:                _vars.add(0);
1223:                for (Node child = node.getFirstChild(); child != null; child = child
1224:                        .getNextSibling()) {
1225:                    generateChild(child);
1226:                }
1227:                int count = _vars.pop();
1228:                if (count > 0 && _vars.size() > 0)
1229:                    printPopScope(count);
1230:            }
1231:
1232:            protected void generateChild(Node child) throws Exception {
1233:                generateChildImpl(child);
1234:            }
1235:
1236:            public void generateChildImpl(Node child) throws Exception {
1237:                String nodeName = getXslLocal(child);
1238:                int code = -1;
1239:                if (nodeName != null)
1240:                    code = _tags.get(nodeName);
1241:                else if ((nodeName = getXtpLocal(child)) != null)
1242:                    code = _xtpTags.get(nodeName);
1243:                /* XXX: xsl/04al
1244:                else if (macros.get(child.getNodeName()) != null) {
1245:                  generateMacro((Element) child);
1246:                  return;
1247:                }
1248:                 */
1249:
1250:                if (nodeName == null) {
1251:                    if (child.getNodeType() == child.TEXT_NODE)
1252:                        generateText(child);
1253:                    else if (child.getNodeType() == child.ELEMENT_NODE) {
1254:                        NamespaceContext oldNamespace = addNamespace((Element) child);
1255:                        printElement((Element) child);
1256:                        _namespace = oldNamespace;
1257:                    }
1258:                    return;
1259:                }
1260:
1261:                if (child instanceof  QElement) {
1262:                    NamespaceContext oldNamespace = addNamespace((QElement) child);
1263:                    generateChild(child, code);
1264:                    _namespace = oldNamespace;
1265:                } else
1266:                    generateChild(child, code);
1267:            }
1268:
1269:            public void generateChild(Node child, int code) throws Exception {
1270:                if (child instanceof  QAbstractNode) {
1271:                    QAbstractNode qChild = (QAbstractNode) child;
1272:                    setLocation(qChild.getBaseURI(), qChild.getFilename(),
1273:                            qChild.getLine());
1274:                }
1275:
1276:                switch (code) {
1277:                case TEXT:
1278:                    generateText(child);
1279:                    break;
1280:
1281:                case XSL_TEXT:
1282:                    generateXslText((Element) child);
1283:                    break;
1284:
1285:                case APPLY_TEMPLATES:
1286:                    generateApplyTemplates((Element) child);
1287:                    break;
1288:
1289:                case APPLY_IMPORTS:
1290:                    generateApplyImports((Element) child);
1291:                    break;
1292:
1293:                case CALL_TEMPLATE:
1294:                    generateCallTemplate((Element) child);
1295:                    break;
1296:
1297:                case PARAM:
1298:                    generateParamVariable((Element) child);
1299:                    break;
1300:
1301:                case VARIABLE:
1302:                    generateVariable((Element) child);
1303:                    break;
1304:
1305:                case VALUE_OF:
1306:                    generateValueOf((Element) child);
1307:                    break;
1308:
1309:                case COPY_OF:
1310:                    generateCopyOf((Element) child);
1311:                    break;
1312:
1313:                case FOR_EACH:
1314:                    generateForEach((Element) child);
1315:                    break;
1316:
1317:                case IF:
1318:                    generateIf((Element) child);
1319:                    break;
1320:
1321:                case CHOOSE:
1322:                    generateChoose((Element) child);
1323:                    break;
1324:
1325:                case NUMBER:
1326:                    generateNumber((Element) child);
1327:                    break;
1328:
1329:                case COPY:
1330:                    printCopy((Element) child);
1331:                    break;
1332:
1333:                case COPY_ELEMENT:
1334:                    printCopyElement((Element) child);
1335:                    break;
1336:
1337:                case ELEMENT:
1338:                    generateElement((Element) child);
1339:                    break;
1340:
1341:                case ATTRIBUTE:
1342:                    generateAttribute((Element) child);
1343:                    break;
1344:
1345:                case PI:
1346:                    printPi((Element) child);
1347:                    break;
1348:
1349:                case COMMENT:
1350:                    printComment((Element) child);
1351:                    break;
1352:
1353:                case MESSAGE:
1354:                    printMessage((Element) child);
1355:                    break;
1356:
1357:                case EXPRESSION:
1358:                    if (!_defaultCacheable)
1359:                        _isCacheable = false;
1360:                    printExpression((Element) child);
1361:                    break;
1362:
1363:                case SCRIPTLET:
1364:                    if (!_defaultCacheable)
1365:                        _isCacheable = false;
1366:                    printScriptlet((Element) child);
1367:                    break;
1368:
1369:                case DIRECTIVE_CACHE:
1370:                    generateCacheDepends(((Element) child).getAttribute("file"));
1371:                    if (!((Element) child).getAttribute("no-cache").equals("")) {
1372:                        _isCacheable = false;
1373:                        _defaultCacheable = false;
1374:                    } else
1375:                        _defaultCacheable = true;
1376:                    break;
1377:
1378:                case WHILE:
1379:                    generateWhile((Element) child);
1380:                    break;
1381:
1382:                case ASSIGN:
1383:                    generateAssign((Element) child);
1384:                    break;
1385:
1386:                case RESULT_DOCUMENT:
1387:                    generateResultDocument((Element) child);
1388:                    break;
1389:
1390:                case IGNORE:
1391:                    break;
1392:
1393:                default:
1394:                    if (child instanceof  QElement
1395:                            && XSLNS.equals(((QElement) child)
1396:                                    .getNamespaceURI()) && _version != null
1397:                            && _version.equals("1.0"))
1398:                        throw error(child, "unknown XSL element `"
1399:                                + child.getNodeName() + "'");
1400:                    else {
1401:                        Node subchild = child.getFirstChild();
1402:                        boolean hasFallback = false;
1403:                        for (; subchild != null; subchild = subchild
1404:                                .getNextSibling()) {
1405:                            String local = getXslLocal(subchild);
1406:                            if (local != null && local.equals("fallback")) {
1407:                                hasFallback = true;
1408:                                generateChildren(subchild);
1409:                            }
1410:                        }
1411:                        if (!hasFallback) // && child.getNamespace().equals(XSLNS))
1412:                            printError(L.l("expected xsl tag at `{0}'", child
1413:                                    .getNodeName()));
1414:                    }
1415:                    break;
1416:                }
1417:            }
1418:
1419:            private void generateText(Node node) throws Exception {
1420:                String data = node.getNodeValue();
1421:                int length = data.length();
1422:
1423:                if (length == 0)
1424:                    return;
1425:
1426:                int i = 0;
1427:                for (; i < length && XmlChar.isWhitespace(data.charAt(i)); i++) {
1428:                }
1429:
1430:                if (i == length && stripNode(node))
1431:                    return;
1432:
1433:                if (data != null && data.length() > 0
1434:                        && node instanceof  QAbstractNode) {
1435:                    setLocation(node);
1436:                    writeText(data);
1437:                }
1438:            }
1439:
1440:            private boolean stripNode(Node node) {
1441:                for (node = node.getParentNode(); node != null; node = node
1442:                        .getParentNode()) {
1443:                    if (node instanceof  Element) {
1444:                        Element elt = (Element) node;
1445:                        String space = elt.getAttribute("xml:space");
1446:                        if (!space.equals(""))
1447:                            return !space.equals("preserve");
1448:                    }
1449:                }
1450:
1451:                return true;
1452:            }
1453:
1454:            void generateXslText(Element element) throws Exception {
1455:                _text.clear();
1456:                for (Node child = element.getFirstChild(); child != null; child = child
1457:                        .getNextSibling()) {
1458:                    if (!(child instanceof  Text))
1459:                        continue;
1460:
1461:                    String data = child.getNodeValue();
1462:                    int length = data.length();
1463:
1464:                    _text.append(data);
1465:                }
1466:
1467:                String disableEscaping = element
1468:                        .getAttribute("disable-output-escaping");
1469:                if (disableEscaping.equals(""))
1470:                    disableEscaping = "no";
1471:
1472:                if (_text.length() <= 0) {
1473:                } else if (!disableEscaping.equals("yes")
1474:                        && !disableEscaping.equals("true"))
1475:                    writeText(_text.toString());
1476:                else {
1477:                    startDisableEscaping();
1478:                    writeText(_text.toString());
1479:                    endDisableEscaping();
1480:                }
1481:            }
1482:
1483:            private void generateApplyTemplates(Node node) throws Exception {
1484:                QElement element = (QElement) node;
1485:                String select = element.getAttribute("select");
1486:                String mode = element.getAttribute("mode");
1487:                AbstractPattern selectPattern = null;
1488:                if (!select.equals(""))
1489:                    selectPattern = parseSelect(select, node);
1490:
1491:                Sort[] sort = generateSort(node);
1492:
1493:                if (sort != null && selectPattern == null)
1494:                    selectPattern = parseSelect("*", node);
1495:
1496:                pushCall();
1497:                generateArgs(element);
1498:                printApplyTemplates(selectPattern, mode, sort);
1499:                popCall();
1500:            }
1501:
1502:            private void generateApplyImports(Node node) throws Exception {
1503:                QElement element = (QElement) node;
1504:                String mode = element.getAttribute("mode");
1505:
1506:                if (element.getFirstChild() != null)
1507:                    throw error(L.l("xsl:apply-imports must be empty"));
1508:
1509:                pushCall();
1510:                generateArgs(element);
1511:                printApplyImports(mode, _minImportance, _importance);
1512:                popCall();
1513:            }
1514:
1515:            private void generateCallTemplate(Element element) throws Exception {
1516:                String name = element.getAttribute("name");
1517:                String mode = element.getAttribute("mode");
1518:
1519:                if (name.equals(""))
1520:                    throw error(L.l("{0} expects `{1}' attribute",
1521:                            "xsl:call-template", "name"));
1522:
1523:                if (findMacro(name) == null)
1524:                    throw error(
1525:                            element,
1526:                            L
1527:                                    .l(
1528:                                            "`{0}' is an unknown macro for xsl:call-template.  All macros must be defined in an <xsl:template name='...'> element.",
1529:                                            name));
1530:
1531:                pushCall();
1532:                generateArgs(element);
1533:                printCallTemplate(name, mode);
1534:                popCall();
1535:            }
1536:
1537:            private Element findMacro(String name) throws Exception {
1538:                Element template = findMacroInDocument(_doc, name);
1539:                if (template != null)
1540:                    return template;
1541:
1542:                Iterator iter = _files.values().iterator();
1543:                while (iter.hasNext()) {
1544:                    Document doc = (Document) iter.next();
1545:
1546:                    template = findMacroInDocument(doc, name);
1547:
1548:                    if (template != null)
1549:                        return template;
1550:                }
1551:
1552:                return null;
1553:            }
1554:
1555:            private Element findMacroInDocument(Document doc, String name) {
1556:                Element elt = doc.getDocumentElement();
1557:
1558:                for (Node child = elt.getFirstChild(); child != null; child = child
1559:                        .getNextSibling()) {
1560:                    if (!child.getNodeName().equals("xsl:template"))
1561:                        continue;
1562:
1563:                    Element template = (Element) child;
1564:
1565:                    if (template.getAttribute("name").equals(name))
1566:                        return template;
1567:                }
1568:
1569:                return null;
1570:            }
1571:
1572:            private void generateMacro(Element element) throws Exception {
1573:                QElement elt = (QElement) element;
1574:
1575:                String name = element.getNodeName();
1576:                String mode = element.getAttribute("mode");
1577:
1578:                pushCall();
1579:                for (Node node = elt.getFirstAttribute(); node != null; node = node
1580:                        .getNextSibling()) {
1581:                    String argName = node.getNodeName();
1582:                    String argValue = node.getNodeValue();
1583:
1584:                    printParam(argName, argValue, elt);
1585:                }
1586:                printParam("contents", elt);
1587:                printCallTemplate(name, mode);
1588:                popCall();
1589:            }
1590:
1591:            private void generateArgs(Element element) throws Exception {
1592:                for (Node node = element.getFirstChild(); node != null; node = node
1593:                        .getNextSibling()) {
1594:                    String localName = getXslLocal(node);
1595:
1596:                    if ("with-param".equals(localName)) {
1597:                        String key = ((Element) node).getAttribute("name");
1598:                        String expr = ((Element) node).getAttribute("select");
1599:                        if (key.equals(""))
1600:                            throw error(L.l("{0} requires `{1}' attribute",
1601:                                    "xsl:with-param", "name"));
1602:
1603:                        if (!expr.equals(""))
1604:                            printParam(key, parseExpr(expr));
1605:                        else
1606:                            printParam(key, node);
1607:                    }
1608:                }
1609:            }
1610:
1611:            private void generateParamVariable(Element element)
1612:                    throws Exception {
1613:                int i = _vars.size() - 1;
1614:                _vars.set(i, _vars.get(i) + 1);
1615:
1616:                String name = element.getAttribute("name");
1617:                String expr = element.getAttribute("select");
1618:                if (name.equals(""))
1619:                    throw error(L.l("{0} expects `{1}' attribute", "xsl:param",
1620:                            "name"));
1621:
1622:                if (!expr.equals(""))
1623:                    printParamVariable(name, parseExpr(expr));
1624:                else
1625:                    printParamVariable(name, element);
1626:            }
1627:
1628:            private void generateVariable(Element element) throws Exception {
1629:                int i = _vars.size() - 1;
1630:                _vars.set(i, _vars.get(i) + 1);
1631:
1632:                String name = element.getAttribute("name");
1633:                String expr = element.getAttribute("select");
1634:                if (name.equals(""))
1635:                    throw error(L.l("{0} expects `{1}' attribute.",
1636:                            "xsl:variable", "name"));
1637:
1638:                if (!expr.equals(""))
1639:                    printVariable(name, parseExpr(expr));
1640:                else
1641:                    printVariable(name, element);
1642:            }
1643:
1644:            private void generateAssign(Element element) throws Exception {
1645:                String name = element.getAttribute("name");
1646:                String expr = element.getAttribute("select");
1647:                if (name.equals(""))
1648:                    throw error(L.l("{0} expects `{1}' attribute.",
1649:                            "xtp:assign", "name"));
1650:
1651:                if (!expr.equals(""))
1652:                    printAssign(name, parseExpr(expr));
1653:                else
1654:                    printAssign(name, element);
1655:            }
1656:
1657:            private void generateResultDocument(Element element)
1658:                    throws Exception {
1659:                String href = element.getAttribute("href");
1660:                String format = element.getAttribute("format");
1661:                if (href.equals(""))
1662:                    throw error(L.l("{0} expects `{1}' attribute.",
1663:                            "xtp:result-document", "href"));
1664:
1665:                printResultDocument(element, href, format);
1666:            }
1667:
1668:            private void generateValueOf(Element element) throws Exception {
1669:                String select = element.getAttribute("select");
1670:                if (select.equals(""))
1671:                    throw error(L.l("{0} expects `{1}' attribute.",
1672:                            "xsl:value-of", "select"));
1673:
1674:                if (element.getFirstChild() != null)
1675:                    throw error(L.l("{0} must be empty", "xsl:value-of"));
1676:
1677:                String disable = element
1678:                        .getAttribute("disable-output-escaping");
1679:                boolean isDisabled = disable.equals("yes");
1680:                if (isDisabled)
1681:                    startDisableEscaping();
1682:
1683:                printSelectValue(select, element);
1684:
1685:                if (isDisabled)
1686:                    endDisableEscaping();
1687:            }
1688:
1689:            private void generateCopyOf(Element element) throws Exception {
1690:                String select = element.getAttribute("select");
1691:                if (select.equals(""))
1692:                    throw error(L.l("{0} expects `{1}' attribute",
1693:                            "xsl:copy-of", "select"));
1694:
1695:                if (element.getFirstChild() != null)
1696:                    throw error(L.l("{0} must be empty", "xsl:copy-of"));
1697:
1698:                printCopyOf(select, element);
1699:            }
1700:
1701:            /**
1702:             * Generates code for the xsl:for-each element
1703:             */
1704:            void generateForEach(Element element) throws Exception {
1705:                String select = element.getAttribute("select");
1706:                if (select.equals(""))
1707:                    throw error(L.l("{0} expects `{1}' attribute",
1708:                            "xsl:for-each", "select"));
1709:
1710:                Sort[] sort = generateSort(element);
1711:
1712:                if (sort != null)
1713:                    printForEach(element, select, sort);
1714:                else
1715:                    printForEach(element, select);
1716:            }
1717:
1718:            private Sort[] generateSort(Node node) throws XslParseException,
1719:                    IOException {
1720:                ArrayList<Sort> sorts = new ArrayList<Sort>();
1721:                sort: for (Node child = node.getFirstChild(); child != null; child = child
1722:                        .getNextSibling()) {
1723:                    if (child.getNodeType() == child.TEXT_NODE) {
1724:                        String data = child.getNodeValue();
1725:                        for (int i = 0; i < data.length(); i++) {
1726:                            if (!XmlChar.isWhitespace(data.charAt(i)))
1727:                                break sort;
1728:                        }
1729:                        continue;
1730:                    } else if (child.getNodeType() == child.COMMENT_NODE
1731:                            || child.getNodeType() == child.PROCESSING_INSTRUCTION_NODE)
1732:                        continue;
1733:
1734:                    String name = getXslLocal(child);
1735:                    if (!"sort".equals(name))
1736:                        break;
1737:
1738:                    Element elt = (Element) child;
1739:                    String select = elt.getAttribute("select");
1740:                    if (select.equals(""))
1741:                        throw error(L.l("{0} expects attribute `{1}'",
1742:                                "xsl:sort", "select"));
1743:
1744:                    Expr expr = parseExpr(select);
1745:                    String order = elt.getAttribute("order");
1746:                    Expr isAscending = null;
1747:                    if (order.equals("")) {
1748:                        isAscending = parseExpr("true()");
1749:                    } else if (order.startsWith("{") && order.endsWith("}")) {
1750:                        order = order.substring(1, order.length() - 1);
1751:
1752:                        isAscending = parseExpr(order + " = 'ascending'");
1753:                    } else if (order.equals("ascending"))
1754:                        isAscending = parseExpr("true()");
1755:                    else
1756:                        isAscending = parseExpr("false()");
1757:
1758:                    String dataType = elt.getAttribute("data-type");
1759:                    boolean isText = true;
1760:                    if (dataType.equals("number"))
1761:                        isText = false;
1762:
1763:                    String lang = elt.getAttribute("lang");
1764:                    if (lang.equals("")) {
1765:                        sorts.add(Sort.create(expr, isAscending, isText));
1766:                    } else {
1767:                        if (lang.startsWith("{") && lang.endsWith("}"))
1768:                            lang = lang.substring(1, lang.length() - 1);
1769:                        else
1770:                            lang = "'" + lang + "'";
1771:
1772:                        sorts.add(Sort.create(expr, isAscending,
1773:                                parseExpr(lang)));
1774:                        /*
1775:                            int p = lang.indexOf('-');
1776:                            Locale locale = null;
1777:
1778:                            if (p < 0) {
1779:                              locale = new Locale(lang, "");
1780:                            }
1781:                            else {
1782:                              String language = lang.substring(0, p);
1783:                              
1784:                              int q = lang.indexOf(p + 1, '-');
1785:
1786:                              if (q < 0) {
1787:                                String country = lang.substring(p + 1);
1788:
1789:                                locale = new Locale(language, country);
1790:                              }
1791:                              else {
1792:                                String country = lang.substring(p + 1, q);
1793:                                String variant = lang.substring(q);
1794:
1795:                                locale = new Locale(language, country, variant);
1796:                              }
1797:                            }
1798:
1799:                            sorts.add(Sort.create(expr, isAscending, lang));
1800:                         */
1801:                    }
1802:                }
1803:
1804:                if (sorts.size() > 0)
1805:                    return (Sort[]) sorts.toArray(new Sort[sorts.size()]);
1806:                else
1807:                    return null;
1808:            }
1809:
1810:            void generateIf(Element element) throws Exception {
1811:                String test = (String) element.getAttribute("test");
1812:                if (test.equals(""))
1813:                    throw error(L.l("{0} expects `{1}' attribute", "xsl:if",
1814:                            "test"));
1815:
1816:                printIf(element, parseExpr(test));
1817:            }
1818:
1819:            void generateWhile(Element element) throws Exception {
1820:                String test = (String) element.getAttribute("test");
1821:                if (test.equals(""))
1822:                    throw error(L.l("{0} expects `{1}' attribute", "xsl:while",
1823:                            "test"));
1824:
1825:                printWhile(element, parseExpr(test));
1826:            }
1827:
1828:            void generateChoose(Element element) throws Exception {
1829:                boolean first = true;
1830:                for (Node child = element.getFirstChild(); child != null; child = child
1831:                        .getNextSibling()) {
1832:                    if (!(child instanceof  Element))
1833:                        continue;
1834:
1835:                    String name = getXslLocal(child);
1836:
1837:                    if ("when".equals(name)) {
1838:                        Element elt = (Element) child;
1839:                        String test = elt.getAttribute("test");
1840:                        if (test.equals(""))
1841:                            throw error(L.l("{0} expects `{1}' attribute",
1842:                                    "xsl:when", "test"));
1843:
1844:                        printChoose(elt, parseExpr(test), first);
1845:                        first = false;
1846:                    } else if ("otherwise".equals(name)) {
1847:                        printOtherwise((Element) child, first);
1848:                    } else
1849:                        throw error(L
1850:                                .l(
1851:                                        "xsl:choose expects `xsl:when' or `xsl:otherwise' at `{0}'",
1852:                                        child.getNodeName()));
1853:                }
1854:            }
1855:
1856:            void generateElement(Element element) throws Exception {
1857:                String name = (String) element.getAttribute("name");
1858:                if (name.equals(""))
1859:                    throw error(L.l("{0} expects `{1}' attribute.",
1860:                            "xsl:element", "name"));
1861:                Attr nsAttr = element.getAttributeNode("namespace");
1862:
1863:                if (nsAttr == null)
1864:                    printElement(element, name);
1865:                else
1866:                    printElement(element, name, nsAttr.getNodeValue());
1867:            }
1868:
1869:            void generateAttribute(Element element) throws Exception {
1870:                String name = (String) element.getAttribute("name");
1871:                if (name.equals(""))
1872:                    throw error(L.l("{0} expects `{1}' attribute",
1873:                            "xsl:attribute", "name"));
1874:                Attr nsAttr = element.getAttributeNode("namespace");
1875:
1876:                boolean oldSpecial = _isSpecial;
1877:                _isSpecial = true;
1878:
1879:                if (nsAttr == null)
1880:                    printAttribute(element, name);
1881:                else
1882:                    printAttribute(element, name, nsAttr.getNodeValue());
1883:
1884:                _isSpecial = oldSpecial;
1885:            }
1886:
1887:            void generateNumber(Element element) throws Exception {
1888:                String value = element.getAttribute("value");
1889:                String count = element.getAttribute("count");
1890:                String from = element.getAttribute("from");
1891:                String level = element.getAttribute("level");
1892:                String format = element.getAttribute("format");
1893:                String letter = element.getAttribute("letter-value");
1894:                String separator = element.getAttribute("grouping-separator");
1895:                String lang = element.getAttribute("lang");
1896:                String size_name = element.getAttribute("grouping-size");
1897:
1898:                int size = 0;
1899:                for (int i = 0; i < size_name.length(); i++) {
1900:                    char ch = size_name.charAt(i);
1901:                    if (ch >= '0' && ch <= '9')
1902:                        size = 10 * size + ch - '0';
1903:                }
1904:
1905:                boolean isAlphabetic = true;
1906:                if (!letter.equals("alphabetic"))
1907:                    isAlphabetic = false;
1908:
1909:                AbstractPattern countPattern = null;
1910:                if (!count.equals(""))
1911:                    countPattern = parseMatch(count);
1912:
1913:                AbstractPattern fromPattern = null;
1914:                if (!from.equals(""))
1915:                    fromPattern = parseMatch(from);
1916:
1917:                if (level.equals("") || level.equals("single"))
1918:                    level = "single";
1919:                else if (level.equals("multiple")) {
1920:                } else if (level.equals("any")) {
1921:                } else
1922:                    throw error(L.l("xsl:number can't understand level=`{0}'",
1923:                            level));
1924:
1925:                XslNumberFormat xslFormat;
1926:                xslFormat = new XslNumberFormat(format, lang, isAlphabetic,
1927:                        separator, size);
1928:
1929:                if (!value.equals(""))
1930:                    printNumber(parseExpr(value), xslFormat);
1931:                else
1932:                    printNumber(level, countPattern, fromPattern, xslFormat);
1933:            }
1934:
1935:            void printNumber(Expr expr, XslNumberFormat format)
1936:                    throws Exception {
1937:
1938:            }
1939:
1940:            void printNumber(String level, AbstractPattern countPattern,
1941:                    AbstractPattern fromPattern, XslNumberFormat format)
1942:                    throws Exception {
1943:
1944:            }
1945:
1946:            /**
1947:             * Sets location code for the node.
1948:             */
1949:            void setLocation(Node node) throws Exception {
1950:                if (node instanceof  QAbstractNode) {
1951:                    setLocation(((QAbstractNode) node).getBaseURI(),
1952:                            ((QAbstractNode) node).getFilename(),
1953:                            ((QAbstractNode) node).getLine());
1954:                }
1955:            }
1956:
1957:            public void setLocation(String systemId, String filename, int line)
1958:                    throws XslParseException, IOException {
1959:                if (filename != null) {
1960:                    _systemId = systemId;
1961:                    _filename = filename;
1962:                    _line = line;
1963:                    // _lineMap.add(filename, line, getOut().getDestLine());
1964:                }
1965:            }
1966:
1967:            int getTextLength() {
1968:                return _text.length();
1969:            }
1970:
1971:            protected void printHeader() throws XslParseException, IOException {
1972:            }
1973:
1974:            abstract protected void startDisableEscaping() throws Exception;
1975:
1976:            abstract protected void endDisableEscaping() throws Exception;
1977:
1978:            abstract protected void writeText(String text) throws Exception;
1979:
1980:            abstract protected void printTemplate(Element node, String name,
1981:                    String pattern, String mode, double priority)
1982:                    throws Exception;
1983:
1984:            /**
1985:             * Prints location code for the node.
1986:             */
1987:            void printLocation(Node node) throws Exception {
1988:                if (node instanceof  QAbstractNode) {
1989:                    printLocation(((QAbstractNode) node).getBaseURI(),
1990:                            ((QAbstractNode) node).getFilename(),
1991:                            ((QAbstractNode) node).getLine());
1992:                }
1993:            }
1994:
1995:            abstract protected void printLocation(String systemId,
1996:                    String filename, int line) throws Exception;
1997:
1998:            abstract protected void printElement(Node node) throws Exception;
1999:
2000:            abstract protected void printApplyTemplates(AbstractPattern select,
2001:                    String mode, Sort[] sort) throws Exception;
2002:
2003:            abstract protected void printApplyImports(String mode, int min,
2004:                    int max) throws Exception;
2005:
2006:            abstract protected void printCallTemplate(String name, String mode)
2007:                    throws Exception;
2008:
2009:            abstract protected void pushCall() throws Exception;
2010:
2011:            abstract protected void popCall() throws Exception;
2012:
2013:            abstract protected void printParam(String name, Object value)
2014:                    throws Exception;
2015:
2016:            abstract protected void printParam(String name, String value,
2017:                    Element elt) throws Exception;
2018:
2019:            abstract protected void printParamVariable(String name, Expr expr)
2020:                    throws Exception;
2021:
2022:            abstract protected void printParamVariable(String name, Element elt)
2023:                    throws Exception;
2024:
2025:            abstract protected void printVariable(String name, Object value)
2026:                    throws Exception;
2027:
2028:            protected void printAssign(String name, Object value)
2029:                    throws Exception {
2030:                printVariable(name, value);
2031:            }
2032:
2033:            abstract protected void printPopScope(int count) throws Exception;
2034:
2035:            abstract protected void printCopyOf(String select, Element element)
2036:                    throws Exception;
2037:
2038:            abstract protected void printSelectValue(String select,
2039:                    Element element) throws Exception;
2040:
2041:            abstract protected void printForEach(Element element, String select)
2042:                    throws Exception;
2043:
2044:            abstract protected void printForEach(Element element,
2045:                    String select, Sort[] sort) throws Exception;
2046:
2047:            protected void printIf(Element element, Expr expr) throws Exception {
2048:            }
2049:
2050:            protected void printChoose(Element element, Expr expr, boolean first)
2051:                    throws Exception {
2052:            }
2053:
2054:            protected void printOtherwise(Element element, boolean first)
2055:                    throws Exception {
2056:            }
2057:
2058:            protected void printCopy(Element element) throws Exception {
2059:            }
2060:
2061:            protected void printCopyElement(Element element) throws Exception {
2062:            }
2063:
2064:            protected void printElement(Element element, String name)
2065:                    throws Exception {
2066:            }
2067:
2068:            protected void printElement(Element element, String name,
2069:                    String namespace) throws Exception {
2070:            }
2071:
2072:            protected void printAttribute(Element node, String name)
2073:                    throws Exception {
2074:            }
2075:
2076:            protected void printAttribute(Element node, String name,
2077:                    String namespace) throws Exception {
2078:            }
2079:
2080:            protected void printPi(Element node) throws Exception {
2081:            }
2082:
2083:            protected void printComment(Element node) throws Exception {
2084:            }
2085:
2086:            protected void printError(String msg) throws Exception {
2087:            }
2088:
2089:            protected void printMessage(Element node) throws Exception {
2090:            }
2091:
2092:            // extension
2093:
2094:            protected void printExpression(Element node) throws Exception {
2095:            }
2096:
2097:            protected void printScriptlet(Element node) throws Exception {
2098:            }
2099:
2100:            protected void printDeclaration(Element node) throws Exception {
2101:            }
2102:
2103:            protected void printCacheDepends(String path) throws Exception {
2104:            }
2105:
2106:            protected void printWhile(Element element, Expr expr)
2107:                    throws Exception {
2108:            }
2109:
2110:            protected void printResultDocument(Element element, String href,
2111:                    String format) throws Exception {
2112:            }
2113:
2114:            public int getImportance() {
2115:                return _importance;
2116:            }
2117:
2118:            public void setMinImportance(int importance) {
2119:                _minImportance = importance;
2120:            }
2121:
2122:            public void incrementImportance() {
2123:                _importance++;
2124:            }
2125:
2126:            /**
2127:             * Adds a new template pattern.
2128:             *
2129:             * @param pattern the match pattern.
2130:             * @param mode the template mode.
2131:             * @param priority the template priority.
2132:             * @param function the associated function name.
2133:             * @param funId the function id.
2134:             */
2135:            Template addPattern(AbstractPattern pattern, String mode,
2136:                    double priority, String function, int funId) {
2137:                if (pattern instanceof  UnionPattern) {
2138:                    UnionPattern union = (UnionPattern) pattern;
2139:                    addPattern(union.getLeft(), mode, priority, function, funId);
2140:                    return addPattern(union.getRight(), mode, priority,
2141:                            function, funId);
2142:                }
2143:
2144:                if (Double.isNaN(priority))
2145:                    priority = pattern.getPriority();
2146:
2147:                if (log.isLoggable(Level.FINER))
2148:                    log.finer("add " + pattern.getNodeName() + " " + pattern
2149:                            + " fun:" + function + " mode:" + mode
2150:                            + " priority:" + priority);
2151:
2152:                Template template = new Template(pattern, mode, _minImportance,
2153:                        _importance, priority, _templateCount++, function,
2154:                        funId);
2155:
2156:                addTemplate(pattern.getNodeName(), template);
2157:
2158:                return template;
2159:            }
2160:
2161:            private void addTemplate(String nodeName, Template template) {
2162:                ArrayList<Template> templateList = _templates.get(nodeName);
2163:
2164:                if (templateList == null) {
2165:                    templateList = new ArrayList<Template>();
2166:                    _templates.put(nodeName, templateList);
2167:                }
2168:
2169:                for (int i = templateList.size() - 1; i >= 0; i--) {
2170:                    Template item = templateList.get(i);
2171:
2172:                    if (template.compareTo(item) <= 0) {
2173:                        templateList.add(i + 1, template);
2174:                        return;
2175:                    }
2176:                }
2177:
2178:                templateList.add(0, template);
2179:            }
2180:
2181:            public AbstractPattern parseMatch(String pattern)
2182:                    throws XslParseException, IOException {
2183:                if (true)
2184:                    throw new RuntimeException();
2185:                try {
2186:                    return XPath.parseMatch(pattern, _namespace).getPattern();
2187:                } catch (Exception e) {
2188:                    throw error(L.l("{0} in pattern `{1}'", e.toString(),
2189:                            pattern));
2190:                }
2191:            }
2192:
2193:            public AbstractPattern parseSelect(String pattern)
2194:                    throws IOException, XslParseException {
2195:                if (true)
2196:                    throw new RuntimeException();
2197:
2198:                try {
2199:                    return XPath.parseSelect(pattern, _namespace).getPattern();
2200:                } catch (Exception e) {
2201:                    throw error(e);
2202:                }
2203:            }
2204:
2205:            protected AbstractPattern parseSelect(String pattern, Node node)
2206:                    throws IOException, XslParseException {
2207:                if (true)
2208:                    throw new UnsupportedOperationException();
2209:                try {
2210:                    return XPath.parseSelect(pattern, _namespace).getPattern();
2211:                } catch (Exception e) {
2212:                    throw error(node, e);
2213:                }
2214:            }
2215:
2216:            public Expr parseExpr(String pattern) throws XslParseException {
2217:                if (true)
2218:                    throw new UnsupportedOperationException();
2219:                try {
2220:                    return XPath.parseExpr(pattern, _namespace,
2221:                            _nodeListContext);
2222:                } catch (Exception e) {
2223:                    throw error(e);
2224:                }
2225:            }
2226:
2227:            XslParseException error(Exception e) {
2228:                if (e.getMessage() != null)
2229:                    return error(e.getMessage());
2230:                else {
2231:                    log.log(Level.WARNING, e.toString(), e);
2232:
2233:                    return error(e.toString());
2234:                }
2235:            }
2236:
2237:            XslParseException error(Node node, Exception e) {
2238:                if (e.getMessage() != null)
2239:                    return error(node, e.getMessage());
2240:                else {
2241:                    log.log(Level.WARNING, e.toString(), e);
2242:
2243:                    return error(e.toString());
2244:                }
2245:            }
2246:
2247:            XslParseException error(String message) {
2248:                return new XslParseException(_filename + ":" + _line + ": "
2249:                        + message);
2250:            }
2251:
2252:            /**
2253:             * Creates an error message with filename and line number based on
2254:             * the source node.
2255:             *
2256:             * @param node XML node of the source XSL.
2257:             * @param message the error message.
2258:             */
2259:            XslParseException error(Node node, String message) {
2260:                if (!(node instanceof  QAbstractNode))
2261:                    return error(message);
2262:
2263:                QAbstractNode qnode = (QAbstractNode) node;
2264:
2265:                String filename = qnode.getFilename();
2266:                int line = qnode.getLine();
2267:
2268:                if (filename != null)
2269:                    return new XslParseException(filename + ":" + line + ": "
2270:                            + message);
2271:                else
2272:                    return error(message);
2273:            }
2274:
2275:            /**
2276:             * Returns the local name of an XSL element.  Non-XSL elements return
2277:             * null.  So xsl:copy will return "copy", while "foo:bar" returns null.
2278:             *
2279:             * @param node the XSL source node
2280:             * @return the local part of the XSL name.
2281:             */
2282:            protected String getXslLocal(Node node) {
2283:                if (!(node instanceof  Element))
2284:                    return null;
2285:
2286:                QElement elt = (QElement) node;
2287:
2288:                String ns = elt.getNamespaceURI();
2289:                String prefix = elt.getPrefix();
2290:
2291:                if (ns == null || ns.equals("")) {
2292:                    return (elt.getNodeName().startsWith("xsl:") ? elt
2293:                            .getNodeName().substring(4) : null);
2294:                } else if (ns.startsWith(XSLNS)
2295:                        && (ns.length() == XSLNS.length() || ns.charAt(XSLNS
2296:                                .length()) == '/'))
2297:                    return elt.getLocalName();
2298:                else
2299:                    return null;
2300:            }
2301:
2302:            protected String getXtpLocal(Node node) {
2303:                if (!(node instanceof  Element))
2304:                    return null;
2305:
2306:                QElement elt = (QElement) node;
2307:
2308:                String ns = elt.getNamespaceURI();
2309:                String prefix = elt.getPrefix();
2310:
2311:                if (ns == null || ns.equals("")) {
2312:                    return (elt.getNodeName().startsWith("xtp:") ? elt
2313:                            .getNodeName().substring(4) : null);
2314:                } else if (ns.startsWith(XTPNS))
2315:                    return elt.getLocalName();
2316:                else
2317:                    return null;
2318:            }
2319:
2320:            /**
2321:             * Parses an expression in a context
2322:             */
2323:            private Expr parseExpr(Node node, String expr) throws Exception {
2324:                try {
2325:                    return XPath.parseExpr(expr, _namespace, _nodeListContext);
2326:                } catch (Exception e) {
2327:                    throw error(node, e.getMessage());
2328:                }
2329:            }
2330:
2331:            /**
2332:             * Adds the namespaces in the element to the current NamespaceContext.
2333:             * The XPath pattern parsing uses NamespaceContext to associate the right
2334:             * context with element patterns.
2335:             *
2336:             * @param elt the XSL element being processed.
2337:             *
2338:             * @return the old namespace context
2339:             */
2340:            protected NamespaceContext addNamespace(Element elt) {
2341:                NamespaceContext oldNamespace = _namespace;
2342:
2343:                Node attr = ((QElement) elt).getFirstAttribute();
2344:                for (; attr != null; attr = attr.getNextSibling()) {
2345:                    String name = attr.getNodeName();
2346:
2347:                    if (name.startsWith("xmlns:"))
2348:                        name = name.substring(6);
2349:                    else if (name.equals("xmlns"))
2350:                        name = "";
2351:                    else
2352:                        continue;
2353:
2354:                    // Note: according to the spec, the default namespace is not used
2355:
2356:                    String url = attr.getNodeValue();
2357:                    if (url.equals(XSLNS) || url.equals(XTPNS))
2358:                        continue;
2359:
2360:                    if (url.startsWith("quote:"))
2361:                        url = url.substring(6);
2362:
2363:                    _namespace = new NamespaceContext(_namespace, name, url);
2364:                }
2365:
2366:                return oldNamespace;
2367:            }
2368:
2369:            void addDepend(Path depend) {
2370:                if (depend != null)
2371:                    _depends.add(depend);
2372:            }
2373:
2374:            abstract protected StylesheetImpl completeGenerate(
2375:                    ArrayList<XslNode> inits, ArrayList globals)
2376:                    throws Exception;
2377:
2378:            /**
2379:             * Close call when an error occurs.
2380:             */
2381:            public void close() throws IOException, XslParseException {
2382:            }
2383:
2384:            static {
2385:                _tags = new IntMap();
2386:                _tags.put("stylesheet", STYLESHEET);
2387:                _tags.put("transform", STYLESHEET);
2388:                _tags.put("output", OUTPUT);
2389:                _tags.put("template", TEMPLATE);
2390:                _tags.put("preserve-space", PRESERVE_SPACE);
2391:                _tags.put("strip-space", STRIP_SPACE);
2392:                _tags.put("import", IMPORT);
2393:                _tags.put("include", INCLUDE);
2394:                _tags.put("key", KEY);
2395:                _tags.put("decimal-format", LOCALE);
2396:                _tags.put("attribute-set", ATTRIBUTE_SET);
2397:                _tags.put("namespace-alias", NAMESPACE_ALIAS);
2398:
2399:                _tags.put("apply-templates", APPLY_TEMPLATES);
2400:                _tags.put("apply-imports", APPLY_IMPORTS);
2401:                _tags.put("call-template", CALL_TEMPLATE);
2402:                _tags.put("param", PARAM);
2403:                _tags.put("variable", VARIABLE);
2404:                _tags.put("for-each", FOR_EACH);
2405:                _tags.put("if", IF);
2406:                _tags.put("choose", CHOOSE);
2407:
2408:                _tags.put("value-of", VALUE_OF);
2409:                _tags.put("copy-of", COPY_OF);
2410:                _tags.put("text", XSL_TEXT);
2411:                _tags.put("#text", TEXT);
2412:                _tags.put("number", NUMBER);
2413:                _tags.put("copy", COPY);
2414:                _tags.put("element", ELEMENT);
2415:                _tags.put("attribute", ATTRIBUTE);
2416:                _tags.put("pi", PI);
2417:                _tags.put("processing-instruction", PI);
2418:                _tags.put("comment", COMMENT);
2419:
2420:                _tags.put("message", MESSAGE);
2421:
2422:                _tags.put("sort", IGNORE);
2423:                _tags.put("fallback", IGNORE);
2424:                // xslt 2.0
2425:                _tags.put("result-document", RESULT_DOCUMENT);
2426:
2427:                _xtpTags = new IntMap();
2428:                _xtpTags.put("expression", EXPRESSION);
2429:                _xtpTags.put("expr", EXPRESSION);
2430:                _xtpTags.put("eval", EXPRESSION);
2431:                _xtpTags.put("scriptlet", SCRIPTLET);
2432:                _xtpTags.put("script", SCRIPTLET);
2433:                _xtpTags.put("decl", DECLARATION);
2434:                _xtpTags.put("declaration", DECLARATION);
2435:                _xtpTags.put("directive.cache", DIRECTIVE_CACHE);
2436:                _xtpTags.put("while", WHILE);
2437:                _xtpTags.put("assign", ASSIGN);
2438:            }
2439:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.