diff options
author | vbaciu | 2009-04-23 06:44:33 +0000 |
---|---|---|
committer | vbaciu | 2009-04-23 06:44:33 +0000 |
commit | 339e43061431083da95b2b0674c27527b19b655a (patch) | |
tree | bc6725ed64dd7ca955d6c9e9851a8bce8774948f /bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse | |
parent | c7451ef77a24e23abf5ed34a6f969201bf410646 (diff) | |
download | webtools.sourceediting-339e43061431083da95b2b0674c27527b19b655a.tar.gz webtools.sourceediting-339e43061431083da95b2b0674c27527b19b655a.tar.xz webtools.sourceediting-339e43061431083da95b2b0674c27527b19b655a.zip |
[156564] Improve performance when editing large XML Schema documents
Diffstat (limited to 'bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse')
2 files changed, 209 insertions, 4 deletions
diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelDelayedReconciler.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelDelayedReconciler.java new file mode 100644 index 0000000000..02b7b6d76b --- /dev/null +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelDelayedReconciler.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + *******************************************************************************/ +package org.eclipse.wst.xsd.ui.internal.text; + + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; +import org.eclipse.wst.xsd.ui.internal.editor.InternalXSDMultiPageEditor; +import org.eclipse.xsd.XSDConcreteComponent; +import org.eclipse.xsd.XSDSchema; +import org.w3c.dom.Element; + + +/** + * Provides delayed reconciliation between the SSE DOM and the XSD EMF model. + * Changes in the DOM are queued and processed by a UI job. When a new request + * comes in, the current run is cancelled, the new request is added to the queue, + * then the job is re-scheduled. + */ +public class XSDModelDelayedReconciler +{ + /** + * The model reconciler job. + */ + private ReconcilerJob reconcilerJob; + + /** + * The time in milliseconds to delay updating the EMF model. + */ + private static final int DELAY = 300; + + /** + * The elements to reconcile. + */ + private List elementsToReconcile = new ArrayList(); + + /** + * Determines if the delayed reconciler should kick in. + */ + public boolean shouldDelay(XSDSchema schema) + { + boolean shouldDelay = false; + + // The delayed reconciler should not be used when the editor is in graphical editing mode. + + IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + IWorkbenchPage workbenchPage = workbenchWindow.getActivePage(); + IEditorPart editorPart = workbenchPage != null ? workbenchPage.getActiveEditor() : null; + if (editorPart != null && editorPart instanceof InternalXSDMultiPageEditor) + { + InternalXSDMultiPageEditor xsdEditor = (InternalXSDMultiPageEditor)editorPart; + shouldDelay = xsdEditor.isSourcePageActive(); + } + + return shouldDelay; + } + + /** + * Updates the XSD EMF component corresponding to the DOM element. + * + * @param element the changed element. + * @param schema the containing schema. + */ + public void elementChanged(Element element, XSDSchema schema) + { + synchronized (elementsToReconcile) + { + // The number of elements should be small so a linear search should be fine. + + if (!elementsToReconcile.contains(element)) + { + elementsToReconcile.add(element); + } + + if (reconcilerJob == null) + { + reconcilerJob = new ReconcilerJob(schema); + } + + reconcilerJob.schedule(DELAY); + } + } + + /** + * A UI job used to reconcile the XSD EMF model with the associated SSE DOM. + */ + class ReconcilerJob extends UIJob + { + /** + * The target schema. + */ + private XSDSchema schema; + + /** + * The number of times allowed to wake up and do nothing. + */ + private static final int MAX_INACTIVE_COUNT = 10; + + /** + * The job will terminate once this counter reaches MAX_INACTIVE_COUNT. + */ + private int timesAwakeAndIdle = 0; + + /** + * Constructs the reconciler job and configures some of its properties. + */ + public ReconcilerJob(XSDSchema schema) + { + super("Reconciling the XSD EMF model"); //$NON-NLS-1$ + setSystem(true); + setPriority(Job.LONG); + this.schema = schema; + } + + public IStatus runInUIThread(IProgressMonitor monitor) + { + if (monitor.isCanceled()) + { + return Status.CANCEL_STATUS; + } + + Element[] elements = null; + + synchronized (elementsToReconcile) + { + if (!elementsToReconcile.isEmpty()) + { + elements = new Element[elementsToReconcile.size()]; + elementsToReconcile.toArray(elements); + elementsToReconcile.clear(); + } + else + { + if (shouldTerminate()) + { + reconcilerJob = null; + return Status.CANCEL_STATUS; + } + } + } + + reconcile(elements); + + schedule(DELAY); + + return Status.OK_STATUS; + } + + private void reconcile(Element[] modifiedElements) + { + if (modifiedElements != null) + { + for (int index = 0; index < modifiedElements.length; index++) + { + Element modifiedElement = modifiedElements[index]; + + reconcile(modifiedElement); + } + } + } + + private void reconcile(Element modifiedElement) + { + if (modifiedElement != null) + { + XSDConcreteComponent concreteComponent = schema.getCorrespondingComponent(modifiedElement); + concreteComponent.elementChanged(modifiedElement); + } + } + + private boolean shouldTerminate() + { + return timesAwakeAndIdle++ == MAX_INACTIVE_COUNT; + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelReconcileAdapter.java b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelReconcileAdapter.java index 80a6db576b..44b0626f8b 100644 --- a/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelReconcileAdapter.java +++ b/bundles/org.eclipse.wst.xsd.ui/src-adt-xsd/org/eclipse/wst/xsd/ui/internal/text/XSDModelReconcileAdapter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 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 @@ -24,11 +24,13 @@ import org.w3c.dom.Node; public class XSDModelReconcileAdapter extends ModelReconcileAdapter { protected XSDSchema schema; + protected XSDModelDelayedReconciler delayedReconciler; public XSDModelReconcileAdapter(Document document, XSDSchema schema) { super(document); this.schema = schema; + this.delayedReconciler = new XSDModelDelayedReconciler(); } protected void handleNodeChanged(Node node) @@ -50,9 +52,17 @@ public class XSDModelReconcileAdapter extends ModelReconcileAdapter if (node instanceof Element) { - XSDConcreteComponent concreteComponent = schema.getCorrespondingComponent(node); - concreteComponent.elementChanged((Element)node); - } + Element element = (Element) node; + if (delayedReconciler.shouldDelay(schema)) + { + delayedReconciler.elementChanged(element, schema); + } + else + { + XSDConcreteComponent concreteComponent = schema.getCorrespondingComponent(node); + concreteComponent.elementChanged(element); + } + } else if (node instanceof Document) { // The document changed so we may need to fix up the |