// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, com.instantiations.assist.eclipse.analysis.deserializeabilitySecurity, 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 implements the context-sensitive command to add a review item | |
* to a review | |
* | |
* Contributors: | |
* Sebastien Dubois - Created for Mylyn Review R4E project | |
* | |
******************************************************************************/ | |
package org.eclipse.mylyn.reviews.r4e.ui.internal.commands.handlers; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
import org.eclipse.core.commands.AbstractHandler; | |
import org.eclipse.core.commands.ExecutionEvent; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.core.runtime.jobs.Job; | |
import org.eclipse.jdt.core.IJavaElement; | |
import org.eclipse.jdt.core.ISourceReference; | |
import org.eclipse.jface.dialogs.ErrorDialog; | |
import org.eclipse.jface.text.ITextSelection; | |
import org.eclipse.jface.viewers.AbstractTreeViewer; | |
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.core.model.R4EFormalReview; | |
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReview; | |
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewComponent; | |
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewPhase; | |
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewType; | |
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.OutOfSyncException; | |
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.ResourceHandlingException; | |
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.ReviewsFileStorageException; | |
import org.eclipse.mylyn.reviews.r4e.ui.R4EUIPlugin; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIPosition; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIContent; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIContentsContainer; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIFileContext; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIModelController; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewBasic; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewItem; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUISelection; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUISelectionContainer; | |
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.MailServicesProxy; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.R4EUIConstants; | |
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.UIUtils; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.ui.IEditorInput; | |
import org.eclipse.ui.IEditorPart; | |
import org.eclipse.ui.PlatformUI; | |
import org.eclipse.ui.handlers.HandlerUtil; | |
import org.eclipse.ui.texteditor.ITextEditor; | |
/** | |
* @author Sebastien Dubois | |
* @version $Revision: 1.0 $ | |
*/ | |
public class NewReviewItemHandler extends AbstractHandler { | |
// ------------------------------------------------------------------------ | |
// Constants | |
// ------------------------------------------------------------------------ | |
/** | |
* Field COMMAND_MESSAGE. (value is ""Adding New Review Items..."") | |
*/ | |
private static final String COMMAND_MESSAGE = "Adding New Review Items..."; | |
// ------------------------------------------------------------------------ | |
// Methods | |
// ------------------------------------------------------------------------ | |
/** | |
* Method execute. | |
* | |
* @param event | |
* ExecutionEvent | |
* @return Object | |
* @see org.eclipse.core.commands.IHandler#execute(ExecutionEvent) | |
*/ | |
public Object execute(final ExecutionEvent event) { | |
final IEditorPart editorPart = PlatformUI.getWorkbench() | |
.getActiveWorkbenchWindow() | |
.getActivePage() | |
.getActiveEditor(); // $codepro.audit.disable methodChainLength | |
final IEditorInput input; | |
if (null != editorPart) { | |
input = PlatformUI.getWorkbench() | |
.getActiveWorkbenchWindow() | |
.getActivePage() | |
.getActiveEditor() | |
.getEditorInput(); // $codepro.audit.disable methodChainLength | |
} else { | |
input = null; | |
} | |
final Job job = new Job(COMMAND_MESSAGE) { | |
@Override | |
public IStatus run(IProgressMonitor monitor) { | |
final ISelection selection = HandlerUtil.getCurrentSelection(event); | |
R4EUIModelController.setJobInProgress(true); | |
//Act differently depending on the type of selection we get | |
if (selection instanceof ITextSelection) { | |
monitor.beginTask(COMMAND_MESSAGE, IProgressMonitor.UNKNOWN); | |
addReviewItemFromText((ITextSelection) selection, input); | |
} else if (selection instanceof IStructuredSelection) { | |
//First remove any editor selection (if open) if we execute the command from the review navigator view | |
if (null != editorPart && editorPart instanceof ITextEditor) { | |
((ITextEditor) editorPart).getSelectionProvider().setSelection(null); | |
} | |
//Then iterate through all selections | |
monitor.beginTask(COMMAND_MESSAGE, ((IStructuredSelection) selection).size()); | |
for (final Iterator<?> iterator = ((IStructuredSelection) selection).iterator(); iterator.hasNext();) { | |
addReviewItemFromTree(iterator.next(), monitor); | |
if (monitor.isCanceled()) { | |
R4EUIModelController.setJobInProgress(false); | |
return Status.CANCEL_STATUS; | |
} | |
} | |
} | |
R4EUIModelController.setJobInProgress(false); | |
return Status.OK_STATUS; | |
} | |
}; | |
job.setUser(true); | |
job.schedule(); | |
return null; | |
} | |
/** | |
* Method addReviewItemFromText. | |
* | |
* @param aSelection | |
* ITextSelection | |
* @param aInput | |
* - IEditorInput | |
*/ | |
private void addReviewItemFromText(ITextSelection aSelection, IEditorInput aInput) { | |
//This is a text selection in a text editor, we need to get the file path and | |
//the position of the selection within the file | |
try { | |
final IR4EUIPosition position = CommandUtils.getPosition(aSelection); | |
final R4EFileVersion baseVersion = CommandUtils.getBaseFileData(aInput); | |
final R4EFileVersion targetVersion = CommandUtils.getTargetFileData(aInput); | |
//Add selection to model | |
if (null != targetVersion) { | |
addReviewItem(baseVersion, targetVersion, position); | |
} else { | |
R4EUIPlugin.Ftracer.traceWarning("Trying to add review item to base file"); | |
final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, | |
"Add Review Item Error", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, | |
"No Target File present to Add Review Item", null), IStatus.ERROR); | |
Display.getDefault().syncExec(new Runnable() { | |
public void run() { | |
dialog.open(); | |
} | |
}); | |
} | |
} catch (CoreException e) { | |
UIUtils.displayCoreErrorDialog(e); | |
} catch (ReviewsFileStorageException e) { | |
UIUtils.displayReviewsFileStorageErrorDialog(e); | |
} | |
} | |
/** | |
* Method addReviewItemFromTree. | |
* | |
* @param aSelection | |
* ITreeSelection | |
* @param aMonitor | |
* IProgressMonitor | |
*/ | |
private void addReviewItemFromTree(Object aSelection, IProgressMonitor aMonitor) { | |
//This is a selection from the tree view (e.g. Review Navigator, Package Explorer etc...) | |
//We will need to get the parent file path and the position of the element in a text editor | |
//If the selection is on the File itself, then the selection will include all the lines | |
//in the file. Otherwise it will include all the lines corresponding to the currently | |
//selected element | |
try { | |
IR4EUIPosition position = null; | |
IFile workspaceFile = null; | |
//Next find out what kind of selection we are dealing with | |
if (aSelection instanceof IFile) { | |
position = CommandUtils.getPosition((IFile) aSelection); | |
workspaceFile = (IFile) aSelection; | |
} else if (R4EUIPlugin.isJDTAvailable() && aSelection instanceof ISourceReference) { | |
//NOTE: This is always true because all elements that implement ISourceReference | |
// also implement IJavaElement. The resource is always an IFile | |
workspaceFile = (IFile) ((IJavaElement) aSelection).getResource(); | |
//TODO is that the right file to get the position??? | |
position = CommandUtils.getPosition((ISourceReference) aSelection, workspaceFile); | |
} else if (R4EUIPlugin.isCDTAvailable() | |
&& aSelection instanceof org.eclipse.cdt.core.model.ISourceReference) { | |
//NOTE: This is always true because all elements that implement ISourceReference | |
// also implement ICElement. The resource is always an IFile | |
//TO Fix this causes an error java.lang.ClassCastException: org.eclipse.core.internal.resources.Project cannot be cast to org.eclipse.core.resources.IFile | |
org.eclipse.cdt.core.model.ICElement cdtElement = (org.eclipse.cdt.core.model.ICElement) aSelection; | |
while (null != cdtElement) { | |
if (cdtElement.getResource() instanceof IFile) { | |
workspaceFile = (IFile) cdtElement.getResource(); | |
break; | |
} | |
cdtElement = cdtElement.getParent(); | |
} | |
if (null == workspaceFile) { | |
//This should never happen | |
return; | |
} | |
//NOTE: When selecting whole CDT File, the position is always set to line 0. This is what is returned by CDT | |
position = CommandUtils.getPosition((org.eclipse.cdt.core.model.ISourceReference) aSelection, | |
workspaceFile); | |
} else { | |
//This should never happen | |
R4EUIPlugin.Ftracer.traceWarning("Invalid selection " + aSelection.getClass().toString() | |
+ ". Ignoring"); | |
return; | |
} | |
//Add selection to model | |
final R4EFileVersion baseVersion = CommandUtils.updateBaseFile(workspaceFile); | |
final R4EFileVersion targetVersion = CommandUtils.updateTargetFile(workspaceFile); | |
//Add selection to model | |
if (null != targetVersion) { | |
aMonitor.subTask("Adding " + targetVersion.getName()); | |
addReviewItem(baseVersion, targetVersion, position); | |
aMonitor.worked(1); | |
} else { | |
R4EUIPlugin.Ftracer.traceWarning("Trying to add review item to base file"); | |
final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, | |
"Add Review Item Error", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, 0, | |
"No Target File present to Add Review Item", null), IStatus.ERROR); | |
Display.getDefault().syncExec(new Runnable() { | |
public void run() { | |
dialog.open(); | |
} | |
}); | |
} | |
} catch (CoreException e) { | |
UIUtils.displayCoreErrorDialog(e); | |
} catch (ReviewsFileStorageException e) { | |
UIUtils.displayReviewsFileStorageErrorDialog(e); | |
} | |
} | |
/** | |
* // $codepro.audit.disable blockDepth Method AddReviewItem. Adds a review item to the model based on user input | |
* | |
* @param aUIPosition | |
* IR4EUIPosition | |
* @param aBaseFileVersion | |
* R4EFileVersion | |
* @param aTargetFileVersion | |
* R4EFileVersion | |
*/ | |
private void addReviewItem(R4EFileVersion aBaseFileVersion, R4EFileVersion aTargetFileVersion, | |
IR4EUIPosition aUIPosition) { | |
try { | |
//Check if the file element and/or selection already exist | |
//If file exists, add selection element to it | |
//if selection element already exist, ignore command | |
//for all other cases, create the parent elements as needed as well. | |
final List<R4EUIReviewItem> reviewItems = R4EUIModelController.getActiveReview().getReviewItems(); | |
boolean newSelection = true; | |
for (R4EUIReviewItem reviewItem : reviewItems) { | |
R4EUIFileContext[] files = (R4EUIFileContext[]) reviewItem.getChildren(); | |
for (R4EUIFileContext file : files) { | |
if (null != file.getFileContext().getTarget() | |
&& aTargetFileVersion.getLocalVersionID().equals( | |
file.getFileContext().getTarget().getLocalVersionID())) { | |
if ((null == file.getFileContext().getBase() && (null == aBaseFileVersion || "".equals(aBaseFileVersion.getVersionID()))) | |
|| (null != file.getFileContext().getBase() && null != aBaseFileVersion && aBaseFileVersion.getLocalVersionID() | |
.equals(file.getFileContext().getBase().getLocalVersionID()))) { | |
//File already exists, check if selection also exists | |
R4EUIContentsContainer contentContainer = file.getContentsContainerElement(); | |
if (!(contentContainer instanceof R4EUISelectionContainer)) { | |
//If this is a Commit element, we skip it | |
continue; | |
} | |
R4EUIContent[] contentElements = (R4EUIContent[]) contentContainer.getChildren(); | |
for (R4EUIContent contentElement : contentElements) { | |
if (contentElement.getPosition().isSameAs(aUIPosition)) { | |
newSelection = false; | |
} | |
} | |
if (newSelection) { | |
addReviewItemToExistingFileContext((R4EUISelectionContainer) contentContainer, | |
aUIPosition); | |
R4EUIPlugin.Ftracer.traceInfo("Added review item: Target = " | |
+ file.getFileContext().getTarget().getName() | |
+ ((null != file.getFileContext().getBase()) ? "Base = " | |
+ file.getFileContext().getBase().getName() : "") + " Position = " | |
+ aUIPosition.toString()); | |
} else { | |
//The selection already exists so ignore command | |
R4EUIPlugin.Ftracer.traceWarning("Review Item already exists. Ignoring"); | |
final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_WARNING, | |
"Cannot add Review Item", new Status(IStatus.WARNING, R4EUIPlugin.PLUGIN_ID, 0, | |
"Review Item already exists", null), IStatus.WARNING); | |
Display.getDefault().syncExec(new Runnable() { | |
public void run() { | |
dialog.open(); | |
} | |
}); | |
} | |
return; //We found the file so we are done here | |
} | |
} | |
} | |
} | |
//This is a new file create it (and its parent reviewItem) and all its children | |
addReviewItemToNewFileContext(aBaseFileVersion, aTargetFileVersion, aUIPosition); | |
R4EUIPlugin.Ftracer.traceInfo("Added Review Item: Target = " | |
+ aTargetFileVersion.getName() | |
+ "_" | |
+ aTargetFileVersion.getVersionID() | |
+ ((null != aBaseFileVersion) ? "Base = " + aBaseFileVersion.getName() + "_" | |
+ aBaseFileVersion.getVersionID() : "") + " Position = " + aUIPosition.toString()); | |
} catch (ResourceHandlingException e) { | |
UIUtils.displayResourceErrorDialog(e); | |
} catch (OutOfSyncException e) { | |
UIUtils.displaySyncErrorDialog(e); | |
} catch (CoreException e) { | |
UIUtils.displayCoreErrorDialog(e); | |
} | |
} | |
/** | |
* Method addReviewItemToExistingFileContext. | |
* | |
* @param aContainer | |
* R4EUISelectionContainer | |
* @param aUIPosition | |
* IR4EUIPosition | |
* @throws ResourceHandlingException | |
* @throws OutOfSyncException | |
*/ | |
private void addReviewItemToExistingFileContext(R4EUISelectionContainer aContainer, IR4EUIPosition aUIPosition) | |
throws ResourceHandlingException, OutOfSyncException { | |
final R4EUISelection uiSelection = aContainer.createSelection((R4EUITextPosition) aUIPosition); | |
R4EUIModelController.setJobInProgress(false); | |
UIUtils.setNavigatorViewFocus(uiSelection, AbstractTreeViewer.ALL_LEVELS); | |
} | |
/** | |
* Method addReviewItemToNewFileContext. | |
* | |
* @param aBaseFileVersion | |
* R4EFileVersion | |
* @param aTargetFileVersion | |
* R4EFileVersion | |
* @param aUIPosition | |
* IR4EUIPosition | |
* @throws ResourceHandlingException | |
* @throws OutOfSyncException | |
* @throws CoreException | |
*/ | |
private void addReviewItemToNewFileContext(R4EFileVersion aBaseFileVersion, R4EFileVersion aTargetFileVersion, | |
IR4EUIPosition aUIPosition) throws ResourceHandlingException, OutOfSyncException, CoreException { | |
final R4EUIReviewBasic uiReview = R4EUIModelController.getActiveReview(); | |
final R4EUIReviewItem uiReviewItem = uiReview.createResourceReviewItem(aTargetFileVersion.getName()); | |
if (null == uiReviewItem) { | |
return; | |
} | |
//NOTE: Resource Review Items always only have a target file | |
final R4EUIFileContext uiFileContext = uiReviewItem.createFileContext(aBaseFileVersion, aTargetFileVersion, | |
null); | |
if (null == uiFileContext) { | |
uiReview.removeChildren(uiReviewItem, false); | |
return; | |
} | |
final R4EUISelectionContainer uiSelectionContainer = (R4EUISelectionContainer) uiFileContext.getContentsContainerElement(); | |
uiSelectionContainer.createSelection((R4EUITextPosition) aUIPosition); | |
R4EUIModelController.setJobInProgress(false); | |
UIUtils.setNavigatorViewFocus(uiReviewItem, 1); | |
//Send email notification if needed | |
final List<R4EReviewComponent> addedItems = new ArrayList<R4EReviewComponent>(); | |
addedItems.add(uiReviewItem.getItem()); | |
final R4EReview review = uiReview.getReview(); | |
if (review.getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL)) { | |
if (((R4EFormalReview) review).getCurrent().getType().equals(R4EReviewPhase.R4E_REVIEW_PHASE_PREPARATION)) { | |
MailServicesProxy.sendItemsAddedNotification(addedItems); | |
} | |
} | |
} | |
} |