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.HashMap;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022:
023: import javax.el.ELException;
024: import javax.el.ValueExpression;
025: import javax.faces.FacesException;
026: import javax.faces.context.FacesContext;
027: import javax.faces.el.ValueBinding;
028: import javax.faces.event.AbortProcessingException;
029:
030: /**
031: * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
032: *
033: * @author Manfred Geiler (latest modification by $Author: mbr $)
034: * @version $Revision: 518788 $ $Date: 2007-03-15 23:29:10 +0100 (Do, 15 Mrz 2007) $
035: */
036: public abstract class UIComponent implements StateHolder {
037:
038: protected Map<String, ValueExpression> bindings;
039:
040: public UIComponent() {
041: }
042:
043: public abstract java.util.Map<String, Object> getAttributes();
044:
045: /**
046: * @deprecated Replaced by getValueExpression
047: */
048: public abstract javax.faces.el.ValueBinding getValueBinding(
049: java.lang.String name);
050:
051: public ValueExpression getValueExpression(String name) {
052: if (name == null)
053: throw new NullPointerException("name can not be null");
054:
055: if (bindings == null) {
056: if (!(this instanceof UIComponentBase)) {
057: // if the component does not inherit from UIComponentBase and don't implements JSF 1.2 or later
058: ValueBinding vb = getValueBinding(name);
059: if (vb != null) {
060: bindings = new HashMap<String, ValueExpression>();
061: ValueExpression ve = new _ValueBindingToValueExpression(
062: vb);
063: bindings.put(name, ve);
064: return ve;
065: }
066: }
067: } else {
068: return bindings.get(name);
069: }
070:
071: return null;
072: }
073:
074: /**
075: * @deprecated Replaced by setValueExpression
076: */
077: public abstract void setValueBinding(java.lang.String name,
078: javax.faces.el.ValueBinding binding);
079:
080: public void setValueExpression(String name,
081: ValueExpression expression) {
082: if (name == null)
083: throw new NullPointerException("name");
084: if (name.equals("id"))
085: throw new IllegalArgumentException(
086: "Can't set a ValueExpression for the 'id' property.");
087: if (name.equals("parent"))
088: throw new IllegalArgumentException(
089: "Can't set a ValueExpression for the 'parent' property.");
090:
091: if (expression == null) {
092: if (bindings != null) {
093: bindings.remove(name);
094: if (bindings.isEmpty())
095: bindings = null;
096: }
097: } else {
098: if (expression.isLiteralText()) {
099: try {
100: Object value = expression
101: .getValue(getFacesContext().getELContext());
102: getAttributes().put(name, value);
103: return;
104: } catch (ELException e) {
105: throw new FacesException(e);
106: }
107: }
108:
109: if (bindings == null) {
110: bindings = new HashMap<String, ValueExpression>();
111: }
112:
113: bindings.put(name, expression);
114: }
115: }
116:
117: /**
118: * Invokes the <code>invokeContextCallback</code> method with the component, specified by <code>clientId</code>.
119: * @param context <code>FacesContext</code> for the current request
120: * @param clientId the id of the desired <code>UIComponent</code> clazz
121: * @param callback Implementation of the <code>ContextCallback</code> to be called
122: * @return has component been found ?
123: * @throws javax.faces.FacesException
124: */
125: public boolean invokeOnComponent(
126: javax.faces.context.FacesContext context, String clientId,
127: javax.faces.component.ContextCallback callback)
128: throws javax.faces.FacesException {
129: //java.lang.NullPointerException - if any of the arguments are null
130: if (context == null || clientId == null || callback == null) {
131: throw new NullPointerException();
132: }
133:
134: //searching for this component?
135: boolean returnValue = this .getClientId(context)
136: .equals(clientId);
137: if (returnValue) {
138: try {
139: callback.invokeContextCallback(context, this );
140: } catch (Exception e) {
141: throw new FacesException(e);
142: }
143: return returnValue;
144: }
145: //Searching for this component's children/facets
146: for (Iterator<UIComponent> it = this .getFacetsAndChildren(); !returnValue
147: && it.hasNext();) {
148: returnValue = it.next().invokeOnComponent(context,
149: clientId, callback);
150: }
151:
152: return returnValue;
153: }
154:
155: public abstract java.lang.String getClientId(
156: javax.faces.context.FacesContext context);
157:
158: public abstract java.lang.String getFamily();
159:
160: public abstract java.lang.String getId();
161:
162: public abstract void setId(java.lang.String id);
163:
164: /**
165: * Returns the parent of the component.
166: * Children can be added to or removed from a component even if this method returns null
167: * for the child.
168: */
169: public abstract javax.faces.component.UIComponent getParent();
170:
171: /**
172: * For JSF-framework internal use only. Don't call this method to
173: * add components to the component tree.
174: * Use <code>parent.getChildren().add(child)</code> instead.
175: */
176: public abstract void setParent(
177: javax.faces.component.UIComponent parent);
178:
179: public abstract boolean isRendered();
180:
181: public abstract void setRendered(boolean rendered);
182:
183: public abstract java.lang.String getRendererType();
184:
185: public abstract void setRendererType(java.lang.String rendererType);
186:
187: public abstract boolean getRendersChildren();
188:
189: public abstract java.util.List<UIComponent> getChildren();
190:
191: public abstract int getChildCount();
192:
193: public abstract javax.faces.component.UIComponent findComponent(
194: java.lang.String expr);
195:
196: public abstract java.util.Map<String, UIComponent> getFacets();
197:
198: public abstract javax.faces.component.UIComponent getFacet(
199: java.lang.String name);
200:
201: public abstract java.util.Iterator<UIComponent> getFacetsAndChildren();
202:
203: public abstract void broadcast(javax.faces.event.FacesEvent event)
204: throws AbortProcessingException;
205:
206: public abstract void decode(javax.faces.context.FacesContext context);
207:
208: public abstract void encodeBegin(
209: javax.faces.context.FacesContext context)
210: throws java.io.IOException;
211:
212: public abstract void encodeChildren(
213: javax.faces.context.FacesContext context)
214: throws java.io.IOException;
215:
216: public abstract void encodeEnd(
217: javax.faces.context.FacesContext context)
218: throws java.io.IOException;
219:
220: public void encodeAll(javax.faces.context.FacesContext context)
221: throws java.io.IOException {
222: if (context == null) {
223: throw new NullPointerException();
224: }
225:
226: if (isRendered()) {
227: this .encodeBegin(context);
228:
229: //rendering children
230: if (this .getRendersChildren()) {
231: this .encodeChildren(context);
232: }
233: //let children render itself
234: else {
235: List<UIComponent> comps = this .getChildren();
236: for (Iterator<UIComponent> iter = comps.iterator(); iter
237: .hasNext();) {
238: iter.next().encodeAll(context);
239: ;
240: }
241: }
242: this .encodeEnd(context);
243: }
244: }
245:
246: protected abstract void addFacesListener(
247: javax.faces.event.FacesListener listener);
248:
249: protected abstract javax.faces.event.FacesListener[] getFacesListeners(
250: java.lang.Class clazz);
251:
252: protected abstract void removeFacesListener(
253: javax.faces.event.FacesListener listener);
254:
255: public abstract void queueEvent(javax.faces.event.FacesEvent event);
256:
257: public abstract void processRestoreState(
258: javax.faces.context.FacesContext context,
259: java.lang.Object state);
260:
261: public abstract void processDecodes(
262: javax.faces.context.FacesContext context);
263:
264: public abstract void processValidators(
265: javax.faces.context.FacesContext context);
266:
267: public abstract void processUpdates(
268: javax.faces.context.FacesContext context);
269:
270: public abstract java.lang.Object processSaveState(
271: javax.faces.context.FacesContext context);
272:
273: protected abstract javax.faces.context.FacesContext getFacesContext();
274:
275: protected abstract javax.faces.render.Renderer getRenderer(
276: javax.faces.context.FacesContext context);
277:
278: /**
279: * @since 1.2
280: */
281:
282: public int getFacetCount() {
283: // not sure why the RI has this method in both
284: // UIComponent and UIComponentBase
285: Map<String, UIComponent> facets = getFacets();
286: return facets == null ? 0 : facets.size();
287: }
288:
289: /**
290: * @since 1.2
291: */
292:
293: public String getContainerClientId(FacesContext ctx) {
294: if (ctx == null)
295: throw new NullPointerException("FacesContext ctx");
296:
297: return getClientId(ctx);
298: }
299: }
|