resource bundle support updated...
[mir.git] / source / mir / generator / FreemarkerGenerator.java
1 package mir.generator;
2
3 import java.util.*;
4 import java.io.*;
5 import freemarker.template.*;
6 import mir.entity.*;
7 import mir.util.*;
8 import mir.misc.*;
9 import org.apache.struts.util.MessageResources;
10
11 public class FreemarkerGenerator implements Generator {
12   private Template template;
13
14   public FreemarkerGenerator(Template aTemplate) {
15     template = aTemplate;
16   }
17
18   public void generate(PrintWriter anOutputWriter, Map aValues, PrintWriter aLogger) throws GeneratorException {
19     aLogger.println("processing...<br/>");
20                 template.process((TemplateModelRoot) makeMapAdapter(aValues), anOutputWriter);
21     aLogger.println("processed...<br/>");
22         }
23
24   private static TemplateScalarModel makeStringAdapter(String aString) {
25     return new SimpleScalar(aString);
26   }
27
28   private static TemplateHashModel makeMapAdapter(Map aMap)  {
29     return new MapAdapter(aMap);
30   }
31
32   private static TemplateListModel makeIteratorAdapter(Iterator anIterator) {
33     return new IteratorAdapter(anIterator);
34   }
35
36         private static TemplateModel makeAdapter(Object anObject) throws TemplateModelException {
37           if (anObject == null)
38             return null;
39           if (anObject instanceof TemplateModel)
40             return (TemplateModel) anObject;
41           else if (anObject instanceof MessageResources)
42             return new MessageMethodModel((MessageResources) anObject);
43           else if (anObject instanceof String)
44             return makeStringAdapter((String) anObject);
45           else if (anObject instanceof Map)
46             return makeMapAdapter((Map) anObject);
47           else if (anObject instanceof Iterator)
48             return makeIteratorAdapter((Iterator) anObject);
49           else
50             throw new TemplateModelException("Unadaptable class: " + anObject.getClass().getName());
51         }
52
53         private static class MapAdapter implements TemplateModelRoot {
54           Map map;
55           Map valuesCache;
56
57           private MapAdapter(Map aMap) {
58             map = aMap;
59             valuesCache = new HashMap();
60           }
61
62           public void put(String aKey, TemplateModel aModel) {
63             valuesCache.put(aKey, aModel);
64           }
65
66           public void remove(String aKey) {
67             // ML: kinda tricky...
68           }
69
70           public boolean isEmpty() {
71             return map.isEmpty();
72           }
73
74           public TemplateModel get(String aKey) throws TemplateModelException {
75             if (!valuesCache.containsKey(aKey)) {
76               Object value = map.get(aKey);
77
78               if (value == null)
79                 throw new TemplateModelException("MapAdapter: no key "+aKey+" available");
80
81               valuesCache.put(aKey, makeAdapter(value));
82             }
83
84             return (TemplateModel) valuesCache.get(aKey);
85           }
86         }
87
88         private static class IteratorAdapter implements TemplateListModel {
89           Iterator iterator;
90           List valuesCache;
91           int position;
92
93           private IteratorAdapter(Iterator anIterator) {
94             iterator = anIterator;
95
96             valuesCache = new Vector();
97             position=0;
98
99
100             if (iterator instanceof RewindableIterator) {
101               ((RewindableIterator) iterator).rewind();
102             }
103           }
104
105           public boolean isEmpty() {
106             return valuesCache.isEmpty() && !iterator.hasNext();
107           }
108
109           private void getUntil(int anIndex) throws TemplateModelException {
110             while (valuesCache.size()<=anIndex && iterator.hasNext())
111             {
112               valuesCache.add(makeAdapter(iterator.next()));
113             }
114           };
115
116           public TemplateModel get(int anIndex) throws TemplateModelException {
117             TemplateModel result;
118
119             getUntil(anIndex);
120
121             if (anIndex<valuesCache.size())
122             {
123               result = (TemplateModel) valuesCache.get(anIndex);
124
125               return result;
126             }
127             else
128               throw new TemplateModelException( "Iterator out of bounds" );
129           }
130
131     public boolean hasNext() {
132       return position<valuesCache.size() || iterator.hasNext();
133     }
134
135     public boolean isRewound() {
136       return position==0;
137     }
138
139     public TemplateModel next() throws TemplateModelException {
140       TemplateModel result;
141
142       if (hasNext()) {
143         result = get(position);
144         position++;
145       }
146       else
147               throw new TemplateModelException( "Iterator out of bounds" );
148
149       return result;
150     }
151
152     public void rewind() {
153       position=0;
154     }
155         }
156
157         private static class ListAdapter implements TemplateListModel {
158           List list;
159           List valuesCache;
160           int position;
161
162           private ListAdapter(List aList) {
163             list = aList;
164             valuesCache = new Vector();
165             position=0;
166           }
167
168           public boolean isEmpty() {
169             return list.isEmpty();
170           }
171
172           public TemplateModel get(int i) throws TemplateModelException {
173
174             if (i>=valuesCache.size() && i<list.size()) {
175               for(int j=valuesCache.size(); j<=i; j++) {
176                 valuesCache.add(makeAdapter(list.get(j)));
177               }
178             }
179
180             if (i<valuesCache.size())
181               return (TemplateModel) valuesCache.get(i);
182             else
183               throw new TemplateModelException( "Iterator out of bounds" );
184           }
185
186     public boolean hasNext() {
187       return position<list.size();
188     }
189
190     public boolean isRewound() {
191       return position==0;
192     }
193
194     public TemplateModel next() throws TemplateModelException {
195       TemplateModel result;
196
197       if (hasNext()) {
198         result = get(position);
199         position++;
200       }
201             else
202               throw new TemplateModelException( "Iterator out of bounds" );
203
204       return result;
205     }
206
207     public void rewind() {
208       position=0;
209     }
210         }
211 }