From a841b85307a342bbaaf328ab2a79d9dbc4619b1f Mon Sep 17 00:00:00 2001 From: zapata Date: Fri, 21 Nov 2003 17:50:01 +0000 Subject: [PATCH] preliminary support for a TAL template engine --- source/mir/generator/TALGenerator.java | 88 ++++++ source/mir/generator/VelocityGenerator.java | 174 ++++++++--- source/mir/generator/tal/CachingFileLoader.java | 135 +++++++++ source/mir/generator/tal/MirExpressionParser.java | 146 +++++++++ source/mir/generator/tal/TALExc.java | 38 +++ source/mir/generator/tal/TALFailure.java | 42 +++ source/mir/generator/tal/TALTemplate.java | 333 +++++++++++++++++++++ source/mir/generator/tal/TALTemplateEngine.java | 65 ++++ source/mir/generator/tal/TALTemplateParser.java | 244 +++++++++++++++ source/mir/generator/tal/TALTest.java | 64 ++++ .../tal/interfaces/TALExpressionParser.java | 68 +++++ source/mir/util/HTMLRoutines.java | 2 +- source/mir/util/ParameterExpander.java | 2 +- source/mir/util/StringRoutines.java | 10 + source/mir/util/XMLReader.java | 61 +++- .../basic/MirBasicGeneratorLocalizer.java | 4 + source/tool/ConfigTool.java | 29 ++ templates/admin/FUNCTIONS.template | 56 ++-- templates/admin/contentlist.template | 2 +- templates/admin/start_admin.template | 2 +- 20 files changed, 1483 insertions(+), 82 deletions(-) create mode 100755 source/mir/generator/TALGenerator.java create mode 100755 source/mir/generator/tal/CachingFileLoader.java create mode 100755 source/mir/generator/tal/MirExpressionParser.java create mode 100755 source/mir/generator/tal/TALExc.java create mode 100755 source/mir/generator/tal/TALFailure.java create mode 100755 source/mir/generator/tal/TALTemplate.java create mode 100755 source/mir/generator/tal/TALTemplateEngine.java create mode 100755 source/mir/generator/tal/TALTemplateParser.java create mode 100755 source/mir/generator/tal/TALTest.java create mode 100755 source/mir/generator/tal/interfaces/TALExpressionParser.java diff --git a/source/mir/generator/TALGenerator.java b/source/mir/generator/TALGenerator.java new file mode 100755 index 00000000..3744b1fc --- /dev/null +++ b/source/mir/generator/TALGenerator.java @@ -0,0 +1,88 @@ +/* + * 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; + +import java.io.PrintWriter; +import java.util.Map; + +import mir.generator.tal.MirExpressionParser; +import mir.generator.tal.TALTemplate; +import mir.generator.tal.TALTemplateEngine; +import mir.log.LoggerWrapper; + +public class TALGenerator implements Generator { + private String templateIdentifier; + private TALGeneratorLibrary library; + private static LoggerWrapper logger = new LoggerWrapper("Generator.velocity"); + + public TALGenerator(String aTemplate, TALGeneratorLibrary aLibrary) { + templateIdentifier = aTemplate; + library = aLibrary; + } + + public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure { + TALTemplate template; + + try { + template = library.engine.loadTemplate(templateIdentifier); + if (template == null) { + throw new GeneratorExc("TALGeneratorLibrary: Can't find template " + templateIdentifier); + } + template.processTemplate(aValues, (PrintWriter) anOutputWriter); + } + catch (Throwable t) { + throw new GeneratorFailure(t); + } + } + + public static class TALGeneratorLibrary implements GeneratorLibrary { + private TALTemplateEngine engine; + + public TALGeneratorLibrary(String aTemplateRoot) throws GeneratorExc, GeneratorFailure { + engine = new TALTemplateEngine(new MirExpressionParser(), aTemplateRoot); + } + + public Generator makeGenerator(String anIdentifier) throws GeneratorExc, GeneratorFailure { + return new TALGenerator(anIdentifier, this); + } + } + + public static class TALGeneratorLibraryFactory implements GeneratorLibraryFactory { + private String basePath; + + public TALGeneratorLibraryFactory(String aBasePath) { + basePath = aBasePath; + } + + public GeneratorLibrary makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure { + return new TALGeneratorLibrary(basePath+anInitializationString); + }; + } +} diff --git a/source/mir/generator/VelocityGenerator.java b/source/mir/generator/VelocityGenerator.java index 730b7d23..e827cc50 100755 --- a/source/mir/generator/VelocityGenerator.java +++ b/source/mir/generator/VelocityGenerator.java @@ -58,11 +58,25 @@ public class VelocityGenerator implements Generator { private VelocityGeneratorLibrary library; private static LoggerWrapper logger = new LoggerWrapper("Generator.velocity"); + /** + * + * @param aTemplate + * @param aLibrary + */ + public VelocityGenerator(String aTemplate, VelocityGeneratorLibrary aLibrary) { templateIdentifier = aTemplate; library = aLibrary; } + /** + * + * @param anOutputWriter + * @param aValues + * @param aLogger + * @throws GeneratorExc + * @throws GeneratorFailure + */ public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure { Template template; Context context = makeMapAdapter(aValues); @@ -89,6 +103,15 @@ public class VelocityGenerator implements Generator { } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class ContextAdapter implements Context { public boolean containsKey(java.lang.Object key) { return false; @@ -111,31 +134,69 @@ public class VelocityGenerator implements Generator { } } + /** + * + * @param aMap + * @return + */ private static Context makeMapAdapter(Map aMap) { return new MapAdapter(aMap); } + /** + * + * @param anIterator + * @return + */ private static List makeIteratorAdapter(Iterator anIterator) { return new IteratorAdapter(anIterator); } + /** + * + * @param aList + * @return + */ private static List makeListAdapter(List aList) { return new ListAdapter(aList); } - + /** + * + * @param aFunction + * @return + */ private static Object makeFunctionAdapter(Generator.GeneratorFunction aFunction) { return new FunctionAdapter(aFunction); } + /** + * + * @param anObject + * @return + */ private static Object makeBeanAdapter(Object anObject) { return new BeanAdapter(anObject); } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private interface VelocityAdapter { public Object getOriginal(); } + /** + * + * @param anObject + * @return + */ public static Object unmakeAdapter(Object anObject) { if (anObject instanceof VelocityAdapter) { return ((VelocityAdapter) anObject).getOriginal(); @@ -144,6 +205,11 @@ public class VelocityGenerator implements Generator { return anObject; } + /** + * + * @param anObject + * @return + */ public static Object makeAdapter(Object anObject) { if (anObject == null) return null; @@ -173,6 +239,15 @@ public class VelocityGenerator implements Generator { return makeBeanAdapter(anObject); } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ public static class FunctionAdapter implements VelocityAdapter { private GeneratorFunction function; @@ -216,6 +291,15 @@ public class VelocityGenerator implements Generator { } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class MapAdapter implements Context, VelocityAdapter { private Map map; private Map valuesCache; @@ -268,6 +352,15 @@ public class VelocityGenerator implements Generator { } } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class IteratorAdapter extends AbstractList implements VelocityAdapter { private Iterator iterator; private List valuesCache; @@ -318,6 +411,15 @@ public class VelocityGenerator implements Generator { } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class ListAdapter extends AbstractList implements VelocityAdapter { private List list; private List valuesCache; @@ -362,31 +464,15 @@ public class VelocityGenerator implements Generator { } -/* - private static class FunctionAdapter implements TemplateMethodModel { - private Generator.GeneratorFunction function; - - public FunctionAdapter(Generator.GeneratorFunction aFunction) { - function = aFunction; - } - - public TemplateModel exec(List anArguments) throws TemplateModelException { - try { - return makeAdapter(function.perform(anArguments)); - } - catch (Throwable t) { - throw new TemplateModelException(t.getMessage()); - } - } - - public boolean isEmpty() { - return false; - } - - } - -*/ - + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class BeanAdapter implements Context, VelocityAdapter { private Object object; @@ -437,6 +523,15 @@ public class VelocityGenerator implements Generator { } } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ private static class VelocityLoggerWrapper implements LogSystem { private LoggerWrapper logger; @@ -465,6 +560,15 @@ public class VelocityGenerator implements Generator { } } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ public static class VelocityGeneratorLibrary implements GeneratorLibrary { private VelocityEngine engine; @@ -514,15 +618,6 @@ public class VelocityGenerator implements Generator { logger.error(VelocityEngine.RUNTIME_LOG_LOGSYSTEM); } -/* try { - engine.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, null); - } - catch (Throwable t) { - logger.error(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS); - - } -*/ - engine.init(); } catch (Throwable t) { @@ -538,6 +633,15 @@ public class VelocityGenerator implements Generator { } } + /** + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ public static class VelocityGeneratorLibraryFactory implements GeneratorLibraryFactory { private String basePath; diff --git a/source/mir/generator/tal/CachingFileLoader.java b/source/mir/generator/tal/CachingFileLoader.java new file mode 100755 index 00000000..41256ab2 --- /dev/null +++ b/source/mir/generator/tal/CachingFileLoader.java @@ -0,0 +1,135 @@ +/* + * 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.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +public class CachingFileLoader { + private Map cachedObjects; + private List history; + private int capacity; + private CachedFileObjectFactory factory; + + public CachingFileLoader(int aCapacity, CachedFileObjectFactory aFactory) { + capacity = aCapacity; + cachedObjects = new HashMap(); + history = new Vector(); + factory = aFactory; + } + + private void cacheObject(String aFilename, long aLastModified, Object anObject) { + synchronized (this) { + history.remove(aFilename); + history.add(aFilename); + while (history.size()>capacity && history.size()>0) { + history.remove(0); + } + cachedObjects.put(aFilename, new CachedObject(aFilename, aLastModified, anObject)); + } + } + + private Object constructObject(String aFilename) throws FileNotFoundException { + File file = new File(aFilename); + FileInputStream inputStream = new FileInputStream(file); + try { + Object result = factory.constructObject(inputStream); + cacheObject(aFilename, file.lastModified(), result); + + return result; + } + finally { + try { + inputStream.close(); + } + catch (Throwable t) { + } + } + } + + private void revatilize(String aFilename) { + synchronized (this) { + history.remove(aFilename); + history.add(aFilename); + } + } + + private class CachedObject { + private String filename; + private long lastModified; + private Object object; + + public CachedObject(String aFilename, long aLastModified, Object anObject) { + filename = aFilename; + lastModified = aLastModified; + object = anObject; + } + + public Object getObject() { + return object; + } + + public String getFilename() { + return filename; + } + + public long getLastModified() { + return lastModified; + } + } + + public Object retrieveFile(String aFilename) throws FileNotFoundException { + synchronized (this) { + if (!cachedObjects.containsKey(aFilename)) { + return constructObject(aFilename); + } + + CachedObject cachedObject = (CachedObject) cachedObjects.get(aFilename); + File file = new File(aFilename); + if (file.lastModified() != cachedObject.getLastModified()) { + return constructObject(aFilename); + } + + revatilize(aFilename); + + return cachedObject.getObject(); + } + } + + public interface CachedFileObjectFactory { + Object constructObject(InputStream aStream); + } +} \ No newline at end of file diff --git a/source/mir/generator/tal/MirExpressionParser.java b/source/mir/generator/tal/MirExpressionParser.java new file mode 100755 index 00000000..ef608fc8 --- /dev/null +++ b/source/mir/generator/tal/MirExpressionParser.java @@ -0,0 +1,146 @@ +/* + * 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.util.Iterator; +import java.util.List; +import java.util.Map; + +import mir.generator.tal.interfaces.TALExpressionParser; +import mir.util.ParameterExpander; +import mir.util.RewindableIterator; + +public class MirExpressionParser implements TALExpressionParser { + public Object preparseExpression(String anExpression) { + return anExpression; + } + public Object preparseStringExpression(String anExpression) { + return anExpression; + } + + public Object preparseBooleanExpression(String anExpression) { + return anExpression; + } + + public Object preparseReferenceExpression(String anExpression) { + return anExpression; + } + + public Object preparseListExpression(String anExpression) { + return anExpression; + } + + public Object preparseTRUE() { + return "1==1"; + } + + public Object preparseFALSE() { + return "0==1"; + } + + public Object evaluateExpression(Object aContext, Object aPreparsedExpression) { + try { + return ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public String evaluateStringExpression(Object aContext, Object aPreparsedExpression) { + try { + return ParameterExpander.evaluateStringExpression(aContext, (String) aPreparsedExpression); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public boolean evaluateBooleanExpression(Object aContext, Object aPreparsedExpression) { + try { + return ParameterExpander.evaluateBooleanExpression(aContext, (String) aPreparsedExpression); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public Iterator evaluateListExpression(Object aContext, Object aPreparsedExpression) { + try { + Object list = ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression); + + if (list instanceof List) + return ((List) list).iterator(); + + if (list instanceof RewindableIterator) { + ((RewindableIterator) list).rewind(); + return (RewindableIterator) list; + } + + if (list instanceof Iterator) { + return (Iterator) list; + } + + throw new TALExc("Not a list: " + list); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public void processAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aPreparsedExpression) { + try { + ParameterExpander.setValueForKey( (Map) aContext, (String) aPreparsedReferenceExpression, ParameterExpander.evaluateExpression(aContext, (String) aPreparsedExpression)); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public void processDirectAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aValue) { + try { + ParameterExpander.setValueForKey( (Map) aContext, (String) aPreparsedReferenceExpression, aValue); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + + public void processPseudoAssignment(Object aContext, String aName, Object aValue) { + try { + ParameterExpander.setValueForKey( (Map) aContext, aName, aValue); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + +} \ No newline at end of file diff --git a/source/mir/generator/tal/TALExc.java b/source/mir/generator/tal/TALExc.java new file mode 100755 index 00000000..f722d2cc --- /dev/null +++ b/source/mir/generator/tal/TALExc.java @@ -0,0 +1,38 @@ +/* + * 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); + } +} diff --git a/source/mir/generator/tal/TALFailure.java b/source/mir/generator/tal/TALFailure.java new file mode 100755 index 00000000..d15ebf5d --- /dev/null +++ b/source/mir/generator/tal/TALFailure.java @@ -0,0 +1,42 @@ +/* + * 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); + } +} diff --git a/source/mir/generator/tal/TALTemplate.java b/source/mir/generator/tal/TALTemplate.java new file mode 100755 index 00000000..2b031894 --- /dev/null +++ b/source/mir/generator/tal/TALTemplate.java @@ -0,0 +1,333 @@ +/* + * 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.PrintWriter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import mir.generator.tal.interfaces.TALExpressionParser; +import mir.util.HTMLRoutines; + +/** + * {@link http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4} + * + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ + +public class TALTemplate { + private TemplateNode rootNode; + private TALExpressionParser parser; + + public TALTemplate(TALExpressionParser aParser, TemplateNode aRootNode) { + rootNode = aRootNode; + parser = aParser; + } + + public void processTemplate(Object aContext, PrintWriter aDestination) { + StringBuffer output = new StringBuffer(); + + rootNode.process(parser, aContext, output); + aDestination.print(output); + } + + public interface TemplateNode { + public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination); + } + + public static class CompositeTemplateNode + implements TemplateNode { + private List parts; + + public CompositeTemplateNode() { + parts = new Vector(); + } + + public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) { + Iterator i = parts.iterator(); + + while (i.hasNext()) { + ((TemplateNode) i.next()).process(aParser, aContext, aDestination); + } + } + + public void appendSubNode(TemplateNode aNode) { + if (aNode instanceof CompositeTemplateNode) { + Iterator i = ((CompositeTemplateNode) aNode).parts.iterator(); + while (i.hasNext()) { + appendSubNode((TemplateNode) i.next()); + } + } + else if (aNode instanceof PlainTextTemplateNode && parts.size()>0 && + (parts.get(parts.size()-1) instanceof PlainTextTemplateNode)) { + + ((PlainTextTemplateNode) parts.get(parts.size()-1)).appendText(((PlainTextTemplateNode) aNode).getText()); + } + else { + parts.add(aNode); + } + } + } + + public static class PlainTextTemplateNode + implements TemplateNode { + private String text; + + public PlainTextTemplateNode() { + this(""); + } + + public PlainTextTemplateNode(String aText) { + text = aText; + } + + public void appendText(String aText) { + text = text + aText; + } + + protected String getText() { + return text; + } + + public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) { + aDestination.append(text); + } + } + + public static class SmartTemplateNode implements TemplateNode { + private String tag; + private Map fixedAttributes; + private Map attributeModifiers; + + private List definitions; + private Object condition; + + private Object repeatVariable; + private Object repeatExpression; + private Object contentExpression; + private Object omitTagExpression; + private Object errorExpression; + + private TemplateNode body; + + public SmartTemplateNode(String aTag) { + tag = aTag; + + fixedAttributes = new HashMap(); + attributeModifiers = new HashMap(); + + definitions = new Vector(); + condition = null; + + repeatVariable = null; + repeatExpression = null; + contentExpression = null; + omitTagExpression = null; + + body = null; + } + + public void setBody(TemplateNode aBody) { + body = aBody; + } + + public void addFixedAttribute(String aKey, String aValue) { + fixedAttributes.put(aKey, aValue); + } + + public void addModifiedAttribute(String aKey, Object aValue) { + attributeModifiers.put(aKey, aValue); + } + + public void addDefinition(Object aKey, Object aValue) { + definitions.add(new Definition(aKey, aValue)); + } + + public void setCondition(Object aCondition) { + condition = aCondition; + } + + public void setRepeat(Object aRepeatVariable, Object aRepeatExpression) { + repeatVariable = aRepeatVariable; + repeatExpression = aRepeatExpression; + } + + public void setContent(Object aContentExpression) { + contentExpression = aContentExpression; + } + + public void setOmitTag(Object anOmitTagExpression) { + omitTagExpression = anOmitTagExpression; + } + + public void setError(Object anErrorExpression) { + errorExpression = anErrorExpression; + } + + public static class Definition { + private Object variable; + private Object expression; + + public Definition(Object aVariable, Object anExpression) { + variable = aVariable; + expression = anExpression; + } + + public Object getVariable() { + return variable; + } + + public Object getExpression() { + return expression; + } + } + + public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) { + Iterator i; + + i = definitions.iterator(); + while (i.hasNext()) { + Definition d = (Definition) i.next(); + aParser.processAssignment(aContext, d.getVariable(), d.getExpression()); + } + + if (condition == null || aParser.evaluateBooleanExpression(aContext, condition)) { + if (repeatExpression != null) { + i = aParser.evaluateListExpression(aContext, repeatExpression); + + while (i.hasNext()) { + aParser.processDirectAssignment(aContext, repeatVariable, i.next()); + innerProcess(aParser, aContext, aDestination); + } + } + else { + innerProcess(aParser, aContext, aDestination); + } + + /* + define + condition + repeat + attributes + content + OR + replace + OR + omit-tag + content + * define + * condition + * repeat + * content + * attributes + * omit-tag + */ + } + }; + + private void innerProcess(TALExpressionParser aParser, Object aContext, StringBuffer aDestination) { + boolean omitTag = false; + if (omitTagExpression != null) + omitTag = aParser.evaluateBooleanExpression(aContext, omitTagExpression); + + if (!omitTag) { + Map generatedAttributes = new HashMap(fixedAttributes); + + Iterator i = attributeModifiers.keySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = (Map.Entry) i.next(); + + generatedAttributes.put(entry.getKey(), aParser.evaluateStringExpression(aContext, entry.getValue())); + } + + aDestination.append("<"); + aDestination.append(tag); + + i = generatedAttributes.keySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = (Map.Entry) i.next(); + aDestination.append(" "); + aDestination.append(entry.getKey()); + aDestination.append("="); + aDestination.append("\""); + aDestination.append(HTMLRoutines.encodeHTML( (String) entry.getValue())); + aDestination.append("\""); + } + aDestination.append(">"); + } + + StringBuffer destination = aDestination; + if (errorExpression != null) { + destination = new StringBuffer(); + } + try { + if (contentExpression != null) { + destination.append(aParser.evaluateStringExpression(aContext, contentExpression)); + } + else { + if (body != null) + body.process(aParser, aContext, destination); + } + } + catch (RuntimeException t) { + if (errorExpression != null) { + try { + destination.delete(0, destination.length()); + + aParser.processPseudoAssignment(aContext, "exception", t); + destination.append(aParser.evaluateStringExpression(aContext, errorExpression)); + } + catch (Throwable s) { + } + } + else + throw t; + } + finally { + if (errorExpression != null) { + aDestination.append(destination); + } + } + if (!omitTag) { + aDestination.append(""); + } + } + } +} \ No newline at end of file diff --git a/source/mir/generator/tal/TALTemplateEngine.java b/source/mir/generator/tal/TALTemplateEngine.java new file mode 100755 index 00000000..74b4b371 --- /dev/null +++ b/source/mir/generator/tal/TALTemplateEngine.java @@ -0,0 +1,65 @@ +/* + * 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.File; +import java.io.IOException; +import java.io.InputStream; + +import mir.generator.tal.interfaces.TALExpressionParser; + +public class TALTemplateEngine { + private TALExpressionParser expressionParser; + private String basePath; + private CachingFileLoader loader; + + public TALTemplateEngine(TALExpressionParser anExpressionParser, String aBasePath) { + expressionParser = anExpressionParser; + basePath = aBasePath; + loader = new CachingFileLoader(100, new TemplateFactory()); + } + + public TALTemplate loadTemplate(String aName) throws IOException { + File location = new File(basePath, aName); + return (TALTemplate) loader.retrieveFile(location.getCanonicalPath()); + } + + private class TemplateFactory implements CachingFileLoader.CachedFileObjectFactory { + public Object constructObject(InputStream aStream) { + try { + return TALTemplateParser.parseInputStream(aStream, expressionParser); + } + catch (Throwable t) { + throw new TALFailure(t); + } + } + } +} \ No newline at end of file diff --git a/source/mir/generator/tal/TALTemplateParser.java b/source/mir/generator/tal/TALTemplateParser.java new file mode 100755 index 00000000..ba739192 --- /dev/null +++ b/source/mir/generator/tal/TALTemplateParser.java @@ -0,0 +1,244 @@ +/* + * 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); + } + } +} diff --git a/source/mir/generator/tal/TALTest.java b/source/mir/generator/tal/TALTest.java new file mode 100755 index 00000000..02e63f80 --- /dev/null +++ b/source/mir/generator/tal/TALTest.java @@ -0,0 +1,64 @@ +/* + * 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; + +/** + *

Title:

+ *

Description:

+ *

Copyright: Copyright (c) 2003

+ *

Company:

+ * @author not attributable + * @version 1.0 + */ + +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; + +public class TALTest { + public static void main(String args[]) { + try { + TALTemplateParser parser = new TALTemplateParser(); + MirExpressionParser expressionParser = new MirExpressionParser(); + Map test = new HashMap(); + test.put("name", "zapata"); + + TALTemplate template = parser.parseString("

test

", expressionParser); + PrintWriter o = new PrintWriter(System.out); + template.processTemplate(test, o); + o.close(); + } + catch (Throwable t) { + System.out.println("Exception: " + t.toString()); + t.printStackTrace(System.out); + } + + } +} \ No newline at end of file diff --git a/source/mir/generator/tal/interfaces/TALExpressionParser.java b/source/mir/generator/tal/interfaces/TALExpressionParser.java new file mode 100755 index 00000000..66b8262d --- /dev/null +++ b/source/mir/generator/tal/interfaces/TALExpressionParser.java @@ -0,0 +1,68 @@ +/* + * 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 diff --git a/source/mir/util/HTMLRoutines.java b/source/mir/util/HTMLRoutines.java index 53a4cda6..4ed503bf 100755 --- a/source/mir/util/HTMLRoutines.java +++ b/source/mir/util/HTMLRoutines.java @@ -56,7 +56,7 @@ public class HTMLRoutines { } } - public static String encodeHTML(String aText) throws UtilExc { + public static String encodeHTML(String aText) { final char[] CHARACTERS_TO_ESCAPE = { '&', '<', '>', '"' }; final String[] ESCAPE_CODES = { "&", "<", ">", """ }; diff --git a/source/mir/util/ParameterExpander.java b/source/mir/util/ParameterExpander.java index 71e154a2..75f92a72 100755 --- a/source/mir/util/ParameterExpander.java +++ b/source/mir/util/ParameterExpander.java @@ -590,7 +590,7 @@ public class ParameterExpander { 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); } } } diff --git a/source/mir/util/StringRoutines.java b/source/mir/util/StringRoutines.java index bd6f2745..0627dbc1 100755 --- a/source/mir/util/StringRoutines.java +++ b/source/mir/util/StringRoutines.java @@ -277,6 +277,16 @@ public class StringRoutines { return result; } + /** + * Separates a string based on a separator, taking into account an escape character: + * seperateString("a:/::b", ":", "/"); will lead to + * a List with 3 Strings: "a", ":" and "b" + * + * @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; diff --git a/source/mir/util/XMLReader.java b/source/mir/util/XMLReader.java index 954b2e71..a1be97c2 100755 --- a/source/mir/util/XMLReader.java +++ b/source/mir/util/XMLReader.java @@ -29,7 +29,7 @@ */ package mir.util; -import java.io.FileInputStream; +import java.io.*; import java.io.InputStream; import java.util.HashMap; import java.util.Map; @@ -63,6 +63,15 @@ public class XMLReader { 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 { @@ -74,6 +83,10 @@ public class XMLReader { } 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(); @@ -82,7 +95,7 @@ public class XMLReader { XMLReaderHandler handler = new XMLReaderHandler(parserFactory, aRootHandler); - handler.processInputStream(anInputStream); + handler.processInputSource(anInputSource); } catch (Throwable e) { Throwable t = ExceptionFunctions.traceCauseException(e); @@ -98,11 +111,9 @@ public class XMLReader { 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(); @@ -116,12 +127,11 @@ public class XMLReader { 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); @@ -160,14 +170,15 @@ public class XMLReader { try { attributesMap = new HashMap(); - if (namespaceAware) +// if (namespaceAware) for (i=0; i0)? "["+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) && diff --git a/source/mircoders/localizer/basic/MirBasicGeneratorLocalizer.java b/source/mircoders/localizer/basic/MirBasicGeneratorLocalizer.java index 478e20bc..d9b44079 100755 --- a/source/mircoders/localizer/basic/MirBasicGeneratorLocalizer.java +++ b/source/mircoders/localizer/basic/MirBasicGeneratorLocalizer.java @@ -31,6 +31,7 @@ package mircoders.localizer.basic; import mir.generator.FreemarkerGenerator; import mir.generator.VelocityGenerator; +import mir.generator.TALGenerator; import mir.generator.Generator; import mir.generator.GeneratorLibraryRepository; import mir.generator.WriterEngine; @@ -58,6 +59,9 @@ public class MirBasicGeneratorLocalizer implements MirGeneratorLocalizer { 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 { diff --git a/source/tool/ConfigTool.java b/source/tool/ConfigTool.java index 351274e2..d7e89932 100755 --- a/source/tool/ConfigTool.java +++ b/source/tool/ConfigTool.java @@ -1,3 +1,32 @@ +/* + * 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; diff --git a/templates/admin/FUNCTIONS.template b/templates/admin/FUNCTIONS.template index 5ef9efe5..e2b84e25 100755 --- a/templates/admin/FUNCTIONS.template +++ b/templates/admin/FUNCTIONS.template @@ -232,57 +232,59 @@ complete search-form for contenentries, not sure if it works from everywhere - +
- + + + - class="bg-neutral"> - - - - - - + class="bg-neutral"> + + + + + + - - + - - - - diff --git a/templates/admin/contentlist.template b/templates/admin/contentlist.template index 2752dc37..107a4c4f 100755 --- a/templates/admin/contentlist.template +++ b/templates/admin/contentlist.template @@ -2,7 +2,7 @@ if selectarticleurl is set, this list is used to select an article - + diff --git a/templates/admin/start_admin.template b/templates/admin/start_admin.template index 538f9a23..5e5a86fa 100755 --- a/templates/admin/start_admin.template +++ b/templates/admin/start_admin.template @@ -173,7 +173,7 @@
class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.value")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.field")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.publishedstate")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.articletype")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.order")}class="table_head"class="small bg_neutral" valign="bottom">  
class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.value")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.field")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.publishedstate")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.articletype")}class="table-head"class="small bg-neutral" valign="bottom"> ${lang("contentsearch.order")}class="table_head"class="small bg_neutral" valign="bottom">  
class="listrow2">class="listrow2"> + class="listrow2">class="listrow2"> class="listrow2"> + class="listrow2"> class="listrow2"> + class="listrow2"> class="listrow2"> + class="listrow2"> class="listrow2"> + class="listrow2">

${lang("start.search.title")}

- +
-- 2.11.0