5 import freemarker.template.*;
9 public class FreemarkerGenerator implements Generator {
10 private Template template;
12 public FreemarkerGenerator(Template aTemplate) {
16 public void generate(PrintWriter anOutputWriter, Map aValues, PrintWriter aLogger) throws GeneratorException {
17 aLogger.println("processing...<br/>");
18 template.process((TemplateModelRoot) makeMapAdapter(aValues), anOutputWriter);
19 aLogger.println("processed...<br/>");
22 private static TemplateScalarModel makeStringAdapter(String aString) {
23 return new SimpleScalar(aString);
26 private static TemplateHashModel makeMapAdapter(Map aMap) {
27 return new MapAdapter(aMap);
30 private static TemplateListModel makeIteratorAdapter(Iterator anIterator) {
31 return new IteratorAdapter(anIterator);
34 private static TemplateModel makeAdapter(Object anObject) throws TemplateModelException {
37 if (anObject instanceof TemplateModel)
38 return (TemplateModel) anObject;
39 if (anObject instanceof String)
40 return makeStringAdapter((String) anObject);
41 else if (anObject instanceof Map)
42 return makeMapAdapter((Map) anObject);
43 else if (anObject instanceof Iterator)
44 return makeIteratorAdapter((Iterator) anObject);
46 throw new TemplateModelException("Unadaptable class: " + anObject.getClass().getName());
49 private static class MapAdapter implements TemplateModelRoot {
53 private MapAdapter(Map aMap) {
55 valuesCache = new HashMap();
58 public void put(String aKey, TemplateModel aModel) {
59 valuesCache.put(aKey, aModel);
62 public void remove(String aKey) {
63 // ML: kinda tricky...
66 public boolean isEmpty() {
70 public TemplateModel get(String aKey) throws TemplateModelException {
71 if (!valuesCache.containsKey(aKey)) {
72 Object value = map.get(aKey);
75 throw new TemplateModelException("MapAdapter: no key "+aKey+" available");
77 valuesCache.put(aKey, makeAdapter(value));
80 return (TemplateModel) valuesCache.get(aKey);
84 private static class IteratorAdapter implements TemplateListModel {
89 private IteratorAdapter(Iterator anIterator) {
90 iterator = anIterator;
92 valuesCache = new Vector();
96 if (iterator instanceof RewindableIterator) {
97 ((RewindableIterator) iterator).rewind();
101 public boolean isEmpty() {
102 return valuesCache.isEmpty() && !iterator.hasNext();
105 private void getUntil(int anIndex) throws TemplateModelException {
106 while (valuesCache.size()<=anIndex && iterator.hasNext())
108 valuesCache.add(makeAdapter(iterator.next()));
112 public TemplateModel get(int anIndex) throws TemplateModelException {
113 TemplateModel result;
117 if (anIndex<valuesCache.size())
119 result = (TemplateModel) valuesCache.get(anIndex);
124 throw new TemplateModelException( "Iterator out of bounds" );
127 public boolean hasNext() {
128 return position<valuesCache.size() || iterator.hasNext();
131 public boolean isRewound() {
135 public TemplateModel next() throws TemplateModelException {
136 TemplateModel result;
139 result = get(position);
143 throw new TemplateModelException( "Iterator out of bounds" );
148 public void rewind() {
153 private static class ListAdapter implements TemplateListModel {
158 private ListAdapter(List aList) {
160 valuesCache = new Vector();
164 public boolean isEmpty() {
165 return list.isEmpty();
168 public TemplateModel get(int i) throws TemplateModelException {
170 if (i>=valuesCache.size() && i<list.size()) {
171 for(int j=valuesCache.size(); j<=i; j++) {
172 valuesCache.add(makeAdapter(list.get(j)));
176 if (i<valuesCache.size())
177 return (TemplateModel) valuesCache.get(i);
179 throw new TemplateModelException( "Iterator out of bounds" );
182 public boolean hasNext() {
183 return position<list.size();
186 public boolean isRewound() {
190 public TemplateModel next() throws TemplateModelException {
191 TemplateModel result;
194 result = get(position);
198 throw new TemplateModelException( "Iterator out of bounds" );
203 public void rewind() {