You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gc...@apache.org on 2010/06/16 17:27:21 UTC
svn commit: r955269 - in
/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main:
java/org/apache/myfaces/trinidad/change/
java/org/apache/myfaces/trinidad/webapp/
xrts/org/apache/myfaces/trinidad/resource/
Author: gcrawford
Date: Wed Jun 16 15:27:21 2010
New Revision: 955269
URL: http://svn.apache.org/viewvc?rev=955269&view=rev
Log:
TRINIDAD-1784 Session ChangeManager should not apply attribute customizations for cases when it is not needed
Modified:
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/AddChildComponentChange.java
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/MoveChildComponentChange.java
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SetFacetChildComponentChange.java
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java
myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/AddChildComponentChange.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/AddChildComponentChange.java?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/AddChildComponentChange.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/AddChildComponentChange.java Wed Jun 16 15:27:21 2010
@@ -28,7 +28,8 @@ import org.apache.myfaces.trinidad.loggi
/**
* Change specialization for adding a child component.
* While applying this Change, the child component is re-created and added to
- * the list of children.
+ * the list of children. If a child component with an id same as the new child being added is
+ * already present in the parent container, the new child is not added.
* @version $Name: $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/change/AddChildComponentChange.java#0 $) $Date: 10-nov-2005.19:09:54 $
*/
public class AddChildComponentChange extends AddComponentChange
@@ -86,17 +87,15 @@ public class AddChildComponentChange ext
String newChildId = child.getId();
List<UIComponent> children = uiComponent.getChildren();
- //pu: If there were to be a child already with the ID same as the
- // to-be-added child, remove it and get the new one added.
- UIComponent removableChild = ChangeUtils.getChildForId(uiComponent, newChildId);
+ // If there were to be a child already with the ID same as the to-be-added child, it might have
+ // been added from previous change application, and further customizations might have happened
+ // on them. We just want to warn, abort the child addition, and not alter the component tree.
+ UIComponent duplicateChild = ChangeUtils.getChildForId(uiComponent, newChildId);
- // Users can add component themselves in addition to adding a ComponentChange
- // This could cause duplicates, which is fine. Handle this gracefully with
- // a info log and replacement
- if (removableChild != null)
+ if (duplicateChild != null)
{
_LOG.info("ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID", newChildId);
- children.remove(removableChild);
+ return;
}
if (_insertBeforeId == null)
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/MoveChildComponentChange.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/MoveChildComponentChange.java?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/MoveChildComponentChange.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/MoveChildComponentChange.java Wed Jun 16 15:27:21 2010
@@ -38,9 +38,8 @@ import org.w3c.dom.Node;
* parent component instance must be passed as an argument. The add() utility
* method in this class can be alternatively used to conveniently register the
* change against the common parent. While applying this change, if a child with
- * the same identifier as the movable child were to be already present in the
- * destination container, it will be considered as a duplicate child, will be
- * removed and movable child will be added.
+ * the same id as the movable child were to be already present in the destination
+ * container, the move operation is aborted.
* @see #add(FacesContext, ChangeManager)
* @see ChangeManager#addComponentChange(FacesContext, UIComponent, ComponentChange)
* @see ChangeManager#addDocumentChange(FacesContext, UIComponent, DocumentChange)
@@ -113,8 +112,8 @@ public final class MoveChildComponentCha
ComponentUtils.getScopedIdForComponent(destinationContainer, _commonParent);
_commonParentScopedId =
- ComponentUtils.getScopedIdForComponent(_commonParent, null);
-
+ ComponentUtils.getScopedIdForComponent(_commonParent,
+ FacesContext.getCurrentInstance().getViewRoot());
if (_movableChildScopedId == null ||
_sourceParentScopedId == null ||
_destinationContainerScopedId == null ||
@@ -233,35 +232,71 @@ public final class MoveChildComponentCha
return;
}
- // 2. Find movableChild, gather any duplicates and remove them.
+ // 2. Find movableChild, gather the possible duplicates (theoritically only three) and keep a
+ // single copy among them.
// Duplicates are possible because
// a) taghandlers re-create the component that was in the jspx file in
// their original location, no matter whether it was moved/removed due to
// aplication of a different ComponentChange. Such components could now
- // be considered duplicates. In theory, there could be just one such
+ // be considered duplicates, because they are newly created from their vanilla definition
+ // in the jspx document, and would not have any further ComponentChanges applied on them.
+ // There should be one such duplicate.
+ // b) Apart from adding the MoveComponentChange, we expect developers to apply the change in
+ // order to reflect in the same request cycle (i.e. developers call
+ // ComponentChange.changeComponent()). Consequently, the component tree contains a moved
+ // child at the destination. Such components must be preserved, because they have
+ // incorporated any subsequent ComponentChanges on them. There should be one such moved
+ // component.
+ // c) We would have moved/added components due to previous customization an earlier application
+ // of ComponentChange, that could still be in the view tree. There should be one such zombie/
// duplicate.
- // b) We would have moved/added components due to an earlier application of
- // a ComponentChange, that could still be in the view tree. Such
- // components must now be considered duplicates. In theory, there could
- // be just one such duplicate.
- // This issue of duplicates is more common when the movement is within same
- // NamingContainer.
UIComponent sourceParent =
changeTargetComponent.findComponent(_sourceParentScopedId);
UIComponent foundChild =
changeTargetComponent.findComponent(_movableChildScopedId);
- //Assume the first found child is the movableChild
- UIComponent movableChild = foundChild;
+
+ // To flag if a child was already found in a destination container (maybe due to previous move)
+ boolean isChildIdAtDestination = false;
+
+ UIComponent movableChild = null;
int movableChildIndex = 0;
+ UIComponent movedChild = null;
+ int movedChildIndex = 0;
+ UIComponent duplicateChild = null;
+ int duplicateChildIndex = 0;
+ UIComponent duplicateChildParent = null;
+
while (foundChild != null)
{
- // If the parent matches, this is the one to move, rest are duplicates
+ // 2.a. If the parent matches, this could be the component that JSF-Runtime re-created
+ // and added because it is in the physical document
if (foundChild.getParent().equals(sourceParent))
{
movableChild = foundChild;
movableChildIndex = sourceParent.getChildren().indexOf(movableChild);
}
+ // 2.b.a. We could possibly find the child at its destination, because apart from
+ // adding the change, the change was applied in previous request, and the move
+ // could have been within the same naming container umbrella. In this case
+ // we do not want to move anything and the movable child is considered as a
+ // duplicate and candidate for removal.
+ else if (foundChild.getParent().equals(destinationContainer))
+ {
+ isChildIdAtDestination = true;
+ movedChild = foundChild;
+ movedChildIndex = destinationContainer.getChildren().indexOf(movedChild);
+ }
+ // 2.c. Possible dup from subsequent MoveChildComponentChange in the sequence of multiple
+ // moves of the component in this same request. For example, if the move is from A->B->C,
+ // and if we are currently dealing with move from A->B, the component that was added at
+ // position C (in addition to adding the move change to changemanager) will now be dup.
+ else
+ {
+ duplicateChild = foundChild;
+ duplicateChildIndex = foundChild.getParent().getChildren().indexOf(foundChild);
+ duplicateChildParent = foundChild.getParent();
+ }
// Invariably, remove the found component from the tree. We remove the
// movableChild also, otherwise, findComponent blind loops on this same
@@ -269,39 +304,74 @@ public final class MoveChildComponentCha
// NamingContainer.
foundChild.getParent().getChildren().remove(foundChild);
- // Try and find the next potential duplicate
+ // Try and find the next potential copy of the component to move
foundChild = changeTargetComponent.findComponent(_movableChildScopedId);
}
+ // We need to re-attach the dup for now, the dupes will be eliminated gradually while applying
+ // the successive move change involving the same component.
+ if (duplicateChild != null)
+ {
+ duplicateChildParent.getChildren().add(duplicateChildIndex, duplicateChild);
+ }
+
+ // Can't do anything without a movable child.
if(movableChild == null)
{
_LOG.warning("MOVABLE_CHILD_NOT_FOUND", _movableChildScopedId);
+ // Reverse any damage that we might have caused, and exit
+ if (movedChild != null)
+ {
+ destinationContainer.getChildren().add(movedChildIndex, movedChild);
+ }
return;
}
- // Reattach the moveable child, so that move happens atomically at the end.
- sourceParent.getChildren().add(movableChildIndex, movableChild);
-
- // 3. If there is a child already existing with the same identifier in the
- // destination container, remove it. We are doing this before identifying
- // the insert index so that insert index is accurate, in case we end up
- // removing any child in this step.
- String movableChildId = movableChild.getId();
- int indexOfChildWithSameIdAtDestination = 0;
- UIComponent childWithSameIdAtDestination = null;
- for (UIComponent childComponent:destinationContainer.getChildren())
+ // 2.b.b. Similar to situation in step #2.b.a, but here the move is across different naming
+ // containers, we could not catch this earlier.
+ if (!isChildIdAtDestination)
{
- if (movableChildId.equals(childComponent.getId()))
+ String movableChildId = movableChild.getId();
+ for (UIComponent childComponent:destinationContainer.getChildren())
+ {
+ if (movableChildId.equals(childComponent.getId()))
+ {
+ isChildIdAtDestination = true;
+ movedChild = childComponent;
+ // Temporarily remove this child, we might add it back in step #3 below.
+ movedChild.getParent().getChildren().remove(movedChild);
+ break;
+ }
+ }
+ }
+
+ // 3. Check whether the destination container has a child with same id.
+ if (isChildIdAtDestination)
+ {
+ _LOG.warning("MOVABLE_CHILD_SAME_ID_FOUND", _movableChildScopedId);
+
+ // Component type matches, this means the child is already at destination. We have removed all
+ // duplicates, and have nothing more to do in this case
+ if ( (movableChild.getFamily().equals(movedChild.getFamily())) &&
+ (movableChild.getRendererType().equals(movedChild.getRendererType())) )
+ {
+ // Add back the moved child that we removed earlier.
+ destinationContainer.getChildren().add(movedChildIndex, movedChild);
+ }
+ else
{
- indexOfChildWithSameIdAtDestination =
- destinationContainer.getChildren().indexOf(childComponent);
- childWithSameIdAtDestination = childComponent;
- destinationContainer.getChildren().remove(childComponent);
+ // Duplicate child by id, but not of the same component type - a condition we cannot handle.
+ // Reverse any damage that we might have caused and exit
+ sourceParent.getChildren().add(movableChildIndex, movableChild);
}
+ return;
}
+
+ // We are now dealing with case where there were no duplicates, and a proper point-to-point
+ // move should happen. Reattach the moveable child, so that move happens atomically at the end.
+ sourceParent.getChildren().add(movableChildIndex, movableChild);
- // 4. See if we can find the insertBeforeComponent among the
- // destinationContainer's children
+ // 4. See if we can find the insertBeforeComponent among the destinationContainer's children
int insertIndex = -1;
if (_insertBeforeId != null)
{
@@ -315,16 +385,9 @@ public final class MoveChildComponentCha
}
}
- // insertBeforeId was specified, but corresponding component is missing.
- // In this case abort the move, after re-adding any components in
- // destination container that we may have deleted from step #3.
+ // insertBeforeId was specified, but we cannot find the insertBefore component. Exit.
if (insertIndex == -1)
{
- if (childWithSameIdAtDestination != null)
- destinationContainer.getChildren().add(
- indexOfChildWithSameIdAtDestination,
- childWithSameIdAtDestination);
-
_LOG.warning("INSERT_BEFORE_NOT_FOUND", _insertBeforeId);
return;
}
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java Wed Jun 16 15:27:21 2010
@@ -36,19 +36,25 @@ import javax.faces.component.UIComponent
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
+import org.apache.myfaces.trinidad.context.RequestContext;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.util.CollectionUtils;
import org.apache.myfaces.trinidad.util.ComponentUtils;
+import org.apache.myfaces.trinidad.webapp.UIXComponentELTag;
+
import org.w3c.dom.Document;
/**
- * A ChangeManager implementation that manages
- * persisting the added Changes at the session. This means
- * the lifetime of Changes added such is within the session scope.
+ * A ChangeManager implementation that manages persisting the added Changes at the session.
+ * This means the lifetime of Changes added such is within the session scope. If any of the changes
+ * are managed as state changes and restored by JSF state saving mechanism, the SessionChangeManager
+ * will not re-apply such changes. For example: AttributeComponentChanges are not applied during
+ * a postback unless its target component happened to be a result of any move/add operation, this is
+ * because attribute changes are handled by state manager during postback for common cases.
* @version $Name: $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/change/SessionChangeManager.java#0 $) $Date: 10-nov-2005.19:06:35 $
- */
+*/
public class SessionChangeManager extends BaseChangeManager
{
/**
@@ -80,7 +86,7 @@ public class SessionChangeManager extend
"INVALID_TYPE", root));
}
- rootId = ComponentUtils.getScopedIdForComponent((UIComponent)root, null);
+ rootId = ComponentUtils.getScopedIdForComponent((UIComponent)root, facesContext.getViewRoot());
}
_applyComponentChanges(facesContext, rootId);
@@ -108,7 +114,7 @@ public class SessionChangeManager extend
// get the absolute scopedId for the target component so that we have a unique identifier
// to compare
String scopedIdForTargetComponent =
- ComponentUtils.getScopedIdForComponent(targetComponent, null);
+ ComponentUtils.getScopedIdForComponent(targetComponent, facesContext.getViewRoot());
// try to collapse AttributeComponentChanges, handling component movement so that
// we can collapse any attribute change on the same component
@@ -221,26 +227,137 @@ public class SessionChangeManager extend
if (!_acceptChange(qualifiedChange, rootId))
continue;
- UIComponent targetComponent =
- viewRoot.findComponent(qualifiedChange.getTargetComponentScopedId());
+ String targetComponentScopedId = qualifiedChange.getTargetComponentScopedId();
+
+ UIComponent targetComponent = viewRoot.findComponent(targetComponentScopedId);
- // Possible that the target component no more exists in the view
- if (targetComponent != null)
- {
- ComponentChange componentChange = qualifiedChange.getComponentChange();
- componentChange.changeComponent(targetComponent);
- }
- else
+ // Possible that the target component no more exists in the view, if yes, skip
+ if (targetComponent == null)
{
_LOG.info(this.getClass().getName(),
"applyComponentChangesForCurrentView",
"TARGET_COMPONENT_MISSING_CHANGE_FAILED",
- qualifiedChange.getTargetComponentScopedId());
+ targetComponentScopedId);
+ continue;
+ }
+
+ ComponentChange componentChange = qualifiedChange.getComponentChange();
+
+ // We do not apply attribute changes if it is a postback, because we expect that
+ // 1. Users calling ChangeManager.addComponentChange() would also apply the change right at
+ // that point in time (maybe by calling ComponentChange.changeComponent() method).
+ // 2. If #1 was done, JSF state manager will consider this a state change and will store and
+ // restore it during subsequent postbacks, so there is no need for applying attribute changes
+ // for postback cases. There are few exceptions where the state management will not help, for
+ // which we force the attribute changes even when it is a postback.
+ if ( componentChange instanceof AttributeComponentChange &&
+ _isStateRestored(facesContext) &&
+ !_isAttributeChangeForced(facesContext, targetComponentScopedId) )
+ continue;
+
+ // Apply the change
+ componentChange.changeComponent(targetComponent);
+
+ // Now that the change is applied, we can identify if the components altered by the currently
+ // applied change needs forced application of any further changes regardless of request
+ // being a postback.
+ if (componentChange instanceof MoveChildComponentChange)
+ {
+ String destinationScopedId =
+ ((MoveChildComponentChange)componentChange).getDestinationScopedId();
+ _addAttributeChangeForced(facesContext, destinationScopedId);
+ }
+ else if (componentChange instanceof SetFacetChildComponentChange)
+ {
+ String facetName = ((SetFacetChildComponentChange)componentChange).getFacetName();
+ UIComponent facetComponent = targetComponent.getFacet(facetName);
+ String facetScopedId =
+ ComponentUtils.getScopedIdForComponent(facetComponent, facesContext.getViewRoot());
+ if (facetComponent != null)
+ _addAttributeChangeForced(facesContext, facetScopedId);
+ }
+ else if (componentChange instanceof AddChildComponentChange)
+ {
+ // Get the added component from AddComponentChange, this component is actually re-created
+ // from the proxy, and not the actual added component.
+ // Bit hacky but this is only way to get Id.
+ String addedComponentId = ((AddChildComponentChange)componentChange).getComponent().getId();
+ // Now get the actual added component finding from the parent to which it was added to
+ UIComponent addedComponent =
+ ComponentUtils.findRelativeComponent(targetComponent, addedComponentId);
+ String addedChildComponentScopedId =
+ ComponentUtils.getScopedIdForComponent(addedComponent, facesContext.getViewRoot());
+ if (addedComponent != null)
+ _addAttributeChangeForced(facesContext, addedChildComponentScopedId);
}
}
}
/**
+ * Is the state restored by JSF state manager in this request. This is usually true if this is a
+ * postback request. Additionally check if the document tag created a document component, because
+ * if this is the case, we are sure that there was no state restoration.
+ */
+ private boolean _isStateRestored(FacesContext facesContext)
+ {
+ boolean docCompCreated = Boolean.TRUE.equals(facesContext.getExternalContext().
+ getRequestMap().get(UIXComponentELTag.DOCUMENT_CREATED_KEY));
+ return (docCompCreated) ? false : RequestContext.getCurrentInstance().isPostback();
+ }
+
+ /**
+ * For a given scopedId records that any further AttributeComponentChanges must be applied always.
+ */
+ private void _addAttributeChangeForced(FacesContext facesContext, String targetScopedId)
+ {
+ if (targetScopedId == null)
+ return;
+
+ Object session = facesContext.getExternalContext().getSession(true);
+
+ synchronized(session)
+ {
+ Map<String, Object> sessMap = facesContext.getExternalContext().getSessionMap();
+
+ CopyOnWriteArrayList<String> forceChangesTargetList = (CopyOnWriteArrayList<String>)
+ sessMap.get(_ATTRIBUTE_CHANGE_FORCED_COMPONENTS);
+
+ if (forceChangesTargetList == null)
+ {
+ forceChangesTargetList = new CopyOnWriteArrayList<String>();
+ sessMap.put(_ATTRIBUTE_CHANGE_FORCED_COMPONENTS, forceChangesTargetList);
+ }
+
+ forceChangesTargetList.addIfAbsent(targetScopedId);
+ }
+ }
+
+ /**
+ * Given a scopedId for the component, returns whether all AttributeComponentChange should be
+ * forced on this component.
+ */
+ private boolean _isAttributeChangeForced(FacesContext facesContext, String targetScopedId)
+ {
+ if (targetScopedId == null)
+ return false;
+
+ Object session = facesContext.getExternalContext().getSession(true);
+
+ synchronized(session)
+ {
+ Map<String, Object> sessMap = facesContext.getExternalContext().getSessionMap();
+
+ List<String> forceChangesTargetList = (List<String>)
+ sessMap.get(_ATTRIBUTE_CHANGE_FORCED_COMPONENTS);
+
+ if (forceChangesTargetList == null || forceChangesTargetList.isEmpty())
+ return false;
+
+ return forceChangesTargetList.contains(targetScopedId);
+ }
+ }
+
+ /**
* Tests whether the specified change should be applied based on the
* specified root id. If root id is null, all changes are accepted/applied.
* If the root id is non-null, only changes which target ids underneath
@@ -461,6 +578,9 @@ public class SessionChangeManager extend
private static final String _COMPONENT_CHANGES_MAP_FOR_SESSION_KEY =
"org.apache.myfaces.trinidadinternal.ComponentChangesMapForSession";
+ private static final String _ATTRIBUTE_CHANGE_FORCED_COMPONENTS =
+ "org.apache.myfaces.trinidadinternal.AttributeChangeForcedComponents";
+
private static final TrinidadLogger _LOG =
TrinidadLogger.createTrinidadLogger(SessionChangeManager.class);
}
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SetFacetChildComponentChange.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SetFacetChildComponentChange.java?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SetFacetChildComponentChange.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SetFacetChildComponentChange.java Wed Jun 16 15:27:21 2010
@@ -19,13 +19,14 @@
package org.apache.myfaces.trinidad.change;
import javax.faces.component.UIComponent;
+
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
/**
* Change specialization for adding a facet.
- * While applying this Change, the specified component is re-created and added
- * as a facet. If there were to be a facet by the specified name already, it
- * will be replaced.
+ * While applying this Change, the specified component is re-created and added as a facet. If there
+ * were to be a facet by the specified name already, the new facet will not be added.
* @version $Name: $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/change/SetFacetChildComponentChange.java#0 $) $Date: 10-nov-2005.19:10:02 $
*/
public class SetFacetChildComponentChange extends AddComponentChange
@@ -72,8 +73,16 @@ public class SetFacetChildComponentChang
if (facetComponent == null)
return;
-
+
+ // Do not replace a facet if it already exists.
+ if (uiComponent.getFacets().get(_facetName) != null)
+ {
+ _LOG.info("FACET_ALREADY_PRESENT", _facetName);
+ return;
+ }
+
uiComponent.getFacets().put(_facetName, facetComponent);
+
}
private final String _facetName;
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java Wed Jun 16 15:27:21 2010
@@ -35,6 +35,7 @@ import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.webapp.UIComponentELTag;
@@ -86,6 +87,12 @@ abstract public class UIXComponentELTag
// created. End of document tag is a best bet.
if (component instanceof UIXDocument)
{
+ if (getCreated())
+ {
+ ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
+ // Used by SessionChangeManager to confirm that the state was not restored.
+ ec.getRequestMap().put(DOCUMENT_CREATED_KEY, Boolean.TRUE);
+ }
ChangeManager cm = RequestContext.getCurrentInstance().getChangeManager();
cm.applyComponentChangesForCurrentView(FacesContext.getCurrentInstance());
}
@@ -488,6 +495,9 @@ abstract public class UIXComponentELTag
return sdf;
}
+ public static final String DOCUMENT_CREATED_KEY = "org.apache.myfaces.trinidad.DOCUMENTCREATED";
+
private MethodExpression _attributeChangeListener;
private String _validationError;
+
}
Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts?rev=955269&r1=955268&r2=955269&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts Wed Jun 16 15:27:21 2010
@@ -178,7 +178,7 @@
<resource key="INVALID_INDEX">Invalid index</resource>
<!-- ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID -->
- <resource key="ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID">Adding a child when a child with same ID already exists. Old child will be removed and new child added. {0}</resource>
+ <resource key="ATTEMPT_ADD_CHILD_WITH_DUPLICATE_ID">Change manager failed to apply AddChildComponentChange because a child component with the same id already exists. {0}</resource>
<!-- NO_NODE_SPECIFIED -->
<resource key="NO_NODE_SPECIFIED">No node specified</resource>
@@ -225,6 +225,9 @@
<!-- FACET_NAME_MUST_SPECIFIED -->
<resource key="FACET_NAME_MUST_SPECIFIED">Facet name must be specified</resource>
+ <!-- FACET_ALREADY_PRESENT -->
+ <resource key="FACET_ALREADY_PRESENT">Change manager failed to apply SetFacetChildComponentChange because a facet with the same name already exists. {0}</resource>
+
<!-- MOVABLE_CHILD_REQUIRED -->
<resource key="MOVABLE_CHILD_REQUIRED">Child component to be moved is required.</resource>
@@ -243,6 +246,9 @@
<!-- DESTINATION_CONTAINER_NOT_FOUND -->
<resource key="DESTINATION_CONTAINER_NOT_FOUND">Destination container could not be found: {0}.</resource>
+ <!-- MOVABLE_CHILD_SAME_ID_FOUND -->
+ <resource key="MOVABLE_CHILD_SAME_ID_FOUND">A different component with same id was found in the destination container. Move operation aborted: {0}.</resource>
+
<!-- INSERT_BEFORE_NOT_FOUND -->
<resource key="INSERT_BEFORE_NOT_FOUND">Insert before component or node could not be found: {0}.</resource>