KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > event > helper > DefaultViewHandler


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: DefaultViewHandler.java,v 1.20 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.event.helper;
21
22 import java.io.*;
23 import java.util.*;
24 import javax.servlet.*;
25
26 import org.apache.log4j.*;
27 import org.w3c.dom.*;
28
29 import org.enhydra.barracuda.core.comp.*;
30 import org.enhydra.barracuda.core.util.dom.*;
31 import org.enhydra.barracuda.core.event.*;
32 import org.enhydra.barracuda.core.helper.servlet.*;
33
34 /**
35  * <p>A very simple view handler that provides a default implementation
36  * tailored for the use of components. In many ways, this is analagous to
37  * the ComponentGateway class--a component hierarchy is created, initialized
38  * and rendered automatically for you. All the developer has to do is a)
39  * implement the handleViewEvent method to add any custom components to the root
40  * component (ie. for rendering) and b) return the master DOM page that needs
41  * to be rendered to generate the final view.
42  */

43 public abstract class DefaultViewHandler extends DefaultBaseEventListener {
44
45     //public vars...eventually, these should probably be final
46
protected static final Logger localLogger = Logger.getLogger(DefaultViewHandler.class.getName());
47     
48     //private vars
49
//csc_061202.1_start - add support for max age; also note that these should NOT be global
50
//as they will cause the pretty printing and caching stuff to apply to the entire app,
51
//and realistically, we probably wouldn't want to do that...we'd probably want to do
52
//it on a page level instead
53
// protected boolean printPretty = false;
54
// protected boolean preventCaching = false;
55
// protected int maxAge = 0;
56
//csc_061202.1_end
57
protected boolean recycleChildren = false;
58     protected ViewContext vc = null; //csc_030503.1
59

60     /**
61      * Public noargs constructor
62      */

63     public DefaultViewHandler() {}
64
65
66     //-------------------- DefaultViewHandler --------------------
67
/**
68      * <p>Handle a view event. This is the method developers will
69      * typically override. The developers shaould add any components
70      * to the root component and then return the underlying DOM Document
71      * (that backs their components) so it can be rendered
72      *
73      * @param root the root component which will get rendered as a result
74      * of this request
75      * @return the Document to be rendered
76      * @throws ServletException
77      * @throws IOException
78      */

79 //csc_030603.1 public abstract Document handleViewEvent(BComponent root, ViewContext vc) throws EventException, ServletException, IOException;
80
public abstract Document handleViewEvent(BComponent root) throws EventException, ServletException, IOException; //csc_030603.1
81

82     /**
83      * The purpose of this method is to allow for optional pre-component-render
84      * cycle processing (ie. to stick a value in the user's session). If you need
85      * a reference to the view context, call getViewContext()
86      *
87      * @param root the root component which will get rendered as a result
88      * of this request
89      */

90 //csc_030603.1 public void preCompRender(BComponent root, ViewContext vc) {
91
public void preCompRender(BComponent root) { //csc_030603.1
92
//(--n/a--)
93
}
94     
95     /**
96      * The purpose of this method is to allow for optional post-component-render
97      * cycle processing (ie. to remove a value from the user's session). If you need
98      * a reference to the view context, call getViewContext()
99      *
100      * @param root the root component which will get rendered as a result
101      * of this request
102      */

103 //csc_030603.1 public void postCompRender(BComponent root, ViewContext vc) {
104
public void postCompRender(BComponent root) { //csc_030603.1
105
//(--n/a--)
106
}
107
108     /**
109      * <p>Get a DOMWriter. By default, we use a DefaultDOMWriter. If
110      * you'd like to use something else, override this method.
111      *
112      * @return a DOMWriter to be used to render the DOM
113      */

114     public DOMWriter getDOMWriter() {
115         //return DefaultDOM writer
116
// DefaultDOMWriter ddw = new DefaultDOMWriter(printPretty, preventCaching);
117
// ddw.setMaxAge(maxAge); //csc_061202.1
118
// return ddw;
119
//since we don't override defaults here and there are no setter methods for
120
//printPretty, preventCaching, and maxAge in this class, don't bother storing
121
//this stuff in this class. Let DefaultDOMWriter deal with the defaults.
122
//If one wants specific behavior, override this method and set up the DOMWriter
123
//however you want.
124
return new DefaultDOMWriter();
125     }
126
127     //csc_030503.1_start - make it possible to get a reference to the ViewContext
128
//without having to pass it everywhere. NOte that this actually renders the ViewContext
129
//paramter in handleViewEvent, preCompRender, and postCompRender obsolete, but for
130
//now we'll just leave them in there (so we don't break existing code)
131
/**
132      * Set the view context
133      */

134     public void setViewContext(ViewContext ivc) {
135         vc = ivc;
136     }
137     
138     /**
139      * Get the view context
140      */

141     public ViewContext getViewContext() {
142         return vc;
143     }
144     //csc_030503.1_end
145

146
147     //-------------------- DefaultBaseEventListener --------------
148
/**
149      * Handle the ViewEvent
150      */

151     public void handleViewEvent(ViewEventContext vec) throws EventException, ServletException, IOException {
152         long bmillis = 0;
153         long smillis = 0;
154         long emillis = 0;
155         long elapsed1 = 0;
156         long elapsed2 = 0;
157         if (localLogger.isInfoEnabled()) bmillis = System.currentTimeMillis();
158         if (localLogger.isInfoEnabled()) localLogger.info("Handling ViewEvent in "+this);
159
160         try {
161             //start by figuring out the ViewCapabilities
162
if (localLogger.isDebugEnabled()) localLogger.debug("Create the ViewContext");
163             ViewContext vc = new DefaultViewContext(vec);
164             setViewContext(vc); //csc_030503.1
165

166             //create our root component
167
if (localLogger.isDebugEnabled()) localLogger.debug("Create component root");
168             BComponent broot = new BComponent();
169             broot.setName("Root");
170         
171             //give the implementation a chance to add any components to the root
172
if (localLogger.isDebugEnabled()) localLogger.debug("Handling default");
173 //csc_030603.1 Document doc = handleViewEvent(broot, vc);
174
Document doc = handleViewEvent(broot); //csc_030603.1
175

176             //now init the component
177
if (localLogger.isDebugEnabled()) localLogger.debug("Invoking initCycle on component hierarchy");
178             broot.initCycle();
179         
180             //allow for pre-rendering processing //csc_021102.2 - added
181
if (localLogger.isDebugEnabled()) localLogger.debug("Pre-component render");
182             if (localLogger.isDebugEnabled()) smillis = System.currentTimeMillis();
183 //csc_030603.1 preCompRender(broot, vc);
184
preCompRender(broot); //csc_030603.1
185
if (localLogger.isDebugEnabled()) elapsed1 = System.currentTimeMillis()-smillis;
186
187             //now render the component
188
if (localLogger.isDebugEnabled()) localLogger.debug("Rendering component hierarchy");
189             if (localLogger.isDebugEnabled()) smillis = System.currentTimeMillis();
190             broot.render(vc);
191             if (localLogger.isDebugEnabled()) elapsed1 = System.currentTimeMillis()-smillis;
192
193             //allow for pre-rendering processing //csc_021102.2 - added
194
if (localLogger.isDebugEnabled()) localLogger.debug("Post-component render");
195             if (localLogger.isDebugEnabled()) smillis = System.currentTimeMillis();
196 //csc_030603.1 postCompRender(broot, vc);
197
postCompRender(broot); //csc_030603.1
198
if (localLogger.isDebugEnabled()) elapsed1 = System.currentTimeMillis()-smillis;
199
200             //its possible the implementor may want to recycle children...if so, remove them
201
//prior to calling destroy on the root
202
if (recycleChildren) {
203                 if (localLogger.isDebugEnabled()) localLogger.debug("Recycling child components");
204                 List children = broot.getChildren();
205                 if (children!=null) {
206                     for (int i=children.size()-1; i>=0; i--) {
207                         broot.removeChild(i);
208                     }
209                 }
210             }
211
212             //now destroy the component
213
if (localLogger.isDebugEnabled()) localLogger.debug("Invoking destroyCycle on component hierarchy");
214             broot.destroyCycle();
215         
216             //csc_102201.1
217
//now adjust the outgoing page (this is critical to make sure we
218
//can accurately detect client scripting)
219
ScriptDetector.prepareClientResp(doc, vc);
220
221             //now render the page
222
if (localLogger.isDebugEnabled()) localLogger.debug("Rendering the DOM");
223             if (localLogger.isInfoEnabled()) smillis = System.currentTimeMillis();
224             this.getDOMWriter().write(doc, vec.getResponse());
225             if (localLogger.isInfoEnabled()) {
226                 elapsed2 = System.currentTimeMillis()-smillis;
227                 emillis = System.currentTimeMillis();
228             }
229         } catch (RenderException e) {
230             //if we get an EventException, handle it
231
if (localLogger.isInfoEnabled()) localLogger.info("Unexpected RenderException:"+e);
232             throw new EventException ("Unexpected RenderException:"+e, e);
233             
234         } catch (RuntimeException JavaDoc re) {
235             //if we get an RuntimeException, just log that it happened
236
if (localLogger.isInfoEnabled()) localLogger.info("Unexpected RuntimeException:"+re, re);
237             throw re;
238
239         } finally {
240             setViewContext(null); //csc_030503.1
241
}
242
243         if (localLogger.isInfoEnabled()) localLogger.info("ViewEvent handled! (rendered in "+(elapsed1)+"/written in "+(elapsed2)+" of "+(emillis-bmillis)+" millis)");
244     }
245
246
247 }
248
Popular Tags