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: CssReconcileStep.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
14 package net.sourceforge.phpeclipse.css.ui.internal.text;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.List;
20 import net.sourceforge.phpeclipse.css.core.model.IStyleSheet;
21 import net.sourceforge.phpeclipse.css.core.parser.IProblem;
22 import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector;
23 import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
24 import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
25 import net.sourceforge.phpeclipse.css.ui.internal.CssDocumentProvider;
27 import org.eclipse.jface.text.IRegion;
28 import org.eclipse.jface.text.Position;
29 import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
30 import org.eclipse.jface.text.reconciler.DirtyRegion;
31 import org.eclipse.jface.text.reconciler.IReconcilableModel;
32 import org.eclipse.jface.text.reconciler.IReconcileResult;
33 import org.eclipse.jface.text.reconciler.IReconcileStep;
34 import org.eclipse.jface.text.source.Annotation;
35 import org.eclipse.ui.texteditor.IDocumentProvider;
36 import org.eclipse.ui.texteditor.ITextEditor;
39 * Implementation of a reconcile step for building the CSS parse tree on changes
40 * to the editor content.
42 public class CssReconcileStep extends AbstractReconcileStep {
44 // Inner Classes -----------------------------------------------------------
47 * Adapts an <code>IStyleSheet</code> to the <code>IReconcilableModel</code>
50 private class StyleSheetAdapter implements IReconcilableModel {
52 private IStyleSheet styleSheet;
54 public StyleSheetAdapter(IStyleSheet styleSheet) {
55 this.styleSheet = styleSheet;
58 public IStyleSheet getStyleSheet() {
65 * Implementation of the problem collector interface for creating problem
66 * annotations when there are problems parsing the style sheet.
68 private class ProblemCollector implements IProblemCollector {
71 * The list of problems added to this collector.
73 private List collectedProblems = new ArrayList();
76 * @see IProblemCollector#addProblem(IProblem)
78 public void addProblem(IProblem problem) {
79 collectedProblems.add(problem);
83 * Returns the list of problems collected while the CSS source has been
84 * parsed, in the order they were reported. The list returned is
87 * @return the list of collected problems (of type {@link IProblem})
89 public List getProblems() {
90 return Collections.unmodifiableList(collectedProblems);
96 * Adapter that adapts an {@link IProblem} to an {@link Annotation}.
98 private class ProblemAdapter extends AnnotationAdapter {
100 private IProblem problem;
101 private Position position;
103 ProblemAdapter(IProblem problem) {
104 this.problem = problem;
107 public Position getPosition() {
108 if (position == null) {
109 position = createPositionFromProblem();
114 public Annotation createAnnotation() {
115 int start = problem.getSourceStart();
119 int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
124 if (problem.isWarning()) {
125 type = "org.eclipse.ui.workbench.texteditor.warning"; //$NON-NLS-1$
126 } else if (problem.isError()) {
127 type = "org.eclipse.ui.workbench.texteditor.error"; //$NON-NLS-1$
129 return new Annotation(type, false, problem.getMessage());
132 private Position createPositionFromProblem() {
133 int start = problem.getSourceStart();
137 int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
141 return new Position(start, length);
146 // Instance Variables ------------------------------------------------------
148 private ITextEditor editor;
150 private StyleSheetAdapter styleSheetAdapter;
152 // Constructors ------------------------------------------------------------
155 * Default constructor.
157 public CssReconcileStep(ITextEditor editor) {
158 this.editor = editor;
159 styleSheetAdapter = new StyleSheetAdapter(getStyleSheet());
165 * @param step the step to add to the pipe
166 * @param editor the associated text editor
168 public CssReconcileStep(IReconcileStep step, ITextEditor editor) {
170 this.editor = editor;
171 styleSheetAdapter = new StyleSheetAdapter(getStyleSheet());
174 // AbstractReconcileStep Implementation ------------------------------------
177 * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
179 protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion,
181 IStyleSheet styleSheet = styleSheetAdapter.getStyleSheet();
182 ProblemCollector problemCollector = new ProblemCollector();
184 styleSheet.reconcile(problemCollector);
185 } catch (LexicalErrorException e) {
186 // Already reported to the problem collector
187 } catch (SyntaxErrorException e) {
188 // Already reported to the problem collector
190 List problems = problemCollector.getProblems();
191 IReconcileResult[] retVal = new IReconcileResult[problems.size()];
192 for (int i = 0; i < problems.size(); i++) {
193 IProblem problem = (IProblem) problems.get(i);
194 retVal[i] = new ProblemAdapter(problem);
200 * @see AbstractReconcileStep#getModel()
202 public IReconcilableModel getModel() {
203 return styleSheetAdapter;
206 // Private Methods Implementation ------------------------------------------
209 * Retrieve the style sheet associated with the editor input.
211 private IStyleSheet getStyleSheet() {
212 IDocumentProvider documentProvider = editor.getDocumentProvider();
213 if (documentProvider instanceof CssDocumentProvider) {
214 CssDocumentProvider cssDocumentProvider = (CssDocumentProvider)
216 return cssDocumentProvider.getStyleSheet(editor.getEditorInput());