You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2009/11/11 19:06:31 UTC
svn commit: r834992 - in
/myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad:
component/UIXComponent.java util/ComponentUtils.java
Author: arobinson74
Date: Wed Nov 11 18:06:31 2009
New Revision: 834992
URL: http://svn.apache.org/viewvc?rev=834992&view=rev
Log:
Proposed changes
Modified:
myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
Modified: myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java?rev=834992&r1=834991&r2=834992&view=diff
==============================================================================
--- myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java (original)
+++ myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java Wed Nov 11 18:06:31 2009
@@ -251,7 +251,7 @@
{
ComponentProcessingContext processingContext = new ComponentProcessingContext();
processingContext.__setIsRendering();
-
+
return processFlattenedChildren(context,
processingContext,
childProcessor,
@@ -481,6 +481,57 @@
}
/**
+ * @inheritDoc
+ * <p>In addition to the standard {@link UIComponent#findComponent(String)} functionality,
+ * <c>UIXComponent</c> supports relative ID support in the find component method. This involves
+ * the resolution of Trinidad scoped IDs (IDs that search in parent naming containers using
+ * multiple colons). See the static {@link #findComponent(UIComponent, String)} method for
+ * more information on this syntax.</p>
+ *
+ * @param expr The expression to use to find the component
+ * @return The component if found, otherwise null
+ */
+ @Override
+ public UIComponent findComponent(
+ String expr)
+ {
+ return _findComponentImpl(this, expr);
+ }
+
+ /**
+ * Find a component relative to another.
+ * <p>
+ * The relative ID must account for NamingContainers. If the component is already inside
+ * of a naming container, you can use a single colon to start the search from the root,
+ * or multiple colons to move up through the NamingContainers - "::" will
+ * pop out of the current naming container, ":::" will pop out of two
+ * naming containers, etc.
+ * </p>
+ *
+ * @param from the component to search relative to
+ * @param scopedId the relative id path from the 'from' component to the
+ * component to find
+ * @return the component if found, null otherwise
+ * @see org.apache.myfaces.trinidad.render.RenderUtils#getRelativeId
+ * @see javax.faces.component.UIComponent#findComponent
+ */
+ public static UIComponent findComponent(
+ UIComponent from,
+ String scopedId)
+ {
+ if (from == null)
+ return null;
+
+ if (from instanceof UIXComponent)
+ {
+ // UIXComponent can handle relative IDs in its findComponent method
+ return from.findComponent(scopedId);
+ }
+
+ return _findComponentImpl(from, scopedId);
+ }
+
+ /**
* Add a component as a partial target to the current request. This code handles the
* delegation to {@link #setPartialTarget(FacesContext, PartialPageContext)}
* for UIXComponents or assumes for {@link UIComponent} that components with a renderer
@@ -792,4 +843,59 @@
* @see UIXComponentBase#getClientId(FacesContext context)
*/
abstract public String getContainerClientId(FacesContext context, UIComponent child);
+
+ private static UIComponent _findComponentImpl(
+ UIComponent from,
+ String scopedId)
+ {
+ boolean isRelative = scopedId.startsWith("::", 0);
+
+ if (isRelative)
+ {
+ // if the component is not a NamingContainer, then we need to
+ // get the component's naming container and set this as the 'from'.
+ // this way we'll pop out of the component's
+ // naming container if there is are multiple colons.
+ if (!(from instanceof NamingContainer))
+ {
+ from = _getParentNamingContainerOrViewRoot(from);
+
+ if (from instanceof UIXComponent)
+ {
+ // The parent naming container is a UIXComponent, let it process the resolution
+ // of the find in case it has overridden the default behavior
+ return ((UIXComponent)from).findComponent(scopedId);
+ }
+ }
+
+ // Pop out of the current naming container and get the parent naming container
+ from = _getParentNamingContainerOrViewRoot(from);
+
+ // Strip off both colons if there are only 2 at the start, otherwise strip off one
+ scopedId = (scopedId.length() >= 3 && scopedId.charAt(2) == ':')
+ ? scopedId.substring(1) : scopedId.substring(2);
+
+ // Let the naming container resolve the remainder
+ return UIXComponent.findComponent(from, scopedId);
+ }
+
+ return from.findComponent(scopedId);
+ }
+
+ /**
+ * Given a component, get its naming container. If the component
+ * is a naming container, it will get its naming container.
+ * If no parent naming containers exist, it stops at the ViewRoot.
+ */
+ private static UIComponent _getParentNamingContainerOrViewRoot (
+ UIComponent from)
+ {
+ while (from.getParent() != null)
+ {
+ from = from.getParent();
+ if (from instanceof NamingContainer)
+ break;
+ }
+ return from;
+ }
}
Modified: myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java?rev=834992&r1=834991&r2=834992&view=diff
==============================================================================
--- myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java (original)
+++ myfaces/trinidad/branches/ar_Issue1633/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java Wed Nov 11 18:06:31 2009
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -24,11 +24,12 @@
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
-
import javax.faces.component.UIViewRoot;
+import org.apache.myfaces.trinidad.component.UIXComponent;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
/**
* Utility functions used by the Apache Trinidad components.
* <p>
@@ -45,7 +46,7 @@
* returning a default value if the value is null.
*/
public static Object resolveObject(
- Object value,
+ Object value,
Object defaultValue
)
{
@@ -59,7 +60,7 @@
* Utility method for component code that transforms Object->boolean.
*/
public static boolean resolveBoolean(
- Object value,
+ Object value,
boolean defaultValue
)
{
@@ -204,7 +205,7 @@
? (Number) value
: defaultValue;
}
-
+
/**
* Utility method for component code that transforms Object->String.
@@ -231,7 +232,7 @@
? value.toString()
: defaultValue;
}
-
+
/**
* Utility method for code that transforms Object->String[]
*/
@@ -240,7 +241,7 @@
{
return resolveStringArray(value, null);
}
-
+
/**
* Utility method for code that transforms Object->String[]
*/
@@ -252,15 +253,15 @@
? (String[]) value
: defaultValue;
}
-
+
/**
* Utility method for code that transforms Object->Date
*/
- public static Date resolveDate(Object value)
+ public static Date resolveDate(Object value)
{
return resolveDate(value, null);
}
-
+
/**
* Utility method for code that transforms Object->Date
*/
@@ -271,15 +272,15 @@
return (value != null)
? (Date) value
: defaultValue;
- }
-
+ }
+
public static TimeZone resolveTimeZone(
Object value
)
{
return resolveTimeZone(value, null);
}
-
+
public static TimeZone resolveTimeZone(
Object value,
TimeZone defaultValue
@@ -289,14 +290,14 @@
? (TimeZone) value
: defaultValue;
}
-
+
public static Locale resolveLocale(
Object value
)
{
return resolveLocale(value, null);
}
-
+
public static Locale resolveLocale(
Object value,
Locale defaultValue
@@ -306,7 +307,7 @@
? (Locale) value
: defaultValue;
}
-
+
/**
* Gets the root cause of an exception.
* Keeps unwrapping the given throwable until the root cause is found.
@@ -323,98 +324,33 @@
return t;
}
-
/**
- * Find a component relative to another.
- * <p>
- * The relative ID must account for NamingContainers. If the component is already inside
- * of a naming container, you can use a single colon to start the search from the root,
- * or multiple colons to move up through the NamingContainers - "::" will
- * pop out of the current naming container, ":::" will pop out of two
- * naming containers, etc.
- * </p>
- *
- * @param from the component to search relative to
- * @param scopedId the relative id path from the 'from' component to the
- * component to find
- * @return the component if found, null otherwise
- * @see org.apache.myfaces.trinidad.render.RenderUtils#getRelativeId
- * @see javax.faces.component.UIComponent#findComponent
+ * @deprecated Use {@link UIXComponent#findComponent(UIComponent, String)} instead
*/
+ @Deprecated
public static UIComponent findRelativeComponent(
UIComponent from,
String scopedId)
{
- if (from == null)
- return null;
- UIComponent originalFrom = from;
- String originalRelativeId = scopedId;
-
- int idLength = scopedId.length();
- // Figure out how many colons
- int colonCount = 0;
- while (colonCount < idLength)
- {
- if (scopedId.charAt(colonCount) != NamingContainer.SEPARATOR_CHAR)
- break;
- colonCount++;
- }
-
- // colonCount == 0: fully relative
- // colonCount == 1: absolute (still normal findComponent syntax)
- // colonCount > 1: for each extra colon after 1, pop out of
- // the naming container (to the view root, if naming containers run out)
- if (colonCount > 1)
- {
- scopedId = scopedId.substring(colonCount);
-
- // if the component is not a NamingContainer, then we need to
- // get the component's naming container and set this as the 'from'.
- // this way we'll pop out of the component's
- // naming container if there is are multiple colons.
- if (!(from instanceof NamingContainer))
- {
- from = _getParentNamingContainerOrViewRoot(from);
- }
-
- // pop out of the naming containers if there are multiple colons
- for (int j = 1; j < colonCount; j++)
- {
- from = _getParentNamingContainerOrViewRoot(from);
- }
- }
-
- UIComponent found = from.findComponent(scopedId);
- if (found != null)
- return found;
- else
- {
- // try the old way for backward compatability as far as it differed,
- // which is only if the 'from' was not a NamingContainer.
- if (!(originalFrom instanceof NamingContainer))
- return _findRelativeComponentDeprecated(originalFrom, originalRelativeId);
- else
- return null;
- }
-
+ return UIXComponent.findComponent(from, scopedId);
}
-
+
/**
* Gets the scoped identifier for the target component. The scoping will be
* within a subtree rooted by the supplied base component. If the supplied
- * base component were to be the view root, the returned id will be the
+ * base component were to be the view root, the returned id will be the
* absolute id and hence prefixed with NamingContainer.SEPARATOR_CHARACTER.
- *
- * This algorithm reverse matches that of UIComponent.findComponent().
- * In other words, the scoped id returned by this method can be safely used
+ *
+ * This algorithm reverse matches that of UIComponent.findComponent().
+ * In other words, the scoped id returned by this method can be safely used
* in calls to findComponent() on the baseComponent, if it were to be
* enclosing the targetComponent.
- *
+ *
* This method assumes that the supplied baseComponent definitely encloses the
* targetComponent, return value is not reliable if this is not the case.
- *
+ *
* Examples of id returned: ':foo:bar:baz'/'foo:baz'/'foo'
- *
+ *
* @param targetComponent The component for which the scoped id needs to be
* determined.
* @param baseComponent The component relative to which the scoped id for the
@@ -427,24 +363,24 @@
UIComponent baseComponent)
{
String targetComponentId = targetComponent.getId();
-
- if (targetComponent == null ||
+
+ if (targetComponent == null ||
targetComponentId == null ||
targetComponentId.length() == 0)
return null;
-
+
// Optimize when both arguments are the same
if (targetComponent.equals(baseComponent))
return targetComponentId;
StringBuilder builder = new StringBuilder(100);
-
+
// Add a leading ':' if the baseComponent is the view root
if (baseComponent instanceof UIViewRoot)
builder.append(NamingContainer.SEPARATOR_CHAR);
_buildScopedId(targetComponent, baseComponent, builder);
-
+
return builder.toString();
}
@@ -463,7 +399,7 @@
UIComponent baseComponent,
StringBuilder builder)
{
- UIComponent namingContainer =
+ UIComponent namingContainer =
_getParentNamingContainer(targetComponent, baseComponent);
if (namingContainer != null)
@@ -471,17 +407,17 @@
_buildScopedId(namingContainer, baseComponent, builder);
builder.append(NamingContainer.SEPARATOR_CHAR);
}
-
+
builder.append(targetComponent.getId());
}
/**
* Returns the naming container of the component. This method makes sure that
- * we don't go beyond the a supplied base component.
- * @param component the UIComponent
+ * we don't go beyond the a supplied base component.
+ * @param component the UIComponent
* @param baseComponent The component to limit the search up to.
- * @return the naming container of the component which has to be in the
- * subtree rooted by the baseComponent. Returns null if no such ancestor
+ * @return the naming container of the component which has to be in the
+ * subtree rooted by the baseComponent. Returns null if no such ancestor
* naming container component exists.
*/
private static UIComponent _getParentNamingContainer(
@@ -492,24 +428,24 @@
// in _buildScopedId()
if (component.equals(baseComponent))
return null;
-
+
UIComponent checkedParent = component.getParent();
-
+
while(checkedParent != null)
{
if (checkedParent instanceof NamingContainer)
break;
-
+
// We hit the base component, abort.
if (checkedParent == baseComponent)
return null;
-
+
checkedParent = checkedParent.getParent();
}
-
+
return checkedParent;
}
-
+
// given a component, get its naming container. If the component
// is a naming container, it will get its naming container.
// if no parent naming containers exist, it stops at the ViewRoot.
@@ -532,12 +468,12 @@
* new findRelativeComponent method is backward compatibility.
* <p>
* The relative ID must account for NamingContainers. If the component is already inside
- * of a naming container, you can use a single colon to start the search from the root,
- * or multiple colons to move up through the NamingContainers - "::" will search from
- * the parent naming container, ":::" will search from the grandparent
+ * of a naming container, you can use a single colon to start the search from the root,
+ * or multiple colons to move up through the NamingContainers - "::" will search from
+ * the parent naming container, ":::" will search from the grandparent
* naming container, etc.
* </p>
- *
+ *
* @param from the component to search relative to
* @param relativeId the relative path to the component to find
* @return the component if found, null otherwise
@@ -545,7 +481,7 @@
private static UIComponent _findRelativeComponentDeprecated(
UIComponent from,
String relativeId)
- {
+ {
UIComponent originalFrom = from;
String originalRelativeId = relativeId;
@@ -580,12 +516,12 @@
UIComponent found = from.findComponent(relativeId);
if (found != null)
{
- _LOG.warning("DEPRECATED_RELATIVE_ID_SYNTAX",
+ _LOG.warning("DEPRECATED_RELATIVE_ID_SYNTAX",
new Object[] {originalRelativeId, originalFrom});
}
return found;
}
-
+
static private final TrinidadLogger _LOG =
TrinidadLogger.createTrinidadLogger(ComponentUtils.class);
}