]> git.uio.no Git - ifi-stolz-refaktor.git/blobdiff - 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
diff --git a/case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/actions/BlockCommentAction.java b/case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/actions/BlockCommentAction.java
new file mode 100644 (file)
index 0000000..cd983dd
--- /dev/null
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.actions;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPartitioningException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.IRewriteTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.ui.IEditorInput;
+
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+import org.eclipse.jdt.ui.text.IJavaPartitions;
+
+import org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit;
+
+
+/**
+ * Common block comment code.
+ *
+ * @since 3.0
+ */
+public abstract class BlockCommentAction extends TextEditorAction {
+
+       /**
+        * Creates a new instance.
+        * @param bundle
+        * @param prefix
+        * @param editor
+        */
+       public BlockCommentAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
+               super(bundle, prefix, editor);
+       }
+
+       /**
+        * An edit is a kind of <code>DocumentEvent</code>, in this case an edit instruction, that is
+        * affiliated with a <code>Position</code> on a document. The offset of the document event is
+        * not stored statically, but taken from the affiliated <code>Position</code>, which gets
+        * updated when other edits occur.
+        */
+       static class Edit extends DocumentEvent {
+
+               /**
+                * Factory for edits which manages the creation, installation and destruction of
+                * position categories, position updaters etc. on a certain document. Once a factory has
+                * been obtained, <code>Edit</code> objects can be obtained from it which will be linked to
+                * the document by positions of one position category.
+                * <p>Clients are required to call <code>release</code> once the <code>Edit</code>s are not
+                * used any more, so the positions can be discarded.</p>
+                */
+               public static class EditFactory {
+
+                       /** The position category basename for this edits. */
+                       private static final String CATEGORY= "__positionalEditPositionCategory"; //$NON-NLS-1$
+
+                       /** The count of factories. */
+                       private static int fgCount= 0;
+
+                       /** This factory's category. */
+                       private final String fCategory;
+                       private IDocument fDocument;
+                       private IPositionUpdater fUpdater;
+
+                       /**
+                        * Creates a new <code>EditFactory</code> with an unambiguous position category name.
+                        * @param document the document that is being edited.
+                        */
+                       public EditFactory(IDocument document) {
+                               fCategory= CATEGORY + fgCount++;
+                               fDocument= document;
+                       }
+
+                       /**
+                        * Creates a new edition on the document of this factory.
+                        *
+                        * @param offset the offset of the edition at the point when is created.
+                        * @param length the length of the edition (not updated via the position update mechanism)
+                        * @param text the text to be replaced on the document
+                        * @return an <code>Edit</code> reflecting the edition on the document
+                        */
+                       public Edit createEdit(int offset, int length, String text) throws BadLocationException {
+
+                               if (!fDocument.containsPositionCategory(fCategory)) {
+                                       fDocument.addPositionCategory(fCategory);
+                                       fUpdater= new DefaultPositionUpdater(fCategory);
+                                       fDocument.addPositionUpdater(fUpdater);
+                               }
+
+                               Position position= new Position(offset);
+                               try {
+                                       fDocument.addPosition(fCategory, position);
+                               } catch (BadPositionCategoryException e) {
+                                       Assert.isTrue(false);
+                               }
+                               return new Edit(fDocument, length, text, position);
+                       }
+
+                       /**
+                        * Releases the position category on the document and uninstalls the position updater.
+                        * <code>Edit</code>s managed by this factory are not updated after this call.
+                        */
+                       public void release() {
+                               if (fDocument != null && fDocument.containsPositionCategory(fCategory)) {
+                                       fDocument.removePositionUpdater(fUpdater);
+                                       try {
+                                               fDocument.removePositionCategory(fCategory);
+                                       } catch (BadPositionCategoryException e) {
+                                               Assert.isTrue(false);
+                                       }
+                                       fDocument= null;
+                                       fUpdater= null;
+                               }
+                       }
+
+                       public void generated_6386106608258765155(IDocumentExtension3 docExtension, List<Edit> edits, int tokenLength, int offset, int endOffset) throws BadLocationException,
+                                       BadPartitioningException {
+                               ITypedRegion partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, offset, false);
+                               int partOffset= partition.getOffset();
+                               int partEndOffset= partOffset + partition.getLength();
+                       
+                               while (partEndOffset < endOffset) {
+                       
+                                       if (partition.getType() == IJavaPartitions.JAVA_MULTI_LINE_COMMENT) {
+                                               edits.add(createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
+                                               edits.add(createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
+                                       }
+                       
+                                       partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, partEndOffset, false);
+                                       partOffset= partition.getOffset();
+                                       partEndOffset= partOffset + partition.getLength();
+                               }
+                       
+                               if (partition.getType() == IJavaPartitions.JAVA_MULTI_LINE_COMMENT) {
+                                       edits.add(createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$
+                                       edits.add(createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$
+                               }
+                       }
+
+                       public List<Edit> generated_8423036925688668927(IDocumentExtension3 docExtension, AddBlockCommentAction addblockcommentaction, int selectionOffset, int selectionEndOffset) throws BadLocationException,
+                                       BadPartitioningException {
+                               List<Edit> edits= new LinkedList<Edit>();
+                               ITypedRegion partition= docExtension.getPartition(IJavaPartitions.JAVA_PARTITIONING, selectionOffset, false);
+                       
+                               addblockcommentaction.handleFirstPartition(partition, edits, this, selectionOffset);
+                       
+                               while (partition.getOffset() + partition.getLength() < selectionEndOffset) {
+                                       partition= addblockcommentaction.handleInteriorPartition(partition, edits, this, docExtension);
+                               }
+                       
+                               addblockcommentaction.handleLastPartition(partition, edits, this, selectionEndOffset);
+                               return edits;
+                       }
+               }
+
+               /** The position in the document where this edit be executed. */
+               private Position fPosition;
+
+               /**
+                * Creates a new edition on <code>document</code>, taking its offset from <code>position</code>.
+                *
+                * @param document the document being edited
+                * @param length the length of the edition
+                * @param text the replacement text of the edition
+                * @param position the position keeping the edition's offset
+                */
+               protected Edit(IDocument document, int length, String text, Position position) {
+                       super(document, 0, length, text);
+                       fPosition= position;
+               }
+
+               /*
+                * @see org.eclipse.jface.text.DocumentEvent#getOffset()
+                */
+               @Override
+               public int getOffset() {
+                       return fPosition.getOffset();
+               }
+
+               /**
+                * Executes the edition on document. The offset is taken from the position.
+                *
+                * @throws BadLocationException if the execution of the document fails.
+                */
+               public void perform() throws BadLocationException {
+                       getDocument().replace(getOffset(), getLength(), getText());
+               }
+
+       }
+
+       @Override
+       public void run() {
+               if (!isEnabled())
+                       return;
+
+               ITextEditor editor= getTextEditor();
+               if (editor == null || !ensureEditable(editor))
+                       return;
+
+               ITextSelection selection= getCurrentSelection();
+               if (!isValidSelection(selection))
+                       return;
+
+               if (!validateEditorInputState())
+                       return;
+
+               IDocumentProvider docProvider= editor.getDocumentProvider();
+               IEditorInput input= editor.getEditorInput();
+               if (docProvider == null || input == null)
+                       return;
+
+               IDocument document= docProvider.getDocument(input);
+               if (document == null)
+                       return;
+
+               IDocumentExtension3 docExtension;
+               if (document instanceof IDocumentExtension3)
+                       docExtension= (IDocumentExtension3) document;
+               else
+                       return;
+
+               IRewriteTarget target= (IRewriteTarget)editor.getAdapter(IRewriteTarget.class);
+               if (target != null) {
+                       target.beginCompoundChange();
+               }
+
+               Edit.EditFactory factory= new Edit.EditFactory(document);
+
+               try {
+                       runInternal(selection, docExtension, factory);
+
+               } catch (BadLocationException e) {
+                       // can happen on concurrent modification, deletion etc. of the document
+                       // -> don't complain, just bail out
+               } catch (BadPartitioningException e) {
+                       // should not happen
+                       Assert.isTrue(false, "bad partitioning");  //$NON-NLS-1$
+               } finally {
+                       factory.release();
+
+                       if (target != null) {
+                               target.endCompoundChange();
+                       }
+               }
+       }
+
+       /**
+        * Calls <code>perform</code> on all <code>Edit</code>s in <code>edits</code>.
+        *
+        * @param edits a list of <code>Edit</code>s
+        * @throws BadLocationException if an <code>Edit</code> threw such an exception.
+        */
+       protected void executeEdits(List<Edit> edits) throws BadLocationException {
+               for (Iterator<Edit> it= edits.iterator(); it.hasNext();) {
+                       Edit edit= it.next();
+                       edit.perform();
+               }
+       }
+
+       /**
+        * Ensures that the editor is modifyable. If the editor is an instance of
+        * <code>ITextEditorExtension2</code>, its <code>validateEditorInputState</code> method
+        * is called, otherwise, the result of <code>isEditable</code> is returned.
+        *
+        * @param editor the editor to be checked
+        * @return <code>true</code> if the editor is editable, <code>false</code> otherwise
+        */
+       protected boolean ensureEditable(ITextEditor editor) {
+               Assert.isNotNull(editor);
+
+               if (editor instanceof ITextEditorExtension2) {
+                       ITextEditorExtension2 ext= (ITextEditorExtension2) editor;
+                       return ext.validateEditorInputState();
+               }
+
+               return editor.isEditable();
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.IUpdate#update()
+        */
+       @Override
+       public void update() {
+               super.update();
+
+               if (isEnabled()) {
+                       if (!canModifyEditor() || !isValidSelection(getCurrentSelection()))
+                               setEnabled(false);
+               }
+       }
+
+       /**
+        * Returns the editor's selection, or <code>null</code> if no selection can be obtained or the
+        * editor is <code>null</code>.
+        *
+        * @return the selection of the action's editor, or <code>null</code>
+        */
+       protected ITextSelection getCurrentSelection() {
+               ITextEditor editor= getTextEditor();
+               if (editor != null) {
+                       ISelectionProvider provider= editor.getSelectionProvider();
+                       if (provider != null) {
+                               ISelection selection= provider.getSelection();
+                               if (selection instanceof ITextSelection)
+                                       return (ITextSelection) selection;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Runs the real command once all the editor, document, and selection checks have succeeded.
+        *
+        * @param selection the current selection we are being called for
+        * @param docExtension the document extension where we get the partitioning from
+        * @param factory the edit factory we can use to create <code>Edit</code>s
+        * @throws BadLocationException if an edition fails
+        * @throws BadPartitioningException if a partitioning call fails
+        */
+       protected abstract void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) throws BadLocationException, BadPartitioningException;
+
+       /**
+        * Checks whether <code>selection</code> is valid.
+        *
+        * @param selection the selection to check
+        * @return <code>true</code> if the selection is valid, <code>false</code> otherwise
+        */
+       protected abstract boolean isValidSelection(ITextSelection selection);
+
+       /**
+        * Returns the text to be inserted at the selection start.
+        *
+        * @return the text to be inserted at the selection start
+        */
+       protected String getCommentStart() {
+               // for now: no space story
+               return "/*"; //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the text to be inserted at the selection end.
+        *
+        * @return the text to be inserted at the selection end
+        */
+       protected String getCommentEnd() {
+               // for now: no space story
+               return "*/"; //$NON-NLS-1$
+       }
+
+}