1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.custom.buffer;
20
21 import javax.faces.component.UIComponentBase;
22 import javax.faces.context.FacesContext;
23 import javax.faces.el.ValueBinding;
24
25 /**
26 * A component that renders its child components into an in-memory buffer rather than
27 * render them directly to the response stream.
28 * <p>
29 * Property "into" is an EL expression that specifies where to store a String holding
30 * the results of rendering all the children of this component; this is assigned to
31 * after rendering of this component (and its children) is complete.
32 * </p>
33 * <p>
34 * Typically, an h:output tag is then used later in the same page to output the buffer
35 * contents.
36 * </p>
37 * <p>
38 * This can be useful with JSF1.1/JSP2.0 to work around the well-known problem where
39 * on first render of a page, a component "A" cannot reference a component "B" which is
40 * defined later in the page because it has not yet been created. A solution is to define
41 * "B" before "A", but wrapped in a Buffer component. Component A can then be rendered
42 * and successfully reference "B" because it now exists. And later in the page, the buffer
43 * contents can then be output, preserving the original layout.
44 * </p>
45 * <p>
46 * This can also be useful when rendering the same data block multiple times within a page.
47 * For example, a datatable can be rendered with a datascroller both before and after it;
48 * first render the table into a buffer B1, then render the datascroller into a buffer B2,
49 * then output buffers B2,B1,B2.
50 * </p>
51 *
52 * @JSFComponent
53 * name = "t:buffer"
54 * class = "org.apache.myfaces.custom.buffer.Buffer"
55 * tagClass = "org.apache.myfaces.custom.buffer.BufferTag"
56 *
57 * @JSFJspProperty
58 * name = "rendered"
59 * returnType = "boolean"
60 * tagExcluded = "true"
61 *
62 * @JSFJspProperty
63 * name = "binding"
64 * returnType = "java.lang.String"
65 * tagExcluded = "true"
66 *
67 * @JSFJspProperty
68 * name = "id"
69 * returnType = "java.lang.String"
70 * tagExcluded = "true"
71 * @since 1.1.7
72 * @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
73 * @version $Revision: 691856 $ $Date: 2008-09-03 21:40:30 -0500 (Wed, 03 Sep 2008) $
74 */
75 public abstract class AbstractBuffer extends UIComponentBase{
76
77 public static final String COMPONENT_TYPE = "org.apache.myfaces.Buffer";
78 public static final String COMPONENT_FAMILY = "javax.faces.Data";
79 private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Buffer";
80
81 protected abstract String getLocalInto();
82
83 public abstract void setInto(String into);
84
85 void fill(String content, FacesContext facesContext){
86 ValueBinding intoVB;
87
88 if (getLocalInto() == null) {
89 intoVB = getValueBinding("into");
90 setInto(intoVB.getExpressionString());
91 } else {
92 intoVB = facesContext.getApplication().createValueBinding( getLocalInto() );
93 }
94
95 intoVB.setValue(facesContext, content);
96 }
97
98 /**
99 * An EL expression that specifies where to store a String holding
100 * the results of rendering all the children of this component;
101 * this is assigned to after rendering of this component (and its
102 * children) is complete.
103 *
104 * @JSFProperty
105 * required = "true"
106 * localMethod = "true"
107 */
108 protected abstract String getInto();
109
110 }