You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2009/01/15 01:04:58 UTC
svn commit: r734568 - in
/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component:
UIComponent.java UIViewRoot.java
Author: slessard
Date: Wed Jan 14 16:04:57 2009
New Revision: 734568
URL: http://svn.apache.org/viewvc?rev=734568&view=rev
Log:
Apply latest spec changes for UIComponent and UIViewRoot
Modified:
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java
Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java?rev=734568&r1=734567&r2=734568&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponent.java Wed Jan 14 16:04:57 2009
@@ -563,7 +563,6 @@
/**
* @since 1.2
*/
-
public String getContainerClientId(FacesContext ctx)
{
if (ctx == null)
Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=734568&r1=734567&r2=734568&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIViewRoot.java Wed Jan 14 16:04:57 2009
@@ -20,9 +20,11 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
@@ -180,72 +182,33 @@
*/
public void broadcastEvents(FacesContext context, PhaseId phaseId)
{
- /*
- * Broadcast any events that have been queued. First broadcast events that have been queued for
- * PhaseId.ANY_PHASE. Then broadcast ane events that have been queued for the current phase.
- * In both cases,
- * UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent) must
- * be called before the event is broadcast, and
- * UIComponent.popComponentFromEL(javax.faces.context.FacesContext) must be called after the return from
- * the broadcast, even in the case of an exception.
- */
- // TODO
-
if (_events == null)
{
return;
}
- // TODO
- // TODO
- // TODO
- for (ListIterator<FacesEvent> listIterator = _events.listIterator(); listIterator.hasNext();)
- {
-
- }
-
- boolean abort = false;
-
- int phaseIdOrdinal = phaseId.getOrdinal();
- for (ListIterator<FacesEvent> listiterator = _events.listIterator(); listiterator.hasNext();)
+
+ // Gather the events and purge the event list to prevent concurrent modification during broadcasting
+ List<FacesEvent> anyPhase = new ArrayList<FacesEvent>(_events.size());
+ List<FacesEvent> onPhase = new ArrayList<FacesEvent>(_events.size());
+ for (Iterator<FacesEvent> iterator = _events.iterator(); iterator.hasNext();)
{
- FacesEvent event = listiterator.next();
- int ordinal = event.getPhaseId().getOrdinal();
- if (ordinal == ANY_PHASE_ORDINAL || ordinal == phaseIdOrdinal)
+ FacesEvent event = iterator.next();
+ if (event.getPhaseId().equals(PhaseId.ANY_PHASE))
{
- UIComponent source = event.getComponent();
- try
- {
- source.broadcast(event);
- }
- catch (AbortProcessingException e)
- {
- // abort event processing Page 3-30 of JSF 1.1 spec: "Throw an AbortProcessingException,
- // to tell the JSF implementation that no further broadcast of this event, or any further
- // events, should take place."
- abort = true;
- break;
- }
- finally
- {
- try
- {
- listiterator.remove();
- }
- catch (ConcurrentModificationException cme)
- {
- int eventIndex = listiterator.previousIndex();
- _events.remove(eventIndex);
- listiterator = _events.listIterator();
- }
- }
+ anyPhase.add(event);
+ iterator.remove();
+ }
+ else if (event.getPhaseId().equals(phaseId))
+ {
+ onPhase.add(event);
+ iterator.remove();
}
}
-
- if (abort)
+
+ // First broadcast events that have been queued for PhaseId.ANY_PHASE.
+ if (_broadcastAll(context, anyPhase))
{
- // TODO: abort processing of any event of any phase or just of any
- // event of the current phase???
- clearEvents();
+ _broadcastAll(context, onPhase);
}
}
@@ -599,14 +562,14 @@
public void processApplication(final FacesContext context)
{
checkNull(context, "context");
- process(context, PhaseId.INVOKE_APPLICATION, null, true);
+ _process(context, PhaseId.INVOKE_APPLICATION, null);
}
@Override
public void processDecodes(FacesContext context)
{
checkNull(context, "context");
- process(context, PhaseId.APPLY_REQUEST_VALUES, APPLY_REQUEST_VALUES_PROCESSOR, true);
+ _process(context, PhaseId.APPLY_REQUEST_VALUES, APPLY_REQUEST_VALUES_PROCESSOR);
}
/**
@@ -624,7 +587,7 @@
finally
{
// The try block must have a finally block that ensures that no FacesEvents remain in the event queue
- _broadcastForPhase(PhaseId.RESTORE_VIEW);
+ broadcastEvents(context, PhaseId.RESTORE_VIEW);
// that any PhaseListeners in getPhaseListeners() are invoked as appropriate
PhaseEvent event = createEvent(context, PhaseId.RESTORE_VIEW);
@@ -654,14 +617,14 @@
public void processValidators(FacesContext context)
{
checkNull(context, "context");
- process(context, PhaseId.PROCESS_VALIDATIONS, PROCESS_VALIDATORS_PROCESSOR, true);
+ _process(context, PhaseId.PROCESS_VALIDATIONS, PROCESS_VALIDATORS_PROCESSOR);
}
@Override
public void processUpdates(FacesContext context)
{
checkNull(context, "context");
- process(context, PhaseId.UPDATE_MODEL_VALUES, UPDATE_MODEL_PROCESSOR, true);
+ _process(context, PhaseId.UPDATE_MODEL_VALUES, UPDATE_MODEL_PROCESSOR);
}
public void setLocale(Locale locale)
@@ -669,29 +632,6 @@
this._locale = locale;
}
- private boolean process(FacesContext context, PhaseId phaseId, PhaseProcessor processor, boolean broadcast)
- {
- if (!notifyListeners(context, phaseId, getBeforePhaseListener(), true))
- {
- if (processor != null)
- {
- processor.process(context, this);
- }
-
- if (broadcast)
- {
- _broadcastForPhase(phaseId);
- }
- }
-
- if (context.getRenderResponse() || context.getResponseComplete())
- {
- clearEvents();
- }
-
- return notifyListeners(context, phaseId, getAfterPhaseListener(), false);
- }
-
/**
* Invoke view-specific phase listeners, plus an optional EL MethodExpression.
* <p>
@@ -733,8 +673,6 @@
* passing in the same PhaseId as in the previous step.
*/
- boolean skipPhase = false;
-
if (listener != null || (_phaseListeners != null && !_phaseListeners.isEmpty()))
{
PhaseEvent event = createEvent(context, phaseId);
@@ -742,7 +680,6 @@
if (listener != null)
{
listener.invoke(context.getELContext(), new Object[] { event });
- skipPhase = context.getResponseComplete() || context.getRenderResponse();
}
if (_phaseListeners != null && !_phaseListeners.isEmpty())
@@ -760,13 +697,12 @@
{
phaseListener.afterPhase(event);
}
- skipPhase = context.getResponseComplete() || context.getRenderResponse();
}
}
}
}
- return skipPhase;
+ return context.getResponseComplete() || context.getRenderResponse();
}
private PhaseEvent createEvent(FacesContext context, PhaseId phaseId)
@@ -783,6 +719,46 @@
}
return new PhaseEvent(context, phaseId, _lifecycle);
}
+
+ /**
+ * Broadcast all events in the specified collection, stopping the at any time an AbortProcessingException
+ * is thrown.
+ *
+ * @param context the current JSF context
+ * @param events the events to broadcast
+ *
+ * @return <code>true</code> if the broadcast was completed without abortion, <code>false</code> otherwise
+ */
+ private boolean _broadcastAll(FacesContext context, Collection<? extends FacesEvent> events)
+ {
+ assert events != null;
+
+ for (FacesEvent event : events)
+ {
+ UIComponent source = event.getComponent();
+
+ // Push the source as the current component
+ pushComponentToEL(context, source);
+
+ try
+ {
+ // Actual event broadcasting
+ source.broadcast(event);
+ }
+ catch (AbortProcessingException e)
+ {
+ // Abortion
+ return false;
+ }
+ finally
+ {
+ // Restore the current component
+ popComponentFromEL(context);
+ }
+ }
+
+ return true;
+ }
private void _broadcastForPhase(PhaseId phaseId)
{
@@ -1120,6 +1096,38 @@
return clientIds;
}
+
+ /**
+ * Process the specified phase by calling PhaseListener.beforePhase for every phase listeners defined on this
+ * view root, then calling the process method of the processor, broadcasting relevant events and finally
+ * notifying the afterPhase method of every phase listeners registered on this view root.
+ *
+ * @param context
+ * @param phaseId
+ * @param processor
+ * @param broadcast
+ *
+ * @return
+ */
+ private boolean _process(FacesContext context, PhaseId phaseId, PhaseProcessor processor)
+ {
+ if (!notifyListeners(context, phaseId, getBeforePhaseListener(), true))
+ {
+ if (processor != null)
+ {
+ processor.process(context, this);
+ }
+
+ broadcastEvents(context, phaseId);
+ }
+
+ if (context.getRenderResponse() || context.getResponseComplete())
+ {
+ clearEvents();
+ }
+
+ return notifyListeners(context, phaseId, getAfterPhaseListener(), false);
+ }
private void _processDecodesAjax(FacesContext context)
{