--- /dev/null
+/*******************************************************************************
+ * 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.compare;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.ui.history.ElementLocalHistoryPageSource;
+import org.eclipse.team.ui.history.HistoryPageCompareEditorInput;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+
+import org.eclipse.core.resources.IFile;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.NodeFinder;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.util.Resources;
+
+import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
+import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
+
+
+/**
+ * Provides "Replace from local history" for Java elements.
+ */
+class JavaReplaceWithEditionActionImpl extends JavaHistoryActionImpl {
+
+ protected boolean fPrevious= false;
+
+ JavaReplaceWithEditionActionImpl(boolean previous) {
+ super(true);
+ fPrevious= previous;
+ }
+
+ @Override
+ public void run(ISelection selection) {
+
+ Shell shell= getShell();
+
+ final IMember input= getEditionElement(selection);
+ if (input == null) {
+ MessageDialog.openInformation(shell, CompareMessages.ReplaceFromHistory_title, CompareMessages.ReplaceFromHistory_invalidSelectionMessage);
+ return;
+ }
+
+ final IFile file= getFile(input);
+ if (file == null) {
+ showError();
+ return;
+ }
+
+ IStatus status= Resources.makeCommittable(file, shell);
+ if (!status.isOK()) {
+ return;
+ }
+
+ if (fPrevious) {
+ String errorTitle= CompareMessages.ReplaceFromHistory_title;
+ String errorMessage= CompareMessages.ReplaceFromHistory_internalErrorMessage;
+ try {
+ ITypedElement ti = ElementLocalHistoryPageSource.getPreviousEdition(file, input);
+ if (ti == null) {
+ MessageDialog.openInformation(shell, errorTitle, CompareMessages.ReplaceFromHistory_parsingErrorMessage);
+ return;
+ }
+ replace(input, file, ti);
+ } catch (TeamException e) {
+ ExceptionHandler.handle(e, shell, errorTitle, errorMessage);
+ }
+ } else {
+ JavaElementHistoryPageSource pageSource = JavaElementHistoryPageSource.getInstance();
+ CompareConfiguration cc = new CompareConfiguration();
+ cc.setLeftEditable(false);
+ cc.setRightEditable(false);
+ HistoryPageCompareEditorInput ci = new HistoryPageCompareEditorInput(cc, pageSource, input) {
+ @Override
+ protected void performReplace(Object selectedElement) {
+ if (selectedElement instanceof ITypedElement) {
+ JavaReplaceWithEditionActionImpl.this.replace(input, file, (ITypedElement)selectedElement);
+ }
+ }
+ };
+ ci.setReplace(true);
+ ci.setTitle(CompareMessages.JavaReplaceWithEditionActionImpl_0);
+ ci.setHelpContextId(IJavaHelpContextIds.REPLACE_ELEMENT_WITH_HISTORY_DIALOG);
+ CompareUI.openCompareDialog(ci);
+ }
+ }
+
+ public void replace(IMember input, IFile file, ITypedElement element) {
+
+ Shell shell= getShell();
+
+ String errorTitle= CompareMessages.ReplaceFromHistory_title;
+ String errorMessage= CompareMessages.ReplaceFromHistory_internalErrorMessage;
+
+ // get the document where to insert the text
+ IPath path= file.getFullPath();
+ ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager();
+ ITextFileBuffer textFileBuffer= null;
+ try {
+ bufferManager.connect(path, LocationKind.IFILE, null);
+ textFileBuffer= bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
+ IDocument document= textFileBuffer.getDocument();
+ performReplace(input, file, textFileBuffer, document, element);
+ } catch(InvocationTargetException ex) {
+ ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);
+
+ } catch(InterruptedException ex) {
+ // shouldn't be called because is not cancelable
+ Assert.isTrue(false);
+
+ } catch(CoreException ex) {
+ ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);
+
+ } finally {
+ try {
+ if (textFileBuffer != null)
+ bufferManager.disconnect(path, LocationKind.IFILE, null);
+ } catch (CoreException e) {
+ JavaPlugin.log(e);
+ }
+ }
+ }
+
+ private void performReplace(IMember input, IFile file,
+ ITextFileBuffer textFileBuffer, IDocument document, ITypedElement ti)
+ throws CoreException, JavaModelException,
+ InvocationTargetException, InterruptedException {
+
+ if (ti instanceof IStreamContentAccessor) {
+
+ boolean inEditor= beingEdited(file);
+
+ String content= JavaCompareUtilities.readString((IStreamContentAccessor)ti);
+ String newContent= trimTextBlock(content, TextUtilities.getDefaultLineDelimiter(document), input.getJavaProject());
+ if (newContent == null) {
+ showError();
+ return;
+ }
+
+ ICompilationUnit compilationUnit= input.getCompilationUnit();
+ CompilationUnit root= parsePartialCompilationUnit(compilationUnit);
+
+
+ ISourceRange nameRange= input.getNameRange();
+ if (nameRange == null)
+ nameRange= input.getSourceRange();
+ // workaround for bug in getNameRange(): for AnnotationMembers length is negative
+ int length= nameRange.getLength();
+ if (length < 0)
+ length= 1;
+ ASTNode node2= NodeFinder.perform(root, new SourceRange(nameRange.getOffset(), length));
+ ASTNode node;
+ if (node2.getNodeType() == ASTNode.INITIALIZER)
+ node= node2;
+ else
+ node= ASTNodes.getParent(node2, BodyDeclaration.class);
+ if (node == null)
+ node= ASTNodes.getParent(node2, AnnotationTypeDeclaration.class);
+ if (node == null)
+ node= ASTNodes.getParent(node2, EnumDeclaration.class);
+
+ //ASTNode node= getBodyContainer(root, input);
+ if (node == null) {
+ showError();
+ return;
+ }
+
+ ASTRewrite rewriter= ASTRewrite.create(root.getAST());
+ rewriter.replace(node, rewriter.createStringPlaceholder(newContent, node.getNodeType()), null);
+
+ if (inEditor) {
+ JavaEditor je= getEditor(file);
+ if (je != null)
+ je.setFocus();
+ }
+
+ Map<String, String> options= null;
+ IJavaProject javaProject= compilationUnit.getJavaProject();
+ if (javaProject != null)
+ options= javaProject.getOptions(true);
+ applyChanges(rewriter, document, textFileBuffer, getShell(), inEditor, options);
+
+ }
+ }
+
+ private void showError() {
+ MessageDialog.openError(getShell(), CompareMessages.ReplaceFromHistory_title, CompareMessages.ReplaceFromHistory_internalErrorMessage);
+ }
+}