com.icesoft.util.CoreComponentUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icefaces-compat Show documentation
Show all versions of icefaces-compat Show documentation
${icefaces.product.name} Compat Component Library
/*
* Copyright 2004-2012 ICEsoft Technologies Canada Corp.
*
* Licensed 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 KIND, either
* express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.icesoft.util;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.component.UINamingContainer;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;
/**
*
*/
public class CoreComponentUtils {
private static final Pattern ClientIdPattern = Pattern.compile("^(([\\w\\_]*)\\" + UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance()) + "([\\w\\_]*))*$");
/**
* Find a component with an id specified in the following ways
*
* -
* :componetId - Absolute id, search starts at UIViewRoot
-
* componentId - Relative id, search starts at nearest parent namingContainer or ViewRoot
-
* :xN componentId - Numbered relative id, search starts at N'th parent naming container or ViewRoot
*
*
* @param clientId id of component
* @param base UIComponent base to start searching from
*/
public static UIComponent findComponent(String clientId, UIComponent base) {
//System.out.println(" findComponent() clientId: " + clientId + " base: " + base);
// Set base, the parent component whose children are searched, to be the
// nearest parent that is either 1) the view root if the id expression
// is absolute (i.e. starts with the delimiter) or 2) the nearest parent
// NamingContainer if the expression is relative (doesn't start with
// the delimiter)
char separatorChar = getSeparatorChar();
String delimeter = String.valueOf(separatorChar);
int count = getNumberOfLeadingNamingContainerSeparators(clientId);
//System.out.println(" count: " + count);
if (count == 1) {
// Absolute searches start at the root of the tree
while (base.getParent() != null) {
base = base.getParent();
}
// Treat remainder of the expression as relative
clientId = clientId.substring(delimeter.length());
} else if (count == 0) {
// Relative expressions start at the closest NamingContainer or root
while (base.getParent() != null) {
if (base instanceof NamingContainer) {
break;
}
base = base.getParent();
}
} else if (count > 1) {
// Relative expressions start at the closest NamingContainer or root
int numNamingContainersUp = count - 1;
//System.out.println(" numNamingContainersUp: " + numNamingContainersUp);
while (base.getParent() != null) {
if (base instanceof NamingContainer) {
numNamingContainersUp--;
//System.out.println(" NamingContainer["+numNamingContainersUp+"]: " + base);
if (numNamingContainersUp == 0)
break;
}
base = base.getParent();
}
clientId = clientId.substring(delimeter.length() * count);
//System.out.println(" clientId: " + clientId);
}
// Evaluate the search expression (now guaranteed to be relative)
String id = null;
UIComponent result = null;
while (clientId.length() > 0) {
int separator = clientId.indexOf(separatorChar);
if (base instanceof UIData) {
if (separator >= 0) {
clientId = clientId.substring(separator + 1);
}
separator = clientId.indexOf(separatorChar);
}
if (separator >= 0) {
id = clientId.substring(0, separator);
clientId = clientId.substring(separator + 1);
} else {
id = clientId;
clientId = "";
}
result = findComponent(base, id);
if ((result == null) || (clientId.length() == 0)) {
break; // Missing intermediate node or this is the last node
}
if (result instanceof NamingContainer) {
result = findComponent(clientId, result);
break;
}
}
return result;
}
private static int getNumberOfLeadingNamingContainerSeparators(String clientId) {
int count = 0;
String delimeter = String.valueOf(getSeparatorChar());
for (int index = 0; clientId.indexOf(delimeter, index) == index; index += delimeter.length())
count++;
return count;
}
private static char getSeparatorChar(){
return UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance());
}
/**
* Find a component with a given id, given a starting component
*
* @param uiComponent
* @param componentId
* @return
*/
private static UIComponent findComponent(UIComponent uiComponent,
String componentId) {
UIComponent component = null;
UIComponent child = null;
if (componentId.equals(uiComponent.getId())) {
return uiComponent;
}
Iterator children = uiComponent.getFacetsAndChildren();
while (children.hasNext() && (component == null)) {
child = (UIComponent) children.next();
if (!(child instanceof NamingContainer)) {
component = findComponent(child, componentId);
if (component != null) {
break;
}
} else if (child.getId() != null && componentId.equals(child.getId())) {
component = child;
break;
}
}
return component;
}
/**
* A version of findComponent() that attempts to locate a component by id (not clientId)
* and searches into NamingContainers. If there are more than one component with the
* provided id, the first one found will be returned
*
* @param uiComponent the base component to search from
* @param componentId the id to search for
*/
public static UIComponent findComponentInView(UIComponent uiComponent,
String componentId) {
UIComponent component = null;
UIComponent child = null;
if (componentId.equals(uiComponent.getId())) {
return uiComponent;
}
Iterator children = uiComponent.getFacetsAndChildren();
while (children.hasNext() && (component == null)) {
child = (UIComponent) children.next();
component = findComponentInView(child, componentId);
if (component != null) {
break;
}
if (child.getId() != null && componentId.endsWith(child.getId())) {
component = child;
break;
}
}
return component;
}
/**
* ICE-4417 Migrate method for setting focus id.
*
* @param focusId Id of component to get the focus
*/
public static void setFocusId(String focusId) {
//ignore call, dead code
}
/**
* Return the id of the Element that currently has focus in the browser.
*
* @return String
*/
public static String getFocusId(FacesContext context) {
ExternalContext externalContext = context.getExternalContext();
Map map = externalContext.getRequestParameterMap();
String focusedElement = (String) map.get("ice.focus");
return focusedElement != null && ClientIdPattern.matcher(focusedElement).matches() ? focusedElement : "";
}
}