You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2012/12/10 12:50:29 UTC
svn commit: r1419357 -
/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java
Author: werpu
Date: Mon Dec 10 11:50:28 2012
New Revision: 1419357
URL: http://svn.apache.org/viewvc?rev=1419357&view=rev
Log:
https://issues.apache.org/jira/browse/TOMAHAWK-1607
Modified:
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java
Modified: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java?rev=1419357&r1=1419356&r2=1419357&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java (original)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/custom/focus/AbstractHtmlFocus.java Mon Dec 10 11:50:28 2012
@@ -18,20 +18,23 @@
*/
package org.apache.myfaces.custom.focus;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIInput;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.component.html.ext.UIComponentPerspective;
+import org.apache.myfaces.component.html.util.HtmlComponentUtils;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIData;
+import javax.faces.component.UIInput;
+import java.util.Iterator;
/**
- * @JSFComponent
- * name = "s:focus"
- * class = "org.apache.myfaces.custom.focus.HtmlFocus"
- * tagClass = "org.apache.myfaces.custom.focus.HtmlFocusTag"
- *
* @author Rogerio Pereira Araujo (latest modification by $Author$)
* @version $Revision$ $Date$
+ * @JSFComponent name = "s:focus"
+ * class = "org.apache.myfaces.custom.focus.HtmlFocus"
+ * tagClass = "org.apache.myfaces.custom.focus.HtmlFocusTag"
*/
public abstract class AbstractHtmlFocus extends UIInput
{
@@ -45,19 +48,18 @@ public abstract class AbstractHtmlFocus
/**
* The JSF id of the component to receive focus.
- *
+ *
* @JSFProperty
*/
public abstract String getFor();
/**
- * @JSFProperty
- * defaultValue="false"
+ * @JSFProperty defaultValue="false"
*/
public abstract boolean isRememberClientFocus();
- protected UIComponent findUIComponent()
+ /*protected UIComponent findUIComponent()
{
String forStr = getFor();
@@ -73,6 +75,209 @@ public abstract class AbstractHtmlFocus
+ forStr + "'");
}
return forComp;
+ }*/
+
+ /**
+ * Standard method for finding other components by id, inherited by
+ * most UIComponent objects.
+ * <p/>
+ * The lookup is performed in a manner similar to finding a file
+ * in a filesystem; there is a "base" at which to start, and the
+ * id can be for something in the "local directory", or can include
+ * a relative path. Here, NamingContainer components fill the role
+ * of directories, and ":" is the "path separator". Note, however,
+ * that although components have a strict parent/child hierarchy,
+ * component ids are only prefixed ("namespaced") with the id of
+ * their parent when the parent is a NamingContainer.
+ * <p/>
+ * The base node at which the search starts is determined as
+ * follows:
+ * <ul>
+ * <li>When expr starts with ':', the search starts with the root
+ * component of the tree that this component is in (ie the ancestor
+ * whose parent is null).
+ * <li>Otherwise, if this component is a NamingContainer then the search
+ * starts with this component.
+ * <li>Otherwise, the search starts from the nearest ancestor
+ * NamingContainer (or the root component if there is no NamingContainer
+ * ancestor).
+ * </ul>
+ *
+ * @param expr is of form "id1:id2:id3".
+ * @return UIComponent or null if no component with the specified id is
+ * found.
+ */
+ //https://issues.apache.org/jira/browse/TOMAHAWK-1607
+ UIComponent getRootComponent(UIComponent component)
+ {
+ UIComponent parent;
+ for (;;)
+ {
+ parent = component.getParent();
+ if (parent == null)
+ {
+ return component;
+ }
+ component = parent;
+ }
+ }
+
+ public UIComponent findComponentWithRowSupport(String expr)
+ {
+ if (expr == null) throw new NullPointerException("expr");
+ if (expr.length() == 0) throw new IllegalArgumentException("empty expr"); //TODO: not specified!
+
+ UIComponent findBase;
+ if (expr.charAt(0) == NamingContainer.SEPARATOR_CHAR)
+ {
+ findBase = getRootComponent(this);
+ expr = expr.substring(1);
+ } else
+ {
+ if (this instanceof NamingContainer)
+ {
+ findBase = this;
+ } else
+ {
+ findBase = HtmlComponentUtils.findParentNamingContainer(this, true /* root if not found */);
+ }
+ }
+
+ return findComponentWithRowSupportFromBase(findBase, expr);
+ }
+
+ public UIComponent findComponentWithRowSupportFromBase(UIComponent base, String expr)
+ {
+ if (expr == null) throw new NullPointerException("expr");
+ if (expr.length() == 0) throw new IllegalArgumentException("empty expr"); //TODO: not specified!
+
+ // Remember current row index
+ int originalRowIndex = -2;
+ UIData uiData = null;
+ if (base instanceof UIData)
+ {
+ uiData = (UIData) base;
+ originalRowIndex = uiData.getRowIndex();
+ }
+
+ UIComponent foundComponent;
+ int separator = expr.indexOf(NamingContainer.SEPARATOR_CHAR);
+ if (separator == -1)
+ {
+ foundComponent = findComponentWithRowSupport(base, expr);
+ } else
+ {
+ String id = expr.substring(0, separator);
+ base = findComponentWithRowSupport(base, id);
+ if (base == null)
+ {
+ foundComponent = null;
+ } else
+ {
+ if (!(base instanceof NamingContainer))
+ throw new IllegalArgumentException("Intermediate identifier " + id + " in search expression " +
+ expr + " identifies a UIComponent that is not a NamingContainer");
+ foundComponent = findComponentWithRowSupportFromBase(base, expr.substring(separator + 1));
+ }
+ }
+
+ // Reset row index
+ if (null != uiData)
+ {
+ if (foundComponent != uiData)
+ {
+
+ UIComponentPerspective cp = new UIComponentPerspective(uiData, foundComponent, uiData.getRowIndex());
+ foundComponent = cp;
+
+ // If the foundComponent is the uiData with a particular rowIndex, I guess we're going to need to leave it alone.
+ uiData.setRowIndex(originalRowIndex);
+ }
+ }
+
+ return foundComponent;
+ }
+
+ UIComponent findComponentWithRowSupport(UIComponent findBase, String id)
+ {
+ if ((findBase instanceof UIData) && (id.matches("[0-9]*")))
+ {
+ UIData uiData = (UIData) findBase;
+ int rowIndex = Integer.parseInt(id);
+ uiData.setRowIndex(rowIndex);
+ return uiData;
+ }
+
+ if (idsAreEqual(id, findBase))
+ {
+ return findBase;
+ }
+
+ for (Iterator it = findBase.getFacetsAndChildren(); it.hasNext(); )
+ {
+ UIComponent childOrFacet = (UIComponent) it.next();
+ if (!(childOrFacet instanceof NamingContainer))
+ {
+ UIComponent find = findComponentWithRowSupportFromBase(childOrFacet, id);
+ if (find != null) return find;
+ } else if (idsAreEqual(id, childOrFacet))
+ {
+ return childOrFacet;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * Return true if the specified component matches the provided id.
+ * This needs some quirks to handle components whose id value gets
+ * dynamically "tweaked", eg a UIData component whose id gets
+ * the current row index appended to it.
+ */
+ private static boolean idsAreEqual(String id, UIComponent cmp)
+ {
+ if (id.equals(cmp.getId()))
+ return true;
+
+ if (cmp instanceof UIData)
+ {
+ UIData uiData = ((UIData) cmp);
+
+ if (uiData.getRowIndex() == -1)
+ {
+ return dynamicIdIsEqual(id, cmp.getId());
+ } else
+ {
+ return id.equals(cmp.getId() + NamingContainer.SEPARATOR_CHAR + uiData.getRowIndex());
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean dynamicIdIsEqual(String dynamicId, String id)
+ {
+ return dynamicId.matches(id + ":[0-9]*");
+ }
+
+ protected UIComponent findUIComponent()
+ {
+ String forStr = getFor();
+
+ if (forStr == null)
+ {
+ throw new IllegalArgumentException("focus@for must be specified");
+ }
+
+ UIComponent forComp = findComponentWithRowSupport(forStr);
+
+ if (forComp == null)
+ {
+ log.warn("could not find UIComponent referenced by attribute focus@for = '"
+ + forStr + "'");
+ }
+ return forComp;
}
}