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  
22  import java.io.IOException;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIViewRoot;
28  import javax.faces.component.behavior.ClientBehaviorHolder;
29  import javax.faces.component.html.HtmlPanelGroup;
30  import javax.faces.context.FacesContext;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
35  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
36  import org.apache.myfaces.component.AlignProperty;
37  import org.apache.myfaces.component.DataProperties;
38  import org.apache.myfaces.component.EventAware;
39  import org.apache.myfaces.component.PanelProperties;
40  import org.apache.myfaces.component.UniversalProperties;
41  
42  /**
43   * 
44   * Renders a vertical menu structure with support for nested menu 
45   * items. Unless otherwise specified, all attributes accept 
46   * static values or EL expressions.
47   * 
48   * Panel, that includes navigation items ({@link HtmlCommandNavigation}) and other
49   * components (separators).
50   * 
51   * @since 1.1.7
52   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
53   * @version $Revision: 691871 $ $Date: 2008-09-03 23:32:08 -0500 (miƩ, 03 sep 2008) $
54   */
55  @JSFComponent(
56          name = "t:panelNavigation",
57          clazz = "org.apache.myfaces.custom.navigation.HtmlPanelNavigation",
58          tagClass = "org.apache.myfaces.custom.navigation.HtmlPanelNavigationTag")
59  public abstract class AbstractHtmlPanelNavigation
60          extends HtmlPanelGroup implements AlignProperty,
61          UniversalProperties, EventAware, DataProperties, PanelProperties, ClientBehaviorHolder
62  {
63      private static final Log log = LogFactory.getLog(AbstractHtmlPanelNavigation.class);
64  
65      public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlPanelNavigation";
66      public static final String COMPONENT_FAMILY = "javax.faces.Panel";
67      private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Navigation";
68  
69      private static final int DEFAULT_BORDER = Integer.MIN_VALUE;
70  
71      private static final String PREVIOUS_VIEW_ROOT = AbstractHtmlPanelNavigation.class.getName() + ".PREVIOUS_VIEW_ROOT";
72      private boolean _itemOpenActiveStatesRestored = false;
73  
74      public void decode(FacesContext context)
75      {
76          super.decode(context);    //To change body of overridden methods use File | Settings | File Templates.
77          
78          //Save the current view root for later reference...
79          context.getExternalContext().getRequestMap().put(PREVIOUS_VIEW_ROOT, context.getViewRoot());
80          //...and remember that this instance needs NO special treatment on rendering:
81          _itemOpenActiveStatesRestored = true;
82      }
83  
84      public void encodeBegin(FacesContext context) throws IOException
85      {
86          if (!_itemOpenActiveStatesRestored && getChildCount() > 0)
87          {
88              UIViewRoot previousRoot = (UIViewRoot)context.getExternalContext().getRequestMap().get(PREVIOUS_VIEW_ROOT);
89              if (previousRoot != null)
90              {
91                  restoreOpenActiveStates(context, previousRoot, getChildren());
92              }
93              else
94              {
95                  //no previous root, means no decode was done
96                  //--> a new request
97              }
98          }
99          
100         super.encodeBegin(context);    //To change body of overridden methods use File | Settings | File Templates.
101     }
102     
103     public void restoreOpenActiveStates(FacesContext facesContext,
104                                         UIViewRoot previousRoot,
105                                         List children)
106     {
107         for (Iterator it = children.iterator(); it.hasNext(); )
108         {
109             UIComponent child = (UIComponent)it.next();
110             if (child instanceof HtmlCommandNavigation)
111             {
112                 HtmlCommandNavigation previousItem = (HtmlCommandNavigation)previousRoot.findComponent(child.getClientId(facesContext));
113                 if (previousItem != null)
114                 {
115 
116                     HtmlCommandNavigation childItem = (HtmlCommandNavigation)child;
117                     if(previousItem.getOpenDirectly()!=null)
118                     {
119                         childItem.setOpen(previousItem.isOpen());
120                     }
121                     else if(previousItem.getValueExpression("open")!=null)
122                     {
123                         childItem.setValueExpression("open",previousItem.getValueExpression("open"));
124                     }
125 
126                     if(previousItem.getActiveDirectly()!=null)
127                     {
128                         childItem.setActive(previousItem.isActive());
129                     }
130                     else if(previousItem.getValueExpression("active")!=null)
131                     {
132                         childItem.setValueExpression("active",previousItem.getValueExpression("active"));
133                     }
134                 }
135                 else
136                 {
137                     log.error("Navigation item " + child.getClientId(facesContext) + " not found in previous view.");
138                 }
139                 if (child.getChildCount() > 0)
140                 {
141                     restoreOpenActiveStates(facesContext, previousRoot, child.getChildren());
142                 }
143             }
144         }
145     }
146             
147     /**
148      * The CSS class of closed navigation items.
149      * 
150      */
151     @JSFProperty
152     public abstract String getItemClass();
153 
154     /**
155      * The CSS class of open navigation items.
156      * 
157      */
158     @JSFProperty
159     public abstract String getOpenItemClass();
160 
161     /**
162      * The CSS class of the active navigation item.
163      * 
164      */
165     @JSFProperty
166     public abstract String getActiveItemClass();
167 
168     /**
169      * The CSS class for the td element of a separator.
170      * 
171      */
172     @JSFProperty
173     public abstract String getSeparatorClass();
174 
175     /**
176      * The CSS Style of closed navigation items.
177      * 
178      */
179     @JSFProperty
180     public abstract String getItemStyle();
181 
182     /**
183      * The CSS Style of open navigation items.
184      * 
185      */
186     @JSFProperty
187     public abstract String getOpenItemStyle();
188 
189     /**
190      * The CSS Style of the active navigation item.
191      * 
192      */
193     @JSFProperty
194     public abstract String getActiveItemStyle();
195 
196     /**
197      * The CSS Style for the td element of a separator.
198      * 
199      */
200     @JSFProperty
201     public abstract String getSeparatorStyle();
202 
203 }