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 as...@apache.org on 2019/03/25 19:35:11 UTC

[portals-pluto] branch master updated: PLUTO-746 Develop the portlet-servlet-adapter module

This is an automated email from the ASF dual-hosted git repository.

asfgriff pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/portals-pluto.git


The following commit(s) were added to refs/heads/master by this push:
     new c685163  PLUTO-746 Develop the portlet-servlet-adapter module
c685163 is described below

commit c6851636f50121ade74576128df5ba5c96ecff2f
Author: Neil Griffin <ne...@gmail.com>
AuthorDate: Mon Mar 25 15:33:44 2019 -0400

    PLUTO-746 Develop the portlet-servlet-adapter module
---
 pom.xml                                            |   1 +
 portlet-servlet-adapter/pom.xml                    |  41 ++
 .../servlet/adapter/HttpServletRequestAdapter.java | 468 +++++++++++++++++++++
 .../adapter/HttpServletResponseAdapter.java        | 365 ++++++++++++++++
 .../servlet/adapter/HttpSessionAdapter.java        | 168 ++++++++
 5 files changed, 1043 insertions(+)

diff --git a/pom.xml b/pom.xml
index f09f0d1..86c65c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -757,6 +757,7 @@ TODO: Check if we need all of them. -->
         <module>maven-pluto-plugin</module>
         <module>pluto-ant-tasks</module>
         <module>pluto-site-skin</module>
+        <module>portlet-servlet-adapter</module>
         
         <!-- the Technology Compliance Kit -->
         <module>test-base</module>
