intial source from ttp://www.sf.net/projects/wdte
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.css.ui / src / net / sourceforge / phpeclipse / css / ui / internal / text / CssReconcilingStrategy.java
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcilingStrategy.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/CssReconcilingStrategy.java
new file mode 100644 (file)
index 0000000..c1ab039
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Christopher Lenz - initial API and implementation
+ * 
+ * $Id: CssReconcilingStrategy.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.text;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcileResult;
+import org.eclipse.jface.text.reconciler.IReconcileStep;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * Reconciling strategy for CSS style sheets. This class is responsible for 
+ * keeping the parsed model in sync with the text.
+ */
+public class CssReconcilingStrategy
+       implements IReconcilingStrategy, IReconcilingStrategyExtension {
+
+       // Instance Variables ------------------------------------------------------
+
+       /**
+        * The associated text editor.
+        */
+       private ITextEditor editor;
+
+       /**
+        * A progress monitor that should be used for long-running operations.
+        */
+       IProgressMonitor progressMonitor;
+
+       /**
+        * The first (and only) reconcile step is the parsing of the style sheet.
+        */
+       private IReconcileStep firstStep;
+
+       // Constructors ------------------------------------------------------------
+
+       public CssReconcilingStrategy(ITextEditor editor) {
+               this.editor = editor;
+               firstStep = new CssReconcileStep(editor);
+       }
+
+       // IReconcilingStrategy Implementation -------------------------------------
+
+       /**
+        * @see IReconcilingStrategy#reconcile(DirtyRegion, IRegion)
+        */
+       public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(dirtyRegion, subRegion));
+       }
+
+       /**
+        * @see IReconcilingStrategy#reconcile(IRegion)
+        */
+       public void reconcile(IRegion partition) {
+               removeTemporaryAnnotations();
+               process(firstStep.reconcile(partition));
+       }
+
+       /**
+        * @see IReconcilingStrategy#setDocument(IDocument)
+        */
+       public void setDocument(IDocument document) {
+               // FIXME
+               firstStep.setInputModel(null); //new DocumentAdapter(document);
+       }
+
+       // IReconcilingStrategyExtension Implementation ----------------------------
+
+       /**
+        * @see IReconcilingStrategyExtension#initialReconcile()
+        */
+       public void initialReconcile() {
+               process(firstStep.reconcile(null));
+       }
+
+       /**
+        * @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
+        */
+       public void setProgressMonitor(IProgressMonitor monitor) {
+               firstStep.setProgressMonitor(monitor);
+               progressMonitor = monitor;
+       }
+
+       // Private Methods ---------------------------------------------------------
+
+       /**
+        * Returns the annotation model for the editor input.
+        * 
+        * @return the annotation model
+        */
+       IAnnotationModel getAnnotationModel()  {
+               IEditorInput input = editor.getEditorInput();
+               return editor.getDocumentProvider().getAnnotationModel(input);
+       }
+
+       /**
+        * Adds results of the reconcilation to the annotation model.
+        */
+       private void process(final IReconcileResult[] results) {
+               if (results == null) {
+                       return;
+               }
+
+               IRunnableWithProgress runnable = new WorkspaceModifyOperation() {
+                       protected void execute(IProgressMonitor monitor) {
+                               for (int i = 0; i < results.length; i++) {
+                                       if ((progressMonitor != null)
+                                                       && (progressMonitor.isCanceled())) {
+                                               return;
+                                       }
+
+                                       if (!(results[i] instanceof AnnotationAdapter)) {
+                                               continue;
+                                       }
+
+                                       AnnotationAdapter result = (AnnotationAdapter) results[i];
+                                       Position pos = result.getPosition();
+                                       Annotation annotation = result.createAnnotation();
+                                       getAnnotationModel().addAnnotation(annotation, pos);
+                               }
+                       }
+               };
+
+               try {
+                       runnable.run(null);
+               } catch (InvocationTargetException e) {
+                       CssUI.log(e);
+               } catch (InterruptedException e) {
+                       CssUI.log(e);
+               }
+
+               if (editor instanceof IReconcilingParticipant) {
+                       ((IReconcilingParticipant) editor).reconciled();
+               }
+       }
+
+       /*
+        * TODO A "real" implementation must be smarter, i.e. don't remove and add
+        *      the annotations which are the same.
+        */ 
+       private void removeTemporaryAnnotations() {
+               Iterator i = getAnnotationModel().getAnnotationIterator();
+               while (i.hasNext())  {
+                       Annotation annotation = (Annotation) i.next();
+                       if (!annotation.isPersistent()) {
+                               getAnnotationModel().removeAnnotation(annotation);
+                       }
+               }
+       }
+}