You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jw...@apache.org on 2013/08/20 19:00:57 UTC

svn commit: r1515879 - in /myfaces/trinidad/trunk/trinidad-api/src/main: java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts

Author: jwaldman
Date: Tue Aug 20 17:00:57 2013
New Revision: 1515879

URL: http://svn.apache.org/r1515879
Log:
TRINIDAD-2409  improve diagnostics during tag execution component binding failures 
Thanks to Pavitra Subramaniam for the patch

Modified:
    myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java
    myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java?rev=1515879&r1=1515878&r2=1515879&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/UIXComponentELTag.java Tue Aug 20 17:00:57 2013
@@ -44,6 +44,7 @@ import org.apache.myfaces.trinidad.bean.
 import org.apache.myfaces.trinidad.component.UIXComponent;
 import org.apache.myfaces.trinidad.context.RequestContext;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.util.ComponentUtils;
 
 
 /**
@@ -76,6 +77,9 @@ abstract public class UIXComponentELTag 
   @Override
   public int doStartTag() throws JspException
   {
+    FacesContext context = getFacesContext();
+    Map<String, Object> reqMap = context.getExternalContext().getRequestMap();
+    
     Map<Object, Object> facesContextAttributes = getFacesContext().getAttributes();
 
     // Only support skipping the body of a tag when not iterating. This is due to the fact that
@@ -102,7 +106,22 @@ abstract public class UIXComponentELTag 
     }
 
     _skipEndTagSuperCall = false;
-    int retVal = super.doStartTag();
+
+    int retVal;
+    try
+    {
+      retVal = super.doStartTag();
+    }
+    catch (RuntimeException rte)
+    {
+      _logSevereTagProcessingError(context, rte);
+      throw rte;
+    }
+    catch (JspException jspe)
+    {
+      _logSevereTagProcessingError(context, jspe);
+      throw jspe;
+    }
 
     // There could have been some validation error during property setting
     // on the bean, this is the closest opportunity to burst out.
@@ -193,6 +212,7 @@ abstract public class UIXComponentELTag 
   protected UIComponent createComponent(FacesContext context, String newId)
     throws JspException
   {
+    UIComponent component = null;
     if (RequestContext.isInComponentBindingContext(context) && hasBinding())
     {
      // null out component in binding; this forces a new component to be created.
@@ -200,7 +220,13 @@ abstract public class UIXComponentELTag 
      binding.setValue(getELContext(), null);
     }
     
-    return super.createComponent(context, newId);
+    component = super.createComponent(context, newId);
+    // if the component was pulled out of a component binding during createComponent() it is likely 
+    // to be attached to some component in the tree - and thus the (severe) error is justified
+    if (component != null && component.getParent() != null)
+      _logSevereStaleParentError(context, component, component.getParent());
+    
+    return component;
   }
   
   @Override
@@ -602,6 +628,94 @@ abstract public class UIXComponentELTag 
   }
 
   /**
+    * Logs a severe warning when an exception is thrown during component tag processing.
+    * @param methodName name of the method throwing the exception
+    * @param e Throwable
+    */
+   private void _logSevereTagProcessingError(FacesContext context, Throwable e)
+   {
+     UIViewRoot viewRoot = context.getViewRoot();
+     UIComponent component = this.getComponentInstance();
+     String scopedId = _getScopedId(component, viewRoot);
+     String parentScopedId = _getParentScopedId(viewRoot);
+
+     String message = _LOG.getMessage("ERROR_PARSING_COMPONENT_TAG", 
+                                      new Object[] {scopedId, parentScopedId});
+     _LOG.severe(message, e);
+   }
+   
+   private String _getScopedId(UIComponent component, UIViewRoot viewRoot)
+   {
+     if (component == null)
+     {
+       // use tag id if component was not created
+       return this.getId();
+     }
+     else
+     {
+       return ComponentUtils.getScopedIdForComponent(component, viewRoot);
+     }
+   }
+   
+   /**
+    * Logs a severe error when a stale component is detected during create component.
+    * @param context FacesContext
+    * @param child the UIComponent being created
+    * @param pldParent the parent UIComponent 
+    */
+   private void _logSevereStaleParentError(FacesContext context, 
+                                           UIComponent child, 
+                                           UIComponent oldParent)
+   {
+     UIViewRoot viewRoot = context.getViewRoot();
+
+     String scopedId = ComponentUtils.getScopedIdForComponent(child, viewRoot);
+     String oldParentScopedId = ComponentUtils.getScopedIdForComponent(oldParent, viewRoot);
+     String newParentScopedId = _getParentScopedId(viewRoot);
+       
+     String bindingEL = _getBindingExpression();
+     
+     _LOG.severe("ERROR_CREATE_COMPONENT_STALE", 
+                 new Object[] {scopedId, oldParentScopedId, newParentScopedId, bindingEL});
+     
+   }
+   
+   /**
+    * Returns the expression set for the component's binding attribute or null.
+    * @return String
+    */
+   private String _getBindingExpression()
+   {
+     if (_getBinding() != null)
+     {
+       if (_bindingExpression == null)
+         _bindingExpression = _getBinding().getExpressionString();
+       
+       return _bindingExpression;
+     }
+    
+     return null;
+   }
+   
+   /**
+    * Gets the scopedId of the parent component of the current tag's parent. 
+    * @param viewRoot UIViewRoot instance
+    * @return String 
+    */
+   private String _getParentScopedId(UIViewRoot viewRoot)
+   {
+     UIComponentClassicTagBase parentTag = 
+       UIComponentClassicTagBase.getParentUIComponentClassicTagBase(pageContext);
+     if (parentTag != null)
+     {
+       UIComponent parent = parentTag.getComponentInstance();
+       return ComponentUtils.getScopedIdForComponent(parent, viewRoot);
+     }
+
+     return null;
+   }
+   
+  /**
    * Parse a string into a java.util.Date object.  The
    * string must be in ISO 9601 format (yyyy-MM-dd).
    */
@@ -643,6 +757,7 @@ abstract public class UIXComponentELTag 
 
   private MethodExpression _attributeChangeListener;
   private String           _validationError;
+  private String           _bindingExpression;
   private boolean          _skipEndTagSuperCall = false;
   /*
    * <p>The value binding expression (if any) used to wire up this component

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts?rev=1515879&r1=1515878&r2=1515879&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts Tue Aug 20 17:00:57 2013
@@ -548,5 +548,6 @@
 
 <!-- POP_COMPONENT_BINDING_CONTEXT_FAILED -->
 <resource key="POP_COMPONENT_BINDING_CONTEXT_FAILED">Unable to pop out of a component binding context as a corresponding push never occurred.</resource>
-
+<resource key="ERROR_PARSING_COMPONENT_TAG">Error when processing tag for component with id: "{0}". The scoped id of the parent component is "{1}".</resource>
+<resource key="ERROR_CREATE_COMPONENT_STALE">Detected reuse of component instance with scoped id "{0}" as it is already attached to the parent with scoped id "{1}", whereas its expected parent has a scoped id of "{2}". This error could occur when the component instance was retrieved from the component binding. If it helps the expression set on the binding attribute is "{3}".</resource>
 </resources>