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: XMLReconcileStep.java,v 1.2 2006-10-21 23:14:13 pombredanne Exp $
14 package net.sourceforge.phpeclipse.xml.ui.internal.text;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.List;
20 import net.sourceforge.phpeclipse.xml.core.model.IXMLDocument;
21 import net.sourceforge.phpeclipse.xml.core.parser.IProblem;
22 import net.sourceforge.phpeclipse.xml.core.parser.IProblemCollector;
23 import net.sourceforge.phpeclipse.xml.ui.internal.editor.XMLDocumentProvider;
25 import org.eclipse.core.resources.IFile;
26 import org.eclipse.jface.text.IRegion;
27 import org.eclipse.jface.text.Position;
28 import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
29 import org.eclipse.jface.text.reconciler.DirtyRegion;
30 import org.eclipse.jface.text.reconciler.IReconcilableModel;
31 import org.eclipse.jface.text.reconciler.IReconcileResult;
32 import org.eclipse.jface.text.reconciler.IReconcileStep;
33 import org.eclipse.jface.text.source.Annotation;
34 import org.eclipse.ui.IEditorInput;
35 import org.eclipse.ui.IFileEditorInput;
36 import org.eclipse.ui.texteditor.IDocumentProvider;
37 import org.eclipse.ui.texteditor.ITextEditor;
40 * Implementation of a reconcile step for building the XML parse tree on changes
41 * to the editor content.
43 public class XMLReconcileStep extends AbstractReconcileStep {
45 // Inner Classes -----------------------------------------------------------
48 * Adapts an <code>IXMLDocument</code> to the
49 * <code>IReconcilableModel</code> interface.
51 private class XMLDocumentAdapter implements IReconcilableModel {
52 private IXMLDocument document;
54 public XMLDocumentAdapter(IXMLDocument document) {
55 this.document = document;
58 public IXMLDocument getDocument() {
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 {
70 * The list of problems added to this collector.
72 private List collectedProblems = new ArrayList();
75 * @see IProblemCollector#addProblem(IProblem)
77 public void addProblem(IProblem problem) {
78 collectedProblems.add(problem);
82 * Returns the list of problems collected while the CSS source has been
83 * parsed, in the order they were reported. The list returned is
86 * @return the list of collected problems (of type {@link IProblem})
88 public List getProblems() {
89 return Collections.unmodifiableList(collectedProblems);
94 * Adapter that adapts an {@link IProblem} to an {@link Annotation}.
96 private class ProblemAdapter extends AnnotationAdapter {
97 private IProblem problem;
99 private Position position;
101 public ProblemAdapter(IProblem problem) {
102 this.problem = problem;
105 public Position getPosition() {
106 if (position == null) {
107 position = createPositionFromProblem();
113 public Annotation createAnnotation() {
114 int start = problem.getSourceStart();
119 int length = problem.getSourceEnd() - start + 1;
125 if (problem.isWarning()) {
126 type = XMLAnnotation.TYPE_ERROR;
127 } else if (problem.isError()) {
128 type = XMLAnnotation.TYPE_WARNING;
130 type = XMLAnnotation.TYPE_INFO;
133 return new XMLAnnotation(type, false, problem.getMessage());
136 private Position createPositionFromProblem() {
137 int start = problem.getSourceStart();
142 int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
147 return new Position(start, length);
152 // Instance Variables ------------------------------------------------------
154 private ITextEditor editor;
156 private XMLDocumentAdapter xmlDocumentAdapter;
158 // Constructors ------------------------------------------------------------
161 * Default constructor.
163 public XMLReconcileStep(ITextEditor editor) {
164 this.editor = editor;
166 xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
173 * the step to add to the pipe
175 * the associated text editor
177 public XMLReconcileStep(IReconcileStep step, ITextEditor editor) {
180 this.editor = editor;
182 xmlDocumentAdapter = new XMLDocumentAdapter(getXMLDocument());
185 // AbstractReconcileStep Implementation ------------------------------------
188 * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
190 protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion,
192 IXMLDocument model = xmlDocumentAdapter.getDocument();
194 IEditorInput editorInput = null;
196 if (editor != null) {
197 editorInput = editor.getEditorInput();
200 if (editorInput instanceof IFileEditorInput)
201 file = ((IFileEditorInput) editorInput).getFile();
202 ProblemCollector problemCollector = new ProblemCollector();
203 model.reconcile(problemCollector, file);
205 List problems = problemCollector.getProblems();
206 IReconcileResult[] retVal = new IReconcileResult[problems.size()];
207 for (int i = 0; i < problems.size(); i++) {
208 IProblem problem = (IProblem) problems.get(i);
209 retVal[i] = new ProblemAdapter(problem);
216 * @see AbstractReconcileStep#getModel()
218 public IReconcilableModel getModel() {
219 return xmlDocumentAdapter;
222 // Private Methods Implementation ------------------------------------------
225 * Retrieve the style sheet associated with the editor input.
227 private IXMLDocument getXMLDocument() {
228 IDocumentProvider documentProvider = editor.getDocumentProvider();
229 if (documentProvider instanceof XMLDocumentProvider) {
230 XMLDocumentProvider xmlDocumentProvider = (XMLDocumentProvider) documentProvider;
231 return xmlDocumentProvider.getModel(editor.getEditorInput());