]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/actions/BlockCommentAction.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / actions / BlockCommentAction.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 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 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.actions;
12
13import java.util.Iterator;
14import java.util.LinkedList;
15import java.util.List;
16import java.util.ResourceBundle;
17
18import org.eclipse.core.runtime.Assert;
19
20import org.eclipse.jface.viewers.ISelection;
21import org.eclipse.jface.viewers.ISelectionProvider;
22
23import org.eclipse.jface.text.BadLocationException;
24import org.eclipse.jface.text.BadPartitioningException;
25import org.eclipse.jface.text.BadPositionCategoryException;
26import org.eclipse.jface.text.DefaultPositionUpdater;
27import org.eclipse.jface.text.DocumentEvent;
28import org.eclipse.jface.text.IDocument;
29import org.eclipse.jface.text.IDocumentExtension3;
30import org.eclipse.jface.text.IPositionUpdater;
31import org.eclipse.jface.text.IRewriteTarget;
32import org.eclipse.jface.text.ITextSelection;
33import org.eclipse.jface.text.ITypedRegion;
34import org.eclipse.jface.text.Position;
35
36import org.eclipse.ui.IEditorInput;
37
38import org.eclipse.ui.texteditor.IDocumentProvider;
39import org.eclipse.ui.texteditor.ITextEditor;
40import org.eclipse.ui.texteditor.ITextEditorExtension2;
41import org.eclipse.ui.texteditor.TextEditorAction;
42
43import org.eclipse.jdt.ui.text.IJavaPartitions;
44
45import org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit;
46
47
48/**
49 * Common block comment code.
50 *
51 * @since 3.0
52 */
53public abstract class BlockCommentAction extends TextEditorAction {
54
55 /**
56 * Creates a new instance.
57 * @param bundle
58 * @param prefix
59 * @param editor
60 */
61 public BlockCommentAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
62 super(bundle, prefix, editor);
63 }
64
65 /**
66 * An edit is a kind of <code>DocumentEvent</code>, in this case an edit instruction, that is
67 * affiliated with a <code>Position</code> on a document. The offset of the document event is
68 * not stored statically, but taken from the affiliated <code>Position</code>, which gets
69 * updated when other edits occur.
70 */
71 static class Edit extends DocumentEvent {
72
73 /**
74 * Factory for edits which manages the creation, installation and destruction of
75 * position categories, position updaters etc. on a certain document. Once a factory has
76 * been obtained, <code>Edit</code> objects can be obtained from it which will be linked to
77 * the document by positions of one position category.
78 * <p>Clients are required to call <code>release</code> once the <code>Edit</code>s are not
79 * used any more, so the positions can be discarded.</p>
80 */
81 public static class EditFactory {
82
83 /** The position category basename for this edits. */
84 private static final String CATEGORY= "__positionalEditPositionCategory"; //$NON-NLS-1$
85
86 /** The count of factories. */
87 private static int fgCount= 0;
88
89 /** This factory's category. */
90 private final String fCategory;
91 private IDocument fDocument;
92 private IPositionUpdater fUpdater;
93
94 /**
95 * Creates a new <code>EditFactory</code> with an unambiguous position category name.
96 * @param document the document that is being edited.
97 */
98 public EditFactory(IDocument document) {
99 fCategory= CATEGORY + fgCount++;
100 fDocument= document;
101 }
102
103 /**
104 * Creates a new edition on the document of this factory.
105 *
106 * @param offset the offset of the edition at the point when is created.
107 * @param length the length of the edition (not updated via the position update mechanism)
108 * @param text the text to be replaced on the document
109 * @return an <code>Edit</code> reflecting the edition on the document
110 */
111 public Edit createEdit(int offset, int length, String text) throws BadLocationException {
112
113 if (!fDocument.containsPositionCategory(fCategory)) {
114 fDocument.addPositionCategory(fCategory);
115 fUpdater= new DefaultPositionUpdater(fCategory);
116 fDocument.addPositionUpdater(fUpdater);
117 }
118
119 Position position= new Position(offset);
120 try {
121 fDocument.addPosition(fCategory, position);
122 } catch (BadPositionCategoryException e) {
123 Assert.isTrue(false);
124 }
125 return new Edit(fDocument, length, text, position);
126 }
127
128 /**
129 * Releases the position category on the document and uninstalls the position updater.
130 * <code>Edit</code>s managed by this factory are not updated after this call.
131 */
132 public void release() {
133 if (fDocument != null && fDocument.containsPositionCategory(fCategory)) {
134 fDocument.removePositionUpdater(fUpdater);
135 try {
136 fDocument.removePositionCategory(fCategory);
137 } catch (BadPositionCategoryException e) {
138 Assert.isTrue(false);
139 }
140 fDocument= null;
141 fUpdater= null;
142 }
143 }
144
145 public void generated_6386106608258765155(IDocumentExtension3 docExtension, List<Edit> edits, int tokenLength, int offset, int endOffset) throws BadLocationException,
146 BadPartitioningException {
147 ITypedRegion partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, offset, false);
148 int partOffset= partition.getOffset();
149 int partEndOffset= partOffset + partition.getLength();
150
151 while (partEndOffset < endOffset) {
152
153 if (partition.getType() == IJavaPartitions.JAVA_MULTI_LINE_COMMENT) {
154 edits.add(createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
155 edits.add(createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
156 }
157
158 partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, partEndOffset, false);
159 partOffset= partition.getOffset();
160 partEndOffset= partOffset + partition.getLength();
161 }
162
163 if (partition.getType() == IJavaPartitions.JAVA_MULTI_LINE_COMMENT) {
164 edits.add(createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
165 edits.add(createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
166 }
167 }
168
169 public List<Edit> generated_8423036925688668927(IDocumentExtension3 docExtension, AddBlockCommentAction addblockcommentaction, int selectionOffset, int selectionEndOffset) throws BadLocationException,
170 BadPartitioningException {
171 List<Edit> edits= new LinkedList<Edit>();
172 ITypedRegion partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, selectionOffset, false);
173
174 addblockcommentaction.handleFirstPartition(partition, edits, this, selectionOffset);
175
176 while (partition.getOffset() + partition.getLength() < selectionEndOffset) {
177 partition= addblockcommentaction.handleInteriorPartition(partition, edits, this, docExtension);
178 }
179
180 addblockcommentaction.handleLastPartition(partition, edits, this, selectionEndOffset);
181 return edits;
182 }
183 }
184
185 /** The position in the document where this edit be executed. */
186 private Position fPosition;
187
188 /**
189 * Creates a new edition on <code>document</code>, taking its offset from <code>position</code>.
190 *
191 * @param document the document being edited
192 * @param length the length of the edition
193 * @param text the replacement text of the edition
194 * @param position the position keeping the edition's offset
195 */
196 protected Edit(IDocument document, int length, String text, Position position) {
197 super(document, 0, length, text);
198 fPosition= position;
199 }
200
201 /*
202 * @see org.eclipse.jface.text.DocumentEvent#getOffset()
203 */
204 @Override
205 public int getOffset() {
206 return fPosition.getOffset();
207 }
208
209 /**
210 * Executes the edition on document. The offset is taken from the position.
211 *
212 * @throws BadLocationException if the execution of the document fails.
213 */
214 public void perform() throws BadLocationException {
215 getDocument().replace(getOffset(), getLength(), getText());
216 }
217
218 }
219
220 @Override
221 public void run() {
222 if (!isEnabled())
223 return;
224
225 ITextEditor editor= getTextEditor();
226 if (editor == null || !ensureEditable(editor))
227 return;
228
229 ITextSelection selection= getCurrentSelection();
230 if (!isValidSelection(selection))
231 return;
232
233 if (!validateEditorInputState())
234 return;
235
236 IDocumentProvider docProvider= editor.getDocumentProvider();
237 IEditorInput input= editor.getEditorInput();
238 if (docProvider == null || input == null)
239 return;
240
241 IDocument document= docProvider.getDocument(input);
242 if (document == null)
243 return;
244
245 IDocumentExtension3 docExtension;
246 if (document instanceof IDocumentExtension3)
247 docExtension= (IDocumentExtension3) document;
248 else
249 return;
250
251 IRewriteTarget target= (IRewriteTarget)editor.getAdapter(IRewriteTarget.class);
252 if (target != null) {
253 target.beginCompoundChange();
254 }
255
256 Edit.EditFactory factory= new Edit.EditFactory(document);
257
258 try {
259 runInternal(selection, docExtension, factory);
260
261 } catch (BadLocationException e) {
262 // can happen on concurrent modification, deletion etc. of the document
263 // -> don't complain, just bail out
264 } catch (BadPartitioningException e) {
265 // should not happen
266 Assert.isTrue(false, "bad partitioning"); //$NON-NLS-1$
267 } finally {
268 factory.release();
269
270 if (target != null) {
271 target.endCompoundChange();
272 }
273 }
274 }
275
276 /**
277 * Calls <code>perform</code> on all <code>Edit</code>s in <code>edits</code>.
278 *
279 * @param edits a list of <code>Edit</code>s
280 * @throws BadLocationException if an <code>Edit</code> threw such an exception.
281 */
282 protected void executeEdits(List<Edit> edits) throws BadLocationException {
283 for (Iterator<Edit> it= edits.iterator(); it.hasNext();) {
284 Edit edit= it.next();
285 edit.perform();
286 }
287 }
288
289 /**
290 * Ensures that the editor is modifyable. If the editor is an instance of
291 * <code>ITextEditorExtension2</code>, its <code>validateEditorInputState</code> method
292 * is called, otherwise, the result of <code>isEditable</code> is returned.
293 *
294 * @param editor the editor to be checked
295 * @return <code>true</code> if the editor is editable, <code>false</code> otherwise
296 */
297 protected boolean ensureEditable(ITextEditor editor) {
298 Assert.isNotNull(editor);
299
300 if (editor instanceof ITextEditorExtension2) {
301 ITextEditorExtension2 ext= (ITextEditorExtension2) editor;
302 return ext.validateEditorInputState();
303 }
304
305 return editor.isEditable();
306 }
307
308 /*
309 * @see org.eclipse.ui.texteditor.IUpdate#update()
310 */
311 @Override
312 public void update() {
313 super.update();
314
315 if (isEnabled()) {
316 if (!canModifyEditor() || !isValidSelection(getCurrentSelection()))
317 setEnabled(false);
318 }
319 }
320
321 /**
322 * Returns the editor's selection, or <code>null</code> if no selection can be obtained or the
323 * editor is <code>null</code>.
324 *
325 * @return the selection of the action's editor, or <code>null</code>
326 */
327 protected ITextSelection getCurrentSelection() {
328 ITextEditor editor= getTextEditor();
329 if (editor != null) {
330 ISelectionProvider provider= editor.getSelectionProvider();
331 if (provider != null) {
332 ISelection selection= provider.getSelection();
333 if (selection instanceof ITextSelection)
334 return (ITextSelection) selection;
335 }
336 }
337 return null;
338 }
339
340 /**
341 * Runs the real command once all the editor, document, and selection checks have succeeded.
342 *
343 * @param selection the current selection we are being called for
344 * @param docExtension the document extension where we get the partitioning from
345 * @param factory the edit factory we can use to create <code>Edit</code>s
346 * @throws BadLocationException if an edition fails
347 * @throws BadPartitioningException if a partitioning call fails
348 */
349 protected abstract void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) throws BadLocationException, BadPartitioningException;
350
351 /**
352 * Checks whether <code>selection</code> is valid.
353 *
354 * @param selection the selection to check
355 * @return <code>true</code> if the selection is valid, <code>false</code> otherwise
356 */
357 protected abstract boolean isValidSelection(ITextSelection selection);
358
359 /**
360 * Returns the text to be inserted at the selection start.
361 *
362 * @return the text to be inserted at the selection start
363 */
364 protected String getCommentStart() {
365 // for now: no space story
366 return "/*"; //$NON-NLS-1$
367 }
368
369 /**
370 * Returns the text to be inserted at the selection end.
371 *
372 * @return the text to be inserted at the selection end
373 */
374 protected String getCommentEnd() {
375 // for now: no space story
376 return "*/"; //$NON-NLS-1$
377 }
378
379}