View Javadoc

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.el.ValueExpression;
22  import javax.faces.component.UIComponentBase;
23  import javax.faces.context.FacesContext;
24  
25  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
26  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperties;
27  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
28  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
29  
30  /**
31   * A component that renders its child components into an in-memory buffer rather than
32   * render them directly to the response stream.
33   * <p>
34   * Property "into" is an EL expression that specifies where to store a String holding
35   * the results of rendering all the children of this component; this is assigned to
36   * after rendering of this component (and its children) is complete.
37   * </p>
38   * <p>
39   * Typically, an h:output tag is then used later in the same page to output the buffer
40   * contents.
41   * </p>
42   * <p>
43   * This can be useful with JSF1.1/JSP2.0 to work around the well-known problem where
44   * on first render of a page, a component "A" cannot reference a component "B" which is
45   * defined later in the page because it has not yet been created. A solution is to define
46   * "B" before "A", but wrapped in a Buffer component. Component A can then be rendered
47   * and successfully reference "B" because it now exists. And later in the page, the buffer
48   * contents can then be output, preserving the original layout.
49   * </p>
50   * <p>
51   * This can also be useful when rendering the same data block multiple times within a page.
52   * For example, a datatable can be rendered with a datascroller both before and after it;
53   * first render the table into a buffer B1, then render the datascroller into a buffer B2,
54   * then output buffers B2,B1,B2.
55   * </p>
56   * 
57   * @since 1.1.7
58   * @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
59   * @version $Revision: 691871 $ $Date: 2008-09-03 23:32:08 -0500 (Wed, 03 Sep 2008) $
60   */
61  @JSFComponent(
62          name = "t:buffer",
63          clazz = "org.apache.myfaces.custom.buffer.Buffer",
64          tagClass = "org.apache.myfaces.custom.buffer.BufferTag")
65  @JSFJspProperties(properties={
66          @JSFJspProperty(
67                  name = "rendered",
68                  returnType = "boolean", 
69                  tagExcluded = true),
70          @JSFJspProperty(
71                  name = "binding",
72                  returnType = "java.lang.String",
73                  tagExcluded = true),
74          @JSFJspProperty(
75                  name = "id",
76                  returnType = "java.lang.String",
77                  tagExcluded = true)
78                  })
79  public abstract class AbstractBuffer extends UIComponentBase{
80  
81      public static final String COMPONENT_TYPE = "org.apache.myfaces.Buffer";
82      public static final String COMPONENT_FAMILY = "javax.faces.Data";
83      private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Buffer";
84  
85      protected abstract String getLocalInto();
86      
87      public abstract void setInto(String into);
88  
89      void fill(String content, FacesContext facesContext){
90          ValueExpression intoVB;
91  
92          if (getLocalInto() == null) {
93              intoVB = getValueExpression("into");
94              setInto(intoVB.getExpressionString());
95          } else {
96              intoVB = facesContext.getApplication().
97              getExpressionFactory().createValueExpression(
98                      facesContext.getELContext(), getLocalInto(), Object.class );
99          }
100 
101         intoVB.setValue(facesContext.getELContext(), content);
102     }
103     
104     /**
105      * An EL expression that specifies where to store a String holding 
106      * the results of rendering all the children of this component; 
107      * this is assigned to after rendering of this component (and its 
108      * children) is complete.
109      * 
110      */
111     @JSFProperty(
112             required = true,
113             localMethod = true)
114     protected abstract String getInto(); 
115 
116 }