DomCharacterData.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* DomCharacterData.java --
  2. Copyright (C) 1999,2000,2001,2004,2006 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package gnu.xml.dom;
  32. import org.w3c.dom.CharacterData;
  33. import org.w3c.dom.DOMException;
  34. import org.w3c.dom.Node;
  35. import org.w3c.dom.NodeList;
  36. import org.w3c.dom.events.MutationEvent;
  37. /**
  38. * <p> Abstract "CharacterData" implementation. This
  39. * facilitates reusing code in classes implementing subtypes of that DOM
  40. * interface (Text, Comment, CDATASection). </p>
  41. *
  42. * @author David Brownell
  43. * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  44. */
  45. public abstract class DomCharacterData
  46. extends DomNode
  47. implements CharacterData
  48. {
  49. /**
  50. * Empty node list representing the children of character data nodes.
  51. */
  52. static class EmptyNodeList
  53. implements NodeList
  54. {
  55. public int getLength()
  56. {
  57. return 0;
  58. }
  59. public Node item(int index)
  60. {
  61. return null;
  62. }
  63. }
  64. /**
  65. * Singleton empty node list for character data nodes.
  66. */
  67. static final NodeList CHILD_NODES = new EmptyNodeList();
  68. private String text;
  69. // package private
  70. DomCharacterData(short nodeType, DomDocument doc, String value)
  71. {
  72. super(nodeType, doc);
  73. text = (value == null) ? "" : value;
  74. }
  75. // package private
  76. DomCharacterData(short nodeType, DomDocument doc,
  77. char[] buf, int offset, int length)
  78. {
  79. super(nodeType, doc);
  80. text = (buf == null) ? "" : new String(buf, offset, length);
  81. }
  82. /**
  83. * <b>DOM L1</b>
  84. * Appends the specified data to the value of this node.
  85. * Causes a DOMCharacterDataModified mutation event to be reported.
  86. */
  87. public void appendData(String arg)
  88. {
  89. if (isReadonly())
  90. {
  91. throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
  92. }
  93. String value = text + arg;
  94. mutating(value);
  95. text = value;
  96. }
  97. /**
  98. * <b>DOM L1</b>
  99. * Modifies the value of this node.
  100. * Causes a DOMCharacterDataModified mutation event to be reported.
  101. */
  102. public void deleteData(int offset, int count)
  103. {
  104. if (isReadonly())
  105. {
  106. throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
  107. }
  108. char[] raw = text.toCharArray();
  109. if (offset < 0 || count < 0 || offset > raw.length)
  110. {
  111. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  112. }
  113. if ((offset + count) > raw.length)
  114. {
  115. count = raw.length - offset;
  116. }
  117. if (count == 0)
  118. {
  119. return;
  120. }
  121. try
  122. {
  123. char[] buf = new char[raw.length - count];
  124. System.arraycopy(raw, 0, buf, 0, offset);
  125. System.arraycopy(raw, offset + count, buf, offset,
  126. raw.length - (offset + count));
  127. String value = new String(buf);
  128. mutating(value);
  129. text = value;
  130. }
  131. catch (IndexOutOfBoundsException x)
  132. {
  133. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  134. }
  135. }
  136. /**
  137. * <b>DOM L1</b>
  138. * Returns the value of this node.
  139. */
  140. public String getNodeValue()
  141. {
  142. return text;
  143. }
  144. /**
  145. * <b>DOM L1</b>
  146. * Returns the value of this node; same as getNodeValue.
  147. */
  148. public final String getData()
  149. {
  150. return text;
  151. }
  152. /**
  153. * <b>DOM L1</b>
  154. * Returns the length of the data.
  155. */
  156. public int getLength()
  157. {
  158. return text.length();
  159. }
  160. /**
  161. * <b>DOM L1</b>
  162. * Modifies the value of this node.
  163. */
  164. public void insertData(int offset, String arg)
  165. {
  166. if (isReadonly())
  167. {
  168. throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
  169. }
  170. char[] raw = text.toCharArray();
  171. char[] tmp = arg.toCharArray ();
  172. char[] buf = new char[raw.length + tmp.length];
  173. try
  174. {
  175. System.arraycopy(raw, 0, buf, 0, offset);
  176. System.arraycopy(tmp, 0, buf, offset, tmp.length);
  177. System.arraycopy(raw, offset, buf, offset + tmp.length,
  178. raw.length - offset);
  179. String value = new String(buf);
  180. mutating(value);
  181. text = value;
  182. }
  183. catch (IndexOutOfBoundsException x)
  184. {
  185. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  186. }
  187. }
  188. /**
  189. * <b>DOM L1</b>
  190. * Modifies the value of this node. Causes DOMCharacterDataModified
  191. * mutation events to be reported (at least one).
  192. */
  193. public void replaceData(int offset, int count, String arg)
  194. {
  195. if (readonly)
  196. {
  197. throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
  198. }
  199. char[] raw = text.toCharArray();
  200. // deleteData
  201. if (offset < 0 || count < 0 || offset > raw.length)
  202. {
  203. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  204. }
  205. if ((offset + count) > raw.length)
  206. {
  207. count = raw.length - offset;
  208. }
  209. try
  210. {
  211. char[] buf = new char[raw.length - count];
  212. System.arraycopy(raw, 0, buf, 0, offset);
  213. System.arraycopy(raw, offset + count, buf, offset,
  214. raw.length - (offset + count));
  215. // insertData
  216. char[] tmp = arg.toCharArray ();
  217. char[] buf2 = new char[buf.length + tmp.length];
  218. System.arraycopy(raw, 0, buf, 0, offset);
  219. System.arraycopy(tmp, 0, buf, offset, tmp.length);
  220. System.arraycopy(raw, offset, buf, offset + tmp.length,
  221. raw.length - offset);
  222. String value = new String(buf);
  223. mutating(value);
  224. text = value;
  225. }
  226. catch (IndexOutOfBoundsException x)
  227. {
  228. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  229. }
  230. }
  231. /**
  232. * <b>DOM L1</b>
  233. * Assigns the value of this node.
  234. * Causes a DOMCharacterDataModified mutation event to be reported.
  235. */
  236. public void setNodeValue(String value)
  237. {
  238. if (isReadonly())
  239. {
  240. throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
  241. }
  242. if (value == null)
  243. {
  244. value = "";
  245. }
  246. mutating(value);
  247. text = value;
  248. }
  249. /**
  250. * <b>DOM L1</b>
  251. * Assigns the value of this node; same as setNodeValue.
  252. */
  253. final public void setData(String data)
  254. {
  255. setNodeValue(data);
  256. }
  257. /**
  258. * <b>DOM L1</b>
  259. * Returns the specified substring.
  260. */
  261. public String substringData(int offset, int count)
  262. {
  263. try
  264. {
  265. return text.substring(offset, count);
  266. }
  267. catch (StringIndexOutOfBoundsException e)
  268. {
  269. if (offset >= 0 && count >= 0 && offset < text.length())
  270. {
  271. return text.substring(offset);
  272. }
  273. throw new DomDOMException(DOMException.INDEX_SIZE_ERR);
  274. }
  275. }
  276. /**
  277. * Returns an empty node list.
  278. * Character data nodes do not have children.
  279. */
  280. public NodeList getChildNodes()
  281. {
  282. return CHILD_NODES;
  283. }
  284. /**
  285. * The base URI for character data is <code>null</code>.
  286. * @since DOM Level 3 Core
  287. */
  288. public final String getBaseURI()
  289. {
  290. return null;
  291. }
  292. private void mutating(String newValue)
  293. {
  294. if (!reportMutations)
  295. {
  296. return;
  297. }
  298. // EVENT: DOMCharacterDataModified, target = this,
  299. // prev/new values provided
  300. MutationEvent event;
  301. event = (MutationEvent) createEvent("MutationEvents");
  302. event.initMutationEvent("DOMCharacterDataModified",
  303. true /* bubbles */, false /* nocancel */,
  304. null, text, newValue, null, (short) 0);
  305. dispatchEvent(event);
  306. }
  307. }