5 import freemarker.template.*;
9 import org.apache.struts.util.MessageResources;
11 public class FreemarkerGenerator implements Generator {
12 private Template template;
14 public FreemarkerGenerator(Template aTemplate) {
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/>");
24 private static TemplateScalarModel makeStringAdapter(String aString) {
25 return new SimpleScalar(aString);
28 private static TemplateHashModel makeMapAdapter(Map aMap) {
29 return new MapAdapter(aMap);
32 private static TemplateListModel makeIteratorAdapter(Iterator anIterator) {
33 return new IteratorAdapter(anIterator);
36 private static TemplateModel makeAdapter(Object anObject) throws TemplateModelException {
39 if (anObject instanceof TemplateModel)
40 return (TemplateModel) anObject;
41 // if (anObject instanceof Date)
42 // return new DateAdapter((Date) anObject);
43 else if (anObject instanceof MessageResources)
44 return new MessageMethodModel((MessageResources) anObject);
45 else if (anObject instanceof String)
46 return makeStringAdapter((String) anObject);
47 else if (anObject instanceof Map)
48 return makeMapAdapter((Map) anObject);
49 else if (anObject instanceof Iterator)
50 return makeIteratorAdapter((Iterator) anObject);
52 throw new TemplateModelException("Unadaptable class: " + anObject.getClass().getName());
55 private static class MapAdapter implements TemplateModelRoot {
59 private MapAdapter(Map aMap) {
61 valuesCache = new HashMap();
64 public void put(String aKey, TemplateModel aModel) {
65 valuesCache.put(aKey, aModel);
68 public void remove(String aKey) {
69 // ML: kinda tricky...
72 public boolean isEmpty() {
76 public TemplateModel get(String aKey) throws TemplateModelException {
77 if (!valuesCache.containsKey(aKey)) {
78 Object value = map.get(aKey);
81 throw new TemplateModelException("MapAdapter: no key "+aKey+" available");
83 valuesCache.put(aKey, makeAdapter(value));
86 return (TemplateModel) valuesCache.get(aKey);
90 private static class IteratorAdapter implements TemplateListModel {
95 private IteratorAdapter(Iterator anIterator) {
96 iterator = anIterator;
98 valuesCache = new Vector();
102 if (iterator instanceof RewindableIterator) {
103 ((RewindableIterator) iterator).rewind();
107 public boolean isEmpty() {
108 return valuesCache.isEmpty() && !iterator.hasNext();
111 private void getUntil(int anIndex) throws TemplateModelException {
112 while (valuesCache.size()<=anIndex && iterator.hasNext())
114 valuesCache.add(makeAdapter(iterator.next()));
118 public TemplateModel get(int anIndex) throws TemplateModelException {
119 TemplateModel result;
123 if (anIndex<valuesCache.size())
125 result = (TemplateModel) valuesCache.get(anIndex);
130 throw new TemplateModelException( "Iterator out of bounds" );
133 public boolean hasNext() {
134 return position<valuesCache.size() || iterator.hasNext();
137 public boolean isRewound() {
141 public TemplateModel next() throws TemplateModelException {
142 TemplateModel result;
145 result = get(position);
149 throw new TemplateModelException( "Iterator out of bounds" );
154 public void rewind() {
159 private static class ListAdapter implements TemplateListModel {
164 private ListAdapter(List aList) {
166 valuesCache = new Vector();
170 public boolean isEmpty() {
171 return list.isEmpty();
174 public TemplateModel get(int i) throws TemplateModelException {
176 if (i>=valuesCache.size() && i<list.size()) {
177 for(int j=valuesCache.size(); j<=i; j++) {
178 valuesCache.add(makeAdapter(list.get(j)));
182 if (i<valuesCache.size())
183 return (TemplateModel) valuesCache.get(i);
185 throw new TemplateModelException( "Iterator out of bounds" );
188 public boolean hasNext() {
189 return position<list.size();
192 public boolean isRewound() {
196 public TemplateModel next() throws TemplateModelException {
197 TemplateModel result;
200 result = get(position);
204 throw new TemplateModelException( "Iterator out of bounds" );
209 public void rewind() {
214 /* private static class DateAdapter implements TemplateHashModel {
217 private DateAdapter(Date aDate) {
221 public boolean isEmpty() {
225 public TemplateModel get(String aKey) throws TemplateModelException {
226 return makeAdapter(new SimpleDateFormat(aKey).format(date));