001: /* AbstractTextual.java
002:
003: {{IS_NOTE
004:
005: Purpose:
006: Description:
007: History:
008: C2001/10/22 20:48:47, reate, Tom M. Yeh
009: }}IS_NOTE
010:
011: Copyright (C) 2001 Potix Corporation. All Rights Reserved.
012:
013: {{IS_RIGHT
014: This program is distributed under GPL Version 2.0 in the hope that
015: it will be useful, but WITHOUT ANY WARRANTY.
016: }}IS_RIGHT
017: */
018: package org.zkoss.idom.impl;
019:
020: import java.util.List;
021: import org.w3c.dom.CharacterData;
022:
023: import org.zkoss.lang.Objects;
024: import org.zkoss.lang.Classes;
025: import org.zkoss.lang.SystemException;
026: import org.zkoss.idom.*;
027:
028: /**
029: * Represents a textual item.
030: *
031: * <p>Note: any deriving class's getText shall not return null.
032: *
033: * <p>Element.getText uses this class's isPartOfParentText to know
034: * whether a child's text shall be catenated.
035: *
036: * @author tomyeh
037: * @see Element
038: */
039: public abstract class AbstractTextual extends AbstractItem implements
040: Textual, CharacterData {
041: /** The text. */
042: protected String _text;
043:
044: /** Constructor.
045: */
046: protected AbstractTextual(String text) {
047: setText(text);
048: }
049:
050: /** Constructor.
051: */
052: protected AbstractTextual() {
053: _text = "";
054: }
055:
056: //-- Textual --//
057: /**
058: * Returns true if this text object is part of the parent's text.
059: * Default: true.
060: */
061: public boolean isPartOfParentText() {
062: return true;
063: }
064:
065: /**
066: * Returns true if this textual object is allowed to be coalesced with
067: * its siblings with the same type (class).
068: * It is used by Group.coalesce.
069: * <p>Default: false. Right now only Text override it to true.
070: */
071: public boolean isCoalesceable() {
072: return false;
073: }
074:
075: public Textual split(int offset) {
076: String s = getText();
077: if (offset < s.length())
078: return null;
079:
080: Textual vtx;
081: try {
082: vtx = (Textual) Classes.newInstance(getClass(),
083: new Class[] { String.class }, new Object[] { s
084: .substring(offset) });
085: } catch (Exception ex) {
086: throw SystemException.Aide.wrap(ex, getClass()
087: + " must have a String constructor");
088: }
089: setText(s.substring(0, offset));
090:
091: if (getParent() != null) {
092: List list = getParent().getChildren();
093: list.add(list.indexOf(this ) + 1, vtx);
094: }
095: return vtx;
096: }
097:
098: //-- utilities --//
099: /**
100: * Checks whether the text is valid.
101: * It is usually overridden by the deriving classes to check
102: * more specifically.
103: */
104: protected void checkText(String text) {
105: Verifier.checkCharacterData(text, getLocator());
106: }
107:
108: //-- Item --//
109: public String getText() {
110: return _text;
111: }
112:
113: public void setText(String text) {
114: checkWritable();
115:
116: if (text == null)
117: text = "";
118:
119: if (!Objects.equals(_text, text)) {
120: checkText(text);
121: _text = text;
122: setModified();
123: }
124: }
125:
126: //-- CharacterData --//
127: public final int getLength() {
128: return getText().length(); //not use _text since it might be overred
129: }
130:
131: public final String getData() {
132: return getText();
133: }
134:
135: public final void setData(String data) {
136: setText(data);
137: }
138:
139: public final String substringData(int offset, int count) {
140: return getText().substring(offset, offset + count);
141: }
142:
143: public final void appendData(String newData) {
144: if (newData != null && newData.length() != 0)
145: setText(getText() + newData);
146: }
147:
148: public final void insertData(int offset, String arg) {
149: if (arg != null && arg.length() != 0)
150: setText(new StringBuffer(getText()).insert(offset, arg)
151: .toString());
152: }
153:
154: public final void deleteData(int offset, int count) {
155: if (offset < getLength())
156: setText(new StringBuffer(getText()).delete(offset,
157: offset + count).toString());
158: }
159:
160: public final void replaceData(int offset, int count, String arg) {
161: setText(new StringBuffer(getText()).replace(offset,
162: offset + count, arg).toString());
163: }
164:
165: //-- Text if implemented by derived class --//
166: public final org.w3c.dom.Text splitText(int offset) {
167: return (org.w3c.dom.Text) split(offset);
168: }
169:
170: public boolean isElementContentWhitespace() {
171: throw new UnsupportedOperationException("DOM Level 3");
172: }
173:
174: public String getWholeText() {
175: throw new UnsupportedOperationException("DOM Level 3");
176: }
177:
178: public org.w3c.dom.Text replaceWholeText(String content)
179: throws DOMException {
180: throw new UnsupportedOperationException("DOM Level 3");
181: }
182:
183: //Node//
184: public String getTextContent() {
185: return getText();
186: }
187:
188: //-- Object --//
189: /**
190: * Gets the textual representation for debug.
191: */
192: public String toString() {
193: String clsName = getClass().getName();
194: int j = clsName.lastIndexOf('.');
195: if (j >= 0)
196: clsName = clsName.substring(j + 1);
197: return '[' + clsName + ": \"" + getText() + "\"]";
198: }
199: }
|