KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > dom > CharacterDataImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2001 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.dom;
59
60 import org.w3c.dom.DOMException JavaDoc;
61 import org.w3c.dom.Node JavaDoc;
62 import org.w3c.dom.NodeList JavaDoc;
63
64 /**
65  * CharacterData is an abstract Node that can carry character data as its
66  * Value. It provides shared behavior for Text, CData, and
67  * possibly other node types. All offsets are 0-based.
68  * <p>
69  * Since ProcessingInstructionImpl inherits from this class to reuse the
70  * setNodeValue method, this class isn't declared as implementing the interface
71  * CharacterData. This is done by relevant subclasses (TexImpl, CommentImpl).
72  * <p>
73  * This class doesn't directly support mutation events, however, it notifies
74  * the document when mutations are performed so that the document class do so.
75  *
76  * @version
77  * @since PR-DOM-Level-1-19980818.
78  */

79 public abstract class CharacterDataImpl
80     extends ChildNode {
81
82     //
83
// Constants
84
//
85

86     /** Serialization version. */
87     static final long serialVersionUID = 7931170150428474230L;
88
89     //
90
// Data
91
//
92

93     protected String JavaDoc data;
94
95     /** Empty child nodes. */
96     private static transient NodeList JavaDoc singletonNodeList = new NodeList JavaDoc() {
97         public Node JavaDoc item(int index) { return null; }
98         public int getLength() { return 0; }
99     };
100
101     //
102
// Constructors
103
//
104

105     /** Factory constructor. */
106     protected CharacterDataImpl(CoreDocumentImpl ownerDocument, String JavaDoc data) {
107         super(ownerDocument);
108         this.data = data;
109     }
110
111     //
112
// Node methods
113
//
114

115     /** Returns an empty node list. */
116     public NodeList JavaDoc getChildNodes() {
117         return singletonNodeList;
118     }
119
120     /*
121      * returns the content of this node
122      */

123     public String JavaDoc getNodeValue() {
124         if (needsSyncData()) {
125             synchronizeData();
126         }
127         return data;
128     }
129
130     /** This function added so that we can distinguish whether
131      * setNodeValue has been called from some other DOM functions.
132      * or by the client.<p>
133      * This is important, because we do one type of Range fix-up,
134      * from the high-level functions in CharacterData, and another
135      * type if the client simply calls setNodeValue(value).
136      */

137     protected void setNodeValueInternal(String JavaDoc value) {
138         if (isReadOnly())
139             throw new DOMException JavaDoc(
140                 DOMException.NO_MODIFICATION_ALLOWED_ERR,
141                 "DOM001 Modification not allowed");
142         // revisit: may want to set the value in ownerDocument.
143
// Default behavior, overridden in some subclasses
144
if (needsSyncData()) {
145             synchronizeData();
146         }
147
148         // keep old value for document notification
149
String JavaDoc oldvalue = this.data;
150
151         CoreDocumentImpl ownerDocument = ownerDocument();
152
153         // notify document
154
ownerDocument.modifyingCharacterData(this);
155
156         this.data = value;
157
158         // notify document
159
ownerDocument.modifiedCharacterData(this, oldvalue, value);
160     }
161
162     /**
163      * Sets the content, possibly firing related events,
164      * and updating ranges (via notification to the document)
165      */

166     public void setNodeValue(String JavaDoc value) {
167
168         setNodeValueInternal(value);
169
170         // notify document
171
ownerDocument().replacedText(this);
172     }
173
174     //
175
// CharacterData methods
176
//
177

178     /**
179      * Retrieve character data currently stored in this node.
180      *
181      * @throws DOMExcpetion(DOMSTRING_SIZE_ERR) In some implementations,
182      * the stored data may exceed the permitted length of strings. If so,
183      * getData() will throw this DOMException advising the user to
184      * instead retrieve the data in chunks via the substring() operation.
185      */

186     public String JavaDoc getData() {
187         if (needsSyncData()) {
188             synchronizeData();
189         }
190         return data;
191     }
192
193     /**
194      * Report number of characters currently stored in this node's
195      * data. It may be 0, meaning that the value is an empty string.
196      */

197     public int getLength() {
198         if (needsSyncData()) {
199             synchronizeData();
200         }
201         return data.length();
202     }
203
204     /**
205      * Concatenate additional characters onto the end of the data
206      * stored in this node. Note that this, and insert(), are the paths
207      * by which a DOM could wind up accumulating more data than the
208      * language's strings can easily handle. (See above discussion.)
209      *
210      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
211      */

212     public void appendData(String JavaDoc data) {
213
214         if (isReadOnly()) {
215             throw new DOMException JavaDoc(
216                 DOMException.NO_MODIFICATION_ALLOWED_ERR,
217                 "DOM001 Modification not allowed");
218         }
219
220         if (needsSyncData()) {
221             synchronizeData();
222         }
223         
224         setNodeValue(this.data + data);
225
226     } // appendData(String)
227

228     /**
229      * Remove a range of characters from the node's value. Throws a
230      * DOMException if the offset is beyond the end of the
231      * string. However, a deletion _count_ that exceeds the available
232      * data is accepted as a delete-to-end request.
233      *
234      * @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
235      * greater than length, or if count is negative.
236      *
237      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is
238      * readonly.
239      */

240     public void deleteData(int offset, int count)
241         throws DOMException JavaDoc {
242
243         if (isReadOnly()) {
244             throw new DOMException JavaDoc(
245                 DOMException.NO_MODIFICATION_ALLOWED_ERR,
246                 "DOM001 Modification not allowed");
247         }
248
249         if (count < 0) {
250             throw new DOMException JavaDoc(DOMException.INDEX_SIZE_ERR,
251                                        "DOM004 Index out of bounds");
252         }
253
254         if (needsSyncData()) {
255             synchronizeData();
256         }
257         int tailLength = Math.max(data.length() - count - offset, 0);
258         try {
259             String JavaDoc value = data.substring(0, offset) +
260                 (tailLength > 0
261                  ? data.substring(offset + count, offset + count + tailLength)
262                  : "");
263
264             setNodeValueInternal(value);
265
266             // notify document
267
ownerDocument().deletedText(this, offset, count);
268         }
269         catch (StringIndexOutOfBoundsException JavaDoc e) {
270             throw new DOMException JavaDoc(DOMException.INDEX_SIZE_ERR,
271                                        "DOM004 Index out of bounds");
272         }
273
274     } // deleteData(int,int)
275

276     /**
277      * Insert additional characters into the data stored in this node,
278      * at the offset specified.
279      *
280      * @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
281      * greater than length.
282      *
283      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
284      */

285     public void insertData(int offset, String JavaDoc data)
286         throws DOMException JavaDoc {
287
288         if (isReadOnly()) {
289             throw new DOMException JavaDoc(
290                 DOMException.NO_MODIFICATION_ALLOWED_ERR,
291                 "DOM001 Modification not allowed");
292         }
293
294         if (needsSyncData()) {
295             synchronizeData();
296         }
297         try {
298             String JavaDoc value =
299                 new StringBuffer JavaDoc(this.data).insert(offset, data).toString();
300
301             setNodeValueInternal(value);
302
303             // notify document
304
ownerDocument().insertedText(this, offset, data.length());
305         }
306         catch (StringIndexOutOfBoundsException JavaDoc e) {
307             throw new DOMException JavaDoc(DOMException.INDEX_SIZE_ERR,
308                                        "DOM004 Index out of bounds");
309         }
310
311     } // insertData(int,int)
312

313     /**
314      * Replace a series of characters at the specified (zero-based)
315      * offset with a new string, NOT necessarily of the same
316      * length. Convenience method, equivalent to a delete followed by an
317      * insert. Throws a DOMException if the specified offset is beyond
318      * the end of the existing data.
319      *
320      * @param offset The offset at which to begin replacing.
321      *
322      * @param count The number of characters to remove,
323      * interpreted as in the delete() method.
324      *
325      * @param data The new string to be inserted at offset in place of
326      * the removed data. Note that the entire string will
327      * be inserted -- the count parameter does not affect
328      * insertion, and the new data may be longer or shorter
329      * than the substring it replaces.
330      *
331      * @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
332      * greater than length, or if count is negative.
333      *
334      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is
335      * readonly.
336      */

337     public void replaceData(int offset, int count, String JavaDoc data)
338         throws DOMException JavaDoc {
339
340         // The read-only check is done by deleteData()
341
// ***** This could be more efficient w/r/t Mutation Events,
342
// specifically by aggregating DOMAttrModified and
343
// DOMSubtreeModified. But mutation events are
344
// underspecified; I don't feel compelled
345
// to deal with it right now.
346
deleteData(offset, count);
347         insertData(offset, data);
348
349     } // replaceData(int,int,String)
350

351     /**
352      * Store character data into this node.
353      *
354      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
355      */

356     public void setData(String JavaDoc value)
357         throws DOMException JavaDoc {
358         setNodeValue(value);
359     }
360
361     /**
362      * Substring is more than a convenience function. In some
363      * implementations of the DOM, where the stored data may exceed the
364      * length that can be returned in a single string, the only way to
365      * read it all is to extract it in chunks via this method.
366      *
367      * @param offset Zero-based offset of first character to retrieve.
368      * @param count Number of characters to retrieve.
369      *
370      * If the sum of offset and count exceeds the length, all characters
371      * to end of data are returned.
372      *
373      * @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
374      * greater than length, or if count is negative.
375      *
376      * @throws DOMException(WSTRING_SIZE_ERR) In some implementations,
377      * count may exceed the permitted length of strings. If so,
378      * substring() will throw this DOMException advising the user to
379      * instead retrieve the data in smaller chunks.
380      */

381     public String JavaDoc substringData(int offset, int count)
382         throws DOMException JavaDoc {
383
384         if (needsSyncData()) {
385             synchronizeData();
386         }
387         
388         int length = data.length();
389         if (count < 0 || offset < 0 || offset > length - 1) {
390             throw new DOMException JavaDoc(DOMException.INDEX_SIZE_ERR,
391                                        "DOM004 Index out of bounds");
392         }
393
394         int tailIndex = Math.min(offset + count, length);
395
396         return data.substring(offset, tailIndex);
397
398     } // substringData(int,int):String
399

400 } // class CharacterDataImpl
401
Popular Tags