001: /* Utils.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Fri Jul 20 19:30:17 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.util.Collection;
022: import java.util.Iterator;
023: import java.util.ArrayList;
024: import java.util.List;
025: import java.io.Writer;
026: import java.io.IOException;
027:
028: import javax.faces.component.UIComponent;
029: import javax.faces.context.FacesContext;
030:
031: import org.zkoss.lang.Objects;
032:
033: import org.zkoss.zk.ui.Page;
034: import org.zkoss.zk.ui.Component;
035:
036: /**
037: * A utility to help Component .
038: *
039: * @author Dennis.Chen
040: */
041: /*package*/class Utils {
042: private static final String MARK_PREFIX = "<zk~f[",
043: MARK_POSTFIX = "]>";
044:
045: /** Adjust the children based the output generated by the inner
046: * components of {@link BranchComponent} (aka., body).
047: *
048: * @param page the page. Specified only if parent is null (aka. root).
049: * @param parent the parent component. If null, page must be specified.
050: */
051: /*package*/static void adjustChildren(Page page,
052: AbstractComponent parent, Collection children, String body) {
053:
054: Iterator it = new ArrayList(children).iterator();
055:
056: //component info for current JSFZUL component tree.
057: ComponentInfo cinfo = parent.getComponentInfo();
058:
059: for (int j = 0, len = body != null ? body.length() : 0; j < len;) {
060: int k = body.indexOf(MARK_PREFIX, j);
061: String txt = null;
062: String cid = null;
063: LeafComponent child = null;
064: if (k >= 0) {
065: int l = k + MARK_PREFIX.length();
066: int m = body.indexOf(MARK_POSTFIX, l);
067: if (m <= l) { //not found or empty uuid
068: k = -1;
069: } else {
070: txt = body.substring(j, k).trim();
071: cid = body.substring(l, m);
072: child = matchNextLeafComponent(it,
073: (AbstractComponent) cinfo
074: .getRegistedComponent(cid));
075: k = m + MARK_POSTFIX.length();
076: }
077: }
078: if (k < 0)
079: txt = body.substring(j).trim();
080: //inline handle...
081: if (txt.length() > 0) {
082: final Inline inl = new Inline(txt);
083: if (child != null) {
084: Component[] zulcomps = null;
085: if (child instanceof BaseUi) {
086: zulcomps = ((BaseUi) child).getComponent();
087: } else {
088: zulcomps = new Component[] { child
089: .getZULComponent() };
090: }
091: boolean ipage = (parent == null || !(parent instanceof BranchComponent));
092: if (ipage) {
093: inl.setPageBefore(page, zulcomps[0]);
094: } else {
095: ((BranchComponent) parent).getZULComponent()
096: .insertBefore(inl, zulcomps[0]);
097: }
098: } else {
099: /*
100: * avoid parent is root
101: */
102: if (parent != null
103: && parent instanceof BranchComponent) {
104: ((BranchComponent) parent).getZULComponent()
105: .appendChild(inl);
106: } else {
107: inl.setPage(page);
108: }
109: }
110: }
111:
112: if (k < 0)
113: break; //no more
114: j = k;
115: }
116: //Should I remove the component which is out of my control? it there exist this one?
117: //while (it.hasNext())
118: // ((Component)it.next()).detach();
119: }
120:
121: /** Matches the next component with the specified child,
122: * returns null if no match at all.
123: * Note: if it.next().getUuid() is not uuid, it will be removed.
124: */
125: private static LeafComponent matchNextLeafComponent(Iterator it,
126: AbstractComponent child) {
127: while (it.hasNext()) {
128: final AbstractComponent nextchild = (AbstractComponent) it
129: .next();
130: if (!(nextchild instanceof LeafComponent)) {
131: //not a LeafComponent, maybe a ZScript or other, so do not adjust it
132: continue;
133: }
134:
135: if (Objects.equals(nextchild, child)) {
136: return (LeafComponent) nextchild; //found
137: }
138: /**
139: * remove components that not in same order,
140: */
141: Component comp = ((LeafComponent) nextchild)
142: .getZULComponent();
143: if (comp != null) {
144: comp.detach(); //remove it
145: }
146:
147: }
148: return null;
149: }
150:
151: /** Writes a special mark to the output to represent the component
152: * of the specified child.
153: * The mark is then used by {@link #adjustChildren}
154: */
155: /*package*/static void writeComponentMark(Writer out,
156: AbstractComponent comp) throws IOException {
157: String uid = comp.getComponentInfo().registerComponent(comp);
158: out.write(MARK_PREFIX);
159: out.write(uid);
160: out.write(MARK_POSTFIX);
161: }
162:
163: /**
164: * A helper for render a component, It's will go thought a component.
165: * @param component the component to render
166: * @param context the FacesContext.
167: * @throws IOException
168: */
169: /*package*/static void renderComponent(UIComponent component,
170: FacesContext context) throws IOException {
171: if (!component.isRendered())
172: return;
173:
174: if (component instanceof AbstractComponent) {
175: if (!((AbstractComponent) component).isEffective()) {
176: return;
177: }
178: }
179:
180: //String id = component.getId();
181: //if (id != null) component.setId(id);
182: component.encodeBegin(context);
183: if (component.getRendersChildren()) {
184: component.encodeChildren(context);
185: } else {
186: UIComponent kid;
187: for (Iterator kids = component.getChildren().iterator(); kids
188: .hasNext(); renderComponent(kid, context))
189: kid = (UIComponent) kids.next();
190:
191: }
192: component.encodeEnd(context);
193: }
194:
195: /**
196: * Debug only method, please doen't use this method
197: */
198: static public void outComponent(Component comp) {
199: outComponent(comp, 0);
200: }
201:
202: /**
203: * Debug only method, please doen't use this method
204: */
205: static public void outComponent(Collection children) {
206: for (Iterator iter = children.iterator(); iter.hasNext();) {
207: Component kid = (Component) iter.next();
208: outComponent(kid, 0);
209: }
210: }
211:
212: static private void outComponent(Component comp, int depth) {
213: if (depth == 0) {
214: System.out.print("R:");
215: }
216: for (int i = 0; i < depth; i++) {
217: System.out.print("++++");
218: }
219: System.out.print(comp.toString());
220: if (comp instanceof Inline) {
221: System.out.println("content of inline[");
222: System.out.println(((Inline) comp).getContent());
223: System.out.println("]end content of inline");
224: }
225: System.out.println();
226:
227: List children = comp.getChildren();
228: for (Iterator iter = children.iterator(); iter.hasNext();) {
229: Component kid = (Component) iter.next();
230: outComponent(kid, depth + 1);
231: }
232: }
233:
234: }
|