[PORTLETSPEC3-60] Portlet Analogs for new Servlet Response Methods Created: 01/Sep/15  Updated: 01/Sep/15

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

My proposals for handling the ServletResponse and HttpServletResponse methods added since servlet version 2.4 appear below in the table cell adjacent to the servlet response method name. The description in the code example box (grey) is that of the original servlet method.


setContentLengthLong add ResourceResponse#setContentLengthLong method

    void setContentLengthLong(long len)

    Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length header.

    Parameters: len - a long specifying the length of the content being returned to the client; sets the Content-Length header
    Since: Servlet 3.1

getStatus add ResourceResponse#getStatus method

    int getStatus()

    Gets the current status code of this response.

    Returns: the current status code of this response
    Since: Servlet 3.0

getHeader add PortletResponse#getProperty method; returns only property for current portlet

    String getHeader(String name)

    Gets the value of the response header with the given name.

    If a response header with the given name exists and contains multiple values, the value that was added first will be returned.

    This method considers only response headers set or added via setHeader(java.lang.String, java.lang.String), addHeader(java.lang.String, java.lang.String), setDateHeader(java.lang.String, long), addDateHeader(java.lang.String, long), setIntHeader(java.lang.String, int), or addIntHeader(java.lang.String, int), respectively.

    Parameters: name - the name of the response header whose value to return
    Returns: the value of the response header with the given name, or null if no header with the given name has been set on this response
    Since: Servlet 3.0

getHeaders add PortletResponse#getProperties method; returns only values added / set by current portlet

    Collection<String> getHeaders(String name)

    Gets the values of the response header with the given name.

    This method considers only response headers set or added via setHeader(java.lang.String, java.lang.String), addHeader(java.lang.String, java.lang.String), setDateHeader(java.lang.String, long), addDateHeader(java.lang.String, long), setIntHeader(java.lang.String, int), or addIntHeader(java.lang.String, int), respectively.

    Any changes to the returned Collection must not affect this HttpServletResponse.

    Parameters: name - the name of the response header whose values to return
    Returns: a (possibly empty) Collection of the values of the response header with the given name
    Since: Servlet 3.0

getHeaderNames add PortletResponse#getPropertyNames method; returns only properties for current portlet.

    Collection<String> getHeaderNames()

    Gets the names of the headers of this response.

    This method considers only response headers set or added via setHeader(java.lang.String, java.lang.String), addHeader(java.lang.String, java.lang.String), setDateHeader(java.lang.String, long), addDateHeader(java.lang.String, long), setIntHeader(java.lang.String, int), or addIntHeader(java.lang.String, int), respectively.

    Any changes to the returned Collection must not affect this HttpServletResponse.

    Returns: a (possibly empty) Collection of the names of the headers of this response
    Since: Servlet 3.0





[PORTLETSPEC3-40] Add new javax.portlet.ResourceComparator annotation in order to identify duplicate resources Created: 13/Dec/13  Updated: 13/May/14

Status: Open
Project: portletspec3
Component/s: Ideas for JSR 362 Extensions
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Neil Griffin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I would like to propose the following annotation, which
would allow portlet developers (and JSF portlet bridge implementors)
to provide a way to inform the portlet container of duplicate
resources. This is a common problem with JSF portlets, since each
JSF portlet on the portal page needs the "jsf.js" resource:

