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