001: /*
002: * Copyright (c) 2003 The Visigoth Software Society. All rights
003: * reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * 2. Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowledgement:
019: * "This product includes software developed by the
020: * Visigoth Software Society (http://www.visigoths.org/)."
021: * Alternately, this acknowledgement may appear in the software itself,
022: * if and wherever such third-party acknowledgements normally appear.
023: *
024: * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
025: * project contributors may be used to endorse or promote products derived
026: * from this software without prior written permission. For written
027: * permission, please contact visigoths@visigoths.org.
028: *
029: * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
030: * nor may "FreeMarker" or "Visigoth" appear in their names
031: * without prior written permission of the Visigoth Software Society.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of the Visigoth Software Society. For more
049: * information on the Visigoth Software Society, please see
050: * http://www.visigoths.org/
051: */
052:
053: package freemarker.testcase;
054:
055: import java.io.BufferedOutputStream;
056: import java.io.File;
057: import java.io.FileOutputStream;
058: import java.io.OutputStream;
059: import java.io.OutputStreamWriter;
060: import java.io.Writer;
061: import java.util.List;
062: import java.util.Locale;
063:
064: import freemarker.template.Configuration;
065: import freemarker.template.SimpleHash;
066: import freemarker.template.Template;
067: import freemarker.template.TemplateBooleanModel;
068: import freemarker.template.TemplateCollectionModel;
069: import freemarker.template.TemplateHashModel;
070: import freemarker.template.TemplateMethodModelEx;
071: import freemarker.template.TemplateModel;
072: import freemarker.template.TemplateModelIterator;
073: import freemarker.template.TemplateNumberModel;
074: import freemarker.template.TemplateScalarModel;
075:
076: /**
077: * This class executes a FreeMarker template repeatedly in an endless loop.
078: * It is meant to run inside a profiler to identify potential bottlenecks.
079: * It can process either into a local file, or into a special /dev/null
080: * style output stream.
081: * @version $Id: PerformanceTest.java,v 1.18 2004/11/28 12:58:34 ddekany Exp $
082: */
083: public class PerformanceTest {
084: public static void main(String[] args) throws Exception {
085: Configuration config = new Configuration();
086: // config.setDebugMode(false);
087: config.setClassicCompatible(false);
088: config.setClassForTemplateLoading(PerformanceTest.class,
089: "/freemarker/testcase");
090: Template template = config.getTemplate("PerformanceTest.fm");
091: boolean toFile = args.length > 0 && args[0].equals("file");
092: File f = File.createTempFile("fmPerfTest", ".txt");
093: f.deleteOnExit();
094: OutputStream nullStream = new NullStream();
095: SimpleHash h = new SimpleHash();
096: h.put("ii", new TestSequence());
097: h.put("j", new TestHash());
098: h.put("k", new TestMethod());
099:
100: for (;;) {
101: OutputStream stream = toFile ? new BufferedOutputStream(
102: new FileOutputStream(f)) : nullStream;
103: Writer writer = new OutputStreamWriter(stream, "UTF-8");
104: try {
105: template.process(h, writer);
106: } finally {
107: writer.close();
108: }
109: }
110: }
111:
112: private static class TestSequence implements
113: TemplateCollectionModel {
114: public TemplateModelIterator iterator() {
115: return new TemplateModelIterator() {
116: private int i = 0;
117:
118: public TemplateModel next() {
119: return new TestI(i++);
120: }
121:
122: public boolean hasNext() {
123: return i < 1000;
124: }
125: };
126: };
127: }
128:
129: private static class TestHash implements TemplateHashModel,
130: TemplateScalarModel {
131: public TemplateModel get(String key) {
132: return this ;
133: }
134:
135: public String getAsString() {
136: return "j";
137: }
138:
139: public boolean isEmpty() {
140: return false;
141: }
142: }
143:
144: private static class TestMethod implements TemplateMethodModelEx {
145: public Object exec(List arguments) {
146: return arguments.get(0);
147: }
148: }
149:
150: private static class TestI implements TemplateHashModel,
151: TemplateNumberModel {
152: private final int i;
153:
154: TestI(int i) {
155: this .i = i;
156: }
157:
158: public TemplateModel get(String key) {
159: return (i & 1) == 1 ? TemplateBooleanModel.TRUE
160: : TemplateBooleanModel.FALSE;
161: }
162:
163: public String getAsString(Locale locale) {
164: return Integer.toString(i);
165: }
166:
167: public Number getAsNumber() {
168: return new Integer(i);
169: }
170:
171: public boolean isEmpty() {
172: return false;
173: }
174: }
175:
176: private static class NullStream extends OutputStream {
177: public void close() {
178: }
179:
180: public void flush() {
181: }
182:
183: public void write(byte[] arg0, int arg1, int arg2) {
184: }
185:
186: public void write(byte[] arg0) {
187: }
188:
189: public void write(int arg0) {
190: }
191: }
192: }
|