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: matzew $)
33   * @version $Revision: 557350 $ $Date: 2007-07-18 13:19:50 -0500 (Wed, 18 Jul 2007) $
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 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         return false;
118 
119       // ... or if the ID was generated, don't bother
120       if (id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
121         return false;
122 
123       return true;
124     }
125 
126     /***
127      * Coerces an object into a URI, accounting for JSF rules
128      * with initial slashes.
129      */
130     static public String toUri(Object o)
131     {
132       if (o == null)
133         return null;
134 
135       String uri = o.toString();
136       if (uri.startsWith("/"))
137       {
138         // Treat two slashes as server-relative
139         if (uri.startsWith("//"))
140         {
141           uri = uri.substring(1);
142         }
143         else
144         {
145           FacesContext fContext = FacesContext.getCurrentInstance();
146           uri = fContext.getExternalContext().getRequestContextPath() + uri;
147         }
148       }
149 
150       return uri;
151     }
152 }