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>