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);
51 else if (anObject instanceof List)
52 return makeIteratorAdapter(((List) anObject).iterator());
54 throw new TemplateModelException("Unadaptable class: " + anObject.getClass().getName());
57 private static class MapAdapter implements TemplateModelRoot {
61 private MapAdapter(Map aMap) {
63 valuesCache = new HashMap();
66 public void put(String aKey, TemplateModel aModel) {
67 valuesCache.put(aKey, aModel);
70 public void remove(String aKey) {
71 // ML: kinda tricky...
74 public boolean isEmpty() {
78 public TemplateModel get(String aKey) throws TemplateModelException {
79 if (!valuesCache.containsKey(aKey)) {
80 Object value = map.get(aKey);
82 // ML: this unfortunately doesn't work, because the entity doesn't seem to store
83 // fields with null values
84 // if (value == null && !map.containsKey(aKey))
85 // throw new TemplateModelException("MapAdapter: no key "+aKey+" available");
87 valuesCache.put(aKey, makeAdapter(value));
90 return (TemplateModel) valuesCache.get(aKey);
94 private static class IteratorAdapter implements TemplateListModel {
99 private IteratorAdapter(Iterator anIterator) {
100 iterator = anIterator;
102 valuesCache = new Vector();
106 if (iterator instanceof RewindableIterator) {
107 ((RewindableIterator) iterator).rewind();
111 public boolean isEmpty() {
112 return valuesCache.isEmpty() && !iterator.hasNext();
115 private void getUntil(int anIndex) throws TemplateModelException {
116 while (valuesCache.size()<=anIndex && iterator.hasNext())
118 valuesCache.add(makeAdapter(iterator.next()));
122 public TemplateModel get(int anIndex) throws TemplateModelException {
123 TemplateModel result;
127 if (anIndex<valuesCache.size())
129 result = (TemplateModel) valuesCache.get(anIndex);
134 throw new TemplateModelException( "Iterator out of bounds" );
137 public boolean hasNext() {
138 return position<valuesCache.size() || iterator.hasNext();
141 public boolean isRewound() {
145 public TemplateModel next() throws TemplateModelException {
146 TemplateModel result;
149 result = get(position);
153 throw new TemplateModelException( "Iterator out of bounds" );
158 public void rewind() {
163 private static class ListAdapter implements TemplateListModel {
168 private ListAdapter(List aList) {
170 valuesCache = new Vector();
174 public boolean isEmpty() {
175 return list.isEmpty();
178 public TemplateModel get(int i) throws TemplateModelException {
180 if (i>=valuesCache.size() && i<list.size()) {
181 for(int j=valuesCache.size(); j<=i; j++) {
182 valuesCache.add(makeAdapter(list.get(j)));
186 if (i<valuesCache.size())
187 return (TemplateModel) valuesCache.get(i);
189 throw new TemplateModelException( "Iterator out of bounds" );
192 public boolean hasNext() {
193 return position<list.size();
196 public boolean isRewound() {
200 public TemplateModel next() throws TemplateModelException {
201 TemplateModel result;
204 result = get(position);
208 throw new TemplateModelException( "Iterator out of bounds" );
213 public void rewind() {
218 /* private static class DateAdapter implements TemplateHashModel {
221 private DateAdapter(Date aDate) {
225 public boolean isEmpty() {
229 public TemplateModel get(String aKey) throws TemplateModelException {
230 return makeAdapter(new SimpleDateFormat(aKey).format(date));