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 }