View Javadoc

1   /*
2    * Copyright 2000-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  package org.apache.jetspeed.portal.portlets;
17  
18  
19  import java.lang.reflect.InvocationTargetException;
20  import java.lang.reflect.Method;
21  
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletResponse;
24  
25  import org.apache.ecs.ConcreteElement;
26  import org.apache.jetspeed.portal.PortletSet;
27  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
28  import org.apache.jetspeed.services.logging.JetspeedLogger;
29  import org.apache.jetspeed.services.resources.JetspeedResources;
30  import org.apache.jetspeed.services.rundata.JetspeedRunData;
31  import org.apache.jetspeed.services.statemanager.SessionState;
32  import org.apache.jetspeed.util.JetspeedClearElement;
33  import org.apache.jetspeed.util.PortletConfigState;
34  import org.apache.jetspeed.util.StringUtils;
35  import org.apache.jetspeed.util.URIEncoder;
36  import org.apache.turbine.util.RunData;
37  
38  /***
39   * RedirectPortlet can be used for menu options that redirect directly 
40   * to a URL outside of the portal.
41   *
42   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
43   * @version $Id: RedirectPortlet.java,v 1.5 2004/03/22 22:26:58 taylor Exp $
44   */
45  public class RedirectPortlet extends AbstractInstancePortlet
46  {           
47      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(RedirectPortlet.class.getName());      
48      
49      public ConcreteElement getContent(RunData rundata)
50      {
51          String menuLevel = this.getPortletConfig().getInitParameter("menuLevel");        
52          int menus = 1;        
53          try 
54          {
55              if (menuLevel != null)
56              {
57                  menus = Integer.parseInt(menuLevel);
58              }
59          }
60          catch (Exception e)
61          {
62              logger.error("failed to parse menu level from Redirect Portlet");
63          }
64          
65          // clear the pane ids of all parents so we don't get lock out the portal on return by recursive redirection
66          PortletSet set = this.getPortletConfig().getPortletSet();
67          int count = 0;
68          while (set != null && count <= menus)
69          {
70              clearState(rundata, set);
71              set = set.getPortletConfig().getPortletSet();
72              count++;
73          }
74                       
75          String url = this.getPortletConfig().getInitParameter("url");
76          url = createDynamicUrl((JetspeedRunData)rundata, url);
77          // rundata.setRedirectURI(url);
78          HttpServletRequest request = rundata.getRequest();
79          HttpServletResponse response = rundata.getResponse();
80          try
81          {
82              String script = "<script> setTimeout( \"location.href='" + url + "'\", 1) </script>";
83              response.getWriter().write(script);
84              //response.sendRedirect(url);
85          }
86          catch (Exception e)
87          {
88              e.printStackTrace();
89              String message = "Failed to redirect to " + url;
90              logger.error(message, e);
91              return new JetspeedClearElement(message);
92          }
93          return new JetspeedClearElement(url);        
94      }
95      
96      private void clearState(RunData rundata, PortletSet set)
97      {
98          SessionState state = ((JetspeedRunData)rundata).getPortletSessionState(set.getID());
99          state.setAttribute(JetspeedResources.PATH_PANEID_KEY, null);
100     }
101     
102     private String createDynamicUrl(JetspeedRunData rundata, String url)
103     {
104         String parameterNames = PortletConfigState.getParameter(this, rundata, "parameterNames", null);
105         String sessionAttributeNames = PortletConfigState.getParameter(this, rundata, "sessionAttributeNames", null);
106         if (parameterNames == null || sessionAttributeNames == null)
107         {
108             return url;
109         }
110         
111         String[] names = StringUtils.stringToArray(parameterNames, ",");
112         String[] attribNames = StringUtils.stringToArray(sessionAttributeNames, ",");
113         
114         if (names == null || attribNames == null)
115         {
116             return url;
117         }
118         if (names.length == 0 || attribNames.length == 0)
119         {
120             return url;
121         }
122         int count = (names.length > attribNames.length) ? names.length : attribNames.length;
123         StringBuffer dynamic = new StringBuffer(url);
124         int appended = 0;
125         for(int ix=0; ix < count; ix++)
126         {
127                 String attribute = lookup(rundata, attribNames[ix]);
128             //String attribute = (String)rundata.getSession().getAttribute(attribNames[ix]);
129             if (attribute == null)
130             {
131                 continue;
132             }
133             if (appended == 0)
134             {
135                 dynamic.append("?");                
136             }
137             else
138             {
139                 dynamic.append("&");
140             }
141             appended++;
142             dynamic.append(URIEncoder.encode(names[ix]));
143             dynamic.append("=");
144             dynamic.append(URIEncoder.encode(attribute));
145         }
146         return dynamic.toString();
147     }
148     
149     /***
150      * First we look in the request for it, if not found look in the session.
151      * If it contains a '.' & an object is found in the one of the scopes, then
152      * we try and call the getter method for the field defined after the '.'.
153      * 
154      * @param rundata
155      * @param attributeName
156      * @return String The value
157      */
158     private String lookup(JetspeedRunData rundata,String attributeName)
159     {
160         String value = null;
161         
162         Object o = lookupAttribute(rundata, attributeName);
163         
164         //now see if there is a property defined in the attributeName
165         if(o == null)
166         {
167             int index = attributeName.lastIndexOf(".");
168             if(index > 0)
169             {
170                 String name = attributeName.substring(0, index);
171                 String property = attributeName.substring(index + 1);
172     
173                 o = lookupAttribute(rundata, name, property);
174                 
175                 if (o instanceof String)
176                 {
177                     value = (String)o;
178                 }
179                 
180             } //end if attributeName contains period
181         }
182         else if (o instanceof String)
183         {
184             value = (String) o;
185         }
186         return value;
187     }
188     
189     private Object lookupAttribute(JetspeedRunData rundata, String name)
190     {
191         Object o = rundata.getRequest().getAttribute(name);
192         if(o == null)
193         {
194             o = rundata.getSession().getAttribute(name);
195         }
196     
197         return o;        
198     }
199     
200     private Object lookupAttribute(JetspeedRunData rundata, String name, String property)
201     {
202         Object o = lookupAttribute(rundata, name);
203         Object returnObject = null;                
204         if(o != null)
205         {
206             //invoke the getter method for the property
207             String getterName = "get" + property.substring(0,1).toUpperCase() + 
208                                  property.substring(1);                    
209             try 
210             {
211                 Method getter = o.getClass().getMethod(getterName,null);
212                         
213                 returnObject = getter.invoke(o,null);
214             }
215             catch(Exception e)
216             {
217                 o = null;
218             }
219         } //end if o not null
220 
221         return returnObject;
222     }
223 }