KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > wcf > component > RendererTag


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.wcf.component;
14
15 import java.io.StringWriter JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23 import javax.servlet.jsp.JspException JavaDoc;
24 import javax.servlet.jsp.tagext.TagSupport JavaDoc;
25 import javax.xml.transform.Transformer JavaDoc;
26 import javax.xml.transform.dom.DOMSource JavaDoc;
27 import javax.xml.transform.stream.StreamResult JavaDoc;
28
29 import org.apache.log4j.Logger;
30 import org.w3c.dom.Document JavaDoc;
31 import org.w3c.dom.Element JavaDoc;
32 import org.w3c.dom.Node JavaDoc;
33 import org.w3c.dom.NodeList JavaDoc;
34
35 import com.tonbeller.wcf.controller.RequestContext;
36 import com.tonbeller.wcf.expr.ExprUtils;
37 import com.tonbeller.wcf.token.RequestToken;
38 import com.tonbeller.wcf.utils.DomUtils;
39 import com.tonbeller.wcf.utils.XmlUtils;
40
41 /**
42  * renders a Component via xsl stylesheet. The following
43  * stylesheet parameters are provided automatically (w/o nested parameter tag):
44  * <ul>
45  * <li><code>renderId</code> - contains the id of this tag. If not set the modelReference is taken
46  * <li><code>context</code> - the context path of the application for building URLs
47  * </ul>
48  * Parameters may occur in xsl (as usual) and in the <code>Document</code> created by the
49  * <code>Component</code>
50  * <p>
51  * Searches for &lt;param name=".."/&gt; elements and creates
52  * a corresponding attribute in its parent. For example, if a <code>Component</code>s
53  * <code>render()</code> method returns the following <code>Document</code>
54  * <pre>
55  * &lt;myelem&gt;
56  * &lt;param name="abc" attr="bcd"/&gt;
57  * &lt;/myelem&gt;
58  * </pre>
59  * it will become
60  * <pre>
61  * &lt;myelem bcd="efg"&gt;
62  * &lt;param name="abc" attr="bcd"/&gt;
63  * &lt;/myelem&gt;
64  * </pre>
65  * where <code>efg</code> is the value of the <code>abc</code> parameter.
66  * If the parameter <code>abc</code> does not exsist, the attribute
67  * <code>bcd</code> is removed.
68  * <p>
69  * This may be used to configure the page flow from a jsp, e.g.
70  * <pre>
71  * &lt;button label="OK" action="validate" handler="...">
72  * &lt;param name="successPage" attr="forward"/>
73  * &lt;/button>
74  * </pre>
75  * will create a forward attribute to the button element whose value is supplied by the jsp author.
76  *
77  * @author av
78  */

