--- /dev/null
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two. You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries. If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+\r
+package mir.generator.tal.template;\r
+\r
+import java.util.*;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.generator.tal.interfaces.TALLogger;\r
+import mir.util.HTMLRoutines;\r
+import mir.util.StringRoutines;\r
+import mir.util.xml.XMLName;\r
+import mir.util.xml.XMLParserExc;\r
+import mir.util.xml.XMLReaderTool;\r
+\r
+public class CoreTemplateNodeLibrary implements TemplateNodeLibrary {\r
+ private String prefix;\r
+ private String uri;\r
+\r
+ private boolean isOurTag(XMLName aName) {\r
+ return prefix.equals(aName.getPrefix()) || uri.equals(aName.getNamespaceURI());\r
+ }\r
+\r
+ public CoreTemplateNodeLibrary(String aPrefix, String aUri) {\r
+ prefix = aPrefix;\r
+ uri = aUri;\r
+ }\r
+\r
+ private static final String CONDITION_ATTRIBUTE = "condition";\r
+ private static final String REPEAT_ATTRIBUTE = "repeat";\r
+ private static final String CONTENT_ATTRIBUTE = "content";\r
+ private static final String ERROR_ATTRIBUTE = "on-error";\r
+ private static final String REPLACE_ATTRIBUTE = "replace";\r
+ private static final String DEFINITION_ATTRIBUTE = "define";\r
+ private static final String OMITTAG_ATTRIBUTE = "omit-tag";\r
+ private static final String ATTRIBUTE_ATTRIBUTE = "attributes";\r
+\r
+ public TemplateNode constructTemplateNode(TALExpressionParser aParser, XMLName aTag, Map anAttributes,\r
+ TemplateNode aChildTemplateNode, Map aTemplateContext) throws XMLParserExc {\r
+ TALBasicTemplateNode result = new TALBasicTemplateNode(XMLReaderTool.normalizeXMLName(aTag));\r
+ result.setBody(aChildTemplateNode);\r
+\r
+ if (isOurTag(aTag))\r
+ result.setOmitTag(aParser.preparseTRUE());\r
+\r
+ Iterator i = anAttributes.entrySet().iterator();\r
+ while (i.hasNext()) {\r
+ Map.Entry entry = (Map.Entry) i.next();\r
+ XMLName name = (XMLName) entry.getKey();\r
+\r
+ if (!isOurTag(name)) {\r
+ result.addFixedAttribute(XMLReaderTool.normalizeXMLName(name), (String) entry.getValue());\r
+ }\r
+ else {\r
+ if (name.getLocalName().equalsIgnoreCase(DEFINITION_ATTRIBUTE)) {\r
+ List definitions = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
+\r
+ Iterator j = definitions.iterator();\r
+ while (j.hasNext())\r
+ {\r
+ List parts = StringRoutines.separateString((String) j.next(), " ");\r
+\r
+ if (parts.size()==2) {\r
+ result.addDefinition(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
+ }\r
+ }\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(CONDITION_ATTRIBUTE)) {\r
+ result.setCondition(aParser.preparseBooleanExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(CONTENT_ATTRIBUTE)) {\r
+ result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(ERROR_ATTRIBUTE)) {\r
+ result.setError(aParser.preparseStringExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(OMITTAG_ATTRIBUTE)) {\r
+ if (((String) entry.getValue()).trim().length()==0)\r
+ result.setOmitTag(aParser.preparseTRUE());\r
+ else\r
+ result.setOmitTag(aParser.preparseBooleanExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(REPLACE_ATTRIBUTE)) {\r
+ result.setOmitTag(aParser.preparseTRUE());\r
+ result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(REPEAT_ATTRIBUTE)) {\r
+ List parts = StringRoutines.separateString((String) entry.getValue(), " ");\r
+\r
+ if (parts.size()==2) {\r
+ result.setRepeat(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
+ }\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(ATTRIBUTE_ATTRIBUTE)) {\r
+ List attributes = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
+\r
+ Iterator j = attributes.iterator();\r
+ while (j.hasNext()) {\r
+ String value = (String) j.next();\r
+ List parts = StringRoutines.separateString(value.trim(), " ");\r
+\r
+ if (parts.size()==2) {\r
+ result.addModifiedAttribute((String) parts.get(0), aParser.preparseExpression((String) parts.get(1)));\r
+ }\r
+ else {\r
+ throw new XMLParserExc(ATTRIBUTE_ATTRIBUTE + " tag should have exactly 2 parts ("+value+")");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+ public static class TALBasicTemplateNode implements TemplateNode {\r
+ private String tag;\r
+ private Map fixedAttributes;\r
+ private Map attributeModifiers;\r
+\r
+ private List definitions;\r
+ private Object condition;\r
+\r
+ private Object repeatVariable;\r
+ private Object repeatExpression;\r
+ private Object contentExpression;\r
+ private Object omitTagExpression;\r
+ private Object errorExpression;\r
+\r
+ private TemplateNode body;\r
+\r
+ public TALBasicTemplateNode(String aTag) {\r
+ tag = aTag;\r
+\r
+ fixedAttributes = new HashMap();\r
+ attributeModifiers = new HashMap();\r
+\r
+ definitions = new ArrayList();\r
+ condition = null;\r
+\r
+ repeatVariable = null;\r
+ repeatExpression = null;\r
+ contentExpression = null;\r
+ omitTagExpression = null;\r
+\r
+ body = null;\r
+ }\r
+\r
+ public void setBody(TemplateNode aBody) {\r
+ body = aBody;\r
+ }\r
+\r
+ public void addFixedAttribute(String aKey, String aValue) {\r
+ fixedAttributes.put(aKey, aValue);\r
+ }\r
+\r
+ public void addModifiedAttribute(String aKey, Object aValue) {\r
+ attributeModifiers.put(aKey, aValue);\r
+ }\r
+\r
+ public void addDefinition(Object aKey, Object aValue) {\r
+ definitions.add(new Definition(aKey, aValue));\r
+ }\r
+\r
+ public void setCondition(Object aCondition) {\r
+ condition = aCondition;\r
+ }\r
+\r
+ public void setRepeat(Object aRepeatVariable, Object aRepeatExpression) {\r
+ repeatVariable = aRepeatVariable;\r
+ repeatExpression = aRepeatExpression;\r
+ }\r
+\r
+ public void setContent(Object aContentExpression) {\r
+ contentExpression = aContentExpression;\r
+ }\r
+\r
+ public void setOmitTag(Object anOmitTagExpression) {\r
+ omitTagExpression = anOmitTagExpression;\r
+ }\r
+\r
+ public void setError(Object anErrorExpression) {\r
+ errorExpression = anErrorExpression;\r
+ }\r
+\r
+ public static class Definition {\r
+ private Object variable;\r
+ private Object expression;\r
+\r
+ public Definition(Object aVariable, Object anExpression) {\r
+ variable = aVariable;\r
+ expression = anExpression;\r
+ }\r
+\r
+ public Object getVariable() {\r
+ return variable;\r
+ }\r
+\r
+ public Object getExpression() {\r
+ return expression;\r
+ }\r
+ }\r
+\r
+ public void process(TALExpressionParser aParser, Object aContext,\r
+ StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext,\r
+ TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+ if (errorExpression != null) {\r
+ StringBuffer destination = new StringBuffer();\r
+\r
+ try {\r
+ outerProcess(aParser, aContext, destination, aLogger, aTemplateContext, aLibrary);\r
+ }\r
+ catch (Throwable t) {\r
+ try {\r
+// destination.delete(0, destination.length());\r
+ aParser.processPseudoAssignment(aContext, "exception", t);\r
+ destination.insert(0, aParser.evaluateStringExpression(aContext, errorExpression));\r
+ destination.append(" >>>ERROR POSITION<<< ");\r
+ }\r
+ catch (Throwable s) {\r
+ throw new TemplateProcessingException(s);\r
+ }\r
+ }\r
+ finally {\r
+ aDestination.append(destination);\r
+ }\r
+ }\r
+ else {\r
+ outerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+ }\r
+ }\r
+\r
+ public String getPlainText() {\r
+ return body.getPlainText();\r
+ }\r
+\r
+ public void outerProcess(TALExpressionParser aParser, Object aContext,\r
+ StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext,\r
+ TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+\r
+ Object oldAttributes = aParser.evaluatePseudoVariable(aContext, "tagattributes");\r
+ aParser.processPseudoAssignment(aContext, "tagattributes", Collections.unmodifiableMap(fixedAttributes));\r
+\r
+ Object oldContent = aParser.evaluatePseudoVariable(aContext, "tagcontent");\r
+ aParser.processPseudoAssignment(aContext, "tagcontent", body.getPlainText());\r
+\r
+ try {\r
+ Iterator i;\r
+\r
+ i = definitions.iterator();\r
+ while (i.hasNext()) {\r
+ Definition d = (Definition) i.next();\r
+ aParser.processAssignment(aContext, d.getVariable(), d.getExpression());\r
+ }\r
+\r
+ if (condition == null || aParser.evaluateBooleanExpression(aContext, condition)) {\r
+ if (repeatExpression != null) {\r
+ i = aParser.evaluateListExpression(aContext, repeatExpression);\r
+\r
+ while (i.hasNext()) {\r
+ aParser.processDirectAssignment(aContext, repeatVariable, i.next());\r
+ innerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+ }\r
+ }\r
+ else {\r
+ innerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+ }\r
+ }\r
+ }\r
+ finally {\r
+ try {\r
+ aParser.processPseudoAssignment(aContext, "tagattributes", oldAttributes);\r
+ aParser.processPseudoAssignment(aContext, "tagcontent", oldContent);\r
+ }\r
+ catch (Throwable t) {\r
+ }\r
+ }\r
+ };\r
+\r
+ private void innerProcess(TALExpressionParser aParser, Object aContext,\r
+ StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext, TemplateLibrary aLibrary)\r
+ throws TemplateProcessingException {\r
+\r
+ boolean omitTag = false;\r
+ StringBuffer content = aDestination;\r
+\r
+ if (omitTagExpression != null)\r
+ omitTag = aParser.evaluateBooleanExpression(aContext, omitTagExpression);\r
+\r
+ if (!omitTag) {\r
+ content = new StringBuffer();\r
+ Map generatedAttributes = new HashMap(fixedAttributes);\r
+\r
+ Iterator i = attributeModifiers.entrySet().iterator();\r
+ while (i.hasNext()) {\r
+ Map.Entry entry = (Map.Entry) i.next();\r
+\r
+ generatedAttributes.put(entry.getKey(), aParser.evaluateStringExpression(aContext, entry.getValue()));\r
+ }\r
+\r
+ aDestination.append("<");\r
+ aDestination.append(tag);\r
+\r
+ i = generatedAttributes.entrySet().iterator();\r
+ while (i.hasNext()) {\r
+ Map.Entry entry = (Map.Entry) i.next();\r
+ aDestination.append(" ");\r
+ aDestination.append(entry.getKey());\r
+ aDestination.append("=");\r
+ aDestination.append("\"");\r
+ aDestination.append(HTMLRoutines.encodeHTML( (String) entry.getValue()));\r
+ aDestination.append("\"");\r
+ }\r
+ }\r
+\r
+ try{\r
+ if (contentExpression != null) {\r
+ content.append(aParser.evaluateStringExpression(aContext, contentExpression));\r
+ }\r
+ else {\r
+ if (body != null) {\r
+ body.process(aParser, aContext, content, aLogger, aTemplateContext, aLibrary);\r
+ }\r
+ }\r
+ if (!omitTag) {\r
+ if (content.length()==0) {\r
+ aDestination.append(" />");\r
+ }\r
+ else {\r
+ aDestination.append(">");\r
+ aDestination.append(content);\r
+ aDestination.append("</");\r
+ aDestination.append(tag);\r
+ aDestination.append(">");\r
+ }\r
+ }\r
+ }\r
+ catch (Throwable t) {\r
+ if (!omitTag) {\r
+ aDestination.append(content);\r
+ }\r
+\r
+ if (t instanceof TemplateProcessingException) {\r
+ throw (TemplateProcessingException) t;\r
+ }\r
+ else if (t instanceof RuntimeException) {\r
+ throw (RuntimeException) t;\r
+ }\r
+ else throw new TemplateProcessingException(t.toString());\r
+ }\r
+ }\r
+ }\r
+}\r