some new producer related files added
[mir.git] / source / mir / generator / FreemarkerGenerator.java
1 package mir.generator;
2
3 import freemarker.template.*;
4 import mir.entity.*;
5 import java.util.*;
6 import java.io.*;
7
8 public class FreemarkerGenerator implements Generator {
9   private Template template;
10
11   public FreemarkerGenerator(Template aTemplate) {
12     template = aTemplate;
13   }
14
15   public void generate(PrintWriter anOutputWriter, Map aValues, PrintWriter aLogger) throws GeneratorException {
16     aLogger.println("processing...<br/>");
17                 template.process((TemplateModelRoot) makeMapAdapter(aValues), anOutputWriter);
18     aLogger.println("processed...<br/>");
19         }
20
21   private static TemplateScalarModel makeStringAdapter(String aString) {
22     return new SimpleScalar(aString);
23   }
24
25   private static TemplateHashModel makeMapAdapter(Map aMap)  {
26     return new MapAdapter(aMap);
27   }
28
29   private static TemplateListModel makeListAdapter(List aList) {
30     return new ListAdapter(aList);
31   }
32
33         private static TemplateModel makeAdapter(Object anObject) {
34           if (anObject == null)
35             return null;
36           if (anObject instanceof TemplateModel)
37             return (TemplateModel) anObject;
38           if (anObject instanceof String)
39             return makeStringAdapter((String) anObject);
40           else if (anObject instanceof Map)
41             return makeMapAdapter((Map) anObject);
42           else if (anObject instanceof List)
43             return makeListAdapter((List) anObject);
44           else
45             return null;
46         }
47
48         private static class MapAdapter implements TemplateModelRoot {
49           Map map;
50           Map valuesCache;
51
52           private MapAdapter(Map aMap) {
53             map = aMap;
54             valuesCache = new HashMap();
55           }
56
57           public void put(String aKey, TemplateModel aModel) {
58             valuesCache.put(aKey, aModel);
59           }
60
61           public void remove(String aKey) {
62             // ML: kinda tricky...
63           }
64
65           public boolean isEmpty() {
66             return map.isEmpty();
67           }
68
69           public TemplateModel get(String aKey) throws TemplateModelException {
70             if (!valuesCache.containsKey(aKey)) {
71               Object value = map.get(aKey);
72
73               if (value == null)
74                 throw new TemplateModelException("MapAdapter: no key "+aKey+" available");
75
76               valuesCache.put(aKey, makeAdapter(value));
77             }
78
79             return (TemplateModel) valuesCache.get(aKey);
80           }
81         }
82
83         private static class ListAdapter implements TemplateListModel {
84           List list;
85           List valuesCache;
86           int position;
87
88           private ListAdapter(List aList) {
89             list = aList;
90             valuesCache = new Vector();
91             position=0;
92           }
93
94           public boolean isEmpty() {
95             return list.isEmpty();
96           }
97
98           public TemplateModel get(int i) {
99
100             if (i>=valuesCache.size() && i<list.size()) {
101               for(int j=valuesCache.size(); j<=i; j++) {
102                 valuesCache.add(makeAdapter(list.get(j)));
103               }
104             }
105
106             if (i<valuesCache.size())
107               return (TemplateModel) valuesCache.get(i);
108             else
109               return null;
110           }
111
112     public boolean hasNext() {
113       return position<list.size();
114     }
115
116     public boolean isRewound() {
117       return position==0;
118     }
119
120     public TemplateModel next() {
121       TemplateModel result = null;
122
123       if (hasNext()) {
124         result = get(position);
125         position++;
126       }
127
128       return result;
129     }
130
131     public void rewind() {
132       position=0;
133     }
134         }
135 }