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.navigation;
20  
21  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
22  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
23  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
24  import org.apache.myfaces.renderkit.html.ext.HtmlLinkRenderer;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import javax.faces.component.UIComponent;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import java.io.IOException;
33  import java.util.Iterator;
34  import java.util.List;
35  
36  /**
37   * @JSFRenderer
38   *   renderKitId = "HTML_BASIC" 
39   *   family = "javax.faces.Panel"
40   *   type = "org.apache.myfaces.Navigation"
41   *   
42   * @JSFRenderer
43   *   renderKitId = "HTML_BASIC" 
44   *   family = "javax.faces.Command"
45   *   type = "org.apache.myfaces.Navigation"
46   * 
47   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
48   * @version $Revision: 980618 $ $Date: 2010-07-29 19:39:35 -0500 (Thu, 29 Jul 2010) $
49   */
50  public class HtmlNavigationRenderer
51          extends HtmlLinkRenderer
52  {
53      private static final Log log = LogFactory.getLog(HtmlNavigationRenderer.class);
54  
55      private static final Integer ZERO_INTEGER = new Integer(0);
56  
57      public boolean getRendersChildren()
58      {
59          return true;
60      }
61  
62      public void decode(FacesContext facesContext, UIComponent component)
63      {
64          if (component instanceof HtmlCommandNavigation)
65          {
66              //HtmlCommandNavigation
67              super.decode(facesContext, component);
68          }
69      }
70  
71      public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException
72      {
73          if (component instanceof HtmlCommandNavigation)
74          {
75              //HtmlCommandNavigation
76              super.encodeBegin(facesContext, component);
77          }
78      }
79  
80      public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException
81      {
82          if (component instanceof HtmlCommandNavigation)
83          {
84              //HtmlCommandNavigation
85              super.encodeChildren(facesContext, component);
86          }
87      }
88  
89      public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException
90      {
91          if (component instanceof HtmlCommandNavigation)
92          {
93              //HtmlCommandNavigation
94              super.encodeEnd(facesContext, component);
95              return;
96          }
97  
98          RendererUtils.checkParamValidity(facesContext, component, HtmlPanelNavigation.class);
99          ResponseWriter writer = facesContext.getResponseWriter();
100         HtmlPanelNavigation panelNav = (HtmlPanelNavigation)component;
101 
102         if (panelNav.getChildCount() > 0)
103         {
104             HtmlRendererUtils.writePrettyLineSeparator(facesContext);
105             writer.startElement(HTML.TABLE_ELEM, component);
106             HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
107             HtmlRendererUtils.renderHTMLAttributes(writer, panelNav, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
108             
109             boolean isBorderAlreadyDefined = component.getAttributes().containsKey(HTML.BORDER_ATTR);
110             
111             if (panelNav.getStyle() == null && panelNav.getStyleClass() == null && !isBorderAlreadyDefined)
112             {
113                 writer.writeAttribute(HTML.BORDER_ATTR, ZERO_INTEGER, null);
114             }
115 
116             renderChildren(facesContext, writer, panelNav, panelNav.getChildren(), 0);
117 
118             HtmlRendererUtils.writePrettyLineSeparator(facesContext);
119             writer.endElement(HTML.TABLE_ELEM);
120         }
121         else
122         {
123             if (log.isWarnEnabled()) log.warn("Navigation panel without children.");
124         }
125     }
126 
127 
128     protected void renderChildren(FacesContext facesContext,
129                                   ResponseWriter writer,
130                                   HtmlPanelNavigation panelNav,
131                                   List children,
132                                   int level)
133             throws IOException
134     {
135         for (Iterator it = children.iterator(); it.hasNext(); )
136         {
137             UIComponent child = (UIComponent)it.next();
138             if (!child.isRendered()) continue;
139             if (child instanceof HtmlCommandNavigation)
140             {
141                 //navigation item
142                 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
143 
144                 String style = getNavigationItemStyle(panelNav, (HtmlCommandNavigation)child);
145                 String styleClass = getNavigationItemClass(panelNav, (HtmlCommandNavigation)child);
146 
147                 writer.startElement(HTML.TR_ELEM, panelNav);
148                 writer.startElement(HTML.TD_ELEM, panelNav);
149                 writeStyleAttributes(writer, style, styleClass);
150 
151                 if (style != null || styleClass != null)
152                 {
153                     writer.startElement(HTML.SPAN_ELEM, panelNav);
154                     writeStyleAttributes(writer, style, styleClass);
155                 }
156                 indent(writer, level);
157                 child.encodeBegin(facesContext);
158                 child.encodeEnd(facesContext);
159                 if (style != null || styleClass != null)
160                 {
161                     writer.endElement(HTML.SPAN_ELEM);
162                 }
163 
164                 writer.endElement(HTML.TD_ELEM);
165                 writer.endElement(HTML.TR_ELEM);
166 
167                 if (child.getChildCount() > 0)
168                 {
169                     renderChildren(facesContext, writer, panelNav, child.getChildren(), level + 1);
170                 }
171             }
172             else
173             {
174                 //separator
175                 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
176 
177                 String style = panelNav.getSeparatorStyle();
178                 String styleClass = panelNav.getSeparatorClass();
179 
180                 writer.startElement(HTML.TR_ELEM, panelNav);
181                 writer.startElement(HTML.TD_ELEM, panelNav);
182                 writeStyleAttributes(writer, style, styleClass);
183 
184                 if (style != null || styleClass != null)
185                 {
186                     writer.startElement(HTML.SPAN_ELEM, panelNav);
187                     writeStyleAttributes(writer, style, styleClass);
188                 }
189                 indent(writer, level);
190                 RendererUtils.renderChild(facesContext, child);
191                 if (style != null || styleClass != null)
192                 {
193                     writer.endElement(HTML.SPAN_ELEM);
194                 }
195 
196                 writer.endElement(HTML.TD_ELEM);
197                 writer.endElement(HTML.TR_ELEM);
198             }
199 
200         }
201     }
202 
203 
204     protected void indent(ResponseWriter writer, int level)
205         throws IOException
206     {
207         StringBuffer buf = new StringBuffer();
208         for (int i = 0; i < level; i++)
209         {
210             buf.append("&#160;&#160;&#160;&#160;");
211         }
212         writer.write(buf.toString());
213     }
214 
215 
216 
217     protected String getNavigationItemStyle(HtmlPanelNavigation navPanel,
218                                             HtmlCommandNavigation navItem)
219     {
220         if (navItem.isActive())
221         {
222             return navPanel.getActiveItemStyle();
223         }
224         else if (navItem.isOpen())
225         {
226             return navPanel.getOpenItemStyle();
227         }
228         else
229         {
230             return navPanel.getItemStyle();
231         }
232     }
233 
234     protected String getNavigationItemClass(HtmlPanelNavigation navPanel,
235                                             HtmlCommandNavigation navItem)
236     {
237         // MYFACES-117, if a styleClass is supplied for a HtmlCommandNavigation,
238         // panelNavigation active/open/normal styles for items will be overriden
239         if (navItem.getStyleClass() != null) 
240         {
241             return navItem.getStyleClass();
242         }
243         
244         if (navItem.isActive())
245         {
246             return navPanel.getActiveItemClass();
247         }
248         else if (navItem.isOpen())
249         {
250             return navPanel.getOpenItemClass();
251         }
252         else
253         {
254             return navPanel.getItemClass();
255         }
256     }
257 
258 
259 
260     protected void writeStyleAttributes(ResponseWriter writer,
261                                         String style,
262                                         String styleClass)
263             throws IOException
264     {
265         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR, style);
266         HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR, styleClass);
267     }
268 
269 
270     protected String getStyle(FacesContext facesContext, UIComponent link)
271     {
272         if (!(link instanceof HtmlCommandNavigation))
273         {
274             throw new IllegalArgumentException();
275         }
276 
277         UIComponent navPanel = link.getParent();
278         while (navPanel != null && !(navPanel instanceof HtmlPanelNavigation))
279         {
280             navPanel = navPanel.getParent();
281         }
282         if (navPanel == null)
283         {
284             throw new IllegalStateException("HtmlCommandNavigation not nested in HtmlPanelNavigation!?");
285         }
286 
287         HtmlCommandNavigation navItem = (HtmlCommandNavigation)link;
288         if (navItem.isActive())
289         {
290             return ((HtmlPanelNavigation)navPanel).getActiveItemStyle();
291         }
292         else if (navItem.isOpen())
293         {
294             return ((HtmlPanelNavigation)navPanel).getOpenItemStyle();
295         }
296         else
297         {
298             return ((HtmlPanelNavigation)navPanel).getItemStyle();
299         }
300     }
301 
302 
303     protected String getStyleClass(FacesContext facesContext, UIComponent link)
304     {
305         if (!(link instanceof HtmlCommandNavigation))
306         {
307             throw new IllegalArgumentException();
308         }
309 
310         UIComponent navPanel = link.getParent();
311         while (navPanel != null && !(navPanel instanceof HtmlPanelNavigation))
312         {
313             navPanel = navPanel.getParent();
314         }
315         if (navPanel == null)
316         {
317             throw new IllegalStateException("HtmlCommandNavigation not nested in HtmlPanelNavigation!?");
318         }
319 
320         HtmlCommandNavigation navItem = (HtmlCommandNavigation)link;
321         if (navItem.isActive())
322         {
323             return ((HtmlPanelNavigation)navPanel).getActiveItemClass();
324         }
325         else if (navItem.isOpen())
326         {
327             return ((HtmlPanelNavigation)navPanel).getOpenItemClass();
328         }
329         else
330         {
331             return ((HtmlPanelNavigation)navPanel).getItemClass();
332         }
333     }
334 
335 
336 
337 }