KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > actions > BlockCommentAction


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.jdt.internal.ui.actions;
12
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.ResourceBundle JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18
19 import org.eclipse.jface.text.*;
20 import org.eclipse.jface.viewers.ISelection;
21 import org.eclipse.jface.viewers.ISelectionProvider;
22
23 import org.eclipse.ui.IEditorInput;
24 import org.eclipse.ui.texteditor.IDocumentProvider;
25 import org.eclipse.ui.texteditor.ITextEditor;
26 import org.eclipse.ui.texteditor.ITextEditorExtension2;
27 import org.eclipse.ui.texteditor.TextEditorAction;
28
29
30 /**
31  * Common block comment code.
32  *
33  * @since 3.0
34  */

35 public abstract class BlockCommentAction extends TextEditorAction {
36
37     /**
38      * Creates a new instance.
39      * @param bundle
40      * @param prefix
41      * @param editor
42      */

43     public BlockCommentAction(ResourceBundle JavaDoc bundle, String JavaDoc prefix, ITextEditor editor) {
44         super(bundle, prefix, editor);
45     }
46
47     /**
48      * An edit is a kind of <code>DocumentEvent</code>, in this case an edit instruction, that is
49      * affiliated with a <code>Position</code> on a document. The offset of the document event is
50      * not stored statically, but taken from the affiliated <code>Position</code>, which gets
51      * updated when other edits occur.
52      */

53     static class Edit extends DocumentEvent {
54         
55         /**
56          * Factory for edits which manages the creation, installation and destruction of
57          * position categories, position updaters etc. on a certain document. Once a factory has
58          * been obtained, <code>Edit</code> objects can be obtained from it which will be linked to
59          * the document by positions of one position category.
60          * <p>Clients are required to call <code>release</code> once the <code>Edit</code>s are not
61          * used any more, so the positions can be discarded.</p>
62          */

63         public static class EditFactory {
64     
65             /** The position category basename for this edits. */
66             private static final String JavaDoc CATEGORY= "__positionalEditPositionCategory"; //$NON-NLS-1$
67

68             /** The count of factories. */
69             private static int fgCount= 0;
70         
71             /** This factory's category. */
72             private final String JavaDoc fCategory;
73             private IDocument fDocument;
74             private IPositionUpdater fUpdater;
75             
76             /**
77              * Creates a new <code>EditFactory</code> with an unambiguous position category name.
78              * @param document the document that is being edited.
79              */

80             public EditFactory(IDocument document) {
81                 fCategory= CATEGORY + fgCount++;
82                 fDocument= document;
83             }
84             
85             /**
86              * Creates a new edition on the document of this factory.
87              *
88              * @param offset the offset of the edition at the point when is created.
89              * @param length the length of the edition (not updated via the position update mechanism)
90              * @param text the text to be replaced on the document
91              * @return an <code>Edit</code> reflecting the edition on the document
92              */

93             public Edit createEdit(int offset, int length, String JavaDoc text) throws BadLocationException {
94                 
95                 if (!fDocument.containsPositionCategory(fCategory)) {
96                     fDocument.addPositionCategory(fCategory);
97                     fUpdater= new DefaultPositionUpdater(fCategory);
98                     fDocument.addPositionUpdater(fUpdater);
99                 }
100                 
101                 Position position= new Position(offset);
102                 try {
103                     fDocument.addPosition(fCategory, position);
104                 } catch (BadPositionCategoryException e) {
105                     Assert.isTrue(false);
106                 }
107                 return new Edit(fDocument, length, text, position);
108             }
109             
110             /**
111              * Releases the position category on the document and uninstalls the position updater.
112              * <code>Edit</code>s managed by this factory are not updated after this call.
113              */

114             public void release() {
115                 if (fDocument != null && fDocument.containsPositionCategory(fCategory)) {
116                     fDocument.removePositionUpdater(fUpdater);
117                     try {
118                         fDocument.removePositionCategory(fCategory);
119                     } catch (BadPositionCategoryException e) {
120                         Assert.isTrue(false);
121                     }
122                     fDocument= null;
123                     fUpdater= null;
124                 }
125             }
126         }
127         
128         /** The position in the document where this edit be executed. */
129         private Position fPosition;
130         
131         /**
132          * Creates a new edition on <code>document</code>, taking its offset from <code>position</code>.
133          *
134          * @param document the document being edited
135          * @param length the length of the edition
136          * @param text the replacement text of the edition
137          * @param position the position keeping the edition's offset
138          */

139         protected Edit(IDocument document, int length, String JavaDoc text, Position position) {
140             super(document, 0, length, text);
141             fPosition= position;
142         }
143         
144         /*
145          * @see org.eclipse.jface.text.DocumentEvent#getOffset()
146          */

147         public int getOffset() {
148             return fPosition.getOffset();
149         }
150         
151         /**
152          * Executes the edition on document. The offset is taken from the position.
153          *
154          * @throws BadLocationException if the execution of the document fails.
155          */

156         public void perform() throws BadLocationException {
157             getDocument().replace(getOffset(), getLength(), getText());
158         }
159         
160     }
161
162     public void run() {
163         if (!isEnabled())
164             return;
165             
166         ITextEditor editor= getTextEditor();
167         if (editor == null || !ensureEditable(editor))
168             return;
169             
170         ITextSelection selection= getCurrentSelection();
171         if (!isValidSelection(selection))
172             return;
173         
174         if (!validateEditorInputState())
175             return;
176         
177         IDocumentProvider docProvider= editor.getDocumentProvider();
178         IEditorInput input= editor.getEditorInput();
179         if (docProvider == null || input == null)
180             return;
181             
182         IDocument document= docProvider.getDocument(input);
183         if (document == null)
184             return;
185             
186         IDocumentExtension3 docExtension;
187         if (document instanceof IDocumentExtension3)
188             docExtension= (IDocumentExtension3) document;
189         else
190             return;
191         
192         IRewriteTarget target= (IRewriteTarget)editor.getAdapter(IRewriteTarget.class);
193         if (target != null) {
194             target.beginCompoundChange();
195         }
196         
197         Edit.EditFactory factory= new Edit.EditFactory(document);
198         
199         try {
200             runInternal(selection, docExtension, factory);
201     
202         } catch (BadLocationException e) {
203             // can happen on concurrent modification, deletion etc. of the document
204
// -> don't complain, just bail out
205
} catch (BadPartitioningException e) {
206             // should not happen
207
Assert.isTrue(false, "bad partitioning"); //$NON-NLS-1$
208
} finally {
209             factory.release();
210             
211             if (target != null) {
212                 target.endCompoundChange();
213             }
214         }
215     }
216
217     /**
218      * Calls <code>perform</code> on all <code>Edit</code>s in <code>edits</code>.
219      *
220      * @param edits a list of <code>Edit</code>s
221      * @throws BadLocationException if an <code>Edit</code> threw such an exception.
222      */

223     protected void executeEdits(List JavaDoc edits) throws BadLocationException {
224         for (Iterator JavaDoc it= edits.iterator(); it.hasNext();) {
225             Edit edit= (Edit) it.next();
226             edit.perform();
227         }
228     }
229
230     /**
231      * Ensures that the editor is modifyable. If the editor is an instance of
232      * <code>ITextEditorExtension2</code>, its <code>validateEditorInputState</code> method
233      * is called, otherwise, the result of <code>isEditable</code> is returned.
234      *
235      * @param editor the editor to be checked
236      * @return <code>true</code> if the editor is editable, <code>false</code> otherwise
237      */

238     protected boolean ensureEditable(ITextEditor editor) {
239         Assert.isNotNull(editor);
240     
241         if (editor instanceof ITextEditorExtension2) {
242             ITextEditorExtension2 ext= (ITextEditorExtension2) editor;
243             return ext.validateEditorInputState();
244         }
245         
246         return editor.isEditable();
247     }
248
249     /*
250      * @see org.eclipse.ui.texteditor.IUpdate#update()
251      */

252     public void update() {
253         super.update();
254         
255         if (isEnabled()) {
256             if (!canModifyEditor() || !isValidSelection(getCurrentSelection()))
257                 setEnabled(false);
258         }
259     }
260
261     /**
262      * Returns the editor's selection, or <code>null</code> if no selection can be obtained or the
263      * editor is <code>null</code>.
264      *
265      * @return the selection of the action's editor, or <code>null</code>
266      */

267     protected ITextSelection getCurrentSelection() {
268         ITextEditor editor= getTextEditor();
269         if (editor != null) {
270             ISelectionProvider provider= editor.getSelectionProvider();
271             if (provider != null) {
272                 ISelection selection= provider.getSelection();
273                 if (selection instanceof ITextSelection)
274                     return (ITextSelection) selection;
275             }
276         }
277         return null;
278     }
279
280     /**
281      * Runs the real command once all the editor, document, and selection checks have succeeded.
282      *
283      * @param selection the current selection we are being called for
284      * @param docExtension the document extension where we get the partitioning from
285      * @param factory the edit factory we can use to create <code>Edit</code>s
286      * @throws BadLocationException if an edition fails
287      * @throws BadPartitioningException if a partitioning call fails
288      */

289     protected abstract void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) throws BadLocationException, BadPartitioningException;
290
291     /**
292      * Checks whether <code>selection</code> is valid.
293      *
294      * @param selection the selection to check
295      * @return <code>true</code> if the selection is valid, <code>false</code> otherwise
296      */

297     protected abstract boolean isValidSelection(ITextSelection selection);
298
299     /**
300      * Returns the text to be inserted at the selection start.
301      *
302      * @return the text to be inserted at the selection start
303      */

304     protected String JavaDoc getCommentStart() {
305         // for now: no space story
306
return "/*"; //$NON-NLS-1$
307
}
308
309     /**
310      * Returns the text to be inserted at the selection end.
311      *
312      * @return the text to be inserted at the selection end
313      */

314     protected String JavaDoc getCommentEnd() {
315         // for now: no space story
316
return "*/"; //$NON-NLS-1$
317
}
318
319 }
320
Popular Tags