View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.container.url.impl;
18  
19  import java.io.UnsupportedEncodingException;
20  import java.util.Map;
21  
22  import javax.portlet.PortletMode;
23  import javax.portlet.WindowState;
24  import javax.servlet.http.HttpServletRequest;
25  
26  import org.apache.jetspeed.PortalContext;
27  import org.apache.jetspeed.container.ContainerConstants;
28  import org.apache.jetspeed.container.state.NavigationalState;
29  import org.apache.jetspeed.container.url.BasePortalURL;
30  import org.apache.jetspeed.container.url.PortalURL;
31  import org.apache.jetspeed.util.ArgUtil;
32  import org.apache.pluto.om.window.PortletWindow;
33  
34  /***
35   * AbstractPortalURL delivers the base implemention for parsing Jetspeed Portal URLs and creating new Portlet URLs.
36   * Not implemented is the encoding and decoding of the NavigationState parameter in the URL, allowing concrete
37   * implementations to supply different algorithms for it like encoding it as pathInfo or as query string parameter.
38   *
39   * @author <a href="mailto:ate@apache.org">Ate Douma</a>
40   * @version $Id: AbstractPortalURL.java 605989 2007-12-20 18:26:54Z ate $
41   */
42  public abstract class AbstractPortalURL implements PortalURL
43  {
44      public static final String DEFAULT_NAV_STATE_PARAMETER = "_ns";
45      
46      protected static String navStateParameter;
47      
48      protected NavigationalState navState;
49      protected BasePortalURL base = null;
50      
51      protected static Boolean relativeOnly;
52      protected String contextPath;
53      protected String basePath;
54      protected String path;
55      protected String encodedNavState;
56      protected String secureBaseURL;
57      protected String nonSecureBaseURL;
58      protected String characterEncoding = "UTF-8";
59      
60  
61      public AbstractPortalURL(NavigationalState navState, PortalContext portalContext, BasePortalURL base)
62      {
63          this(navState, portalContext);        
64          this.base = base;
65      }
66      
67      public AbstractPortalURL(NavigationalState navState, PortalContext portalContext)
68      {
69          if ( navStateParameter == null )
70          {
71              navStateParameter = 
72                  portalContext.getConfigurationProperty("portalurl.navigationalstate.parameter.name", 
73                          DEFAULT_NAV_STATE_PARAMETER);
74          }
75          this.navState = navState;
76          if ( relativeOnly == null )
77          {
78              relativeOnly = new Boolean(portalContext.getConfiguration().getBoolean("portalurl.relative.only", false));
79          }
80      }
81      
82      
83      public AbstractPortalURL(String characterEncoding, NavigationalState navState, PortalContext portalContext)
84      {
85          this(navState, portalContext);
86          this.characterEncoding = characterEncoding;
87      }
88      
89      public AbstractPortalURL(HttpServletRequest request, String characterEncoding, NavigationalState navState, PortalContext portalContext)
90      {
91          this(characterEncoding, navState, portalContext);
92          setRequest(request);
93      }
94      
95      public boolean isRelativeOnly()
96      {
97          return relativeOnly.booleanValue();
98      }
99      
100     public static String getNavigationalStateParameterName()
101     {
102         return navStateParameter;
103     }
104     
105     public String createNavigationalEncoding(PortletWindow window, Map parameters, PortletMode mode, WindowState state, boolean action)
106     {
107         try
108         {
109             return getNavigationalStateParameterName() + ":" + getNavigationalState().encode(window, parameters, mode, state, action);
110         }
111         catch (UnsupportedEncodingException e)
112         {
113             e.printStackTrace();
114             return "";            
115         }    
116     }
117     
118     public String createNavigationalEncoding(PortletWindow window, PortletMode mode, WindowState state)
119     {
120         try
121         {
122             return getNavigationalStateParameterName() + ":" + getNavigationalState().encode(window, mode, state);
123         }
124         catch (UnsupportedEncodingException e)
125         {
126             e.printStackTrace();
127             return "";            
128         }                
129     }
130     
131     protected void decodeBaseURL(HttpServletRequest request)
132     {
133         if (base == null)
134         {
135             base = new BasePortalURLImpl();
136             base.setServerScheme(request.getScheme());
137             base.setServerName(request.getServerName());
138             base.setServerPort(request.getServerPort());
139             base.setSecure(request.isSecure());            
140         }
141         if ( relativeOnly.booleanValue() )
142         {
143             this.secureBaseURL = this.nonSecureBaseURL = "";
144         }
145         else
146         {
147             StringBuffer buffer;
148             
149             buffer = new StringBuffer(HTTPS);
150             buffer.append("://").append(base.getServerName());
151             if (base.getServerPort() != 443 && base.getServerPort() != 80)
152             {
153                 buffer.append(":").append(base.getServerPort());
154             }
155             this.secureBaseURL = buffer.toString();
156             
157             buffer = new StringBuffer(HTTP);
158             buffer.append("://").append(base.getServerName());
159             if (base.getServerPort() != 443 && base.getServerPort() != 80)
160             {
161                  buffer.append(":").append(base.getServerPort());
162             }
163             this.nonSecureBaseURL = buffer.toString();
164         }
165     }
166     
167     protected void decodeBasePath(HttpServletRequest request)
168     {
169         this.contextPath = (String) request.getAttribute(ContainerConstants.PORTAL_CONTEXT);
170         if (contextPath == null)
171         {
172             contextPath = request.getContextPath();
173         }
174         if (contextPath == null)
175         {
176             contextPath = "";
177         }
178         String servletPath = request.getServletPath();
179         if (servletPath == null)
180         {
181             servletPath = "";
182         }
183         this.basePath = contextPath + servletPath;
184     }
185 
186     protected void setEncodedNavigationalState(String encodedNavigationalState)
187     {
188         this.encodedNavState = encodedNavigationalState;        
189         try
190         {
191             navState.init(encodedNavState, characterEncoding);
192         }
193         catch (UnsupportedEncodingException e)
194         {
195             IllegalStateException ise = new IllegalStateException("An unsupported encoding was defined for this NavigationalState.");
196             ise.initCause(e);
197             throw ise;
198         }
199     }
200 
201     protected void setPath(String path)
202     {
203         this.path = path;
204     }
205 
206     public String getBaseURL()
207     {
208         return getBaseURL(base.isSecure());
209     }
210     
211     public String getBaseURL(boolean secure)
212     {
213         // TODO: delivering both secure and non-secure baseURL for PLT.7.1.2
214         //       currently only the baseURL as decoded (secure or non-secure) is returned
215         //       and the secure parameter is ignored
216         return secure ? secureBaseURL : nonSecureBaseURL;
217     }
218     
219     public String getBasePath()
220     {
221         return basePath;
222     }
223     
224     public String getPath()
225     {
226         return path;
227     }    
228 
229     public String getPageBasePath()
230     {
231         if ( null == path || (1 == path.length() && '/' == path.charAt(0)) )
232         {
233             return basePath;
234         }
235         else if ( -1 != path.indexOf('/') && !path.endsWith("/") )
236         {
237             return basePath + path.substring(0, path.lastIndexOf('/') );
238         }
239         else
240         {
241             return basePath + path;
242         }
243     }
244     
245     public boolean isSecure()
246     {
247         return base.isSecure();
248     }
249         
250     public NavigationalState getNavigationalState()
251     {
252         return navState;
253     }
254 
255     public String createPortletURL(PortletWindow window, Map parameters, PortletMode mode, WindowState state, boolean action, boolean secure)
256     {
257         try
258         {
259             return createPortletURL(navState.encode(window,parameters,mode,state,action), secure);
260         }
261         catch (UnsupportedEncodingException e)
262         {
263             // should never happen
264             e.printStackTrace();
265             // to keep the compiler happy
266             return null;
267         }
268     }
269 
270     public String createPortletURL(PortletWindow window, PortletMode mode, WindowState state, boolean secure)
271     {
272         try
273         {
274             return createPortletURL(navState.encode(window,mode,state), secure);
275         }
276         catch (UnsupportedEncodingException e)
277         {
278             // should never happen
279             e.printStackTrace();
280             // to keep the compiler happy
281             return null;
282         }
283     }    
284 
285     protected abstract void decodePathAndNavigationalState(HttpServletRequest request);
286     
287     protected abstract String createPortletURL(String encodedNavState, boolean secure);
288 
289     public void setRequest(HttpServletRequest request)
290     {
291         ArgUtil.assertNotNull(HttpServletRequest.class, request, this, "setRequest");
292         decodeBaseURL(request);        
293         decodeBasePath(request);        
294         decodePathAndNavigationalState(request);        
295     }
296 
297     public void setCharacterEncoding(String characterEncoding)
298     {
299         this.characterEncoding = characterEncoding;
300     }
301     
302     public String getPortalURL()
303     {
304         try
305         {
306             return createPortletURL(navState.encode(), isSecure());
307         }
308         catch (UnsupportedEncodingException e)
309         {
310             // should never happen
311             e.printStackTrace();
312             // to keep the compiler happy
313             return null;
314         }
315     }
316 
317     public boolean hasEncodedNavState()
318     {
319         return encodedNavState != null;
320     }
321 
322     public boolean isPathInfoEncodingNavState()
323     {
324         return false;
325     }
326 }