2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.view.faces;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24 import javax.faces.component.UINamingContainer;
25 import javax.faces.context.ExternalContext;
26 import javax.faces.context.FacesContext;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.shale.util.Messages;
30 import org.apache.shale.view.Constants;
31 import org.apache.shale.view.ExceptionHandler;
32 import org.apache.shale.view.ViewController;
33
34 /***
35 * <p>Specialized implementation of <code>UINamingContainer</code> that
36 * provides {@link ViewController} functionality for subviews.</p>
37 *
38 * $Id: SubviewComponent.java 464373 2006-10-16 04:21:54Z rahul $
39 */
40 public class SubviewComponent extends UINamingContainer {
41
42
43
44
45
46 /***
47 * <p>Log instance for this class.</p>
48 */
49 private static final Log log = LogFactory.getLog(SubviewComponent.class);
50
51
52 /***
53 * <p>Message resources for this class.</p>
54 */
55 private static Messages messages =
56 new Messages("org.apache.shale.view.resources.Bundle",
57 SubviewComponent.class.getClassLoader());
58
59
60
61
62
63 /***
64 * <p>Return the component family for this component.</p>
65 */
66 public String getFamily() {
67
68 return "org.apache.shale.view.Subview";
69
70 }
71
72
73 /***
74 * <p>Prior to the standard processing, call the <code>prerender()</code>
75 * callback on the {@link ViewController} associated with this subview,
76 * if any.</p>
77 *
78 * @param context <code>FacesContext</code> for the current request
79 *
80 * @exception IOException if an input/output error occurs
81 */
82 public void encodeBegin(FacesContext context) throws IOException {
83
84 Object vc = getViewController(context, false);
85 if (vc != null) {
86 try {
87 getViewControllerCallbacks(context).prerender(vc);
88 } catch (Exception e) {
89 handleException(context, e);
90 }
91 }
92 super.encodeBegin(context);
93
94 }
95
96
97 /***
98 * <p>Prior to the standard processing, call the <code>preprocess()</code>
99 * callback on the {@link ViewController} associated with this subview,
100 * if any.</p>
101 *
102 * @param context <code>FacesContext</code> for the current request
103 */
104 public void processDecodes(FacesContext context) {
105
106 Object vc = getViewController(context, true);
107 if (vc != null) {
108 try {
109 getViewControllerCallbacks(context).preprocess(vc);
110 } catch (Exception e) {
111 handleException(context, e);
112 }
113 }
114 super.processDecodes(context);
115
116 }
117
118
119
120
121
122 /***
123 * <p>Return the {@link ViewController} associated with this component,
124 * if any; otherwise, return <code>null</code>. Note that the signature
125 * for this method is <code>Object</code>, because the instance might
126 * have the <code>@View</code> annotation rather than implementing the
127 * <code>ViewController</code> interface.</p>
128 *
129 * @param context <code>FacesContext</code> for the current request
130 * @param postback Are we processing a postback?
131 */
132 private Object getViewController(FacesContext context,
133 boolean postback) {
134
135
136
137 String name = getId();
138 ExternalContext econtext = context.getExternalContext();
139 Object vc = null;
140 vc = econtext.getRequestMap().get(name);
141 if (vc == null) {
142 vc = econtext.getSessionMap().get(name);
143 }
144 if (vc == null) {
145 vc = econtext.getApplicationMap().get(name);
146 }
147 if (vc != null) {
148 return vc;
149 }
150
151
152 String expr = "#{" + name + "}";
153 vc = context.getApplication().
154 createValueBinding(expr).getValue(context);
155 if (vc == null) {
156 log.debug(messages.getMessage("subview.noBean",
157 new Object[] { getId() }));
158 return null;
159 }
160
161
162 if (vc instanceof ViewController) {
163 ((ViewController) vc).setPostBack(postback);
164 }
165
166
167 Map map = econtext.getRequestMap();
168 List list = (List) map.get(FacesConstants.VIEWS_INITIALIZED);
169 if (list == null) {
170 list = new ArrayList();
171 map.put(FacesConstants.VIEWS_INITIALIZED, list);
172 }
173 list.add(vc);
174
175
176 return vc;
177
178 }
179
180
181 /***
182 * <p>Return the <code>ViewControllerCallbacks</code> instance to be used
183 * to forward prerender and preprocess callbacks to our view controller,
184 * whether or not it implements the <code>ViewController</code> interface
185 * (it may not if it is using the <code>@View</code> annotation from the
186 * shale-tiger module).</p>
187 *
188 * @param context <code>FacesContext</code> for the current request
189 */
190 private ViewControllerCallbacks getViewControllerCallbacks(FacesContext context) {
191
192 ViewControllerCallbacks vcb = (ViewControllerCallbacks)
193 context.getApplication().getVariableResolver().resolveVariable
194 (context, FacesConstants.VIEW_CALLBACKS);
195 return vcb;
196
197 }
198
199
200 /***
201 * <p>Handle the specified exception according to the strategy
202 * defined by our current {@link ExceptionHandler}.</p>
203 *
204 * @param context FacesContext for the current request
205 * @param exception Exception to be handled
206 */
207 private void handleException(FacesContext context, Exception exception) {
208
209 if (context == null) {
210 exception.printStackTrace(System.out);
211 return;
212 }
213 ExceptionHandler handler = (ExceptionHandler)
214 context.getApplication().getVariableResolver().resolveVariable
215 (context, Constants.EXCEPTION_HANDLER);
216 handler.handleException(exception);
217
218 }
219
220
221 }