You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by cd...@apache.org on 2006/10/26 13:55:23 UTC

svn commit: r467968 - in /portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal: ./ impl/

Author: cdoremus
Date: Thu Oct 26 04:55:22 2006
New Revision: 467968

URL: http://svn.apache.org/viewvc?view=rev&rev=467968
Log:
Implementations for JSR-286 support. Some methods are stubbed out and throw an UnsupportedOperationException to make sure we don't forget about them.

Added:
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/InternalEventResponse.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/BaseURLImpl.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/CacheControlImpl.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventImpl.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventResponseImpl.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/ResourceURLImpl.java
    portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/StateAwareResponseImpl.java

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/InternalEventResponse.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/InternalEventResponse.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/InternalEventResponse.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/InternalEventResponse.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 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.pluto.internal;
+
+ /** 
+  * The internal event response interface extends the internal portlet response
+  * interface and provides some event-specific methods.
+  *
+  * @since 2.0
+ */
+public interface InternalEventResponse extends InternalPortletResponse {
+
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/BaseURLImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/BaseURLImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/BaseURLImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/BaseURLImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2003,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.pluto.internal.impl;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.portlet.BaseURL;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.PortletSecurityException;
+import javax.portlet.WindowState;
+
+import org.apache.pluto.PortletContainer;
+import org.apache.pluto.descriptors.portlet.PortletDD;
+import org.apache.pluto.descriptors.portlet.SupportsDD;
+import org.apache.pluto.internal.InternalPortletWindow;
+import org.apache.pluto.spi.PortletURLProvider;
+import org.apache.pluto.util.StringManager;
+import org.apache.pluto.util.StringUtils;
+
+/**
+ * Implementation of JSR-286 <code>BaseURL</code>, which includes a refactoring
+ * of <code>PortletURLImpl</code>.
+ *
+ * @since 2.0
+ */
+public class BaseURLImpl implements BaseURL {
+
+	private static final StringManager EXCEPTIONS = StringManager.getManager(PortletURLImpl.class.getPackage().getName());
+	protected Map parameters = new HashMap();
+	protected boolean secure;
+	protected PortletContainer container;
+	protected PortletMode mode = null;
+	protected InternalPortletWindow internalPortletWindow;
+	protected javax.servlet.http.HttpServletRequest servletRequest;
+	protected javax.servlet.http.HttpServletResponse servletResponse;
+	protected WindowState state;
+	protected boolean isAction;
+	protected boolean isResourceServing;
+	protected PortalContext context;
+	
+	public BaseURLImpl(PortletContainer container,
+			InternalPortletWindow internalPortletWindow,
+			javax.servlet.http.HttpServletRequest servletRequest,
+			javax.servlet.http.HttpServletResponse servletResponse,
+			boolean isAction, boolean isResourceServing) {
+		this.container = container;
+		this.internalPortletWindow = internalPortletWindow;
+		this.servletRequest = servletRequest;
+		this.servletResponse = servletResponse;
+		secure = servletRequest.isSecure();
+		this.isAction = isAction;
+		this.isResourceServing = isResourceServing;
+		this.context = container.getRequiredContainerServices().getPortalContext();
+	}
+
+	public void setParameter(String name, String value) {
+	    if (name == null || value == null) {
+	        throw new IllegalArgumentException(
+	            "name and value must not be null");
+	    }
+	
+	    parameters.put(name, new String[]{value});
+	}
+
+	public void setParameter(String name, String[] values) {
+	    if (name == null || values == null || values.length == 0) {
+	        throw new IllegalArgumentException(
+	            "name and values must not be null or values be an empty array");
+	    }
+	
+	    parameters.put(name, StringUtils.copy(values));
+	}
+
+	public void setParameters(Map parameters) {
+	    if (parameters == null) {
+	        throw new IllegalArgumentException("Parameters must not be null.");
+	    }
+	    for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
+	        Map.Entry entry = (Map.Entry) it.next();
+	        if (!(entry.getKey() instanceof String)) {
+	            throw new IllegalArgumentException(
+	                "Key must not be null and of type java.lang.String.");
+	        }
+	        if (!(entry.getValue() instanceof String[])) {
+	            throw new IllegalArgumentException(
+	                "Value must not be null and of type java.lang.String[].");
+	        }
+	    }
+	
+	    this.parameters = StringUtils.copyParameters(parameters);
+	}
+
+	public void setSecure(boolean secure) throws PortletSecurityException {
+	    this.secure = secure;
+	}
+
+	public String toString() {
+	    StringBuffer url = new StringBuffer(200);
+	
+	    PortletURLProvider urlProvider = container
+	    		.getRequiredContainerServices()
+	    		.getPortalCallbackService()
+	    		.getPortletURLProvider(servletRequest, internalPortletWindow);
+	
+	    if (mode != null) {
+	        urlProvider.setPortletMode(mode);
+	    }
+	    if (state != null) {
+	        urlProvider.setWindowState(state);
+	    }
+	    if (isAction) {
+	        urlProvider.setAction(true);
+	    }
+	    if (isResourceServing){
+	    	urlProvider.setResourceServing(true);
+	    }
+	    if (secure) {
+	        urlProvider.setSecure();
+	    }
+	    urlProvider.clearParameters();
+	    urlProvider.setParameters(parameters);
+	
+	    url.append(urlProvider.toString());
+	
+	    return url.toString();
+	}
+	// --------------------------------------------------------------------------------------------
+
+	public String getParameter(String name) {
+	    return (String) parameters.get(name);
+	}
+
+	public String[] getParameters(String name) {
+	    return (String[]) parameters.get(name);
+	}
+
+	public PortletMode getPortletMode() {
+	    return mode;
+	}
+
+	public WindowState getWindowState() {
+	    return state;
+	}
+	// --------------------------------------------------------------------------------------------
+
+	protected boolean isPortletModeAllowed(PortletMode mode) throws PortletModeException {
+	    if (mode == null) {
+	        throw new PortletModeException(
+	            EXCEPTIONS.getString("javax.portlet.PortletModeException.null"),
+	            null);
+	    }
+	
+	    return isPortletModeAllowedByPortlet(mode)
+	           && isPortletModeAllowedByPortal(mode);
+	}
+
+	private boolean isPortletModeAllowedByPortlet(PortletMode mode) throws PortletModeException {
+	    // PLT 8.1: View Portlet Mode should always be
+	    // supported by a portlet, even if not defined in the descriptor
+	    if (mode.equals(PortletMode.VIEW)) {
+	        return true;
+	    }
+	
+	    PortletDD dd = internalPortletWindow.getPortletEntity()
+	        .getPortletDefinition();
+	    Iterator supports = dd.getSupports().iterator();
+	    while(supports.hasNext()) {
+	        SupportsDD support = (SupportsDD)supports.next();
+	        Iterator modes = support.getPortletModes().iterator();
+	        while(modes.hasNext()) {
+	            String md = (String)modes.next();
+	            if (md.toUpperCase().equals(
+	                mode.toString().toUpperCase())) {
+	                return true;
+	            }
+	        }
+	    }
+	    String message = EXCEPTIONS.getString(
+	        "javax.portlet.PortletModeException.portlet", mode.toString());
+	
+	    throw new PortletModeException(message, mode);
+	}
+
+	private boolean isPortletModeAllowedByPortal(PortletMode mode) throws PortletModeException {
+	    Enumeration supportedModes = context.getSupportedPortletModes();
+	    while (supportedModes.hasMoreElements()) {
+	        if (supportedModes.nextElement().toString().toUpperCase().equals(
+	            (mode.toString().toUpperCase()))) {
+	            return true;
+	        }
+	    }
+	    String message = EXCEPTIONS.getString(
+	        "javax.portlet.PortletModeException.portal", mode.toString());
+	
+	    throw new PortletModeException(message, mode);
+	}
+
+	protected boolean isWindowStateAllowed(WindowState state) {
+	    Enumeration supportedStates = context.getSupportedWindowStates();
+	    while (supportedStates.hasMoreElements()) {
+	        if (supportedStates.nextElement().toString().toUpperCase().equals(
+	            (state.toString().toUpperCase()))) {
+	            return true;
+	        }
+	    }
+	    return false;
+	}
+
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/CacheControlImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/CacheControlImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/CacheControlImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/CacheControlImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2003,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.pluto.internal.impl;
+
+import javax.portlet.CacheControl;
+
+/**
+ * Implementation of JSR-286 <code>CacheControl</code>.
+ *
+ * @since 2.0
+ * TODO: Implement this class ;-)
+ */
+public class CacheControlImpl implements CacheControl {
+
+	public String getETag() {
+		// TODO Auto-generated method stub
+//		return null;
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public long getExpirationTime() {
+		// TODO Auto-generated method stub
+//		return 0;
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public boolean isPublicScope() {
+		// TODO Auto-generated method stub
+//		return false;
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public void setETag(String arg0) {
+		// TODO Auto-generated method stub
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public void setExpirationTime(long arg0) {
+		// TODO Auto-generated method stub
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public void setPublicScope(boolean arg0) {
+		// TODO Auto-generated method stub
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public void setUseCachedContent(boolean arg0) {
+		// TODO Auto-generated method stub
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public boolean useCachedContent() {
+		// TODO Auto-generated method stub
+//		return false;
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2003,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.pluto.internal.impl;
+
+import javax.portlet.Event;
+
+/**
+ * Implementation of JSR-286 <code>Event</code>.
+ *
+ * @since 2.0
+ */
+public class EventImpl implements Event {
+
+	private String _name;
+	private Object _value;
+	
+	public EventImpl(String name){
+		_name = name;
+	}
+	
+	public EventImpl(String name, Object value){
+		this(name);
+		_value = value;
+	}
+
+	public String getName() {
+		return _name;
+	}
+
+	public Object getValue() {
+		return _value;
+	}
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventResponseImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventResponseImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventResponseImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/EventResponseImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2003,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.pluto.internal.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.portlet.EventResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.pluto.PortletContainer;
+import org.apache.pluto.internal.InternalEventResponse;
+import org.apache.pluto.internal.InternalPortletWindow;
+
+/**
+ * Implementation of JSR-286 <code>EventResponse</code>.
+ *
+ * @since 2.0
+ */
+
+public class EventResponseImpl extends StateAwareResponseImpl
+	implements EventResponse,InternalEventResponse {
+
+    public EventResponseImpl(PortletContainer container,
+                              InternalPortletWindow internalPortletWindow,
+                              HttpServletRequest servletRequest,
+                              HttpServletResponse servletResponse) {
+        super(container, internalPortletWindow, servletRequest,
+              servletResponse);
+    }
+
+	
+
+	public ServletOutputStream getOutputStream() throws IOException {
+		// TODO Auto-generated method stub
+//		return null;
+		throw new UnsupportedOperationException("This method needs to be implemented.");
+	}
+
+	public PrintWriter getWriter() throws IOException {
+		// TODO Auto-generated method stub
+//		return null;
+		throw new UnsupportedOperationException();
+	}
+
+
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/ResourceURLImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/ResourceURLImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/ResourceURLImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/ResourceURLImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 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.pluto.internal.impl;
+
+import javax.portlet.ResourceURL;
+
+import org.apache.pluto.PortletContainer;
+import org.apache.pluto.internal.InternalPortletWindow;
+
+/**
+ * Implementation of JSR-286 <code>ResourceURL</code>.
+ *
+ * @since 2.0
+ */
+public class ResourceURLImpl extends BaseURLImpl implements ResourceURL {
+	public ResourceURLImpl(PortletContainer container,
+	        InternalPortletWindow internalPortletWindow,
+	        javax.servlet.http.HttpServletRequest servletRequest,
+	        javax.servlet.http.HttpServletResponse servletResponse) {
+			super(container,internalPortletWindow,servletRequest,
+				servletResponse,false,true);
+	}
+}

Added: portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/StateAwareResponseImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/StateAwareResponseImpl.java?view=auto&rev=467968
==============================================================================
--- portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/StateAwareResponseImpl.java (added)
+++ portals/pluto/branches/1.1-286-COMPATIBILITY/pluto-container/src/main/java/org/apache/pluto/internal/impl/StateAwareResponseImpl.java Thu Oct 26 04:55:22 2006
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2006 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.pluto.internal.impl;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.StateAwareResponse;
+import javax.portlet.WindowState;
+import javax.portlet.WindowStateException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.apache.pluto.PortletContainer;
+import org.apache.pluto.descriptors.portlet.PortletDD;
+import org.apache.pluto.descriptors.portlet.SupportsDD;
+import org.apache.pluto.internal.InternalPortletWindow;
+import org.apache.pluto.spi.PortalCallbackService;
+import org.apache.pluto.spi.ResourceURLProvider;
+import org.apache.pluto.util.StringUtils;
+
+/**
+ * Implementation of JSR-286 <code>StateAwareResponse</code>.
+ *
+ * @since 2.0
+ */
+public class StateAwareResponseImpl extends PortletResponseImpl implements
+		StateAwareResponse {
+
+	boolean redirectAllowed = true;
+	private boolean redirected;
+	private String redirectLocation;
+    
+
+    private Map renderParameters = new HashMap();
+    private WindowState windowState = null;
+    private PortletMode portletMode = null;
+	private PortalCallbackService callback;
+    private PortalContext context;
+    
+	public StateAwareResponseImpl(PortletContainer container,
+			            InternalPortletWindow internalPortletWindow,
+			            HttpServletRequest servletRequest,
+			            HttpServletResponse servletResponse) {
+		super(container, internalPortletWindow, servletRequest,
+		servletResponse);
+		context = container.getRequiredContainerServices().getPortalContext();
+		callback = container.getRequiredContainerServices().getPortalCallbackService();
+	}
+	public void setEvent(String name, Object value) {
+		
+	}
+
+	public void setEvents(Map events) {
+		
+	}
+
+	public void sendRedirect(String location) throws java.io.IOException {
+        if (redirectAllowed) {
+            if (location != null) {
+                HttpServletResponse redirectResponse = getHttpServletResponse();
+                while (redirectResponse instanceof HttpServletResponseWrapper) {
+                    redirectResponse = (HttpServletResponse)
+                        ((HttpServletResponseWrapper)redirectResponse).getResponse();
+                }
+
+                ResourceURLProvider provider = callback.getResourceURLProvider(
+                                getHttpServletRequest(),
+                                getInternalPortletWindow()
+                );
+
+                if (location.indexOf("://") != -1) {
+                    provider.setAbsoluteURL(location);
+                } else {
+                    provider.setFullPath(location);
+                }
+                location =
+                redirectResponse.encodeRedirectURL(provider.toString());
+                //redirectResponse.sendRedirect(location);
+                redirectLocation = location;
+                redirected = true;
+            }
+        } else {
+            throw new java.lang.IllegalStateException(
+                "Can't invoke sendRedirect() after certain methods have been called");
+        }
+
+    }
+
+    
+
+    public String getRedirectLocation() {
+        return redirectLocation;
+    }
+	//
+//	 javax.portlet.ActionResponse
+	//
+    public void setWindowState(WindowState windowState)
+        throws WindowStateException {
+        if (redirected) {
+            throw new IllegalStateException(
+                "it is not allowed to invoke setWindowState after sendRedirect has been called");
+        }
+
+        if (isWindowStateAllowed(windowState)) {
+            this.windowState = windowState;
+        } else {
+            throw new WindowStateException("Can't set this WindowState",
+                                           windowState);
+        }
+        redirectAllowed = false;
+    }
+	    
+    public void setPortletMode(PortletMode portletMode)
+        throws PortletModeException {
+        if (redirected) {
+            throw new IllegalStateException(
+                "it is not allowed to invoke setPortletMode after sendRedirect has been called");
+        }
+
+        // check if portal supports portlet mode
+        boolean supported = isPortletModeAllowed(portletMode);
+
+
+        // if porlet mode is allowed
+        if (supported) {
+            this.portletMode = portletMode;
+        } else {
+            throw new PortletModeException("Can't set this PortletMode",
+                                           portletMode);
+        }
+
+        redirectAllowed = false;
+
+    }
+    
+    public void setRenderParameters(Map parameters) {
+        if (redirected) {
+            throw new IllegalStateException(
+                "Can't invoke setRenderParameters() after sendRedirect() has been called");
+        }
+        if (parameters == null) {
+            throw new IllegalArgumentException(
+                "Render parameters must not be null.");
+        }
+        for (Iterator iter = parameters.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            if (!(entry.getKey() instanceof String)) {
+                throw new IllegalArgumentException(
+                    "Key must not be null and of type java.lang.String.");
+            }
+            if (!(entry.getValue() instanceof String[])) {
+                throw new IllegalArgumentException(
+                    "Value must not be null and of type java.lang.String[].");
+            }
+        }
+
+        renderParameters = StringUtils.copyParameters(parameters);
+
+        redirectAllowed = false;
+    }
+    
+    public void setRenderParameter(String key, String value) {
+        if (redirected) {
+            throw new IllegalStateException(
+                "Can't invoke setRenderParameter() after sendRedirect() has been called");
+        }
+
+        if ((key == null) || (value == null)) {
+            throw new IllegalArgumentException(
+                "Render parameter key or value must not be null.");
+        }
+
+        renderParameters.put(key, new String[]{value});
+
+        redirectAllowed = false;
+    }
+    
+    public void setRenderParameter(String key, String[] values) {
+        if (redirected) {
+            throw new IllegalStateException(
+                "Can't invoke setRenderParameter() after sendRedirect() has been called");
+        }
+
+        if (key == null || values == null || values.length == 0) {
+            throw new IllegalArgumentException(
+                "Render parameter key or value must not be null or values be an empty array.");
+        }
+
+        renderParameters.put(key, StringUtils.copy(values));
+
+        redirectAllowed = false;
+    }
+    // --------------------------------------------------------------------------------------------
+    
+    // org.apache.pluto.core.InternalActionResponse implementation --------------------------------
+    public Map getRenderParameters() {
+        return renderParameters;
+    }
+
+    public PortletMode getChangedPortletMode() {
+        return this.portletMode;
+    }
+
+    public WindowState getChangedWindowState() {
+        return this.windowState;
+    }
+    
+    private boolean isPortletModeAllowed(PortletMode mode) {
+        return isPortletModeAllowedByPortlet(mode)
+               && isPortletModeAllowedByPortal(mode);
+    }
+
+    private boolean isPortletModeAllowedByPortlet(PortletMode mode) {
+        PortletDD dd = getInternalPortletWindow().getPortletEntity()
+            .getPortletDefinition();
+
+        Iterator supports = dd.getSupports().iterator();
+        while(supports.hasNext()) {
+            SupportsDD sup = (SupportsDD)supports.next();
+            Iterator modes = sup.getPortletModes().iterator();
+            while(modes.hasNext()) {
+                if (modes.next().toString().equalsIgnoreCase(mode.toString())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isPortletModeAllowedByPortal(PortletMode mode) {
+        Enumeration supportedModes = context.getSupportedPortletModes();
+        while (supportedModes.hasMoreElements()) {
+            if (supportedModes.nextElement().toString().equalsIgnoreCase(
+                (mode.toString()))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isWindowStateAllowed(WindowState state) {
+        Enumeration supportedStates = context.getSupportedWindowStates();
+        while (supportedStates.hasMoreElements()) {
+            if (supportedStates.nextElement().toString().equalsIgnoreCase(
+                (state.toString()))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}