--- /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
+package mir.generator;\r
+\r
+import java.io.PrintWriter;\r
+import java.util.Map;\r
+\r
+import mir.generator.tal.MirExpressionParser;\r
+import mir.generator.tal.TALTemplate;\r
+import mir.generator.tal.TALTemplateEngine;\r
+import mir.log.LoggerWrapper;\r
+\r
+public class TALGenerator implements Generator {\r
+ private String templateIdentifier;\r
+ private TALGeneratorLibrary library;\r
+ private static LoggerWrapper logger = new LoggerWrapper("Generator.velocity");\r
+\r
+ public TALGenerator(String aTemplate, TALGeneratorLibrary aLibrary) {\r
+ templateIdentifier = aTemplate;\r
+ library = aLibrary;\r
+ }\r
+\r
+ public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure {\r
+ TALTemplate template;\r
+\r
+ try {\r
+ template = library.engine.loadTemplate(templateIdentifier);\r
+ if (template == null) {\r
+ throw new GeneratorExc("TALGeneratorLibrary: Can't find template " + templateIdentifier);\r
+ }\r
+ template.processTemplate(aValues, (PrintWriter) anOutputWriter);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new GeneratorFailure(t);\r
+ }\r
+ }\r
+\r
+ public static class TALGeneratorLibrary implements GeneratorLibrary {\r
+ private TALTemplateEngine engine;\r
+\r
+ public TALGeneratorLibrary(String aTemplateRoot) throws GeneratorExc, GeneratorFailure {\r
+ engine = new TALTemplateEngine(new MirExpressionParser(), aTemplateRoot);\r
+ }\r
+\r
+ public Generator makeGenerator(String anIdentifier) throws GeneratorExc, GeneratorFailure {\r
+ return new TALGenerator(anIdentifier, this);\r
+ }\r
+ }\r
+\r
+ public static class TALGeneratorLibraryFactory implements GeneratorLibraryFactory {\r
+ private String basePath;\r
+\r
+ public TALGeneratorLibraryFactory(String aBasePath) {\r
+ basePath = aBasePath;\r
+ }\r
+\r
+ public GeneratorLibrary makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure {\r
+ return new TALGeneratorLibrary(basePath+anInitializationString);\r
+ };\r
+ }\r
+}\r
private VelocityGeneratorLibrary library;\r
private static LoggerWrapper logger = new LoggerWrapper("Generator.velocity");\r
\r
+ /**\r
+ *\r
+ * @param aTemplate\r
+ * @param aLibrary\r
+ */\r
+\r
public VelocityGenerator(String aTemplate, VelocityGeneratorLibrary aLibrary) {\r
templateIdentifier = aTemplate;\r
library = aLibrary;\r
}\r
\r
+ /**\r
+ *\r
+ * @param anOutputWriter\r
+ * @param aValues\r
+ * @param aLogger\r
+ * @throws GeneratorExc\r
+ * @throws GeneratorFailure\r
+ */\r
public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure {\r
Template template;\r
Context context = makeMapAdapter(aValues);\r
\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class ContextAdapter implements Context {\r
public boolean containsKey(java.lang.Object key) {\r
return false;\r
}\r
}\r
\r
+ /**\r
+ *\r
+ * @param aMap\r
+ * @return\r
+ */\r
private static Context makeMapAdapter(Map aMap) {\r
return new MapAdapter(aMap);\r
}\r
\r
+ /**\r
+ *\r
+ * @param anIterator\r
+ * @return\r
+ */\r
private static List makeIteratorAdapter(Iterator anIterator) {\r
return new IteratorAdapter(anIterator);\r
}\r
\r
+ /**\r
+ *\r
+ * @param aList\r
+ * @return\r
+ */\r
private static List makeListAdapter(List aList) {\r
return new ListAdapter(aList);\r
}\r
\r
-\r
+ /**\r
+ *\r
+ * @param aFunction\r
+ * @return\r
+ */\r
private static Object makeFunctionAdapter(Generator.GeneratorFunction aFunction) {\r
return new FunctionAdapter(aFunction);\r
}\r
\r
+ /**\r
+ *\r
+ * @param anObject\r
+ * @return\r
+ */\r
private static Object makeBeanAdapter(Object anObject) {\r
return new BeanAdapter(anObject);\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private interface VelocityAdapter {\r
public Object getOriginal();\r
}\r
\r
+ /**\r
+ *\r
+ * @param anObject\r
+ * @return\r
+ */\r
public static Object unmakeAdapter(Object anObject) {\r
if (anObject instanceof VelocityAdapter) {\r
return ((VelocityAdapter) anObject).getOriginal();\r
return anObject;\r
}\r
\r
+ /**\r
+ *\r
+ * @param anObject\r
+ * @return\r
+ */\r
public static Object makeAdapter(Object anObject) {\r
if (anObject == null)\r
return null;\r
return makeBeanAdapter(anObject);\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
public static class FunctionAdapter implements VelocityAdapter {\r
private GeneratorFunction function;\r
\r
}\r
\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class MapAdapter implements Context, VelocityAdapter {\r
private Map map;\r
private Map valuesCache;\r
}\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class IteratorAdapter extends AbstractList implements VelocityAdapter {\r
private Iterator iterator;\r
private List valuesCache;\r
\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class ListAdapter extends AbstractList implements VelocityAdapter {\r
private List list;\r
private List valuesCache;\r
\r
}\r
\r
-/*\r
- private static class FunctionAdapter implements TemplateMethodModel {\r
- private Generator.GeneratorFunction function;\r
-\r
- public FunctionAdapter(Generator.GeneratorFunction aFunction) {\r
- function = aFunction;\r
- }\r
-\r
- public TemplateModel exec(List anArguments) throws TemplateModelException {\r
- try {\r
- return makeAdapter(function.perform(anArguments));\r
- }\r
- catch (Throwable t) {\r
- throw new TemplateModelException(t.getMessage());\r
- }\r
- }\r
-\r
- public boolean isEmpty() {\r
- return false;\r
- }\r
-\r
- }\r
-\r
-*/\r
-\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class BeanAdapter implements Context, VelocityAdapter {\r
private Object object;\r
\r
}\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
private static class VelocityLoggerWrapper implements LogSystem {\r
private LoggerWrapper logger;\r
\r
}\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
public static class VelocityGeneratorLibrary implements GeneratorLibrary {\r
private VelocityEngine engine;\r
\r
logger.error(VelocityEngine.RUNTIME_LOG_LOGSYSTEM);\r
\r
}\r
-/* try {\r
- engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, null);\r
- }\r
- catch (Throwable t) {\r
- logger.error(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS);\r
-\r
- }\r
-*/\r
-\r
engine.init();\r
}\r
catch (Throwable t) {\r
}\r
}\r
\r
+ /**\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
public static class VelocityGeneratorLibraryFactory implements GeneratorLibraryFactory {\r
private String basePath;\r
\r
--- /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
+package mir.generator.tal;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.InputStream;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Vector;\r
+\r
+public class CachingFileLoader {\r
+ private Map cachedObjects;\r
+ private List history;\r
+ private int capacity;\r
+ private CachedFileObjectFactory factory;\r
+\r
+ public CachingFileLoader(int aCapacity, CachedFileObjectFactory aFactory) {\r
+ capacity = aCapacity;\r
+ cachedObjects = new HashMap();\r
+ history = new Vector();\r
+ factory = aFactory;\r
+ }\r
+\r
+ private void cacheObject(String aFilename, long aLastModified, Object anObject) {\r
+ synchronized (this) {\r
+ history.remove(aFilename);\r
+ history.add(aFilename);\r
+ while (history.size()>capacity && history.size()>0) {\r
+ history.remove(0);\r
+ }\r
+ cachedObjects.put(aFilename, new CachedObject(aFilename, aLastModified, anObject));\r
+ }\r
+ }\r
+\r
+ private Object constructObject(String aFilename) throws FileNotFoundException {\r
+ File file = new File(aFilename);\r
+ FileInputStream inputStream = new FileInputStream(file);\r
+ try {\r
+ Object result = factory.constructObject(inputStream);\r
+ cacheObject(aFilename, file.lastModified(), result);\r
+\r
+ return result;\r
+ }\r
+ finally {\r
+ try {\r
+ inputStream.close();\r
+ }\r
+ catch (Throwable t) {\r
+ }\r
+ }\r
+ }\r
+\r
+ private void revatilize(String aFilename) {\r
+ synchronized (this) {\r
+ history.remove(aFilename);\r
+ history.add(aFilename);\r
+ }\r
+ }\r
+\r
+ private class CachedObject {\r
+ private String filename;\r
+ private long lastModified;\r
+ private Object object;\r
+\r
+ public CachedObject(String aFilename, long aLastModified, Object anObject) {\r
+ filename = aFilename;\r
+ lastModified = aLastModified;\r
+ object = anObject;\r
+ }\r
+\r
+ public Object getObject() {\r
+ return object;\r
+ }\r
+\r
+ public String getFilename() {\r
+ return filename;\r
+ }\r
+\r
+ public long getLastModified() {\r
+ return lastModified;\r
+ }\r
+ }\r
+\r
+ public Object retrieveFile(String aFilename) throws FileNotFoundException {\r
+ synchronized (this) {\r
+ if (!cachedObjects.containsKey(aFilename)) {\r
+ return constructObject(aFilename);\r
+ }\r
+\r
+ CachedObject cachedObject = (CachedObject) cachedObjects.get(aFilename);\r
+ File file = new File(aFilename);\r
+ if (file.lastModified() != cachedObject.getLastModified()) {\r
+ return constructObject(aFilename);\r
+ }\r
+\r
+ revatilize(aFilename);\r
+\r
+ return cachedObject.getObject();\r
+ }\r
+ }\r
+\r
+ public interface CachedFileObjectFactory {\r
+ Object constructObject(InputStream aStream);\r
+ }\r
+}
\ No newline at end of file
--- /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;\r
+\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.util.ParameterExpander;\r
+import mir.util.RewindableIterator;\r
+\r
+public class MirExpressionParser implements TALExpressionParser {\r
+ public Object preparseExpression(String anExpression) {\r
+ return anExpression;\r
+ }\r
+ public Object preparseStringExpression(String anExpression) {\r
+ return anExpression;\r
+ }\r
+\r
+ public Object preparseBooleanExpression(String anExpression) {\r
+ return anExpression;\r
+ }\r
+\r
+ public Object preparseReferenceExpression(String anExpression) {\r
+ return anExpression;\r
+ }\r
+\r
+ public Object preparseListExpression(String anExpression) {\r
+ return anExpression;\r
+ }\r
+\r
+ public Object preparseTRUE() {\r
+ return "1==1";\r
+ }\r
+\r
+ public Object preparseFALSE() {\r
+ return "0==1";\r
+ }\r
+\r
+ public Object evaluateExpression(Object aContext, Object aPreparsedExpression) {\r
+ try {\r
+ return ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public String evaluateStringExpression(Object aContext, Object aPreparsedExpression) {\r
+ try {\r
+ return ParameterExpander.evaluateStringExpression(aContext, (String) aPreparsedExpression);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public boolean evaluateBooleanExpression(Object aContext, Object aPreparsedExpression) {\r
+ try {\r
+ return ParameterExpander.evaluateBooleanExpression(aContext, (String) aPreparsedExpression);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public Iterator evaluateListExpression(Object aContext, Object aPreparsedExpression) {\r
+ try {\r
+ Object list = ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression);\r
+\r
+ if (list instanceof List)\r
+ return ((List) list).iterator();\r
+\r
+ if (list instanceof RewindableIterator) {\r
+ ((RewindableIterator) list).rewind();\r
+ return (RewindableIterator) list;\r
+ }\r
+\r
+ if (list instanceof Iterator) {\r
+ return (Iterator) list;\r
+ }\r
+\r
+ throw new TALExc("Not a list: " + list);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public void processAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aPreparsedExpression) {\r
+ try {\r
+ ParameterExpander.setValueForKey( (Map) aContext, (String) aPreparsedReferenceExpression, ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression));\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public void processDirectAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aValue) {\r
+ try {\r
+ ParameterExpander.setValueForKey( (Map) aContext, (String) aPreparsedReferenceExpression, aValue);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public void processPseudoAssignment(Object aContext, String aName, Object aValue) {\r
+ try {\r
+ ParameterExpander.setValueForKey( (Map) aContext, aName, aValue);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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 multex.Exc;
+
+public class TALExc extends Exc {
+ public TALExc(String aMessage) {
+ super(aMessage);
+ }
+}
--- /dev/null
+/*
+ * 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 multex.Failure;
+
+public class TALFailure extends Failure {
+ public TALFailure(String msg,Throwable cause) {
+ super(msg,cause);
+ }
+
+ public TALFailure(Throwable aCause) {
+ this (aCause.getMessage(), aCause);
+ }
+}
--- /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
+package mir.generator.tal;\r
+\r
+import java.io.PrintWriter;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Vector;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.util.HTMLRoutines;\r
+\r
+/**\r
+ * {@link http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4}\r
+ *\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
+\r
+public class TALTemplate {\r
+ private TemplateNode rootNode;\r
+ private TALExpressionParser parser;\r
+\r
+ public TALTemplate(TALExpressionParser aParser, TemplateNode aRootNode) {\r
+ rootNode = aRootNode;\r
+ parser = aParser;\r
+ }\r
+\r
+ public void processTemplate(Object aContext, PrintWriter aDestination) {\r
+ StringBuffer output = new StringBuffer();\r
+\r
+ rootNode.process(parser, aContext, output);\r
+ aDestination.print(output);\r
+ }\r
+\r
+ public interface TemplateNode {\r
+ public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination);\r
+ }\r
+\r
+ public static class CompositeTemplateNode\r
+ implements TemplateNode {\r
+ private List parts;\r
+\r
+ public CompositeTemplateNode() {\r
+ parts = new Vector();\r
+ }\r
+\r
+ public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) {\r
+ Iterator i = parts.iterator();\r
+\r
+ while (i.hasNext()) {\r
+ ((TemplateNode) i.next()).process(aParser, aContext, aDestination);\r
+ }\r
+ }\r
+\r
+ public void appendSubNode(TemplateNode aNode) {\r
+ if (aNode instanceof CompositeTemplateNode) {\r
+ Iterator i = ((CompositeTemplateNode) aNode).parts.iterator();\r
+ while (i.hasNext()) {\r
+ appendSubNode((TemplateNode) i.next());\r
+ }\r
+ }\r
+ else if (aNode instanceof PlainTextTemplateNode && parts.size()>0 &&\r
+ (parts.get(parts.size()-1) instanceof PlainTextTemplateNode)) {\r
+\r
+ ((PlainTextTemplateNode) parts.get(parts.size()-1)).appendText(((PlainTextTemplateNode) aNode).getText());\r
+ }\r
+ else {\r
+ parts.add(aNode);\r
+ }\r
+ }\r
+ }\r
+\r
+ public static class PlainTextTemplateNode\r
+ implements TemplateNode {\r
+ private String text;\r
+\r
+ public PlainTextTemplateNode() {\r
+ this("");\r
+ }\r
+\r
+ public PlainTextTemplateNode(String aText) {\r
+ text = aText;\r
+ }\r
+\r
+ public void appendText(String aText) {\r
+ text = text + aText;\r
+ }\r
+\r
+ protected String getText() {\r
+ return text;\r
+ }\r
+\r
+ public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) {\r
+ aDestination.append(text);\r
+ }\r
+ }\r
+\r
+ public static class SmartTemplateNode 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 SmartTemplateNode(String aTag) {\r
+ tag = aTag;\r
+\r
+ fixedAttributes = new HashMap();\r
+ attributeModifiers = new HashMap();\r
+\r
+ definitions = new Vector();\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, StringBuffer aDestination) {\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);\r
+ }\r
+ }\r
+ else {\r
+ innerProcess(aParser, aContext, aDestination);\r
+ }\r
+\r
+ /*\r
+ define\r
+ condition\r
+ repeat\r
+ attributes\r
+ content\r
+ OR\r
+ replace\r
+ OR\r
+ omit-tag\r
+ content\r
+ * define\r
+ * condition\r
+ * repeat\r
+ * content\r
+ * attributes\r
+ * omit-tag\r
+ */\r
+ }\r
+ };\r
+\r
+ private void innerProcess(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) {\r
+ boolean omitTag = false;\r
+ if (omitTagExpression != null)\r
+ omitTag = aParser.evaluateBooleanExpression(aContext, omitTagExpression);\r
+\r
+ if (!omitTag) {\r
+ Map generatedAttributes = new HashMap(fixedAttributes);\r
+\r
+ Iterator i = attributeModifiers.keySet().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.keySet().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
+ aDestination.append(">");\r
+ }\r
+\r
+ StringBuffer destination = aDestination;\r
+ if (errorExpression != null) {\r
+ destination = new StringBuffer();\r
+ }\r
+ try {\r
+ if (contentExpression != null) {\r
+ destination.append(aParser.evaluateStringExpression(aContext, contentExpression));\r
+ }\r
+ else {\r
+ if (body != null)\r
+ body.process(aParser, aContext, destination);\r
+ }\r
+ }\r
+ catch (RuntimeException t) {\r
+ if (errorExpression != null) {\r
+ try {\r
+ destination.delete(0, destination.length());\r
+\r
+ aParser.processPseudoAssignment(aContext, "exception", t);\r
+ destination.append(aParser.evaluateStringExpression(aContext, errorExpression));\r
+ }\r
+ catch (Throwable s) {\r
+ }\r
+ }\r
+ else\r
+ throw t;\r
+ }\r
+ finally {\r
+ if (errorExpression != null) {\r
+ aDestination.append(destination);\r
+ }\r
+ }\r
+ if (!omitTag) {\r
+ aDestination.append("</");\r
+ aDestination.append(tag);\r
+ aDestination.append(">");\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /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;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+\r
+public class TALTemplateEngine {\r
+ private TALExpressionParser expressionParser;\r
+ private String basePath;\r
+ private CachingFileLoader loader;\r
+\r
+ public TALTemplateEngine(TALExpressionParser anExpressionParser, String aBasePath) {\r
+ expressionParser = anExpressionParser;\r
+ basePath = aBasePath;\r
+ loader = new CachingFileLoader(100, new TemplateFactory());\r
+ }\r
+\r
+ public TALTemplate loadTemplate(String aName) throws IOException {\r
+ File location = new File(basePath, aName);\r
+ return (TALTemplate) loader.retrieveFile(location.getCanonicalPath());\r
+ }\r
+\r
+ private class TemplateFactory implements CachingFileLoader.CachedFileObjectFactory {\r
+ public Object constructObject(InputStream aStream) {\r
+ try {\r
+ return TALTemplateParser.parseInputStream(aStream, expressionParser);\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /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
+package mir.generator.tal;\r
+\r
+import java.io.InputStream;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.util.HTMLRoutines;\r
+import mir.util.StringRoutines;\r
+import mir.util.XMLReader;\r
+import mir.util.XMLReader.AbstractSectionHandler;\r
+\r
+public class TALTemplateParser {\r
+ private int bal;\r
+ private static final String TAL_PREFIX = "tal";\r
+\r
+ public static TALTemplate parseString(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {\r
+ try {\r
+ TALHandler handler = new TALHandler(aParser);\r
+ XMLReader reader = new XMLReader(false);\r
+\r
+ reader.parseString(aData, handler);\r
+\r
+ return new TALTemplate(aParser, handler.getNode());\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ public static TALTemplate parseInputStream(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {\r
+ try {\r
+ TALHandler handler = new TALHandler(aParser);\r
+ XMLReader reader = new XMLReader(false);\r
+\r
+ reader.parseInputStream(anInputStream, handler);\r
+\r
+ return new TALTemplate(aParser, handler.getNode());\r
+ }\r
+ catch (Throwable t) {\r
+ throw new TALFailure(t);\r
+ }\r
+ }\r
+\r
+ private static final String CONDITION_ATTRIBUTE = "tal:condition";\r
+ private static final String REPEAT_ATTRIBUTE = "tal:repeat";\r
+ private static final String CONTENT_ATTRIBUTE = "tal:content";\r
+ private static final String ERROR_ATTRIBUTE = "tal:on-error";\r
+ private static final String REPLACE_ATTRIBUTE = "tal:replace";\r
+ private static final String DEFINITION_ATTRIBUTE = "tal:define";\r
+ private static final String ONERROR_ATTRIBUTE = "tal:onerror";\r
+ private static final String OMITTAG_ATTRIBUTE = "tal:omit-tag";\r
+ private static final String ATTRIBUTE_ATTRIBUTE = "tal:attributes";\r
+\r
+\r
+ protected static class TALHandler extends XMLReader.AbstractSectionHandler {\r
+ private TALTemplate.CompositeTemplateNode compositeNode;\r
+ private StringBuffer data;\r
+ private TALExpressionParser parser;\r
+ private TALTemplate.SmartTemplateNode smartNode;\r
+ private boolean smartTag;\r
+ private String currentTag;\r
+\r
+ public TALHandler(TALExpressionParser aParser) {\r
+ parser = aParser;\r
+ data = new StringBuffer();\r
+ compositeNode = new TALTemplate.CompositeTemplateNode();\r
+ }\r
+\r
+ private void flushData() {\r
+ if (data.length()!=0) {\r
+ compositeNode.appendSubNode(new TALTemplate.PlainTextTemplateNode(data.toString()));\r
+ data.delete(0, data.length());\r
+ }\r
+ }\r
+\r
+ public XMLReader.SectionHandler startElement(XMLReader.XMLName aTag, Map anAttributes) throws XMLReader.XMLReaderExc {\r
+ smartTag = false;\r
+\r
+ currentTag = aTag.getLocalName();\r
+ if (aTag.getPrefix().length()>0)\r
+ currentTag = aTag.getPrefix() + ":" + currentTag;\r
+\r
+ smartTag = (aTag.getPrefix().equals(TAL_PREFIX));\r
+\r
+ Iterator i = anAttributes.keySet().iterator();\r
+\r
+ while (!smartTag && i.hasNext()) {\r
+ XMLReader.XMLName name = (XMLReader.XMLName) i.next();\r
+ smartTag = smartTag || (name.getPrefix().equals(TAL_PREFIX));\r
+ }\r
+\r
+ if (!smartTag) {\r
+ appendCode("<"+currentTag);\r
+ i = anAttributes.entrySet().iterator();\r
+\r
+ while (i.hasNext()) {\r
+ Map.Entry entry = (Map.Entry) i.next();\r
+\r
+ appendCode(" "+ (String) entry.getKey());\r
+ appendCode("=\"");\r
+ appendText((String) entry.getValue());\r
+ appendCode("\"");\r
+ }\r
+ appendCode(">");\r
+ }\r
+ else {\r
+ smartNode = new TALTemplate.SmartTemplateNode(currentTag);\r
+ if (aTag.getPrefix().equals(TAL_PREFIX))\r
+ smartNode.setOmitTag(parser.preparseTRUE());\r
+\r
+ i = anAttributes.entrySet().iterator();\r
+ while (i.hasNext()) {\r
+ Map.Entry entry = (Map.Entry) i.next();\r
+ XMLReader.XMLName name = (XMLReader.XMLName) entry.getKey();\r
+\r
+ if (!name.getPrefix().equals(TAL_PREFIX)) {\r
+ smartNode.addFixedAttribute(name.getLocalName(), (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
+ List parts = StringRoutines.separateString((String) i.next(), " ");\r
+\r
+ if (parts.size()==2) {\r
+ smartNode.addDefinition(parser.preparseReferenceExpression((String) parts.get(0)), parser.preparseExpression((String) parts.get(1)));\r
+ }\r
+ }\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(CONDITION_ATTRIBUTE)) {\r
+ smartNode.setCondition(parser.preparseBooleanExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(CONTENT_ATTRIBUTE)) {\r
+ smartNode.setContent(parser.preparseStringExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(ERROR_ATTRIBUTE)) {\r
+ smartNode.setError(parser.preparseStringExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(OMITTAG_ATTRIBUTE)) {\r
+ if (((String) entry.getValue()).trim().length()==0)\r
+ smartNode.setOmitTag(parser.preparseTRUE());\r
+ else\r
+ smartNode.setOmitTag(parser.preparseBooleanExpression((String) entry.getValue()));\r
+ }\r
+ else if (name.getLocalName().equalsIgnoreCase(REPLACE_ATTRIBUTE)) {\r
+ smartNode.setOmitTag(parser.preparseTRUE());\r
+ smartNode.setContent(parser.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
+ smartNode.setRepeat(parser.preparseReferenceExpression((String) parts.get(0)), parser.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
+ List parts = StringRoutines.separateString((String) i.next(), " ");\r
+\r
+ if (parts.size()==2) {\r
+ smartNode.addModifiedAttribute((String) parts.get(0), parser.preparseExpression((String) parts.get(1)));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ flushData();\r
+\r
+ return new TALHandler(parser);\r
+ };\r
+\r
+ public void endElement(XMLReader.SectionHandler aHandler) throws XMLReader.XMLReaderExc {\r
+ if (!smartTag) {\r
+ appendSubNode(((TALHandler) aHandler).getNode());\r
+ appendCode("</"+currentTag+">");\r
+ }\r
+ else {\r
+ smartNode.setBody(((TALHandler) aHandler).getNode());\r
+ appendSubNode(smartNode);\r
+ smartNode=null;\r
+ }\r
+ };\r
+\r
+ protected void appendSubNode(TALTemplate.TemplateNode aNode) {\r
+ compositeNode.appendSubNode(aNode);\r
+ }\r
+\r
+ protected void appendCode(String aCode) {\r
+ data.append(aCode);\r
+ }\r
+\r
+ protected void appendText(String aText) {\r
+ data.append(HTMLRoutines.encodeHTML(aText));\r
+ }\r
+\r
+ public void finishSection() throws XMLReader.XMLReaderExc {\r
+ flushData();\r
+ }\r
+\r
+ public TALTemplate.TemplateNode getNode() {\r
+ return compositeNode;\r
+ }\r
+\r
+ public void characters(String aCharacters) throws XMLReader.XMLReaderExc {\r
+ appendText(aCharacters);\r
+ }\r
+ }\r
+}\r
--- /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
+package mir.generator.tal;\r
+\r
+/**\r
+ * <p>Title: </p>\r
+ * <p>Description: </p>\r
+ * <p>Copyright: Copyright (c) 2003</p>\r
+ * <p>Company: </p>\r
+ * @author not attributable\r
+ * @version 1.0\r
+ */\r
+\r
+import java.io.PrintWriter;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+public class TALTest {\r
+ public static void main(String args[]) {\r
+ try {\r
+ TALTemplateParser parser = new TALTemplateParser();\r
+ MirExpressionParser expressionParser = new MirExpressionParser();\r
+ Map test = new HashMap();\r
+ test.put("name", "zapata");\r
+\r
+ TALTemplate template = parser.parseString("<html tal:on-error='exception.message'><head></head><body><tal:test tal:content='name'></tal:test><h1 tal:content=\"name.bla\">test</h1></body></html>", expressionParser);\r
+ PrintWriter o = new PrintWriter(System.out);\r
+ template.processTemplate(test, o);\r
+ o.close();\r
+ }\r
+ catch (Throwable t) {\r
+ System.out.println("Exception: " + t.toString());\r
+ t.printStackTrace(System.out);\r
+ }\r
+\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.interfaces;
+
+import java.util.Iterator;
+
+public interface TALExpressionParser {
+ public Object preparseExpression(String anExpression);
+ public Object preparseStringExpression(String anExpression);
+ public Object preparseBooleanExpression(String anExpression);
+ public Object preparseReferenceExpression(String anExpression);
+ public Object preparseListExpression(String anExpression);
+ public Object preparseTRUE();
+ public Object preparseFALSE();
+
+ public Object evaluateExpression(Object aContext, Object aPreparsedExpression);
+ public String evaluateStringExpression(Object aContext, Object aPreparsedExpression);
+ public boolean evaluateBooleanExpression(Object aContext, Object aPreparsedExpression);
+ public Iterator evaluateListExpression(Object aContext, Object aPreparsedExpression);
+ public void processAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aPreparsedExpression);
+
+ /**
+ * process a direct assignment of an object to a preparsed reference expression
+ *
+ * @param aContext
+ * @param aPreparsedReferenceExpression
+ * @param aValue
+ */
+ public void processDirectAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aValue);
+
+
+ /**
+ * process an assigment to a pseudo variable. The pseudo variable will have a java
+ * identifier-like name.
+ *
+ * @param aContext
+ * @param aPreparsedReferenceExpression
+ * @param aValue
+ */
+ public void processPseudoAssignment(Object aContext, String aName, Object aValue);
+}
\ No newline at end of file
}
}
- public static String encodeHTML(String aText) throws UtilExc {
+ public static String encodeHTML(String aText) {
final char[] CHARACTERS_TO_ESCAPE = { '&', '<', '>', '"' };
final String[] ESCAPE_CODES = { "&", "<", ">", """ };
return MethodUtils.invokeExactMethod(anObject, "get", aField);
}
catch (Throwable t) {
- throw new RuntimeException("Invalid reference of " + aField + "into " + anObject);
+ throw new RuntimeException("Invalid reference of " + aField + " into " + anObject);
}
}
}
return result;
}
+ /**
+ * Separates a string based on a separator, taking into account an escape character:
+ * <code>seperateString("a:/::b", ":", "/");</code> will lead to
+ * a List with 3 Strings: <code>"a"</code>, <code>":"</code> and <code>"b"</code>
+ *
+ * @param aString The string to split
+ * @param aSeparator
+ * @return
+ */
+
public static List splitStringWithEscape(String aString, char aSeparator, char anEscape) {
List result= new Vector();
int previousPosition = 0;
*/
package mir.util;
-import java.io.FileInputStream;
+import java.io.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
filename="";
}
+ public void parseString(String aString, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
+ try {
+ parseInputSource(new InputSource(new StringReader(aString)), aRootHandler);
+ }
+ catch (Throwable t) {
+ throw new XMLReaderFailure(t);
+ }
+ }
+
public void parseFile(String aFileName, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
filename= aFileName;
try {
}
public void parseInputStream(InputStream anInputStream, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
+ parseInputSource(new InputSource(anInputStream), aRootHandler);
+ }
+
+ public void parseInputSource(InputSource anInputSource, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
try {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
XMLReaderHandler handler = new XMLReaderHandler(parserFactory, aRootHandler);
- handler.processInputStream(anInputStream);
+ handler.processInputSource(anInputSource);
}
catch (Throwable e) {
Throwable t = ExceptionFunctions.traceCauseException(e);
throw new XMLReaderFailure(t);
}
}
-
private class XMLReaderHandler extends DefaultHandler {
private SAXParserFactory parserFactory;
private SectionsManager manager;
- private InputSource inputSource;
public XMLReaderHandler(SAXParserFactory aParserFactory, SectionHandler aRootHandler) {
super();
locator=aLocator;
}
- private void processInputStream(InputStream anInputStream) throws XMLReaderExc, XMLReaderFailure {
+ private void processInputSource(InputSource anInputSource) throws XMLReaderExc, XMLReaderFailure {
try {
SAXParser parser=parserFactory.newSAXParser();
- inputSource = new InputSource(anInputStream);
- parser.parse(inputSource, this);
+ parser.parse(anInputSource, this);
}
catch (Throwable e) {
Throwable t = ExceptionFunctions.traceCauseException(e);
try {
attributesMap = new HashMap();
- if (namespaceAware)
+// if (namespaceAware)
for (i=0; i<anAttributes.getLength(); i++)
- attributesMap.put(new XMLName(anAttributes.getURI(i), anAttributes.getLocalName(i)), anAttributes.getValue(i));
- else
+ attributesMap.put(new XMLName(anAttributes.getURI(i), XMLReaderTool.getNameSpaceFromQualifiedName(anAttributes.getQName(i)), anAttributes.getLocalName(i)), anAttributes.getValue(i));
+/* else
for (i=0; i<anAttributes.getLength(); i++)
attributesMap.put(anAttributes.getLocalName(i), anAttributes.getValue(i));
+*/
- SectionHandler handler = manager.currentHandler().startElement(new XMLName(aUri, aLocalName), attributesMap);
+ SectionHandler handler = manager.currentHandler().startElement(new XMLName(aUri, XMLReaderTool.getNameSpaceFromQualifiedName(aQualifiedName), aLocalName), attributesMap);
manager.pushHandler( handler );
}
public static class XMLName {
private String namespaceURI;
private String localName;
+ private String prefix;
public XMLName(String aLocalName) {
- this(aLocalName, null);
+ this(null, null, aLocalName);
+ }
+
+ public XMLName(String aNamespaceURI, String aPrefix, String aLocalName) {
+ localName="";
+ prefix="";
+ namespaceURI="";
+
+ if (aLocalName!=null)
+ localName = aLocalName;
+ if (aPrefix!=null)
+ prefix = aPrefix;
+ if (aNamespaceURI!=null)
+ namespaceURI = aNamespaceURI;
}
public XMLName(String aNamespaceURI, String aLocalName) {
- namespaceURI = aNamespaceURI;
- localName = aLocalName;
+ this (aNamespaceURI, null, aLocalName);
}
public String getNamespaceURI() {
return localName;
}
+ public String getPrefix() {
+ return prefix;
+ }
+
public int hashCode() {
if (namespaceURI == null)
- return localName.hashCode();
+ return localName.hashCode() + 3*prefix.hashCode();
else
return localName.hashCode() + 3*namespaceURI.hashCode();
}
public String toString() {
- return namespaceURI+":"+localName;
+ return ((namespaceURI.length()>0)? "["+namespaceURI+"]":"")+((prefix.length()>0)?prefix+":":"")+localName;
}
public boolean equals(Object anObject) {
if (anObject instanceof XMLName) {
if (namespaceURI==null)
return (((XMLName) anObject).namespaceURI == null) &&
+ prefix.equals(((XMLName) anObject).prefix) &&
localName.equals(((XMLName) anObject).localName);
else
return namespaceURI.equals(((XMLName) anObject).namespaceURI) &&
import mir.generator.FreemarkerGenerator;
import mir.generator.VelocityGenerator;
+import mir.generator.TALGenerator;
import mir.generator.Generator;
import mir.generator.GeneratorLibraryRepository;
import mir.generator.WriterEngine;
aRepository.registerLibraryFactory(
"velocity",
new VelocityGenerator.VelocityGeneratorLibraryFactory(MirGlobal.config().getString("Home") ) );
+ aRepository.registerLibraryFactory(
+ "tal",
+ new TALGenerator.TALGeneratorLibraryFactory(MirGlobal.config().getString("Home") ) );
}
public Generator.GeneratorLibrary makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+/*
+ * 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 tool;
import gnu.regexp.RE;
</function>
<comment>complete search-form for contenentries, not sure if it works from everywhere</comment>
-<function ContentSearch (layout)>
+<function ContentSearch (aLayout)>
<form method="GET" action="${config.actionRoot}">
<input type="hidden" name="module" value="Content">
<input type="hidden" name="do" value="search">
- <input type="hidden" name="selectarticleurl" value="${utility.encodeHTML(selectarticleurl)}">
+ <if selectarticleurl>
+ <input type="hidden" name="selectarticleurl" value="${utility.encodeHTML(selectarticleurl)}">
+ </if>
<table border="0" cellpadding="2" cellspacing="3">
- <tr <if !layout>class="bg-neutral"</if>>
- <td <if layout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.value")}</td>
- <td <if layout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.field")}</td>
- <td <if layout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.publishedstate")}</td>
- <td <if layout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.articletype")}</td>
- <td <if layout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.order")}</td>
- <td <if layout>class="table_head"<else>class="small bg_neutral"</if> valign="bottom"> </td>
+ <tr <if !aLayout>class="bg-neutral"</if>>
+ <td <if aLayout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.value")}</td>
+ <td <if aLayout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.field")}</td>
+ <td <if aLayout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.publishedstate")}</td>
+ <td <if aLayout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.articletype")}</td>
+ <td <if aLayout>class="table-head"<else>class="small bg-neutral"</if> valign="bottom"> ${lang("contentsearch.order")}</td>
+ <td <if aLayout>class="table_head"<else>class="small bg_neutral"</if> valign="bottom"> </td>
</tr>
<tr>
- <td <if layout>class="listrow2"</if>><input type="text" size="10" maxlength="20" name="searchvalue" value="${searchvalue}"></td>
- <td <if layout>class="listrow2"</if>>
+ <td <if aLayout>class="listrow2"</if>><input type="text" size="10" maxlength="20" name="searchvalue" value="${searchvalue}"></td>
+ <td <if aLayout>class="listrow2"</if>>
<select name="searchfield">
- <option value="title"<if searchfield=="title"> selected</if>>${lang("contentsearch.field.title")}</option>
- <option value="creator"<if searchfield=="creator"> selected</if>>${lang("contentsearch.field.creator")}</option>
- <option value="contents"<if searchfield=="content"> selected</if>>${lang("contentsearch.field.contents")}</option>
- <option value="creator_main_url"<if searchfield=="creator_main_url"> selected</if>>${lang("contentsearch.field.creator_main_url")}</option>
- <option value="creator_email"<if searchfield=="creator_email"> selected</if>>${lang("contentsearch.field.creator_email")}</option>
+ <option value="title"<if searchfield && searchfield=="title"> selected</if>>${lang("contentsearch.field.title")}</option>
+ <option value="creator"<if searchfield && searchfield=="creator"> selected</if>>${lang("contentsearch.field.creator")}</option>
+ <option value="contents"<if searchfield && searchfield=="content"> selected</if>>${lang("contentsearch.field.contents")}</option>
+ <option value="creator_main_url"<if searchfield && searchfield=="creator_main_url"> selected</if>>${lang("contentsearch.field.creator_main_url")}</option>
+ <option value="creator_email"<if searchfield && searchfield=="creator_email"> selected</if>>${lang("contentsearch.field.creator_email")}</option>
</select>
</td>
- <td <if layout>class="listrow2"</if>>
+ <td <if aLayout>class="listrow2"</if>>
<select name="searchispublished">
<option value="">--</option>
- <option value="0" <if searchispublished=="0"> selected</if>>${lang("contentsearch.publishedstate.hidden")}</option>
- <option value="1" <if searchispublished=="1"> selected</if>>${lang("contentsearch.publishedstate.published")}</option>
+ <option value="0" <if searchispublished && searchispublished=="0"> selected</if>>${lang("contentsearch.publishedstate.hidden")}</option>
+ <option value="1" <if searchispublished && searchispublished=="1"> selected</if>>${lang("contentsearch.publishedstate.published")}</option>
</select>
</td>
- <td <if layout>class="listrow2"</if>>
+ <td <if aLayout>class="listrow2"</if>>
<select name="searcharticletype">
<option value="">--</option>
<list articletypes as at>
- <option value="${at.id}" <if searcharticletype==at.id> selected</if>>${lang("articletypes."+at.name)}</option>
+ <option value="${at.id}" <if searcharticletype && searcharticletype==at.id> selected</if>>${lang("articletypes."+at.name)}</option>
</list>
</select>
</td>
- <td <if layout>class="listrow2"</if>>
+ <td <if aLayout>class="listrow2"</if>>
<select name="searchorder">
- <option value="datedesc" <if searchorder=="datedesc"> selected</if>>${lang("contentsearch.order.datedesc")}</option>
- <option value="dateasc" <if searchorder=="dateasc"> selected</if>>${lang("contentsearch.order.dateasc")}</option>
- <option value="title" <if searchorder=="title"> selected</if>>${lang("contentsearch.order.title")}</option>
- <option value="creator" <if searchorder=="creator"> selected</if>>${lang("contentsearch.order.creator")}</option>
+ <option value="datedesc" <if searchorder && searchorder=="datedesc"> selected</if>>${lang("contentsearch.order.datedesc")}</option>
+ <option value="dateasc" <if searchorder && searchorder=="dateasc"> selected</if>>${lang("contentsearch.order.dateasc")}</option>
+ <option value="title" <if searchorder && searchorder=="title"> selected</if>>${lang("contentsearch.order.title")}</option>
+ <option value="creator" <if searchorder && searchorder=="creator"> selected</if>>${lang("contentsearch.order.creator")}</option>
</select>
</td>
- <td <if layout>class="listrow2"</if>>
+ <td <if aLayout>class="listrow2"</if>>
<input class="majorbutton" type="submit" name="search" value="${lang("contentsearch.searchbutton")}">
</td>
</tr>
if selectarticleurl is set, this list is used to select an article
</comment>
-<if selectarticleurl!="">
+<if selectarticleurl && selectarticleurl!="">
<assign showsearch="1">
<assign showactions="0">
<else>
<td colspan="3" valign="top">
<p class="box-head"><b>${lang("start.search.title")}</b></p>
<div class="box">
- <call ContentSearch ("")>
+ <call ContentSearch("")>
</div>
<comment>