Author: chris.laprun(a)jboss.com
Date: 2006-12-27 21:58:09 -0500 (Wed, 27 Dec 2006)
New Revision: 5937
Modified:
trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java
Log:
- Now try to protect every method with an initialization of the producer. This could be
optimized if we could detect producer changes...
- getPortlet now uses getPortletDescription if there's a cache miss.
- Renamed registerIfNeeded to initializeProducerInteractionAndRegisterIfPossible.
- Renamed checkRegistrationDataAgainstInitialServiceDescription to
examineProducerMetadataAndGetRegistrationDataIfPossible.
- Now uses a special RegistrationData to specify that the associated producer didn't
need registration.
- Minor other changes.
Modified: trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java
===================================================================
--- trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java 2006-12-28
02:35:15 UTC (rev 5936)
+++ trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java 2006-12-28
02:58:09 UTC (rev 5937)
@@ -52,11 +52,14 @@
import org.jboss.portal.wsrp.core.DestroyFailed;
import org.jboss.portal.wsrp.core.DestroyPortlets;
import org.jboss.portal.wsrp.core.DestroyPortletsResponse;
+import org.jboss.portal.wsrp.core.GetPortletDescription;
import org.jboss.portal.wsrp.core.GetPortletProperties;
import org.jboss.portal.wsrp.core.GetServiceDescription;
+import org.jboss.portal.wsrp.core.InvalidHandleFault;
import org.jboss.portal.wsrp.core.LocalizedString;
import org.jboss.portal.wsrp.core.ModelDescription;
import org.jboss.portal.wsrp.core.PortletDescription;
+import org.jboss.portal.wsrp.core.PortletDescriptionResponse;
import org.jboss.portal.wsrp.core.Property;
import org.jboss.portal.wsrp.core.PropertyDescription;
import org.jboss.portal.wsrp.core.PropertyList;
@@ -132,6 +135,16 @@
/** The registration data used to register this consumer with the associated producer
*/
private RegistrationData registrationData;
+ /** A registration data element used to indicate when no registration was required by
the producer */
+ private final static RegistrationData REGISTRATION_NOT_NEEDED =
WSRPTypeFactory.createDefaultRegistrationData();
+
+ static
+ {
+ REGISTRATION_NOT_NEEDED.setConsumerAgent("INVALID AGENT");
+ REGISTRATION_NOT_NEEDED.setConsumerName("INVALID NAME");
+ REGISTRATION_NOT_NEEDED.setRegistrationProperties(null);
+ }
+
/** The default user scopes as per the specification (6.1.4) */
private static final Set WSRP_DEFAULT_USER_SCOPE = new HashSet(2);
@@ -176,28 +189,60 @@
{
ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(portletId, "portlet
id", "PortletContext");
- Map portlets;
- try
+ Portlet portlet;
+
+ // if cache is still valid, use information from cached service description
+ if (useCache() && !isCacheExpired())
{
- portlets = getPortletMap();
+ log.debug("getPortlet from cached service description");
+ Map portlets;
+ try
+ {
+ portlets = getPortletMap();
+ }
+ catch (ServiceDescriptionUnavailableException e)
+ {
+ throw new InvokerUnavailableException(e.getMessage(), e.getCause());
+ }
+
+ portlet = (Portlet)portlets.get(portletId);
}
- catch (ServiceDescriptionUnavailableException e)
+ else // otherwise, retrieve just the information for the appropriate portlet
{
- throw new InvokerUnavailableException(e.getMessage(), e.getCause());
+ log.debug("getPortlet via getPortletDescription");
+ initializeProducerInteractionAndRegisterIfPossible();
+ GetPortletDescription gpd =
WSRPTypeFactory.createGetPortletDescription(registrationContext, portletId);
+ gpd.setUserContext(null); // todo: deal with user context!!
+ try
+ {
+ PortletDescriptionResponse response =
getPortletManagementService().getPortletDescription(gpd);
+ ParameterValidation.throwIllegalArgExceptionIfNull(response,
"PortletDescriptionResponse");
+ portlet =
createWSRPPortletFromPortletDescription(response.getPortletDescription());
+ }
+ catch (InvalidHandleFault invalidHandleFault)
+ {
+ throw new NoSuchPortletException(invalidHandleFault, portletId);
+ }
+ catch (Exception e)
+ {
+ throw new InvokerUnavailableException("Couldn't access remote
producer '" + producerId + "'", e);
+ }
}
- Portlet portlet = (Portlet)portlets.get(portletId);
if (portlet == null)
{
throw new NoSuchPortletException(portletId);
}
-
- return portlet;
+ else
+ {
+ return portlet;
+ }
}
public PortletInvocationResponse invoke(PortletInvocation invocation) throws
PortletInvokerException
{
InvocationHandler handler;
+ initializeProducerInteractionAndRegisterIfPossible();
if (invocation instanceof RenderInvocation)
{
@@ -219,7 +264,7 @@
{
ParameterValidation.throwIllegalArgExceptionIfNull(portletContext,
"PortletContext");
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
// todo: deal with user context
ClonePortlet clonePortlet =
WSRPTypeFactory.createClonePortlet(registrationContext,
@@ -238,7 +283,7 @@
{
ParameterValidation.throwIllegalArgExceptionIfNull(portletIds, "Portlet
identifiers");
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
DestroyPortlets destroyPortlets =
WSRPTypeFactory.createDestroyPortlets(registrationContext,
(String[])portletIds.toArray(new String[0]));
@@ -279,7 +324,7 @@
{
ParameterValidation.throwIllegalArgExceptionIfNull(portletContext,
"PortletContext");
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
GetPortletProperties getPortletProperties =
WSRPTypeFactory.createGetPortletProperties(registrationContext, portletContext.getId());
getPortletProperties.setNames(keys);
@@ -326,7 +371,7 @@
ParameterValidation.throwIllegalArgExceptionIfNull(portletContext,
"PortletContext");
ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(changes, "Property
changes");
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
PropertyList propertyList = WSRPTypeFactory.createPropertyList();
int changesNumber = changes.length;
@@ -460,42 +505,12 @@
for (int i = 0; i < length; i++)
{
PortletDescription portletDescription = portletDescriptions[i];
- String portletHandle = portletDescription.getPortletHandle();
+ WSRPPortlet wsrpPortlet =
createWSRPPortletFromPortletDescription(portletDescription);
- log.debug("Extracting info for '" + portletHandle + "'
portlet");
- WSRPPortletInfo info = new WSRPPortletInfo(portletDescription);
- if (info.isUsesMethodGet())
+ if (wsrpPortlet != null)
{
- log.warn("Portlet '" + portletHandle
- + "' uses the GET method in forms. Since we don't handle
this, this portlet will be excluded from " +
- "the list of offered portlets for producer " +
getProducerId());
+ portlets.put(wsrpPortlet.getContext().getId(), wsrpPortlet);
}
- else if (info.isHasUserSpecificState())
- {
- log.warn("Portlet '" + portletHandle
- + "' will store persistent state for each user. To be handled
properly, this would require " +
- "supporting portlet cloning, which we don't currently do. This
portlet will be excluded from the " +
- "list of offered portlets for producer " + getProducerId());
- }
- else
- {
- WSRPPortlet wsrpPortlet = new WSRPPortlet(portletHandle, info);
-
- // add the portlet to the appropriate group if needed
- String portletGroupId = portletDescription.getGroupID();
- if (portletGroupId != null)
- {
- Set groupedPortlets = (Set)portletGroups.get(portletGroupId);
- if (groupedPortlets == null)
- {
- groupedPortlets = new HashSet();
- portletGroups.put(portletGroupId, groupedPortlets);
- }
- groupedPortlets.add(wsrpPortlet);
- }
-
- portlets.put(portletHandle, wsrpPortlet);
- }
}
return portlets;
@@ -506,6 +521,51 @@
}
}
+ /**
+ * @param portletDescription
+ * @return
+ * @since 2.6
+ */
+ private WSRPPortlet createWSRPPortletFromPortletDescription(PortletDescription
portletDescription)
+ {
+ ParameterValidation.throwIllegalArgExceptionIfNull(portletDescription,
"PortletDescription");
+ String portletHandle = portletDescription.getPortletHandle();
+ log.debug("Extracting info for '" + portletHandle + "'
portlet");
+ WSRPPortletInfo info = new WSRPPortletInfo(portletDescription);
+ WSRPPortlet wsrpPortlet = null;
+ if (info.isUsesMethodGet())
+ {
+ log.warn("Portlet '" + portletHandle
+ + "' uses the GET method in forms. Since we don't handle this,
this portlet will be excluded from " +
+ "the list of offered portlets for producer " + getProducerId());
+ }
+ else if (info.isHasUserSpecificState())
+ {
+ log.warn("Portlet '" + portletHandle
+ + "' will store persistent state for each user. To be handled
properly, this would require " +
+ "supporting portlet cloning, which we don't currently do. This
portlet will be excluded from the " +
+ "list of offered portlets for producer " + getProducerId());
+ }
+ else
+ {
+ wsrpPortlet = new WSRPPortlet(portletHandle, info);
+
+ // add the portlet to the appropriate group if needed
+ String portletGroupId = portletDescription.getGroupID();
+ if (portletGroupId != null)
+ {
+ Set groupedPortlets = (Set)portletGroups.get(portletGroupId);
+ if (groupedPortlets == null)
+ {
+ groupedPortlets = new HashSet();
+ portletGroups.put(portletGroupId, groupedPortlets);
+ }
+ groupedPortlets.add(wsrpPortlet);
+ }
+ }
+ return wsrpPortlet;
+ }
+
// Cache support
****************************************************************************************************
private boolean useCache()
@@ -516,7 +576,7 @@
private void updateCachesIfNeeded()
throws ServiceDescriptionUnavailableException, PortletInvokerException
{
- if (System.currentTimeMillis() > expirationTimeMillis || cachedPortletMap ==
null || portletGroups == null)
+ if (isCacheExpired())
{
cachedPortletMap =
extractOfferedPortlets(getServiceDescriptionAndRegisterIfNeeded());
@@ -525,6 +585,15 @@
}
}
+ /**
+ * @return
+ * @since 2.6
+ */
+ private boolean isCacheExpired()
+ {
+ return System.currentTimeMillis() > expirationTimeMillis || cachedPortletMap ==
null || portletGroups == null;
+ }
+
public Integer getExpirationCacheSeconds()
{
return expirationCacheSeconds;
@@ -559,7 +628,7 @@
// reset registration data and try again
resetRegistration();
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
}
RegistrationContext getRegistrationContext()
@@ -648,7 +717,7 @@
private ServiceDescription getServiceDescriptionAndRegisterIfNeeded() throws
ServiceDescriptionUnavailableException, PortletInvokerException
{
// try initial registration if needed
- registerIfNeeded();
+ initializeProducerInteractionAndRegisterIfPossible();
GetServiceDescription request = getServiceDescriptionRequest();
request.setRegistrationContext(registrationContext);
@@ -661,9 +730,6 @@
if (serviceDescription != null)
{
- // do we need to call initCookie or not?
-
sessionHandler.setRequiresInitCookie(serviceDescription.getRequiresInitCookie());
-
// from now on (that is until getServiceDescription fails) use this
successful request
setServiceDescriptionRequest(request);
return serviceDescription;
@@ -684,61 +750,59 @@
}
/**
- * Attempts to register if our producer configuration provides registration data and
we don't have a valid
- * RegistrationContext yet.
+ * Examine the producer's metadata and attempts to register if required by the
producer and possible.
*
* @throws org.jboss.portal.portlet.PortletInvokerException
*
* @since 2.6
*/
- private void registerIfNeeded() throws PortletInvokerException
+ private void initializeProducerInteractionAndRegisterIfPossible() throws
PortletInvokerException
{
- // no registrationContext = we might need to register
- if (registrationContext == null)
+ // this could be optimized if we could ensure that the service description
hadn't changed
+ // in particular with consumer.MarkupTestCase.testInitCookie, we change the cookie
requirements
+ // and we need to be able to detect it... :( todo: use extensions for JBoss to
JBoss?
+ ServiceDescription serviceDescription = getMinimalServiceDescription();
+
+ // do we need to call initCookie or not?
+ sessionHandler.setRequiresInitCookie(serviceDescription.getRequiresInitCookie());
+
+ //todo: could extract more information here...
+
+ // no registrationContext and the producer didn't already indicate that it
didn't require registration
+ if (registrationContext == null &&
!REGISTRATION_NOT_NEEDED.equals(registrationData))
{
- // we don't have any registration data, check if need one and inform user if
needed
- if (registrationData == null)
- {
- checkRegistrationDataAgainstInitialServiceDescription();
- }
+ examineProducerMetadataAndGetRegistrationDataIfPossible(serviceDescription);
- try
+ if (!REGISTRATION_NOT_NEEDED.equals(registrationData))
{
- registrationContext = getRegistrationService().register(registrationData);
- if (registrationContext == null)
+ try
{
- throw new PortletInvokerException("Received null response from
producer '" + producerId + "'");
+ registrationContext =
getRegistrationService().register(registrationData);
+ if (registrationContext == null)
+ {
+ throw new PortletInvokerException("Received null response from
producer '" + producerId + "'");
+ }
+
+ log.info("Successfully registered with handle: '" +
registrationContext.getRegistrationHandle() + "'");
}
-
- log.info("Successfully registered with handle: '" +
registrationContext.getRegistrationHandle() + "'");
+ catch (Exception e)
+ {
+ resetRegistration();
+ throw new PortletInvokerException("Couldn't register with
producer '" + producerId + "'", e);
+ }
}
- catch (Exception e)
- {
- resetRegistration();
- throw new PortletInvokerException("Couldn't register with producer
'" + producerId + "'", e);
- }
}
}
/**
+ * @param serviceDescription
* @throws ServiceDescriptionUnavailableException
*
* @throws PortletInvokerException
* @since 2.6
*/
- private void checkRegistrationDataAgainstInitialServiceDescription() throws
PortletInvokerException
+ private void
examineProducerMetadataAndGetRegistrationDataIfPossible(ServiceDescription
serviceDescription) throws PortletInvokerException
{
- ServiceDescription serviceDescription;
- try
- {
- serviceDescription =
getServiceDescriptionService().getServiceDescription(getUnregisteredServiceDescriptionRequest());
- }
- catch (Exception e)
- {
- throw new PortletInvokerException("Couldn't access service description
for producer '"
- + getProducerId() + "'", e);
- }
-
if (serviceDescription.isRequiresRegistration())
{
StringBuffer message = new StringBuffer("Producer
'").append(producerId)
@@ -807,8 +871,34 @@
registrationData = WSRPTypeFactory.createDefaultRegistrationData();
}
}
+ else
+ {
+ // the producer doesn't need registration, let this consumer know for future
reference
+ registrationData = REGISTRATION_NOT_NEEDED;
+ }
}
+ /**
+ * @return
+ * @throws PortletInvokerException
+ * @since 2.6
+ */
+ private ServiceDescription getMinimalServiceDescription()
+ throws PortletInvokerException
+ {
+ ServiceDescription serviceDescription;
+ try
+ {
+ serviceDescription =
getServiceDescriptionService().getServiceDescription(getUnregisteredServiceDescriptionRequest());
+ }
+ catch (Exception e)
+ {
+ throw new PortletInvokerException("Couldn't access service description
for producer '"
+ + getProducerId() + "'", e);
+ }
+ return serviceDescription;
+ }
+
/** @since 2.6 */
private void resetRegistration()
{