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 tomyeh
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.jsp.zul.impl;
020:
021: import java.util.Collection;
022: import java.util.Iterator;
023: import java.util.ArrayList;
024: import java.io.Writer;
025: import java.io.IOException;
026:
027: import org.zkoss.lang.Objects;
028:
029: import org.zkoss.zk.ui.Page;
030: import org.zkoss.zk.ui.Component;
031:
032: /**
033: * A utility to be shared by {@link BranchTag} and {@link RootTag} to
034: * implement the capability to hold a list of children.
035: *
036: * @author tomyeh
037: */
038: /*package*/class Utils {
039: private static final String MARK_PREFIX = "<zk~u[",
040: MARK_POSTFIX = "]>";
041:
042: /** Adjust the children based the output generated by the inner
043: * tags of {@link BranchTag} (aka., body).
044: *
045: * @param page the page. Specified ony if parent is null (aka. root).
046: * @param parent the parent component. If null, page must be specified.
047: */
048: /*package*/static void adjustChildren(Page page, Component parent,
049: Collection children, String body) {
050:
051: Iterator it = new ArrayList(children).iterator();
052:
053: for (int j = 0, len = body != null ? body.length() : 0; j < len;) {
054: int k = body.indexOf(MARK_PREFIX, j);
055: String txt = null;
056: Component child = null;
057: if (k >= 0) {
058: int l = k + MARK_PREFIX.length();
059: int m = body.indexOf(MARK_POSTFIX, l);
060: if (m <= l) { //not found or empty uuid
061: k = -1;
062: } else {
063: txt = body.substring(j, k).trim();
064: child = matchNext(it, body.substring(l, m));
065: k = m + MARK_POSTFIX.length();
066: }
067: }
068: if (k < 0)
069: txt = body.substring(j).trim();
070: //inline handle...
071: if (txt.length() > 0) {
072: final Inline inl = new Inline(txt);
073: if (child != null) {
074: if (parent != null)
075: parent.insertBefore(inl, child);
076: else
077: inl.setPageBefore(page, child);
078: } else {
079: if (parent != null)
080: parent.appendChild(inl);
081: else
082: inl.setPage(page);
083: }
084: }
085:
086: if (k < 0)
087: break; //no more
088: j = k;
089: }
090:
091: // while (it.hasNext())
092: // ((Component)it.next()).detach();
093: }
094:
095: /** Matches the next component with the specified uuid,
096: * returns null if no match at all.
097: * Note: if it.next().getUuid() is not uuid, it will be removed.
098: */
099: private static Component matchNext(Iterator it, String uuid) {
100: while (it.hasNext()) {
101: final Component child = (Component) it.next();
102: if (Objects.equals(uuid, child.getUuid()))
103: return child; //found
104: child.detach(); //remove it
105: //Note: it assumes it has the full set and they are
106: //in the same order
107: }
108: return null;
109: }
110:
111: /** Writes a special mark to the output to represent the component
112: * of the specified child.
113: * The mark is then used by {@link #adjustChildren}
114: */
115: /*package*/static void writeComponentMark(Writer out,
116: Component comp) throws IOException {
117: out.write(MARK_PREFIX);
118: out.write(comp.getUuid());
119: out.write(MARK_POSTFIX);
120: }
121:
122: }
|