001: /*
002: * Copyright (c) 2002-2007 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.views.freemarker.tags;
006:
007: import com.opensymphony.webwork.components.Component;
008: import com.opensymphony.xwork.util.OgnlValueStack;
009:
010: import freemarker.template.DefaultObjectWrapper;
011: import freemarker.template.TemplateModel;
012: import freemarker.template.TemplateModelException;
013: import freemarker.template.TemplateTransformModel;
014:
015: import javax.servlet.http.HttpServletRequest;
016: import javax.servlet.http.HttpServletResponse;
017: import java.io.IOException;
018: import java.io.Writer;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: /**
027: * An abstract class mean to be implemented by WebWork's Freemarker's
028: * Tag. It abstracts away the logic of parameter conversion exposed by
029: * Freemarker's {@link TemplateTransformModel#getWriter(Writer, Map)} method
030: * and populating them into WebWork's component exposed by subclass
031: * through {@link #getBean()} method.
032: *
033: * @author plightbo
034: * @author tmjee
035: * @version $Date: 2007-03-20 18:52:15 +0100 (Tue, 20 Mar 2007) $ $Id: TagModel.java 2866 2007-03-20 17:52:15Z tm_jee $
036: */
037: public abstract class TagModel implements TemplateTransformModel {
038: private static final Log LOG = LogFactory.getLog(TagModel.class);
039:
040: protected OgnlValueStack stack;
041: protected HttpServletRequest req;
042: protected HttpServletResponse res;
043:
044: public TagModel(OgnlValueStack stack, HttpServletRequest req,
045: HttpServletResponse res) {
046: this .stack = stack;
047: this .req = req;
048: this .res = res;
049: }
050:
051: /**
052: * Returns a Writer that will render WebWork Freemarker tag.
053: *
054: * @see TemplateTransformModel#getWriter(Writer, Map)
055: */
056: public Writer getWriter(Writer writer, Map params)
057: throws TemplateModelException, IOException {
058: Component bean = getBean();
059:
060: Map unwrappedParameters = unwrapParameters(params);
061: bean.copyParams(unwrappedParameters);
062:
063: //Map basicParams = convertParams(params);
064: //bean.copyParams(basicParams);
065: //bean.addAllParameters(getComplexParams(params));
066:
067: return new CallbackWriter(bean, writer);
068: }
069:
070: /**
071: * Unwraped the parameters (Map) passed in by
072: * {TemplateTransformModel{@link #getWriter(Writer, Map)}. It makes use
073: * of {DefaultObjectWrapper{@link #unwrapParameters(Map)} to do the
074: * unwrapping if the value of the entry in the <code>params</code> is
075: * of type {#TemplateModel} (which should ALWAYS be the case) else it
076: * will just use the <code>toString()</code> representation of it.
077: *
078: * @param params
079: * @return Map
080: */
081: protected Map unwrapParameters(Map params) {
082: Map map = new HashMap(params.size());
083: DefaultObjectWrapper objectWrapper = new DefaultObjectWrapper();
084: for (Iterator iterator = params.entrySet().iterator(); iterator
085: .hasNext();) {
086: Map.Entry entry = (Map.Entry) iterator.next();
087:
088: Object value = entry.getValue();
089:
090: if (value != null) {
091: // the value should ALWAYS be a decendant of TemplateModel
092: if (value instanceof TemplateModel) {
093: try {
094: map.put(entry.getKey(), objectWrapper
095: .unwrap((TemplateModel) value));
096: } catch (TemplateModelException e) {
097: LOG.error("failed to unwrap [" + value
098: + "] it will be ignored", e);
099: }
100: }
101: // if it doesn't, we'll do it the old way by just returning the toString() representation
102: else {
103: map.put(entry.getKey(), value.toString());
104: }
105: }
106: }
107: return map;
108: }
109:
110: /**
111: * An abstract method subclass should implement, exposing the WebWork's
112: * underlying {Component} this tag is supposed to delegate to.
113: *
114: * @return Component
115: */
116: protected abstract Component getBean();
117:
118: /*private Map convertParams(Map params) {
119: HashMap map = new HashMap(params.size());
120: for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
121: Map.Entry entry = (Map.Entry) iterator.next();
122: Object value = entry.getValue();
123: if (value != null && !complexType(value)) {
124: map.put(entry.getKey(), value.toString());
125: }
126: }
127: return map;
128: }*/
129:
130: /*private Map getComplexParams(Map params) {
131: HashMap map = new HashMap(params.size());
132: for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();) {
133: Map.Entry entry = (Map.Entry) iterator.next();
134: Object value = entry.getValue();
135: if (value != null && complexType(value)) {
136: if (value instanceof freemarker.ext.beans.BeanModel) {
137: map.put(entry.getKey(), ((freemarker.ext.beans.BeanModel) value).getWrappedObject());
138: } else if (value instanceof SimpleNumber) {
139: map.put(entry.getKey(), ((SimpleNumber) value).getAsNumber());
140: } else if (value instanceof SimpleSequence) {
141: try {
142: map.put(entry.getKey(), ((SimpleSequence) value).toList());
143: } catch (TemplateModelException e) {
144: LOG.error("There was a problem converting a SimpleSequence to a list", e);
145: }
146: }
147: }
148: }
149: return map;
150: }*/
151:
152: /*private boolean complexType(Object value) {
153: return value instanceof freemarker.ext.beans.BeanModel
154: || value instanceof SimpleNumber
155: || value instanceof SimpleSequence;
156: }*/
157: }
|