diff --git a/portlet-servlet-adapter/pom.xml b/portlet-servlet-adapter/pom.xml
new file mode 100644
index 0000000..760b526
--- /dev/null
+++ b/portlet-servlet-adapter/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <modelVersion>4.0.0</modelVersion>
+   <parent>
+      <groupId>org.apache.portals.pluto</groupId>
+      <artifactId>pluto</artifactId>
+      <version>3.0.2-SNAPSHOT</version>
+      <relativePath>../pom.xml</relativePath>
+   </parent>
+
+   <artifactId>portlet-servlet-adapter</artifactId>
+   <name>Portlet Servlet Adapter</name>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>javax.portlet</groupId>
+         <artifactId>portlet-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>javax.servlet-api</artifactId>
+         <version>3.1.0</version>
+         <scope>provided</scope>
+      </dependency>
+
+   </dependencies>
+   
+</project>
diff --git a/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletRequestAdapter.java b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletRequestAdapter.java
new file mode 100644
index 0000000..e655bc2
--- /dev/null
+++ b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletRequestAdapter.java
@@ -0,0 +1,468 @@
+/*
+ * 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.pluto.portlet.servlet.adapter;
+
+import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpUpgradeHandler;
+import javax.servlet.http.Part;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Provides a way to decorate a {@link PortletRequest} as an {@link HttpServletRequest}. Methods that have no
+ * correspondence to {@link HttpServletRequest} throw {@link UnsupportedOperationException}.
+ *
+ * @author Neil Griffin
+ */
+public class HttpServletRequestAdapter implements HttpServletRequest {
+
+	private PortletRequest portletRequest;
+	private ServletContext servletContext;
+
+	public HttpServletRequestAdapter(PortletRequest portletRequest) {
+		this.portletRequest = portletRequest;
+	}
+
+	public HttpServletRequestAdapter(PortletRequest portletRequest, ServletContext servletContext) {
+		this.portletRequest = portletRequest;
+		this.servletContext = servletContext;
+	}
+
+	@Override
+	public String getAuthType() {
+		return portletRequest.getAuthType();
+	}
+
+	@Override
+	public Cookie[] getCookies() {
+		return portletRequest.getCookies();
+	}
+
+	@Override
+	public long getDateHeader(String name) {
+		return Long.valueOf(portletRequest.getProperty(name));
+	}
+
+	@Override
+	public String getHeader(String name) {
+		return portletRequest.getProperty(name);
+	}
+
+	@Override
+	public Enumeration<String> getHeaders(String name) {
+		return portletRequest.getProperties(name);
+	}
+
+	@Override
+	public Enumeration<String> getHeaderNames() {
+		return portletRequest.getPropertyNames();
+	}
+
+	@Override
+	public int getIntHeader(String name) {
+		return Integer.valueOf(getHeader(name));
+	}
+
+	@Override
+	public String getMethod() {
+
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getMethod();
+		}
+
+		return "";
+	}
+
+	@Override
+	public String getPathInfo() {
+		return "";
+	}
+
+	@Override
+	public String getPathTranslated() {
+		return "";
+	}
+
+	@Override
+	public String getContextPath() {
+		return portletRequest.getContextPath();
+	}
+
+	@Override
+	public String getQueryString() {
+		return "";
+	}
+
+	@Override
+	public String getRemoteUser() {
+		return portletRequest.getRemoteUser();
+	}
+
+	@Override
+	public boolean isUserInRole(String role) {
+		return portletRequest.isUserInRole(role);
+	}
+
+	@Override
+	public Principal getUserPrincipal() {
+		return portletRequest.getUserPrincipal();
+	}
+
+	@Override
+	public String getRequestedSessionId() {
+		return portletRequest.getRequestedSessionId();
+	}
+
+	@Override
+	public String getRequestURI() {
+		return "";
+	}
+
+	@Override
+	public StringBuffer getRequestURL() {
+		return new StringBuffer();
+	}
+
+	@Override
+	public String getServletPath() {
+		return "";
+	}
+
+	@Override
+	public HttpSession getSession(boolean create) {
+		PortletSession portletSession = portletRequest.getPortletSession(create);
+
+		if (portletSession == null) {
+			return null;
+		}
+
+		return new HttpSessionAdapter(portletSession);
+	}
+
+	@Override
+	public HttpSession getSession() {
+		return getSession(true);
+	}
+
+	@Override
+	public String changeSessionId() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public boolean isRequestedSessionIdValid() {
+		return portletRequest.isRequestedSessionIdValid();
+	}
+
+	@Override
+	public boolean isRequestedSessionIdFromCookie() {
+		return false;
+	}
+
+	@Override
+	public boolean isRequestedSessionIdFromURL() {
+		return false;
+	}
+
+	@Override
+	public boolean isRequestedSessionIdFromUrl() {
+		return false;
+	}
+
+	@Override
+	public boolean authenticate(HttpServletResponse httpServletResponse) throws IOException, ServletException {
+		return false;
+	}
+
+	@Override
+	public void login(String username, String password) throws ServletException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void logout() throws ServletException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Collection<Part> getParts() throws IOException, ServletException {
+
+		if (portletRequest instanceof ClientDataRequest) {
+			try {
+				return ((ClientDataRequest)portletRequest).getParts();
+			}
+			catch (PortletException e) {
+				throw new ServletException(e);
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public Part getPart(String name) throws IOException, ServletException {
+
+		if (portletRequest instanceof ClientDataRequest) {
+			try {
+				return ((ClientDataRequest)portletRequest).getPart(name);
+			}
+			catch (PortletException e) {
+				throw new ServletException(e);
+			}
+		}
+
+		return null;
+	}
+
+	@Override
+	public <T extends HttpUpgradeHandler> T upgrade(Class<T> aClass) throws IOException, ServletException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Object getAttribute(String name) {
+		return portletRequest.getAttribute(name);
+	}
+
+	@Override
+	public Enumeration<String> getAttributeNames() {
+		return portletRequest.getAttributeNames();
+	}
+
+	@Override
+	public String getCharacterEncoding() {
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getCharacterEncoding();
+		}
+
+		return "";
+	}
+
+	@Override
+	public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException {
+		if (portletRequest instanceof ClientDataRequest) {
+			((ClientDataRequest)portletRequest).setCharacterEncoding(encoding);
+		}
+	}
+
+	@Override
+	public int getContentLength() {
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getContentLength();
+		}
+		else {
+			return 0;
+		}
+	}
+
+	@Override
+	public long getContentLengthLong() {
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getContentLengthLong();
+		}
+		else {
+			return 0;
+		}
+	}
+
+	@Override
+	public String getContentType() {
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getContentType();
+		}
+		else {
+			return "";
+		}
+	}
+
+	@Override
+	public ServletInputStream getInputStream() throws IOException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String getParameter(String name) {
+		return portletRequest.getParameter(name);
+	}
+
+	@Override
+	public Enumeration<String> getParameterNames() {
+		return portletRequest.getParameterNames();
+	}
+
+	@Override
+	public String[] getParameterValues(String name) {
+		return portletRequest.getParameterValues(name);
+	}
+
+	@Override
+	public Map<String, String[]> getParameterMap() {
+		return portletRequest.getParameterMap();
+	}
+
+	@Override
+	public String getProtocol() {
+		return "";
+	}
+
+	@Override
+	public String getScheme() {
+		return portletRequest.getScheme();
+	}
+
+	@Override
+	public String getServerName() {
+		return portletRequest.getServerName();
+	}
+
+	@Override
+	public int getServerPort() {
+		return portletRequest.getServerPort();
+	}
+
+	@Override
+	public BufferedReader getReader() throws IOException {
+
+		if (portletRequest instanceof ClientDataRequest) {
+			return ((ClientDataRequest)portletRequest).getReader();
+		}
+
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String getRemoteAddr() {
+		return "";
+	}
+
+	@Override
+	public String getRemoteHost() {
+		return "";
+	}
+
+	@Override
+	public void setAttribute(String name, Object value) {
+		portletRequest.setAttribute(name, value);
+	}
+
+	@Override
+	public void removeAttribute(String name) {
+		portletRequest.removeAttribute(name);
+	}
+
+	@Override
+	public Locale getLocale() {
+		return portletRequest.getLocale();
+	}
+
+	@Override
+	public Enumeration<Locale> getLocales() {
+		return portletRequest.getLocales();
+	}
+
+	@Override
+	public boolean isSecure() {
+		return portletRequest.isSecure();
+	}
+
+	@Override
+	public RequestDispatcher getRequestDispatcher(String path) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String getRealPath(String path) {
+		return "";
+	}
+
+	@Override
+	public int getRemotePort() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String getLocalName() {
+		return "";
+	}
+
+	@Override
+	public String getLocalAddr() {
+		return "";
+	}
+
+	@Override
+	public int getLocalPort() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public ServletContext getServletContext() {
+		return servletContext;
+	}
+
+	@Override
+	public AsyncContext startAsync() throws IllegalStateException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public AsyncContext startAsync(
+		ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public boolean isAsyncStarted() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public boolean isAsyncSupported() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public AsyncContext getAsyncContext() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public DispatcherType getDispatcherType() {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletResponseAdapter.java b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletResponseAdapter.java
new file mode 100644
index 0000000..2eef2a3
--- /dev/null
+++ b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpServletResponseAdapter.java
@@ -0,0 +1,365 @@
+/*
+ * 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.pluto.portlet.servlet.adapter;
+
+import javax.portlet.ActionResponse;
+import javax.portlet.MimeResponse;
+import javax.portlet.PortletResponse;
+import javax.portlet.ResourceResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Locale;
+
+/**
+ * Provides a way to decorate a {@link PortletResponse} as an {@link HttpServletResponse}. Methods that have no
+ * correspondence to {@link HttpServletResponse} throw {@link UnsupportedOperationException}.
+ *
+ * @author Neil Griffin
+ */
+public class HttpServletResponseAdapter implements HttpServletResponse {
+
+	private PortletResponse portletResponse;
+
+	public HttpServletResponseAdapter(PortletResponse portletResponse) {
+		this.portletResponse = portletResponse;
+	}
+
+	@Override
+	public void addCookie(Cookie cookie) {
+		portletResponse.addProperty(cookie);
+	}
+
+	@Override
+	public boolean containsHeader(String name) {
+		return false;
+	}
+
+	@Override
+	public String encodeURL(String url) {
+		return portletResponse.encodeURL(url);
+	}
+
+	@Override
+	public String encodeRedirectURL(String url) {
+		return url;
+	}
+
+	@Override
+	public String encodeUrl(String url) {
+		return portletResponse.encodeURL(url);
+	}
+
+	@Override
+	public String encodeRedirectUrl(String url) {
+		return url;
+	}
+
+	@Override
+	public void sendError(int statusCode, String message) throws IOException {
+		setStatus(statusCode, message);
+	}
+
+	@Override
+	public void sendError(int statusCode) throws IOException {
+		setStatus(statusCode);
+	}
+
+	@Override
+	public void sendRedirect(String location) throws IOException {
+		if (portletResponse instanceof ActionResponse) {
+			((ActionResponse)portletResponse).sendRedirect(location);
+		}
+		else {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	@Override
+	public void setDateHeader(String name, long date) {
+		setHeader(name, Long.toString(date));
+	}
+
+	@Override
+	public void addDateHeader(String name, long date) {
+		addHeader(name, Long.toString(date));
+	}
+
+	@Override
+	public void setHeader(String name, String value) {
+		portletResponse.setProperty(name, value);
+	}
+
+	@Override
+	public void addHeader(String name, String value) {
+		portletResponse.addProperty(name, value);
+	}
+
+	@Override
+	public void setIntHeader(String name, int value) {
+		setHeader(name, Integer.toString(value));
+	}
+
+	@Override
+	public void addIntHeader(String name, int value) {
+		addHeader(name, Integer.toString(value));
+	}
+
+	@Override
+	public void setStatus(int statusCode) {
+
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse)portletResponse).setStatus(statusCode);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setStatus(int statusCode, String statusMessage) {
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse)portletResponse).setStatus(statusCode);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public int getStatus() {
+
+		if (portletResponse instanceof ResourceResponse) {
+			return ((ResourceResponse)portletResponse).getStatus();
+		}
+
+		return HttpServletResponse.SC_OK;
+	}
+
+	@Override
+	public String getHeader(String name) {
+		return portletResponse.getProperty(name);
+	}
+
+	@Override
+	public Collection<String> getHeaders(String name) {
+		return portletResponse.getPropertyValues(name);
+	}
+
+	@Override
+	public Collection<String> getHeaderNames() {
+		return portletResponse.getPropertyNames();
+	}
+
+	@Override
+	public String getCharacterEncoding() {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).getCharacterEncoding();
+		}
+
+		return "UTF-8";
+	}
+
+	@Override
+	public String getContentType() {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).getContentType();
+		}
+		else {
+			return "";
+		}
+	}
+
+	@Override
+	public ServletOutputStream getOutputStream() throws IOException {
+
+		if (portletResponse instanceof MimeResponse) {
+			return new ServletOutputStreamAdapter(((MimeResponse)portletResponse).getPortletOutputStream());
+		}
+
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public PrintWriter getWriter() throws IOException {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).getWriter();
+		}
+
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void setCharacterEncoding(String charset) {
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse) portletResponse).setCharacterEncoding(charset);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setContentLength(int length) {
+
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse)portletResponse).setContentLength(length);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setContentLengthLong(long length) {
+
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse)portletResponse).setContentLengthLong(length);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setContentType(String contentType) {
+
+		if (portletResponse instanceof MimeResponse) {
+			((MimeResponse)portletResponse).setContentType(contentType);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setBufferSize(int size) {
+
+		if (portletResponse instanceof MimeResponse) {
+			((MimeResponse)portletResponse).setBufferSize(size);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public int getBufferSize() {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).getBufferSize();
+		}
+
+		return 0;
+	}
+
+	@Override
+	public void flushBuffer() throws IOException {
+
+		if (portletResponse instanceof MimeResponse) {
+			((MimeResponse)portletResponse).flushBuffer();
+		}
+		else {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	@Override
+	public void resetBuffer() {
+
+		if (portletResponse instanceof MimeResponse) {
+			((MimeResponse)portletResponse).resetBuffer();
+		}
+		else {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	@Override
+	public boolean isCommitted() {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).isCommitted();
+		}
+
+		return false;
+	}
+
+	@Override
+	public void reset() {
+
+		if (portletResponse instanceof MimeResponse) {
+			((MimeResponse)portletResponse).reset();
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public void setLocale(Locale locale) {
+
+		if (portletResponse instanceof ResourceResponse) {
+			((ResourceResponse)portletResponse).setLocale(locale);
+		}
+		else {
+			// no-op
+		}
+	}
+
+	@Override
+	public Locale getLocale() {
+
+		if (portletResponse instanceof MimeResponse) {
+			return ((MimeResponse)portletResponse).getLocale();
+		}
+		else {
+			return null;
+		}
+	}
+
+	private static class ServletOutputStreamAdapter extends ServletOutputStream {
+
+		private OutputStream portletOutputStream;
+
+		public ServletOutputStreamAdapter(OutputStream portletOutputStream) {
+			this.portletOutputStream = portletOutputStream;
+		}
+
+		@Override
+		public boolean isReady() {
+			return true;
+		}
+
+		@Override
+		public void setWriteListener(WriteListener writeListener) {
+		}
+
+		@Override
+		public void write(int b) throws IOException {
+			portletOutputStream.write(b);
+		}
+	}
+}
diff --git a/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpSessionAdapter.java b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpSessionAdapter.java
new file mode 100644
index 0000000..0dc2dac
--- /dev/null
+++ b/portlet-servlet-adapter/src/main/java/org/apache/pluto/portlet/servlet/adapter/HttpSessionAdapter.java
@@ -0,0 +1,168 @@
+/*
+ * 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.pluto.portlet.servlet.adapter;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+import java.util.Enumeration;
+import java.util.Map;
+
+
+/**
+ * Provides a way to decorate a {@link PortletSession} as an {@link HttpSession}. Methods that have no correspondence to
+ * {@link HttpSession} throw {@link UnsupportedOperationException}
+ *
+ * @author  Neil Griffin
+ */
+public class HttpSessionAdapter implements PortletSession, HttpSession {
+
+	// Private Data Members
+	private PortletSession wrappedPortletSession;
+
+	public HttpSessionAdapter(PortletSession portletSession) {
+		this.wrappedPortletSession = portletSession;
+	}
+
+	@Override
+	public Object getAttribute(String name) {
+		Object value = wrappedPortletSession.getAttribute(name, PortletSession.PORTLET_SCOPE);
+
+		if (value == null) {
+			value = wrappedPortletSession.getAttribute(name, PortletSession.APPLICATION_SCOPE);
+		}
+
+		return value;
+	}
+
+	@Override
+	public Object getAttribute(String name, int scope) {
+		return wrappedPortletSession.getAttribute(name, scope);
+	}
+
+	@Override
+	public Map<String, Object> getAttributeMap() {
+		return wrappedPortletSession.getAttributeMap();
+	}
+
+	@Override
+	public Map<String, Object> getAttributeMap(int scope) {
+		return wrappedPortletSession.getAttributeMap(scope);
+	}
+
+	@Override
+	public Enumeration<String> getAttributeNames() {
+		return wrappedPortletSession.getAttributeNames();
+	}
+
+	@Override
+	public Enumeration<String> getAttributeNames(int scope) {
+		return wrappedPortletSession.getAttributeNames(scope);
+	}
+
+	@Override
+	public long getCreationTime() {
+		return wrappedPortletSession.getCreationTime();
+	}
+
+	@Override
+	public String getId() {
+		return wrappedPortletSession.getId();
+	}
+
+	@Override
+	public long getLastAccessedTime() {
+		return wrappedPortletSession.getLastAccessedTime();
+	}
+
+	@Override
+	public int getMaxInactiveInterval() {
+		return wrappedPortletSession.getMaxInactiveInterval();
+	}
+
+	@Override
+	public PortletContext getPortletContext() {
+		return wrappedPortletSession.getPortletContext();
+	}
+
+	@Override
+	public ServletContext getServletContext() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public HttpSessionContext getSessionContext() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Object getValue(String name) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public String[] getValueNames() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void invalidate() {
+		wrappedPortletSession.invalidate();
+	}
+
+	@Override
+	public boolean isNew() {
+		return wrappedPortletSession.isNew();
+	}
+
+	@Override
+	public void putValue(String name, Object value) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void removeAttribute(String name) {
+		wrappedPortletSession.removeAttribute(name);
+	}
+
+	@Override
+	public void removeAttribute(String name, int scope) {
+		wrappedPortletSession.removeAttribute(name, scope);
+	}
+
+	@Override
+	public void removeValue(String name) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public void setAttribute(String name, Object value) {
+		wrappedPortletSession.setAttribute(name, value);
+	}
+
+	@Override
+	public void setAttribute(String name, Object value, int scope) {
+		wrappedPortletSession.setAttribute(name, value, scope);
+	}
+
+	@Override
+	public void setMaxInactiveInterval(int interval) {
+		wrappedPortletSession.setMaxInactiveInterval(interval);
+	}
+}