001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.compare;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.Map;
014:
015: import org.eclipse.core.runtime.Assert;
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.IStatus;
019:
020: import org.eclipse.core.filebuffers.FileBuffers;
021: import org.eclipse.core.filebuffers.ITextFileBuffer;
022: import org.eclipse.core.filebuffers.ITextFileBufferManager;
023: import org.eclipse.core.filebuffers.LocationKind;
024:
025: import org.eclipse.core.resources.IFile;
026:
027: import org.eclipse.swt.widgets.Shell;
028:
029: import org.eclipse.jface.dialogs.MessageDialog;
030: import org.eclipse.jface.viewers.ISelection;
031:
032: import org.eclipse.jface.text.IDocument;
033: import org.eclipse.jface.text.TextUtilities;
034:
035: import org.eclipse.compare.CompareConfiguration;
036: import org.eclipse.compare.CompareUI;
037: import org.eclipse.compare.IStreamContentAccessor;
038: import org.eclipse.compare.ITypedElement;
039:
040: import org.eclipse.team.core.TeamException;
041:
042: import org.eclipse.team.ui.history.ElementLocalHistoryPageSource;
043: import org.eclipse.team.ui.history.HistoryPageCompareEditorInput;
044:
045: import org.eclipse.jdt.core.ICompilationUnit;
046: import org.eclipse.jdt.core.IJavaProject;
047: import org.eclipse.jdt.core.IMember;
048: import org.eclipse.jdt.core.ISourceRange;
049: import org.eclipse.jdt.core.JavaModelException;
050: import org.eclipse.jdt.core.dom.ASTNode;
051: import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
052: import org.eclipse.jdt.core.dom.BodyDeclaration;
053: import org.eclipse.jdt.core.dom.CompilationUnit;
054: import org.eclipse.jdt.core.dom.EnumDeclaration;
055: import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
056:
057: import org.eclipse.jdt.internal.corext.SourceRange;
058: import org.eclipse.jdt.internal.corext.dom.ASTNodes;
059: import org.eclipse.jdt.internal.corext.dom.NodeFinder;
060: import org.eclipse.jdt.internal.corext.util.Resources;
061:
062: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
063: import org.eclipse.jdt.internal.ui.JavaPlugin;
064: import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
065: import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
066:
067: /**
068: * Provides "Replace from local history" for Java elements.
069: */
070: class JavaReplaceWithEditionActionImpl extends JavaHistoryActionImpl {
071:
072: protected boolean fPrevious = false;
073:
074: JavaReplaceWithEditionActionImpl(boolean previous) {
075: super (true);
076: fPrevious = previous;
077: }
078:
079: public void run(ISelection selection) {
080:
081: Shell shell = getShell();
082:
083: final IMember input = getEditionElement(selection);
084: if (input == null) {
085: MessageDialog
086: .openInformation(
087: shell,
088: CompareMessages.ReplaceFromHistory_title,
089: CompareMessages.ReplaceFromHistory_invalidSelectionMessage);
090: return;
091: }
092:
093: final IFile file = getFile(input);
094: if (file == null) {
095: showError();
096: return;
097: }
098:
099: IStatus status = Resources.makeCommittable(file, shell);
100: if (!status.isOK()) {
101: return;
102: }
103:
104: if (fPrevious) {
105: String errorTitle = CompareMessages.ReplaceFromHistory_title;
106: String errorMessage = CompareMessages.ReplaceFromHistory_internalErrorMessage;
107: try {
108: ITypedElement ti = ElementLocalHistoryPageSource
109: .getPreviousEdition(file, input);
110: if (ti == null) {
111: MessageDialog
112: .openInformation(
113: shell,
114: errorTitle,
115: CompareMessages.ReplaceFromHistory_parsingErrorMessage);
116: return;
117: }
118: replace(input, file, ti);
119: } catch (TeamException e) {
120: ExceptionHandler.handle(e, shell, errorTitle,
121: errorMessage);
122: }
123: } else {
124: JavaElementHistoryPageSource pageSource = JavaElementHistoryPageSource
125: .getInstance();
126: CompareConfiguration cc = new CompareConfiguration();
127: cc.setLeftEditable(false);
128: cc.setRightEditable(false);
129: HistoryPageCompareEditorInput ci = new HistoryPageCompareEditorInput(
130: cc, pageSource, input) {
131: protected void performReplace(Object selectedElement) {
132: if (selectedElement instanceof ITypedElement) {
133: JavaReplaceWithEditionActionImpl.this .replace(
134: input, file,
135: (ITypedElement) selectedElement);
136: }
137: }
138: };
139: ci.setReplace(true);
140: ci
141: .setTitle(CompareMessages.JavaReplaceWithEditionActionImpl_0);
142: ci
143: .setHelpContextId(IJavaHelpContextIds.REPLACE_ELEMENT_WITH_HISTORY_DIALOG);
144: CompareUI.openCompareDialog(ci);
145: }
146: }
147:
148: public void replace(IMember input, IFile file, ITypedElement element) {
149:
150: Shell shell = getShell();
151:
152: String errorTitle = CompareMessages.ReplaceFromHistory_title;
153: String errorMessage = CompareMessages.ReplaceFromHistory_internalErrorMessage;
154:
155: // get the document where to insert the text
156: IPath path = file.getFullPath();
157: ITextFileBufferManager bufferManager = FileBuffers
158: .getTextFileBufferManager();
159: ITextFileBuffer textFileBuffer = null;
160: try {
161: bufferManager.connect(path, LocationKind.IFILE, null);
162: textFileBuffer = bufferManager.getTextFileBuffer(path,
163: LocationKind.IFILE);
164: IDocument document = textFileBuffer.getDocument();
165: performReplace(input, file, textFileBuffer, document,
166: element);
167: } catch (InvocationTargetException ex) {
168: ExceptionHandler
169: .handle(ex, shell, errorTitle, errorMessage);
170:
171: } catch (InterruptedException ex) {
172: // shouldn't be called because is not cancelable
173: Assert.isTrue(false);
174:
175: } catch (CoreException ex) {
176: ExceptionHandler
177: .handle(ex, shell, errorTitle, errorMessage);
178:
179: } finally {
180: try {
181: if (textFileBuffer != null)
182: bufferManager.disconnect(path, LocationKind.IFILE,
183: null);
184: } catch (CoreException e) {
185: JavaPlugin.log(e);
186: }
187: }
188: }
189:
190: private void performReplace(IMember input, IFile file,
191: ITextFileBuffer textFileBuffer, IDocument document,
192: ITypedElement ti) throws CoreException, JavaModelException,
193: InvocationTargetException, InterruptedException {
194:
195: if (ti instanceof IStreamContentAccessor) {
196:
197: boolean inEditor = beingEdited(file);
198:
199: String content = JavaCompareUtilities
200: .readString((IStreamContentAccessor) ti);
201: String newContent = trimTextBlock(content, TextUtilities
202: .getDefaultLineDelimiter(document), input
203: .getJavaProject());
204: if (newContent == null) {
205: showError();
206: return;
207: }
208:
209: ICompilationUnit compilationUnit = input
210: .getCompilationUnit();
211: CompilationUnit root = parsePartialCompilationUnit(compilationUnit);
212:
213: final ISourceRange nameRange = input.getNameRange();
214: // workaround for bug in getNameRange(): for AnnotationMembers length is negative
215: int length = nameRange.getLength();
216: if (length < 0)
217: length = 1;
218: ASTNode node2 = NodeFinder.perform(root, new SourceRange(
219: nameRange.getOffset(), length));
220: ASTNode node = ASTNodes.getParent(node2,
221: BodyDeclaration.class);
222: if (node == null)
223: node = ASTNodes.getParent(node2,
224: AnnotationTypeDeclaration.class);
225: if (node == null)
226: node = ASTNodes.getParent(node2, EnumDeclaration.class);
227:
228: //ASTNode node= getBodyContainer(root, input);
229: if (node == null) {
230: showError();
231: return;
232: }
233:
234: ASTRewrite rewriter = ASTRewrite.create(root.getAST());
235: rewriter.replace(node, rewriter.createStringPlaceholder(
236: newContent, node.getNodeType()), null);
237:
238: if (inEditor) {
239: JavaEditor je = getEditor(file);
240: if (je != null)
241: je.setFocus();
242: }
243:
244: Map options = null;
245: IJavaProject javaProject = compilationUnit.getJavaProject();
246: if (javaProject != null)
247: options = javaProject.getOptions(true);
248: applyChanges(rewriter, document, textFileBuffer,
249: getShell(), inEditor, options);
250:
251: }
252: }
253:
254: private void showError() {
255: MessageDialog
256: .openError(
257: getShell(),
258: CompareMessages.ReplaceFromHistory_title,
259: CompareMessages.ReplaceFromHistory_internalErrorMessage);
260: }
261: }
|