package javax.portlet;
/**
* Annotation for marking a class that compares resource URLs. Such classes are
* discovered by the portlet container at startup and are required to
* implement the {@link java.util.Comparator} interface in order to compare
* resources represented as type {@link java.lang.String}. If the
* {@link java.util.Comparator#compare(Object, Object)} method returns 0, then
* the portlet container will consider the resources to be identical and will include
* only the first resource in the &lt;head/&gt; section of the rendered portal page.
*
* @since 3.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceComparator {
}

Here is an example that a JSF portlet bridge could use in order to prevent duplicate JSF resources:

public interface FacesResource {

	public enum TYPE {
		HREF, LINK, SCRIPT
	}
	
	public TYPE getType();
	
	public String getName();
	
	public String getLibrary();
}
@ResourceComparator
public class FacesResourceComparator implements Comparator<String> {

	public int compare(String resourceURL1, String resourceURL2) {

		if (isFacesResource(resourceURL1) && isFacesResource(resourceURL2)) {
				
				FacesResource facesResource1 = new FacesResourceImpl(resourceURL1);
				FacesResource facesResource2 = new FacesResourceImpl(resourceURL2);

				if (facesResource1.equals(facesResource2)) {
					return 0;
				}
				else {
					return -1;
				}
		}
		else {
			return -1;
		}
	}

	protected boolean isFacesResource(String url) {
		return ((url != null) && url.contains("javax.faces.resource"));
	}
}


 Comments   
Comment by kito75 [ 14/Jan/14 ]

Sounds good to me. Would we need a default implementation?

Comment by Ed Burns [ 13/May/14 ]

This seems like a tough problem to solve in the absence of a component based rendering model.

Comment by Ed Burns [ 13/May/14 ]

I would need to see more context to be able to critique this. I don't know enough about the portlet runtime to understand who would be instantiating the FacesResourceComparator and when it would be getting invoked, for example.

Comment by Neil Griffin [ 13/May/14 ]

After each portlet on a page has undergone the RENDER_PHASE of the portlet lifecycle, the portal server is responsible for assembling a complete HTML document. When it comes time for the portal server to build up the contents of the <head>...</head> section, the portal server would invoke classes marked with @ResourceComparator in order to let individual portlets determine whether or not two resources are essentially identical. One example would be a portal page with two or more JSF portlets. Each JSF portlet would attempt to add jsf.js to the <head>...</head> section. The JSF Portlet Bridge could have a class annotated with @ResourceComparator that would be able to identify duplicate jsf.js inclusions. The portal server would then know that it should only include the first instance of jsf.js in the <head>...</head> section.





[PORTLETSPEC3-53] New Methods for PortletContext Created: 05/Aug/15  Updated: 25/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: Neil Griffin
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

1. Should the portlet container runtime options be configurable through annotations?

The current annotations proposal does not include the portlet container runtime options because the annotations are all portlet-specific while the deployment descriptor allows runtime options to be declared at both the portlet application and portlet levels.

However, it might be good to allow portlet-level portlet container runtime options to be specified through annotations.

2. Many new methods were added to ServletContext since Servlet v2.4. These primarily allow servlets to be defined dynamically which might be good for framework or test purposes.

Do we want to provide analogous methods for the portlet context? The following table shows my initial guess. The Method column lists the method from the ServletContext. The Version column lists the servlet version that introduced the new method.

Method Version Comments
String getContextPath() 2.5 yes
int getEffectiveMajorVersion() 3.0 yes
int getEffectiveMinorVersion() 3.0 yes
boolean setInitParameter(String name, String value) 3.0 no
ServletRegistration.Dynamic addServlet(String servletName, String className) 3.0 no
ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) 3.0 no
ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) 3.0 no
<T extends Servlet> T createServlet(Class<T> clazz) 3.0 no
ServletRegistration getServletRegistration(String servletName) 3.0 no
Map<String,? extends ServletRegistration> getServletRegistrations() 3.0 no
FilterRegistration.Dynamic addFilter(String filterName, String className) 3.0 no
FilterRegistration.Dynamic addFilter(String filterName, Filter filter) 3.0 no
FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) 3.0 no
<T extends Filter> T createFilter(Class<T> clazz) 3.0 no
FilterRegistration getFilterRegistration(String filterName) 3.0 no
Map<String,? extends FilterRegistration> getFilterRegistrations() 3.0 no
SessionCookieConfig getSessionCookieConfig() 3.0 no
void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) 3.0 no
Set<SessionTrackingMode> getDefaultSessionTrackingModes() 3.0 no
Set<SessionTrackingMode> getEffectiveSessionTrackingModes() 3.0 no
void addListener(String className) 3.0 no
<T extends EventListener> void addListener(T t) 3.0 no
void addListener(Class<? extends EventListener> listenerClass) 3.0 no
<T extends EventListener> T createListener(Class<T> clazz) 3.0 no
JspConfigDescriptor getJspConfigDescriptor() 3.0 no
ClassLoader getClassLoader() 3.0 yes
void declareRoles(String... roleNames) 3.0 no
String getVirtualServerName() 3.0 no

3. Please review section on "7.4.4 Runtime Option javax.portlet.actionScopedRequestAttributes".



 Comments   
Comment by msnicklous [ 25/Jan/16 ]

1) The container runtime options can be specified through annotations. See spec section 28.1.12. See @PortletApplication annotation.

2) In the servlet world, the methods marked with 'no' in the comments column are primarily useful in a servlet container initializer setting. While it might be useful to provide a similar functionality for portlets, I believe it would go beyond the scope of the version 3.0 spec to do so. The methods marked with 'yes' will be implemented for v3.





[PORTLETSPEC3-59] Portlet Analogs for new Servlet Request Methods Created: 01/Sep/15  Updated: 28/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The following ServletRequest and HttpServletRequest methods have been added since v2.4. I've added my suggestions for how they should be dealt with when mapped to portlets in the table cell adjacent to the servlet request method name. The description in the code example box (grey) is that of the original servlet method.


getContentLengthLong add ClientDataRequest#getContentLengthLong method

    long getContentLengthLong()

    Returns the length, in bytes, of the request body and made available by the input stream, or -1 if the length is not known. For HTTP servlets, same as the value of the CGI variable CONTENT_LENGTH.

    Returns: a long containing the length of the request body or -1L if the length is not known
    Since: Servlet 3.1


getServletContext add PortletRequest#getPortletContext()

    ServletContext getServletContext()

    Gets the servlet context to which this ServletRequest was last dispatched.

    Returns: the servlet context to which this ServletRequest was last dispatched
    Since: Servlet 3.0

startAsync Add ResourceRequest#startAsync

    AsyncContext startAsync() throws IllegalStateException

    Puts this request into asynchronous mode, and initializes its AsyncContext with the original (unwrapped) ServletRequest and ServletResponse objects.

    Calling this method will cause committal of the associated response to be delayed until AsyncContext.complete() is called on the returned AsyncContext, or the asynchronous operation has timed out.

    Calling AsyncContext.hasOriginalRequestAndResponse() on the returned AsyncContext will return true. Any filters invoked in the outbound direction after this request was put into asynchronous mode may use this as an indication that any request and/or response wrappers that they added during their inbound invocation need not stay around for the duration of the asynchronous operation, and therefore any of their associated resources may be released.

    This method clears the list of AsyncListener instances (if any) that were registered with the AsyncContext returned by the previous call to one of the startAsync methods, after calling each AsyncListener at its onStartAsync method.

    Subsequent invocations of this method, or its overloaded variant, will return the same AsyncContext instance, reinitialized as appropriate.

    Returns: the (re)initialized AsyncContext
    Throws: IllegalStateException - if this request is within the scope of a filter or servlet that does not support asynchronous operations (that is, isAsyncSupported() returns false), or if this method is called again without any asynchronous dispatch (resulting from one of the AsyncContext.dispatch() methods), is called outside the scope of any such dispatch, or is called again within the scope of the same dispatch, or if the response has already been closed
    Since: Servlet 3.0
    See Also: AsyncContext.dispatch()

startAsync Add ResourceRequest#startAsync

    AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException

    Puts this request into asynchronous mode, and initializes its AsyncContext with the given request and response objects.

    The ServletRequest and ServletResponse arguments must be the same instances, or instances of ServletRequestWrapper and ServletResponseWrapper that wrap them, that were passed to the service method of the Servlet or the doFilter method of the Filter, respectively, in whose scope this method is being called.

    Calling this method will cause committal of the associated response to be delayed until AsyncContext.complete() is called on the returned AsyncContext, or the asynchronous operation has timed out.

    Calling AsyncContext.hasOriginalRequestAndResponse() on the returned AsyncContext will return false, unless the passed in ServletRequest and ServletResponse arguments are the original ones or do not carry any application-provided wrappers. Any filters invoked in the outbound direction after this request was put into asynchronous mode may use this as an indication that some of the request and/or response wrappers that they added during their inbound invocation may need to stay in place for the duration of the asynchronous operation, and their associated resources may not be released. A ServletRequestWrapper applied during the inbound invocation of a filter may be released by the outbound invocation of the filter only if the given servletRequest, which is used to initialize the AsyncContext and will be returned by a call to AsyncContext.getRequest(), does not contain said ServletRequestWrapper. The same holds true for ServletResponseWrapper instances.

    This method clears the list of AsyncListener instances (if any) that were registered with the AsyncContext returned by the previous call to one of the startAsync methods, after calling each AsyncListener at its onStartAsync method.

    Subsequent invocations of this method, or its zero-argument variant, will return the same AsyncContext instance, reinitialized as appropriate. If a call to this method is followed by a call to its zero-argument variant, the specified (and possibly wrapped) request and response objects will remain locked in on the returned AsyncContext.

    Parameters: servletRequest - the ServletRequest used to initialize the AsyncContext
        servletResponse - the ServletResponse used to initialize the AsyncContext
    Returns: the (re)initialized AsyncContext
    Throws: IllegalStateException - if this request is within the scope of a filter or servlet that does not support asynchronous operations (that is, isAsyncSupported() returns false), or if this method is called again without any asynchronous dispatch (resulting from one of the AsyncContext.dispatch() methods), is called outside the scope of any such dispatch, or is called again within the scope of the same dispatch, or if the response has already been closed
    Since: Servlet 3.0

isAsyncStarted Add ResourceRequest#isAsyncStarted

    boolean isAsyncStarted()

    Checks if this request has been put into asynchronous mode.

    A ServletRequest is put into asynchronous mode by calling startAsync() or startAsync(ServletRequest,ServletResponse) on it.

    This method returns false if this request was put into asynchronous mode, but has since been dispatched using one of the AsyncContext.dispatch() methods or released from asynchronous mode via a call to AsyncContext.complete().

    Returns: true if this request has been put into asynchronous mode, false otherwise
    Since: Servlet 3.0

isAsyncSupported Add ResourceRequest#isAsyncSupported

    boolean isAsyncSupported()

    Checks if this request supports asynchronous operation.

    Asynchronous operation is disabled for this request if this request is within the scope of a filter or servlet that has not been annotated or flagged in the deployment descriptor as being able to support asynchronous handling.

    Returns: true if this request supports asynchronous operation, false otherwise
    Since: Servlet 3.0

getAsyncContext Add ResourceRequest#getAsyncContext

    AsyncContext getAsyncContext()

    Gets the AsyncContext that was created or reinitialized by the most recent invocation of startAsync() or startAsync(ServletRequest,ServletResponse) on this request.

    Returns: the AsyncContext that was created or reinitialized by the most recent invocation of startAsync() or startAsync(ServletRequest,ServletResponse) on this request
    Throws: IllegalStateException - if this request has not been put into asynchronous mode, i.e., if neither startAsync() nor startAsync(ServletRequest,ServletResponse) has been called
    Since: Servlet 3.0

getDispatcherType add PortletRequest#getDispatcherType

    DispatcherType getDispatcherType()

    Gets the dispatcher type of this request.

    The dispatcher type of a request is used by the container to select the filters that need to be applied to the request: Only filters with matching dispatcher type and url patterns will be applied.

    Allowing a filter that has been configured for multiple dispatcher types to query a request for its dispatcher type allows the filter to process the request differently depending on its dispatcher type.

    The initial dispatcher type of a request is defined as DispatcherType.REQUEST. The dispatcher type of a request dispatched via RequestDispatcher.forward(ServletRequest, ServletResponse) or RequestDispatcher.include(ServletRequest, ServletResponse) is given as DispatcherType.FORWARD or DispatcherType.INCLUDE, respectively, while the dispatcher type of an asynchronous request dispatched via one of the AsyncContext.dispatch() methods is given as DispatcherType.ASYNC. Finally, the dispatcher type of a request dispatched to an error page by the container's error handling mechanism is given as DispatcherType.ERROR.

    Returns: the dispatcher type of this request
    Since: Servlet 3.0
    See Also: DispatcherType

====
changeSessionId No support

    String changeSessionId()

    Change the session id of the current session associated with this request and return the new session id.

    Returns: the new session id
    Throws: IllegalStateException - if there is no session associated with the request
    Since: Servlet 3.1


authenticate add ClientDataRequest#authenticate

    boolean authenticate(HttpServletResponse response) throws IOException, ServletException

    Use the container login mechanism configured for the ServletContext to authenticate the user making this request.

    This method may modify and commit the argument HttpServletResponse.

    Parameters: response - The HttpServletResponse associated with this HttpServletRequest
    Returns: true when non-null values were or have been established as the values returned by getUserPrincipal, getRemoteUser, and getAuthType. Return false if authentication is incomplete and the underlying login mechanism has committed, in the response, the message (e.g., challenge) and HTTP status code to be returned to the user.
    Throws: IOException - if an input or output error occurred while reading from this request or writing to the given response
        IllegalStateException - if the login mechanism attempted to modify the response and it was already committed
        ServletException - if the authentication failed and the caller is responsible for handling the error (i.e., the underlying login mechanism did NOT establish the message and HTTP status code to be returned to the user)
    Since: Servlet 3.0

login add ClientDataRequest#login

    void login(String username, String password) throws ServletException

    Validate the provided username and password in the password validation realm used by the web container login mechanism configured for the ServletContext.

    This method returns without throwing a ServletException when the login mechanism configured for the ServletContext supports username password validation, and when, at the time of the call to login, the identity of the caller of the request had not been established (i.e, all of getUserPrincipal, getRemoteUser, and getAuthType return null), and when validation of the provided credentials is successful. Otherwise, this method throws a ServletException as described below.

    When this method returns without throwing an exception, it must have established non-null values as the values returned by getUserPrincipal, getRemoteUser, and getAuthType.

    Parameters: username - The String value corresponding to the login identifier of the user.
        password - The password String corresponding to the identified user.
    Throws: ServletException - if the configured login mechanism does not support username password authentication, or if a non-null caller identity had already been established (prior to the call to login), or if validation of the provided username and password fails.
    Since: Servlet 3.0

logout add ClientDataRequest#logout

    void logout() throws ServletException

    Establish null as the value returned when getUserPrincipal, getRemoteUser, and getAuthType is called on the request.

    Throws: ServletException - if logout fails
    Since: Servlet 3.0

getParts add ClientDataRequest#getParts

    Collection<Part> getParts() throws IOException, ServletException

    Gets all the Part components of this request, provided that it is of type multipart/form-data.

    If this request is of type multipart/form-data, but does not contain any Part components, the returned Collection will be empty.

    Any changes to the returned Collection must not affect this HttpServletRequest.

    Returns: 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
        ServletException - if this request is not of type multipart/form-data
        IllegalStateException - if the request body is larger than maxRequestSize, or any Part in the request is larger than maxFileSize, or there is no @MultipartConfig or multipart-config in deployment descriptors
    Since: Servlet 3.0
    See Also: MultipartConfig.maxFileSize(), MultipartConfig.maxRequestSize()

getPart add ClientDataRequest#getPart

    Part getPart(String name) throws IOException, ServletException

    Gets the Part with the given name.

    Parameters: name - the name of the requested Part
    Returns: 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 requested Part
        ServletException - if this request is not of type multipart/form-data
        IllegalStateException - if the request body is larger than maxRequestSize, or any Part in the request is larger than maxFileSize, or there is no @MultipartConfig or multipart-config in deployment descriptors
    Since: Servlet 3.0
    See Also: MultipartConfig.maxFileSize(), MultipartConfig.maxRequestSize()

upgrade Add ResourceRequest#upgrade

    <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException

    Create an instance of HttpUpgradeHandler for an given class and uses it for the http protocol upgrade processing.

    Parameters: handlerClass - The HttpUpgradeHandler class used for the upgrade.
    Returns: an instance of the HttpUpgradeHandler
    Throws: IOException - if an I/O error occurred during the upgrade
        ServletException - if the given handlerClass fails to be instantiated
    Since: Servlet 3.1
    See Also: HttpUpgradeHandler, WebConnection





[PORTLETSPEC3-65] Add Protocol Upgrade Support Created: 29/Jan/16  Updated: 29/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PORTLETSPEC3-59 for method descriptions.

This will enable web socket support.

Add the following methods:

ResourceRequest#upgrade
String ResourceRequest#getProtocol()

The getProtocol method will return null if the request is not an upgrade request and will return the requested protocol string if it is an upgrade request.

The client would be able to use a resource URL to initiate the protocol upgrade.

The alternative would be to introduce a new, dedicated URL type along with the corresponding request and response types and request handling methods, but I believe that would be too complicated and would not add much value.






[PORTLETSPEC3-63] Make user agent available to Portlets Created: 29/Jan/16  Updated: 29/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

We should make the use agent available to portlets in a standard manner. The alternatives are:

1) Add the PortletRequest#getUserAgent() method and specify that it always must return the user agent string.

2) Change the spec so that PortletRequest#getProperty("User-Agent") always must return the user agent string.

3) Require support for the javax.ccpp.Profile that can be obtained through:

Profile prof = (Profile) ((PortletRequest)request).getAttribute(PortletRequest.CCPP_PROFILE);
Attribute attr = prof.getAttribute(deviceAttribute);

I think I would choose #2 unless there are opinions to the contrary.






[PORTLETSPEC3-64] Add miscellaneous request APIs for servlet 3.1 alignment Created: 29/Jan/16  Updated: 29/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PORTLETSPEC3-59 for method descriptions.

Add the following methods:

ClientDataRequest#getContentLengthLong method
PortletRequest#getPortletContext()
PortletRequest#getDispatcherType





[PORTLETSPEC3-67] Add Multipart Support Created: 29/Jan/16  Updated: 29/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PORTLETSPEC3-59 for method descriptions.

Multipart requests should be supported to allow file uploads, etc.

Add the following methods:

ClientDataRequest#getParts
ClientDataRequest#getPart

Configuration:

1) Add a Multipart annotation that can only be used within an @PortletConfiguration annotation
to provide the required configuration data.

@Multipart(location="/tmp", fileSizeThreshold=1024*1024, 
    maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)

2) Allow the same info to be specified through the portlet deployment descriptor
on a per-portlet basis.

<portlet>
   ...
   <multipart-config>
       <location>/tmp</location>
       <max-file-size>20848820</max-file-size>
       <max-request-size>418018841</max-request-size>
       <file-size-threshold>1048576</file-size-threshold>
   </multipart-config>
</portlet>

The alternative to adding a new annotation would be to just require use of
the javax.servlet.annotation.MultipartConfig annotation. However, I think
that might be a problem, since it is not specified how a servlet container
has to react when this annotation is applied to a non-Servlet class. Some servlet
containers might just ignore it, while others might reject the whole application
at deployment time. So I think it would be better to add our own annotation.






[PORTLETSPEC3-66] Add new Security Methods Created: 29/Jan/16  Updated: 29/Jan/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PORTLETSPEC3-59 for method descriptions.

This will allow a login portlet to be written or step-up authentication to be supported.

Add the following methods:

ClientDataRequest#authenticate
ClientDataRequest#login
ClientDataRequest#logout





[PORTLETSPEC3-68] Add Async Support Created: 29/Jan/16  Updated: 01/Feb/16

Status: Open
Project: portletspec3
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: msnicklous Assignee: msnicklous
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PORTLETSPEC3-59 for method descriptions.

Add Async support for resource requests.

Add the following methods:

ResourceRequest#startAsync
ResourceRequest#startAsync
ResourceRequest#isAsyncStarted
ResourceRequest#isAsyncSupported
ResourceRequest#getAsyncContext

This still needs to be detailed out, but would at first glance also entail introducing the necessary async objects to properly wrap the ResourceRequest / ResourceResponse and to avoid directly exposing the underlying servlet artifacts. This might mean introduction of classes like the following with methods that match the corresponding servlet classes:

PortletAsyncContext
PortletAsyncListener
PortletAsyncEvent

Providing these classes would allow portlets that use async to access the render and resource parameters that were in effect during the original request.

I think that async support should be limited to the resource phase, as it makes little sense for the action and event phases, and would be to difficult to support for the render phase.



 Comments   
Comment by kito75 [ 29/Jan/16 ]

Why don't you think this should be supported in the Action phase? It might be useful for executing business logic.

Comment by msnicklous [ 29/Jan/16 ]

I can actually see the use case for async support in the action method for executing long-running business logic. It's more of a question of cost effectiveness and complexity I think.

My thinking goes like this ...

Async support provides a performance benefit by off-loading a long-running process from a request thread to a separate thread and by allowing the request to respond using non-blocking IO.

A portal system is often (probably almost always) implemented as a system of servlets. The portal servlet is the central entry point for incoming requests. The portal servlet includes or forwards requests to the portlet servlets in order to cause them to execute the portlet methods.

With the resource request, the portal servlet passes the request to the target portlet servlet containing the resource method to be executed. In the Pluto RI (and I suspect many other portal implementations) the portal servlet actually forwards the request to the target portlet servlet. The resource method executed by the portlet servlet has nearly complete control over the response. If the resource method starts async processing, the request thread is freed up, and the resource method can make use of non-blocking IO when generating its response.

With an action method, the portal servlet has to wait for the portlet servlet to complete its action method processing so that it can either directly perform a page render or issue a redirect to the target render URL, causing the page to be rendered. If the action method starts async processing, the portal servlet would still be blocked, so it would seem that there wouldn't be much potential benefit from freeing the response thread. Also, the action method doesn't produce any response output, so there is no benefit from non-blocking IO. And although I haven't tried it out, it seems to me like there could be synchronization issues between the portal servlet and the portlet servlet that could come up if action methods were to provide async support.

So it seems to me like providing async support in the action method would potentially imply considerable additional complexity without providing a really clear benefit. Async support in the resource method provides a clear benefit and should be fairly straight-forward to implement.

Comment by kito75 [ 01/Feb/16 ]

Hmmm.. couldn't the action method execute an async task and then just return? (Perhaps leaving the portlet to be notified later via WebSocket or polling?)





Generated at Sat Feb 06 00:10:52 UTC 2016 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.