org.icefaces.ace.util.ComponentUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icefaces-ace Show documentation
Show all versions of icefaces-ace Show documentation
${icefaces.product.name} ACE Component Library
/*
* Original Code Copyright Prime Technology.
* Subsequent Code Modifications Copyright 2011-2012 ICEsoft Technologies Canada Corp. (c)
*
* 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.
*
* NOTE THIS CODE HAS BEEN MODIFIED FROM ORIGINAL FORM
*
* Subsequent Code Modifications have been made and contributed by ICEsoft Technologies Canada Corp. (c).
*
* Code Modification 1: Integrated with ICEfaces Advanced Component Environment.
* Contributors: ICEsoft Technologies Canada Corp. (c)
*
* Code Modification 2: [ADD BRIEF DESCRIPTION HERE]
* Contributors: ______________________
* Contributors: ______________________
*/
package org.icefaces.ace.util;
import org.icefaces.ace.renderkit.CoreRenderer;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.ProjectStage;
import javax.faces.component.*;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.faces.render.Renderer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ComponentUtils {
private final static Logger logger = Logger.getLogger(ComponentUtils.class.getName());
/**
* Algorithm works as follows;
* - If it's an input component, submitted value is checked first since it'd be the value to be used in case validation errors
* terminates jsf lifecycle
* - Finally the value of the component is retrieved from backing bean and if there's a converter, converted value is returned
*
* - If the component is not a value holder, toString of component is used to support Facelets UIInstructions.
*
* @param facesContext FacesContext instance
* @param component UIComponent instance whose value will be returned
* @return End text
*/
public static String getStringValueToRender(FacesContext facesContext, UIComponent component) {
if (component instanceof ValueHolder) {
if (component instanceof EditableValueHolder) {
Object submittedValue = ((EditableValueHolder) component).getSubmittedValue();
if (submittedValue != null) {
return submittedValue.toString();
}
}
ValueHolder valueHolder = (ValueHolder) component;
Object value = valueHolder.getValue();
if (value == null)
return "";
//first ask the converter
if (valueHolder.getConverter() != null) {
return valueHolder.getConverter().getAsString(facesContext, component, value);
}
//Try to guess
else {
ValueExpression expr = component.getValueExpression("value");
if (expr != null) {
Class> valueType = expr.getType(facesContext.getELContext());
if (valueType != null) {
Converter converterForType = facesContext.getApplication().createConverter(valueType);
if (converterForType != null)
return converterForType.getAsString(facesContext, component, value);
}
}
}
//No converter found just return the value as string
return value.toString();
} else {
//This would get the plain texts on UIInstructions when using Facelets
String value = component.toString();
if (value != null)
return value.trim();
else
return "";
}
}
/**
* Attempts to return the property accessed in a simple EL expression of the form
* ${someObject.property}.
*
* @param expression An EL expression to parse the property from.
* @return The property name of the EL expression.
*/
public static String resolveField(ValueExpression expression) {
String expressionString = expression.getExpressionString();
return expressionString.substring(expressionString.indexOf(".") + 1, expressionString.length() - 1);
}
/**
* Resolves the end text to render by using a specified value
*
* @param facesContext FacesContext instance
* @param component UIComponent instance whose value will be returned
* @return End text
*/
public static String getStringValueToRender(FacesContext facesContext, UIComponent component, Object value) {
if (value == null) return null;
ValueHolder valueHolder = (ValueHolder) component;
Converter converter = valueHolder.getConverter();
if (converter != null) {
return converter.getAsString(facesContext, component, value);
} else {
ValueExpression expr = component.getValueExpression("value");
if (expr != null) {
Class> valueType = expr.getType(facesContext.getELContext());
Converter converterForType = facesContext.getApplication().createConverter(valueType);
if (converterForType != null)
return converterForType.getAsString(facesContext, component, value);
}
}
return value.toString();
}
public static UIComponent findParentForm(FacesContext context, UIComponent component) {
UIComponent parent = component;
while (parent != null)
if (parent instanceof UIForm) break;
else parent = parent.getParent();
return parent;
}
public static void decorateAttribute(UIComponent component, String attribute, String value) {
String attributeValue = (String) component.getAttributes().get(attribute);
if (attributeValue != null) {
if (attributeValue.indexOf(value) == -1) {
String decoratedValue = attributeValue + ";" + value;
component.getAttributes().put(attribute, decoratedValue);
} else {
component.getAttributes().put(attribute, attributeValue);
}
} else {
component.getAttributes().put(attribute, value);
}
}
public static List createSelectItems(UIComponent component) {
List items = new ArrayList();
Iterator children = component.getChildren().iterator();
while (children.hasNext()) {
UIComponent child = children.next();
if (child instanceof UISelectItem) {
UISelectItem selectItem = (UISelectItem) child;
items.add(new SelectItem(selectItem.getItemValue(), selectItem.getItemLabel()));
} else if (child instanceof UISelectItems) {
Object selectItems = ((UISelectItems) child).getValue();
if (selectItems instanceof SelectItem[]) {
SelectItem[] itemsArray = (SelectItem[]) selectItems;
for (SelectItem item : itemsArray)
items.add(new SelectItem(item.getValue(), item.getLabel()));
} else if (selectItems instanceof Collection) {
Collection collection = (Collection) selectItems;
for (SelectItem item : collection)
items.add(new SelectItem(item.getValue(), item.getLabel()));
}
}
}
return items;
}
public static String escapeJQueryId(String id) {
return "#" + id.replaceAll(":", "\\\\\\\\:");
}
public static String findClientIds(FacesContext context, UIComponent component, String list) {
if (list == null) return "@none";
//System.out.println("ComponentUtils.findClientIds() component.clientId: " + component.getClientId(context) + " list: " + list);
String[] ids = list.split("[,\\s]+");
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < ids.length; i++) {
if (i != 0) buffer.append(" ");
String id = ids[i].trim();
//System.out.println("ComponentUtils.findClientIds() ["+i+"] id: " + id);
if (id.equals("@all") || id.equals("@none")) {
//System.out.println("ComponentUtils.findClientIds() ["+i+"] " + id);
buffer.append(id);
}
else if (id.equals("@this")) {
//System.out.println("ComponentUtils.findClientIds() ["+i+"] @this : " + component.getClientId(context));
buffer.append(component.getClientId(context));
}
else if (id.equals("@parent")) {
//System.out.println("ComponentUtils.findClientIds() ["+i+"] @parent: " + component.getParent().getClientId(context));
buffer.append(component.getParent().getClientId(context));
}
else if (id.equals("@form")) {
UIComponent form = ComponentUtils.findParentForm(context, component);
if (form == null)
throw new FacesException("Component " + component.getClientId(context) + " needs to be enclosed in a form");
buffer.append(form.getClientId(context));
}
else {
UIComponent comp = component.findComponent(id);
//For portlets, if the standard search doesn't work, it may be necessary to do an absolute search
//which requires including the portlet's namespace. So the resulting encoded id looks something
//like portletNamespace:container:componentId. We make the search absolute by pre-pending
//a leading colon (:).
if(comp == null){
String encodedId = encodeNameSpace(context,id);
if( !encodedId.startsWith(":")){
encodedId = ":" + encodedId;
}
comp = component.findComponent(encodedId);
// System.out.println("ComponentUtils.findClientIds() ["+i+"] comp : " + (comp == null ? "null" : comp.getClientId(context)) + " id: " + encodedId);
}
if (comp != null) {
buffer.append(comp.getClientId(context));
}
else {
if (context.getApplication().getProjectStage().equals(ProjectStage.Development)) {
logger.log(Level.INFO, "Cannot find component with identifier \"{0}\" in view.", id);
}
buffer.append(id);
}
}
}
return buffer.toString();
}
/**
* Environments like portlets need to namespace the components in order to uniquely identify them
* on the page in case there are multiple instances of the same portlet or different portlets that use
* the same ids. This method will prepend the namespace properly taking care to ensure that the
* namespace is not added twice and that a colon (:) is added if necessary.
*
* @param fc The current FacesContext instance
* @param id The id to encode
* @return The namespace encoded id
*/
public static String encodeNameSpace(FacesContext fc, String id){
if( id == null || id.trim().length() == 0){
return id;
}
String tempId = id;
ExternalContext ec = fc.getExternalContext();
String encodedId = ec.encodeNamespace(tempId);
//If no namespace was applied, we're done.
if( encodedId.equals(id)){
return id;
}
//Extract the actual namespace.
int idStart = encodedId.indexOf(id);
String ns = encodedId.substring(0,idStart);
//Check if the id already had the namespace. If so, we're done.
if( id.startsWith(ns) ){
return id;
}
//If necessary, add the separator character before including the namespace.
String sep = String.valueOf(UINamingContainer.getSeparatorChar(fc));
if( !id.startsWith(sep)){
id = ":" + id;
}
//Add the namespace.
id = ns + id;
return id;
}
public static String findComponentClientId(String id) {
UIComponent component = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
component = findComponent(facesContext.getViewRoot(), id);
return component.getClientId(facesContext);
}
public static UIComponent findComponent(UIComponent base, String id) {
if (id.equals(base.getId()))
return base;
UIComponent kid = null;
UIComponent result = null;
Iterator kids = base.getFacetsAndChildren();
while (kids.hasNext() && (result == null)) {
kid = (UIComponent) kids.next();
if (id.equals(kid.getId())) {
result = kid;
break;
}
result = findComponent(kid, id);
if (result != null) {
break;
}
}
return result;
}
public static String getWidgetVar(String id) {
UIComponent component = findComponent(FacesContext.getCurrentInstance().getViewRoot(), id);
Renderer renderer = FacesContext.getCurrentInstance().getRenderKit()
.getRenderer(component.getFamily(), component.getRendererType());
if (component == null) throw new FacesException("Cannot find component " + id + " in view.");
else if (!(renderer instanceof CoreRenderer))
throw new FacesException("Component with id " + id + " is not derived from CoreRenderer.");
return ((CoreRenderer) renderer).resolveWidgetVar(component);
}
public static boolean isLiteralText(UIComponent component) {
return component.getFamily().equalsIgnoreCase("facelets.LiteralText");
}
}