View Javadoc

1   /**
2    * This file is part of the equanda project.
3    *
4    * The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7    *
8    * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
9    * ANY KIND, either express or implied. See the License for the specific language governing rights and
10   * limitations under the License.
11   *
12   * Alternatively, the contents of this file may be used under the terms of
13   * either the GNU General Public License Version 2 or later (the "GPL"), or
14   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15   * in which case the provisions of the GPL or the LGPL are applicable instead
16   * of those above. If you wish to allow use of your version of this file only
17   * under the terms of either the GPL or the LGPL, and not to allow others to
18   * use your version of this file under the terms of the MPL, indicate your
19   * decision by deleting the provisions above and replace them with the notice
20   * and other provisions required by the GPL or the LGPL. If you do not delete
21   * the provisions above, a recipient may use your version of this file under
22   * the terms of any one of the MPL, the GPL or the LGPL.
23   */
24  
25  package org.equanda.tapestry5.base;
26  
27  import org.apache.tapestry5.Block;
28  import org.apache.tapestry5.ComponentResources;
29  import org.apache.tapestry5.RenderSupport;
30  import org.apache.tapestry5.annotations.Environmental;
31  import org.apache.tapestry5.annotations.Parameter;
32  import org.apache.tapestry5.annotations.SetupRender;
33  import org.apache.tapestry5.annotations.SupportsInformalParameters;
34  import org.apache.tapestry5.ioc.annotations.Inject;
35  import org.apache.tapestry5.services.RequestGlobals;
36  import org.slf4j.Logger;
37  
38  import javax.servlet.http.Cookie;
39  import java.io.Serializable;
40  import java.util.ArrayList;
41  import java.util.List;
42  
43  /**
44   * Abstract superclass for tapestry components that consist of list of maximum 50 panels, where only
45   * one of the panels is currently active. A typical example is a tabs component.
46   *
47   * @author <a href="mailto:joachim@progs.be">Joachim Van der Auwera</a>
48   * @author <a href="mailto:geert@synergetics.be">Geert Mergan</a>
49   */
50  @SupportsInformalParameters
51  abstract public class TitleContent
52  {
53      private static final int MAX_PANELS = 50; // max number of supported panels
54  
55      @Environmental
56      private RenderSupport renderSupport;
57  
58      @Inject
59      private ComponentResources resources;
60  
61      @Parameter
62      private Block titleIcon;
63  
64      @Parameter
65      private Integer exclude;
66  
67      @Inject
68      private RequestGlobals requestGlobals;
69  
70      @Inject
71      private Logger log;
72  
73      private TwoBlocks panel;
74      private int index;
75      private int panelCount;
76      private String assignedId;
77  
78      private int activeIndex;
79  
80      /**
81       * TitleContent provides a cookie-based mechanism to keep track of the component which is currently active.
82       * Is the superclass going to use this cookie-based mechanism or not?
83       *
84       * @return true if it will use the cookies, false otherwise.
85       */
86      abstract public boolean isUsingCookies();
87  
88      protected int getActiveIndex()
89      {
90          return activeIndex;
91      }
92  
93      protected void setActiveIndex( int activeIndex )
94      {
95          this.activeIndex = activeIndex;
96      }
97  
98      public String getId()
99      {
100         return assignedId;
101     }
102 
103     public int getIndex()
104     {
105         return index;
106     }
107 
108     public void setIndex( int index )
109     {
110         this.index = index;
111     }
112 
113     public TwoBlocks getPanel()
114     {
115         return panel;
116     }
117 
118     public void setPanel( TwoBlocks panel )
119     {
120         this.panel = panel;
121     }
122 
123     public Block getTitleIcon()
124     {
125         return titleIcon;
126     }
127 
128     public void setTitleIcon( Block titleIcon )
129     {
130         this.titleIcon = titleIcon;
131     }
132 
133     public List<TwoBlocks> getPanels()
134     {
135         panelCount = 0;
136         List<TwoBlocks> list = new ArrayList<TwoBlocks>();
137         for ( int i = 0; i < MAX_PANELS ; i++ )
138         {
139             String index = Integer.toString( i + 1 );
140             if ( resources.isBound( "title" + index ) && resources.isBound( "content" + index ) )
141             {
142                 list.add( new TwoBlocks( i + 1 ) );
143             }
144         }
145         if ( exclude != null )
146         {
147             if ( exclude >= 0 )
148             {
149                 if ( list.size() > 0 && exclude < list.size() )
150                 {
151                     list.remove( exclude.intValue() );
152                 }
153             }
154             else
155             {
156                 int lastIndex = list.size() + ( exclude );
157                 if ( lastIndex >= 0 && lastIndex < list.size() )
158                 {
159                     list = new ArrayList<TwoBlocks>( list.subList( 0, lastIndex ) );
160                 }
161             }
162         }
163         panelCount = list.size();
164         return list;
165     }
166 
167     @SetupRender
168     protected final void setupRender()
169     {
170         assignedId = renderSupport.allocateClientId( resources );
171         if ( isUsingCookies() )
172         {
173             Cookie[] cookies = requestGlobals.getHTTPServletRequest().getCookies();
174             if ( cookies != null )
175             {
176                 for ( Cookie cookie : cookies )
177                 {
178                     if ( cookie.getName().equalsIgnoreCase( "active_index_" + assignedId ) )
179                     {
180                         String val = cookie.getValue();
181                         if ( val != null && val.trim().length() > 0 )
182                         {
183                             try
184                             {
185                                 setActiveIndex( Integer.parseInt( val ) );
186                             }
187                             catch ( Exception e )
188                             {
189                                 log.warn( "Failed to parse cookie with active index: " + val );
190                             }
191                         }
192                         break;
193                     }
194                 }
195             }
196         }
197         if ( getActiveIndex() == 0 )
198         {
199             setActiveIndex( 1 );
200         }
201     }
202 
203     public int getPanelCount()
204     {
205         return panelCount;
206     }
207 
208     public class TwoBlocks
209         implements Serializable
210     {
211         private Block title, content;
212         private boolean active;
213 
214         public TwoBlocks( int index )
215         {
216             active = ( getActiveIndex() == index );
217             title = resources.getBlockParameter( "title" + index );
218             content = resources.getBlockParameter( "content" + index );
219         }
220 
221         public Block getTitle()
222         {
223             return title;
224         }
225 
226         public void setTitle( Block title )
227         {
228             this.title = title;
229         }
230 
231         public Block getContent()
232         {
233             return content;
234         }
235 
236         public void setContent( Block content )
237         {
238             this.content = content;
239         }
240 
241         public boolean isActive()
242         {
243             return active;
244         }
245 
246         public void setActive( boolean active )
247         {
248             this.active = active;
249         }
250     }
251 }