Source code: org/apache/batik/dom/AbstractCharacterData.java
1 /*
2
3 Copyright 2000-2001 The Apache Software Foundation
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16
17 */
18 package org.apache.batik.dom;
19
20 import org.w3c.dom.CharacterData;
21 import org.w3c.dom.DOMException;
22 import org.w3c.dom.Node;
23
24 /**
25 * This class implements the {@link org.w3c.dom.CharacterData} interface.
26 *
27 * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
28 * @version $Id: AbstractCharacterData.java,v 1.7 2005/02/22 09:12:57 cam Exp $
29 */
30 public abstract class AbstractCharacterData
31 extends AbstractChildNode
32 implements CharacterData {
33 /**
34 * The value of this node.
35 */
36 protected String nodeValue = "";
37
38 /**
39 * <b>DOM</b>: Implements {@link org.w3c.dom.Node#getNodeValue()}.
40 * @return {@link #nodeValue}.
41 */
42 public String getNodeValue() throws DOMException {
43 return nodeValue;
44 }
45
46 /**
47 * <b>DOM</b>: Implements {@link org.w3c.dom.Node#setNodeValue(String)}.
48 */
49 public void setNodeValue(String nodeValue) throws DOMException {
50 if (isReadonly()) {
51 throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
52 "readonly.node",
53 new Object[] { new Integer(getNodeType()),
54 getNodeName() });
55 }
56 // Node modification
57 String val = this.nodeValue;
58 this.nodeValue = (nodeValue == null) ? "" : nodeValue;
59
60 // Mutation event
61 fireDOMCharacterDataModifiedEvent(val, this.nodeValue);
62 if (getParentNode() != null) {
63 ((AbstractParentNode)getParentNode()).
64 fireDOMSubtreeModifiedEvent();
65 }
66 }
67
68 /**
69 * <b>DOM</b>: Implements {@link org.w3c.dom.CharacterData#getData()}.
70 * @return {@link #getNodeValue()}.
71 */
72 public String getData() throws DOMException {
73 return getNodeValue();
74 }
75
76 /**
77 * <b>DOM</b>: Implements {@link
78 * org.w3c.dom.CharacterData#setData(String)}.
79 */
80 public void setData(String data) throws DOMException {
81 setNodeValue(data);
82 }
83
84 /**
85 * <b>DOM</b>: Implements {@link org.w3c.dom.CharacterData#getLength()}.
86 * @return {@link #nodeValue}.length().
87 */
88 public int getLength() {
89 return nodeValue.length();
90 }
91
92 /**
93 * <b>DOM</b>: Implements {@link
94 * org.w3c.dom.CharacterData#substringData(int,int)}.
95 */
96 public String substringData(int offset, int count) throws DOMException {
97 checkOffsetCount(offset, count);
98
99 String v = getNodeValue();
100 return v.substring(offset, Math.min(v.length(), offset + count));
101 }
102
103 /**
104 * <b>DOM</b>: Implements {@link
105 * org.w3c.dom.CharacterData#appendData(String)}.
106 */
107 public void appendData(String arg) throws DOMException {
108 if (isReadonly()) {
109 throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
110 "readonly.node",
111 new Object[] { new Integer(getNodeType()),
112 getNodeName() });
113 }
114 setNodeValue(getNodeValue() + ((arg == null) ? "" : arg));
115 }
116
117 /**
118 * <b>DOM</b>: Implements {@link
119 * org.w3c.dom.CharacterData#insertData(int,String)}.
120 */
121 public void insertData(int offset, String arg) throws DOMException {
122 if (isReadonly()) {
123 throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
124 "readonly.node",
125 new Object[] { new Integer(getNodeType()),
126 getNodeName() });
127 }
128 if (offset < 0 || offset > getLength()) {
129 throw createDOMException(DOMException.INDEX_SIZE_ERR,
130 "offset",
131 new Object[] { new Integer(offset) });
132 }
133 String v = getNodeValue();
134 setNodeValue(v.substring(0, offset) +
135 arg + v.substring(offset, v.length()));
136 }
137
138 /**
139 * <b>DOM</b>: Implements {@link
140 * org.w3c.dom.CharacterData#deleteData(int,int)}.
141 */
142 public void deleteData(int offset, int count) throws DOMException {
143 if (isReadonly()) {
144 throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
145 "readonly.node",
146 new Object[] { new Integer(getNodeType()),
147 getNodeName() });
148 }
149 checkOffsetCount(offset, count);
150
151 String v = getNodeValue();
152 setNodeValue(v.substring(0, offset) +
153 v.substring(Math.min(v.length(), offset + count),
154 v.length()));
155 }
156
157 /**
158 * <b>DOM</b>: Implements {@link
159 * org.w3c.dom.CharacterData#replaceData(int,int,String)}.
160 */
161 public void replaceData(int offset, int count, String arg)
162 throws DOMException {
163 if (isReadonly()) {
164 throw createDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
165 "readonly.node",
166 new Object[] { new Integer(getNodeType()),
167 getNodeName() });
168 }
169 checkOffsetCount(offset, count);
170
171 String v = getNodeValue();
172 setNodeValue(v.substring(0, offset) +
173 arg +
174 v.substring(Math.min(v.length(), offset + count),
175 v.length()));
176 }
177
178 /**
179 * Checks the given offset and count validity.
180 */
181 protected void checkOffsetCount(int offset, int count)
182 throws DOMException {
183 if (offset < 0 || offset >= getLength()) {
184 throw createDOMException(DOMException.INDEX_SIZE_ERR,
185 "offset",
186 new Object[] { new Integer(offset) });
187 }
188 if (count < 0) {
189 throw createDOMException(DOMException.INDEX_SIZE_ERR,
190 "negative.count",
191 new Object[] { new Integer(count) });
192 }
193 }
194
195 /**
196 * Exports this node to the given document.
197 */
198 protected Node export(Node n, AbstractDocument d) {
199 super.export(n, d);
200 AbstractCharacterData cd = (AbstractCharacterData)n;
201 cd.nodeValue = nodeValue;
202 return n;
203 }
204
205 /**
206 * Deeply exports this node to the given document.
207 */
208 protected Node deepExport(Node n, AbstractDocument d) {
209 super.deepExport(n, d);
210 AbstractCharacterData cd = (AbstractCharacterData)n;
211 cd.nodeValue = nodeValue;
212 return n;
213 }
214
215 /**
216 * Copy the fields of the current node into the given node.
217 * @param n a node of the type of this.
218 */
219 protected Node copyInto(Node n) {
220 super.copyInto(n);
221 AbstractCharacterData cd = (AbstractCharacterData)n;
222 cd.nodeValue = nodeValue;
223 return n;
224 }
225
226 /**
227 * Deeply copy the fields of the current node into the given node.
228 * @param n a node of the type of this.
229 */
230 protected Node deepCopyInto(Node n) {
231 super.deepCopyInto(n);
232 AbstractCharacterData cd = (AbstractCharacterData)n;
233 cd.nodeValue = nodeValue;
234 return n;
235 }
236 }