KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > soto > state > cocoon > view > JellyView


1 package org.sapia.soto.state.cocoon.view;
2
3 import org.apache.commons.jelly.Jelly;
4 import org.apache.commons.jelly.JellyContext;
5 import org.apache.commons.jelly.Script;
6 import org.apache.commons.jelly.XMLOutput;
7 import org.apache.commons.lang.ClassUtils;
8
9 import org.sapia.soto.state.Result;
10 import org.sapia.soto.state.StateRuntimeException;
11 import org.sapia.soto.state.Step;
12 import org.sapia.soto.state.cocoon.CocoonContext;
13 import org.sapia.soto.state.xml.StyleStep;
14 import org.sapia.soto.state.xml.TransformState;
15 import org.sapia.soto.state.xml.XMLContext;
16 import org.sapia.soto.util.Param;
17 import org.sapia.soto.util.Resource;
18 import org.sapia.soto.util.ResourceHandler;
19 import org.sapia.soto.util.Utils;
20
21 import org.sapia.util.xml.confix.ConfigurationException;
22
23 import org.xml.sax.ContentHandler JavaDoc;
24
25 import java.io.IOException JavaDoc;
26
27 import java.net.URL JavaDoc;
28
29 import java.util.ArrayList JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32
33 import javax.xml.transform.TransformerConfigurationException JavaDoc;
34
35 /**
36  * An instance of this class implements XSL pipelining in the following way:
37  *
38  * <ul>
39  * <li>It expects the URI to a valid Jelly script to be given to it.
40  * <li>If stylesheets (<code>XslSource</code> instances) are assigned to it,
41  * they take part in the pipeline of SAX events that originate from the Jelly
42  * script's execution.
43  * </ul>
44  * <p>
45  * A Jelly view expects the model (in an MVC sense) to be the "current object" on
46  * the execution context's stack. The current object is exported to the Jelly script's
47  * context, under the name "Model", or under the name specified by the application. The
48  * view parameters are also exported to the Jelly context.
49  * <p>
50  * An instance of this class checks if its Jelly script source has been modified, and
51  * reloads it if such is the case. If the given script URI does not correspond to a
52  * <code>File</code> object, then there is no way to check for such modifications, and
53  * in such cases such a check is impossible. To make sure that this feature is "on",
54  * use the <code>file</code> protocol when setting URIs (e.g.: file:/some/jellyScript.xml).
55  * <p>
56  * See <a HREF="http://jakarta.apache.org/jelly">Jelly's doc</a> for more info.
57  *
58  * @see org.sapia.soto.state.Context
59  * @see org.sapia.soto.state.cocoon.CocoonContext#getViewParams()
60  *
61  *
62  * @author Yanick Duchesne
63  * <dl>
64  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
65  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
66  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
67  * </dl>
68  */

69 public class JellyView extends TransformState implements Step {
70   private Script _jelly;
71   private String JavaDoc _uri;
72   private String JavaDoc _id;
73   private Resource _res;
74   private long _lastModified;
75   private List JavaDoc _params = new ArrayList JavaDoc();
76   
77   /**
78    * @see org.sapia.soto.state.Step#getName()
79    */

80   public String JavaDoc getName() {
81     return ClassUtils.getShortClassName(getClass());
82   }
83
84   /**
85    * @param uri the URI to a Jelly script.
86    * @throws IOException
87    * @throws Exception
88    */

89   public void setSrc(String JavaDoc uri) throws IOException JavaDoc, Exception JavaDoc {
90     _uri = uri;
91
92     ResourceHandler handler = (ResourceHandler) env().getResourceHandlerFor(Utils.chopScheme(
93           uri));
94     _res = handler.getResourceObject(uri);
95
96     Jelly j = new Jelly();
97     _lastModified = _res.lastModified();
98     j.setUrl(new URL JavaDoc(_res.getURI()));
99     _jelly = j.compileScript();
100   }
101   
102     /**
103      * Internally creates and adds a parameter to this instance, and returns
104      * that parameter.
105      *
106      * @return a <code>Param</code>
107      */

108     public Param createParam(){
109         Param p = new Param();
110         _params.add(p);
111         return p;
112     }
113     
114
115   /**
116    * @see org.sapia.soto.state.xml.TransformState#process(org.sapia.soto.state.Result, org.xml.sax.ContentHandler)
117    */

118   protected void process(Result res, ContentHandler JavaDoc handler) {
119     XMLContext ctx = (XMLContext) res.getContext();
120
121     Object JavaDoc model = null;
122
123     if (ctx.hasCurrentObject()) {
124       model = ctx.currentObject();
125     }
126
127     try {
128       execute(model, ctx.getViewParams(), handler);
129     } catch (Throwable JavaDoc t) {
130       throw new StateRuntimeException("Could not run Jelly state: " + getId() +
131         " for script: " + _uri, t);
132     }
133   }
134
135   protected void execute(Object JavaDoc model, Map JavaDoc viewParams, ContentHandler JavaDoc handler)
136     throws Throwable JavaDoc {
137     if (_jelly == null) {
138       throw new IllegalStateException JavaDoc("Jelly script not set on Jelly view");
139     }
140
141     if (_lastModified != _res.lastModified()) {
142       reload();
143     }
144
145     JellyContext jelly = new JellyContext();
146     JellyUtils.copyParamsTo(jelly, viewParams);
147   
148     jelly.setVariable(CocoonContext.MODEL_KEY, model);
149     
150         Param p;
151         for(int i = 0; i < _params.size(); i++){
152             p = (Param)_params.get(i);
153             if(p.getName() != null && p.getValue() != null){
154                 jelly.setVariable(p.getName(), p.getValue());
155             }
156         }
157     
158     XMLOutput output = new XMLOutput(handler);
159     output.startDocument();
160     _jelly.run(jelly, output);
161     output.endDocument();
162   }
163
164   /**
165    * @see org.sapia.util.xml.confix.ObjectHandlerIF#handleObject(java.lang.String, java.lang.Object)
166    */

167   public void handleObject(String JavaDoc name, Object JavaDoc obj)
168     throws ConfigurationException {
169     if (obj instanceof XslSource) {
170         try{
171             XslSource xsl = (XslSource)obj;
172           StyleStep step = new StyleStep();
173         step.setEnv(env());
174         step.setSrc(xsl.getUri());
175         }catch(TransformerConfigurationException JavaDoc e){
176             throw new ConfigurationException("Could not instantiate StyleStep", e);
177         }catch(IOException JavaDoc e){
178             throw new ConfigurationException("Could not inialize stylesheet", e);
179         }
180     }
181     else{
182             super.handleObject(name, obj);
183     }
184   }
185
186   private synchronized void reload() throws Exception JavaDoc {
187     if (_res.lastModified() != _lastModified) {
188       Jelly j = new Jelly();
189       j.setUrl(new URL JavaDoc(_res.getURI()));
190       _jelly = j.compileScript();
191     }
192
193     _lastModified = _res.lastModified();
194   }
195 }
196
Popular Tags