View Javadoc

1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (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
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.portal.controllers;
18  
19  // Turbine stuff
20  import org.apache.turbine.util.DynamicURI;
21  import org.apache.turbine.util.RunData;
22  
23  // Jetspeed stuff
24  import org.apache.jetspeed.portal.Portlet;
25  import org.apache.jetspeed.portal.PanedPortletController;
26  import org.apache.jetspeed.util.template.JetspeedLink;
27  import org.apache.jetspeed.util.template.JetspeedLinkFactory;
28  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
29  import org.apache.jetspeed.services.logging.JetspeedLogger;
30  import org.apache.jetspeed.services.statemanager.SessionState;
31  import org.apache.jetspeed.services.rundata.JetspeedRunData;
32  import org.apache.jetspeed.services.resources.JetspeedResources;
33  
34  /***
35   * A Velocity based portlet controller implementation that can be used
36   * to manage paned content (ie, where a only a subset of all portlets
37   * is visible at any given time)
38   * 
39   * @author <a href="mailto:raphael@apache.org">Raphaël Luta</a>
40   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
41   *
42   * @version $Id: VelocityPanedPortletController.java,v 1.13 2004/02/23 03:25:06 jford Exp $
43   */
44  
45  public class VelocityPanedPortletController extends VelocityPortletController
46      implements PanedPortletController
47  {
48      
49      /***
50       * Static initialization of the logger for this class
51       */    
52      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(VelocityPanedPortletController.class.getName());
53      
54      public static final String DEFAULT_PARAMETER = "pane";
55  
56      /*
57       * @return the pane parameter name
58       *
59       */
60      public String getPaneParameter()    
61      {
62          return JetspeedResources.PATH_PANEID_KEY;
63      }
64  
65  
66      /***
67       * Test whether the selected portlet is considered selected for the current
68       * request.
69       *
70       * @param p the Portlet to check
71       * @param rundata the RunData for the request
72       * @return true if the portlet is selected, false otherwise
73       */
74      public boolean isSelected( Portlet p, RunData rundata )
75      {
76          String peid = rundata.getParameters().getString( getPaneParameter() );
77          String pname = rundata.getParameters().getString(JetspeedResources.PATH_PANENAME_KEY);
78          String last = retrievePaneIDFromSession(rundata);
79          
80          //match by portlet name if appropriate.
81          if (pname != null && pname.equals(p.getName())) 
82          {
83              return true;	
84          }
85  
86          if (peid == null)
87          {
88              if (last == null)
89              {
90                  return (getPortlets().getPortletAt( 0 ) == p);
91              }
92              else
93              {
94                  if (pname == null) 
95                  {
96                      return (p.getID().equals(last));
97                  }
98                  else
99                  {
100                     //If the current portlet set has a portlet with the same name as the one we're trying to select
101                     //we don't want to select anything else b/c we'll select the one we want AND the last-used portlet.
102                     //If the portlet set doesn't have a portlet by this name, we WANT to select the last
103                     //used, otherwise nothing will be selected in this set.
104 	                 return (getPortlets().getPortletByName(pname) == null && p.getID().equals(last));
105                 }
106             }
107         }
108         else 
109         {          
110             String subPane = null;
111             int index = peid.indexOf(JetspeedResources.PATH_SUBPANE_SEPARATOR);
112             if (index > -1)
113             {
114                 subPane = peid.substring(index + 1);
115                 peid = peid.substring(0, index);
116             }
117             
118             if ( p.getID().equals(peid) ) // && subPane == null )
119             {
120                 return true;
121             }
122 
123             // is this the sub pane?
124             if (subPane!=null && p.getID().equals(subPane))
125             {
126               // change the currently selected pane in the user session
127               // If this is not done, the tab selection works, but the
128               // content is picked up from the pane in the session!!
129               if(!p.getAttribute("_menustate", "open", rundata).equals("closed")) {
130                   SessionState state = ((JetspeedRunData)rundata).getPortletSessionState(getPortlets().getID());
131                   state.setAttribute(JetspeedResources.PATH_PANEID_KEY, subPane);   
132               }
133 
134               return true;
135             }
136 
137 			// is the peid for this tab set?
138             if (getPortlets().getPortletByID(peid) != null)
139             {
140                 // its for another tab in this set
141                 return false;
142             }
143             if (subPane == null)
144             {
145                 if (last == null)
146                 {
147                     return (getPortlets().getPortletAt( 0 ) == p); 
148                 }
149                 else
150                 {
151                     return (p.getID().equals(last));
152                 }
153             }
154             else
155             {
156                 if (p.getID().equals( subPane )) 
157                 {
158                     // change the currently selected pane in the user session
159                     // If this is not done, the tab selection works, but the
160                     // content is picked up from the pane in the session!!
161                     if(!p.getAttribute("_menustate", "open", rundata).equals("closed"))
162                     {
163                         SessionState state = 
164                             ((JetspeedRunData)rundata).getPortletSessionState(getPortlets().getID());
165                         state.setAttribute(JetspeedResources.PATH_PANEID_KEY, subPane);
166                     }
167                     return true;
168                 }
169             }
170         }
171         return false;
172     }
173 
174     /***
175      *  Builds the link to access to a given pane.
176      *
177      *  @param rundata The request data.
178      *  @param portlet The portlet to build the link for by id.
179      *  @return DynamicURI A new Dynamic URI with the query parameter
180      */
181     public DynamicURI getPortletURI( Portlet portlet, RunData rundata )
182     {
183         JetspeedLink jsLink = null;
184         try
185         {
186             jsLink = JetspeedLinkFactory.getInstance(rundata);
187         }
188         catch( Exception e)
189         {
190             logger.error("Exception",  e);
191         }
192         DynamicURI uri = jsLink.getPaneById(portlet.getID());
193         JetspeedLinkFactory.putInstance(jsLink);
194         
195         return uri;
196     }
197 
198     /***
199      * Returns the pane id of the parameter used for pane selection
200      *
201      *  @param rundata The request data.
202      *  @param byParameter Set to true to look by query parameter first.
203      *  @return String The pane id for the selected pane.
204      *
205      */
206     public String retrievePaneID(RunData rundata, boolean byParameter)
207     {
208         if (false == byParameter)
209             return retrievePaneIDFromSession(rundata);
210 
211         String pane = rundata.getParameters().getString( getPaneParameter() );
212         
213         if (pane == null)
214         {
215             // the parameter is undefined, search for sticky value in session
216             String id = getPortlets().getID(); 
217             pane = retrievePaneIDFromSession(rundata);
218         }
219         
220         if(pane != null)
221         {
222             int index = pane.indexOf(JetspeedResources.PATH_SUBPANE_SEPARATOR);
223             if (index > -1)
224             {
225                 //return pane.substring(index + 1);
226                 return pane.substring(0, index);
227             }
228         }
229         
230         return pane;
231     }
232 
233     /***
234      * Returns the pane id from the session for pane selection of this portlet set / portal page
235      *
236      *  @param rundata The request data.
237      *  @return String The pane id for the selected pane.
238      *
239      */
240     protected String retrievePaneIDFromSession(RunData rundata)
241     {
242         // get the state for this portlet (portlet set) in this page in this session
243         SessionState state = ((JetspeedRunData)rundata).getPortletSessionState(getPortlets().getID());
244 
245         // get the PANE_PARAMETER attribute
246         String pane = (String) state.getAttribute(JetspeedResources.PATH_PANEID_KEY);
247         
248         // if not yet defined, select the first portlet set
249         if (pane == null)
250         {
251             // use default
252             if(getPortlets().size() > 0)
253             {
254 	            pane = getPortlets().getPortletAt(0).getID();
255             }
256         }
257        
258         return pane;
259     }
260 
261     /***
262      * Saves the pane id to the session to remember selection state of menu or tab for this portlet set / portal page.
263      *
264      *  @param rundata The request data.
265      *  @param id  The tab id to save for this controller
266      */
267     public void savePaneID( RunData data, String id )
268     {
269         // get the state for this portlet (portlet set) in this page in this session
270         SessionState state = ((JetspeedRunData)data).getPortletSessionState(getPortlets().getID());
271         
272         // set the PANE_PARAMETER attribute
273         state.setAttribute(JetspeedResources.PATH_PANEID_KEY, id);
274     }
275 
276     /***
277      * Sets the name of the parameter that will define which pane should
278      * be displayed
279      *
280      * @deprecated
281      *
282      * @param name the selection parameter name
283      */
284     public void setParameterName( String name )
285     {
286         getConfig().setInitParameter( "parameter", name );          
287     }
288     
289     /***
290      * Returns the name of the parameter used for pane selection
291      *
292      * @deprecated
293      */
294     public String getParameterName()
295     {
296         return getConfig().getInitParameter( "parameter", DEFAULT_PARAMETER )
297                + getPortlets().getName();
298     }
299 
300     /***
301      * Returns the name of the parameter used for pane selection
302      *
303      * @deprecated
304      *
305      */
306     public String retrievePaneName(RunData rundata)
307     {
308         String pane = rundata.getParameters().getString( getParameterName() );
309         
310         if (pane == null)
311         {
312             // the parameter is undefined, search for sticky value in session
313             pane = (String)rundata.getUser().getTemp( "pane-"+getParameterName() );
314             
315             if (pane == null)
316             {
317                 // use default
318                 pane = getConfig().getInitParameter( "defaultpane", "0" );
319             }
320         }
321         
322         return pane;
323     }
324 
325     /***
326      * Sets the name of the parameter that will define which pane should
327      * be displayed
328      *
329      * @deprecated
330      *
331      * @param name the selection parameter name
332      */
333     public void savePaneName( RunData data, String name )
334     {
335         data.getUser().setTemp( "pane-"+getParameterName(), name );
336     }
337     
338 }
339