1 /*
2 * $Id: Renderer.java,v 1.39 2007/04/27 22:00:10 ofung Exp $
3 */
4
5 /*
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7 *
8 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
9 *
10 * The contents of this file are subject to the terms of either the GNU
11 * General Public License Version 2 only ("GPL") or the Common Development
12 * and Distribution License("CDDL") (collectively, the "License"). You
13 * may not use this file except in compliance with the License. You can obtain
14 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
15 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
16 * language governing permissions and limitations under the License.
17 *
18 * When distributing the software, include this License Header Notice in each
19 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
20 * Sun designates this particular file as subject to the "Classpath" exception
21 * as provided by Sun in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the License
23 * Header, with the fields enclosed by brackets [] replaced by your own
24 * identifying information: "Portions Copyrighted [year]
25 * [name of copyright owner]"
26 *
27 * Contributor(s):
28 *
29 * If you wish your version of this file to be governed by only the CDDL or
30 * only the GPL Version 2, indicate your decision by adding "[Contributor]
31 * elects to include this software in this distribution under the [CDDL or GPL
32 * Version 2] license." If you don't indicate a single choice of license, a
33 * recipient has the option to distribute your version of this file under
34 * either the CDDL, the GPL Version 2 or to extend the choice of license to
35 * its licensees as provided above. However, if you add GPL Version 2 code
36 * and therefore, elected the GPL Version 2 license, then the option applies
37 * only if the new code is made subject to such option by the copyright
38 * holder.
39 */
40
41 package javax.faces.render;
42
43
44 import java.io.IOException;
45 import java.util.Iterator;
46 import javax.faces.component.UIComponent;
47 import javax.faces.convert.ConverterException;
48 import javax.faces.context.FacesContext;
49
50
51 /**
52 * <p>A <strong>Renderer</strong> converts the internal representation of
53 * {@link UIComponent}s into the output stream (or writer) associated with
54 * the response we are creating for a particular request. Each
55 * <code>Renderer</code> knows how to render one or more {@link UIComponent}
56 * types (or classes), and advertises a set of render-dependent attributes
57 * that it recognizes for each supported {@link UIComponent}.</p>
58 *
59 * <p>Families of {@link Renderer}s are packaged as a {@link RenderKit},
60 * and together support the rendering of all of the {@link UIComponent}s
61 * in a view associated with a {@link FacesContext}. Within the set of
62 * {@link Renderer}s for a particular {@link RenderKit}, each must be
63 * uniquely identified by the <code>rendererType</code> property.</p>
64 *
65 * <p>Individual {@link Renderer} instances will be instantiated as requested
66 * during the rendering process, and will remain in existence for the
67 * remainder of the lifetime of a web application. Because each instance
68 * may be invoked from more than one request processing thread simultaneously,
69 * they MUST be programmed in a thread-safe manner.</p>
70 */
71
72 public abstract class Renderer {
73
74 // ------------------------------------------------------ Rendering Methods
75
76
77 /**
78 * <p>Decode any new state of the specified {@link UIComponent}
79 * from the request contained in the specified {@link FacesContext},
80 * and store that state on the {@link UIComponent}.</p>
81 *
82 * <p>During decoding, events may be enqueued for later processing
83 * (by event listeners that have registered an interest), by calling
84 * <code>queueEvent()</code> on the associated {@link UIComponent}.
85 * </p>
86 *
87 * @param context {@link FacesContext} for the request we are processing
88 * @param component {@link UIComponent} to be decoded.
89 *
90 * @throws NullPointerException if <code>context</code>
91 * or <code>component</code> is <code>null</code>
92 */
93 public void decode(FacesContext context, UIComponent component) {
94 if (null == context || null == component) {
95 throw new NullPointerException();
96 }
97 }
98
99
100 /**
101 * <p>Render the beginning specified {@link UIComponent} to the
102 * output stream or writer associated with the response we are creating.
103 * If the conversion attempted in a previous call to
104 * <code>getConvertedValue()</code> for this component failed, the state
105 * information saved during execution
106 * of <code>decode()</code> should be used to reproduce the incorrect
107 * input.</p>
108 *
109 * @param context {@link FacesContext} for the request we are processing
110 * @param component {@link UIComponent} to be rendered
111 *
112 * @throws IOException if an input/output error occurs while rendering
113 * @throws NullPointerException if <code>context</code>
114 * or <code>component</code> is null
115 */
116 public void encodeBegin(FacesContext context,
117 UIComponent component)
118 throws IOException {
119 if (null == context || null == component) {
120 throw new NullPointerException();
121 }
122 }
123
124
125 /**
126 * <p>Render the child components of this {@link UIComponent}, following
127 * the rules described for <code>encodeBegin()</code> to acquire the
128 * appropriate value to be rendered. This method will only be called
129 * if the <code>rendersChildren</code> property of this component
130 * is <code>true</code>.</p>
131 *
132 * @param context {@link FacesContext} for the response we are creating
133 * @param component {@link UIComponent} whose children are to be rendered
134 *
135 * @throws IOException if an input/output error occurs while rendering
136 * @throws NullPointerException if <code>context</code>
137 * or <code>component</code> is <code>null</code>
138 */
139 public void encodeChildren(FacesContext context, UIComponent component)
140 throws IOException {
141 if (context == null || component == null) {
142 throw new NullPointerException();
143 }
144 if (component.getChildCount() > 0) {
145 Iterator<UIComponent> kids = component.getChildren().iterator();
146 while (kids.hasNext()) {
147 UIComponent kid = kids.next();
148 kid.encodeAll(context);
149 }
150 }
151 }
152
153
154 /**
155 * <p>Render the ending of the current state of the specified
156 * {@link UIComponent}, following the rules described for
157 * <code>encodeBegin()</code> to acquire the appropriate value
158 * to be rendered.</p>
159 *
160 * @param context {@link FacesContext} for the response we are creating
161 * @param component {@link UIComponent} to be rendered
162 *
163 * @throws IOException if an input/output error occurs while rendering
164 * @throws NullPointerException if <code>context</code>
165 * or <code>component</code> is <code>null</code>
166 */
167 public void encodeEnd(FacesContext context,
168 UIComponent component)
169 throws IOException {
170 if (null == context || null == component) {
171 throw new NullPointerException();
172 }
173 }
174
175 /**
176 * <p>Convert the component generated client id to a form suitable
177 * for transmission to the client.</p>
178 *
179 * <p>The default implementation returns the argument
180 * <code>clientId</code> unchanged.</p>
181 *
182 * @param context {@link FacesContext} for the current request
183 * @param clientId the client identifier to be converted to client a
184 * specific format.
185 *
186 * @throws NullPointerException if <code>context</code>
187 * or <code>clientId</code> is <code>null</code>
188 */
189 public String convertClientId(FacesContext context, String clientId) {
190
191 if ((context == null) || (clientId == null)) {
192 throw new NullPointerException();
193 }
194 return (clientId);
195
196 }
197
198 /**
199 * <p>Return a flag indicating whether this {@link Renderer} is responsible
200 * for rendering the children the component it is asked to render.
201 * The default implementation returns <code>false</code>.</p>
202 */
203
204 public boolean getRendersChildren() {
205 return false;
206 }
207
208
209 /**
210 * <p>Attempt to convert previously stored state information into an
211 * object of the type required for this component (optionally using the
212 * registered {@link javax.faces.convert.Converter} for this component,
213 * if there is one). If conversion is successful, the new value
214 * should be returned from this method; if not, a
215 * {@link ConverterException} should be thrown.</p>
216 *
217 * @param context {@link FacesContext} for the request we are processing
218 * @param component {@link UIComponent} to be decoded.
219 * @param submittedValue a value stored on the component during
220 * <code>decode</code>.
221 *
222 * @throws ConverterException if the submitted value
223 * cannot be converted successfully.
224 * @throws NullPointerException if <code>context</code>
225 * or <code>component</code> is <code>null</code>
226 */
227 public Object getConvertedValue(FacesContext context,
228 UIComponent component,
229 Object submittedValue)
230 throws ConverterException {
231 if ((context == null) || (component == null)) {
232 throw new NullPointerException();
233 }
234 return submittedValue;
235 }
236 }