fixed/rearranged some tal stuff
[mir.git] / source / mir / generator / tal / TALTemplateParser.java
index f82ec6a..d37f95f 100755 (executable)
  */
 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.io.File;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
 import java.util.Iterator;
-import java.util.List;
 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.TALTemplate;
+import mir.generator.tal.template.TALTemplateNodeLibrary;
+import mir.generator.tal.template.TemplateNode;
 import mir.util.HTMLRoutines;
-import mir.util.StringRoutines;
-import mir.util.xml.XMLParserExc;
-import mir.util.xml.XMLParserEngine;
-import mir.util.xml.XMLParserFailure;
 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;
+
+// TODO: add a templatelibrary repository and remove dependency of TALTemplateEngine
 
 public class TALTemplateParser {
-  private static final String TAL_PREFIX = "tal";
+  private TALTemplateEngine engine;
 
-  public static TALTemplate parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {
+  //private static final String TAL_PREFIX = "tal";
+  public TALTemplateParser(TALTemplateEngine anEngine) {
+    engine = anEngine;
+  }
+
+  public TALTemplate parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {
     return parse(new StringReader(aData), aParser);
   }
 
-  public static TALTemplate parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public TALTemplate parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure {
     try {
       return parse(new BufferedInputStream(new FileInputStream(aFile), 1024*128), aParser);
     }
@@ -65,11 +76,11 @@ public class TALTemplateParser {
       throw new TALFailure(e);
     }
   }
-  public static TALTemplate parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public TALTemplate parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {
     return parse(new InputStreamReader(anInputStream), aParser);
   }
 
-  public static TALTemplate parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public TALTemplate parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure {
     TALHandler handler = new TALHandler(aParser);
 
     try {
@@ -82,40 +93,24 @@ public class TALTemplateParser {
     return new TALTemplate(aParser, handler.getNode());
   }
 
-  private static String normalizeXMLName(mir.util.xml.XMLName aName) {
-    String result = aName.getLocalName();
-    if (aName.getPrefix().length() > 0)
-      result = aName.getPrefix() + ":" + result;
-
-    return result;
-  }
-
-  private static final String CONDITION_ATTRIBUTE = "condition";
-  private static final String REPEAT_ATTRIBUTE = "repeat";
-  private static final String CONTENT_ATTRIBUTE = "content";
-  private static final String ERROR_ATTRIBUTE = "on-error";
-  private static final String REPLACE_ATTRIBUTE = "replace";
-  private static final String DEFINITION_ATTRIBUTE = "define";
-  private static final String OMITTAG_ATTRIBUTE = "omit-tag";
-  private static final String ATTRIBUTE_ATTRIBUTE = "attributes";
-
-  protected static class TALHandler implements SectionHandler {
-    private TALTemplate.CompositeTemplateNode compositeNode;
+  protected class TALHandler implements SectionHandler {
+    private CompositeTemplateNode compositeNode;
     private StringBuffer data;
     private TALExpressionParser parser;
-    private TALTemplate.SmartTemplateNode smartNode;
-    private boolean smartTag;
     private String currentTag;
+    private TALTemplateNodeLibrary library;
+    private XMLName tag;
+    private Map attributes;
 
     public TALHandler(TALExpressionParser aParser) {
       parser = aParser;
       data = new StringBuffer();
-      compositeNode = new TALTemplate.CompositeTemplateNode();
+      compositeNode = new CompositeTemplateNode();
     }
 
     private void flushData() {
       if (data.length()!=0) {
-        compositeNode.appendSubNode(new TALTemplate.PlainTextTemplateNode(data.toString()));
+        compositeNode.appendSubNode(new PlainTextTemplateNode(data.toString()));
         data.delete(0, data.length());
       }
     }
@@ -124,26 +119,38 @@ public class TALTemplateParser {
       appendCode(anExtraData);
     }
 
-    public SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
-      smartTag = false;
+    public TALTemplateNodeLibrary findLibrary(XMLName aName) {
+      TALTemplateNodeLibrary result = null;
+
+      if (aName.getNamespaceURI()!=null) {
+        result = engine.getLibraryForUrl(aName.getNamespaceURI());
+      }
+
+      if ((result == null) && (aName.getPrefix()!=null) && (aName.getPrefix().length()>0)) {
+        result = engine.getLibraryForPrefix(aName.getPrefix());
+      }
 
-      currentTag = normalizeXMLName(aTag);
-      smartTag = (aTag.getPrefix().equals(TAL_PREFIX));
+      return result;
+    }
+
+    public SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
+      library = findLibrary(aTag);
 
       Iterator i = anAttributes.keySet().iterator();
-      while (!smartTag && i.hasNext()) {
-        XMLName name = (XMLName) i.next();
-        smartTag = smartTag || (name.getPrefix().equals(TAL_PREFIX));
+      while (library==null && i.hasNext()) {
+        library=findLibrary((XMLName) i.next());
       }
 
-      if (!smartTag) {
+      currentTag = XMLReaderTool.normalizeXMLName(aTag);
+
+      if (library == null) {
         appendCode("<"+currentTag);
         i = anAttributes.entrySet().iterator();
 
         while (i.hasNext()) {
           Map.Entry entry = (Map.Entry) i.next();
 
-          appendCode(" "+ normalizeXMLName((XMLName) entry.getKey()));
+          appendCode(" "+ XMLReaderTool.normalizeXMLName((XMLName) entry.getKey()));
           appendCode("=\"");
           appendText((String) entry.getValue());
           appendCode("\"");
@@ -151,96 +158,28 @@ public class TALTemplateParser {
         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();
-          XMLName name = (XMLName) entry.getKey();
-
-          if (!name.getPrefix().equals(TAL_PREFIX)) {
-            smartNode.addFixedAttribute(normalizeXMLName(name), (String) entry.getValue());
-          }
-          else {
-            if (name.getLocalName().equalsIgnoreCase(DEFINITION_ATTRIBUTE)) {
-              List definitions = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');
-
-              Iterator j = definitions.iterator();
-              while (j.hasNext())
-              {
-                List parts = StringRoutines.separateString((String) j.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();
-              while (j.hasNext()) {
-                String value = (String) j.next();
-                List parts = StringRoutines.separateString(value, " ");
-
-                if (parts.size()==2) {
-                  smartNode.addModifiedAttribute((String) parts.get(0), parser.preparseExpression((String) parts.get(1)));
-                }
-                else {
-                  throw new XMLParserExc(ATTRIBUTE_ATTRIBUTE + " tag should have exactly 2 parts ("+value+")");
-                }
-              }
-            }
-          }
-        }
+        tag = aTag;
+        attributes = anAttributes;
       }
 
-      flushData();
-
       return new TALHandler(parser);
     };
 
     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
-      if (!smartTag) {
+      if (library == null) {
         appendSubNode(((TALHandler) aHandler).getNode());
         appendCode("</"+currentTag+">");
       }
       else {
-        smartNode.setBody(((TALHandler) aHandler).getNode());
-        appendSubNode(smartNode);
-        smartNode=null;
+        appendSubNode(library.constructTemplateNode(parser, tag, attributes, ((TALHandler) aHandler).getNode()));
+        tag = null;
+        attributes = null;
       }
     };
 
-    protected void appendSubNode(TALTemplate.TemplateNode aNode) {
+    protected void appendSubNode(TemplateNode aNode) {
+      flushData();
+
       compositeNode.appendSubNode(aNode);
     }
 
@@ -256,7 +195,7 @@ public class TALTemplateParser {
       flushData();
     }
 
-    public TALTemplate.TemplateNode getNode() {
+    public TemplateNode getNode() {
       return compositeNode;
     }