X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=source%2Fmir%2Fgenerator%2Ftal%2FTALTemplateParser.java;h=9c06c61bde7e8523b16071fbaa1a7f4b1bd3d6d4;hb=HEAD;hp=ba739192728346a8b0fda50b56f0b5a31f297e6c;hpb=a841b85307a342bbaaf328ab2a79d9dbc4619b1f;p=mir.git diff --git a/source/mir/generator/tal/TALTemplateParser.java b/source/mir/generator/tal/TALTemplateParser.java index ba739192..9c06c61b 100755 --- a/source/mir/generator/tal/TALTemplateParser.java +++ b/source/mir/generator/tal/TALTemplateParser.java @@ -1,244 +1,220 @@ -/* - * Copyright (C) 2001, 2002 The Mir-coders group - * - * This file is part of Mir. - * - * Mir is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Mir is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mir; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * In addition, as a special exception, The Mir-coders gives permission to link - * the code of this program with any library licensed under the Apache Software License, - * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library - * (or with modified versions of the above that use the same license as the above), - * and distribute linked combinations including the two. You must obey the - * GNU General Public License in all respects for all of the code used other than - * the above mentioned libraries. If you modify this file, you may extend this - * exception to your version of the file, but you are not obligated to do so. - * If you do not wish to do so, delete this exception statement from your version. - */ -package mir.generator.tal; - -import java.io.InputStream; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import mir.generator.tal.interfaces.TALExpressionParser; -import mir.util.HTMLRoutines; -import mir.util.StringRoutines; -import mir.util.XMLReader; -import mir.util.XMLReader.AbstractSectionHandler; - -public class TALTemplateParser { - private int bal; - private static final String TAL_PREFIX = "tal"; - - public static TALTemplate parseString(String aData, TALExpressionParser aParser) throws TALExc, TALFailure { - try { - TALHandler handler = new TALHandler(aParser); - XMLReader reader = new XMLReader(false); - - reader.parseString(aData, handler); - - return new TALTemplate(aParser, handler.getNode()); - } - catch (Throwable t) { - throw new TALFailure(t); - } - } - - public static TALTemplate parseInputStream(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure { - try { - TALHandler handler = new TALHandler(aParser); - XMLReader reader = new XMLReader(false); - - reader.parseInputStream(anInputStream, handler); - - return new TALTemplate(aParser, handler.getNode()); - } - catch (Throwable t) { - throw new TALFailure(t); - } - } - - private static final String CONDITION_ATTRIBUTE = "tal:condition"; - private static final String REPEAT_ATTRIBUTE = "tal:repeat"; - private static final String CONTENT_ATTRIBUTE = "tal:content"; - private static final String ERROR_ATTRIBUTE = "tal:on-error"; - private static final String REPLACE_ATTRIBUTE = "tal:replace"; - private static final String DEFINITION_ATTRIBUTE = "tal:define"; - private static final String ONERROR_ATTRIBUTE = "tal:onerror"; - private static final String OMITTAG_ATTRIBUTE = "tal:omit-tag"; - private static final String ATTRIBUTE_ATTRIBUTE = "tal:attributes"; - - - protected static class TALHandler extends XMLReader.AbstractSectionHandler { - private TALTemplate.CompositeTemplateNode compositeNode; - private StringBuffer data; - private TALExpressionParser parser; - private TALTemplate.SmartTemplateNode smartNode; - private boolean smartTag; - private String currentTag; - - public TALHandler(TALExpressionParser aParser) { - parser = aParser; - data = new StringBuffer(); - compositeNode = new TALTemplate.CompositeTemplateNode(); - } - - private void flushData() { - if (data.length()!=0) { - compositeNode.appendSubNode(new TALTemplate.PlainTextTemplateNode(data.toString())); - data.delete(0, data.length()); - } - } - - public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc { - smartTag = false; - - currentTag = aTag.getLocalName(); - if (aTag.getPrefix().length()>0) - currentTag = aTag.getPrefix() + ":" + currentTag; - - smartTag = (aTag.getPrefix().equals(TAL_PREFIX)); - - Iterator i = anAttributes.keySet().iterator(); - - while (!smartTag && i.hasNext()) { - XMLReader.XMLName name = (XMLReader.XMLName) i.next(); - smartTag = smartTag || (name.getPrefix().equals(TAL_PREFIX)); - } - - if (!smartTag) { - appendCode("<"+currentTag); - i = anAttributes.entrySet().iterator(); - - while (i.hasNext()) { - Map.Entry entry = (Map.Entry) i.next(); - - appendCode(" "+ (String) entry.getKey()); - appendCode("=\""); - appendText((String) entry.getValue()); - appendCode("\""); - } - appendCode(">"); - } - else { - smartNode = new TALTemplate.SmartTemplateNode(currentTag); - if (aTag.getPrefix().equals(TAL_PREFIX)) - smartNode.setOmitTag(parser.preparseTRUE()); - - i = anAttributes.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry entry = (Map.Entry) i.next(); - XMLReader.XMLName name = (XMLReader.XMLName) entry.getKey(); - - if (!name.getPrefix().equals(TAL_PREFIX)) { - smartNode.addFixedAttribute(name.getLocalName(), (String) entry.getValue()); - } - else { - if (name.getLocalName().equalsIgnoreCase(DEFINITION_ATTRIBUTE)) { - List definitions = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\'); - - Iterator j = definitions.iterator(); { - List parts = StringRoutines.separateString((String) i.next(), " "); - - if (parts.size()==2) { - smartNode.addDefinition(parser.preparseReferenceExpression((String) parts.get(0)), parser.preparseExpression((String) parts.get(1))); - } - } - } - else if (name.getLocalName().equalsIgnoreCase(CONDITION_ATTRIBUTE)) { - smartNode.setCondition(parser.preparseBooleanExpression((String) entry.getValue())); - } - else if (name.getLocalName().equalsIgnoreCase(CONTENT_ATTRIBUTE)) { - smartNode.setContent(parser.preparseStringExpression((String) entry.getValue())); - } - else if (name.getLocalName().equalsIgnoreCase(ERROR_ATTRIBUTE)) { - smartNode.setError(parser.preparseStringExpression((String) entry.getValue())); - } - else if (name.getLocalName().equalsIgnoreCase(OMITTAG_ATTRIBUTE)) { - if (((String) entry.getValue()).trim().length()==0) - smartNode.setOmitTag(parser.preparseTRUE()); - else - smartNode.setOmitTag(parser.preparseBooleanExpression((String) entry.getValue())); - } - else if (name.getLocalName().equalsIgnoreCase(REPLACE_ATTRIBUTE)) { - smartNode.setOmitTag(parser.preparseTRUE()); - smartNode.setContent(parser.preparseStringExpression((String) entry.getValue())); - } - else if (name.getLocalName().equalsIgnoreCase(REPEAT_ATTRIBUTE)) { - List parts = StringRoutines.separateString((String) entry.getValue(), " "); - - if (parts.size()==2) { - smartNode.setRepeat(parser.preparseReferenceExpression((String) parts.get(0)), parser.preparseExpression((String) parts.get(1))); - } - } - else if (name.getLocalName().equalsIgnoreCase(ATTRIBUTE_ATTRIBUTE)) { - List attributes = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\'); - - Iterator j = attributes.iterator(); { - List parts = StringRoutines.separateString((String) i.next(), " "); - - if (parts.size()==2) { - smartNode.addModifiedAttribute((String) parts.get(0), parser.preparseExpression((String) parts.get(1))); - } - } - } - } - } - } - - flushData(); - - return new TALHandler(parser); - }; - - public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc { - if (!smartTag) { - appendSubNode(((TALHandler) aHandler).getNode()); - appendCode(""); - } - else { - smartNode.setBody(((TALHandler) aHandler).getNode()); - appendSubNode(smartNode); - smartNode=null; - } - }; - - protected void appendSubNode(TALTemplate.TemplateNode aNode) { - compositeNode.appendSubNode(aNode); - } - - protected void appendCode(String aCode) { - data.append(aCode); - } - - protected void appendText(String aText) { - data.append(HTMLRoutines.encodeHTML(aText)); - } - - public void finishSection() throws XMLReader.XMLReaderExc { - flushData(); - } - - public TALTemplate.TemplateNode getNode() { - return compositeNode; - } - - public void characters(String aCharacters) throws XMLReader.XMLReaderExc { - appendText(aCharacters); - } - } -} +/* + * Copyright (C) 2005 The Mir-coders group + * + * This file is part of Mir. + * + * Mir is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Mir is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mir; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, The Mir-coders gives permission to link + * the code of this program with any library licensed under the Apache Software License. + * You must obey the GNU General Public License in all respects for all of the code used + * other than the above mentioned libraries. If you modify this file, you may extend this + * exception to your version of the file, but you are not obligated to do so. + * If you do not wish to do so, delete this exception statement from your version. + */ +package mir.generator.tal; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import mir.generator.tal.interfaces.TALExpressionParser; +import mir.generator.tal.template.CompositeTemplateNode; +import mir.generator.tal.template.PlainTextTemplateNode; +import mir.generator.tal.template.Template; +import mir.generator.tal.template.TemplateNode; +import mir.generator.tal.template.TemplateNodeLibrary; +import mir.generator.tal.template.TemplateNodeLibraryRegistry; +import mir.util.HTMLRoutines; +import mir.util.xml.SectionHandler; +import mir.util.xml.XMLName; +import mir.util.xml.XMLParserEngine; +import mir.util.xml.XMLParserExc; +import mir.util.xml.XMLParserFailure; +import mir.util.xml.XMLReaderTool; + +public class TALTemplateParser { + private TemplateNodeLibraryRegistry registry; + + public TALTemplateParser(TemplateNodeLibraryRegistry aRegistry) { + registry = aRegistry; + } + + public Template parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure { + return parse(new StringReader(aData), aParser); + } + + public Template parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure { + try { + return parse(new BufferedInputStream(new FileInputStream(aFile), 1024*128), aParser); + } + catch (FileNotFoundException e) { + throw new TALFailure(e); + } + } + public Template parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure { + return parse(new InputStreamReader(anInputStream), aParser); + } + + public Template parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure { + Map templateContext = new HashMap(); + TALHandler handler = new TALHandler(aParser, templateContext); + + try { + XMLParserEngine.getInstance().parse("html", aReader, handler); + } + catch (XMLParserExc e) { + throw new TALFailure(e); + } + + return new Template(aParser, handler.getNode(), templateContext); + } + + protected class TALHandler implements SectionHandler { + private CompositeTemplateNode compositeNode; + private StringBuffer data; + private StringBuffer plainData; + private TALExpressionParser parser; + private String currentTag; + private TemplateNodeLibrary library; + private XMLName tag; + private Map attributes; + private Map templateContext; + + public TALHandler(TALExpressionParser aParser, Map aTemplateContext) { + parser = aParser; + data = new StringBuffer(); + plainData = new StringBuffer(); + compositeNode = new CompositeTemplateNode(); + templateContext = aTemplateContext; + } + + private void flushData() { + if (data.length()!=0) { + compositeNode.appendSubNode(new PlainTextTemplateNode(data.toString(), plainData.toString())); + data.delete(0, data.length()); + plainData.delete(0, plainData.length()); + } + } + + public void extra(String anExtraData) throws XMLParserExc, XMLParserFailure { + appendCode(anExtraData); + } + + public TemplateNodeLibrary findLibrary(XMLName aName) { + TemplateNodeLibrary result = null; + + if (aName.getNamespaceURI()!=null) { + result = registry.findLibraryForUrl(aName.getNamespaceURI()); + } + + if ((result == null) && (aName.getPrefix()!=null) && (aName.getPrefix().length()>0)) { + result = registry.findLibraryForPrefix(aName.getPrefix()); + } + + return result; + } + + public SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc { + library = findLibrary(aTag); + + Iterator i = anAttributes.keySet().iterator(); + while (library==null && i.hasNext()) { + library=findLibrary((XMLName) i.next()); + } + + currentTag = XMLReaderTool.normalizeXMLName(aTag); + + if (library == null) { + appendCode("<"+currentTag); + i = anAttributes.entrySet().iterator(); + + while (i.hasNext()) { + Map.Entry entry = (Map.Entry) i.next(); + + appendCode(" "+ XMLReaderTool.normalizeXMLName((XMLName) entry.getKey())); + appendCode("=\""); + appendText((String) entry.getValue()); + appendCode("\""); + } + } + else { + tag = aTag; + attributes = anAttributes; + } + + return new TALHandler(parser, templateContext); + } + + public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc { + if (library == null) { + TemplateNode subNode = ((TALHandler) aHandler).getNode(); + if (subNode instanceof CompositeTemplateNode && + ((CompositeTemplateNode) subNode).isEmpty()) { + appendCode(" />"); + } + else { + appendCode(">"); + appendSubNode(subNode); + appendCode(""); + } + } + else { + appendSubNode( + library.constructTemplateNode(parser, tag, attributes, ((TALHandler) aHandler).getNode(), templateContext)); + tag = null; + attributes = null; + } + } + + protected void appendSubNode(TemplateNode aNode) { + flushData(); + + compositeNode.appendSubNode(aNode); + } + + protected void appendCode(String aCode) { + data.append(aCode); + } + + protected void appendText(String aText) { + data.append(HTMLRoutines.encodeHTML(aText)); + plainData.append(aText); + } + + public void finishSection() throws XMLParserExc { + flushData(); + } + + public TemplateNode getNode() { + return compositeNode; + } + + public void characters(String aCharacters) throws XMLParserExc { + appendText(aCharacters); + } + + public void startSection() throws XMLParserExc, XMLParserFailure { + } + } +}