Source for gnu.xml.dom.DomCharacterData

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