001: /* AbstractComponent.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Aug 7, 2007 5:53:41 PM 2007, Created by Dennis.Chen
010: }}IS_NOTE
011:
012: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.jsf.zul.impl;
020:
021: import java.io.IOException;
022: import java.io.StringWriter;
023: import java.util.Iterator;
024: import java.util.LinkedHashMap;
025: import java.util.LinkedList;
026: import java.util.List;
027: import java.util.Map;
028:
029: import javax.faces.component.UIComponent;
030: import javax.faces.component.UIComponentBase;
031: import javax.faces.context.FacesContext;
032:
033: /**
034: * The skeletal class for implementing the generic ZULJSF Component.
035: * This component handle _if, _unless attributes of ZUL Component.
036: * This component also handle bodyContent which is set by {@link org.zkoss.jsf.zul.tag.impl.AbstractTag#doAfterBody()}
037: *
038: * @author Dennis.Chen
039: */
040: public class AbstractComponent extends UIComponentBase {
041:
042: private boolean _if = true;
043:
044: private boolean _unless = false;
045:
046: private boolean _suppressed = false;
047:
048: private String _bodyContent;
049:
050: /**
051: * Returns whether this component is effective. If false, this component does
052: * nothing (as if not specified at all).
053: */
054: public boolean isEffective() {
055: return _if && !_unless;
056: }
057:
058: /**
059: * Returns the if condition. If the if condition is false, this component is
060: * ignored. If the unless condition ({@link #getUnless}) is true, this
061: * component is ignored, too. Components deriving from this class shall
062: * invoke {@link #isEffective} to know the result.
063: *
064: * <p>
065: * Default: true.
066: */
067: public boolean getIf() {
068: return _if;
069: }
070:
071: /**
072: * Sets the if condition.
073: */
074: public void setIf(boolean ifcond) {
075: _if = ifcond;
076: }
077:
078: /**
079: * Returns the unless condition. If the unless condition is true, this
080: * component is ignored. If the if condition ({@link #getIf}) is true,
081: * this component is ignored, too. Components deriving from this class shall
082: * invoke {@link #isEffective} to know the result.
083: *
084: * <p>
085: * Default: false.
086: */
087: public boolean getUnless() {
088: return _unless;
089: }
090:
091: /**
092: * Sets the unless condition.
093: */
094: public void setUnless(boolean unless) {
095: _unless = unless;
096: }
097:
098: /**
099: * get Component Family of ZULJSF Component.
100: */
101: public String getFamily() {
102: return "org.zkoss.zul";
103: }
104:
105: /**
106: * A convenient method for finding ancestor of special class.
107: * this method is use to build ZULJSF component tree under JSF component tree.
108: *
109: * @param component
110: * a component, usually a AbstractComponent instance
111: * @param clazz
112: * a class, usually a AbstractComponent class
113: * @return a ancestor Component
114: */
115: protected UIComponent findAncestorWithClass(UIComponent component,
116: Class clazz) {
117: UIComponent parent = component.getParent();
118: if (parent != null) {
119: if (clazz.isAssignableFrom(parent.getClass()))
120: return parent;
121: return findAncestorWithClass(parent, clazz);
122: }
123: return null;
124: }
125:
126: /**
127: * Call by RootComponent or BranchComponent to load tree structure of zk zul components.
128: * This method is invoked from a RootComponent's encodeEnd() or a BranchComponent's loadZK().
129: * It will go through all ZULJSF Component Tree to initial ZUL Component of corresponding ZULJSFComponent.
130: * <br/>Note: Do nothing in default implementation.
131: */
132: protected void loadZULTree(org.zkoss.zk.ui.Page page,
133: StringWriter writer) throws IOException {
134: // do nothing
135:
136: }
137:
138: /**
139: * Set BodyContnet, this method is called by {@link org.zkoss.jsf.zul.tag.impl.AbstractTag} to setup JSP Body
140: * Content, developer rarely call this method.
141: * @param content content of this component
142: */
143: public void setBodyContent(String content) {
144: _bodyContent = content;
145: }
146:
147: /**
148: * get the body content of this ZULJSF Component.
149: * @return the body content of JSP
150: */
151: protected String getBodyContent() {
152: return _bodyContent;
153: }
154:
155: /**
156: * get current FacesContext for this component, this method is protected in
157: * super class, I public it for convenient usage.
158: */
159: public FacesContext getFacesContext() {
160: return super .getFacesContext();
161: }
162:
163: /**
164: * Get ComponentInfo for current Component Tree.<br/> In LeafComponent,
165: * it always return RootComponent's getComponentInfo(), if RootComponent doesn't exist return null;<br/>
166: * In RootComponet , it check a existed instance and return it, if not, a new instance will be created and return.</br>
167: * Note : return null in default implementation.
168: * @return a ComponentInfo of current Component Tree
169: */
170: protected ComponentInfo getComponentInfo() {
171: return null;
172: }
173:
174: // ----------------------------------------------------- StateHolder Methods
175:
176: /**
177: * Override Method, save the state of this component.
178: */
179: public Object saveState(FacesContext context) {
180: Object values[] = new Object[4];
181: values[0] = super .saveState(context);
182: values[1] = _if ? Boolean.TRUE : Boolean.FALSE;
183: values[2] = _unless ? Boolean.TRUE : Boolean.FALSE;
184: values[3] = _suppressed ? Boolean.TRUE : Boolean.FALSE;
185: return (values);
186: }
187:
188: /**
189: * Override Method, restore the state of this component.
190: */
191: public void restoreState(FacesContext context, Object state) {
192:
193: Object values[] = (Object[]) state;
194: super .restoreState(context, values[0]);
195: _if = ((Boolean) values[1]).booleanValue();
196: _unless = ((Boolean) values[2]).booleanValue();
197: _suppressed = ((Boolean) values[3]).booleanValue();
198: }
199:
200: /**
201: * a convenient to save the state of a Map.
202: * @param context FacesContext
203: * @param mapObject a Map to save
204: * @return two handled Object, Object[0] handle the state of keys of Map, Object[1] handle the state of values of Map.
205: */
206: protected static Object[] saveAttachedMapState(
207: FacesContext context, Map mapObject) {
208: if (null == context) {
209: throw new NullPointerException();
210: }
211: if (null == mapObject) {
212: return null;
213: }
214: Object[] result = new Object[2];
215: List keyList = new LinkedList();
216: List valueList = new LinkedList();
217:
218: for (Iterator itor = mapObject.entrySet().iterator(); itor
219: .hasNext();) {
220: Map.Entry entry = (Map.Entry) itor.next();
221: keyList.add(entry.getKey());
222: valueList.add(entry.getValue());
223: }
224: result[0] = saveAttachedState(context, keyList);
225: result[1] = saveAttachedState(context, valueList);
226: return result;
227: }
228:
229: /**
230: * a convenient to restore the state of a Map.
231: * @param context FacesContext
232: * @param keys a Object which is create by {@link #saveAttachedMapState}[0]
233: * @param values a Object which is create by {@link #saveAttachedMapState}[1]
234: * @return restored Map instance
235: */
236: protected static Map restoreAttachedMapState(FacesContext context,
237: Object keys, Object values) {
238: if (null == context) {
239: throw new NullPointerException();
240: }
241: if (null == keys || null == values) {
242: return null;
243: }
244: List keyList = (List) restoreAttachedState(context, keys);
245: List valueList = (List) restoreAttachedState(context, values);
246:
247: Map result = new LinkedHashMap(keyList.size());
248: int size = keyList.size();
249: for (int i = 0; i < size; i++) {
250: result.put(keyList.get(i), valueList.get(i));
251: }
252: return result;
253: }
254:
255: /**
256: * <p>Return <code>true</code> if rendering should be suppressed because
257: * of any of the follow reasons.</p>
258: * <ul>
259: * <li>The component is a facet (whose rendering, if any), is always
260: * the responsibility of the owing component.</li>
261: * <li>The component has its <code>rendered</code> property set
262: * to <code>false</code>.</li>
263: * <li>The component is a child of a parent whose
264: * <code>rendersChildren</code> is <code>true</code>.</li>
265: * <li>The component is a child of a parent whose rendering is itself
266: * suppressed.</li>
267: * </ul>
268: */
269: protected boolean isSuppressed() {
270: return _suppressed;
271: }
272:
273: /**
274: * set suppressed by {@link org.zkoss.jsf.zul.tag.impl.AbstractTag} only, developer should not call this method.
275: * @param suppressed
276: */
277: public void setSuppressed(boolean suppressed) {
278: this._suppressed = suppressed;
279: }
280:
281: }
|