You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2008/04/10 01:39:33 UTC
svn commit: r646598 - in
/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched:
api/src/main/java/javax/portlet/faces/
impl/src/main/java/org/apache/myfaces/portlet/faces/application/
impl/src/main/java/org/apache/myfaces/portlet/faces/...
Author: sobryan
Date: Wed Apr 9 16:39:32 2008
New Revision: 646598
URL: http://svn.apache.org/viewvc?rev=646598&view=rev
Log:
Some initial changes to this branch
Modified:
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/Bridge.java
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/FacesContextFactoryImpl.java
myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/Bridge.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/Bridge.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/Bridge.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/Bridge.java Wed Apr 9 16:39:32 2008
@@ -16,6 +16,8 @@
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
import javax.portlet.UnavailableException;
/**
@@ -117,6 +119,12 @@
/**
* Special token parameter in the url passed to the bridge's ExternalContext.encodeResourceURL()
+ * that it recognizes as an indication that this resource should be handled in protocol.
+ */
+ public static final String IN_PROTOCOL_RESOURCE_LINK = BRIDGE_PACKAGE_PREFIX + "InProtocolResourceLink";
+
+ /**
+ * Special token parameter in the url passed to the bridge's ExternalContext.encodeResourceURL()
* that it recognizes as an indication that an URL refering back to the page which
* contains this portlet should be encoded in the resource url. This reference is
* encoded as the value of a query string parameter whose name is the value of this back
@@ -208,7 +216,7 @@
public static enum PortletPhase
{
- ACTION_PHASE, RENDER_PHASE;
+ ACTION_PHASE, RENDER_PHASE, EVENT_PHASE, RESOURCE_PHASE;
}
/** Enumeration whose values describe the render policy used by the bridge
@@ -290,8 +298,9 @@
* all other internal exceptions are converted to a BridgeException.
*/
public void doFacesRequest(ActionRequest request, ActionResponse response)
- throws BridgeDefaultViewNotSpecifiedException,
- BridgeException;
+ throws BridgeDefaultViewNotSpecifiedException,
+ BridgeUninitializedException,
+ BridgeException;
/**
* Called by the portlet when it wants the bridge to process a render request.
@@ -309,8 +318,25 @@
* all other internal exceptions are converted to a BridgeException.
*/
public void doFacesRequest(RenderRequest request, RenderResponse response)
- throws BridgeDefaultViewNotSpecifiedException,
- BridgeException;
+ throws BridgeDefaultViewNotSpecifiedException,
+ BridgeUninitializedException,
+ BridgeException;
+ /**
+ * Called by the portlet when it wants the bridge to process an in-protocol
+ * resource request.
+ *
+ * @param request
+ * the request object.
+ * @param response
+ * the response object.
+ * @throws BridgeUninitializedException
+ * thrown if the bridge is not initialized.
+ * @throws BridgeException
+ * all other internal exceptions are converted to a BridgeException.
+ */
+ public void doFacesRequest(ResourceRequest request, ResourceResponse response)
+ throws BridgeUninitializedException,
+ BridgeException;
/**
* Called by the portlet to take the bridge out of service. Once out of service, the bridge must
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java Wed Apr 9 16:39:32 2008
@@ -29,6 +29,8 @@
import javax.portlet.PortletRequest;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
import javax.portlet.WindowState;
/**
@@ -219,6 +221,7 @@
}
+
@Override
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException,
@@ -226,6 +229,17 @@
{
doBridgeDispatch(request, response, getDefaultViewId(request, request.getPortletMode()));
}
+
+ /**
+ * Handles resource requests and dispatches to the Bridge
+ */
+ @Override
+ public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException,
+ IOException
+ {
+ doBridgeDispatch(request, response, getDefaultViewId(request, request.getPortletMode()));
+
+ }
/**
* Returns the set of RequestAttribute names that the portlet wants the bridge to
@@ -415,6 +429,28 @@
initBridge();
// Push information for Bridge into request attributes
setBridgeRequestContext(request, defaultViewId);
+ try
+ {
+ mFacesBridge.doFacesRequest(request, response);
+ }
+ catch (BridgeException e)
+ {
+ throw new PortletException(
+ "doBridgeDispatch failed: error from Bridge in executing the request",
+ e);
+ }
+
+ }
+
+ private void doBridgeDispatch(ResourceRequest request, ResourceResponse response, String defaultViewId)
+ throws PortletException
+ {
+ // initial Bridge if not already active
+ initBridge();
+ // Push information for Bridge into request attributes
+ setBridgeRequestContext(request, defaultViewId);
+
+
try
{
mFacesBridge.doFacesRequest(request, response);
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java Wed Apr 9 16:39:32 2008
@@ -20,11 +20,20 @@
package org.apache.myfaces.portlet.faces.application;
import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import java.io.Writer;
+
+import java.nio.ByteBuffer;
+
import java.util.Locale;
import java.util.Map;
+import java.util.logging.Level;
+
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.StateManager;
@@ -38,12 +47,15 @@
import javax.faces.render.RenderKitFactory;
import javax.portlet.PortletContext;
+import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.faces.Bridge;
import javax.portlet.faces.BridgeUtil;
import javax.portlet.faces.annotation.PortletNamingContainer;
import javax.portlet.faces.component.PortletNamingContainerUIViewRoot;
+import javax.portlet.filter.PortletResponseWrapper;
+
import org.apache.myfaces.portlet.faces.bridge.BridgeImpl;
import org.apache.myfaces.portlet.faces.util.QueryString;
@@ -102,7 +114,193 @@
}
+/*
+ @Override
+ public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException,
+ FacesException
+ {
+ // Do nothing when not running in portlet request
+ if (!BridgeUtil.isPortletRequest())
+ {
+ super.renderView(context, viewToRender);
+ return;
+ }
+
+ // If first time -- Get the renderPolicy from the context init parameter
+ if (mRenderPolicy == null)
+ {
+ PortletContext pCtx = (PortletContext) context.getExternalContext().getContext();
+ String policy = pCtx.getInitParameter(Bridge.RENDER_POLICY);
+ if (policy != null)
+ {
+ mRenderPolicy = Bridge.BridgeRenderPolicy.valueOf(policy);
+ }
+ else
+ {
+ mRenderPolicy = Bridge.BridgeRenderPolicy.DEFAULT;
+ }
+ }
+
+ if (mRenderPolicy == Bridge.BridgeRenderPolicy.ALWAYS_DELEGATE)
+ {
+ super.renderView(context, viewToRender);
+ return;
+ }
+ else if (mRenderPolicy == Bridge.BridgeRenderPolicy.DEFAULT)
+ {
+ try
+ {
+ super.renderView(context, viewToRender);
+ return;
+ }
+ catch (Throwable t)
+ {
+ // catch all throws and swallow -- falling through to our own
+ // render
+ }
+ }
+
+ // suppress rendering if "rendered" property on the component is
+ // false
+ if (!viewToRender.isRendered())
+ {
+ return;
+ }
+
+ ExternalContext extContext = context.getExternalContext();
+ RenderResponse renderResponse = (RenderResponse) extContext.getResponse();
+
+ try
+ {
+ extContext.getRequestMap().remove("javax.servlet.include.servlet_path");
+ dispatchPageToBuildView(context, extContext, viewToRender);
+ }
+ catch (IOException e)
+ {
+ throw new FacesException(e);
+ }
+
+ // If a redirect occurred -- merely return
+ // check here to see if a redirect occurred -- if so rerun doFacesRequest
+ // for this new view
+ QueryString redirectParams = (QueryString) context.getExternalContext()
+ .getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
+ if ((redirectParams != null))
+ {
+ return;
+ }
+
+ // set up the ResponseWriter
+ RenderKitFactory renderFactory = (RenderKitFactory) FactoryFinder
+ .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ RenderKit renderKit = renderFactory.getRenderKit(context, viewToRender.getRenderKitId());
+
+ ResponseWriter oldWriter = context.getResponseWriter();
+ StringBuilderWriter strWriter = new StringBuilderWriter(context, 4096);
+ ResponseWriter newWriter;
+ if (null != oldWriter)
+ {
+ newWriter = oldWriter.cloneWithWriter(strWriter);
+ }
+ else
+ {
+ newWriter = renderKit.createResponseWriter(strWriter, null,
+ renderResponse.getCharacterEncoding());
+ }
+ context.setResponseWriter(newWriter);
+
+ newWriter.startDocument();
+
+ doRenderView(context, viewToRender);
+
+ newWriter.endDocument();
+
+ // replace markers in the body content and write it to response.
+
+ ResponseWriter responseWriter;
+
+ // Dispatch may have output to an OutputStream instead of a Writer
+ Writer renderResponseWriter = null;
+ try {
+ renderResponseWriter = renderResponse.getWriter();
+ }
+ catch (IllegalStateException ise) {
+ // got this exception because we've called getOutputStream() previously
+ renderResponseWriter = new BufferedWriter(
+ new OutputStreamWriter(
+ renderResponse.getPortletOutputStream(),
+ renderResponse.getCharacterEncoding()));
+ }
+ if (null != oldWriter)
+ {
+ responseWriter = oldWriter.cloneWithWriter(renderResponseWriter);
+ }
+ else
+ {
+ responseWriter = newWriter.cloneWithWriter(renderResponseWriter);
+ }
+ context.setResponseWriter(responseWriter);
+
+ strWriter.write(responseWriter);
+ renderResponseWriter.flush();
+
+ if (null != oldWriter)
+ {
+ context.setResponseWriter(oldWriter);
+ }
+
+ RenderResponse wrappedResponse = (RenderResponse) extContext.getRequestMap().get(Bridge.AFTER_VIEW_CONTENT);
+ if (wrappedResponse != null)
+ {
+ wrappedResponse.flushBuffer();
+ }
+ }
+
+
+ private void dispatchPageToBuildView(FacesContext context,
+ ExternalContext extContext,
+ UIViewRoot viewToRender)
+ throws IOException
+ {
+ String viewURI = viewToRender.getViewId();
+ RenderRequest request = (RenderRequest) extContext.getRequest();
+
+ // update the JSTL locale attribute in request scope so that JSTL
+ // picks up the locale from viewRoot. This attribute must be updated
+ // before the JSTL setBundle tag is called because that is when the
+ // new LocalizationContext object is created based on the locale.
+ extContext.getRequestMap().put("javax.servlet.jsp.jstl.fmt.locale", context.getViewRoot().getLocale());
+
+ // save the original response
+ RenderResponse originalResponse = (RenderResponse) extContext.getResponse();
+
+ // replace the response with our wrapper
+ PortletViewHandlerResponseWrapper wrapped = new PortletViewHandlerResponseWrapper(originalResponse, context.getViewRoot().getLocale());
+ if (!(wrapped instanceof PortletResponseWrapper))
+ throw new IOException();
+
+ extContext.setResponse(wrapped);
+
+ // set request attribute indicating we can deal with content
+ // that is supposed to be delayed until after JSF tree is ouput.
+ extContext.getRequestMap().put(Bridge.RENDER_CONTENT_AFTER_VIEW, Boolean.TRUE);
+
+ // build the view by executing the page
+ extContext.dispatch(viewURI);
+
+ // replace the original response
+ extContext.setResponse(originalResponse);
+
+ // Put the AFTER_VIEW_CONTENT into request scope
+ // temporarily
+ extContext.getRequestMap().put(
+ Bridge.AFTER_VIEW_CONTENT,
+ wrapped);
+
+ }
+*/
+
@Override
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException,
FacesException
@@ -273,6 +471,7 @@
renderResponse.flushBuffer();
}
+
/**
* <p>
* This is a separate method to account for handling the content after the view tag.
@@ -311,8 +510,7 @@
{
viewToRender.encodeAll(context);
}
-
-
+
private static final class StringBuilderWriter extends Writer
{
private StringBuilder mBuilder;
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java Wed Apr 9 16:39:32 2008
@@ -27,6 +27,7 @@
import java.net.URL;
import java.rmi.server.UID;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -41,6 +42,7 @@
import javax.el.ELContext;
import javax.el.ELContextEvent;
import javax.el.ELContextListener;
+
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
@@ -58,18 +60,26 @@
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.ResponseStateManager;
import javax.faces.webapp.FacesServlet;
+
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
+import javax.portlet.ClientDataRequest;
+import javax.portlet.MimeResponse;
import javax.portlet.PortalContext;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
+import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.StateAwareResponse;
import javax.portlet.faces.Bridge;
+import javax.portlet.faces.BridgeDefaultViewNotSpecifiedException;
import javax.portlet.faces.BridgeException;
import javax.portlet.faces.BridgeUninitializedException;
import javax.portlet.faces.annotation.BridgePreDestroy;
@@ -86,6 +96,7 @@
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
+import org.apache.myfaces.portlet.faces.bridge.wrapper.BridgePortletRequestWrapper;
import org.apache.myfaces.portlet.faces.bridge.wrapper.BridgeRenderRequestWrapper;
import org.apache.myfaces.portlet.faces.context.PortletExternalContextImpl;
import org.apache.myfaces.portlet.faces.util.QueryString;
@@ -95,19 +106,26 @@
public class BridgeImpl
implements Bridge, ELContextListener, PhaseListener, ServletRequestAttributeListener
{
- private static final long serialVersionUID = 5807626987246270989L;
+ private static final long serialVersionUID = 5807626987246270989L;
- // public so PortletStateManager can see/use
- public static final String UPDATED_VIEW_STATE_PARAM = "org.apache.myfaces.portlet.faces.updatedViewStateParam";
- public static final String BRIDGE_REDIRECT_VIEWPARAMS = "org.apache.myfaces.portlet.faces.redirectViewParams";
-
- private static final String REQUEST_SCOPE_LOCK = "org.apache.myfaces.portlet.faces.requestScopeLock";
- private static final String REQUEST_SCOPE_MAP = "org.apache.myfaces.portlet.faces.requestScopeMap";
- private static final String REQUEST_SCOPE_LISTENER = "org.apache.myfaces.portlet.faces.requestScopeWatch";
+ // public so PortletStateManager can see/use
+ public static final String UPDATED_VIEW_STATE_PARAM =
+ "org.apache.myfaces.portlet.faces.updatedViewStateParam";
+ public static final String BRIDGE_REDIRECT_VIEWPARAMS =
+ "org.apache.myfaces.portlet.faces.redirectViewParams";
+
+ private static final String REQUEST_SCOPE_LOCK =
+ "org.apache.myfaces.portlet.faces.requestScopeLock";
+ private static final String REQUEST_SCOPE_MAP =
+ "org.apache.myfaces.portlet.faces.requestScopeMap";
+ private static final String REQUEST_SCOPE_LISTENER =
+ "org.apache.myfaces.portlet.faces.requestScopeWatch";
private static final String FACES_VIEWROOT = "org.apache.myfaces.portlet.faces.facesViewRoot";
private static final String FACES_MESSAGES = "org.apache.myfaces.portlet.faces.facesMessages";
- private static final String REQUEST_PARAMETERS = "org.apache.myfaces.portlet.faces.requestParameters";
- private static final String PREEXISTING_ATTRIBUTE_NAMES = "org.apache.myfaces.portlet.faces.preExistingAttributeNames";
+ private static final String REQUEST_PARAMETERS =
+ "org.apache.myfaces.portlet.faces.requestParameters";
+ private static final String PREEXISTING_ATTRIBUTE_NAMES =
+ "org.apache.myfaces.portlet.faces.preExistingAttributeNames";
private static final String REQUEST_SCOPE_ID_RENDER_PARAM = "_bridgeRequestScopeId";
private static final int DEFAULT_MAX_MANAGED_REQUEST_SCOPES = 100;
@@ -129,30 +147,33 @@
public void init(PortletConfig config)
throws BridgeException
{
- //TODO: Should we throw an exception if the bridge is already initialized?
+ //TODO: Should we throw an exception if the bridge is already initialized?
if (mInitialized)
throw new BridgeException("Bridge already initialized.");
-
+
mPortletConfig = config;
PortletContext portletContext = mPortletConfig.getPortletContext();
// get preserveActionParams and excludedAttributes configuration settings.
- mPreserveActionParams = (Boolean) portletContext.getAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + mPortletConfig.getPortletName() +
- "." + Bridge.PRESERVE_ACTION_PARAMS);
-
- mExcludedRequestAttributes = (List <String>) portletContext.getAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + mPortletConfig.getPortletName() +
- "." + Bridge.EXCLUDED_REQUEST_ATTRIBUTES);
+ mPreserveActionParams =
+ (Boolean) portletContext.getAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + mPortletConfig.getPortletName() +
+ "." + Bridge.PRESERVE_ACTION_PARAMS);
+
+ mExcludedRequestAttributes =
+ (List<String>) portletContext.getAttribute(Bridge.BRIDGE_PACKAGE_PREFIX +
+ mPortletConfig.getPortletName() + "." +
+ Bridge.EXCLUDED_REQUEST_ATTRIBUTES);
if (mExcludedRequestAttributes != null)
{
// copy the list as we may be adding to it and don't want to worry that this might be immutable
- mExcludedRequestAttributes = new ArrayList(mExcludedRequestAttributes);
+ mExcludedRequestAttributes = new ArrayList(mExcludedRequestAttributes);
}
else
{
// Otherwise create an empty list
mExcludedRequestAttributes = new ArrayList(5);
}
-
+
// Read excludedAttributes that may be defined in any face-config.xml
readExcludedAttributesFromFacesConfig(portletContext, mExcludedRequestAttributes);
@@ -164,7 +185,7 @@
// putting it in the PortletContext. Hence the sync object allows us
// to limit syncronizing the PortletContext to once per portlet (init
// time);
-
+
// TODO: What about synching on a static object or using a class lock?
// Perhaps even the LRUMap itself if said map is a singleton?
synchronized (portletContext)
@@ -191,20 +212,21 @@
{
throw new BridgeException("BridgeImpl.init(): unable to determine Faces servlet web.xml mapping.");
}
-
+
// remember that init() has been called so can test in other methods.
mInitialized = true;
}
public void doFacesRequest(ActionRequest request, ActionResponse response)
- throws BridgeException, BridgeUninitializedException, NullPointerException
+ throws BridgeException, BridgeDefaultViewNotSpecifiedException, BridgeUninitializedException,
+ NullPointerException
{
- if (!mInitialized)
+ if (!mInitialized)
throw new BridgeUninitializedException();
else if (request == null || response == null)
throw new NullPointerException("request or response parameter is null");
-
+
// Set the Portlet lifecycle phase as a request attribute so its
// available to Faces extensions -- allowing that code to NOT rely on
// instanceof which can fail if a portlet container uses a single class
@@ -242,7 +264,14 @@
// Each action starts a new "action lifecycle"
// The Bridge preserves request scoped data and if so configured
// Action Parameters for the duration of an action lifecycle
- scopeId = initBridgeRequestScope(request, response);
+ scopeId = initBridgeRequestScope(request);
+ // set in response render parameter so will receive in future calls
+ // however don't store internally until there is specific state to
+ // manage
+ response.setRenderParameter(REQUEST_SCOPE_ID_RENDER_PARAM, scopeId);
+
+ // in case a prior scope was managed temporarily on the session -- remove it
+ request.removeAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
// For actions we only execute the lifecycle phase
getLifecycle().execute(context);
@@ -250,7 +279,8 @@
// Check if a redirect was called. If so encode the redirect viewId
// as the action response without saving state. Otherwise its not
// a redirect so save the state for the subsequent render.
- QueryString redirectParams = (QueryString) context.getExternalContext().getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
+ QueryString redirectParams =
+ (QueryString) context.getExternalContext().getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
// Do nothing for redirect case because the ActionResponse is
// already encoded and no additional state needs to be saved.
@@ -277,7 +307,7 @@
// preserve the request scope data and the Faces view tree at
// RequestScope.
saveBridgeRequestScopeData(context, scopeId, preExistingAttributes);
-
+
// Finalize the action response -- key here is the reliance on
// ExternalContext.encodeActionURL to migrate info encoded
// in the actionURL constructed from the target of this
@@ -289,7 +319,6 @@
}
-
}
catch (Exception e)
{
@@ -316,7 +345,7 @@
}
}
}
-
+
private void dumpScopeId(String scopeId, String phase)
{
// Get the data from the scope
@@ -329,40 +358,41 @@
// No scope for all renders before first action to this portletApp
if (requestScopeMap == null)
{
- ctx.log("There are No saved scoped. Can't match: "+ scopeId);
+ ctx.log("There are No saved scoped. Can't match: " + scopeId);
return;
}
Map<String, Object> m = requestScopeMap.get(scopeId);
if (m == null)
{
- ctx.log("Can't match scope: "+ scopeId);
+ ctx.log("Can't match scope: " + scopeId);
return;
}
-
- Set<Map.Entry<String,Object>> set = m.entrySet();
- Iterator<Map.Entry<String,Object>> i = set.iterator();
+
+ Set<Map.Entry<String, Object>> set = m.entrySet();
+ Iterator<Map.Entry<String, Object>> i = set.iterator();
ctx.log("Elements in scope: " + scopeId);
while (i.hasNext())
{
- Map.Entry<String,Object> entry = i.next();
+ Map.Entry<String, Object> entry = i.next();
ctx.log(" " + entry.getKey());
}
ctx.log("end dumpScopeId");
}
-
+
}
public void doFacesRequest(RenderRequest request, RenderResponse response)
- throws BridgeException, BridgeUninitializedException, NullPointerException
+ throws BridgeException, BridgeDefaultViewNotSpecifiedException, BridgeUninitializedException,
+ NullPointerException
{
- if (!mInitialized)
+ if (!mInitialized)
throw new BridgeUninitializedException();
else if (request == null || response == null)
throw new NullPointerException("request or response parameter is null");
-
- String scopeId = null;
-
+
+ String scopeId = getRequestScopeId(request);
+
// Set the Portlet lifecycle phase as a request attribute so its
// available to Faces extensions -- allowing that code to NOT rely on
// instanceof which can fail if a portlet container uses a single class
@@ -375,7 +405,7 @@
{
request.setAttribute(PortletExternalContextImpl.FACES_MAPPING_ATTRIBUTE, mFacesMappings);
}
-
+
// cache existing attributes in case a redirect occurs and
// we need to remove all but these preexisting ones.
List<String> preExistingAttributes = getRequestAttributes(request);
@@ -393,9 +423,7 @@
// extension
RenderRequest extRequest = (RenderRequest) extCtx.getRequest();
- scopeId = extRequest.getParameter(REQUEST_SCOPE_ID_RENDER_PARAM);
-
- if (restoreBridgeRequestScopeData(context, scopeId))
+ if (restoreBridgeRequestScopeData(request, scopeId))
{
// Because the Bridge is required to always save/restore the
// VIEW_STATE
@@ -419,7 +447,7 @@
{
extCtx.getRequestMap().put(Bridge.IS_POSTBACK_ATTRIBUTE, Boolean.TRUE);
}
-
+
doFacesRender(request, response, context, lifecycle, scopeId, preExistingAttributes);
}
catch (Exception e)
@@ -430,7 +458,7 @@
{
removeRequestScopes(scopeId);
}
-
+
context.getExternalContext().log("Exception thrown in doFacesRequest:render", e);
if (!(e instanceof BridgeException))
{
@@ -454,19 +482,14 @@
}
}
}
-
- private void doFacesRender(
- RenderRequest request,
- RenderResponse response,
- FacesContext context,
- Lifecycle lifecycle,
- String scopeId,
- List <String> preExistingAttributes
- )
+
+ private void doFacesRender(PortletRequest request, MimeResponse response, FacesContext context,
+ Lifecycle lifecycle, String scopeId,
+ List<String> preExistingAttributes)
throws BridgeException, BridgeUninitializedException, NullPointerException
{
boolean redirectedDuringRender = false;
-
+
// Note: if the scope wasn't restored then the Faces
// FACES_VIEW_STATE
// parameter will not have been carried into this render and hence
@@ -507,7 +530,7 @@
// as some extensions depend on this being called per request.
PhaseListener[] listeners = lifecycle.getPhaseListeners();
PhaseEvent event = new PhaseEvent(context, PhaseId.RESTORE_VIEW, lifecycle);
- for (PhaseListener listener:listeners)
+ for (PhaseListener listener: listeners)
{
if (listener.getPhaseId() == PhaseId.ANY_PHASE ||
listener.getPhaseId() == PhaseId.RESTORE_VIEW)
@@ -516,11 +539,11 @@
}
}
}
-
+
// check here to see if a redirect occurred -- if so rerun doFacesRequest
// for this new view
- QueryString redirectParams = (QueryString) context.getExternalContext()
- .getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
+ QueryString redirectParams =
+ (QueryString) context.getExternalContext().getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
if ((redirectParams == null))
{
getLifecycle().render(context);
@@ -531,19 +554,19 @@
context = FacesContext.getCurrentInstance();
redirectedDuringRender = true;
}
-
-
+
+
// check here to see if a redirect occurred -- if so rerun doFacesRequest
// for this new view
- redirectParams = (QueryString) context.getExternalContext()
- .getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
+ redirectParams =
+ (QueryString) context.getExternalContext().getRequestMap().get(BridgeImpl.BRIDGE_REDIRECT_VIEWPARAMS);
if ((redirectParams != null))
{
redirectRender(context, lifecycle, request, response, redirectParams, preExistingAttributes);
context = FacesContext.getCurrentInstance();
redirectedDuringRender = true;
}
-
+
// When we have navigated to this view between the action and render
// the initial VIEW_STATE_PARAM reflects the actions view -- update
// here to the one from this render so refresh will work.
@@ -553,20 +576,156 @@
}
}
+ public void doFacesRequest(ResourceRequest request, ResourceResponse response)
+ throws BridgeException, BridgeDefaultViewNotSpecifiedException, BridgeUninitializedException,
+ NullPointerException
+ {
+ if (!mInitialized)
+ throw new BridgeUninitializedException();
+ else if (request == null || response == null)
+ throw new NullPointerException("request or response parameter is null");
+
+ // Set the Portlet lifecycle phase as a request attribute so its
+ // available to Faces extensions -- allowing that code to NOT rely on
+ // instanceof which can fail if a portlet container uses a single class
+ // to implement both the action and render request/response objects
+ request.setAttribute(Bridge.PORTLET_LIFECYCLE_PHASE, Bridge.PortletPhase.RESOURCE_PHASE);
+
+ // Determine whether this is a Faces resource or a regular one.
+ if (request.getParameter(PortletExternalContextImpl.RESOURCE_ACTION_ID_PARAMETER_NAME) == null)
+ {
+ try
+ {
+ String target = request.getResourceID();
+ PortletRequestDispatcher rd =
+ mPortletConfig.getPortletContext().getRequestDispatcher(target);
+ rd.forward(request, response);
+ return;
+ }
+ catch (Exception e)
+ {
+ if (!(e instanceof BridgeException))
+ {
+ Throwable rootCause = e.getCause();
+ throw new BridgeException(e.getMessage(), rootCause);
+ }
+ else
+ {
+ throw (BridgeException) e;
+ }
+ }
+ }
+
+ // Otherwise this is a Faces resource
+
+ // Set the FacesServletMapping attribute so the ExternalContext can
+ // pick it up and use it to reverse map viewIds to paths
+ if (mFacesMappings != null)
+ {
+ request.setAttribute(PortletExternalContextImpl.FACES_MAPPING_ATTRIBUTE, mFacesMappings);
+ }
+
+ // cache names of existing request attributes so can exclude them
+ // from being saved in the bridge's request scope. Note: this is done
+ // before
+ // acquiring the FacesContext because its possible (though unlikely)
+ // the application has inserted itself in this process and sets up
+ // needed request attributes.
+ List<String> preExistingAttributes = getRequestAttributes(request);
+ // place on the request for use here and in the servletRequestAttributeListener
+ if (preExistingAttributes != null)
+ {
+ request.setAttribute(PREEXISTING_ATTRIBUTE_NAMES, preExistingAttributes);
+ }
+
+ String scopeId = getRequestScopeId(request);
+ if (scopeId == null)
+ {
+ // first request is a resource request
+ // create a scope and store in the session until an action occurs
+ scopeId = initBridgeRequestScope(request);
+
+ // store in session until next action
+ PortletSession session = request.getPortletSession(true);
+ session.setAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM, scopeId);
+ }
+
+ restoreBridgeRequestScopeData(request, scopeId);
+
+ FacesContext context = null;
+ try
+ {
+ // Get the FacesContext instance for this request
+ Lifecycle lifecycle = getLifecycle();
+ context =
+ getFacesContextFactory().getFacesContext(mPortletConfig, request, response, lifecycle);
+ ExternalContext extCtx = context.getExternalContext();
+
+ // Use request from ExternalContext in case its been wrapped by an
+ // extension
+ RenderRequest extRequest = (RenderRequest) extCtx.getRequest();
+
+ // Ensure the ContentType is set before rendering
+ if (extCtx.getResponseContentType() == null)
+ {
+ response.setContentType(extRequest.getResponseContentType());
+ }
+
+ // ensure that isPostback attribute set if VIEW_STATE param exists
+ if (extCtx.getRequestParameterValuesMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM))
+ {
+ extCtx.getRequestMap().put(Bridge.IS_POSTBACK_ATTRIBUTE, Boolean.TRUE);
+ }
+
+ doFacesRender(request, response, context, lifecycle, scopeId, preExistingAttributes);
+ }
+ catch (Exception e)
+ {
+ // When exception occurs remove stored scope so don't
+ // get stuck replaying the error when/if user refreshes
+ if (scopeId != null)
+ {
+ removeRequestScopes(scopeId);
+ }
+
+ context.getExternalContext().log("Exception thrown in doFacesRequest:render", e);
+ if (!(e instanceof BridgeException))
+ {
+ Throwable rootCause = e.getCause();
+ throw new BridgeException(e.getMessage(), rootCause);
+ }
+ else
+ {
+ throw (BridgeException) e;
+ }
+ }
+ finally
+ {
+ dumpScopeId(scopeId, "RENDER_PHASE");
+ // our servletrequestattributelistener uses this as an indicator of whether
+ // its actively working on a request -- remove it to indicate we are done
+ request.removeAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
+ if (context != null)
+ {
+ context.release();
+ }
+ }
+ }
+
public void destroy()
{
if (!mInitialized)
// do nothing if destroy an uninitialzed bridge
return;
-
+
mInitialized = false;
-
+
// remove any scopes being managed for this portlet
// Each scope has a per portlet prefix -- pass in the prefix
// constructed by adding the prefix to an empty string.
removeRequestScopes(qualifyScopeId(mPortletConfig.getPortletName(), null, null));
-
+
mPortletConfig = null;
}
@@ -584,29 +743,29 @@
elContext.putContext(PortletConfig.class, mPortletConfig);
}
}
-
+
/*
* ServletRequestAttributeListener implementation
*/
+
public void attributeAdded(ServletRequestAttributeEvent srae)
{
// use this phase attribute as an indicator of whether
// we are actively working on a request
- PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
-
+ PortletPhase phase =
+ (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
+
// do nothing if before/after bridge processing or in the render phase.
// Don't care about render phase because we don't update/change the managed
// scope based on changes during render.
// ALSO: do nothing if not in the Bridge's managed request scope
- if (phase == null || phase == PortletPhase.RENDER_PHASE ||
- isExcludedFromBridgeRequestScope(srae.getName(),
- srae.getValue(),
- (List<String>)
- srae.getServletRequest().getAttribute(PREEXISTING_ATTRIBUTE_NAMES)))
+ if (phase == null || phase == PortletPhase.RENDER_PHASE ||
+ isExcludedFromBridgeRequestScope(srae.getName(), srae.getValue(),
+ (List<String>) srae.getServletRequest().getAttribute(PREEXISTING_ATTRIBUTE_NAMES)))
{
return;
}
-
+
// Otherwise -- see if the added attribute implements the bridge's
// BridgeRequestScopeAdded annotation -- call each method so annotated
Object o = srae.getValue();
@@ -621,65 +780,64 @@
}
catch (Exception e)
{
- // TODO: log problem
- // do nothing and forge ahead
- ;
+ // TODO: log problem
+ // do nothing and forge ahead
+ ;
}
}
}
}
-
+
public void attributeRemoved(ServletRequestAttributeEvent srae)
{
// use this phase attribute as an indicator of whether
// we are actively working on a request
- PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
-
- // If in an action this means the attribute has been removed before we have
- // saved the action scope -- since the managed bean has been informed we are
+ PortletPhase phase =
+ (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
+
+ // If not in a render this means the attribute has been removed before we have
+ // saved the request scope -- since the managed bean has been informed we are
// running in a portlet environment it should have ignored the PreDestroy.
// To make up for this we call its BridgePredestroy
- if (phase != null && phase == PortletPhase.ACTION_PHASE)
+ if (phase != null && phase != PortletPhase.RENDER_PHASE)
{
notifyPreDestroy(srae.getValue()); // in outerclass (BridgeImpl)
}
}
-
+
public void attributeReplaced(ServletRequestAttributeEvent srae)
{
// use this phase attribute as an indicator of whether
// we are actively working on a request
- PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
-
+ PortletPhase phase =
+ (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
+
// If in an action this means the attribute has been replaced before we have
// saved the action scope -- since the managed bean has been informed we are
// running in a portlet environment it should have ignored the PreDestroy.
// To make up for this we call its BridgePredestroy
- if (phase != null && phase == PortletPhase.ACTION_PHASE)
+ if (phase != null && phase != PortletPhase.RENDER_PHASE)
{
notifyPreDestroy(srae.getValue()); // in outerclass (BridgeImpl)
}
}
-
- private void redirectRender(FacesContext context,
- Lifecycle lifecycle,
- RenderRequest request,
- RenderResponse response,
- QueryString redirectParams,
+
+ private void redirectRender(FacesContext context, Lifecycle lifecycle, PortletRequest request,
+ MimeResponse response, QueryString redirectParams,
List<String> preExistingAttrs)
{
-
+
// remove any bridge special marker params as these can't be set in a
// render redirect
redirectParams.removeParameter(Bridge.DIRECT_LINK);
redirectParams.removeParameter(Bridge.PORTLET_MODE_PARAMETER);
redirectParams.removeParameter(Bridge.PORTLET_WINDOWSTATE_PARAMETER);
redirectParams.removeParameter(Bridge.PORTLET_SECURE_PARAMETER);
-
+
// Now turn the QueryString into a parameter map
- Map <String, String[]> paramMap = new LinkedHashMap(redirectParams.numParameters());
+ Map<String, String[]> paramMap = new LinkedHashMap(redirectParams.numParameters());
Enumeration<String> nameEnum = redirectParams.getParameterNames();
- while (nameEnum != null && nameEnum.hasMoreElements())
+ while (nameEnum != null && nameEnum.hasMoreElements())
{
String name = nameEnum.nextElement();
Enumeration<String> valuesEnum = redirectParams.getParameterValues(name);
@@ -687,12 +845,12 @@
while (valuesEnum != null && valuesEnum.hasMoreElements())
{
values.add(valuesEnum.nextElement());
-
+
}
paramMap.put(name, values.toArray(new String[values.size()]));
}
-
+
// reset request attributes to those that existed before we were called.
Map<String, Object> m = context.getExternalContext().getRequestMap();
Set<Map.Entry<String, Object>> entrySet = m.entrySet();
@@ -708,14 +866,15 @@
names[count++] = entry.getKey();
}
}
-
+
for (int j = 0; j < count; j++)
{
m.remove(names[j]);
}
-
+
// now wrap the request object to expose only those params as are in QS
- BridgeRenderRequestWrapper requestWrapper = new BridgeRenderRequestWrapper(request, paramMap, false);
+ BridgePortletRequestWrapper requestWrapper =
+ new BridgePortletRequestWrapper(request, paramMap, false);
// close the FacesContext
context.release();
// start a new FacesContext
@@ -725,9 +884,9 @@
context.getExternalContext().setRequest(requestWrapper);
// Run lifecycle.execute again ... then render
doFacesRender(request, response, context, lifecycle, null, preExistingAttrs);
- return; // to continue on
+ return; // to continue on
}
-
+
private FacesContextFactory getFacesContextFactory()
throws BridgeException
{
@@ -827,11 +986,8 @@
requestMap.put(REQUEST_PARAMETERS, requestParameterMap);
}
}
-
- private void updateViewInfo(
- FacesContext context,
- String scopeId,
- boolean redirectedDuringRender)
+
+ private void updateViewInfo(FacesContext context, String scopeId, boolean redirectedDuringRender)
{
PortletContext portletContext = mPortletConfig.getPortletContext();
@@ -847,7 +1003,7 @@
// Have only done renders to this point -- so no scope to update
return;
}
-
+
// now see if this scope is in the Map
Map<String, Object> scopeMap = requestScopeMap.get(scopeId);
if (scopeMap == null)
@@ -858,22 +1014,23 @@
// Now get the RequestParameters from the scope
@SuppressWarnings("unchecked")
- Map<String, String[]> requestParams = (Map<String, String[]>)scopeMap.get(REQUEST_PARAMETERS);
-
- if (requestParams == null)
+ Map<String, String[]> requestParams =
+ (Map<String, String[]>) scopeMap.get(REQUEST_PARAMETERS);
+
+ if (requestParams == null)
{
requestParams = new HashMap<String, String[]>(1);
scopeMap.put(REQUEST_PARAMETERS, requestParams);
}
-
+
// Prepare the value for storing as a preserved parameter
// Store as an array of Strings with just one entry as per
// portlet request
String[] values = new String[1];
// First make sure we have a value to update
- String updatedViewStateParam = (String) context.getExternalContext()
- .getRequestMap().get(UPDATED_VIEW_STATE_PARAM);
-
+ String updatedViewStateParam =
+ (String) context.getExternalContext().getRequestMap().get(UPDATED_VIEW_STATE_PARAM);
+
if (updatedViewStateParam != null)
{
values[0] = updatedViewStateParam;
@@ -881,7 +1038,7 @@
// finally update the value in the Map
requestParams.put(ResponseStateManager.VIEW_STATE_PARAM, values);
}
-
+
if (redirectedDuringRender)
{
// Add the VIEW_ID
@@ -897,26 +1054,26 @@
}
}
}
-
-
- private LRUMap createRequestScopeMap(PortletContext portletContext)
+
+
+ private LRUMap createRequestScopeMap(PortletContext portletContext)
{
// see if portlet has defined how many requestScopes to manage
// for this portlet
int managedScopes = DEFAULT_MAX_MANAGED_REQUEST_SCOPES;
-
+
String managedScopesSetting =
- portletContext.getInitParameter(Bridge.MAX_MANAGED_REQUEST_SCOPES);
+ portletContext.getInitParameter(Bridge.MAX_MANAGED_REQUEST_SCOPES);
if (managedScopesSetting != null)
{
managedScopes = Integer.parseInt(managedScopesSetting);
}
-
+
return new LRUMap(managedScopes);
}
@SuppressWarnings("unchecked")
- private RenderRequest restoreActionParams(FacesContext context)
+ private RenderRequest restoreActionParams(FacesContext context)
{
// this is a little trickier then saving because there is no
// corresponding set. Instead we wrap the request object and set it
@@ -945,9 +1102,9 @@
while (clientIds.hasNext())
{
String clientId = (String) clientIds.next();
- for(Iterator<FacesMessage> messages = context.getMessages(clientId);messages.hasNext();)
+ for (Iterator<FacesMessage> messages = context.getMessages(clientId); messages.hasNext(); )
{
- state.addMessage(clientId, messages.next());
+ state.addMessage(clientId, messages.next());
}
}
// save state in ViewRoot attributes
@@ -968,31 +1125,41 @@
if (state != null)
{
- for(String clientId:state.getClientIds())
- {
- for(FacesMessage message:state.getMessages(clientId))
- {
- context.addMessage(clientId, message);
+ for (String clientId: state.getClientIds())
+ {
+ for (FacesMessage message: state.getMessages(clientId))
+ {
+ context.addMessage(clientId, message);
}
}
}
}
}
- private String initBridgeRequestScope(ActionRequest request, ActionResponse response)
+ private String getRequestScopeId(PortletRequest request)
+ {
+ String scopeId = request.getParameter(REQUEST_SCOPE_ID_RENDER_PARAM);
+
+ if (scopeId == null)
+ {
+ PortletSession session = request.getPortletSession();
+ if (session != null)
+ {
+ scopeId = (String) session.getAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
+ }
+ }
+ return scopeId;
+ }
+
+ private String initBridgeRequestScope(ClientDataRequest request)
{
// Generate an RMI UID, which is a unique identifier WITHIN the local
// host. This will be used as the new lifecyleID
UID uid = new UID();
- String requestScopeId = qualifyScopeId(mPortletConfig.getPortletName(),
- request.getPortletSession(true).getId(),
- uid.toString());
-
- // set in response render parameter so will receive in future calls
- // however don't store internally until there is specific state to
- // manage
- response.setRenderParameter(REQUEST_SCOPE_ID_RENDER_PARAM, requestScopeId);
+ String requestScopeId =
+ qualifyScopeId(mPortletConfig.getPortletName(), request.getPortletSession(true).getId(),
+ uid.toString());
return requestScopeId;
}
@@ -1034,34 +1201,34 @@
private Map<String, Object> copyRequestMap(Map<String, Object> m, List<String> preExistingList)
{
Map<String, Object> copy = new HashMap<String, Object>(m.size());
-
- for(Map.Entry<String, Object> entry:m.entrySet())
- {
+
+ for (Map.Entry<String, Object> entry: m.entrySet())
+ {
// TODO -- restore the ACTION PARAMS if there
// Don't copy any of the portlet or Faces objects
- String key = entry.getKey();
- Object value = entry.getValue();
- if(!isExcludedFromBridgeRequestScope(key, value, preExistingList))
- {
- copy.put(key, value);
- }
- }
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (!isExcludedFromBridgeRequestScope(key, value, preExistingList))
+ {
+ copy.put(key, value);
+ }
+ }
return copy;
}
-
+
@SuppressWarnings("unchecked")
private List<String> getRequestAttributes(PortletRequest request)
{
- return Collections.list((Enumeration<String>)request.getAttributeNames());
+ return Collections.list((Enumeration<String>) request.getAttributeNames());
}
-
- private boolean isExcludedFromBridgeRequestScope(String key, Object value, List<String> preExistingList)
+
+ private boolean isExcludedFromBridgeRequestScope(String key, Object value,
+ List<String> preExistingList)
{
- return ((value.getClass().getAnnotation(ExcludeFromManagedRequestScope.class) != null) ||
- (preExistingList != null && preExistingList.contains(key)) ||
- isPreDefinedExcludedObject(key, value) ||
- isConfiguredExcludedAttribute(key));
+ return ((value.getClass().getAnnotation(ExcludeFromManagedRequestScope.class) != null) ||
+ (preExistingList != null && preExistingList.contains(key)) ||
+ isPreDefinedExcludedObject(key, value) || isConfiguredExcludedAttribute(key));
}
private boolean isPreDefinedExcludedObject(String s, Object o)
@@ -1071,27 +1238,25 @@
o instanceof PortletPreferences || o instanceof PortalContext || o instanceof FacesContext ||
o instanceof ExternalContext || o instanceof ServletConfig || o instanceof ServletContext ||
o instanceof ServletRequest || o instanceof ServletResponse || o instanceof HttpSession ||
- isInNamespace(s, "javax.portlet.") ||
- isInNamespace(s, "javax.portlet.faces.") ||
- isInNamespace(s, "javax.faces.") ||
- isInNamespace(s, "javax.servlet.") ||
- isInNamespace(s, "javax.servlet.include.") ||
- isInNamespace(s, "org.apache.myfaces.portlet.faces") ||
+ isInNamespace(s, "javax.portlet.") || isInNamespace(s, "javax.portlet.faces.") ||
+ isInNamespace(s, "javax.faces.") || isInNamespace(s, "javax.servlet.") ||
+ isInNamespace(s, "javax.servlet.include.") ||
+ isInNamespace(s, "org.apache.myfaces.portlet.faces") ||
isInNamespace(s, "org.apache.myfaces.portlet.faces.context");
- }
-
+ }
+
private boolean isConfiguredExcludedAttribute(String s)
{
if (mExcludedRequestAttributes == null)
{
return false;
}
-
+
if (mExcludedRequestAttributes.contains(s))
{
return true;
}
-
+
// No direct match -- walk through this list and process namespace checks
Iterator<String> i = mExcludedRequestAttributes.iterator();
while (i.hasNext())
@@ -1107,28 +1272,27 @@
}
return false;
}
-
+
private boolean isInNamespace(String s, String namespace)
{
// This is a non-recursive check so s must be the result of removing the namespace.
if (s.startsWith(namespace))
{
- // extract entire namespace and compare
- s = s.substring(0, s.lastIndexOf('.') + 1);
- return s.equals(namespace);
+ // extract entire namespace and compare
+ s = s.substring(0, s.lastIndexOf('.') + 1);
+ return s.equals(namespace);
}
return false;
}
@SuppressWarnings("unchecked")
- private boolean restoreBridgeRequestScopeData(FacesContext context, String scopeId)
+ private boolean restoreBridgeRequestScopeData(PortletRequest request, String scopeId)
throws BridgeException
{
PortletContext portletContext = mPortletConfig.getPortletContext();
Map<String, Object> m;
- Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
-
+
//TODO: Since this is a private method, is it easier to ensure scope id is not null here thus replacing this with
//an assert
if (scopeId == null)
@@ -1153,8 +1317,15 @@
return false;
}
}
-
- requestMap.putAll(m);
+
+ Set<Map.Entry<String, Object>> s = m.entrySet();
+ Iterator<Map.Entry<String, Object>> i = s.iterator();
+ while (i.hasNext())
+ {
+ Map.Entry<String, Object> e = i.next();
+ request.setAttribute(e.getKey(), e.getValue());
+ }
+
return true;
}
@@ -1194,9 +1365,9 @@
}
/*
- * A scope is qualified first by the portlet this scope has been created for
+ * A scope is qualified first by the portlet this scope has been created for
* and then second by the specific session this scope is used in. By doing
- * this we are able to remove this specific scope, all the scopes associated
+ * this we are able to remove this specific scope, all the scopes associated
* with a particular session, or all the scopes associated with a particular
* portlet regardless of sessions.
*/
@@ -1204,11 +1375,12 @@
private String qualifyScopeId(String portletId, String sessionId, String scopeId)
{
// a qualified scope Id must at a minimum be qualified by a portletId
- if (portletId == null) portletId = mPortletConfig.getPortletName();
-
+ if (portletId == null)
+ portletId = mPortletConfig.getPortletName();
+
StringBuffer sb = new StringBuffer(portletId);
sb.append(':');
- if (sessionId != null)
+ if (sessionId != null)
{
sb.append(sessionId);
sb.append(':');
@@ -1234,10 +1406,9 @@
// if invalidated we walk the entire REQUEST_SCOPE Map and
// remove
// every scope that starts with this prefix.
- session.setAttribute(REQUEST_SCOPE_LISTENER, new RequestScopeListener(
- qualifyScopeId(mPortletConfig.getPortletName(),
- session.getId(),
- null)));
+ session.setAttribute(REQUEST_SCOPE_LISTENER,
+ new RequestScopeListener(qualifyScopeId(mPortletConfig.getPortletName(),
+ session.getId(), null)));
}
}
}
@@ -1263,19 +1434,21 @@
context.getExternalContext().encodeActionURL(viewURL);
}
-
+
// notify this scope's attributes that they are being removed
- private void notifyPreDestroy(Map<String,Object> scope)
+
+ private void notifyPreDestroy(Map<String, Object> scope)
{
- Set<Map.Entry<String,Object>> s = scope.entrySet();
- Iterator<Map.Entry<String,Object>> i = s.iterator();
+ Set<Map.Entry<String, Object>> s = scope.entrySet();
+ Iterator<Map.Entry<String, Object>> i = s.iterator();
while (i.hasNext())
{
notifyPreDestroy(i.next().getValue());
}
}
-
+
// notify this scope's attributes that they are being removed
+
private void notifyPreDestroy(Object o)
{
Method[] methods = o.getClass().getMethods();
@@ -1289,9 +1462,9 @@
}
catch (Exception e)
{
- // TODO: log problem
- // do nothing and forge ahead
- ;
+ // TODO: log problem
+ // do nothing and forge ahead
+ ;
}
}
}
@@ -1299,7 +1472,7 @@
private void removeRequestScopes(String scopePrefix)
{
-
+
if (scopePrefix == null || mPortletConfig == null)
return; // Nothing to do -- later case is the session is destroyed after the context
@@ -1319,30 +1492,30 @@
if (requestScopeMap != null)
{
- Iterator<String> iterator = requestScopeMap.keySet().iterator();
- while(iterator.hasNext())
- {
- String scopeId = iterator.next();
+ Iterator<String> iterator = requestScopeMap.keySet().iterator();
+ while (iterator.hasNext())
+ {
+ String scopeId = iterator.next();
if (scopeId != null && scopeId.startsWith(scopePrefix))
{
- iterator.remove();
+ iterator.remove();
}
- }
+ }
}
}
}
-
- private void readExcludedAttributesFromFacesConfig(PortletContext context,
+
+ private void readExcludedAttributesFromFacesConfig(PortletContext context,
List<String> excludedAttributes)
{
FacesConfigurationProcessor processor = new FacesConfigurationProcessor(context);
List<String> list = processor.getExcludedAttributes();
-
+
if (list == null)
{
return;
}
-
+
ListIterator<String> i = (ListIterator<String>) list.listIterator();
while (i.hasNext())
{
@@ -1393,7 +1566,7 @@
}
@Override
- protected boolean removeEldestEntry(Map.Entry<String, Map<String,Object>> eldest)
+ protected boolean removeEldestEntry(Map.Entry<String, Map<String, Object>> eldest)
{
// manually remove the entry so we can ensure notifyPreDestroy is only
// called once
@@ -1404,24 +1577,26 @@
}
return false;
}
-
- public Map<String,Object> remove(String key)
+
+ public Map<String, Object> remove(String key)
{
dumpScopeId(key, "RemovePhase");
- Map<String,Object> o = super.remove(key);
+ Map<String, Object> o = super.remove(key);
// notify attributes maintained in this object (map) they are going away
// Method in the outer BridgeImpl class
- if (o != null) notifyPreDestroy(o);
+ if (o != null)
+ notifyPreDestroy(o);
return o;
}
-
- public Map<String,Object> put(String key, Map<String,Object> value)
+
+ public Map<String, Object> put(String key, Map<String, Object> value)
{
- Map<String,Object> o = super.put(key, value);
+ Map<String, Object> o = super.put(key, value);
// notify attributes maintained in this object (map) they are going away
// Method in the outer BridgeImpl class
- if (o != null) notifyPreDestroy(o);
- return o;
+ if (o != null)
+ notifyPreDestroy(o);
+ return o;
}
}
@@ -1442,7 +1617,8 @@
*/
private static final long serialVersionUID = 8438070672451887050L;
// For saving and restoring FacesMessages
- private Map<String, List<FacesMessage>> mMessages = new HashMap<String, List<FacesMessage>>(); // key=clientId;
+ private Map<String, List<FacesMessage>> mMessages =
+ new HashMap<String, List<FacesMessage>>(); // key=clientId;
// value=FacesMessages
@@ -1496,6 +1672,5 @@
// Call is in the BridgeImpl class
removeRequestScopes(mScopePrefix);
}
-
}
}
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/FacesContextFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/FacesContextFactoryImpl.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/FacesContextFactoryImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/FacesContextFactoryImpl.java Wed Apr 9 16:39:32 2008
@@ -55,6 +55,54 @@
// method as that call requires the facesContext to exist.
if (isPortletRequest(request))
{
+ // As its possible an in-protocol resource needs to access the FacesContext
+ // hence we could be passed the servlet objects in a portlet request
+ // try converting back to the portlet objects
+ Object pTemp = null;
+ PortletRequest pRequest = null;
+ ServletRequest sRequest = null;
+
+ if (request instanceof PortletRequest)
+ pRequest = (PortletRequest) request;
+ else if (request instanceof ServletRequest)
+ sRequest = (ServletRequest) request;
+
+ if (!(config instanceof PortletConfig))
+ {
+ if (pRequest != null)
+ {
+ pTemp = pRequest.getAttribute("javax.portlet.config");
+ }
+ else if (sRequest != null)
+ {
+ pTemp = sRequest.getAttribute("javax.portlet.config");
+ }
+
+ if (pTemp != null) config = pTemp;
+ }
+ if (!(response instanceof PortletResponse))
+ {
+ if (pRequest != null)
+ {
+ pTemp = pRequest.getAttribute("javax.portlet.response");
+ }
+ else if (sRequest != null)
+ {
+ pTemp = sRequest.getAttribute("javax.portlet.response");
+ }
+
+ if (pTemp != null) response = pTemp;
+ }
+ if (!(request instanceof PortletRequest))
+ {
+ if (sRequest != null)
+ {
+ pTemp = sRequest.getAttribute("javax.portlet.request");
+ }
+
+ if (pTemp != null) request = pTemp;
+ }
+
// make sure they passed the right objects
if (config instanceof PortletConfig && request instanceof PortletRequest
&& response instanceof PortletResponse)
Modified: myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java?rev=646598&r1=646597&r2=646598&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan-PortletBridge20-patched/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java Wed Apr 9 16:39:32 2008
@@ -32,7 +32,6 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -45,6 +44,8 @@
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
+import javax.portlet.ClientDataRequest;
+import javax.portlet.MimeResponse;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
@@ -55,6 +56,7 @@
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceURL;
import javax.portlet.WindowState;
import javax.portlet.faces.Bridge;
import javax.portlet.faces.BridgeDefaultViewNotSpecifiedException;
@@ -92,7 +94,8 @@
Bridge.BRIDGE_PACKAGE_PREFIX + "." + Bridge.RENDER_POLICY;
// Render parameter to store the viewId
- public static final String ACTION_ID_PARAMETER_NAME = "_xACTION_ID";
+ public static final String ACTION_ID_PARAMETER_NAME = "_xBridgeActionID";
+ public static final String RESOURCE_ACTION_ID_PARAMETER_NAME = "_xBridgeResourceActionID";
public static final String REDIRECT_ID_PARAMETER_NAME = "org.apache.myfaces.portlet.faces.redirectViewParams";
@@ -412,6 +415,8 @@
public String encodeResourceURL(String s)
{
boolean containsBackLinkMarker = false, isViewLink = false;
+ boolean isOutOfProtocolResource = false;
+
if (s.indexOf(Bridge.BACK_LINK) != -1)
{
containsBackLinkMarker = true;
@@ -421,6 +426,13 @@
{
// Only non-external URLs can be viewLinks
isViewLink = isViewLink(s);
+
+ // Non-Faces links are out of protocol by default
+ if (!isFacesURL(s))
+ {
+ isOutOfProtocolResource = !isInProtocolResourceLink(s);
+ s = removeInProtocolResourceLink(s);
+ }
if (!s.startsWith("/"))
{
@@ -446,15 +458,10 @@
path = path.substring(0, path.lastIndexOf("/"));
s = URLUtils.convertFromRelative(path, s);
}
-
- // prepend the context path since portletResponse.encodeURL() requires a full path URI
- // Don't need to check return from getRequestContextPath because there must
- // always be a vlaue even if an empty string
- String ctxPath = getRequestContextPath();
- if (ctxPath.length() > 0 && !s.startsWith(ctxPath))
- {
- s = ctxPath + s;
- }
+ }
+ else
+ {
+ isOutOfProtocolResource = true;
}
// Check for backlink and viewlink markers -- if they exist replace
@@ -463,9 +470,12 @@
s = replaceResourceQueryStringMarkers(s, containsBackLinkMarker, isViewLink);
}
- if (!isViewLink)
+ if (isOutOfProtocolResource)
{
s = mPortletResponse.encodeURL(s);
+ } else if (!isViewLink)
+ {
+ s = encodePortletResourceURL(s);
}
else
{
@@ -477,6 +487,104 @@
return s;
}
+
+ private String encodePortletResourceURL(String url)
+ {
+ // If a Faces resource, we assume that clients have called
+ // ViewHandler.getActionURL() before calling encodeResourceURL when
+ // doing a partial page URL. Hence all other framework queryString
+ // params should already be encoded.
+
+ // Though might prefer to defer this analysis until the request is
+ // submitted this info is available within ExternalContext but not the
+ // bridge code -- so we would have to reestablish the faces context to
+ // do it then even if we subsequently don't need it because its not a
+ // Faces resource.
+
+ // Determine if there is a target viewId
+ String viewId = null, path = null;
+ QueryString queryStr = null;
+ int queryStart = -1;
+
+ // First: split URL into path and query string
+ // Hold onto QueryString for later processing
+ queryStart = url.indexOf('?');
+
+ if (queryStart != -1)
+ {
+ // Get the query string
+ queryStr = new QueryString(url.substring(queryStart + 1), "UTF8");
+ path = url.substring(0, queryStart);
+ }
+ else
+ {
+ path = url;
+ // construct an empty queryString to hold the viewId
+ queryStr = new QueryString("UTF8");
+ }
+
+ // Now remove up through the ContextPath as we don't want it
+ String ctxPath = getRequestContextPath();
+ int i = path.indexOf(ctxPath);
+ if (i != -1)
+ {
+ path = path.substring(i + ctxPath.length());
+ }
+
+ // Determine the viewId by inspecting the URL
+ // Can't be relative by the time we get here so don't check
+ viewId = getViewIdFromPath(path);
+
+ if (viewId != null)
+ {
+ // This is a Faces resource
+ // put the viewId in the QueryStr.
+ queryStr.addParameter(RESOURCE_ACTION_ID_PARAMETER_NAME, viewId);
+ queryStr.removeParameter(Bridge.PORTLET_MODE_PARAMETER);
+ queryStr.removeParameter(Bridge.PORTLET_WINDOWSTATE_PARAMETER);
+ }
+
+
+ // Encode the URL
+
+ ResourceURL resource = ((MimeResponse) mPortletResponse).createResourceURL();
+ resource.setResourceID(path);
+
+ // Walk through the queryStr Params and add as resourceParams
+ // remove any attempt to set Mode/WindowState/etc. as
+ // not feasible here
+ // Add parameters so they don't get lost
+ Enumeration<String> list = queryStr.getParameterNames();
+ while (list.hasMoreElements())
+ {
+ String param = list.nextElement().toString();
+ if (param.equals(Bridge.PORTLET_MODE_PARAMETER))
+ {
+ // do nothing -- just ignore -- can't encode in a resourceURL
+ }
+ else if (param.equals(Bridge.PORTLET_WINDOWSTATE_PARAMETER))
+ {
+ // do nothing -- just ignore -- can't encode in a resourceURL
+ }
+ else if (param.equals(Bridge.PORTLET_SECURE_PARAMETER))
+ {
+ try
+ {
+ resource.setSecure(Boolean.getBoolean(queryStr.getParameter(param)));
+ }
+ catch (Exception e)
+ {
+ ; // do nothing -- just ignore
+ }
+ }
+ else
+ {
+ resource.setParameter(param, queryStr.getParameter(param));
+ }
+ }
+
+ return resource.toString();
+ }
@Override
public void dispatch(String requestURI)
@@ -487,11 +595,6 @@
throw new java.lang.NullPointerException();
}
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
- {
- throw new IllegalStateException("Request cannot be an ActionRequest");
- }
-
PortletRequestDispatcher prd = mPortletContext.getRequestDispatcher(requestURI);
if (prd == null)
@@ -502,7 +605,7 @@
try
{
- prd.include((RenderRequest) mOrigPortletRequest, (RenderResponse) mOrigPortletResponse);
+ prd.include((PortletRequest) getRequest(), (PortletResponse) getResponse());
}
catch (PortletException e)
{
@@ -683,14 +786,7 @@
public String encodeNamespace(String s)
{
- if (BridgeUtil.getPortletRequestPhase() != Bridge.PortletPhase.RENDER_PHASE)
- {
- throw new IllegalStateException("Only RenderResponse can be used to encode a namespace");
- }
- else
- {
- return ((RenderResponse) mPortletResponse).getNamespace() + s;
- }
+ return ((PortletResponse) mPortletResponse).getNamespace() + s;
}
@Override
@@ -821,21 +917,9 @@
public void setRequestCharacterEncoding(String encoding)
throws UnsupportedEncodingException, IllegalStateException
{
- /* TODO: Temporary workaround for JIRA PORTLETBRIDGE-14 until EG
- * decides on best course of action.
- *
- if (mPhase != Bridge.PortletPhase.ACTION_PHASE)
- {
-
- throw new IllegalStateException(
- "PortletExternalContextImpl.setRequestCharacterEncoding(): Request must be an ActionRequest");
- }
- */
-
- //Part of temp workaround. Do a noop if we are not in action phase
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
+ if (mPhase != null && mPortletRequest instanceof ClientDataRequest)
{
- ((ActionRequest) mPortletRequest).setCharacterEncoding(encoding);
+ ((ClientDataRequest) mPortletRequest).setCharacterEncoding(encoding);
}
}
@@ -866,13 +950,13 @@
@Override
public String getRequestCharacterEncoding()
{
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
+ if (mPhase != null && mPortletRequest instanceof ClientDataRequest)
{
- return ((ActionRequest) mPortletRequest).getCharacterEncoding();
+ return ((ClientDataRequest) mPortletRequest).getCharacterEncoding();
}
else
{
- // RENDER_PHASE -- return null as per spec
+ // other phases -- return null as per spec
return null;
}
}
@@ -904,13 +988,13 @@
@Override
public String getRequestContentType()
{
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
+ if (mPhase != null && mPortletRequest instanceof ClientDataRequest)
{
- return ((ActionRequest) mPortletRequest).getContentType();
+ return ((ClientDataRequest) mPortletRequest).getContentType();
}
else
{
- // RENDER_PHASE: return null as per spec
+ // Other PHASEs: return null as per spec
return null;
}
}
@@ -943,12 +1027,12 @@
@Override
public String getResponseCharacterEncoding()
{
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
+ if (mPhase != null && mPortletRequest instanceof MimeResponse)
{
throw new IllegalStateException("PortletExternalContextImpl.getResponseCharacterEncoding(): Response must be a RenderRequest");
}
- return ((RenderResponse) mPortletResponse).getCharacterEncoding();
+ return ((MimeResponse) mPortletResponse).getCharacterEncoding();
}
/**
@@ -978,12 +1062,12 @@
@Override
public String getResponseContentType()
{
- if (mPhase == Bridge.PortletPhase.ACTION_PHASE)
+ if (mPhase != null && mPortletRequest instanceof MimeResponse)
{
throw new IllegalStateException("PortletExternalContextImpl.getResponseContentType(): Response must be a RenderRequest");
}
- return ((RenderResponse) mPortletResponse).getContentType();
+ return ((MimeResponse) mPortletResponse).getContentType();
}
/**
@@ -1049,6 +1133,12 @@
// where we couldn't update the ACTION_ID
String viewId = mPortletRequest.getParameter(REDIRECT_ID_PARAMETER_NAME);
+ // Next Possibility is its a Resource Request
+ if (viewId == null)
+ {
+ viewId = mPortletRequest.getParameter(RESOURCE_ACTION_ID_PARAMETER_NAME);
+ }
+
// Normal case is its returned in the render parameter
if (viewId == null)
{
@@ -1273,8 +1363,8 @@
}
else
{
- // Set to what follows the URL
- viewId = url;
+ // Not a Faces URL
+ viewId = null;
}
return viewId;
}
@@ -1475,6 +1565,12 @@
return isTokenLink(Bridge.DIRECT_LINK, url);
}
+ private boolean isInProtocolResourceLink(String url)
+ {
+ return isTokenLink(Bridge.IN_PROTOCOL_RESOURCE_LINK, url);
+ }
+
+
private boolean isViewLink(String url)
{
return isTokenLink(Bridge.VIEW_LINK, url);
@@ -1499,6 +1595,11 @@
private String removeDirectLink(String url)
{
return removeTokenLink(Bridge.DIRECT_LINK, url);
+ }
+
+ private String removeInProtocolResourceLink(String url)
+ {
+ return removeTokenLink(Bridge.IN_PROTOCOL_RESOURCE_LINK, url);
}
private String removeTokenLink(String token, String url)