KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > text > edits > TextEditProcessor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.text.edits;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18
19 import org.eclipse.jface.text.BadLocationException;
20 import org.eclipse.jface.text.IDocument;
21
22 /**
23  * A <code>TextEditProcessor</code> manages a set of edits and applies
24  * them as a whole to an <code>IDocument</code>.
25  * <p>
26  * This class isn't intended to be subclassed.</p>
27  *
28  * @see org.eclipse.text.edits.TextEdit#apply(IDocument)
29  *
30  * @since 3.0
31  */

32 public class TextEditProcessor {
33
34     private IDocument fDocument;
35     private TextEdit fRoot;
36     private int fStyle;
37
38     private boolean fChecked;
39     private MalformedTreeException fException;
40
41     private List JavaDoc fSourceEdits;
42
43     /**
44      * Constructs a new edit processor for the given
45      * document.
46      *
47      * @param document the document to manipulate
48      * @param root the root of the text edit tree describing
49      * the modifications. By passing a text edit a a text edit
50      * processor the ownership of the edit is transfered to the
51      * text edit processors. Clients must not modify the edit
52      * (e.g adding new children) any longer.
53      *
54      * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS})
55      */

56     public TextEditProcessor(IDocument document, TextEdit root, int style) {
57         this(document, root, style, false);
58     }
59
60     private TextEditProcessor(IDocument document, TextEdit root, int style, boolean secondary) {
61         Assert.isNotNull(document);
62         Assert.isNotNull(root);
63         fDocument= document;
64         fRoot= root;
65         if (fRoot instanceof MultiTextEdit)
66             ((MultiTextEdit)fRoot).defineRegion(0);
67         fStyle= style;
68         if (secondary) {
69             fChecked= true;
70             fSourceEdits= new ArrayList JavaDoc();
71         }
72     }
73
74     /**
75      * Creates a special internal processor used to during source computation inside
76      * move source and copy source edits
77      *
78      * @param document the document to be manipulated
79      * @param root the edit tree
80      * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS})
81      * @return a secondary text edit processor
82      * @since 3.1
83      */

84     static TextEditProcessor createSourceComputationProcessor(IDocument document, TextEdit root, int style) {
85         return new TextEditProcessor(document, root, style, true);
86     }
87
88     /**
89      * Returns the document to be manipulated.
90      *
91      * @return the document
92      */

93     public IDocument getDocument() {
94         return fDocument;
95     }
96
97     /**
98      * Returns the edit processor's root edit.
99      *
100      * @return the processor's root edit
101      */

102     public TextEdit getRoot() {
103         return fRoot;
104     }
105
106     /**
107      * Returns the style bits of the text edit processor
108      *
109      * @return the style bits
110      * @see TextEdit#CREATE_UNDO
111      * @see TextEdit#UPDATE_REGIONS
112      */

113     public int getStyle() {
114         return fStyle;
115     }
116
117     /**
118      * Checks if the processor can execute all its edits.
119      *
120      * @return <code>true</code> if the edits can be executed. Return <code>false
121      * </code>otherwise. One major reason why edits cannot be executed are wrong
122      * offset or length values of edits. Calling perform in this case will very
123      * likely end in a <code>BadLocationException</code>.
124      */

125     public boolean canPerformEdits() {
126         try {
127             fRoot.dispatchCheckIntegrity(this);
128             fChecked= true;
129         } catch (MalformedTreeException e) {
130             fException= e;
131             return false;
132         }
133         return true;
134     }
135
136     /**
137      * Executes the text edits.
138      *
139      * @return an object representing the undo of the executed edits
140      * @exception MalformedTreeException is thrown if the edit tree isn't
141      * in a valid state. This exception is thrown before any edit is executed.
142      * So the document is still in its original state.
143      * @exception BadLocationException is thrown if one of the edits in the
144      * tree can't be executed. The state of the document is undefined if this
145      * exception is thrown.
146      */

147     public UndoEdit performEdits() throws MalformedTreeException, BadLocationException {
148         if (!fChecked) {
149             fRoot.dispatchCheckIntegrity(this);
150         } else {
151             if (fException != null)
152                 throw fException;
153         }
154         return fRoot.dispatchPerformEdits(this);
155     }
156
157     /*
158      * Class isn't intended to be sub-lcassed
159      */

160     protected boolean considerEdit(TextEdit edit) {
161         return true;
162     }
163
164     //---- checking --------------------------------------------------------------------
165

166     void checkIntegrityDo() throws MalformedTreeException {
167         fSourceEdits= new ArrayList JavaDoc();
168         fRoot.traverseConsistencyCheck(this, fDocument, fSourceEdits);
169         if (fRoot.getExclusiveEnd() > fDocument.getLength())
170             throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$
171
}
172
173     void checkIntegrityUndo() {
174         if (fRoot.getExclusiveEnd() > fDocument.getLength())
175             throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$
176
}
177
178     //---- execution --------------------------------------------------------------------
179

180     UndoEdit executeDo() throws BadLocationException {
181         UndoCollector collector= new UndoCollector(fRoot);
182         try {
183             if (createUndo())
184                 collector.connect(fDocument);
185             computeSources();
186             fRoot.traverseDocumentUpdating(this, fDocument);
187             if (updateRegions()) {
188                 fRoot.traverseRegionUpdating(this, fDocument, 0, false);
189             }
190         } finally {
191             collector.disconnect(fDocument);
192         }
193         return collector.undo;
194     }
195
196     private void computeSources() {
197         for (Iterator JavaDoc iter= fSourceEdits.iterator(); iter.hasNext();) {
198             List JavaDoc list= (List JavaDoc)iter.next();
199             if (list != null) {
200                 for (Iterator JavaDoc edits= list.iterator(); edits.hasNext();) {
201                     TextEdit edit= (TextEdit)edits.next();
202                     edit.traverseSourceComputation(this, fDocument);
203                 }
204             }
205         }
206     }
207
208     UndoEdit executeUndo() throws BadLocationException {
209         UndoCollector collector= new UndoCollector(fRoot);
210         try {
211             if (createUndo())
212                 collector.connect(fDocument);
213             TextEdit[] edits= fRoot.getChildren();
214             for (int i= edits.length - 1; i >= 0; i--) {
215                 edits[i].performDocumentUpdating(fDocument);
216             }
217         } finally {
218             collector.disconnect(fDocument);
219         }
220         return collector.undo;
221     }
222
223     private boolean createUndo() {
224         return (fStyle & TextEdit.CREATE_UNDO) != 0;
225     }
226
227     private boolean updateRegions() {
228         return (fStyle & TextEdit.UPDATE_REGIONS) != 0;
229     }
230 }
231
Popular Tags