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.shared.renderkit.html;
20  
21  import org.apache.myfaces.shared.renderkit.JSFAttr;
22  
23  import javax.faces.application.ViewHandler;
24  import javax.faces.component.UIComponent;
25  import javax.faces.component.UIViewRoot;
26  import javax.faces.context.FacesContext;
27  import javax.faces.render.Renderer;
28  import java.io.IOException;
29  import java.util.List;
30  
31  /**
32   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
33   * @version $Revision: 1230324 $ $Date: 2012-01-11 18:21:34 -0500 (Wed, 11 Jan 2012) $
34   */
35  public abstract class HtmlRenderer
36          extends Renderer
37  {
38  
39      /**
40       * Return the list of children of the specified component.
41       * <p>
42       * This default implementation simply returns component.getChildren().
43       * However this method should always be used in order to allow
44       * renderer subclasses to override it and provide filtered or
45       * reordered views of the component children to rendering
46       * methods defined in their ancestor classes.
47       * <p>
48       * Any method that overrides this to "hide" child components
49       * should also override the getChildCount method.
50       * 
51       * @return a list of UIComponent objects.
52       */
53      public List<UIComponent> getChildren(UIComponent component) 
54      {
55          return component.getChildren();
56      }
57  
58      /**
59       * Return the number of children of the specified component.
60       * <p>
61       * See {@link #getChildren(UIComponent)} for more information.
62       */
63      public int getChildCount(UIComponent component) 
64      {
65          return component.getChildCount();
66      }
67      
68      /**
69       * @param facesContext
70       * @return String A String representing the action URL
71       */
72      protected String getActionUrl(FacesContext facesContext)
73      {
74          ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
75          String viewId = facesContext.getViewRoot().getViewId();
76          return viewHandler.getActionURL(facesContext, viewId);
77      }
78  
79      /**
80       * Renders the client ID as an "id".
81       */
82      protected void renderId(
83        FacesContext context,
84        UIComponent  component) throws IOException
85      {
86        if (shouldRenderId(context, component))
87        {
88          String clientId = getClientId(context, component);
89          context.getResponseWriter().writeAttribute(HTML.ID_ATTR, clientId, JSFAttr.ID_ATTR);
90        }
91      }
92  
93      /**
94       * Returns the client ID that should be used for rendering (if
95       * {@link #shouldRenderId} returns true).
96       */
97      protected String getClientId(
98        FacesContext context,
99        UIComponent  component)
100     {
101       return component.getClientId(context);
102     }
103 
104     /**
105      * Returns true if the component should render an ID.  Components
106      * that deliver events should always return "true".
107      * @todo Is this a bottleneck?  If so, optimize!
108      */
109     protected boolean shouldRenderId(
110       FacesContext context,
111       UIComponent  component)
112     {
113       String id = component.getId();
114 
115       // Otherwise, if ID isn't set, don't bother
116       if (id == null)
117       {
118           return false;
119       }
120 
121       // ... or if the ID was generated, don't bother
122       if (id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
123       {
124           return false;
125       }
126 
127       return true;
128     }
129 
130     /**
131      * Coerces an object into a URI, accounting for JSF rules
132      * with initial slashes.
133      */
134     static public String toUri(Object o)
135     {
136       if (o == null)
137       {
138           return null;
139       }
140 
141       String uri = o.toString();
142       if (uri.startsWith("/"))
143       {
144         // Treat two slashes as server-relative
145         if (uri.startsWith("//"))
146         {
147           uri = uri.substring(1);
148         }
149         else
150         {
151           FacesContext fContext = FacesContext.getCurrentInstance();
152           uri = fContext.getExternalContext().getRequestContextPath() + uri;
153         }
154       }
155 
156       return uri;
157     }
158     
159     protected boolean isCommonPropertiesOptimizationEnabled(FacesContext facesContext)
160     {
161         return false;
162     }
163     
164     protected boolean isCommonEventsOptimizationEnabled(FacesContext facesContext)
165     {
166         return false;
167     }
168 }