diff options
Diffstat (limited to 'bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/XMLModelNotifierImpl.java')
-rw-r--r-- | bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/XMLModelNotifierImpl.java | 496 |
1 files changed, 0 insertions, 496 deletions
diff --git a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/XMLModelNotifierImpl.java b/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/XMLModelNotifierImpl.java deleted file mode 100644 index 75f89a089b..0000000000 --- a/bundles/org.eclipse.wst.xml.core/src/org/eclipse/wst/xml/core/internal/document/XMLModelNotifierImpl.java +++ /dev/null @@ -1,496 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2001, 2008 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Jens Lukowski/Innoopract - initial renaming/restructuring - * - *******************************************************************************/ -package org.eclipse.wst.xml.core.internal.document; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier; -import org.eclipse.wst.sse.core.internal.util.Debug; -import org.eclipse.wst.xml.core.internal.Logger; -import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - - -public class XMLModelNotifierImpl implements XMLModelNotifier { - - private static class NotifyEvent { - Object changedFeature; - boolean discarded; - Object newValue; - // note: don't initialize instance variables, since - // that causes double assignments, and lots of these are created. - INodeNotifier notifier; - Object oldValue; - int pos; - String reason; - int type; - int index; - - NotifyEvent(INodeNotifier notifier, int type, Object changedFeature, Object oldValue, Object newValue, int pos) { - this.notifier = notifier; - this.type = type; - this.changedFeature = changedFeature; - this.oldValue = oldValue; - this.newValue = newValue; - this.pos = pos; - this.reason = ""; //$NON-NLS-1$ - } - } - - private final static String ADDED_THEN_REMOVED = "Discard: Added then removed rule"; //$NON-NLS-1$ - private final static boolean fOptimizeDeferred = true; - private final static boolean fOptimizeDeferredAccordingToParentAdded = true; - private final static boolean fOptimizeDeferredAccordingToParentRemoved = true; - private final static String PARENT_IS_ADDED = "Disarded: Parent has just been added"; //$NON-NLS-1$ - /* start: for debugging only */ - private final static String PARENT_IS_REMOVED_TOO = "Discard: Parent was removed too"; //$NON-NLS-1$ - private final static String PARENT_IS_REPARENTED = "Not Discard: Parent was removed so this implies reparenting"; //$NON-NLS-1$ - private Node changedRoot = null; - - private boolean changing = false; - private boolean doingNewModel = false; - private List fEvents = null; - private boolean flushing = false; - - /** - */ - public XMLModelNotifierImpl() { - super(); - } - - /** - * attrReplaced method - * - * @param element - * org.w3c.dom.Element - * @param newAttr - * org.w3c.dom.Attr - * @param oldAttr - * org.w3c.dom.Attr - */ - public void attrReplaced(Element element, Attr newAttr, Attr oldAttr) { - if (element == null) - return; - Attr attr = null; - String oldValue = null; - String newValue = null; - if (oldAttr != null) { - attr = oldAttr; - oldValue = oldAttr.getValue(); - } - if (newAttr != null) { - attr = newAttr; - newValue = newAttr.getValue(); - } - IDOMNode notifier = (IDOMNode) element; - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, attr, oldValue, newValue, offset); - propertyChanged(notifier); - } - - /** - */ - public void beginChanging() { - this.changing = true; - } - - /** - */ - public void beginChanging(boolean newModel) { - beginChanging(); - this.doingNewModel = newModel; - } - - public void cancelPending() { - // we don't want to change the size of this array, since - // the array may be being processed, in the deferred notification - // loop, but we can signal that all - // should be discarded, so any remaining ones will be ignored. - if (this.fEvents != null) { - int size = fEvents.size(); - for (int i = 0; i < size; i++) { - NotifyEvent event = (NotifyEvent) fEvents.get(i); - event.discarded = true; - } - } - // this cancel is presumably being called as a function of - // "reinitiailization" so we can ignore changes to the - // old root, and changes to the new one will be triggered during - // reinitialization. - changedRoot = null; - } - - /** - * childReplaced method - * - * @param parentNode - * org.w3c.dom.Node - * @param newChild - * org.w3c.dom.Node - * @param oldChild - * org.w3c.dom.Node - */ - public void childReplaced(Node parentNode, Node newChild, Node oldChild) { - if (parentNode == null) - return; - IDOMNode notifier = (IDOMNode) parentNode; - int type = INodeNotifier.CHANGE; - if (newChild == null) - type = INodeNotifier.REMOVE; - else if (oldChild == null) - type = INodeNotifier.ADD; - int offset = notifier.getStartOffset(); - notify(notifier, type, oldChild, oldChild, newChild, offset); - structureChanged(notifier); - } - - public void editableChanged(Node node) { - if (node == null) - return; - IDOMNode notifier = (IDOMNode) node; - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, null, null, null, offset); - propertyChanged(notifier); - } - - /** - */ - public void endChanging() { - this.doingNewModel = false; - if (!this.changing) - return; // avoid nesting calls - notifyDeferred(); - if (this.changedRoot != null) { - notifyStructureChanged(this.changedRoot); - if (Debug.debugNotifyDeferred) { - String p = this.changedRoot.getNodeName(); - System.out.println("Deferred STRUCTURE_CHANGED: " + p); //$NON-NLS-1$ - } - this.changedRoot = null; - } - this.changing = false; - } - - /** - */ - public void endTagChanged(Element element) { - if (element == null) - return; - IDOMNode notifier = (IDOMNode) element; - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, null, null, null, offset); - propertyChanged(element); - } - - /** - */ - public boolean hasChanged() { - return (this.fEvents != null); - } - - /** - */ - public boolean isChanging() { - return this.changing; - } - - /** - */ - private void notify(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) { - if (notifier == null) - return; - if (this.changing && !this.flushing) { - // defer notification - if (this.fEvents == null) - this.fEvents = new ArrayList(); - // we do not defer anything if we are doing a new Model, - // except for the document event, since all others are - // trivial and not needed at that initial point. - // But even for that one document event, in the new model case, - // it is still important to defer it. - if ((!doingNewModel) || (((Node) notifier).getNodeType() == Node.DOCUMENT_NODE)) { - this.fEvents.add(new NotifyEvent(notifier, eventType, changedFeature, oldValue, newValue, pos)); - } - return; - } - try { - // Its important to "keep going" if exception occurs, since this - // notification - // comes in between "about to change" and "changed" events. We do - // log, however, - // since would indicate a program error. - notifier.notify(eventType, changedFeature, oldValue, newValue, pos); - } catch (Exception e) { - Logger.logException("A structured model client threw following exception during adapter notification (" + INodeNotifier.EVENT_TYPE_STRINGS[eventType] + " )", e); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - */ - private void notifyDeferred() { - if (this.fEvents == null) - return; - if (this.flushing) - return; - this.flushing = true; // force notification - int count = this.fEvents.size(); - - if (!doingNewModel && fOptimizeDeferred) { - Map notifyEvents = new HashMap(); - for (int i = 0; i < count; i++) { - NotifyEvent event = (NotifyEvent) this.fEvents.get(i); - if (event == null) - continue; // error - event.index = i; - if(event.type == INodeNotifier.REMOVE) { - addToMap(event.oldValue, event, notifyEvents); - } - if(event.type == INodeNotifier.ADD) { - addToMap(event.newValue, event, notifyEvents); - } - } - Iterator it = notifyEvents.values().iterator(); - while (it.hasNext()) { - NotifyEvent[] es = (NotifyEvent[]) it.next(); - for (int i = 0; i < es.length - 1; i++) { - NotifyEvent event = es[i]; - if(es[i].discarded) continue; - NotifyEvent next = es[i + 1]; - if(es[i].type == INodeNotifier.ADD && next.type == INodeNotifier.REMOVE) { - // Added then removed later, discard both - event.discarded = true; - next.discarded = true; - if (Debug.debugNotifyDeferred) { - event.reason = event.reason + ADDED_THEN_REMOVED + "(see " + next.index + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - next.reason = next.reason + ADDED_THEN_REMOVED + "(see " + event.index + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - } - } - for (int i = 0; i < count; i++) { - NotifyEvent event = (NotifyEvent) this.fEvents.get(i); - if (event == null) - continue; // error - if(event.discarded) continue; - if (event.notifier != null && fOptimizeDeferredAccordingToParentAdded) { - if (event.type == INodeNotifier.ADD) { - NotifyEvent[] es = (NotifyEvent[])notifyEvents.get(event.notifier); - if(es != null) for (int p = 0; p < es.length && es[p].index < event.index; p++) { - NotifyEvent prev = es[p]; - if (prev.type == INodeNotifier.REMOVE && prev.oldValue == event.notifier) { - // parent is reparented, do not discard - if (Debug.debugNotifyDeferred) { - event.reason = event.reason + PARENT_IS_REPARENTED + "(see " + prev.index + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - break; - } else if (prev.type == INodeNotifier.ADD && prev.newValue == event.notifier) { - // parent has been added, discard this - event.discarded = true; - if (Debug.debugNotifyDeferred) { - event.reason = event.reason + PARENT_IS_ADDED + "(see " + prev.index + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - break; - } - } - } - } - if(event.discarded) continue; - if (event.notifier != null && fOptimizeDeferredAccordingToParentRemoved) { - if (event.type == INodeNotifier.REMOVE) { - NotifyEvent[] es = (NotifyEvent[])notifyEvents.get(event.notifier); - if(es != null) for (int n = 0; n < es.length; n++) { - NotifyEvent next = es[n]; - if(next.index > event.index && next.type == INodeNotifier.REMOVE) { - if (next.oldValue == event.notifier) { - // parent will be removed, discard this - event.discarded = true; - if (Debug.debugNotifyDeferred) { - event.reason = event.reason + PARENT_IS_REMOVED_TOO + "(see " + next.index + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - } - break; - } - } - } - } - } - if(event.discarded) continue; - } - } - for (int i = 0; i < count; i++) { - NotifyEvent event = (NotifyEvent) this.fEvents.get(i); - if (event == null) - continue; // error - if(event.discarded) continue; - notify(event.notifier, event.type, event.changedFeature, event.oldValue, event.newValue, event.pos); - } - if (Debug.debugNotifyDeferred) { - for (int l = 0; l < count; l++) { - NotifyEvent event = (NotifyEvent) this.fEvents.get(l); - Object o = null; - String t = null; - if (event.type == INodeNotifier.ADD) { - o = event.newValue; - t = " + "; //$NON-NLS-1$ - } else if (event.type == INodeNotifier.REMOVE) { - o = event.oldValue; - t = " - "; //$NON-NLS-1$ - } - if (o instanceof Element) { - String p = ((Node) event.notifier).getNodeName(); - String c = ((Node) o).getNodeName(); - String d = (event.discarded ? "! " : " "); //$NON-NLS-1$ //$NON-NLS-2$ - System.out.println(d + p + t + c); - } - } - } - this.flushing = false; - this.fEvents = null; - } - - void addToMap(Object o, NotifyEvent event, Map map) { - if(o == null) return; - Object x = map.get(o); - if(x == null) { - map.put(o, new NotifyEvent[]{event}); - } else { - NotifyEvent[] es = (NotifyEvent[])x; - NotifyEvent[] es2 = new NotifyEvent[es.length + 1]; - System.arraycopy(es, 0, es2, 0, es.length); - es2[es.length] = event; - map.put(o, es2); - } - } - - /** - */ - private void notifyStructureChanged(Node root) { - if (root == null) - return; - INodeNotifier notifier = (INodeNotifier) root; - try { - // Its important to "keep going" if exception occurs, since this - // notification - // comes in between "about to change" and "changed" events. We do - // log, however, - // since would indicate a program error. - notifier.notify(INodeNotifier.STRUCTURE_CHANGED, null, null, null, -1); - } catch (Exception e) { - Logger.logException("A structured model client threw following exception during adapter notification (" + INodeNotifier.EVENT_TYPE_STRINGS[INodeNotifier.STRUCTURE_CHANGED] + " )", e); //$NON-NLS-1$ //$NON-NLS-2$ - } - - } - - /** - */ - public void propertyChanged(Node node) { - } - - /** - * @param node - */ - private void setCommonRootIfNeeded(Node node) { - // defer notification - if (this.changedRoot == null) { - this.changedRoot = node; - } else { - // tiny optimization: if previous commonAncestor (changedRoot) is - // already 'document', - // or if already equal to this 'node', - // then no need to re-calculate - if (changedRoot.getNodeType() != Node.DOCUMENT_NODE && changedRoot != node) { - Node common = ((NodeImpl) this.changedRoot).getCommonAncestor(node); - if (common != null) - this.changedRoot = common; - else - this.changedRoot = node; - } - } - } - - /** - */ - public void startTagChanged(Element element) { - if (element == null) - return; - IDOMNode notifier = (IDOMNode) element; - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, null, null, null, offset); - propertyChanged(element); - } - - /** - */ - public void structureChanged(Node node) { - if (node == null) - return; - if (isChanging()) { - setCommonRootIfNeeded(node); - if (Debug.debugNotifyDeferred) { - String p = this.changedRoot.getNodeName(); - System.out.println("requested STRUCTURE_CHANGED: " + p); //$NON-NLS-1$ - } - return; - } - if (Debug.debugNotifyDeferred) { - String p = node.getNodeName(); - System.out.println("STRUCTURE_CHANGED: " + p); //$NON-NLS-1$ - } - notifyStructureChanged(node); - } - - /** - * valueChanged method - * - * @param node - * org.w3c.dom.Node - */ - public void valueChanged(Node node) { - if (node == null) - return; - IDOMNode notifier = null; - if (node.getNodeType() == Node.ATTRIBUTE_NODE) { - Attr attr = (Attr) node; - notifier = (IDOMNode) attr.getOwnerElement(); - // TODO_dmw: experimental: changed 06/29/2004 to send "structuure - // changed" even for attribute value changes - // there are pros and cons to considering attribute value - // "structure changed". Will (re)consider - // setCommonRootIfNeeded(notifier); - if (notifier == null) - return; - String value = attr.getValue(); - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, attr, null, value, offset); - } else { - // note: we do not send structured changed event for content - // changed - notifier = (IDOMNode) node; - String value = node.getNodeValue(); - int offset = notifier.getStartOffset(); - notify(notifier, INodeNotifier.CHANGE, null, null, value, offset); - if (node.getNodeType() != Node.ELEMENT_NODE) { - IDOMNode parent = (IDOMNode) node.getParentNode(); - if (parent != null) { - notify(parent, INodeNotifier.CONTENT_CHANGED, node, null, value, offset); - } - } - } - propertyChanged(notifier); - } -} |