Hi,
I'd like to join the discussion around Jetspeed 2 development and initially submit a working solution for Tiles support to the current J2 Struts bridge. The solution comprises a PortletTilesRequestProcessor, which extends org.apache.struts.tiles.TilesRequestProcessor the same way as PortletRequestProcessor extends org.apache.struts.action.RequestProcessor, and a few code patches for PortletServlet, PortletServletRequestDispatcher, and StrutsPortletRenderContext.These patches, in principal, take care of saving and restoring some context that would otherwise be lost due to the separation of action and render request. This context is Tiles specific and just added at places where the other Struts information is usually saved and restored. In order to use the PortletTilesRequestProcessor the controller tag in struts-config.xml has to reference it.
Please find attached the code; the code patches are marked accordingly. Please note that the code is based on the J2M1 release, and thus probably on Struts bridge version 0.1.
I am looking forward to receive feedback or comments.
Regards, Peter
Architect, TEC Wellington, New Zealand email: [EMAIL PROTECTED]
_org.apache.portals.bridges.struts.PortletTilesRequestProcessor_
/*
* 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.portals.bridges.struts;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionMapping; import org.apache.struts.tiles.TilesRequestProcessor;
/** * @author <a href="mailto:[EMAIL PROTECTED]">Peter Meier </a> */ public class PortletTilesRequestProcessor extends TilesRequestProcessor {
public PortletTilesRequestProcessor() {super(); }
public void process( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException {
if ( !( response instanceof PortletServletResponseWrapper ) ) {
response = new PortletServletResponseWrapper( request, response );
}
super.process( request, response );
}
protected boolean processRoles( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping )
throws IOException, ServletException {
boolean proceed = super.processRoles( request, response, mapping );
if ( proceed && ( (PortletServlet)super.servlet ).performActionRenderRequest( request, response, mapping ) ) {
return false;
}
else
return proceed;
}
}
_org.apache.portals.bridges.struts.StrutsPortletRenderContext_
/* * 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.portals.bridges.struts;
import java.io.Serializable;
import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessages; import org.apache.struts.tiles.ComponentContext;
/**
* StrutsPortletRenderContext
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a>
* @version $Id: StrutsPortletRenderContext.java,v 1.1 2004/07/29 22:16:40 ate Exp $
*/
public class StrutsPortletRenderContext implements Serializable {
private String path; private boolean dispatchNamed; private ActionForm actionForm; private boolean requestCancelled; private ActionMessages messages; private ActionMessages errors;
// BEGIN: INSERT // private ComponentContext tilesComponentContext;
// // END: INSERT
public String getPath() {return path; }
public void setPath( String path ) {this.path = path; }
public boolean getDispatchNamed() {return dispatchNamed; }
public void setDispatchNamed( boolean namedPath ) {this.dispatchNamed = namedPath; }
public ActionForm getActionForm() {return actionForm; }
public void setActionForm( ActionForm actionForm ) {this.actionForm = actionForm; }
public boolean isRequestCancelled() {return requestCancelled; }
public void setRequestCancelled( boolean requestCancelled ) {this.requestCancelled = requestCancelled; }
public ActionMessages getMessages() {return messages; }
public void setMessages( ActionMessages messages ) {this.messages = messages; }
public ActionMessages getErrors() {return errors; }
public void setErrors( ActionMessages errors ) {this.errors = errors; }
public ComponentContext getTilesComponentContext() {return tilesComponentContext; }
// BEGIN: INSERT
//
public void setTilesComponentContext( ComponentContext tilesComponentContext ) {
this.tilesComponentContext = tilesComponentContext; } // // END: INSERT }
_org.apache.portals.bridges.struts.PortletServletRequestDispatcher_
/* * 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.portals.bridges.struts;
import java.io.IOException;
import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.portals.bridges.struts.util.HttpRequestDispatcherImpl; import org.apache.struts.Globals; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessages; import org.apache.struts.config.ActionConfig; import org.apache.struts.taglib.tiles.ComponentConstants; import org.apache.struts.tiles.ComponentContext;
/**
* PortletServletRequestDispatcher
*
* @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a>
* @version $Id: PortletServletRequestDispatcher.java,v 1.2 2004/11/27 01:04:12 ate Exp $
*/
public class PortletServletRequestDispatcher extends HttpRequestDispatcherImpl {
private static final Log log = LogFactory.getLog( PortletServletRequestDispatcher.class );
private boolean named;
public PortletServletRequestDispatcher( RequestDispatcher dispatcher, String path, boolean named ) {
super( dispatcher, path ); }
protected void invoke( ServletRequest request, ServletResponse response, boolean include ) throws ServletException,
IOException {
String request_type = (String)request.getAttribute( StrutsPortlet.REQUEST_TYPE );
if ( request_type != null && request_type.equals( StrutsPortlet.ACTION_REQUEST ) ) {
if ( log.isDebugEnabled() ) {
log.debug( "saving " + ( named ? "named " : " " ) + "dispatch to :" + getPath() + ", from " + request_type
+ " " + StrutsPortletURL.getPageURL( request ) );
}
HttpServletRequest req = (HttpServletRequest)request;
StrutsPortletRenderContext context = new StrutsPortletRenderContext();
context.setPath( getPath() );
context.setDispatchNamed( named );
ActionConfig actionConfig = (ActionConfig)request.getAttribute( Globals.MAPPING_KEY );
if ( actionConfig != null ) {
if ( actionConfig.getAttribute() != null && actionConfig.getScope().equals( "request" ) ) {
ActionForm actionForm = (ActionForm)request.getAttribute( actionConfig.getAttribute() );
context.setActionForm( actionForm );
Boolean requestCancelled = (Boolean)request.getAttribute( Globals.CANCEL_KEY );
if ( requestCancelled != null && requestCancelled.booleanValue() ) context.setRequestCancelled( true );
}
}
context.setMessages( (ActionMessages)request.getAttribute( Globals.MESSAGE_KEY ) );
context.setErrors( (ActionMessages)request.getAttribute( Globals.ERROR_KEY ) );
if ( context.getErrors() != null ) {
String originURL = StrutsPortletURL.getOriginURL( request );
if ( originURL != null ) {
request.setAttribute( StrutsPortlet.REDIRECT_PAGE_URL, originURL );
}
}
// INSERT START
//
context.setTilesComponentContext( (ComponentContext)request.getAttribute( ComponentConstants.COMPONENT_CONTEXT ) );
//
// INSERT END
String portletName = (String)req.getAttribute( StrutsPortlet.PORTLET_NAME );
req.getSession( true ).setAttribute( StrutsPortlet.RENDER_CONTEXT + "_" + portletName, context );
}
else {
if ( log.isDebugEnabled() ) {
log.debug( "invoking " + ( named ? "named " : " " ) + " dispatch to :" + getPath() + ", from " + request_type
+ " " + StrutsPortletURL.getPageURL( request ) );
}
super.invoke( request, response, true );
}
}
}
_org.apache.portals.bridges.struts.PortletServlet_
/*
* 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.portals.bridges.struts;
import java.io.IOException;
import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.struts.Globals; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionServlet; import org.apache.struts.taglib.tiles.ComponentConstants;
/** * PortletServlet * * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a> * @version $Id: PortletServlet.java,v 1.2 2004/11/27 01:04:12 ate Exp $ */ public class PortletServlet extends ActionServlet {
public PortletServlet() {super(); }
public void init( ServletConfig config ) throws ServletException {super.init( new PortletServletConfigImpl( config ) ); }
public ServletContext getServletContext() {return getServletConfig().getServletContext(); }
public boolean performActionRenderRequest( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping )
throws IOException, ServletException {
if ( !request.getAttribute( StrutsPortlet.REQUEST_TYPE ).equals( StrutsPortlet.ACTION_REQUEST ) ) {
StrutsPortletRenderContext context = null;
String portletName = (String)request.getAttribute( StrutsPortlet.PORTLET_NAME );
String contextKey = StrutsPortlet.RENDER_CONTEXT + "_" + portletName;
context = (StrutsPortletRenderContext)request.getSession( true ).getAttribute( contextKey );
if ( context != null ) {
if ( log.isDebugEnabled() ) {
log.debug( "render context path: " + context.getPath() );
}
request.getSession().removeAttribute( contextKey );
if ( context.getActionForm() != null ) {
String attribute = mapping.getAttribute();
if ( attribute != null ) {
if ( log.isDebugEnabled() ) {
log.debug( "Putting form " + context.getActionForm().getClass().getName() + " into request as "
+ attribute + " for mapping " + mapping.getName() );
}
request.setAttribute( mapping.getAttribute(), context.getActionForm() );
}
else if ( log.isWarnEnabled() ) {
log.warn( "Attribute is null for form " + context.getActionForm().getClass().getName()
+ ", won't put it into request for mapping " + mapping.getName() );
}
}
if ( context.isRequestCancelled() ) request.setAttribute( Globals.CANCEL_KEY, Boolean.TRUE );
if ( context.getMessages() != null ) request.setAttribute( Globals.MESSAGE_KEY, context.getMessages() );
if ( context.getErrors() != null ) request.setAttribute( Globals.ERROR_KEY, context.getErrors() );
// BEGIN: INSERT
//
if ( context.getTilesComponentContext() != null )
request.setAttribute( ComponentConstants.COMPONENT_CONTEXT, context.getTilesComponentContext() );
//
// END: INSERT
RequestDispatcher dispatcher = null;
if ( context.getDispatchNamed() )
dispatcher = getServletContext().getNamedDispatcher( context.getPath() );
else
dispatcher = getServletContext().getRequestDispatcher( context.getPath() );
dispatcher.include( request, response );
return true;
}
}
return false;
}
}
/* * 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.portals.bridges.struts; import java.io.Serializable; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessages; import org.apache.struts.tiles.ComponentContext; /** * StrutsPortletRenderContext * * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a> * @version $Id: StrutsPortletRenderContext.java,v 1.1 2004/07/29 22:16:40 ate Exp $ */ public class StrutsPortletRenderContext implements Serializable { private String path; private boolean dispatchNamed; private ActionForm actionForm; private boolean requestCancelled; private ActionMessages messages; private ActionMessages errors; // BEGIN: INSERT // private ComponentContext tilesComponentContext; // // END: INSERT public String getPath() { return path; } public void setPath( String path ) { this.path = path; } public boolean getDispatchNamed() { return dispatchNamed; } public void setDispatchNamed( boolean namedPath ) { this.dispatchNamed = namedPath; } public ActionForm getActionForm() { return actionForm; } public void setActionForm( ActionForm actionForm ) { this.actionForm = actionForm; } public boolean isRequestCancelled() { return requestCancelled; } public void setRequestCancelled( boolean requestCancelled ) { this.requestCancelled = requestCancelled; } public ActionMessages getMessages() { return messages; } public void setMessages( ActionMessages messages ) { this.messages = messages; } public ActionMessages getErrors() { return errors; } public void setErrors( ActionMessages errors ) { this.errors = errors; } public ComponentContext getTilesComponentContext() { return tilesComponentContext; } // BEGIN: INSERT // public void setTilesComponentContext( ComponentContext tilesComponentContext ) { this.tilesComponentContext = tilesComponentContext; } // // END: INSERT }
/* * 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.portals.bridges.struts; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.portals.bridges.struts.util.HttpRequestDispatcherImpl; import org.apache.struts.Globals; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessages; import org.apache.struts.config.ActionConfig; import org.apache.struts.taglib.tiles.ComponentConstants; import org.apache.struts.tiles.ComponentContext; /** * PortletServletRequestDispatcher * * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a> * @version $Id: PortletServletRequestDispatcher.java,v 1.2 2004/11/27 01:04:12 ate Exp $ */ public class PortletServletRequestDispatcher extends HttpRequestDispatcherImpl { private static final Log log = LogFactory.getLog( PortletServletRequestDispatcher.class ); private boolean named; public PortletServletRequestDispatcher( RequestDispatcher dispatcher, String path, boolean named ) { super( dispatcher, path ); } protected void invoke( ServletRequest request, ServletResponse response, boolean include ) throws ServletException, IOException { String request_type = (String)request.getAttribute( StrutsPortlet.REQUEST_TYPE ); if ( request_type != null && request_type.equals( StrutsPortlet.ACTION_REQUEST ) ) { if ( log.isDebugEnabled() ) { log.debug( "saving " + ( named ? "named " : " " ) + "dispatch to :" + getPath() + ", from " + request_type + " " + StrutsPortletURL.getPageURL( request ) ); } HttpServletRequest req = (HttpServletRequest)request; StrutsPortletRenderContext context = new StrutsPortletRenderContext(); context.setPath( getPath() ); context.setDispatchNamed( named ); ActionConfig actionConfig = (ActionConfig)request.getAttribute( Globals.MAPPING_KEY ); if ( actionConfig != null ) { if ( actionConfig.getAttribute() != null && actionConfig.getScope().equals( "request" ) ) { ActionForm actionForm = (ActionForm)request.getAttribute( actionConfig.getAttribute() ); context.setActionForm( actionForm ); Boolean requestCancelled = (Boolean)request.getAttribute( Globals.CANCEL_KEY ); if ( requestCancelled != null && requestCancelled.booleanValue() ) context.setRequestCancelled( true ); } } context.setMessages( (ActionMessages)request.getAttribute( Globals.MESSAGE_KEY ) ); context.setErrors( (ActionMessages)request.getAttribute( Globals.ERROR_KEY ) ); if ( context.getErrors() != null ) { String originURL = StrutsPortletURL.getOriginURL( request ); if ( originURL != null ) { request.setAttribute( StrutsPortlet.REDIRECT_PAGE_URL, originURL ); } } // INSERT START // context.setTilesComponentContext( (ComponentContext)request.getAttribute( ComponentConstants.COMPONENT_CONTEXT ) ); // // INSERT END String portletName = (String)req.getAttribute( StrutsPortlet.PORTLET_NAME ); req.getSession( true ).setAttribute( StrutsPortlet.RENDER_CONTEXT + "_" + portletName, context ); } else { if ( log.isDebugEnabled() ) { log.debug( "invoking " + ( named ? "named " : " " ) + " dispatch to :" + getPath() + ", from " + request_type + " " + StrutsPortletURL.getPageURL( request ) ); } super.invoke( request, response, true ); } } }
/* * 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.portals.bridges.struts; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.Globals; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionServlet; import org.apache.struts.taglib.tiles.ComponentConstants; /** * PortletServlet * * @author <a href="mailto:[EMAIL PROTECTED]">Ate Douma </a> * @version $Id: PortletServlet.java,v 1.2 2004/11/27 01:04:12 ate Exp $ */ public class PortletServlet extends ActionServlet { public PortletServlet() { super(); } public void init( ServletConfig config ) throws ServletException { super.init( new PortletServletConfigImpl( config ) ); } public ServletContext getServletContext() { return getServletConfig().getServletContext(); } public boolean performActionRenderRequest( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping ) throws IOException, ServletException { if ( !request.getAttribute( StrutsPortlet.REQUEST_TYPE ).equals( StrutsPortlet.ACTION_REQUEST ) ) { StrutsPortletRenderContext context = null; String portletName = (String)request.getAttribute( StrutsPortlet.PORTLET_NAME ); String contextKey = StrutsPortlet.RENDER_CONTEXT + "_" + portletName; context = (StrutsPortletRenderContext)request.getSession( true ).getAttribute( contextKey ); if ( context != null ) { if ( log.isDebugEnabled() ) { log.debug( "render context path: " + context.getPath() ); } request.getSession().removeAttribute( contextKey ); if ( context.getActionForm() != null ) { String attribute = mapping.getAttribute(); if ( attribute != null ) { if ( log.isDebugEnabled() ) { log.debug( "Putting form " + context.getActionForm().getClass().getName() + " into request as " + attribute + " for mapping " + mapping.getName() ); } request.setAttribute( mapping.getAttribute(), context.getActionForm() ); } else if ( log.isWarnEnabled() ) { log.warn( "Attribute is null for form " + context.getActionForm().getClass().getName() + ", won't put it into request for mapping " + mapping.getName() ); } } if ( context.isRequestCancelled() ) request.setAttribute( Globals.CANCEL_KEY, Boolean.TRUE ); if ( context.getMessages() != null ) request.setAttribute( Globals.MESSAGE_KEY, context.getMessages() ); if ( context.getErrors() != null ) request.setAttribute( Globals.ERROR_KEY, context.getErrors() ); // BEGIN: INSERT // if ( context.getTilesComponentContext() != null ) request.setAttribute( ComponentConstants.COMPONENT_CONTEXT, context.getTilesComponentContext() ); // // END: INSERT RequestDispatcher dispatcher = null; if ( context.getDispatchNamed() ) dispatcher = getServletContext().getNamedDispatcher( context.getPath() ); else dispatcher = getServletContext().getRequestDispatcher( context.getPath() ); dispatcher.include( request, response ); return true; } } return false; } }
/* * 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.portals.bridges.struts; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionMapping; import org.apache.struts.tiles.TilesRequestProcessor; /** * @author <a href="mailto:[EMAIL PROTECTED]">Peter Meier </a> */ public class PortletTilesRequestProcessor extends TilesRequestProcessor { public PortletTilesRequestProcessor() { super(); } public void process( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException { if ( !( response instanceof PortletServletResponseWrapper ) ) { response = new PortletServletResponseWrapper( request, response ); } super.process( request, response ); } protected boolean processRoles( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping ) throws IOException, ServletException { boolean proceed = super.processRoles( request, response, mapping ); if ( proceed && ( (PortletServlet)super.servlet ).performActionRenderRequest( request, response, mapping ) ) { return false; } else return proceed; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
