KickJava   Java API By Example, From Geeks To Geeks.

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


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.List JavaDoc;
15
16 import org.eclipse.core.runtime.Assert;
17
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
20
21 /**
22  * A copy source edit denotes the source of a copy operation. Copy
23  * source edits are only valid inside an edit tree if they have a
24  * corresponding target edit. Furthermore the corresponding
25  * target edit can't be a direct or indirect child of the source
26  * edit. Violating one of two requirements will result in a <code>
27  * MalformedTreeException</code> when executing the edit tree.
28  * <p>
29  * A copy source edit can manage an optional source modifier. A
30  * source modifier can provide a set of replace edits which will
31  * to applied to the source before it gets inserted at the target
32  * position.
33  *
34  * @see org.eclipse.text.edits.CopyTargetEdit
35  *
36  * @since 3.0
37  */

38 public final class CopySourceEdit extends TextEdit {
39
40     private CopyTargetEdit fTarget;
41     private ISourceModifier fModifier;
42
43     private String JavaDoc fSourceContent;
44     private TextEdit fSourceRoot;
45
46     private static class PartialCopier extends TextEditVisitor {
47         TextEdit fResult;
48         List JavaDoc fParents= new ArrayList JavaDoc();
49         TextEdit fCurrentParent;
50
51         public static TextEdit perform(TextEdit source) {
52             PartialCopier copier= new PartialCopier();
53             source.accept(copier);
54             return copier.fResult;
55         }
56         private void manageCopy(TextEdit copy) {
57             if (fResult == null)
58                 fResult= copy;
59             if (fCurrentParent != null) {
60                 fCurrentParent.addChild(copy);
61             }
62             fParents.add(fCurrentParent);
63             fCurrentParent= copy;
64         }
65         public void postVisit(TextEdit edit) {
66             fCurrentParent= (TextEdit)fParents.remove(fParents.size() - 1);
67         }
68         public boolean visitNode(TextEdit edit) {
69             manageCopy(edit.doCopy());
70             return true;
71         }
72         public boolean visit(CopySourceEdit edit) {
73             manageCopy(new RangeMarker(edit.getOffset(), edit.getLength()));
74             return true;
75         }
76         public boolean visit(CopyTargetEdit edit) {
77             manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent()));
78             return true;
79         }
80         public boolean visit(MoveSourceEdit edit) {
81             manageCopy(new DeleteEdit(edit.getOffset(), edit.getLength()));
82             return true;
83         }
84         public boolean visit(MoveTargetEdit edit) {
85             manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent()));
86             return true;
87         }
88     }
89
90     /**
91      * Constructs a new copy source edit.
92      *
93      * @param offset the edit's offset
94      * @param length the edit's length
95      */

96     public CopySourceEdit(int offset, int length) {
97         super(offset, length);
98     }
99
100     /**
101      * Constructs a new copy source edit.
102      *
103      * @param offset the edit's offset
104      * @param length the edit's length
105      * @param target the edit's target
106      */

107     public CopySourceEdit(int offset, int length, CopyTargetEdit target) {
108         this(offset, length);
109         setTargetEdit(target);
110     }
111
112     /*
113      * Copy Constructor
114      */

115     private CopySourceEdit(CopySourceEdit other) {
116         super(other);
117         if (other.fModifier != null)
118             fModifier= other.fModifier.copy();
119     }
120
121     /**
122      * Returns the associated target edit or <code>null</code>
123      * if no target edit is associated yet.
124      *
125      * @return the target edit or <code>null</code>
126      */

127     public CopyTargetEdit getTargetEdit() {
128         return fTarget;
129     }
130
131     /**
132      * Sets the target edit.
133      *
134      * @param edit the new target edit.
135      *
136      * @exception MalformedTreeException is thrown if the target edit
137      * is a direct or indirect child of the source edit
138      */

139     public void setTargetEdit(CopyTargetEdit edit) throws MalformedTreeException {
140         Assert.isNotNull(edit);
141         if (fTarget != edit) {
142             fTarget= edit;
143             fTarget.setSourceEdit(this);
144         }
145     }
146
147     /**
148      * Returns the current source modifier or <code>null</code>
149      * if no source modifier is set.
150      *
151      * @return the source modifier
152      */

153     public ISourceModifier getSourceModifier() {
154         return fModifier;
155     }
156
157     /**
158      * Sets the optional source modifier.
159      *
160      * @param modifier the source modifier or <code>null</code>
161      * if no source modification is need.
162      */

163     public void setSourceModifier(ISourceModifier modifier) {
164         fModifier= modifier;
165     }
166
167     /*
168      * @see TextEdit#doCopy
169      */

170     protected TextEdit doCopy() {
171         return new CopySourceEdit(this);
172     }
173
174     /*
175      * @see TextEdit#accept0
176      */

