2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
30 package mir.generator.tal;
32 import java.io.BufferedInputStream;
34 import java.io.FileInputStream;
35 import java.io.FileNotFoundException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.io.Reader;
39 import java.io.StringReader;
40 import java.util.Iterator;
42 import java.util.HashMap;
44 import mir.generator.tal.interfaces.TALExpressionParser;
45 import mir.generator.tal.template.CompositeTemplateNode;
46 import mir.generator.tal.template.PlainTextTemplateNode;
47 import mir.generator.tal.template.Template;
48 import mir.generator.tal.template.TemplateNodeLibrary;
49 import mir.generator.tal.template.TemplateNode;
50 import mir.generator.tal.template.TemplateNodeLibraryRegistry;
51 import mir.util.HTMLRoutines;
52 import mir.util.xml.SectionHandler;
53 import mir.util.xml.XMLName;
54 import mir.util.xml.XMLParserEngine;
55 import mir.util.xml.XMLParserExc;
56 import mir.util.xml.XMLParserFailure;
57 import mir.util.xml.XMLReaderTool;
59 public class TALTemplateParser {
60 private TemplateNodeLibraryRegistry registry;
62 public TALTemplateParser(TemplateNodeLibraryRegistry aRegistry) {
66 public Template parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {
67 return parse(new StringReader(aData), aParser);
70 public Template parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure {
72 return parse(new BufferedInputStream(new FileInputStream(aFile), 1024*128), aParser);
74 catch (FileNotFoundException e) {
75 throw new TALFailure(e);
78 public Template parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {
79 return parse(new InputStreamReader(anInputStream), aParser);
82 public Template parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure {
83 Map templateContext = new HashMap();
84 TALHandler handler = new TALHandler(aParser, templateContext);
87 XMLParserEngine.getInstance().parse("html", aReader, handler);
89 catch (XMLParserExc e) {
90 throw new TALFailure(e);
93 return new Template(aParser, handler.getNode(), templateContext);
96 protected class TALHandler implements SectionHandler {
97 private CompositeTemplateNode compositeNode;
98 private StringBuffer data;
99 private StringBuffer plainData;
100 private TALExpressionParser parser;
101 private String currentTag;
102 private TemplateNodeLibrary library;
104 private Map attributes;
105 private Map templateContext;
107 public TALHandler(TALExpressionParser aParser, Map aTemplateContext) {
109 data = new StringBuffer();
110 plainData = new StringBuffer();
111 compositeNode = new CompositeTemplateNode();
112 templateContext = aTemplateContext;
115 private void flushData() {
116 if (data.length()!=0) {
117 compositeNode.appendSubNode(new PlainTextTemplateNode(data.toString(), plainData.toString()));
118 data.delete(0, data.length());
119 plainData.delete(0, plainData.length());
123 public void extra(String anExtraData) throws XMLParserExc, XMLParserFailure {
124 appendCode(anExtraData);
127 public TemplateNodeLibrary findLibrary(XMLName aName) {
128 TemplateNodeLibrary result = null;
130 if (aName.getNamespaceURI()!=null) {
131 result = registry.findLibraryForUrl(aName.getNamespaceURI());
134 if ((result == null) && (aName.getPrefix()!=null) && (aName.getPrefix().length()>0)) {
135 result = registry.findLibraryForPrefix(aName.getPrefix());
141 public SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
142 library = findLibrary(aTag);
144 Iterator i = anAttributes.keySet().iterator();
145 while (library==null && i.hasNext()) {
146 library=findLibrary((XMLName) i.next());
149 currentTag = XMLReaderTool.normalizeXMLName(aTag);
151 if (library == null) {
152 appendCode("<"+currentTag);
153 i = anAttributes.entrySet().iterator();
155 while (i.hasNext()) {
156 Map.Entry entry = (Map.Entry) i.next();
158 appendCode(" "+ XMLReaderTool.normalizeXMLName((XMLName) entry.getKey()));
160 appendText((String) entry.getValue());
166 attributes = anAttributes;
169 return new TALHandler(parser, templateContext);
172 public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
173 if (library == null) {
174 TemplateNode subNode = ((TALHandler) aHandler).getNode();
175 if (subNode instanceof CompositeTemplateNode &&
176 ((CompositeTemplateNode) subNode).isEmpty()) {
181 appendSubNode(subNode);
182 appendCode("</"+currentTag+">");
187 library.constructTemplateNode(parser, tag, attributes, ((TALHandler) aHandler).getNode(), templateContext));
193 protected void appendSubNode(TemplateNode aNode) {
196 compositeNode.appendSubNode(aNode);
199 protected void appendCode(String aCode) {
203 protected void appendText(String aText) {
204 data.append(HTMLRoutines.encodeHTML(aText));
205 plainData.append(aText);
208 public void finishSection() throws XMLParserExc {
212 public TemplateNode getNode() {
213 return compositeNode;
216 public void characters(String aCharacters) throws XMLParserExc {
217 appendText(aCharacters);
220 public void startSection() throws XMLParserExc, XMLParserFailure {