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 }