177     protected void accept0(TextEditVisitor visitor) {
178         boolean visitChildren= visitor.visit(this);
179         if (visitChildren) {
180             acceptChildren(visitor);
181         }
182     }
183
184     //---- API for CopyTargetEdit ------------------------------------------------
185

186     String JavaDoc getContent() {
187         // The source content can be null if the edit wasn't executed
188
// due to an exclusion list of the text edit processor. Return
189
// the empty string which can be moved without any harm.
190
if (fSourceContent == null)
191             return ""; //$NON-NLS-1$
192
return fSourceContent;
193     }
194
195     void clearContent() {
196         fSourceContent= null;
197     }
198
199     /*
200      * @see TextEdit#postProcessCopy
201      */

202     protected void postProcessCopy(TextEditCopier copier) {
203         if (fTarget != null) {
204             CopySourceEdit source= (CopySourceEdit)copier.getCopy(this);
205             CopyTargetEdit target= (CopyTargetEdit)copier.getCopy(fTarget);
206             if (source != null && target != null)
207                 source.setTargetEdit(target);
208         }
209     }
210
211     //---- consistency check ----------------------------------------------------
212

213     int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List JavaDoc sourceEdits) {
214         int result= super.traverseConsistencyCheck(processor, document, sourceEdits);
215         // Since source computation takes place in a recursive fashion (see
216
// performSourceComputation) we only do something if we don't have a
217
// computed source already.
218
if (fSourceContent == null) {
219             if (sourceEdits.size() <= result) {
220                 List JavaDoc list= new ArrayList JavaDoc();
221                 list.add(this);
222                 for (int i= sourceEdits.size(); i < result; i++)
223                     sourceEdits.add(null);
224                 sourceEdits.add(list);
225             } else {
226                 List JavaDoc list= (List JavaDoc)sourceEdits.get(result);
227                 if (list == null) {
228                     list= new ArrayList JavaDoc();
229                     sourceEdits.add(result, list);
230                 }
231                 list.add(this);
232             }
233         }
234         return result;
235     }
236
237     void performConsistencyCheck(TextEditProcessor processor, IDocument document) throws MalformedTreeException {
238         if (fTarget == null)
239             throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.no_target")); //$NON-NLS-1$
240
if (fTarget.getSourceEdit() != this)
241             throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_source")); //$NON-NLS-1$
242
/* causes ASTRewrite to fail
243         if (getRoot() != fTarget.getRoot())
244             throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_tree")); //$NON-NLS-1$
245         */

246     }
247
248     //---- source computation -------------------------------------------------------
249

250     void traverseSourceComputation(TextEditProcessor processor, IDocument document) {
251         // always perform source computation independent of processor.considerEdit
252
// The target might need the source and the source is computed in a
253
// temporary buffer.
254
performSourceComputation(processor, document);
255     }
256
257     void performSourceComputation(TextEditProcessor processor, IDocument document) {
258         try {
259             MultiTextEdit root= new MultiTextEdit(getOffset(), getLength());
260             root.internalSetChildren(internalGetChildren());
261             fSourceContent= document.get(getOffset(), getLength());
262             fSourceRoot= PartialCopier.perform(root);
263             fSourceRoot.internalMoveTree(-getOffset());
264             if (fSourceRoot.hasChildren()) {
265                 EditDocument subDocument= new EditDocument(fSourceContent);
266                 TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, TextEdit.NONE);
267                 subProcessor.performEdits();
268                 if (needsTransformation())
269                     applyTransformation(subDocument);
270                 fSourceContent= subDocument.get();
271                 fSourceRoot= null;
272             } else {
273                 if (needsTransformation()) {
274                     EditDocument subDocument= new EditDocument(fSourceContent);
275                     applyTransformation(subDocument);
276                     fSourceContent= subDocument.get();
277                 }
278             }
279         } catch (BadLocationException cannotHappen) {
280             Assert.isTrue(false);
281         }
282     }
283
284     private boolean needsTransformation() {
285         return fModifier != null;
286     }
287
288     private void applyTransformation(IDocument document) throws MalformedTreeException {
289         TextEdit newEdit= new MultiTextEdit(0, document.getLength());
290         ReplaceEdit[] replaces= fModifier.getModifications(document.get());
291         for (int i= 0; i < replaces.length; i++) {
292             newEdit.addChild(replaces[i]);
293         }
294         try {
295             newEdit.apply(document, TextEdit.NONE);
296         } catch (BadLocationException cannotHappen) {
297             Assert.isTrue(false);
298         }
299     }
300
301     //---- document updating ----------------------------------------------------------------
302

303     int performDocumentUpdating(IDocument document) throws BadLocationException {
304         fDelta= 0;
305         return fDelta;
306     }
307
308     //---- region updating ----------------------------------------------------------------
309

310     /*
311      * @see TextEdit#deleteChildren
312      */

313     boolean deleteChildren() {
314         return false;
315     }
316 }
317
Popular Tags