79 public class RendererTag extends TagSupport JavaDoc {
80   String JavaDoc xslUri;
81   boolean xslCache = true;
82   String JavaDoc ref;
83   Map JavaDoc parameters = new HashMap JavaDoc();
84
85   private static Logger logger = Logger.getLogger(RendererTag.class);
86
87   /**
88    * adds a parameter that is valid for this transformation only.
89    */

90   void addParameter(String JavaDoc name, Object JavaDoc value) {
91     parameters.put(name, value);
92   }
93
94   /**
95    * removes a parameter that is defined globally for this transformation
96    * @param name
97    */

98   public void removeParameter(String JavaDoc name) {
99     parameters.remove(name);
100   }
101
102   public int doStartTag() throws JspException JavaDoc {
103     parameters.putAll(RendererParameters.getParameterMap((HttpServletRequest JavaDoc) pageContext.getRequest()));
104     return EVAL_BODY_INCLUDE;
105   }
106
107   /**
108    * renders the component
109    */

110   public int doEndTag() throws JspException JavaDoc {
111     logger.info("enter " + ref);
112
113     try {
114       RequestContext context = RequestContext.instance();
115       Object JavaDoc x = context.getModelReference(getRef());
116       if (x == null)
117         throw new JspException JavaDoc("component \"" + getRef() + "\" not found");
118       if(!(x instanceof Renderable))
119         throw new JspException JavaDoc("component \"" + getRef() + "\" is not Renderable: " + x.getClass());
120       Renderable comp = (Renderable) x;
121
122       if (comp instanceof Visible && !((Visible) comp).isVisible())
123         return EVAL_PAGE;
124
125       if (comp instanceof RoleExprHolder) {
126         String JavaDoc roleExpr = ((RoleExprHolder) comp).getRoleExpr();
127         if (!context.isUserInRole(roleExpr))
128           return EVAL_PAGE;
129       }
130
131       // add "context" and "renderId" to parameter map
132
createPredefinedParameters(context);
133
134       Transformer JavaDoc transformer = XmlUtils.getTransformer(pageContext.getSession(), xslUri, xslCache);
135       setXslParameters(context, transformer);
136
137       Document JavaDoc document = comp.render(context);
138
139       // PrintWriter pw = new PrintWriter(System.out);
140
// XmlUtils.print(document, pw);
141
// pw.flush();
142

143       setXmlParameters(document);
144
145       // we can not render to the output stream directly, because this gives an
146
// "illecal flush" exception in JSF EA2
147
DOMSource JavaDoc source = new DOMSource JavaDoc(document);
148       StringWriter JavaDoc sw = new StringWriter JavaDoc();
149       StreamResult JavaDoc result = new StreamResult JavaDoc(sw);
150
151       transformer.transform(source, result);
152       sw.flush();
153       pageContext.getOut().write(sw.toString());
154
155       parameters.clear();
156       logger.info("leave " + ref);
157       return EVAL_PAGE;
158     } catch (Exception JavaDoc e) {
159       logger.error("trouble rendering " + getRef(), e);
160       throw new JspException JavaDoc(e.toString(), e);
161     }
162   }
163
164   /**
165    * sets the parameters to the xml document.
166    * Searches for &lt;param name=".."/&gt; elements and creates
167    * a corresponding attribute in its parent. For example,
168    * <pre>
169    * &lt;myelem&gt;
170    * &lt;param name="abc" attr="bcd"/&gt;
171    * &lt;/myelem&gt;
172    * </pre>
173    * will become
174    * <pre>
175    * &lt;myelem bcd="efg"&gt;
176    * &lt;param name="abc" attr="bcd"/&gt;
177    * &lt;/myelem&gt;
178    * </pre>
179    * where <code>efg</code> is the value of the <code>abc</code> parameter.
180    * If the parameter <code>abc</code> does not exsist, the attribute
181    * <code>bcd</code> is removed.
182    */

183   protected void setXmlParameters(Document JavaDoc document) /*throws JaxenException*/ {
184     /* eb 16.05.03 - Jaxen ist teuer
185         DOMXPath xp = new DOMXPath("//param");
186         List list = xp.selectNodes(document);
187         for (Iterator it = list.iterator(); it.hasNext();) {
188           Element param = (Element) it.next();
189           String paramName = param.getAttribute("name");
190           String attrName = param.getAttribute("attr");
191           String value = (String)parameters.get(paramName);
192           Element parent = (Element) param.getParentNode();
193           if (value == null || value.length() == 0)
194             parent.removeAttribute(attrName);
195           else
196             parent.setAttribute(attrName, value);
197         }
198     */

199     // tables etc may be *very* large, so we search for
200
// parameters only in <xform ..> documents.
201
Element JavaDoc root = document.getDocumentElement();
202     if (root != null && "xform".equals(root.getNodeName()))
203       setXmlParameters(document.getChildNodes());
204   }
205
206   protected void setXmlParameters(NodeList JavaDoc list) {
207     int len = list.getLength();
208     for (int i = 0; i < len; i++) {
209       Node JavaDoc n = list.item(i);
210       if (n.getNodeType() != Node.ELEMENT_NODE)
211         continue;
212       Element JavaDoc x = (Element JavaDoc) list.item(i);
213
214       if ("param".equals(x.getNodeName())) {
215         String JavaDoc paramName = x.getAttribute("name");
216         String JavaDoc attrName = x.getAttribute("attr");
217         String JavaDoc value = (String JavaDoc) parameters.get(paramName);
218         Element JavaDoc parent = (Element JavaDoc) x.getParentNode();
219         if (value == null || value.length() == 0)
220           DomUtils.removeAttribute(parent, attrName);
221         else
222           parent.setAttribute(attrName, value);
223       } else {
224         setXmlParameters(x.getChildNodes());
225       }
226     }
227   }
228
229   /**
230    * sets the parameters to the transformer
231    */

232   void setXslParameters(RequestContext context, Transformer JavaDoc transformer) {
233     for (Iterator JavaDoc it = parameters.keySet().iterator(); it.hasNext();) {
234       String JavaDoc name = (String JavaDoc) it.next();
235       Object JavaDoc value = parameters.get(name);
236       transformer.setParameter(name, value);
237     }
238   }
239
240   /** add "context" and "renderId" to parameter map */
241   private void createPredefinedParameters(RequestContext context) throws MalformedURLException JavaDoc {
242     String JavaDoc renderId = this.getId();
243     if (renderId == null || renderId.length() == 0)
244       renderId = ExprUtils.getBeanName(getRef());
245     parameters.put("renderId", renderId);
246     parameters.put("context", context.getRequest().getContextPath());
247     // Some FOP-PDF versions require a complete URL, not a path
248
parameters.put("contextUrl", createContextURLValue(context));
249
250     // if there, add token to control page flow
251
if (context.getSession() != null) {
252         RequestToken tok = RequestToken.instance(context.getSession());
253         if (tok != null) {
254             parameters.put("token", tok.getHttpParameterName() + "=" + tok.getToken());
255         }
256     }
257   }
258
259   /** generates the context URL stylesheet parameter */
260   private String JavaDoc createContextURLValue(RequestContext context) throws MalformedURLException JavaDoc {
261
262     if (context.getRequest() == null || context.getRequest().getRequestURL() == null) {
263         return "UNDEFINED";
264     }
265     
266     URL JavaDoc url = new URL JavaDoc((context.getRequest()).getRequestURL().toString());
267
268     StringBuffer JavaDoc c = new StringBuffer JavaDoc();
269     c.append(url.getProtocol());
270     c.append("://");
271     c.append(url.getHost());
272     if (url.getPort() != 80) {
273       c.append(":");
274       c.append(url.getPort());
275     }
276     c.append(context.getRequest().getContextPath());
277
278     return c.toString();
279   }
280
281   /**
282    * Returns the ref.
283    * @return String
284    */

285   public String JavaDoc getRef() {
286     return ref;
287   }
288
289   /**
290    * Returns the xslCache.
291    * @return boolean
292    */

293   public boolean isXslCache() {
294     return xslCache;
295   }
296
297   /**
298    * Returns the xslUri.
299    * @return String
300    */

301   public String JavaDoc getXslUri() {
302     return xslUri;
303   }
304
305   /**
306    * Sets the ref.
307    * @param ref The ref to set
308    */

309   public void setRef(String JavaDoc ref) {
310     this.ref = ref;
311   }
312
313   /**
314    * Sets the xslCache.
315    * @param xslCache The xslCache to set
316    */

317   public void setXslCache(boolean xslCache) {
318     this.xslCache = xslCache;
319   }
320
321   /**
322    * Sets the xslUri.
323    * @param xslUri The xslUri to set
324    */

325   public void setXslUri(String JavaDoc xslUri) {
326     this.xslUri = xslUri;
327   }
328
329 }
330
Popular Tags