001: /*
002: * Copyright 2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package javax.faces.component;
017:
018: import java.util.Iterator;
019:
020: import javax.el.ValueExpression;
021: import javax.faces.application.FacesMessage;
022: import javax.faces.context.FacesContext;
023: import javax.faces.el.EvaluationException;
024: import javax.faces.el.MethodBinding;
025: import javax.faces.el.ValueBinding;
026: import javax.faces.validator.Validator;
027: import javax.faces.validator.ValidatorException;
028:
029: /**
030: * A collection of static helper methods for locating UIComponents.
031: *
032: * @author Manfred Geiler (latest modification by $Author: mbr $)
033: * @version $Revision: 518784 $ $Date: 2007-03-15 23:24:40 +0100 (Do, 15 Mrz 2007) $
034: */
035: class _ComponentUtils {
036: private _ComponentUtils() {
037: }
038:
039: static UIComponent findParentNamingContainer(UIComponent component,
040: boolean returnRootIfNotFound) {
041: UIComponent parent = component.getParent();
042: if (returnRootIfNotFound && parent == null) {
043: return component;
044: }
045: while (parent != null) {
046: if (parent instanceof NamingContainer)
047: return parent;
048: if (returnRootIfNotFound) {
049: UIComponent nextParent = parent.getParent();
050: if (nextParent == null) {
051: return parent; //Root
052: }
053: parent = nextParent;
054: } else {
055: parent = parent.getParent();
056: }
057: }
058: return null;
059: }
060:
061: static UIComponent getRootComponent(UIComponent component) {
062: UIComponent parent;
063: for (;;) {
064: parent = component.getParent();
065: if (parent == null)
066: return component;
067: component = parent;
068: }
069: }
070:
071: /**
072: * Find the component with the specified id starting from the specified
073: * component.
074: * <p>
075: * Param id must not contain any NamingContainer.SEPARATOR_CHAR characters
076: * (ie ":"). This method explicitly does <i>not</i> search into any
077: * child naming container components; this is expected to be handled
078: * by the caller of this method.
079: * <p>
080: * For an implementation of findComponent which does descend into
081: * child naming components, see org.apache.myfaces.custom.util.ComponentUtils.
082: *
083: * @return findBase, a descendant of findBase, or null.
084: */
085: static UIComponent findComponent(UIComponent findBase, String id) {
086: if (idsAreEqual(id, findBase)) {
087: return findBase;
088: }
089:
090: for (Iterator it = findBase.getFacetsAndChildren(); it
091: .hasNext();) {
092: UIComponent childOrFacet = (UIComponent) it.next();
093: if (!(childOrFacet instanceof NamingContainer)) {
094: UIComponent find = findComponent(childOrFacet, id);
095: if (find != null)
096: return find;
097: } else if (idsAreEqual(id, childOrFacet)) {
098: return childOrFacet;
099: }
100: }
101:
102: return null;
103: }
104:
105: /*
106: * Return true if the specified component matches the provided id.
107: * This needs some quirks to handle components whose id value gets
108: * dynamically "tweaked", eg a UIData component whose id gets
109: * the current row index appended to it.
110: */
111: private static boolean idsAreEqual(String id, UIComponent cmp) {
112: if (id.equals(cmp.getId()))
113: return true;
114:
115: if (cmp instanceof UIData) {
116: UIData uiData = ((UIData) cmp);
117:
118: if (uiData.getRowIndex() == -1) {
119: return dynamicIdIsEqual(id, cmp.getId());
120: }
121: return id.equals(cmp.getId()
122: + NamingContainer.SEPARATOR_CHAR
123: + uiData.getRowIndex());
124: }
125:
126: return false;
127: }
128:
129: private static boolean dynamicIdIsEqual(String dynamicId, String id) {
130: return dynamicId.matches(id + ":[0-9]*");
131: }
132:
133: static void callValidators(FacesContext context, UIInput input,
134: Object convertedValue) {
135: // first invoke the list of validator components
136: Validator[] validators = input.getValidators();
137: for (int i = 0; i < validators.length; i++) {
138: Validator validator = validators[i];
139: try {
140: validator.validate(context, input, convertedValue);
141: } catch (ValidatorException e) {
142: input.setValid(false);
143:
144: String validatorMessage = input.getValidatorMessage();
145: if (validatorMessage != null) {
146: context
147: .addMessage(
148: input.getClientId(context),
149: new FacesMessage(
150: FacesMessage.SEVERITY_ERROR,
151: validatorMessage,
152: validatorMessage));
153: } else {
154: FacesMessage facesMessage = e.getFacesMessage();
155: if (facesMessage != null) {
156: facesMessage
157: .setSeverity(FacesMessage.SEVERITY_ERROR);
158: context.addMessage(input.getClientId(context),
159: facesMessage);
160: }
161: }
162: }
163: }
164:
165: // now invoke the validator method defined as a method-binding attribute
166: // on the component
167: MethodBinding validatorBinding = input.getValidator();
168: if (validatorBinding != null) {
169: try {
170: validatorBinding.invoke(context, new Object[] {
171: context, input, convertedValue });
172: } catch (EvaluationException e) {
173: input.setValid(false);
174: Throwable cause = e.getCause();
175: if (cause instanceof ValidatorException) {
176: String validatorMessage = input
177: .getValidatorMessage();
178: if (validatorMessage != null) {
179: context.addMessage(input.getClientId(context),
180: new FacesMessage(
181: FacesMessage.SEVERITY_ERROR,
182: validatorMessage,
183: validatorMessage));
184: } else {
185: FacesMessage facesMessage = ((ValidatorException) cause)
186: .getFacesMessage();
187: if (facesMessage != null) {
188: facesMessage
189: .setSeverity(FacesMessage.SEVERITY_ERROR);
190: context
191: .addMessage(input
192: .getClientId(context),
193: facesMessage);
194: }
195: }
196: } else {
197: throw e;
198: }
199: }
200: }
201: }
202:
203: static String getStringValue(FacesContext context, ValueBinding vb) {
204: Object value = vb.getValue(context);
205: if (value == null) {
206: return null;
207: }
208: return value.toString();
209: }
210:
211: static <T> T getExpressionValue(UIComponent component,
212: String attribute, T overrideValue, T defaultValue) {
213: if (overrideValue != null) {
214: return overrideValue;
215: }
216: ValueExpression ve = component.getValueExpression(attribute);
217: if (ve != null) {
218: return (T) ve.getValue(component.getFacesContext()
219: .getELContext());
220: }
221: return defaultValue;
222: }
223: }
|