// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, useForLoop, com.instantiations.assist.eclipse.analysis.deserializeabilitySecurity, com.instantiations.assist.eclipse.analysis.disallowReturnMutable, com.instantiations.assist.eclipse.analysis.enforceCloneableUsageSecurity | |
/******************************************************************************* | |
* Copyright (c) 2010, 2012 Ericsson AB 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 | |
* | |
* Description: | |
* | |
* This class is used to access various eclipse editors from R4E model elements | |
* | |
* Contributors: | |
* Sebastien Dubois - Created for Mylyn Review R4E project | |
* | |
******************************************************************************/ | |
package org.eclipse.mylyn.reviews.r4e.ui.internal.editors; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.util.Iterator; | |
import org.eclipse.compare.CompareEditorInput; | |
import org.eclipse.compare.CompareUI; | |
import org.eclipse.compare.ITypedElement; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.Platform; | |
import org.eclipse.core.runtime.content.IContentType; | |
import org.eclipse.jface.text.TextSelection; | |
import org.eclipse.jface.util.OpenStrategy; | |
import org.eclipse.jface.viewers.ISelection; | |
import org.eclipse.jface.viewers.IStructuredSelection; | |
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion; | |
import org.eclipse.mylyn.reviews.r4e.ui.R4EUIPlugin; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIPosition; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIAnomalyBasic; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIComment; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIContent; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIFileContext; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUITextPosition; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.CommandUtils; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.UIUtils; | |
import org.eclipse.ui.IEditorDescriptor; | |
import org.eclipse.ui.IEditorPart; | |
import org.eclipse.ui.IEditorReference; | |
import org.eclipse.ui.IEditorRegistry; | |
import org.eclipse.ui.IReusableEditor; | |
import org.eclipse.ui.IStorageEditorInput; | |
import org.eclipse.ui.IWorkbenchPage; | |
import org.eclipse.ui.PlatformUI; | |
import org.eclipse.ui.texteditor.ITextEditor; | |
/** | |
* @author Sebastien Dubois | |
* @version $Revision: 1.0 $ | |
*/ | |
public class EditorProxy { | |
// ------------------------------------------------------------------------ | |
// Constants | |
// ------------------------------------------------------------------------ | |
/** | |
* Field R4E_COMPARE_EDITOR_TITLE. (value is ""R4E Compare"") | |
*/ | |
private static final String R4E_COMPARE_EDITOR_TITLE = "R4E Compare"; | |
/** | |
* Field DEFAULT_EDITOR_NAME. (value is ""org.eclipse.ui.DefaultTextEditor"") | |
*/ | |
private static final String DEFAULT_EDITOR_NAME = "org.eclipse.ui.DefaultTextEditor"; | |
// ------------------------------------------------------------------------ | |
// Methods | |
// ------------------------------------------------------------------------ | |
/** | |
* Method openEditor. Open the editor | |
* | |
* @param aPage | |
* IWorkbenchPage - the current workbench page | |
* @param aSelection | |
* ISelection - the currently selected model element | |
* @param forceSingleEditor | |
* boolean - flag to force single editor | |
* @throws CoreException | |
*/ | |
public static void openEditor(IWorkbenchPage aPage, ISelection aSelection, boolean forceSingleEditor) { | |
if (aSelection.isEmpty() || !(aSelection instanceof IStructuredSelection)) { | |
return; | |
} | |
Object element = null; | |
IR4EUIPosition position = null; | |
R4EUIFileContext context = null; | |
R4EFileVersion baseFileVersion = null; | |
R4EFileVersion targetFileVersion = null; | |
for (final Iterator<?> iterator = ((IStructuredSelection) aSelection).iterator(); iterator.hasNext();) { | |
element = iterator.next(); | |
if (!(element instanceof IR4EUIModelElement)) { | |
continue; | |
} | |
//Depending on which element was selected in the tree, we make the target file editable | |
//The file is editable if it was opened from the anomaly or comment level, otherwise it is not | |
//Check to get the position we should put the cursor on and the highlight range in the editor | |
if (element instanceof R4EUIAnomalyBasic) { | |
position = ((R4EUIAnomalyBasic) element).getPosition(); | |
} else if (element instanceof R4EUIComment) { | |
position = ((R4EUIAnomalyBasic) ((R4EUIComment) element).getParent()).getPosition(); | |
} else if (element instanceof R4EUIContent) { | |
position = ((R4EUIContent) element).getPosition(); | |
} | |
//Find the parent FileContextElement | |
while (!(element instanceof R4EUIFileContext)) { | |
element = ((IR4EUIModelElement) element).getParent(); | |
if (null == element) { | |
return; | |
} | |
} | |
context = ((R4EUIFileContext) element); | |
//Get files from FileContext | |
baseFileVersion = context.getBaseFileVersion(); | |
targetFileVersion = context.getTargetFileVersion(); | |
//If the files are the same (or do not exist), open the single editor | |
if (null == baseFileVersion || null == targetFileVersion | |
|| baseFileVersion.getVersionID().equals(targetFileVersion.getVersionID())) { | |
forceSingleEditor = true; | |
} | |
//Check if the base file is set, if so, we will use the compare editor. Otherwise we use the normal editor of the appropriate type | |
if (context.isFileVersionsComparable() && !forceSingleEditor) { | |
openCompareEditor(aPage, baseFileVersion, targetFileVersion); | |
} else { | |
if (null != targetFileVersion) { | |
openSingleEditor(aPage, targetFileVersion, position); | |
} else { | |
//File was removed, open the base then | |
openSingleEditor(aPage, baseFileVersion, position); | |
} | |
} | |
} | |
} | |
/** | |
* Method openSingleEditor. Open the single-mode default editor for the file type | |
* | |
* @param aPage | |
* IWorkbenchPage - the current workbench page | |
* @param aFileVersion | |
* R4EFileVersion - the file version | |
* @param aPosition | |
* IR4EUIPosition - the position to go to in the file | |
*/ | |
private static void openSingleEditor(IWorkbenchPage aPage, R4EFileVersion aFileVersion, IR4EUIPosition aPosition) { | |
try { | |
IStorageEditorInput editorInput = null; | |
//NOTE: We use the workspace file as input if it is in sync with the file to review, | |
// otherwise we use the file to review that is included in the review repository | |
if (CommandUtils.useWorkspaceResource(aFileVersion)) { | |
editorInput = new R4EFileEditorInput(aFileVersion); | |
} else { | |
editorInput = new R4EFileRevisionEditorInput(aFileVersion); | |
} | |
final String id = getEditorId(editorInput.getName(), | |
getContentType(editorInput.getName(), editorInput.getStorage().getContents())); | |
final IEditorPart editor = aPage.openEditor(editorInput, id, OpenStrategy.activateOnOpen()); | |
//Set highlighted selection and reset cursor if possible | |
if (editor instanceof ITextEditor && aPosition instanceof R4EUITextPosition) { | |
((ITextEditor) editor).setHighlightRange(((R4EUITextPosition) aPosition).getOffset(), | |
((R4EUITextPosition) aPosition).getLength(), true); | |
final TextSelection selectedText = new TextSelection(((R4EUITextPosition) aPosition).getOffset(), | |
((R4EUITextPosition) aPosition).getLength()); | |
((ITextEditor) editor).getSelectionProvider().setSelection(selectedText); | |
} | |
} catch (CoreException e) { | |
UIUtils.displayCoreErrorDialog(e); | |
} | |
} | |
/** | |
* Method openCompareEditor. Open the compare-mode default editor for the file types | |
* | |
* @param aPage | |
* IWorkbenchPage - the current workbench page | |
* @param aBaseFileVersion | |
* R4EFileVersion - the base (or reference) file version | |
* @param aTargetFileVersion | |
* R4EFileVersion - the target (or current) file version | |
*/ | |
private static void openCompareEditor(IWorkbenchPage aPage, R4EFileVersion aBaseFileVersion, | |
R4EFileVersion aTargetFileVersion) { | |
//Reuse editor if it is already open on the same input | |
CompareEditorInput input = null; | |
final IEditorPart editor = findReusableCompareEditor(aPage, aBaseFileVersion, aTargetFileVersion); | |
if (null != editor) { | |
aPage.activate(editor); //Simply provide focus to editor | |
//Go to the correct element in the compare editor | |
UIUtils.selectElementInEditor((R4ECompareEditorInput) editor.getEditorInput()); | |
} else { | |
input = CommandUtils.createCompareEditorInput(aBaseFileVersion, aTargetFileVersion); | |
input.setTitle(R4E_COMPARE_EDITOR_TITLE); // Adjust the compare title | |
R4EUIPlugin.Ftracer.traceInfo("Open compare editor on files " | |
+ ((null != aTargetFileVersion) ? aTargetFileVersion.getName() : "") + " (Target) and " | |
+ ((null != aBaseFileVersion) ? aBaseFileVersion.getName() : "") + " (Base)"); | |
CompareUI.openCompareEditor(input, true); | |
//NOTE: The position is set in editor in R4ECompareEditorInput#createContents | |
} | |
} | |
/** | |
* Method findReusableCompareEditor. Find the appropriate compare editor based on the file types | |
* | |
* @param aPage | |
* IWorkbenchPage - the current workbench page | |
* @param aBaseFile | |
* R4EFileVersion - the base (or reference) file version | |
* @param aTargetFile | |
* R4EFileVersion - the target file version | |
* @return IEditorPart - the editor to use | |
*/ | |
public static IEditorPart findReusableCompareEditor(IWorkbenchPage aPage, R4EFileVersion aBaseFile, | |
R4EFileVersion aTargetFile) { | |
final IEditorReference[] editorRefs = aPage.getEditorReferences(); | |
IEditorPart part = null; | |
R4ECompareEditorInput input = null; | |
ITypedElement left = null; | |
ITypedElement right = null; | |
// first loop looking for an editor with the same input | |
for (IEditorReference editorRef : editorRefs) { | |
part = editorRef.getEditor(false); | |
if (null != part && part instanceof IReusableEditor) { | |
// check if the editor input type complies with the types given by the caller | |
if (R4ECompareEditorInput.class.isInstance(part.getEditorInput())) { | |
//Now check if the input files are the same as with the found editor | |
input = (R4ECompareEditorInput) part.getEditorInput(); | |
left = input.getLeftElement(); | |
right = input.getRightElement(); | |
//Case: No input in editor, that should never happen but guard here just in case | |
if (null == left && null == right) { | |
return null; | |
} | |
//Get the file versions | |
R4EFileVersion leftVersion = null; | |
R4EFileVersion rightVersion = null; | |
if (left instanceof R4EFileRevisionTypedElement) { | |
leftVersion = ((R4EFileRevisionTypedElement) left).getFileVersion(); | |
} else if (left instanceof R4EFileTypedElement) { | |
leftVersion = ((R4EFileTypedElement) left).getFileVersion(); | |
} | |
if (right instanceof R4EFileRevisionTypedElement) { | |
rightVersion = ((R4EFileRevisionTypedElement) right).getFileVersion(); | |
} else if (right instanceof R4EFileTypedElement) { | |
rightVersion = ((R4EFileTypedElement) right).getFileVersion(); | |
} | |
//Case: No target file and base is the same | |
if (null == leftVersion && null == aTargetFile && null != rightVersion && null != aBaseFile | |
&& rightVersion.equals(aBaseFile)) { | |
return part; | |
} | |
//Case: No base file and target is the same | |
if (null == rightVersion && null == aBaseFile && null != leftVersion && null != aTargetFile | |
&& leftVersion.equals(aTargetFile)) { | |
return part; | |
} | |
//Case: Base and target are the same | |
if (null != leftVersion && null != rightVersion && null != aBaseFile && null != aTargetFile) { | |
if (leftVersion.equals(aTargetFile) && rightVersion.equals(aBaseFile)) { | |
return part; | |
} | |
} | |
} | |
} | |
} | |
// no re-usable editor found | |
return null; | |
} | |
/** | |
* Method getEditorId. | |
* | |
* @param aFileName | |
* String | |
* @param aType | |
* IContentType | |
* @return String | |
*/ | |
private static String getEditorId(String aFileName, IContentType aType) { | |
final IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); | |
final IEditorDescriptor descriptor = registry.getDefaultEditor(aFileName, aType); | |
String id = null; | |
if (null == descriptor || descriptor.isOpenExternal()) { | |
id = DEFAULT_EDITOR_NAME; | |
} else { | |
id = descriptor.getId(); | |
} | |
return id; | |
} | |
/** | |
* Method getContentType. | |
* | |
* @param aFileName | |
* String | |
* @param aContents | |
* InputStream | |
* @return IContentType | |
*/ | |
private static IContentType getContentType(String aFileName, InputStream aContents) { | |
IContentType type = null; | |
if (null != aContents) { | |
try { | |
type = Platform.getContentTypeManager().findContentTypeFor(aContents, aFileName); | |
} catch (IOException e) { | |
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")"); | |
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e); | |
} | |
} | |
if (null == type) { | |
type = Platform.getContentTypeManager().findContentTypeFor(aFileName); | |
} | |
return type; | |
} | |
} |