/* * Copyright 2000-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jetspeed.portal.portlets; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.ecs.ConcreteElement; import org.apache.jetspeed.portal.PortletSet; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.jetspeed.services.resources.JetspeedResources; import org.apache.jetspeed.services.rundata.JetspeedRunData; import org.apache.jetspeed.services.statemanager.SessionState; import org.apache.jetspeed.util.JetspeedClearElement; import org.apache.jetspeed.util.PortletConfigState; import org.apache.jetspeed.util.StringUtils; import org.apache.jetspeed.util.URIEncoder; import org.apache.turbine.util.RunData; /** * RedirectPortlet can be used for menu options that redirect directly * to a URL outside of the portal. * * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a> * @version $Id: RedirectPortlet.java,v 1.5 2004/03/22 22:26:58 taylor Exp $ */ public class RedirectPortlet extends AbstractInstancePortlet { private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(RedirectPortlet.class.getName()); public ConcreteElement getContent(RunData rundata) { String menuLevel = this.getPortletConfig().getInitParameter("menuLevel"); int menus = 1; try { if (menuLevel != null) { menus = Integer.parseInt(menuLevel); } } catch (Exception e) { logger.error("failed to parse menu level from Redirect Portlet"); } // clear the pane ids of all parents so we don't get lock out the portal on return by recursive redirection PortletSet set = this.getPortletConfig().getPortletSet(); int count = 0; while (set != null && count <= menus) { clearState(rundata, set); set = set.getPortletConfig().getPortletSet(); count++; } String url = this.getPortletConfig().getInitParameter("url"); url = createDynamicUrl((JetspeedRunData)rundata, url); // rundata.setRedirectURI(url); HttpServletRequest request = rundata.getRequest(); HttpServletResponse response = rundata.getResponse(); try { String script = "<script> setTimeout( \"location.href='" + url + "'\", 1) </script>"; response.getWriter().write(script); //response.sendRedirect(url); } catch (Exception e) { e.printStackTrace(); String message = "Failed to redirect to " + url; logger.error(message, e); return new JetspeedClearElement(message); } return new JetspeedClearElement(url); } private void clearState(RunData rundata, PortletSet set) { SessionState state = ((JetspeedRunData)rundata).getPortletSessionState(set.getID()); state.setAttribute(JetspeedResources.PATH_PANEID_KEY, null); } private String createDynamicUrl(JetspeedRunData rundata, String url) { String parameterNames = PortletConfigState.getParameter(this, rundata, "parameterNames", null); String sessionAttributeNames = PortletConfigState.getParameter(this, rundata, "sessionAttributeNames", null); if (parameterNames == null || sessionAttributeNames == null) { return url; } String[] names = StringUtils.stringToArray(parameterNames, ","); String[] attribNames = StringUtils.stringToArray(sessionAttributeNames, ","); if (names == null || attribNames == null) { return url; } if (names.length == 0 || attribNames.length == 0) { return url; } int count = (names.length > attribNames.length) ? names.length : attribNames.length; StringBuffer dynamic = new StringBuffer(url); int appended = 0; for(int ix=0; ix < count; ix++) { String attribute = lookup(rundata, attribNames[ix]); //String attribute = (String)rundata.getSession().getAttribute(attribNames[ix]); if (attribute == null) { continue; } if (appended == 0) { dynamic.append("?"); } else { dynamic.append("&"); } appended++; dynamic.append(URIEncoder.encode(names[ix])); dynamic.append("="); dynamic.append(URIEncoder.encode(attribute)); } return dynamic.toString(); } /** * First we look in the request for it, if not found look in the session. * If it contains a '.' & an object is found in the one of the scopes, then * we try and call the getter method for the field defined after the '.'. * * @param rundata * @param attributeName * @return String The value */ private String lookup(JetspeedRunData rundata,String attributeName) { String value = null; Object o = lookupAttribute(rundata, attributeName); //now see if there is a property defined in the attributeName if(o == null) { int index = attributeName.lastIndexOf("."); if(index > 0) { String name = attributeName.substring(0, index); String property = attributeName.substring(index + 1); o = lookupAttribute(rundata, name, property); if (o instanceof String) { value = (String)o; } } //end if attributeName contains period } else if (o instanceof String) { value = (String) o; } return value; } private Object lookupAttribute(JetspeedRunData rundata, String name) { Object o = rundata.getRequest().getAttribute(name); if(o == null) { o = rundata.getSession().getAttribute(name); } return o; } private Object lookupAttribute(JetspeedRunData rundata, String name, String property) { Object o = lookupAttribute(rundata, name); Object returnObject = null; if(o != null) { //invoke the getter method for the property String getterName = "get" + property.substring(0,1).toUpperCase() + property.substring(1); try { Method getter = o.getClass().getMethod(getterName,null); returnObject = getter.invoke(o,null); } catch(Exception e) { o = null; } } //end if o not null return returnObject; } }