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 ms...@apache.org on 2016/04/19 15:50:53 UTC
[1/2] portals-pluto git commit: Defined API, config annotations,
and schema changes to implement PORTLETSPEC3-67 Multipart Support.
Completed implementation with unit test cases for configuration processor.
Implemented getPart() and getParts methods on C
Repository: portals-pluto
Updated Branches:
refs/heads/master 8a89cc49f -> a671849a8
Defined API, config annotations, and schema changes to implement
PORTLETSPEC3-67 Multipart Support. Completed implementation with unit test
cases for configuration processor. Implemented getPart() and getParts
methods on ClientDataRequest. Adapted PortletContainerInitializer to
initialize the portlet servlet with multipart config data when the portlet
is configured for multipart support.
Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/1217bb1e
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/1217bb1e
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/1217bb1e
Branch: refs/heads/master
Commit: 1217bb1e0592ebecd48d4edb8b1a4fb5a5fdf6c9
Parents: 8a89cc4
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Apr 18 15:11:07 2016 +0200
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Apr 18 15:11:07 2016 +0200
----------------------------------------------------------------------
.../container/om/portlet/PortletDefinition.java | 13 +++
.../driver/PortletContainerInitializer.java | 6 ++
.../container/impl/ClientDataRequestImpl.java | 24 +++++
.../impl/JSR362ConfigurationProcessor.java | 23 +++++
.../om/portlet/impl/PortletDefinitionImpl.java | 92 ++++++++++++++++++++
.../pluto/container/impl/portlet-app_3_0.xsd | 30 +++++--
.../fixtures/mocks/MockClientDataRequest.java | 13 +++
.../impl/fixtures/TestAnnotatedPortlet.java | 5 +-
.../fixtures/TestMultiAnnotatedPortlet.java | 8 +-
.../impl/jsr362/MergePortletDefinitionTest.java | 16 ++--
.../impl/jsr362/MultiAnnotatedPortletTest.java | 20 +++++
.../PortletDefinition362AnnotationTest.java | 9 ++
.../jsr362/PortletDefinition362ImplTest.java | 25 ++++++
.../container/om/portlet/portlet362Merge.xml | 43 +++++----
.../java/javax/portlet/ClientDataRequest.java | 53 ++++++++++-
.../javax/portlet/annotations/Multipart.java | 85 ++++++++++++++++++
.../annotations/PortletConfiguration.java | 10 +++
.../filter/ClientDataRequestWrapper.java | 23 +++++
portlet-api/src/main/javadoc/overview.html | 8 ++
portlet-api/src/main/javadoc/portlet-api.css | 1 +
20 files changed, 474 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
index 6d896a4..58ca8ff 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
@@ -88,5 +88,18 @@ public interface PortletDefinition {
boolean isAsyncSupported();
void setAsyncSupported(boolean asyncSupported);
+
+ // multipart config
+
+ boolean isMultipartSupported();
+ void setMultipartSupported(boolean multipartSupported);
+ String getLocation();
+ void setLocation(String location);
+ Integer getFileSizeThreshold();
+ void setFileSizeThreshold(Integer fileSizeThreshold);
+ Long getMaxRequestSize();
+ void setMaxRequestSize(Long maxRequestSize);
+ Long getMaxFileSize();
+ void setMaxFileSize(Long maxFileSize);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index 0fb20a6..60a46cf 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -30,6 +30,7 @@ import javax.portlet.annotations.PortletPreferencesValidator;
import javax.portlet.annotations.PortletRequestFilter;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
+import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -161,6 +162,11 @@ public class PortletContainerInitializer implements ServletContainerInitializer
sr.addMapping(mapping);
sr.setInitParameter(PortletServlet3.PORTLET_NAME, pn);
sr.setAsyncSupported(pd.isAsyncSupported());
+ if (pd.isMultipartSupported()) {
+ MultipartConfigElement mce = new MultipartConfigElement(pd.getLocation(),
+ pd.getMaxFileSize(), pd.getMaxRequestSize(), pd.getFileSizeThreshold());
+ sr.setMultipartConfig(mce);
+ }
sr.setLoadOnStartup(100);
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/main/java/org/apache/pluto/container/impl/ClientDataRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/ClientDataRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/ClientDataRequestImpl.java
index 0fff3a6..f259e0a 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/ClientDataRequestImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/ClientDataRequestImpl.java
@@ -21,8 +21,12 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletException;
+import javax.servlet.ServletException;
+import javax.servlet.http.Part;
import org.apache.pluto.container.PortletRequestContext;
import org.apache.pluto.container.PortletResponseContext;
@@ -72,6 +76,26 @@ public abstract class ClientDataRequestImpl extends PortletRequestImpl implement
return getServletRequest().getContentLengthLong();
}
+ @Override
+ public Part getPart(String name) throws IOException, PortletException
+ {
+ try {
+ return getServletRequest().getPart(name);
+ } catch (ServletException e) {
+ throw new PortletException(e);
+ }
+ }
+
+ @Override
+ public Collection<Part> getParts() throws IOException, PortletException
+ {
+ try {
+ return getServletRequest().getParts();
+ } catch (ServletException e) {
+ throw new PortletException(e);
+ }
+ }
+
public java.lang.String getContentType()
{
return getServletRequest().getContentType();
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 5cced2e..ec7b70f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -31,6 +31,7 @@ import javax.portlet.PortletURLGenerationListener;
import javax.portlet.PreferencesValidator;
import javax.portlet.annotations.InitParameter;
import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.Multipart;
import javax.portlet.annotations.PortletApplication;
import javax.portlet.annotations.PortletConfiguration;
import javax.portlet.annotations.PortletListener;
@@ -81,6 +82,7 @@ import org.apache.pluto.container.om.portlet30.impl.InitParamType;
import org.apache.pluto.container.om.portlet30.impl.KeywordsType;
import org.apache.pluto.container.om.portlet30.impl.ListenerType;
import org.apache.pluto.container.om.portlet30.impl.MimeTypeType;
+import org.apache.pluto.container.om.portlet30.impl.MultipartType;
import org.apache.pluto.container.om.portlet30.impl.PortletAppType;
import org.apache.pluto.container.om.portlet30.impl.PortletInfoType;
import org.apache.pluto.container.om.portlet30.impl.PortletModeType;
@@ -872,6 +874,16 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
if (portlet.isAsyncSupported() != null) {
pd.setAsyncSupported(portlet.isAsyncSupported());
}
+
+ // multipart config
+ MultipartType muty = portlet.getMultipartConfig();
+ if (muty != null) {
+ pd.setMultipartSupported(true);
+ pd.setLocation(muty.getLocation());
+ pd.setFileSizeThreshold(muty.getFileSizeThreshold());
+ pd.setMaxFileSize(muty.getMaxFileSize());
+ pd.setMaxRequestSize(muty.getMaxRequestSize());
+ }
pad.addPortlet(pd);
@@ -1297,6 +1309,17 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
pd.setExpirationCache(pc.cacheExpirationTime());
pd.setResourceBundle(pc.resourceBundle());
pd.setAsyncSupported(pc.asyncSupported());
+
+ // multipart config
+
+ if (pc.multipart().supported() == true) {
+ Multipart mp = pc.multipart();
+ pd.setMultipartSupported(true);
+ pd.setLocation(mp.location());
+ pd.setFileSizeThreshold(mp.fileSizeThreshold());
+ pd.setMaxFileSize(mp.maxFileSize());
+ pd.setMaxRequestSize(mp.maxRequestSize());
+ }
// handle portlet info - title, short title, keywords
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
index e2fd37d..f49eb5f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
@@ -75,6 +75,13 @@ public class PortletDefinitionImpl implements PortletDefinition {
private final List<Supports> supps = new ArrayList<Supports>();
private final List<Dependency> dependencies = new ArrayList<Dependency>();
private boolean asyncSupported = false;
+
+ private boolean multipartSupported = false;
+ private String location = "";
+ private Long maxFileSize = -1L;
+ private Long maxRequestSize = -1L;
+ private Integer fileSizeThreshold = 0;
+
/**
* Copy constructor
@@ -127,6 +134,11 @@ public class PortletDefinitionImpl implements PortletDefinition {
this.dependencies.add(dep);
}
this.asyncSupported = pd.isAsyncSupported();
+ this.multipartSupported = pd.isMultipartSupported();
+ this.location = pd.getLocation();
+ this.maxFileSize = pd.getMaxFileSize();
+ this.maxRequestSize = pd.getMaxRequestSize();
+ this.fileSizeThreshold = pd.getFileSizeThreshold();
}
/**
@@ -613,6 +625,86 @@ public class PortletDefinitionImpl implements PortletDefinition {
this.asyncSupported = asyncSupported;
}
+ /**
+ * @return the multipartSupported
+ */
+ @Override
+ public boolean isMultipartSupported() {
+ return multipartSupported;
+ }
+
+ /**
+ * @param multipartSupported the multipartSupported to set
+ */
+ @Override
+ public void setMultipartSupported(boolean multipartSupported) {
+ this.multipartSupported = multipartSupported;
+ }
+
+ /**
+ * @return the location
+ */
+ @Override
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * @param location the location to set
+ */
+ @Override
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ /**
+ * @return the maxFileSize
+ */
+ @Override
+ public Long getMaxFileSize() {
+ return maxFileSize;
+ }
+
+ /**
+ * @param maxFileSize the maxFileSize to set
+ */
+ @Override
+ public void setMaxFileSize(Long maxFileSize) {
+ this.maxFileSize = maxFileSize;
+ }
+
+ /**
+ * @return the maxRequestSize
+ */
+ @Override
+ public Long getMaxRequestSize() {
+ return maxRequestSize;
+ }
+
+ /**
+ * @param maxRequestSize the maxRequestSize to set
+ */
+ @Override
+ public void setMaxRequestSize(Long maxRequestSize) {
+ this.maxRequestSize = maxRequestSize;
+ }
+
+ /**
+ * @return the fileSizeThreshold
+ */
+ @Override
+ public Integer getFileSizeThreshold() {
+ return fileSizeThreshold;
+ }
+
+ /**
+ * @param fileSizeThreshold the fileSizeThreshold to set
+ */
+ @Override
+ public void setFileSizeThreshold(Integer fileSizeThreshold) {
+ this.fileSizeThreshold = fileSizeThreshold;
+ }
+
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
index 8d97be1..3fd88dd 100644
--- a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
+++ b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
@@ -307,14 +307,15 @@
<element name="supported-public-render-parameter" type="portlet:string" minOccurs="0" maxOccurs="unbounded"/>
<element name="container-runtime-option" type="portlet:container-runtime-optionType" minOccurs="0" maxOccurs="unbounded"/>
<element name="dependency" type="portlet:dependencyType" minOccurs="0" maxOccurs="unbounded"/>
- <element name="async-supported" type="boolean" minOccurs="0" maxOccurs="1">
- <annotation>
- <documentation>
- If set to 'true', the portlet will support
- asynchronous processing in resource requests.
- </documentation>
- </annotation>
- </element>
+ <element name="async-supported" type="boolean" minOccurs="0" maxOccurs="1">
+ <annotation>
+ <documentation>
+ If set to 'true', the portlet will support
+ asynchronous processing in resource requests.
+ </documentation>
+ </annotation>
+ </element>
+ <element name="multipart-config" type="portlet:multipartType" minOccurs="0" maxOccurs="1"/>
</sequence>
<attribute name="id" type="portlet:string" use="optional"/>
</complexType>
@@ -675,6 +676,19 @@
<element name="min-version" type="portlet:resourceVersionType"/>
</sequence>
</complexType>
+ <complexType name="multipartType">
+ <annotation>
+ <documentation>
+ Provides multipart configuration information.
+ </documentation>
+ </annotation>
+ <sequence>
+ <element name="location" type="portlet:string" minOccurs="0" maxOccurs="1"/>
+ <element name="max-file-size" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <element name="max-request-size" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <element name="file-size-threshold" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ </complexType>
<complexType name="supported-localeType">
<annotation>
<documentation>
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
index fdfc572..6804f03 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
@@ -23,8 +23,11 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletException;
+import javax.servlet.http.Part;
/**
* @author Scott
@@ -92,4 +95,14 @@ public class MockClientDataRequest extends MockPortletRequest implements ClientD
public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
}
+ @Override
+ public Part getPart(String name) throws IOException, PortletException {
+ return null;
+ }
+
+ @Override
+ public Collection<Part> getParts() throws IOException, PortletException {
+ return null;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
index 8e7cc29..bb20ead 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
@@ -22,6 +22,7 @@ package org.apache.pluto.container.om.portlet.impl.fixtures;
import javax.portlet.annotations.Dependency;
import javax.portlet.annotations.InitParameter;
import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.Multipart;
import javax.portlet.annotations.PortletConfiguration;
import javax.portlet.annotations.Preference;
import javax.portlet.annotations.RuntimeOption;
@@ -75,7 +76,9 @@ import javax.portlet.annotations.Supports;
@Dependency(name="Dojo", minVersion="3.1.4"),
@Dependency(name="AngularJS", minVersion="1.4.8")
},
- asyncSupported = true
+ asyncSupported = true,
+ multipart = @Multipart(supported=true, location="here",
+ fileSizeThreshold=1, maxFileSize=2, maxRequestSize=3)
)
public class TestAnnotatedPortlet {
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
index 6b17008..611029c 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
@@ -22,6 +22,7 @@ package org.apache.pluto.container.om.portlet.impl.fixtures;
import javax.portlet.GenericPortlet;
import javax.portlet.annotations.InitParameter;
import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.Multipart;
import javax.portlet.annotations.PortletApplication;
import javax.portlet.annotations.PortletConfiguration;
import javax.portlet.annotations.PortletConfigurations;
@@ -67,7 +68,8 @@ import javax.portlet.annotations.PortletConfigurations;
}, keywords={
@LocaleString(locale="DE", value="Eins, Zwei, Drei")
},
- asyncSupported=true
+ asyncSupported=true,
+ multipart = @Multipart(supported=false)
),
@PortletConfiguration(portletName="Portlet3",
initParams = {
@@ -84,7 +86,9 @@ import javax.portlet.annotations.PortletConfigurations;
}, keywords={
@LocaleString(locale="DE", value="Eins, Zwei, Drei")
},
- asyncSupported=false
+ asyncSupported=false,
+ multipart = @Multipart(supported=true, location="/home",
+ fileSizeThreshold=11, maxFileSize=22, maxRequestSize=33)
),
})
public class TestMultiAnnotatedPortlet extends GenericPortlet {
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
index c8b5d69..cb5d9e4 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
@@ -19,11 +19,7 @@
package org.apache.pluto.container.om.portlet.impl.jsr362;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.io.InputStream;
import java.util.Arrays;
@@ -884,5 +880,15 @@ public class MergePortletDefinitionTest {
public void testAsyncSupported() throws Exception {
assertFalse(cut.isAsyncSupported());
}
+
+ @Test
+ public void testMultipartSupported() throws Exception {
+ assertTrue(cut.isMultipartSupported());
+
+ assertEquals("/tmp", cut.getLocation());
+ assertEquals(new Integer(103), cut.getFileSizeThreshold());
+ assertEquals(new Long(101), cut.getMaxFileSize());
+ assertEquals(new Long(102), cut.getMaxRequestSize());
+ }
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
index 2561f3b..9c35a4e 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
@@ -358,5 +358,25 @@ public class MultiAnnotatedPortletTest {
public void testAsyncSupportedFalse() throws Exception {
assertFalse(portlet3.isAsyncSupported());
}
+
+ @Test
+ public void testMultipartSupportedDefault() throws Exception {
+ assertFalse(portlet1.isMultipartSupported());
+ }
+
+ @Test
+ public void testMultipartSupportedTrue() throws Exception {
+ assertFalse(portlet2.isMultipartSupported());
+ }
+
+ @Test
+ public void testMultipartSupportedFalse() throws Exception {
+ assertTrue(portlet3.isMultipartSupported());
+
+ assertEquals("/home", portlet3.getLocation());
+ assertEquals(new Integer(11), portlet3.getFileSizeThreshold());
+ assertEquals(new Long(22), portlet3.getMaxFileSize());
+ assertEquals(new Long(33), portlet3.getMaxRequestSize());
+ }
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
index 0f94248..f2f305a 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
@@ -812,5 +812,14 @@ public class PortletDefinition362AnnotationTest {
public void testAsyncSupported() throws Exception {
assertTrue(cut.isAsyncSupported());
}
+
+ @Test
+ public void testMultipartSupported() throws Exception {
+ assertTrue(cut.isMultipartSupported());
+ assertEquals("here", cut.getLocation());
+ assertEquals(new Integer(1), cut.getFileSizeThreshold());
+ assertEquals(new Long(2), cut.getMaxFileSize());
+ assertEquals(new Long(3), cut.getMaxRequestSize());
+ }
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
index abd89da..c9d52fd 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
@@ -888,5 +888,30 @@ public class PortletDefinition362ImplTest {
cut.setAsyncSupported(false);
assertFalse(cut.isAsyncSupported());
}
+
+ @Test
+ public void testSetMultipartSupportedTrue() throws Exception {
+ cut.setMultipartSupported(true);
+ assertTrue(cut.isMultipartSupported());
+ }
+
+ @Test
+ public void testSetMultipartSupportedFalse() throws Exception {
+ cut.setMultipartSupported(false);
+ assertFalse(cut.isMultipartSupported());
+ }
+
+ @Test
+ public void testGetSetMultipartValues() throws Exception {
+ cut.setLocation("there");
+ cut.setFileSizeThreshold(10);
+ cut.setMaxFileSize(20L);
+ cut.setMaxRequestSize(30L);
+
+ assertEquals("there", cut.getLocation());
+ assertEquals(new Integer(10), cut.getFileSizeThreshold());
+ assertEquals(new Long(20), cut.getMaxFileSize());
+ assertEquals(new Long(30), cut.getMaxRequestSize());
+ }
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
index 8ad2e91..9111f85 100644
--- a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
@@ -1,20 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app id="id1" version="3.0"
- xmlns="http://xmlns.jcp.org/xml/ns/portlet"
- xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet"
- xmlns:xml="http://www.w3.org/XML/1998/namespace"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+ xmlns="http://xmlns.jcp.org/xml/ns/portlet" xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet"
+ xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd "
+>
<!-- JSR 362 portlet DD test file -->
<portlet id="id2">
- <description xml:lang="de">multi
- line
- description</description>
+ <description xml:lang="de">multi
+ line
+ description
+ </description>
<portlet-name>AnnotatedPortlet</portlet-name>
<display-name xml:lang="de">display-name</display-name>
- <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet</portlet-class>
+ <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet
+ </portlet-class>
<init-param id="init1">
<description xml:lang="de">description</description>
<name>name</name>
@@ -43,7 +44,8 @@
<window-state>window-state3</window-state>
</supports>
<supported-locale>supported-locale</supported-locale>
- <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
+ <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle
+ </resource-bundle>
<portlet-info id="info1">
<title xml:lang="de">Titel</title>
<short-title xml:lang="de">Kurztitel</short-title>
@@ -94,13 +96,20 @@
<min-version>1.4.8</min-version>
</dependency>
<async-supported>false</async-supported>
+ <multipart-config>
+ <location>/tmp</location>
+ <max-file-size>101</max-file-size>
+ <max-request-size>102</max-request-size>
+ <file-size-threshold>103</file-size-threshold>
+ </multipart-config>
</portlet>
+
<custom-portlet-mode id="mode1">
<description xml:lang="de">description</description>
<portlet-mode>portlet-mode</portlet-mode>
<portal-managed>false</portal-managed>
</custom-portlet-mode>
- <custom-portlet-mode id="mode1">
+ <custom-portlet-mode id="mode1">
<description xml:lang="de">description</description>
<portlet-mode>aMode</portlet-mode>
<portal-managed>false</portal-managed>
@@ -131,12 +140,14 @@
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
- <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
+ <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle
+ </resource-bundle>
<filter>
<description xml:lang="de">description</description>
<display-name xml:lang="de">display-name</display-name>
<filter-name>filter-name</filter-name>
- <filter-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter</filter-class>
+ <filter-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter
+ </filter-class>
<lifecycle>lifecycle</lifecycle>
<init-param id="init2">
<description xml:lang="de">description</description>
@@ -152,7 +163,8 @@
<event-definition id="event1">
<description xml:lang="de">description</description>
<name>another-event</name>
- <value-type>org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType</value-type>
+ <value-type>org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType
+ </value-type>
</event-definition>
<event-definition id="event2">
<description xml:lang="de">description</description>
@@ -173,7 +185,8 @@
<listener-name>test listener</listener-name>
<description xml:lang="de">description</description>
<display-name xml:lang="de">display-name</display-name>
- <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener</listener-class>
+ <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener
+ </listener-class>
</listener>
<container-runtime-option>
<name>Runtime-Option-Portlet-App</name>
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/java/javax/portlet/ClientDataRequest.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/ClientDataRequest.java b/portlet-api/src/main/java/javax/portlet/ClientDataRequest.java
index b5136ac..0bb3d21 100644
--- a/portlet-api/src/main/java/javax/portlet/ClientDataRequest.java
+++ b/portlet-api/src/main/java/javax/portlet/ClientDataRequest.java
@@ -24,6 +24,11 @@
package javax.portlet;
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.servlet.http.Part;
+
/**
* <span class="changed_modified_3_0">The</span>
* <CODE>ClientDataRequest</CODE> represents the request information
@@ -150,7 +155,6 @@ public interface ClientDataRequest extends PortletRequest {
public int getContentLength();
-
/**
* <div class="changed_added_3_0">
* Returns the length, in bytes, of the request body
@@ -165,7 +169,6 @@ public interface ClientDataRequest extends PortletRequest {
* @since 3.0
*
*/
-
public long getContentLengthLong();
/**
@@ -178,5 +181,51 @@ public interface ClientDataRequest extends PortletRequest {
*/
public String getMethod();
+ /**
+ * <div class="changed_added_3_0">
+ * Gets the Part with the given name.
+ * </div>
+ *
+ * @param name - the name of the requested Part
+ *
+ * @return The Part with the given name, or null if this request is of type
+ * multipart/form-data, but does not contain the requested Part
+ *
+ *
+ * @throws IOException if an I/O error occurred during the retrieval of the Part components of
+ * this request
+ * @throws PortletException if this request is not of type multipart/form-data
+ * @throws IllegalStateException if the request body is larger than maxRequestSize, or any Part in
+ * the request is larger than maxFileSize, or there is no multipart configuration
+ * present
+ *
+ * @since 3.0
+ *
+ */
+ public Part getPart(String name) throws IOException, PortletException;
+
+ /**
+ * <div class="changed_added_3_0">
+ * Gets all the Part components of this request, provided that it is of type multipart/form-data.
+ * <p>
+ * If this request is of type multipart/form-data, but does not contain any Part components, the returned Collection will be empty.
+ * <p>
+ * Any changes to the returned Collection must not affect this request object.
+ * </div>
+ *
+ * @return a (possibly empty) Collection of the Part components of this request
+ *
+ * @throws IOException if an I/O error occurred during the retrieval of the Part components of
+ * this request
+ * @throws PortletException if this request is not of type multipart/form-data
+ * @throws IllegalStateException if the request body is larger than maxRequestSize, or any Part in
+ * the request is larger than maxFileSize, or there is no multipart configuration
+ * present
+ *
+ * @since 3.0
+ *
+ */
+ public Collection<Part> getParts() throws IOException, PortletException;
+
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/java/javax/portlet/annotations/Multipart.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/Multipart.java b/portlet-api/src/main/java/javax/portlet/annotations/Multipart.java
new file mode 100644
index 0000000..0f86dbe
--- /dev/null
+++ b/portlet-api/src/main/java/javax/portlet/annotations/Multipart.java
@@ -0,0 +1,85 @@
+/* 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.
+ */
+
+/*
+ * This source code implements specifications defined by the Java
+ * Community Process. In order to remain compliant with the specification
+ * DO NOT add / change / or delete method signatures!
+ */
+
+package javax.portlet.annotations;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * <div class='changed_added_3_0'>
+ * This annotation is used within composite portlet configuration annotations to
+ * add multipart configuration information.
+ * This is the portlet analog of the
+ * <code>javax.servlet.annotation.MultipartConfig</code> annotation.
+ * <p>
+ * This annotation cannot be used as a stand-alone portlet annotation.
+ * </div>
+ *
+ * @see javax.servlet.annotation.MultipartConfig
+ */
+@Retention(RUNTIME) @Target({ANNOTATION_TYPE})
+public @interface Multipart {
+
+ /**
+ * Flag indicating if the portlet supports multipart forms.
+ * Must be set to <code>true</code> to activate multipart forms support.
+ *
+ * @return <code>true</code> if multipart forms are supported; <code>false</code> otherwise.
+ */
+ boolean supported();
+
+ /**
+ * The size threshold after which the file will be written to disk.
+ *
+ * @return The file size threshold
+ */
+ int fileSizeThreshold() default 0;
+
+ /**
+ * The directory location where files will be stored.
+ *
+ * @return The directory location
+ */
+ String location() default "";
+
+ /**
+ * The maximum size allowed for uploaded files.
+ *
+ * @return The maximum size allowed for uploaded files
+ */
+ long maxFileSize() default -1L;
+
+ /**
+ * The maximum size allowed for multipart/form-data requests.
+ *
+ * @return The maximum size allowed for multipart/form-data requests
+ */
+ long maxRequestSize() default -1L;
+}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
index 140993f..ca94586 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
@@ -234,4 +234,14 @@ public @interface PortletConfiguration {
* @return <code>true</code> if the method supports asynchronous mode.
*/
boolean asyncSupported() default false;
+
+ /**
+ * Provides multipart configuration data for the portlet.
+ * <p>
+ * The <code>{@literal @}Multipart</code> annotation <code>supported</code>
+ * element must be set to <code>true</code> to activate multipart form support.
+ *
+ * @return The multipart configuration data.
+ */
+ Multipart multipart() default @Multipart(supported=false);
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/java/javax/portlet/filter/ClientDataRequestWrapper.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/filter/ClientDataRequestWrapper.java b/portlet-api/src/main/java/javax/portlet/filter/ClientDataRequestWrapper.java
index 43b2ef2..bf12de5 100644
--- a/portlet-api/src/main/java/javax/portlet/filter/ClientDataRequestWrapper.java
+++ b/portlet-api/src/main/java/javax/portlet/filter/ClientDataRequestWrapper.java
@@ -22,8 +22,11 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletException;
+import javax.servlet.http.Part;
/**
* <div class="changed_added_3_0"> The <code>ClientDataRequestWrapper</code>
@@ -131,4 +134,24 @@ public class ClientDataRequestWrapper extends PortletRequestWrapper implements C
return ((ClientDataRequest)wrapped).getMethod();
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.portlet.ClientDataRequest#getPart(String)
+ */
+ @Override
+ public Part getPart(String name) throws IOException, PortletException {
+ return ((ClientDataRequest)wrapped).getPart(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.portlet.ClientDataRequest#getParts()
+ */
+ @Override
+ public Collection<Part> getParts() throws IOException, PortletException {
+ return ((ClientDataRequest)wrapped).getParts();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/javadoc/overview.html b/portlet-api/src/main/javadoc/overview.html
index 3e4cbbe..851b116 100644
--- a/portlet-api/src/main/javadoc/overview.html
+++ b/portlet-api/src/main/javadoc/overview.html
@@ -27,6 +27,14 @@
{@link javax.portlet.PortletRequest#getUserAgent() PortletRequest#getUserAgent()}.
and altered the corresponding wrapper class accordingly.
Removed the PortletRequest#USER_AGENT constant, as an alternative implementation was agreed upon.
+ <p>
+ Added multipart support to fulfill
+ <a href="https://java.net/jira/browse/PORTLETSPEC3-67">PORTLETSPEC3-67</a>.
+ See
+ {@link javax.portlet.annotations.PortletConfiguration#multipart() PortletConfiguration#multipart()},
+ {@link javax.portlet.annotations.Multipart Multipart},
+ {@link javax.portlet.ClientDataRequest#getPart(String)}, and
+ {@link javax.portlet.ClientDataRequest#getParts()}.
</li>
<li>
20160406:
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1217bb1e/portlet-api/src/main/javadoc/portlet-api.css
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/javadoc/portlet-api.css b/portlet-api/src/main/javadoc/portlet-api.css
index 7f6b832..ee8d459 100644
--- a/portlet-api/src/main/javadoc/portlet-api.css
+++ b/portlet-api/src/main/javadoc/portlet-api.css
@@ -579,6 +579,7 @@ h1.hidden {
.indexContainer a[href*="LocaleString.html"],
.indexContainer a[href*="package-info.html"],
.indexContainer a[href*="MethodToken.html"],
+.indexContainer a[href*="Multipart.html"],
.indexContainer a[href*="MimeResponseWrapper.html"],
.indexContainer a[href*="Namespace.html"],
.indexContainer a[href*="PortletApplication.html"],
[2/2] portals-pluto git commit: Activated multipart support for the
portal driver servlet in order to allow multipart support to work for
individual portlets. Added a MultipartPortlet demo that can upload and
display a file.
Posted by ms...@apache.org.
Activated multipart support for the portal driver servlet in order to allow
multipart support to work for individual portlets. Added a MultipartPortlet
demo that can upload and display a file.
Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/a671849a
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/a671849a
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/a671849a
Branch: refs/heads/master
Commit: a671849a8c04e01cb7957026710c4d23acce7d72
Parents: 1217bb1
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Apr 19 15:48:36 2016 +0200
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Apr 19 15:48:36 2016 +0200
----------------------------------------------------------------------
.../portals/samples/MultipartPortlet.java | 237 +++++++++++++++++++
.../main/webapp/WEB-INF/jsp/multipartDialog.jsp | 65 +++++
pluto-portal/src/main/webapp/WEB-INF/web.xml | 3 +
3 files changed, 305 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a671849a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/MultipartPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/MultipartPortlet.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/MultipartPortlet.java
new file mode 100644
index 0000000..797e53d
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/MultipartPortlet.java
@@ -0,0 +1,237 @@
+/* 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.portals.samples;
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ServeResourceMethod;
+import javax.servlet.http.Part;
+
+/**
+ * Test vehicle for multipart orm support
+ *
+ * @author Scott Nicklous
+ *
+ */
+public class MultipartPortlet {
+ private static final Logger LOGGER = Logger.getLogger(MultipartPortlet.class.getName());
+
+ private static final String JSP = "/WEB-INF/jsp/multipartDialog.jsp";
+ private static final String TMP = "/temp/";
+
+ @ActionMethod(portletName = "MultipartPortlet")
+ public void handleDialog(ActionRequest req, ActionResponse resp) throws IOException, PortletException {
+ List<String> lines = new ArrayList<String>();
+ req.getPortletSession().setAttribute("lines", lines);
+
+ lines.add("handling dialog");
+ StringBuilder txt = new StringBuilder(128);
+
+ String clr = req.getActionParameters().getValue("color");
+ txt.append("Color: ").append(clr);
+ lines.add(txt.toString());
+ LOGGER.fine(txt.toString());
+
+ resp.getRenderParameters().setValue("color", clr);
+
+ txt.setLength(0);
+ Part part = null;
+ try {
+ part = req.getPart("file");
+ } catch (Throwable t) {}
+
+ if ((part != null) && (part.getSubmittedFileName() != null) &&
+ (part.getSubmittedFileName().length() > 0)) {
+ txt.append("Uploaded file name: ").append(part.getSubmittedFileName());
+ txt.append(", part name: ").append(part.getName());
+ txt.append(", size: ").append(part.getSize());
+ txt.append(", content type: ").append(part.getContentType());
+ lines.add(txt.toString());
+ LOGGER.fine(txt.toString());
+ txt.setLength(0);
+ txt.append("Headers: ");
+ String sep = "";
+ for (String hdrname : part.getHeaderNames()) {
+ txt.append(sep).append(hdrname).append("=").append(part.getHeaders(hdrname));
+ sep = ", ";
+ }
+ lines.add(txt.toString());
+ LOGGER.fine(txt.toString());
+
+ // Store the file in a temporary location in the webapp where it can be served.
+ // Note that this is, in general, not what you want to do in production, as
+ // there can be problems serving the resource. Did it this way for a
+ // quick solution that doesn't require additional Tomcat configuration.
+
+ try {
+ String path = req.getPortletContext().getRealPath(TMP);
+ File dir = new File(path);
+ lines.add("Temp path: " + dir.getCanonicalPath());
+ if (!dir.exists()) {
+ lines.add("Creating directory. Path: " + dir.getCanonicalPath());
+ Files.createDirectories(dir.toPath());
+ }
+ String fn = TMP + part.getSubmittedFileName();
+ lines.add("Temp file: " + fn);
+ path = req.getPortletContext().getRealPath(fn);
+ File img = new File(path);
+ if (img.exists()) {
+ lines.add("deleting existing temp file.");
+ img.delete();
+ }
+ InputStream is = part.getInputStream();
+ Files.copy(is, img.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+ resp.getRenderParameters().setValue("fn", fn);
+ resp.getRenderParameters().setValue("ct", part.getContentType());
+
+ } catch (Exception e) {
+ lines.add("Exception doing I/O: " + e.toString());
+ }
+ } else {
+ lines.add("file part was null");
+ }
+
+ }
+
+ @RenderMethod(portletNames = "MultipartPortlet")
+ public void render(RenderRequest req, RenderResponse resp) throws PortletException, IOException {
+ List<String> lines = new ArrayList<String>();
+ @SuppressWarnings("unchecked")
+ List<String> actionlines = (List<String>) req.getPortletSession().getAttribute("lines");
+ if (actionlines != null) {
+ lines.addAll(actionlines);
+ }
+ req.setAttribute("lines", lines);
+ lines.add("rendering");
+
+ String clr = req.getRenderParameters().getValue("color");
+ if (clr == null) {
+ clr = "#E0FFE0";
+ }
+ req.setAttribute("color", clr);
+
+ // If there is a temp file, read it
+
+ String fn = req.getRenderParameters().getValue("fn");
+ String ct = req.getRenderParameters().getValue("ct");
+ if ((fn == null) || (ct == null)) {
+ lines.add("No file stored.");
+ } else {
+ StringBuilder txt = new StringBuilder(128);
+ txt.append("Rendering with file: ").append(fn);
+ txt.append(", type: ").append(ct);
+ lines.add(txt.toString());
+
+ List<String> flist = new ArrayList<String>();
+ req.setAttribute("flist", flist);
+
+ FileInputStream fis = null;
+ BufferedReader rdr = null;
+ try {
+ String path = req.getPortletContext().getRealPath(fn);
+ File file = new File(path);
+ fis = new FileInputStream(file);
+
+ if (ct.equals("text/plain")) {
+ lines.add("Processing text file.");
+ if (file.length() < 2000) {
+ rdr = new BufferedReader(new InputStreamReader(fis));
+ String line;
+ while ((line = rdr.readLine()) != null) {
+ line = line.replaceAll("&", "&");
+ line = line.replaceAll(" ", " ");
+ line = line.replaceAll("<", "<");
+ flist.add(line);
+ }
+ } else {
+ flist.add("Sorry, file size > 2000 and is too big.");
+ }
+ } else if (ct.matches("image/(?:gif|jpg|jpeg)")) {
+ lines.add("Processing image.");
+
+ BufferedImage bimg = ImageIO.read(fis);
+ int h = bimg.getHeight();
+ int w = bimg.getWidth();
+
+ txt.setLength(0);
+ txt.append("Image height: ").append(h);
+ txt.append(", width: ").append(w);
+ lines.add(txt.toString());
+
+ req.setAttribute("h", h);
+ req.setAttribute("w", w);
+ req.setAttribute("img", fn);
+
+ } else {
+ flist.add("Sorry, can't display this kind of file.");
+ }
+ } catch (Exception e) {
+ flist.add("Exception preparing for render: " + e.toString());
+ } finally {
+ if (rdr != null) {
+ rdr.close();
+ }
+ if (fis != null) {
+ fis.close();
+ }
+ }
+ }
+
+ PortletRequestDispatcher rd = req.getPortletContext().getRequestDispatcher(JSP);
+ rd.include(req, resp);
+ }
+
+ @ServeResourceMethod(portletNames="MultipartPortlet")
+ public void serveImage(ResourceRequest req, ResourceResponse resp) throws IOException {
+ String fn = req.getRenderParameters().getValue("fn");
+ String ct = req.getRenderParameters().getValue("ct");
+
+ resp.setContentType(ct);
+
+ String path = req.getPortletContext().getRealPath(fn);
+ File file = new File(path);
+ OutputStream os = resp.getPortletOutputStream();
+ Files.copy(file.toPath(), os);
+ os.flush();
+ }
+}
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a671849a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/multipartDialog.jsp
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/multipartDialog.jsp b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/multipartDialog.jsp
new file mode 100644
index 0000000..991ce8c
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/multipartDialog.jsp
@@ -0,0 +1,65 @@
+<%@ page session="false" %>
+<%@ page isELIgnored ="false" %>
+<%@ taglib uri="http://xmlns.jcp.org/portlet_3_0" prefix="portlet" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
+
+<html><head>
+<meta charset="UTF-8">
+<title>Multipart Portlet</title>
+<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/resources/css/infobox.css">
+</head>
+<body>
+
+<portlet:defineObjects />
+
+<h3>Multipart Portlet</h3>
+<p>
+This portlet is used to exercise multipart form support.
+It allows a file to be selected and displays its contents.
+</p>
+
+<div class='parmbox'>
+<FORM ACTION='<portlet:actionURL/>' method='POST' enctype='multipart/form-data'>
+ <table style='width:100%;'><tr><td align='left'>
+
+ Select color:
+ </td><td>
+ <input name='color' type='color' value='${color}'>
+ </td><td>
+ </td></tr><tr><td>
+
+ Select file:
+ </td><td>
+ <input name='file' type='file'>
+
+ </td></tr><tr><td>
+ <INPUT VALUE='submit' TYPE='submit'>
+
+ </td></tr></table>
+</FORM>
+</div>
+
+<hr>
+<div class='infobox' style='background-color: ${color};'>
+<h5>Info:</h5>
+<c:forEach items="${lines}" var='line'>
+ ${line}<br>
+</c:forEach>
+</div>
+
+<hr>
+<div class='orangebox'>
+<h5>File contents:</h5>
+
+<c:forEach items="${flist}" var='line'>
+ ${line}<br>
+</c:forEach>
+
+<c:if test="${img != null}">
+<p>
+ <img alt="temp image" height="${h}" width="${w}" src='<portlet:resourceURL/>'>
+</p>
+</c:if>
+</div>
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a671849a/pluto-portal/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/web.xml b/pluto-portal/src/main/webapp/WEB-INF/web.xml
index 283560b..b23007d 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/web.xml
+++ b/pluto-portal/src/main/webapp/WEB-INF/web.xml
@@ -57,6 +57,9 @@ limitations under the License.
<servlet-name>plutoPortalDriver</servlet-name>
<servlet-class>org.apache.pluto.driver.PortalDriverServlet</servlet-class>
<async-supported>true</async-supported>
+ <multipart-config>
+ <file-size-threshold>1048576</file-size-threshold>
+ </multipart-config>
</servlet>
<servlet>