001: /* Copyright 2002-2005 Elliotte Rusty Harold
002:
003: This library is free software; you can redistribute it and/or modify
004: it under the terms of version 2.1 of the GNU Lesser General Public
005: License as published by the Free Software Foundation.
006:
007: This library is distributed in the hope that it will be useful,
008: but WITHOUT ANY WARRANTY; without even the implied warranty of
009: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: GNU Lesser General Public License for more details.
011:
012: You should have received a copy of the GNU Lesser General Public
013: License along with this library; if not, write to the
014: Free Software Foundation, Inc., 59 Temple Place, Suite 330,
015: Boston, MA 02111-1307 USA
016:
017: You can contact Elliotte Rusty Harold by sending e-mail to
018: elharo@metalab.unc.edu. Please include the word "XOM" in the
019: subject line. The XOM home page is located at http://www.xom.nu/
020: */
021:
022: package nu.xom;
023:
024: /**
025: * <p>
026: * This class represents an XML comment such as
027: * <code><-- This is a comment--></code>.
028: * A comment node cannot have any child nodes.
029: * It can be a child of an <code>Element</code>
030: * or a <code>Document</code>.
031: * It has essentially no internal substructure.
032: * </p>
033: *
034: * @author Elliotte Rusty Harold
035: * @version 1.0
036: *
037: */
038: public class Comment extends Node {
039:
040: private String data;
041:
042: /**
043: * <p>
044: * Creates a new <code>Comment</code> object from string data.
045: * The data is checked for legality according to XML 1.0 rules.
046: * Illegal characters such as the form feed and null are not
047: * allowed. Furthermore, the two hyphen string "--" is not allowed;
048: * and the last character of the comment may not be a hyphen.
049: * </p>
050: *
051: * @param data the initial text of the comment
052: */
053: public Comment(String data) {
054: _setValue(data);
055: }
056:
057: /**
058: * <p>
059: * Creates a new comment that's a copy of its argument.
060: * The copy has the same data but no parent node.
061: * </p>
062: *
063: * @param comment the comment to copy
064: */
065: public Comment(Comment comment) {
066: this .data = comment.data;
067: }
068:
069: private Comment() {
070: }
071:
072: static Comment build(String data) {
073: Comment result = new Comment();
074: result.data = data;
075: return result;
076: }
077:
078: /**
079: * <p>
080: * Returns the value of this comment as defined by XPath 1.0.
081: * The XPath string-value of a comment node is the string
082: * content of the node, not including the initial
083: * <code><--</code> and closing <code>--></code>.
084: * </p>
085: *
086: * @return the content of the comment
087: */
088: public final String getValue() {
089: return data;
090: }
091:
092: /**
093: * <p>
094: * Sets the content of this <code>Comment</code> object
095: * to the specified string.
096: * This string is checked for legality according to XML 1.0 rules.
097: * Characters that can be serialized such as < and &
098: * are allowed. However, illegal characters such as the form feed
099: * and unmatched halves of surrogate pairs are not allowed.
100: * Furthermore, the string may not contain a double hyphen
101: * (<code>--</code>) and may not end with a hyphen.
102: * </p>
103: *
104: * @param data the text to install in the comment
105: */
106: public void setValue(String data) {
107: _setValue(data);
108: }
109:
110: private void _setValue(String data) {
111:
112: if (data == null)
113: data = "";
114: else {
115: Verifier.checkPCDATA(data);
116:
117: if (data.indexOf("--") != -1) {
118: IllegalDataException ex = new IllegalDataException(
119: "Comment data contains a double hyphen (--).");
120: ex.setData(data);
121: throw ex;
122: }
123:
124: if (data.indexOf('\r') != -1) {
125: IllegalDataException ex = new IllegalDataException(
126: "Comment data cannot contain carriage returns.");
127: ex.setData(data);
128: throw ex;
129: }
130:
131: if (data.endsWith("-")) {
132: IllegalDataException ex = new IllegalDataException(
133: "Comment data ends with a hyphen.");
134: ex.setData(data);
135: throw ex;
136: }
137:
138: }
139: this .data = data;
140:
141: }
142:
143: /**
144: * <p>
145: * Throws <code>IndexOutOfBoundsException</code> because
146: * comments do not have children.
147: * </p>
148: *
149: * @return never returns because comments do not have children;
150: * Always throws an exception.
151: *
152: * @param position the index of the child node to return
153: *
154: * @throws IndexOutOfBoundsException because comments
155: * do not have children
156: */
157: public final Node getChild(int position) {
158: throw new IndexOutOfBoundsException(
159: "LeafNodes do not have children");
160: }
161:
162: /**
163: * <p>
164: * Returns 0 because comments do not have children.
165: * </p>
166: *
167: * @return zero
168: */
169: public final int getChildCount() {
170: return 0;
171: }
172:
173: /**
174: * <p>
175: * Returns a deep copy of this <code>Comment</code> object
176: * which contains the same text, but does not have any parent.
177: * Thus, it can be inserted into a different document.
178: * </p>
179: *
180: * @return a deep copy of this <code>Comment</code>
181: * that is not part of a document
182: *
183: */
184: public Node copy() {
185: return new Comment(data);
186: }
187:
188: /**
189: * <p>
190: * Returns a <code>String</code> containing the actual XML
191: * form of the comment;
192: * for example, <code><--This is a comment--></code>.
193: * </p>
194: *
195: * @return a <code>String</code> containing a well-formed
196: * XML comment
197: */
198: public final String toXML() {
199: StringBuffer result = new StringBuffer("<!--");
200: result.append(data);
201: result.append("-->");
202: return result.toString();
203: }
204:
205: /**
206: * <p>
207: * Returns a string form of the comment suitable for debugging
208: * and diagnosis. It deliberately does not return an actual
209: * XML comment.
210: * </p>
211: *
212: * @return a representation of the <code>Comment</code>
213: * as a <code>String</code>
214: */
215: public final String toString() {
216:
217: String value = getValue();
218: if (value.length() <= 40) {
219: return "[" + getClass().getName() + ": "
220: + Text.escapeLineBreaksAndTruncate(value) + "]";
221: }
222:
223: return "["
224: + getClass().getName()
225: + ": "
226: + Text.escapeLineBreaksAndTruncate(value.substring(0,
227: 35)) + "...]";
228:
229: }
230:
231: boolean isComment() {
232: return true;
233: }
234:
235: }
|