2 * Copyright (c) 2003-2004 Christopher Lenz and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * Christopher Lenz - initial API and implementation
11 * $Id: XMLReconcilingStrategy.java,v 1.3 2006-10-21 23:14:13 pombredanne Exp $
13 package net.sourceforge.phpeclipse.xml.ui.internal.text;
15 import java.lang.reflect.InvocationTargetException;
16 import java.util.Iterator;
18 import net.sourceforge.phpeclipse.ui.text.IReconcilingParticipant;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.jface.operation.IRunnableWithProgress;
22 import org.eclipse.jface.text.IDocument;
23 import org.eclipse.jface.text.IRegion;
24 import org.eclipse.jface.text.Position;
25 import org.eclipse.jface.text.reconciler.DirtyRegion;
26 import org.eclipse.jface.text.reconciler.IReconcileResult;
27 import org.eclipse.jface.text.reconciler.IReconcileStep;
28 import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
29 import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
30 import org.eclipse.jface.text.source.Annotation;
31 import org.eclipse.jface.text.source.IAnnotationModel;
32 import org.eclipse.ui.IEditorInput;
33 import org.eclipse.ui.actions.WorkspaceModifyOperation;
34 import org.eclipse.ui.texteditor.ITextEditor;
37 * Reconciling strategy for XML document. This class is responsible for keeping
38 * the parsed model in sync with the text.
40 public class XMLReconcilingStrategy implements IReconcilingStrategy,
41 IReconcilingStrategyExtension {
43 // Instance Variables ------------------------------------------------------
46 * The associated text editor.
48 private ITextEditor editor;
51 * A progress monitor that should be used for long-running operations.
53 IProgressMonitor progressMonitor;
56 * The first (and only) reconcile step is the parsing of the style sheet.
58 private IReconcileStep firstStep;
60 // Constructors ------------------------------------------------------------
62 public XMLReconcilingStrategy(ITextEditor editor) {
64 firstStep = new XMLReconcileStep(editor);
67 // IReconcilingStrategy Implementation -------------------------------------
70 * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
72 public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
73 removeTemporaryAnnotations();
74 process(firstStep.reconcile(dirtyRegion, subRegion));
78 * @see IReconcilingStrategy#reconcile(IRegion)
80 public void reconcile(IRegion partition) {
81 removeTemporaryAnnotations();
82 process(firstStep.reconcile(partition));
86 * @see IReconcilingStrategy#setDocument(IDocument)
88 public void setDocument(IDocument document) {
90 firstStep.setInputModel(null); // new DocumentAdapter(document);
93 // IReconcilingStrategyExtension Implementation ----------------------------
96 * @see IReconcilingStrategyExtension#initialReconcile()
98 public void initialReconcile() {
99 process(firstStep.reconcile(null));
103 * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
105 public void setProgressMonitor(IProgressMonitor monitor) {
106 firstStep.setProgressMonitor(monitor);
107 progressMonitor = monitor;
110 // Private Methods ---------------------------------------------------------
113 * Returns the annotation model for the editor input.
115 * @return the annotation model
117 IAnnotationModel getAnnotationModel() {
118 IEditorInput input = editor.getEditorInput();
119 return editor.getDocumentProvider().getAnnotationModel(input);
123 * Adds results of the reconcilation to the annotation model.
125 private void process(final IReconcileResult[] results) {
126 if (results == null) {
130 IRunnableWithProgress runnable = new WorkspaceModifyOperation() {
131 protected void execute(IProgressMonitor monitor) {
132 for (int i = 0; i < results.length; i++) {
133 if ((progressMonitor != null)
134 && (progressMonitor.isCanceled())) {
138 if (results[i] instanceof AnnotationAdapter) {
139 AnnotationAdapter result = (AnnotationAdapter) results[i];
140 Position pos = result.getPosition();
141 Annotation annotation = result.createAnnotation();
142 getAnnotationModel().addAnnotation(annotation, pos);
150 } catch (InvocationTargetException e) {
152 } catch (InterruptedException e) {
156 if (editor instanceof IReconcilingParticipant) {
157 ((IReconcilingParticipant) editor).reconciled();
162 * TODO A "real" implementation must be smarter, i.e. don't remove and add
163 * the annotations which are the same.
165 private void removeTemporaryAnnotations() {
166 Iterator i = getAnnotationModel().getAnnotationIterator();
167 while (i.hasNext()) {
168 Annotation annotation = (Annotation) i.next();
169 if (!annotation.isPersistent()) {
170 getAnnotationModel().removeAnnotation(annotation);