You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ni...@apache.org on 2008/01/21 11:09:07 UTC

svn commit: r613823 [2/4] - in /struts/sandbox/trunk/struts2-portlet2-plugin: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/struts2/ src/main/java/org/apache/struts2/components/ src/main/java/org...

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr286Dispatcher.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr286Dispatcher.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr286Dispatcher.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr286Dispatcher.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,95 @@
+package org.apache.struts2.portlet.dispatcher;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.Event;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.PortletException;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+import org.apache.struts2.StrutsException;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.apache.struts2.portlet.servlet.PortletServletRequest;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.util.TextUtils;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+public class Jsr286Dispatcher extends Jsr168Dispatcher {
+
+	private final static Logger LOG = LoggerFactory.getLogger(Jsr286Dispatcher.class);
+	
+	
+	@Override
+	public void processEvent(EventRequest request, EventResponse response)
+			throws PortletException, IOException {
+		LOG.debug("Entering processEvent");
+		resetActionContext();
+		try {
+			Event event = request.getEvent();
+			// We'll use the event name as the "action"
+			serviceAction(request, response, getActionMapping(request),
+					getRequestMap(request), getParameterMap(request),
+					getSessionMap(request), getApplicationMap(),
+					portletNamespace, EVENT_PHASE);
+			LOG.debug("Leaving processAction");
+		} finally {
+			ActionContext.setContext(null);
+		}
+	}
+
+	@Override
+	public void serveResource(ResourceRequest request, ResourceResponse response)
+			throws PortletException, IOException {
+		LOG.debug("Entering serveResource");
+		resetActionContext();
+		try {
+			serviceAction(request, response, getActionMapping(request),
+					getRequestMap(request), getParameterMap(request),
+					getSessionMap(request), getApplicationMap(),
+					portletNamespace, SERVE_RESOURCE_PHASE);
+		}
+		finally {
+			ActionContext.setContext(null);
+		}
+	}
+	
+	/**
+	 * Gets the action mapping from the event request.
+	 * 
+	 * @param request
+	 *            the EventRequest object.
+	 */
+	protected ActionMapping getActionMapping(final EventRequest request) {
+		ActionMapping mapping = null;
+		String actionPath = null;
+		actionPath = request.getEvent().getName();
+		if (!TextUtils.stringSet(actionPath)) {
+			mapping = (ActionMapping) actionMap.get(request.getPortletMode());
+		} else {
+			Map<String, String[]> extra = new HashMap<String, String[]>();
+			extra.put(ACTION_PARAM, new String[]{actionPath});
+			// Use the usual action mapper, but it is expecting an action
+			// extension
+			// on the uri, so we add the default one, which should be ok as the
+			// portlet is a portlet first, a servlet second
+			PortletServletRequest httpRequest = new PortletServletRequest(
+					request, getPortletContext(), extra);
+			mapping = actionMapper.getMapping(httpRequest, dispatcherUtils
+					.getConfigurationManager());
+		}
+
+		if (mapping == null) {
+			throw new StrutsException(
+					"Unable to locate action mapping for request, probably due to "
+							+ "an invalid action path: " + actionPath);
+		}
+		return mapping;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletAwareInterceptor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletAwareInterceptor.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletAwareInterceptor.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletAwareInterceptor.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,84 @@
+/*
+ * $Id: PortletAwareInterceptor.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletResponse;
+
+import org.apache.struts2.StrutsStatics;
+import org.apache.struts2.interceptor.PrincipalAware;
+import org.apache.struts2.portlet.PortletActionConstants;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+public class PortletAwareInterceptor extends AbstractInterceptor implements PortletActionConstants, StrutsStatics {
+
+	private static final long serialVersionUID = 2476509721059587700L;
+	
+	private static final Logger LOG = LoggerFactory.getLogger(PortletAwareInterceptor.class);
+
+	/**
+     * Sets action properties based on the interfaces an action implements. Things like application properties,
+     * parameters, session attributes, etc are set based on the implementing interface.
+     *
+     * @param invocation an encapsulation of the action execution state.
+     * @throws Exception if an error occurs when setting action properties.
+     */
+    public String intercept(ActionInvocation invocation) throws Exception {
+        final Object action = invocation.getAction();
+        final ActionContext context = invocation.getInvocationContext();
+
+        if (action instanceof PortletRequestAware) {
+            PortletRequest request = (PortletRequest) context.get(REQUEST);
+            ((PortletRequestAware) action).setPortletRequest(request);
+        }
+
+        if (action instanceof PortletResponseAware) {
+            PortletResponse response = (PortletResponse) context.get(RESPONSE);
+            ((PortletResponseAware) action).setPortletResponse(response);
+        }
+        if (action instanceof PrincipalAware) {
+            PortletRequest request = (PortletRequest) context.get(REQUEST);
+            ((PrincipalAware) action).setPrincipalProxy(new PortletPrincipalProxy(request));
+        }
+        if (action instanceof PortletContextAware) {
+            PortletContext portletContext = (PortletContext) context.get(STRUTS_PORTLET_CONTEXT);
+            ((PortletContextAware) action).setPortletContext(portletContext);
+        }
+        if (action instanceof PortletPreferencesAware) {
+        	PortletRequest request = (PortletRequest) context.get(REQUEST);
+            
+            // Check if running in a servlet environment
+            if (request == null) {
+                LOG.warn("This portlet preferences implementation should only be used during development");
+                ((PortletPreferencesAware)action).setPortletPreferences(new ServletPortletPreferences(ActionContext.getContext().getSession()));
+            } else {
+            	((PortletPreferencesAware)action).setPortletPreferences(request.getPreferences());
+            }
+        }
+        return invocation.invoke();
+    }
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletContextAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletContextAware.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletContextAware.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletContextAware.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,29 @@
+/*
+ * $Id: PortletContextAware.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import javax.portlet.PortletContext;
+
+public interface PortletContextAware {
+
+	void setPortletContext(PortletContext portletContext);
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPreferencesAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPreferencesAware.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPreferencesAware.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPreferencesAware.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,39 @@
+/*
+ * $Id: PortletPreferencesAware.java 557544 2007-07-19 10:03:06Z nilsga $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import javax.portlet.PortletPreferences;
+
+
+/**
+ * All Actions that want to have access to the portlet preferences should
+ * implement this interface.  If running in a servlet environment, an
+ * appropriate testing implementation will be provided.
+ */
+public interface PortletPreferencesAware {
+
+    /**
+     * Sets the HTTP request object in implementing classes.
+     *
+     * @param request the HTTP request.
+     */
+    public void setPortletPreferences(PortletPreferences prefs);
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPrincipalProxy.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPrincipalProxy.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPrincipalProxy.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletPrincipalProxy.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,93 @@
+/*
+ * $Id: PortletPrincipalProxy.java 559107 2007-07-24 17:03:11Z jholmes $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import org.apache.struts2.interceptor.PrincipalProxy;
+
+import javax.portlet.PortletRequest;
+import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
+
+/**
+ * PrincipalProxy implementation for using PortletRequest Principal related methods.
+ */
+public class PortletPrincipalProxy implements PrincipalProxy {
+
+    private PortletRequest request;
+
+    /**
+     * Constructs a proxy
+     *
+     * @param request The underlying request
+     */
+    public PortletPrincipalProxy(PortletRequest request) {
+        this.request = request;
+    }
+
+    /**
+     * True if the user is in the given role
+     *
+     * @param role The role
+     * @return True if the user is in that role
+     */
+    public boolean isUserInRole(String role) {
+        return request.isUserInRole(role);
+    }
+
+    /**
+     * Gets the user principal
+     *
+     * @return The principal
+     */
+    public Principal getUserPrincipal() {
+        return request.getUserPrincipal();
+    }
+
+    /**
+     * Gets the user id
+     *
+     * @return The user id
+     */
+    public String getRemoteUser() {
+        return request.getRemoteUser();
+    }
+
+    /**
+     * Is the request using https?
+     *
+     * @return True if using https
+     */
+    public boolean isRequestSecure() {
+        return request.isSecure();
+    }
+
+    /**
+     * Gets the request.
+     *
+     * @return The request
+     * @throws UnsupportedOperationException not supported in this implementation.
+     * @deprecated To obtain the HttpServletRequest in your action, use
+     *             {@link org.apache.struts2.servlet.ServletRequestAware}, since this method will be dropped in future.
+     */
+    public HttpServletRequest getRequest() {
+        throw new UnsupportedOperationException("Usage of getRequest() method is deprecadet and not supported for this implementation");
+    }
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletRequestAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletRequestAware.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletRequestAware.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletRequestAware.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,29 @@
+/*
+ * $Id: PortletRequestAware.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import javax.portlet.PortletRequest;
+
+public interface PortletRequestAware {
+
+	void setPortletRequest(PortletRequest request);
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletResponseAware.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletResponseAware.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletResponseAware.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletResponseAware.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,29 @@
+/*
+ * $Id: PortletResponseAware.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import javax.portlet.PortletResponse;
+
+public interface PortletResponseAware {
+
+	void setPortletResponse(PortletResponse response);
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,96 @@
+/*
+ * $Id: PortletStateInterceptor.java 601698 2007-12-06 10:59:38Z nilsga $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import java.util.Map;
+
+import javax.portlet.ActionResponse;
+import javax.portlet.RenderRequest;
+
+import org.apache.struts2.portlet.PortletActionConstants;
+import org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
+import com.opensymphony.xwork2.util.CompoundRoot;
+import com.opensymphony.xwork2.util.TextUtils;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+public class PortletStateInterceptor extends AbstractInterceptor implements PortletActionConstants {
+
+	private final static Logger LOG = LoggerFactory.getLogger(PortletStateInterceptor.class);
+
+	private static final long serialVersionUID = 6138452063353911784L;
+
+	@Override
+	public String intercept(ActionInvocation invocation) throws Exception {
+		Integer phase = (Integer) invocation.getInvocationContext().get(PHASE);
+		if (RENDER_PHASE.equals(phase)) {
+			restoreStack(invocation);
+			return invocation.invoke();
+		} else if (ACTION_PHASE.equals(phase)) {
+			try {
+				return invocation.invoke();
+			} finally {
+				saveStack(invocation);
+			}
+		} else {
+			return invocation.invoke();
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void saveStack(ActionInvocation invocation) {
+		Map session = invocation.getInvocationContext().getSession();
+		session.put(STACK_FROM_EVENT_PHASE, invocation.getStack());
+		ActionResponse actionResponse = (ActionResponse) invocation.getInvocationContext().get(RESPONSE);
+		actionResponse.setRenderParameter(EVENT_ACTION, "true");
+	}
+
+	@SuppressWarnings("unchecked")
+	private void restoreStack(ActionInvocation invocation) {
+		RenderRequest request = (RenderRequest) invocation.getInvocationContext().get(REQUEST);
+		if (TextUtils.stringSet(request.getParameter(EVENT_ACTION))) {
+			if(!isProperPrg(invocation)) {
+				LOG.debug("Restoring value stack from event phase");
+				ValueStack oldStack = (ValueStack) invocation.getInvocationContext().getSession().get(
+				STACK_FROM_EVENT_PHASE);
+				if (oldStack != null) {
+					CompoundRoot oldRoot = oldStack.getRoot();
+					ValueStack currentStack = invocation.getStack();
+					CompoundRoot root = currentStack.getRoot();
+					root.addAll(oldRoot);
+					LOG.debug("Restored stack");
+				}
+			}
+			else {
+				LOG.debug("Won't restore stack from event phase since it's a proper PRG request");
+			}
+		}
+	}
+
+	private boolean isProperPrg(ActionInvocation invocation) {
+		return !(invocation.getAction() instanceof DirectRenderFromEventAction);
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/ServletPortletPreferences.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/ServletPortletPreferences.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/ServletPortletPreferences.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/interceptor/ServletPortletPreferences.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,95 @@
+/*
+ * $Id: ServletPortletPreferences.java 557544 2007-07-19 10:03:06Z nilsga $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.interceptor;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.ReadOnlyException;
+import javax.portlet.ValidatorException;
+
+/**
+ * Simple portlet preferences implementation that uses a map in the Session
+ * as storage.
+ */
+public class ServletPortletPreferences implements PortletPreferences {
+
+    private Map session;
+    private String PREFERENCES_KEY = "_portlet-preferences";
+    
+    public ServletPortletPreferences(Map session) {
+        this.session = session;
+    }
+    
+    public Map getMap() {
+        Map map = (Map) session.get(PREFERENCES_KEY);
+        if (map == null) {
+            map = new HashMap();
+            session.put(PREFERENCES_KEY, map);
+        }
+        return map;
+    }
+
+    public Enumeration getNames() {
+        return new Vector(getMap().keySet()).elements();
+    }
+
+    public String getValue(String key, String def) {
+        String val = (String) getMap().get(key);
+        if (val == null) {
+            val = def;
+        }
+        return val;
+    }
+
+    public String[] getValues(String key, String[] def) {
+        String[] val = (String[]) getMap().get(key);
+        if (val == null) {
+            val = def;
+        }
+        return val;
+    }
+
+    public boolean isReadOnly(String arg0) {
+        return false;
+    }
+
+    public void reset(String arg0) throws ReadOnlyException {
+        session.put(PREFERENCES_KEY, new HashMap());
+    }
+
+    public void setValue(String key, String value) throws ReadOnlyException {
+        getMap().put(key, value);
+    }
+
+    public void setValues(String key, String[] value) throws ReadOnlyException {
+        getMap().put(key, value);
+    }
+
+    public void store() throws IOException, ValidatorException {
+        
+    }
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,259 @@
+/*
+ * $Id: PortletActionRedirectResult.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.result;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.portlet.PortletMode;
+
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+import org.apache.struts2.dispatcher.mapper.ActionMapper;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.apache.struts2.portlet.PortletActionConstants;
+import org.apache.struts2.views.util.UrlHelper;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.config.entities.ResultConfig;
+import com.opensymphony.xwork2.inject.Inject;
+
+/**
+ * 
+ * Portlet modification of the {@link ServletActionRedirectResult}.
+ * 
+ * <!-- START SNIPPET: description -->
+ * 
+ * This result uses the {@link ActionMapper} provided by the
+ * {@link ActionMapperFactory} to instruct the render phase to invoke the
+ * specified action and (optional) namespace. This is better than the
+ * {@link PortletResult} because it does not require you to encode the URL
+ * patterns processed by the {@link ActionMapper} in to your struts.xml
+ * configuration files. This means you can change your URL patterns at any point
+ * and your application will still work. It is strongly recommended that if you
+ * are redirecting to another action, you use this result rather than the
+ * standard redirect result.
+ * 
+ * See examples below for an example of how request parameters could be passed
+ * in.
+ * 
+ * <!-- END SNIPPET: description -->
+ * 
+ * <b>This result type takes the following parameters:</b>
+ * 
+ * <!-- START SNIPPET: params -->
+ * 
+ * <ul>
+ * 
+ * <li><b>actionName (default)</b> - the name of the action that will be
+ * redirect to</li>
+ * 
+ * <li><b>namespace</b> - used to determine which namespace the action is in
+ * that we're redirecting to . If namespace is null, this defaults to the
+ * current namespace</li>
+ * 
+ * </ul>
+ * 
+ * <!-- END SNIPPET: params -->
+ * 
+ * <b>Example:</b>
+ * 
+ * <pre>
+ * &lt;!-- START SNIPPET: example --&gt;
+ *  &lt;package name=&quot;public&quot; extends=&quot;struts-default&quot;&gt;
+ *      &lt;action name=&quot;login&quot; class=&quot;...&quot;&gt;
+ *          &lt;!-- Redirect to another namespace --&gt;
+ *          &lt;result type=&quot;redirect-action&quot;&gt;
+ *              &lt;param name=&quot;actionName&quot;&gt;dashboard&lt;/param&gt;
+ *              &lt;param name=&quot;namespace&quot;&gt;/secure&lt;/param&gt;
+ *          &lt;/result&gt;
+ *      &lt;/action&gt;
+ *  &lt;/package&gt;
+ * 
+ *  &lt;package name=&quot;secure&quot; extends=&quot;struts-default&quot; namespace=&quot;/secure&quot;&gt;
+ *      &lt;-- Redirect to an action in the same namespace --&gt;
+ *      &lt;action name=&quot;dashboard&quot; class=&quot;...&quot;&gt;
+ *          &lt;result&gt;dashboard.jsp&lt;/result&gt;
+ *          &lt;result name=&quot;error&quot; type=&quot;redirect-action&quot;&gt;error&lt;/result&gt;
+ *      &lt;/action&gt;
+ * 
+ *      &lt;action name=&quot;error&quot; class=&quot;...&quot;&gt;
+ *          &lt;result&gt;error.jsp&lt;/result&gt;
+ *      &lt;/action&gt;
+ *  &lt;/package&gt;
+ * 
+ *  &lt;package name=&quot;passingRequestParameters&quot; extends=&quot;struts-default&quot; namespace=&quot;/passingRequestParameters&quot;&gt;
+ *     &lt;-- Pass parameters (reportType, width and height) --&gt;
+ *     &lt;!--
+ *     The redirect-action url generated will be :
+ *     /genReport/generateReport.action?reportType=pie&amp;width=100&amp;height=100
+ *     --&gt;
+ *     &lt;action name=&quot;gatherReportInfo&quot; class=&quot;...&quot;&gt;
+ *        &lt;result name=&quot;showReportResult&quot; type=&quot;redirect-action&quot;&gt;
+ *           &lt;param name=&quot;actionName&quot;&gt;generateReport&lt;/param&gt;
+ *           &lt;param name=&quot;namespace&quot;&gt;/genReport&lt;/param&gt;
+ *           &lt;param name=&quot;reportType&quot;&gt;pie&lt;/param&gt;
+ *           &lt;param name=&quot;width&quot;&gt;100&lt;/param&gt;
+ *           &lt;param name=&quot;height&quot;&gt;100&lt;/param&gt;
+ *        &lt;/result&gt;
+ *     &lt;/action&gt;
+ *  &lt;/package&gt;
+ * 
+ * 
+ *  &lt;!-- END SNIPPET: example --&gt;
+ * </pre>
+ * 
+ * @see ActionMapper
+ */
+public class PortletActionRedirectResult extends PortletResult {
+
+	private static final long serialVersionUID = -7627388936683562557L;
+
+	/** The default parameter */
+	public static final String DEFAULT_PARAM = "actionName";
+
+	protected String actionName;
+
+	protected String namespace;
+
+	protected String method;
+
+	private Map<String, String> requestParameters = new LinkedHashMap<String, String>();
+
+	private ActionMapper actionMapper;
+
+	public PortletActionRedirectResult() {
+		super();
+	}
+
+	public PortletActionRedirectResult(String actionName) {
+		this(null, actionName, null);
+	}
+
+	public PortletActionRedirectResult(String actionName, String method) {
+		this(null, actionName, method);
+	}
+
+	public PortletActionRedirectResult(String namespace, String actionName, String method) {
+		super(null);
+		this.namespace = namespace;
+		this.actionName = actionName;
+		this.method = method;
+	}
+
+	protected List<String> prohibitedResultParam = Arrays.asList(new String[] { DEFAULT_PARAM, "namespace", "method",
+			"encode", "parse", "location", "prependServletContext" });
+
+	@Inject
+	public void setActionMapper(ActionMapper actionMapper) {
+		this.actionMapper = actionMapper;
+	}
+
+	/**
+	 * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
+	 */
+	public void execute(ActionInvocation invocation) throws Exception {
+		actionName = conditionalParse(actionName, invocation);
+		String portletNamespace = (String)invocation.getInvocationContext().get(PortletActionConstants.PORTLET_NAMESPACE);
+		if (portletMode != null) {
+			Map<PortletMode, String> namespaceMap = (Map<PortletMode, String>) invocation.getInvocationContext().get(
+					PortletActionConstants.MODE_NAMESPACE_MAP);
+			namespace = namespaceMap.get(portletMode);
+		}
+		if (namespace == null) {
+			namespace = invocation.getProxy().getNamespace();
+		} else {
+			namespace = conditionalParse(namespace, invocation);
+		}
+		if (method == null) {
+			method = "";
+		} else {
+			method = conditionalParse(method, invocation);
+		}
+
+		String resultCode = invocation.getResultCode();
+		if (resultCode != null) {
+			ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode);
+			Map resultConfigParams = resultConfig.getParams();
+			for (Iterator i = resultConfigParams.entrySet().iterator(); i.hasNext();) {
+				Map.Entry e = (Map.Entry) i.next();
+				if (!prohibitedResultParam.contains(e.getKey())) {
+					requestParameters.put(e.getKey().toString(), e.getValue() == null ? "" : conditionalParse(e
+							.getValue().toString(), invocation));
+				}
+			}
+		}
+
+		StringBuffer tmpLocation = new StringBuffer(actionMapper.getUriFromActionMapping(new ActionMapping(actionName,
+				(portletNamespace == null ? namespace : portletNamespace + namespace), method, null)));
+		UrlHelper.buildParametersString(requestParameters, tmpLocation, "&");
+
+		setLocation(tmpLocation.toString());
+
+		super.execute(invocation);
+	}
+
+	/**
+	 * Sets the action name
+	 * 
+	 * @param actionName
+	 *            The name
+	 */
+	public void setActionName(String actionName) {
+		this.actionName = actionName;
+	}
+
+	/**
+	 * Sets the namespace
+	 * 
+	 * @param namespace
+	 *            The namespace
+	 */
+	public void setNamespace(String namespace) {
+		this.namespace = namespace;
+	}
+
+	/**
+	 * Sets the method
+	 * 
+	 * @param method
+	 *            The method
+	 */
+	public void setMethod(String method) {
+		this.method = method;
+	}
+
+	/**
+	 * Adds a request parameter to be added to the redirect url
+	 * 
+	 * @param key
+	 *            The parameter name
+	 * @param value
+	 *            The parameter value
+	 */
+	public PortletActionRedirectResult addParameter(String key, Object value) {
+		requestParameters.put(key, String.valueOf(value));
+		return this;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletResult.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletResult.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletResult.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletResult.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,239 @@
+/*
+ * $Id: PortletResult.java 582626 2007-10-07 13:26:12Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.result;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletException;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.StateAwareResponse;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.dispatcher.StrutsResultSupport;
+import org.apache.struts2.portlet.PortletActionConstants;
+import org.apache.struts2.portlet.context.PortletActionContext;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.TextUtils;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+/**
+ * Result type that includes a JSP to render.
+ * 
+ */
+public class PortletResult extends StrutsResultSupport implements PortletActionConstants {
+
+	private static final long serialVersionUID = 434251393926178567L;
+
+	private boolean useDispatcherServlet;
+	
+	private String dispatcherServletName = DEFAULT_DISPATCHER_SERVLET_NAME;
+
+	/**
+	 * Logger instance.
+	 */
+	private static final Logger LOG = LoggerFactory.getLogger(PortletResult.class);
+
+	private String contentType = "text/html";
+
+	private String title;
+	
+	protected PortletMode portletMode;
+
+	public PortletResult() {
+		super();
+	}
+
+	public PortletResult(String location) {
+		super(location);
+	}
+
+	/**
+	 * Execute the result. Obtains the
+	 * {@link javax.portlet.PortletRequestDispatcher}from the
+	 * {@link PortletActionContext}and includes the JSP.
+	 * 
+	 * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
+	 */
+	public void doExecute(String finalLocation, ActionInvocation actionInvocation) throws Exception {
+
+		if (PortletActionContext.isRender()) {
+			executeRenderResult(finalLocation);
+		} else if (PortletActionContext.isAction() || PortletActionContext.isEvent()) {
+			executeActionResult(finalLocation, actionInvocation);
+		} else {
+			executeRegularServletResult(finalLocation, actionInvocation);
+		}
+	}
+
+	/**
+	 * Executes the regular servlet result.
+	 * 
+	 * @param finalLocation
+	 * @param actionInvocation
+	 */
+	private void executeRegularServletResult(String finalLocation, ActionInvocation actionInvocation)
+			throws ServletException, IOException {
+		ServletContext ctx = ServletActionContext.getServletContext();
+		HttpServletRequest req = ServletActionContext.getRequest();
+		HttpServletResponse res = ServletActionContext.getResponse();
+		try {
+			ctx.getRequestDispatcher(finalLocation).include(req, res);
+		} catch (ServletException e) {
+			LOG.error("ServletException including " + finalLocation, e);
+			throw e;
+		} catch (IOException e) {
+			LOG.error("IOException while including result '" + finalLocation + "'", e);
+			throw e;
+		}
+	}
+
+	/**
+	 * Executes the action result.
+	 * 
+	 * @param finalLocation
+	 * @param invocation
+	 */
+	protected void executeActionResult(String finalLocation, ActionInvocation invocation) throws Exception {
+		LOG.debug("Executing result in Event phase");
+		StateAwareResponse res = (StateAwareResponse)PortletActionContext.getResponse();
+		Map sessionMap = invocation.getInvocationContext().getSession();
+		LOG.debug("Setting event render parameter: " + finalLocation);
+		if (finalLocation.indexOf('?') != -1) {
+			convertQueryParamsToRenderParams(res, finalLocation.substring(finalLocation.indexOf('?') + 1));
+			finalLocation = finalLocation.substring(0, finalLocation.indexOf('?'));
+		}
+		if (finalLocation.endsWith(".action")) {
+			// View is rendered with a view action...luckily...
+			finalLocation = finalLocation.substring(0, finalLocation.lastIndexOf("."));
+			res.setRenderParameter(ACTION_PARAM, finalLocation);
+		} else {
+			// View is rendered outside an action...uh oh...
+			res.setRenderParameter(ACTION_PARAM, "renderDirect");
+			sessionMap.put(RENDER_DIRECT_LOCATION, finalLocation);
+		}
+		if(portletMode != null) {
+			res.setPortletMode(portletMode);
+			res.setRenderParameter(PortletActionConstants.MODE_PARAM, portletMode.toString());
+		}
+		else {
+			res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext.getRequest().getPortletMode()
+					.toString());
+		}
+	}
+
+	/**
+	 * Converts the query params to render params.
+	 * 
+	 * @param response
+	 * @param queryParams
+	 */
+	protected static void convertQueryParamsToRenderParams(StateAwareResponse response, String queryParams) {
+		StringTokenizer tok = new StringTokenizer(queryParams, "&");
+		while (tok.hasMoreTokens()) {
+			String token = tok.nextToken();
+			String key = token.substring(0, token.indexOf('='));
+			String value = token.substring(token.indexOf('=') + 1);
+			response.setRenderParameter(key, value);
+		}
+	}
+
+	/**
+	 * Executes the render result.
+	 * 
+	 * @param finalLocation
+	 * @throws PortletException
+	 * @throws IOException
+	 */
+	protected void executeRenderResult(final String finalLocation) throws PortletException, IOException {
+		LOG.debug("Executing result in Render phase");
+		PortletContext ctx = PortletActionContext.getPortletContext();
+		RenderRequest req = PortletActionContext.getRenderRequest();
+		RenderResponse res = PortletActionContext.getRenderResponse();
+		res.setContentType(contentType);
+		if (TextUtils.stringSet(title)) {
+			res.setTitle(title);
+		}
+		LOG.debug("Location: " + finalLocation);
+		if (useDispatcherServlet) {
+			req.setAttribute(DISPATCH_TO, finalLocation);
+			PortletRequestDispatcher dispatcher = ctx.getNamedDispatcher(dispatcherServletName);
+			if(dispatcher == null) {
+				throw new PortletException("Could not locate dispatcher servlet \"" + dispatcherServletName + "\". Please configure it in your web.xml file");
+			}
+			dispatcher.include(req, res);
+		} else {
+			PortletRequestDispatcher dispatcher = ctx.getRequestDispatcher(finalLocation);
+			if (dispatcher == null) {
+				throw new PortletException("Could not locate dispatcher for '" + finalLocation + "'");
+			}
+			dispatcher.include(req, res);
+		}
+	}
+
+	/**
+	 * Sets the content type.
+	 * 
+	 * @param contentType
+	 *            The content type to set.
+	 */
+	public void setContentType(String contentType) {
+		this.contentType = contentType;
+	}
+
+	/**
+	 * Sets the title.
+	 * 
+	 * @param title
+	 *            The title to set.
+	 */
+	public void setTitle(String title) {
+		this.title = title;
+	}
+	
+	public void setPortletMode(String portletMode) {
+		if(portletMode != null) {
+			this.portletMode = new PortletMode(portletMode);
+		}
+	}
+
+	@Inject("struts.portlet.useDispatcherServlet") 
+	public void setUseDispatcherServlet(String useDispatcherServlet) {
+		this.useDispatcherServlet = "true".equalsIgnoreCase(useDispatcherServlet);
+	}
+	
+	@Inject("struts.portlet.dispatcherServletName")
+	public void setDispatcherServletName(String dispatcherServletName) {
+		this.dispatcherServletName = dispatcherServletName;
+	}
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,288 @@
+/*
+ * $Id: PortletVelocityResult.java 582626 2007-10-07 13:26:12Z mrdon $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.result;
+
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import javax.portlet.ActionResponse;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.PageContext;
+
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.dispatcher.StrutsResultSupport;
+import org.apache.struts2.portlet.PortletActionConstants;
+import org.apache.struts2.portlet.context.PortletActionContext;
+import org.apache.struts2.views.JspSupportServlet;
+import org.apache.struts2.views.velocity.VelocityManager;
+import org.apache.velocity.Template;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.context.Context;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+/**
+ * <!-- START SNIPPET: description -->
+ *
+ * Using the Servlet container's {@link JspFactory}, this result mocks a JSP
+ * execution environment and then displays a Velocity template that will be
+ * streamed directly to the servlet output.
+ *
+ * <!-- END SNIPPET: description --> <p/><b>This result type takes the
+ * following parameters: </b>
+ *
+ * <!-- START SNIPPET: params -->
+ *
+ * <ul>
+ *
+ * <li><b>location (default) </b>- the location of the template to process.
+ * </li>
+ *
+ * <li><b>parse </b>- true by default. If set to false, the location param
+ * will not be parsed for Ognl expressions.</li>
+ *
+ * </ul>
+ * <p>
+ * This result follows the same rules from {@link StrutsResultSupport}.
+ * </p>
+ *
+ * <!-- END SNIPPET: params -->
+ *
+ * <b>Example: </b>
+ *
+ * <pre>
+ * &lt;!-- START SNIPPET: example --&gt;
+ *  &lt;result name=&quot;success&quot; type=&quot;velocity&quot;&gt;
+ *    &lt;param name=&quot;location&quot;&gt;foo.vm&lt;/param&gt;
+ *  &lt;/result&gt;
+ *  &lt;!-- END SNIPPET: example --&gt;
+ * </pre>
+ *
+ */
+public class PortletVelocityResult extends StrutsResultSupport {
+
+    private static final long serialVersionUID = -8241086555872212274L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(PortletVelocityResult.class);
+    
+    private String defaultEncoding;
+    private VelocityManager velocityManager;
+    public PortletVelocityResult() {
+        super();
+    }
+
+    public PortletVelocityResult(String location) {
+        super(location);
+    }
+    
+    @Inject
+    public void setVelocityManager(VelocityManager mgr) {
+        this.velocityManager = mgr;
+    }
+    
+    @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
+    public void setDefaultEncoding(String encoding) {
+        this.defaultEncoding = encoding;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.struts2.dispatcher.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation)
+     */
+    public void doExecute(String location, ActionInvocation invocation)
+            throws Exception {
+        if (PortletActionContext.isAction()) {
+            executeActionResult(location, invocation);
+        } else if (PortletActionContext.isRender()) {
+            executeRenderResult(location, invocation);
+        }
+    }
+
+    /**
+     * Executes the result
+     *
+     * @param location The location string
+     * @param invocation The action invocation
+     */
+    private void executeActionResult(String location,
+            ActionInvocation invocation) {
+        ActionResponse res = PortletActionContext.getActionResponse();
+        // View is rendered outside an action...uh oh...
+        res.setRenderParameter(PortletActionConstants.ACTION_PARAM,
+                "freemarkerDirect");
+        res.setRenderParameter("location", location);
+        res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext
+                .getRequest().getPortletMode().toString());
+
+    }
+
+    /**
+     * Creates a Velocity context from the action, loads a Velocity template and
+     * executes the template. Output is written to the servlet output stream.
+     *
+     * @param finalLocation the location of the Velocity template
+     * @param invocation an encapsulation of the action execution state.
+     * @throws Exception if an error occurs when creating the Velocity context,
+     *         loading or executing the template or writing output to the
+     *         servlet response stream.
+     */
+    public void executeRenderResult(String finalLocation,
+            ActionInvocation invocation) throws Exception {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+
+        HttpServletRequest request = ServletActionContext.getRequest();
+        HttpServletResponse response = ServletActionContext.getResponse();
+        JspFactory jspFactory = null;
+        ServletContext servletContext = ServletActionContext
+                .getServletContext();
+        Servlet servlet = JspSupportServlet.jspSupportServlet;
+
+        velocityManager.init(servletContext);
+
+        boolean usedJspFactory = false;
+        PageContext pageContext = (PageContext) ActionContext.getContext().get(
+                ServletActionContext.PAGE_CONTEXT);
+
+        if (pageContext == null && servlet != null) {
+            jspFactory = JspFactory.getDefaultFactory();
+            pageContext = jspFactory.getPageContext(servlet, request, response,
+                    null, true, 8192, true);
+            ActionContext.getContext().put(ServletActionContext.PAGE_CONTEXT,
+                    pageContext);
+            usedJspFactory = true;
+        }
+
+        try {
+            String encoding = getEncoding(finalLocation);
+            String contentType = getContentType(finalLocation);
+
+            if (encoding != null) {
+                contentType = contentType + ";charset=" + encoding;
+            }
+            response.setContentType(contentType);
+            Template t = getTemplate(stack,
+                    velocityManager.getVelocityEngine(), invocation,
+                    finalLocation, encoding);
+
+            Context context = createContext(velocityManager, stack, request,
+                    response, finalLocation);
+            Writer writer = new OutputStreamWriter(response.getOutputStream(),
+                    encoding);
+
+            t.merge(context, writer);
+
+            // always flush the writer (we used to only flush it if this was a
+            // jspWriter, but someone asked
+            // to do it all the time (WW-829). Since Velocity support is being
+            // deprecated, we'll oblige :)
+            writer.flush();
+        } catch (Exception e) {
+            LOG.error("Unable to render Velocity Template, '" + finalLocation
+                    + "'", e);
+            throw e;
+        } finally {
+            if (usedJspFactory) {
+                jspFactory.releasePageContext(pageContext);
+            }
+        }
+
+        return;
+    }
+
+    /**
+     * Retrieve the content type for this template. <p/>People can override
+     * this method if they want to provide specific content types for specific
+     * templates (eg text/xml).
+     *
+     * @return The content type associated with this template (default
+     *         "text/html")
+     */
+    protected String getContentType(String templateLocation) {
+        return "text/html";
+    }
+
+    /**
+     * Retrieve the encoding for this template. <p/>People can override this
+     * method if they want to provide specific encodings for specific templates.
+     *
+     * @return The encoding associated with this template (defaults to the value
+     *         of 'struts.i18n.encoding' property)
+     */
+    protected String getEncoding(String templateLocation) {
+        String encoding = defaultEncoding;
+        if (encoding == null) {
+            encoding = System.getProperty("file.encoding");
+        }
+        if (encoding == null) {
+            encoding = "UTF-8";
+        }
+        return encoding;
+    }
+
+    /**
+     * Given a value stack, a Velocity engine, and an action invocation, this
+     * method returns the appropriate Velocity template to render.
+     *
+     * @param stack the value stack to resolve the location again (when parse
+     *        equals true)
+     * @param velocity the velocity engine to process the request against
+     * @param invocation an encapsulation of the action execution state.
+     * @param location the location of the template
+     * @param encoding the charset encoding of the template
+     * @return the template to render
+     * @throws Exception when the requested template could not be found
+     */
+    protected Template getTemplate(ValueStack stack,
+            VelocityEngine velocity, ActionInvocation invocation,
+            String location, String encoding) throws Exception {
+        if (!location.startsWith("/")) {
+            location = invocation.getProxy().getNamespace() + "/" + location;
+        }
+
+        Template template = velocity.getTemplate(location, encoding);
+
+        return template;
+    }
+
+    /**
+     * Creates the VelocityContext that we'll use to render this page.
+     *
+     * @param velocityManager a reference to the velocityManager to use
+     * @param stack the value stack to resolve the location against (when parse
+     *        equals true)
+     * @param location the name of the template that is being used
+     * @return the a minted Velocity context.
+     */
+    protected Context createContext(VelocityManager velocityManager,
+            ValueStack stack, HttpServletRequest request,
+            HttpServletResponse response, String location) {
+        return velocityManager.createContext(stack, request, response);
+    }
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletHttpSession.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletHttpSession.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletHttpSession.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletHttpSession.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,214 @@
+/*
+ * $Id: PortletHttpSession.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.servlet;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.portlet.PortletSession;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+
+/**
+ * Wrapper object exposing a {@link PortletSession} as a {@link HttpSession} instance.
+ * Clients accessing this session object will in fact operate on the
+ * {@link PortletSession} object wrapped by this session object.
+ */
+public class PortletHttpSession implements HttpSession {
+
+	private PortletSession portletSession;
+
+	public PortletHttpSession(PortletSession portletSession) {
+		this.portletSession = portletSession;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
+	 */
+	public Object getAttribute(String name) {
+		return portletSession.getAttribute(name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getAttributeNames()
+	 */
+	public Enumeration getAttributeNames() {
+		return portletSession.getAttributeNames();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getCreationTime()
+	 */
+	public long getCreationTime() {
+		return portletSession.getCreationTime();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getId()
+	 */
+	public String getId() {
+		return portletSession.getId();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getLastAccessedTime()
+	 */
+	public long getLastAccessedTime() {
+		return portletSession.getLastAccessedTime();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
+	 */
+	public int getMaxInactiveInterval() {
+		return portletSession.getMaxInactiveInterval();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getServletContext()
+	 */
+	public ServletContext getServletContext() {
+		return new PortletServletContext(portletSession.getPortletContext());
+	}
+
+	/**
+	 * @see javax.servlet.http.HttpSession#getSessionContext()
+	 * @throws IllegalStateException
+	 *             Not supported in a portlet.
+	 */
+	public HttpSessionContext getSessionContext() {
+		throw new IllegalStateException("Not supported in a portlet");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getValue(java.lang.String)
+	 */
+	public Object getValue(String name) {
+		return getAttribute(name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#getValueNames()
+	 */
+	public String[] getValueNames() {
+		List<String> names = new ArrayList<String>();
+		Enumeration attrNames = getAttributeNames();
+		while (attrNames.hasMoreElements()) {
+			names.add((String) attrNames.nextElement());
+		}
+		return names.toArray(new String[0]);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#invalidate()
+	 */
+	public void invalidate() {
+		portletSession.invalidate();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#isNew()
+	 */
+	public boolean isNew() {
+		return portletSession.isNew();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#putValue(java.lang.String,
+	 *      java.lang.Object)
+	 */
+	public void putValue(String name, Object value) {
+		setAttribute(name, value);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#removeAttribute(java.lang.String)
+	 */
+	public void removeAttribute(String name) {
+		portletSession.removeAttribute(name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#removeValue(java.lang.String)
+	 */
+	public void removeValue(String name) {
+		removeAttribute(name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#setAttribute(java.lang.String,
+	 *      java.lang.Object)
+	 */
+	public void setAttribute(String name, Object value) {
+		portletSession.setAttribute(name, value);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.servlet.http.HttpSession#setMaxInactiveInterval(int)
+	 */
+	public void setMaxInactiveInterval(int interval) {
+		portletSession.setMaxInactiveInterval(interval);
+	}
+
+	/**
+	 * Get the wrapped portlet session.
+	 * 
+	 * @return The wrapped portlet session.
+	 */
+	public PortletSession getPortletSession() {
+		return portletSession;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletConfig.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletConfig.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletConfig.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletConfig.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,81 @@
+/*
+ * $Id: PortletServletConfig.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.servlet;
+
+import java.util.Enumeration;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletContext;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ * Wrapper object exposing a {@link PortletConfig} as a {@link ServletConfig} instance.
+ * Clients accessing this config object will in fact operate on the
+ * {@link PortletConfig} object wrapped by this config object.
+ */
+public class PortletServletConfig implements ServletConfig {
+
+	private PortletConfig portletConfig;
+	
+	public PortletServletConfig(PortletConfig portletConfig) {
+		this.portletConfig = portletConfig;
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String)
+	 */
+	public String getInitParameter(String name) {
+		return portletConfig.getInitParameter(name);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletConfig#getInitParameterNames()
+	 */
+	public Enumeration getInitParameterNames() {
+		return portletConfig.getInitParameterNames();
+	}
+
+	/**
+	 * Get the {@link PortletContext} as a {@link PortletServletContext} instance.
+	 * @see javax.servlet.ServletConfig#getServletContext()
+	 */
+	public ServletContext getServletContext() {
+		return new PortletServletContext(portletConfig.getPortletContext());
+	}
+
+	/**
+	 * Will return the portlet name.
+	 * @see javax.servlet.ServletConfig#getServletName()
+	 */
+	public String getServletName() {
+		return portletConfig.getPortletName();
+	}
+	
+	/**
+	 * Get the wrapped {@link PortletConfig} instance.
+	 * @return The wrapped {@link PortletConfig} instance.
+	 */
+	public PortletConfig getPortletConfig() {
+		return portletConfig;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletContext.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletContext.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletContext.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletContext.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,235 @@
+/*
+ * $Id: PortletServletContext.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.servlet;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequestDispatcher;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * Wrapper object exposing a {@link PortletContext} as a {@link ServletContext} instance.
+ * Clients accessing this context object will in fact operate on the
+ * {@link PortletContext} object wrapped by this context object.
+ */
+public class PortletServletContext implements ServletContext {
+
+	private PortletContext portletContext;
+	
+	public PortletServletContext(PortletContext portletContext) {
+		this.portletContext = portletContext;
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+	 */
+	public Object getAttribute(String name) {
+		return portletContext.getAttribute(name);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getAttributeNames()
+	 */
+	public Enumeration getAttributeNames() {
+		return portletContext.getAttributeNames();
+	}
+
+	/**
+	 * @see javax.servlet.ServletContext#getContext(java.lang.String)
+	 * @throws IllegalStateException Not supported in a portlet.
+	 */
+	public ServletContext getContext(String uripath) {
+		throw new IllegalStateException("Not supported in a portlet");
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+	 */
+	public String getInitParameter(String name) {
+		return portletContext.getInitParameter(name);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getInitParameterNames()
+	 */
+	public Enumeration getInitParameterNames() {
+		return portletContext.getInitParameterNames();
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getMajorVersion()
+	 */
+	public int getMajorVersion() {
+		return portletContext.getMajorVersion();
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+	 */
+	public String getMimeType(String file) {
+		return portletContext.getMimeType(file);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getMinorVersion()
+	 */
+	public int getMinorVersion() {
+		return portletContext.getMinorVersion();
+	}
+
+	/**
+	 * Returns a {@link PortletServletRequestDispatcher} wrapping the {@link PortletRequestDispatcher}
+	 * as a {@link RequestDispatcher} instance.
+	 * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+	 * @return PortletServletRequestDispatcher
+	 */
+	public RequestDispatcher getNamedDispatcher(String name) {
+		return new PortletServletRequestDispatcher(portletContext.getNamedDispatcher(name));
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+	 */
+	public String getRealPath(String path) {
+		return portletContext.getRealPath(path);
+	}
+
+	/**
+	 * Returns a {@link PortletServletRequestDispatcher} wrapping the {@link PortletRequestDispatcher}
+	 * as a {@link RequestDispatcher} instance.
+	 * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+	 * @return PortletServletRequestDispatcher
+	 */
+	public RequestDispatcher getRequestDispatcher(String path) {
+		return new PortletServletRequestDispatcher(portletContext.getRequestDispatcher(path));
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getResource(java.lang.String)
+	 */
+	public URL getResource(String path) throws MalformedURLException {
+		return portletContext.getResource(path);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+	 */
+	public InputStream getResourceAsStream(String path) {
+		return portletContext.getResourceAsStream(path);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+	 */
+	public Set getResourcePaths(String path) {
+		return portletContext.getResourcePaths(path);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getServerInfo()
+	 */
+	public String getServerInfo() {
+		return portletContext.getServerInfo();
+	}
+
+	/**
+	 * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+	 * @throws IllegalStateException Not supported in a portlet.
+	 */
+	public Servlet getServlet(String name) throws ServletException {
+		throw new IllegalStateException("Not allowed in a portlet");
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#getServletContextName()
+	 */
+	public String getServletContextName() {
+		return portletContext.getPortletContextName();
+	}
+
+	/**
+	 * @see javax.servlet.ServletContext#getServletNames()
+ 	 * @throws IllegalStateException Not supported in a portlet.
+	 */
+	public Enumeration getServletNames() {
+		throw new IllegalStateException("Not allowed in a portlet");
+	}
+
+	/**
+	 * @see javax.servlet.ServletContext#getServlets()
+	 * @throws IllegalStateException Not supported in a portlet.
+	 */
+	public Enumeration getServlets() {
+		throw new IllegalStateException("Not allowed in a portlet");
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#log(java.lang.String)
+	 */
+	public void log(String msg) {
+		portletContext.log(msg);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String)
+	 */
+	public void log(Exception exception, String msg) {
+		log(msg, exception);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable)
+	 */
+	public void log(String message, Throwable throwable) {
+		portletContext.log(message, throwable);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+	 */
+	public void removeAttribute(String name) {
+		portletContext.removeAttribute(name);
+	}
+
+	/* (non-Javadoc)
+	 * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object)
+	 */
+	public void setAttribute(String name, Object object) {
+		portletContext.setAttribute(name, object);
+	}
+	
+	/**
+	 * Get the wrapped {@link PortletContext} instance.
+	 * @return The wrapped {@link PortletContext} instance.
+	 */
+	public PortletContext getPortletContext() {
+		return portletContext;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletInputStream.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletInputStream.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletInputStream.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletInputStream.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,121 @@
+/*
+ * $Id: PortletServletInputStream.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletInputStream;
+
+/**
+ * Wrapper object exposing a {@link InputStream} from a portlet as a {@link ServletInputStream} instance.
+ * Clients accessing this stream object will in fact operate on the
+ * {@link InputStream} object wrapped by this stream object.
+ */
+public class PortletServletInputStream extends ServletInputStream {
+
+	private InputStream portletInputStream;
+	
+	public PortletServletInputStream(InputStream portletInputStream) {
+		this.portletInputStream = portletInputStream;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#read()
+	 */
+	@Override
+	public int read() throws IOException {
+		return portletInputStream.read();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#available()
+	 */
+	@Override
+	public int available() throws IOException {
+		return portletInputStream.available();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#close()
+	 */
+	@Override
+	public void close() throws IOException {
+		portletInputStream.close();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#mark(int)
+	 */
+	@Override
+	public synchronized void mark(int readlimit) {
+		portletInputStream.mark(readlimit);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#markSupported()
+	 */
+	@Override
+	public boolean markSupported() {
+		return portletInputStream.markSupported();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#read(byte[], int, int)
+	 */
+	@Override
+	public int read(byte[] b, int off, int len) throws IOException {
+		return portletInputStream.read(b, off, len);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#read(byte[])
+	 */
+	@Override
+	public int read(byte[] b) throws IOException {
+		return portletInputStream.read(b);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#reset()
+	 */
+	@Override
+	public synchronized void reset() throws IOException {
+		portletInputStream.reset();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.InputStream#skip(long)
+	 */
+	@Override
+	public long skip(long n) throws IOException {
+		return portletInputStream.skip(n);
+	}
+	
+	/**
+	 * Get the wrapped {@link InputStream} instance.
+	 * @return The wrapped {@link InputStream} instance.
+	 */
+	public InputStream getInputStream() {
+		return portletInputStream;
+	}
+
+}

Added: struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletOutputStream.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletOutputStream.java?rev=613823&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletOutputStream.java (added)
+++ struts/sandbox/trunk/struts2-portlet2-plugin/src/main/java/org/apache/struts2/portlet/servlet/PortletServletOutputStream.java Mon Jan 21 02:09:00 2008
@@ -0,0 +1,88 @@
+/*
+ * $Id: PortletServletOutputStream.java 590812 2007-10-31 20:32:54Z apetrelli $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.struts2.portlet.servlet;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletOutputStream;
+
+/**
+ * Wrapper object exposing a {@link OutputStream} from a portlet as a {@link ServletOutputStream} instance.
+ * Clients accessing this stream object will in fact operate on the
+ * {@link OutputStream} object wrapped by this stream object.
+ */
+public class PortletServletOutputStream extends ServletOutputStream {
+
+	private OutputStream portletOutputStream;
+	
+	public PortletServletOutputStream(OutputStream portletOutputStream) {
+		this.portletOutputStream = portletOutputStream;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.OutputStream#write(int)
+	 */
+	@Override
+	public void write(int ch) throws IOException {
+		portletOutputStream.write(ch);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.OutputStream#close()
+	 */
+	@Override
+	public void close() throws IOException {
+		portletOutputStream.close();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.OutputStream#flush()
+	 */
+	@Override
+	public void flush() throws IOException {
+		portletOutputStream.flush();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.OutputStream#write(byte[])
+	 */
+	@Override
+	public void write(byte[] b) throws IOException {
+		portletOutputStream.write(b);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.io.OutputStream#write(byte[], int, int)
+	 */
+	@Override
+	public void write(byte[] b, int off, int len) throws IOException {
+		portletOutputStream.write(b, off, len);
+	}
+	
+	/**
+	 * Get the wrapped {@link OutputStream} instance.
+	 * @return The wrapped {@link OutputStream} instance.
+	 */
+	public OutputStream getOutputStream() {
+		return portletOutputStream;
+	}
+}