//
if (response instanceof UpdateNavigationalStateResponse)
{
// Update portlet NS
UpdateNavigationalStateResponse updateResponse = (UpdateNavigationalStateResponse)response;
updateNavigationalState(context, portletRequest.getWindowId(), updateResponse, pageNavigationalState);
//
ResponseProperties update = updateResponse.getProperties();
if (update != null)
{
requestProperties.append(update);
}
//
EventControllerContext eventCC = context.getEventControllerContext();
UpdateNavigationalStateResponse stateResponse = (UpdateNavigationalStateResponse)response;
//
EventPhaseContextImpl phaseContext = new EventPhaseContextImpl(log);
// Feed session it with the events that may have been produced
for (UpdateNavigationalStateResponse.Event portletEvent : stateResponse.getEvents())
{
PortletWindowEvent producedEvent = new PortletWindowEvent(portletEvent.getName(), portletEvent.getPayload(), portletRequest.getWindowId());
phaseContext.producedEvents.add(new EventProduction(null, producedEvent));
}
//
int eventDistributionStatus = PortletResponse.DISTRIBUTION_DONE;
// Deliver events
while (phaseContext.producedEvents.size() > 0)
{
EventProduction eventProduction = phaseContext.producedEvents.removeFirst();
PortletWindowEvent producedEvent = eventProduction.getProducedEvent();
//
String producerId = producedEvent.getWindowId();
PortletInfo producerPortletInfo = context.getPortletInfo(producerId);
//
if (producerPortletInfo == null)
{
log.trace("Cannot deliver event " + producedEvent +" because the producer does not have portlet info");
safeInvoker.eventDiscarded(eventCC, phaseContext, producedEvent, EventControllerContext.EVENT_PRODUCER_INFO_NOT_AVAILABLE);
continue;
}
//
if (!controller.getDistributeNonProduceableEvents())
{
if (!producerPortletInfo.getEventing().getProducedEvents().containsKey(producedEvent.getName()))
{
log.trace("Cannot deliver event " + producedEvent +" because the producer of the event does not produce the event name");
safeInvoker.eventDiscarded(eventCC, phaseContext, producedEvent, EventControllerContext.PORTLET_DOES_NOT_CONSUME_EVENT);
continue;
}
}
// Apply produced event quota if necessary
int producedEventThreshold = controller.getProducedEventThreshold();
if (producedEventThreshold >= 0)
{
if (phaseContext.producedEventSize + 1 > producedEventThreshold)
{
log.trace("Event distribution interrupted because the maximum number of produced event is reached");
eventDistributionStatus = PortletResponse.PRODUCED_EVENT_FLOODED;
safeInvoker.eventDiscarded(eventCC, phaseContext, producedEvent, EventControllerContext.PRODUCED_EVENT_FLOODED);
break;
}
}
// Give control to the event context
phaseContext.mode = EventPhaseContextImpl.READ_WRITE_MODE;
if (!safeInvoker.eventProduced(eventCC, phaseContext, eventProduction.getConsumedEvent(), producedEvent))
{
continue;
}
// Perform flow control
if (phaseContext.mode == EventPhaseContextImpl.INTERRUPTED_MODE)
{
log.trace("Event distribution interrupted by controller context");
eventDistributionStatus = PortletResponse.INTERRUPTED;
break;
}
//
while (phaseContext.toConsumeEvents.size() > 0)
{
PortletWindowEvent toConsumeEvent = phaseContext.toConsumeEvents.removeFirst();
String consumedId = toConsumeEvent.getWindowId();
//
PortletInfo consumerPortletInfo = context.getPortletInfo(consumedId);
if (consumerPortletInfo == null)
{
log.trace("Cannot deliver event " + producedEvent +" because the consumer of the event does not have a portlet info");
safeInvoker.eventDiscarded(eventCC, phaseContext, toConsumeEvent, EventControllerContext.EVENT_CONSUMER_INFO_NOT_AVAILABLE);
continue;
}
//
if (!controller.getDistributeNonConsumableEvents())
{
if (!consumerPortletInfo.getEventing().getConsumedEvents().containsKey(toConsumeEvent.getName()))
{
log.trace("Cannot deliver event " + producedEvent +" because the consumer of the event does not accept the event name");
safeInvoker.eventDiscarded(eventCC, phaseContext, toConsumeEvent, EventControllerContext.PORTLET_DOES_NOT_CONSUME_EVENT);
continue;
}
}
// Apply consumed event quota if necessary
int consumedEventThreshold = controller.getConsumedEventThreshold();
if (consumedEventThreshold >= 0)
{
if (phaseContext.consumedEventSize + 1 > consumedEventThreshold)
{
log.trace("Event distribution interrupted because the maximum number of consumed event is reached");
safeInvoker.eventDiscarded(eventCC, phaseContext, toConsumeEvent, EventControllerContext.CONSUMED_EVENT_FLOODED);
eventDistributionStatus = PortletResponse.CONSUMED_EVENT_FLOODED;
break;
}
}
//
PortletInvocationResponse eventResponse;
try
{
eventResponse = deliverEvent(context, toConsumeEvent, pageNavigationalState, requestProperties.getCookies());
}
catch (Exception e)
{
log.trace("Event delivery of " + toConsumeEvent + " failed", e);
safeInvoker.eventFailed(eventCC, phaseContext, toConsumeEvent, e);
continue;
}
// Now it is consumed
phaseContext.consumedEventSize++;
// Update nav state if needed
if (eventResponse instanceof UpdateNavigationalStateResponse)
{
UpdateNavigationalStateResponse eventStateResponse = (UpdateNavigationalStateResponse)eventResponse;
// Update ns
updateNavigationalState(context, toConsumeEvent.getWindowId(), eventStateResponse, pageNavigationalState);
// Add events to source event queue
for (UpdateNavigationalStateResponse.Event portletEvent : eventStateResponse.getEvents())
{
PortletWindowEvent toRouteEvent = new PortletWindowEvent(portletEvent.getName(), portletEvent.getPayload(), toConsumeEvent.getWindowId());
phaseContext.producedEvents.add(new EventProduction(toConsumeEvent, toRouteEvent));
}
//
ResponseProperties updateProperties = eventStateResponse.getProperties();
if (updateProperties != null)
{
requestProperties.append(updateProperties);
}
}