david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2001, 2004 IBM Corporation and others. |
| 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the Eclipse Public License v1.0 |
| 5 | * which accompanies this distribution, and is available at |
| 6 | * http://www.eclipse.org/legal/epl-v10.html |
| 7 | * |
| 8 | * Contributors: |
| 9 | * IBM Corporation - initial API and implementation |
| 10 | * Jens Lukowski/Innoopract - initial renaming/restructuring |
| 11 | * |
| 12 | *******************************************************************************/ |
| 13 | package org.eclipse.wst.xml.core.internal.document; |
| 14 | |
david_williams | c911388 | 2005-04-09 03:19:38 +0000 | [diff] [blame] | 15 | import org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel; |
david_williams | 4ad020f | 2005-04-18 08:00:30 +0000 | [diff] [blame] | 16 | import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; |
| 17 | import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener; |
| 18 | import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent; |
| 19 | import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent; |
| 20 | import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent; |
| 21 | import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent; |
| 22 | import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent; |
| 23 | import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; |
| 24 | import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; |
| 25 | import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList; |
| 26 | import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; |
| 27 | import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList; |
david_williams | 425ffe7 | 2004-12-07 21:46:39 +0000 | [diff] [blame] | 28 | import org.eclipse.wst.xml.core.internal.Logger; |
david_williams | 4ad020f | 2005-04-18 08:00:30 +0000 | [diff] [blame] | 29 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; |
| 30 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; |
| 31 | import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; |
| 32 | import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator; |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 33 | import org.w3c.dom.Attr; |
| 34 | import org.w3c.dom.DOMException; |
| 35 | import org.w3c.dom.DOMImplementation; |
| 36 | import org.w3c.dom.Document; |
| 37 | import org.w3c.dom.DocumentType; |
| 38 | import org.w3c.dom.Element; |
| 39 | import org.w3c.dom.Node; |
| 40 | |
| 41 | |
| 42 | /** |
| 43 | * XMLModelImpl class |
| 44 | */ |
david_williams | 5677702 | 2005-04-11 06:21:55 +0000 | [diff] [blame] | 45 | public class DOMModelImpl extends AbstractStructuredModel implements IStructuredDocumentListener, IDOMModel, DOMImplementation { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 46 | private static String TRACE_PARSER_MANAGEMENT_EXCEPTION = "parserManagement"; //$NON-NLS-1$ |
| 47 | private Object active = null; |
david_williams | 63f5c32 | 2005-03-15 06:02:57 +0000 | [diff] [blame] | 48 | private DocumentImpl document = null; |
david_williams | 6a8e389 | 2005-04-05 05:21:12 +0000 | [diff] [blame] | 49 | private ISourceGenerator generator = null; |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 50 | private XMLModelNotifier notifier = null; |
| 51 | private XMLModelParser parser = null; |
| 52 | private boolean refresh = false; |
| 53 | private XMLModelUpdater updater = null; |
| 54 | |
| 55 | /** |
| 56 | * XMLModelImpl constructor |
| 57 | */ |
david_williams | 5677702 | 2005-04-11 06:21:55 +0000 | [diff] [blame] | 58 | public DOMModelImpl() { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 59 | super(); |
| 60 | this.document = (DocumentImpl) internalCreateDocument(); |
| 61 | } |
| 62 | |
| 63 | /** |
| 64 | * This API allows clients to declare that they are about to make a |
| 65 | * "large" change to the model. This change might be in terms of content |
| 66 | * or it might be in terms of the model id or base location. |
| 67 | * |
| 68 | * Note that in the case of embedded calls, notification to listners is |
| 69 | * sent only once. |
| 70 | * |
| 71 | * Note that the client who is making these changes has the responsibility |
| 72 | * to restore the models state once finished with the changes. See |
| 73 | * getMemento and restoreState. |
| 74 | * |
| 75 | * The method isModelStateChanging can be used by a client to determine if |
| 76 | * the model is already in a change sequence. |
| 77 | */ |
| 78 | public void aboutToChangeModel() { |
| 79 | super.aboutToChangeModel(); |
| 80 | // technically, no need to call beginChanging so often, |
| 81 | // since aboutToChangeModel can be nested. |
| 82 | // but will leave as is for this release. |
| 83 | // see modelChanged, and be sure stays coordinated there. |
| 84 | getModelNotifier().beginChanging(); |
| 85 | } |
| 86 | |
| 87 | public void aboutToReinitializeModel() { |
| 88 | XMLModelNotifier notifier = getModelNotifier(); |
| 89 | notifier.cancelPending(); |
| 90 | super.aboutToReinitializeModel(); |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * attrReplaced method |
| 95 | * |
| 96 | * @param element |
| 97 | * org.w3c.dom.Element |
| 98 | * @param newAttr |
| 99 | * org.w3c.dom.Attr |
| 100 | * @param oldAttr |
| 101 | * org.w3c.dom.Attr |
| 102 | */ |
| 103 | protected void attrReplaced(Element element, Attr newAttr, Attr oldAttr) { |
| 104 | if (element == null) |
| 105 | return; |
| 106 | if (getActiveParser() == null) { |
| 107 | XMLModelUpdater updater = getModelUpdater(); |
| 108 | setActive(updater); |
| 109 | updater.initialize(); |
| 110 | updater.replaceAttr(element, newAttr, oldAttr); |
| 111 | setActive(null); |
| 112 | } |
| 113 | getModelNotifier().attrReplaced(element, newAttr, oldAttr); |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * This API allows a client controlled way of notifying all ModelEvent |
| 118 | * listners that the model has been changed. This method is a matched pair |
| 119 | * to aboutToChangeModel, and must be called after aboutToChangeModel ... |
| 120 | * or some listeners could be left waiting indefinitely for the changed |
| 121 | * event. So, its suggested that changedModel always be in a finally |
| 122 | * clause. Likewise, a client should never call changedModel without |
| 123 | * calling aboutToChangeModel first. |
| 124 | * |
| 125 | * In the case of embedded calls, the notification is just sent once. |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 126 | * |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 127 | */ |
| 128 | public void changedModel() { |
| 129 | // NOTE: the order of 'changedModel' and 'endChanging' is significant. |
| 130 | // By calling changedModel first, this basically decrements the |
| 131 | // "isChanging" counter |
| 132 | // in super class and when zero all listeners to model state events |
| 133 | // will be notified |
| 134 | // that the model has been changed. 'endChanging' will notify all |
| 135 | // deferred adapters. |
| 136 | // So, the significance of order is that adapters (and methods they |
| 137 | // call) |
| 138 | // can count on the state of model "isChanging" to be accurate. |
| 139 | // But, remember, that this means the "modelChanged" event can be |
| 140 | // received before all |
| 141 | // adapters have finished their processing. |
| 142 | // NOTE NOTE: The above note is obsolete in fact (though still states |
| 143 | // issue correctly). |
| 144 | // Due to popular demand, the order of these calls were reversed and |
| 145 | // behavior |
| 146 | // changed on 07/22/2004. |
| 147 | // |
| 148 | // see also |
| 149 | // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=4302 |
| 150 | // for motivation for this 'on verge of' call. |
| 151 | // this could be improved in future if notifier also used counting |
| 152 | // flag to avoid nested calls. If/when changed be sure to check if |
| 153 | // aboutToChangeModel needs any changes too. |
| 154 | if (isModelChangeStateOnVergeOfEnding()) { |
| 155 | // end lock before noticiation loop, since directly or indirectly |
| 156 | // we may be "called from foriegn code" during notification. |
| 157 | endLock(); |
david_williams | e2ed76e | 2005-12-06 07:31:36 +0000 | [diff] [blame] | 158 | // we null out here to avoid spurious"warning" message while debug |
| 159 | // tracing is enabled |
david_williams | 6f9dcdd | 2005-10-09 05:14:55 +0000 | [diff] [blame] | 160 | fLockObject = null; |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 161 | // the notifier is what controls adaper notification, which |
| 162 | // should be sent out before the 'modelChanged' event. |
| 163 | getModelNotifier().endChanging(); |
| 164 | } |
| 165 | // changedModel handles 'nesting', so only one event sent out |
| 166 | // when mulitple calls to 'aboutToChange/Changed'. |
| 167 | super.changedModel(); |
| 168 | handleRefresh(); |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * childReplaced method |
| 173 | * |
| 174 | * @param parentNode |
| 175 | * org.w3c.dom.Node |
| 176 | * @param newChild |
| 177 | * org.w3c.dom.Node |
| 178 | * @param oldChild |
| 179 | * org.w3c.dom.Node |
| 180 | */ |
| 181 | protected void childReplaced(Node parentNode, Node newChild, Node oldChild) { |
| 182 | if (parentNode == null) |
| 183 | return; |
| 184 | if (getActiveParser() == null) { |
| 185 | XMLModelUpdater updater = getModelUpdater(); |
| 186 | setActive(updater); |
| 187 | updater.initialize(); |
| 188 | updater.replaceChild(parentNode, newChild, oldChild); |
| 189 | setActive(null); |
| 190 | } |
| 191 | getModelNotifier().childReplaced(parentNode, newChild, oldChild); |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * Creates an XML <code>Document</code> object of the specified type |
| 196 | * with its document element. HTML-only DOM implementations do not need to |
| 197 | * implement this method. |
| 198 | * |
| 199 | * @param namespaceURIThe |
| 200 | * namespace URI of the document element to create. |
| 201 | * @param qualifiedNameThe |
| 202 | * qualified name of the document element to be created. |
| 203 | * @param doctypeThe |
| 204 | * type of document to be created or <code>null</code>. When |
| 205 | * <code>doctype</code> is not <code>null</code>, its |
| 206 | * <code>Node.ownerDocument</code> attribute is set to the |
| 207 | * document being created. |
| 208 | * @return A new <code>Document</code> object. |
| 209 | * @exception DOMException |
| 210 | * INVALID_CHARACTER_ERR: Raised if the specified qualified |
| 211 | * name contains an illegal character. <br> |
| 212 | * NAMESPACE_ERR: Raised if the <code>qualifiedName</code> |
| 213 | * is malformed, if the <code>qualifiedName</code> has a |
| 214 | * prefix and the <code>namespaceURI</code> is |
| 215 | * <code>null</code>, or if the |
| 216 | * <code>qualifiedName</code> has a prefix that is "xml" |
| 217 | * and the <code>namespaceURI</code> is different from " |
| 218 | * http://www.w3.org/XML/1998/namespace" .<br> |
| 219 | * WRONG_DOCUMENT_ERR: Raised if <code>doctype</code> has |
| 220 | * already been used with a different document or was |
| 221 | * created from a different implementation. |
david_williams | 6cb2639 | 2005-06-24 20:13:29 +0000 | [diff] [blame] | 222 | * @see DOM Level 2 |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 223 | */ |
| 224 | public Document createDocument(String namespaceURI, String qualifiedName, DocumentType doctype) throws DOMException { |
| 225 | return null; |
| 226 | } |
| 227 | |
| 228 | /** |
| 229 | * Creates an empty <code>DocumentType</code> node. Entity declarations |
| 230 | * and notations are not made available. Entity reference expansions and |
| 231 | * default attribute additions do not occur. It is expected that a future |
| 232 | * version of the DOM will provide a way for populating a |
| 233 | * <code>DocumentType</code>.<br> |
| 234 | * HTML-only DOM implementations do not need to implement this method. |
| 235 | * |
| 236 | * @param qualifiedNameThe |
| 237 | * qualified name of the document type to be created. |
| 238 | * @param publicIdThe |
| 239 | * external subset public identifier. |
| 240 | * @param systemIdThe |
| 241 | * external subset system identifier. |
| 242 | * @return A new <code>DocumentType</code> node with |
| 243 | * <code>Node.ownerDocument</code> set to <code>null</code>. |
| 244 | * @exception DOMException |
| 245 | * INVALID_CHARACTER_ERR: Raised if the specified qualified |
| 246 | * name contains an illegal character. <br> |
| 247 | * NAMESPACE_ERR: Raised if the <code>qualifiedName</code> |
| 248 | * is malformed. |
david_williams | 6cb2639 | 2005-06-24 20:13:29 +0000 | [diff] [blame] | 249 | * @see DOM Level 2 |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 250 | */ |
| 251 | public DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) throws DOMException { |
| 252 | DocumentTypeImpl documentType = new DocumentTypeImpl(); |
| 253 | documentType.setName(qualifiedName); |
| 254 | documentType.setPublicId(publicId); |
| 255 | documentType.setSystemId(systemId); |
| 256 | return documentType; |
| 257 | } |
| 258 | |
| 259 | /** |
| 260 | */ |
| 261 | protected void documentTypeChanged() { |
| 262 | if (this.refresh) |
| 263 | return; |
| 264 | // unlike 'resfresh', 'reinitialize' finishes loop |
| 265 | // and flushes remaining notification que before |
| 266 | // actually reinitializing. |
david_williams | e5a3701 | 2005-02-09 23:42:12 +0000 | [diff] [blame] | 267 | // ISSUE: should reinit be used instead of handlerefresh? |
| 268 | // this.setReinitializeNeeded(true); |
| 269 | if (this.active != null || getModelNotifier().isChanging()) |
| 270 | return; // defer |
| 271 | handleRefresh(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 272 | } |
| 273 | |
| 274 | protected void editableChanged(Node node) { |
| 275 | if (node != null) { |
| 276 | getModelNotifier().editableChanged(node); |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | /** |
| 281 | */ |
| 282 | protected void endTagChanged(Element element) { |
| 283 | if (element == null) |
| 284 | return; |
| 285 | if (getActiveParser() == null) { |
| 286 | XMLModelUpdater updater = getModelUpdater(); |
| 287 | setActive(updater); |
| 288 | updater.initialize(); |
| 289 | updater.changeEndTag(element); |
| 290 | setActive(null); |
| 291 | } |
| 292 | getModelNotifier().endTagChanged(element); |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | */ |
| 297 | private XMLModelParser getActiveParser() { |
| 298 | if (this.parser == null) |
| 299 | return null; |
| 300 | if (this.parser != this.active) |
| 301 | return null; |
| 302 | return this.parser; |
| 303 | } |
| 304 | |
| 305 | /** |
| 306 | */ |
| 307 | private XMLModelUpdater getActiveUpdater() { |
| 308 | if (this.updater == null) |
| 309 | return null; |
| 310 | if (this.updater != this.active) |
| 311 | return null; |
| 312 | return this.updater; |
| 313 | } |
| 314 | |
| 315 | /* |
| 316 | * (non-Javadoc) |
| 317 | * |
| 318 | * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) |
| 319 | */ |
| 320 | public Object getAdapter(Class adapter) { |
| 321 | if (Document.class.equals(adapter)) |
| 322 | return getDocument(); |
| 323 | return super.getAdapter(adapter); |
| 324 | } |
| 325 | |
| 326 | /** |
| 327 | * getDocument method |
| 328 | * |
| 329 | * @return XMLDocument |
| 330 | */ |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 331 | public IDOMDocument getDocument() { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 332 | return this.document; |
| 333 | } |
| 334 | |
david_williams | 6a8e389 | 2005-04-05 05:21:12 +0000 | [diff] [blame] | 335 | public ISourceGenerator getGenerator() { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 336 | if (this.generator == null) { |
| 337 | this.generator = XMLGeneratorImpl.getInstance(); |
| 338 | } |
| 339 | return this.generator; |
| 340 | } |
| 341 | |
| 342 | /** |
| 343 | * getNode method |
| 344 | * |
| 345 | * @param offset |
| 346 | * int |
| 347 | */ |
| 348 | public IndexedRegion getIndexedRegion(int offset) { |
| 349 | if (this.document == null) |
| 350 | return null; |
| 351 | // search in document children |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 352 | IDOMNode parent = null; |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 353 | int length = this.document.getEndOffset(); |
| 354 | if (offset * 2 < length) { |
| 355 | // search from the first |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 356 | IDOMNode child = (IDOMNode) this.document.getFirstChild(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 357 | while (child != null) { |
| 358 | if (child.getEndOffset() <= offset) { |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 359 | child = (IDOMNode) child.getNextSibling(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 360 | continue; |
| 361 | } |
| 362 | if (child.getStartOffset() > offset) { |
| 363 | break; |
| 364 | } |
| 365 | IStructuredDocumentRegion startStructuredDocumentRegion = child.getStartStructuredDocumentRegion(); |
| 366 | if (startStructuredDocumentRegion != null) { |
| 367 | if (startStructuredDocumentRegion.getEnd() > offset) |
| 368 | return child; |
| 369 | } |
| 370 | IStructuredDocumentRegion endStructuredDocumentRegion = child.getEndStructuredDocumentRegion(); |
| 371 | if (endStructuredDocumentRegion != null) { |
| 372 | if (endStructuredDocumentRegion.getStart() <= offset) |
| 373 | return child; |
| 374 | } |
| 375 | // dig more |
| 376 | parent = child; |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 377 | child = (IDOMNode) parent.getFirstChild(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 378 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 379 | } |
| 380 | else { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 381 | // search from the last |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 382 | IDOMNode child = (IDOMNode) this.document.getLastChild(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 383 | while (child != null) { |
| 384 | if (child.getStartOffset() > offset) { |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 385 | child = (IDOMNode) child.getPreviousSibling(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 386 | continue; |
| 387 | } |
| 388 | if (child.getEndOffset() <= offset) { |
| 389 | break; |
| 390 | } |
| 391 | IStructuredDocumentRegion startStructuredDocumentRegion = child.getStartStructuredDocumentRegion(); |
| 392 | if (startStructuredDocumentRegion != null) { |
| 393 | if (startStructuredDocumentRegion.getEnd() > offset) |
| 394 | return child; |
| 395 | } |
| 396 | IStructuredDocumentRegion endStructuredDocumentRegion = child.getEndStructuredDocumentRegion(); |
| 397 | if (endStructuredDocumentRegion != null) { |
| 398 | if (endStructuredDocumentRegion.getStart() <= offset) |
| 399 | return child; |
| 400 | } |
| 401 | // dig more |
| 402 | parent = child; |
david_williams | c39caaf | 2005-04-05 06:07:16 +0000 | [diff] [blame] | 403 | child = (IDOMNode) parent.getLastChild(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 404 | } |
| 405 | } |
| 406 | return parent; |
| 407 | } |
| 408 | |
| 409 | /** |
| 410 | */ |
| 411 | public XMLModelNotifier getModelNotifier() { |
| 412 | if (this.notifier == null) { |
| 413 | this.notifier = new XMLModelNotifierImpl(); |
| 414 | } |
| 415 | return this.notifier; |
| 416 | } |
| 417 | |
| 418 | /** |
| 419 | */ |
| 420 | private XMLModelParser getModelParser() { |
| 421 | if (this.parser == null) { |
david_williams | 63f5c32 | 2005-03-15 06:02:57 +0000 | [diff] [blame] | 422 | this.parser = createModelParser(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 423 | } |
| 424 | return this.parser; |
| 425 | } |
| 426 | |
david_williams | 63f5c32 | 2005-03-15 06:02:57 +0000 | [diff] [blame] | 427 | protected XMLModelParser createModelParser() { |
| 428 | return new XMLModelParser(this); |
| 429 | } |
| 430 | |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 431 | /** |
| 432 | */ |
| 433 | private XMLModelUpdater getModelUpdater() { |
| 434 | if (this.updater == null) { |
david_williams | 63f5c32 | 2005-03-15 06:02:57 +0000 | [diff] [blame] | 435 | this.updater = createModelUpdater(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 436 | } |
| 437 | return this.updater; |
| 438 | } |
| 439 | |
david_williams | 63f5c32 | 2005-03-15 06:02:57 +0000 | [diff] [blame] | 440 | protected XMLModelUpdater createModelUpdater() { |
| 441 | return new XMLModelUpdater(this); |
| 442 | } |
| 443 | |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 444 | /** |
| 445 | */ |
| 446 | private void handleRefresh() { |
| 447 | if (!this.refresh) |
| 448 | return; |
| 449 | XMLModelNotifier notifier = getModelNotifier(); |
| 450 | boolean isChanging = notifier.isChanging(); |
| 451 | if (!isChanging) |
| 452 | notifier.beginChanging(true); |
| 453 | XMLModelParser parser = getModelParser(); |
| 454 | setActive(parser); |
| 455 | this.document.removeChildNodes(); |
| 456 | try { |
| 457 | parser.replaceStructuredDocumentRegions(getStructuredDocument().getRegionList(), null); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 458 | } |
| 459 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 460 | Logger.logException(ex); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 461 | } |
| 462 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 463 | setActive(null); |
| 464 | if (!isChanging) |
| 465 | notifier.endChanging(); |
| 466 | this.refresh = false; |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | /** |
| 471 | * Test if the DOM implementation implements a specific feature. |
| 472 | * |
| 473 | * @param featureThe |
| 474 | * name of the feature to test (case-insensitive). The values |
| 475 | * used by DOM features are defined throughout the DOM Level 2 |
| 476 | * specifications and listed in the section. The name must be |
| 477 | * an XML name. To avoid possible conflicts, as a convention, |
| 478 | * names referring to features defined outside the DOM |
| 479 | * specification should be made unique by reversing the name of |
| 480 | * the Internet domain name of the person (or the organization |
| 481 | * that the person belongs to) who defines the feature, |
| 482 | * component by component, and using this as a prefix. For |
| 483 | * instance, the W3C SVG Working Group defines the feature |
| 484 | * "org.w3c.dom.svg". |
| 485 | * @param versionThis |
| 486 | * is the version number of the feature to test. In Level 2, |
| 487 | * the string can be either "2.0" or "1.0". If the version is |
| 488 | * not specified, supporting any version of the feature causes |
| 489 | * the method to return <code>true</code>. |
| 490 | * @return <code>true</code> if the feature is implemented in the |
| 491 | * specified version, <code>false</code> otherwise. |
| 492 | */ |
| 493 | public boolean hasFeature(String feature, String version) { |
| 494 | if (feature == null) |
| 495 | return false; |
| 496 | if (version != null) { |
| 497 | if (!version.equals("1.0") && !version.equals("2.0")) { //$NON-NLS-2$//$NON-NLS-1$ |
| 498 | return false; |
| 499 | } |
| 500 | } |
| 501 | if (feature.equalsIgnoreCase("Core")) //$NON-NLS-1$ |
| 502 | return true; //$NON-NLS-1$ |
| 503 | if (feature.equalsIgnoreCase("XML")) //$NON-NLS-1$ |
| 504 | return true; //$NON-NLS-1$ |
| 505 | return false; |
| 506 | } |
| 507 | |
| 508 | /** |
| 509 | * createDocument method |
| 510 | * |
| 511 | * @return org.w3c.dom.Document |
| 512 | */ |
| 513 | protected Document internalCreateDocument() { |
| 514 | DocumentImpl document = new DocumentImpl(); |
| 515 | document.setModel(this); |
| 516 | return document; |
| 517 | } |
| 518 | |
| 519 | boolean isReparsing() { |
| 520 | return (active != null); |
| 521 | } |
| 522 | |
| 523 | /** |
| 524 | * nameChanged method |
| 525 | * |
| 526 | * @param node |
| 527 | * org.w3c.dom.Node |
| 528 | */ |
| 529 | protected void nameChanged(Node node) { |
| 530 | if (node == null) |
| 531 | return; |
| 532 | if (getActiveParser() == null) { |
| 533 | XMLModelUpdater updater = getModelUpdater(); |
| 534 | setActive(updater); |
| 535 | updater.initialize(); |
| 536 | updater.changeName(node); |
| 537 | setActive(null); |
| 538 | } |
| 539 | // notification is already sent |
| 540 | } |
| 541 | |
| 542 | /** |
| 543 | * newModel method |
| 544 | * |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 545 | */ |
| 546 | public void newModel(NewDocumentEvent structuredDocumentEvent) { |
| 547 | if (structuredDocumentEvent == null) |
| 548 | return; |
| 549 | IStructuredDocument structuredDocument = structuredDocumentEvent.getStructuredDocument(); |
| 550 | if (structuredDocument == null) |
| 551 | return; |
| 552 | // this should not happen, but for the case |
david_williams | e2ed76e | 2005-12-06 07:31:36 +0000 | [diff] [blame] | 553 | if (fStructuredDocument != null && fStructuredDocument != structuredDocument) |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 554 | setStructuredDocument(structuredDocument); |
david_williams | e2ed76e | 2005-12-06 07:31:36 +0000 | [diff] [blame] | 555 | |
| 556 | internalSetNewDocument(structuredDocument); |
| 557 | } |
| 558 | |
| 559 | private void internalSetNewDocument(IStructuredDocument structuredDocument) { |
| 560 | if (structuredDocument == null) |
| 561 | return; |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 562 | IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 563 | if ((flatNodes == null) || (flatNodes.getLength() == 0)) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 564 | return; |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 565 | } |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 566 | if (this.document == null) |
| 567 | return; // being constructed |
| 568 | XMLModelUpdater updater = getActiveUpdater(); |
| 569 | if (updater != null) { // being updated |
| 570 | try { |
| 571 | updater.replaceStructuredDocumentRegions(flatNodes, null); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 572 | } |
| 573 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 574 | Logger.logException(ex); |
| 575 | this.refresh = true; |
| 576 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 577 | } |
| 578 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 579 | setActive(null); |
| 580 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 581 | // // for new model, we might need to |
| 582 | // // re-init, e.g. if someone calls setText |
| 583 | // // on an existing model |
| 584 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 585 | return; |
| 586 | } |
| 587 | XMLModelNotifier notifier = getModelNotifier(); |
| 588 | boolean isChanging = notifier.isChanging(); |
| 589 | // call even if changing to notify doing new model |
| 590 | getModelNotifier().beginChanging(true); |
| 591 | XMLModelParser parser = getModelParser(); |
| 592 | setActive(parser); |
| 593 | this.document.removeChildNodes(); |
| 594 | try { |
| 595 | parser.replaceStructuredDocumentRegions(flatNodes, null); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 596 | } |
| 597 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 598 | Logger.logException(ex); |
| 599 | // meaningless to refresh, because the result might be the same |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 600 | } |
| 601 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 602 | setActive(null); |
| 603 | if (!isChanging) { |
| 604 | getModelNotifier().endChanging(); |
| 605 | } |
| 606 | // ignore refresh |
| 607 | this.refresh = false; |
| 608 | } |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 609 | } |
| 610 | |
| 611 | /** |
| 612 | */ |
| 613 | public void noChange(NoChangeEvent event) { |
| 614 | XMLModelUpdater updater = getActiveUpdater(); |
| 615 | if (updater != null) { // being updated |
| 616 | // cleanup updater staffs |
| 617 | try { |
| 618 | updater.replaceStructuredDocumentRegions(null, null); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 619 | } |
| 620 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 621 | Logger.logException(ex); |
| 622 | this.refresh = true; |
| 623 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 624 | } |
| 625 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 626 | setActive(null); |
| 627 | } |
| 628 | // I guess no chanage means the model could not need re-init |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 629 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 630 | return; |
| 631 | } |
| 632 | } |
| 633 | |
| 634 | /** |
| 635 | * nodesReplaced method |
| 636 | * |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 637 | */ |
| 638 | public void nodesReplaced(StructuredDocumentRegionsReplacedEvent event) { |
| 639 | if (event == null) |
| 640 | return; |
| 641 | IStructuredDocumentRegionList oldStructuredDocumentRegions = event.getOldStructuredDocumentRegions(); |
| 642 | IStructuredDocumentRegionList newStructuredDocumentRegions = event.getNewStructuredDocumentRegions(); |
| 643 | XMLModelUpdater updater = getActiveUpdater(); |
| 644 | if (updater != null) { // being updated |
| 645 | try { |
| 646 | updater.replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 647 | } |
| 648 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 649 | if (ex.getClass().equals(StructuredDocumentRegionManagementException.class)) { |
| 650 | Logger.traceException(TRACE_PARSER_MANAGEMENT_EXCEPTION, ex); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 651 | } |
| 652 | else { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 653 | Logger.logException(ex); |
| 654 | } |
| 655 | this.refresh = true; |
| 656 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 657 | } |
| 658 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 659 | setActive(null); |
| 660 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 661 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 662 | return; |
| 663 | } |
| 664 | XMLModelNotifier notifier = getModelNotifier(); |
| 665 | boolean isChanging = notifier.isChanging(); |
| 666 | if (!isChanging) |
| 667 | notifier.beginChanging(); |
| 668 | XMLModelParser parser = getModelParser(); |
| 669 | setActive(parser); |
| 670 | try { |
| 671 | parser.replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 672 | } |
| 673 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 674 | Logger.logException(ex); |
| 675 | this.refresh = true; |
| 676 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 677 | } |
| 678 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 679 | setActive(null); |
| 680 | if (!isChanging) { |
| 681 | notifier.endChanging(); |
| 682 | handleRefresh(); |
| 683 | } |
| 684 | } |
| 685 | |
| 686 | } |
| 687 | |
| 688 | /** |
| 689 | * regionChanged method |
| 690 | * |
| 691 | * @param structuredDocumentEvent |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 692 | */ |
| 693 | public void regionChanged(RegionChangedEvent event) { |
| 694 | if (event == null) |
| 695 | return; |
| 696 | IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion(); |
| 697 | if (flatNode == null) |
| 698 | return; |
| 699 | ITextRegion region = event.getRegion(); |
| 700 | if (region == null) |
| 701 | return; |
| 702 | XMLModelUpdater updater = getActiveUpdater(); |
| 703 | if (updater != null) { // being updated |
| 704 | try { |
| 705 | updater.changeRegion(flatNode, region); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 706 | } |
| 707 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 708 | Logger.logException(ex); |
| 709 | this.refresh = true; |
| 710 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 711 | } |
| 712 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 713 | setActive(null); |
| 714 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 715 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 716 | return; |
| 717 | } |
| 718 | XMLModelNotifier notifier = getModelNotifier(); |
| 719 | boolean isChanging = notifier.isChanging(); |
| 720 | if (!isChanging) |
| 721 | notifier.beginChanging(); |
| 722 | XMLModelParser parser = getModelParser(); |
| 723 | setActive(parser); |
| 724 | try { |
| 725 | parser.changeRegion(flatNode, region); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 726 | } |
| 727 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 728 | Logger.logException(ex); |
| 729 | this.refresh = true; |
| 730 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 731 | } |
| 732 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 733 | setActive(null); |
| 734 | if (!isChanging) { |
| 735 | notifier.endChanging(); |
| 736 | handleRefresh(); |
| 737 | } |
| 738 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 739 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 740 | } |
| 741 | |
| 742 | /** |
| 743 | * regionsReplaced method |
| 744 | * |
| 745 | * @param event |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 746 | */ |
| 747 | public void regionsReplaced(RegionsReplacedEvent event) { |
| 748 | if (event == null) |
| 749 | return; |
| 750 | IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion(); |
| 751 | if (flatNode == null) |
| 752 | return; |
| 753 | ITextRegionList oldRegions = event.getOldRegions(); |
| 754 | ITextRegionList newRegions = event.getNewRegions(); |
| 755 | if (oldRegions == null && newRegions == null) |
| 756 | return; |
| 757 | XMLModelUpdater updater = getActiveUpdater(); |
| 758 | if (updater != null) { // being updated |
| 759 | try { |
| 760 | updater.replaceRegions(flatNode, newRegions, oldRegions); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 761 | } |
| 762 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 763 | Logger.logException(ex); |
| 764 | this.refresh = true; |
| 765 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 766 | } |
| 767 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 768 | setActive(null); |
| 769 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 770 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 771 | return; |
| 772 | } |
| 773 | XMLModelNotifier notifier = getModelNotifier(); |
| 774 | boolean isChanging = notifier.isChanging(); |
| 775 | if (!isChanging) |
| 776 | notifier.beginChanging(); |
| 777 | XMLModelParser parser = getModelParser(); |
| 778 | setActive(parser); |
| 779 | try { |
| 780 | parser.replaceRegions(flatNode, newRegions, oldRegions); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 781 | } |
| 782 | catch (Exception ex) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 783 | Logger.logException(ex); |
| 784 | this.refresh = true; |
| 785 | handleRefresh(); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 786 | } |
| 787 | finally { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 788 | setActive(null); |
| 789 | if (!isChanging) { |
| 790 | notifier.endChanging(); |
| 791 | handleRefresh(); |
| 792 | } |
| 793 | } |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 794 | // checkForReinit(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 795 | } |
| 796 | |
| 797 | /** |
| 798 | */ |
| 799 | public void releaseFromEdit() { |
| 800 | if (!isShared()) { |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 801 | // this.document.releaseStyleSheets(); |
david_williams | b2de2de | 2005-07-16 16:44:06 +0000 | [diff] [blame] | 802 | // this.document.releaseDocumentType(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 803 | } |
| 804 | super.releaseFromEdit(); |
| 805 | } |
| 806 | |
| 807 | /** |
| 808 | */ |
| 809 | public void releaseFromRead() { |
| 810 | if (!isShared()) { |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 811 | // this.document.releaseStyleSheets(); |
david_williams | b2de2de | 2005-07-16 16:44:06 +0000 | [diff] [blame] | 812 | // this.document.releaseDocumentType(); |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 813 | } |
| 814 | super.releaseFromRead(); |
| 815 | } |
| 816 | |
| 817 | /** |
| 818 | */ |
| 819 | private void setActive(Object active) { |
| 820 | this.active = active; |
| 821 | // side effect |
| 822 | // when ever becomes active, besure tagNameCache is cleared |
| 823 | // (and not used) |
| 824 | if (active == null) { |
| 825 | document.activateTagNameCache(true); |
david_williams | 26f5ed4 | 2005-04-10 04:54:13 +0000 | [diff] [blame] | 826 | } |
| 827 | else { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 828 | document.activateTagNameCache(false); |
| 829 | } |
| 830 | |
| 831 | } |
| 832 | |
| 833 | /** |
| 834 | */ |
david_williams | 6a8e389 | 2005-04-05 05:21:12 +0000 | [diff] [blame] | 835 | public void setGenerator(ISourceGenerator generator) { |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 836 | this.generator = generator; |
| 837 | } |
| 838 | |
| 839 | /** |
| 840 | */ |
| 841 | public void setModelNotifier(XMLModelNotifier notifier) { |
| 842 | this.notifier = notifier; |
| 843 | } |
| 844 | |
| 845 | /** |
| 846 | */ |
| 847 | public void setModelParser(XMLModelParser parser) { |
| 848 | this.parser = parser; |
| 849 | } |
| 850 | |
| 851 | /** |
| 852 | */ |
| 853 | public void setModelUpdater(XMLModelUpdater updater) { |
| 854 | this.updater = updater; |
| 855 | } |
| 856 | |
| 857 | /** |
| 858 | * setStructuredDocument method |
| 859 | * |
| 860 | * @param structuredDocument |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 861 | */ |
| 862 | public void setStructuredDocument(IStructuredDocument structuredDocument) { |
david_williams | 4fe8531 | 2005-12-06 08:43:39 +0000 | [diff] [blame] | 863 | IStructuredDocument oldStructuredDocument = super.getStructuredDocument(); |
| 864 | if (structuredDocument == oldStructuredDocument) |
| 865 | return; // nothing to do |
| 866 | if (oldStructuredDocument != null) |
| 867 | oldStructuredDocument.removeDocumentChangingListener(this); |
| 868 | super.setStructuredDocument(structuredDocument); |
| 869 | if (structuredDocument != null) { |
| 870 | internalSetNewDocument(structuredDocument); |
| 871 | structuredDocument.addDocumentChangingListener(this); |
david_williams | b2de2de | 2005-07-16 16:44:06 +0000 | [diff] [blame] | 872 | } |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 873 | } |
| 874 | |
| 875 | /** |
| 876 | */ |
| 877 | protected void startTagChanged(Element element) { |
| 878 | if (element == null) |
| 879 | return; |
| 880 | if (getActiveParser() == null) { |
| 881 | XMLModelUpdater updater = getModelUpdater(); |
| 882 | setActive(updater); |
| 883 | updater.initialize(); |
| 884 | updater.changeStartTag(element); |
| 885 | setActive(null); |
| 886 | } |
| 887 | getModelNotifier().startTagChanged(element); |
| 888 | } |
| 889 | |
| 890 | /** |
| 891 | * valueChanged method |
| 892 | * |
| 893 | * @param node |
| 894 | * org.w3c.dom.Node |
| 895 | */ |
| 896 | protected void valueChanged(Node node) { |
| 897 | if (node == null) |
| 898 | return; |
| 899 | if (getActiveParser() == null) { |
| 900 | XMLModelUpdater updater = getModelUpdater(); |
| 901 | setActive(updater); |
| 902 | updater.initialize(); |
| 903 | updater.changeValue(node); |
| 904 | setActive(null); |
| 905 | } |
| 906 | getModelNotifier().valueChanged(node); |
| 907 | } |
david_williams | 838590b | 2005-04-14 14:05:08 +0000 | [diff] [blame] | 908 | |
| 909 | /** |
| 910 | * NOT IMPLEMENTED. Is defined here in preparation of DOM 3. |
| 911 | */ |
| 912 | public Object getFeature(String feature, String version) { |
nitind | edf5a44 | 2005-05-17 18:23:07 +0000 | [diff] [blame] | 913 | throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implemented in this version."); //$NON-NLS-1$ |
david_williams | 838590b | 2005-04-14 14:05:08 +0000 | [diff] [blame] | 914 | } |
david_williams | 9621348 | 2004-11-11 09:07:12 +0000 | [diff] [blame] | 915 | } |