blob: d3598ec6857232b2e6351bd15e79dee7574f16ed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 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 navigator view context-menu command that is used to
* import postponed anomalies from other reviews
*
* 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.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
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.emf.common.util.EList;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.mylyn.reviews.frame.core.model.Comment;
import org.eclipse.mylyn.reviews.frame.core.model.Item;
import org.eclipse.mylyn.reviews.frame.core.model.Topic;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EAnomaly;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EAnomalyState;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EComment;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileContext;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EItem;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReview;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.CompatibilityException;
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.ui.R4EUIPlugin;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIComment;
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.R4EUIPostponedAnomaly;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIPostponedContainer;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIPostponedFile;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewBasic;
import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIReviewGroup;
import org.eclipse.mylyn.reviews.r4e.ui.internal.preferences.PreferenceConstants;
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.CommandUtils;
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.R4EUIConstants;
import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.UIUtils;
/**
* @author Sebastien Dubois
* @version $Revision: 1.0 $
*/
public class ImportPostponedHandler extends AbstractHandler {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
/**
* Field COMMAND_MESSAGE. (value is ""Importing Postponed Anomalies..."")
*/
private static final String COMMAND_MESSAGE = "Importing Postponed Anomalies...";
// ------------------------------------------------------------------------
// Methods
// ------------------------------------------------------------------------
/**
* Method execute.
*
* @param event
* ExecutionEvent
* @return Object
* @see org.eclipse.core.commands.IHandler#execute(ExecutionEvent)
*/
public Object execute(ExecutionEvent event) {
final Job job = new Job(COMMAND_MESSAGE) {
public String familyName = R4EUIConstants.R4E_UI_JOB_FAMILY;
@Override
public boolean belongsTo(Object family) {
return familyName.equals(family);
}
@Override
public IStatus run(IProgressMonitor monitor) {
R4EUIModelController.setJobInProgress(true);
final R4EUIReviewGroup parentGroup = (R4EUIReviewGroup) R4EUIModelController.getActiveReview()
.getParent();
monitor.beginTask(COMMAND_MESSAGE, parentGroup.getChildren().length);
importPostponedElements(true, monitor);
R4EUIModelController.setJobInProgress(false);
UIUtils.setNavigatorViewFocus(R4EUIModelController.getActiveReview().getPostponedContainer(),
AbstractTreeViewer.ALL_LEVELS);
monitor.done();
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();
return null;
}
/**
* Method importPostponedElements.
*
* @param aAddNewAnomalies
* - boolean
* @param aMonitor
* IProgressMonitor
*/
public static void importPostponedElements(boolean aAddNewAnomalies, IProgressMonitor aMonitor) {
final R4EUIReviewGroup parentGroup = (R4EUIReviewGroup) R4EUIModelController.getActiveReview().getParent();
//For each review in the parent review group, open it and look for postponed anomalies
//If one is found, add it to the imported postponed elements list
for (IR4EUIModelElement oldReview : parentGroup.getChildren()) {
try {
//Ignore current review
if (((R4EUIReviewBasic) oldReview).getName().equals(R4EUIModelController.getActiveReview().getName())) {
continue;
}
if (null != aMonitor) {
aMonitor.subTask("Processing Review: " + oldReview.getName());
}
List<R4EAnomaly> oldAnomalies = getAnomalies((R4EUIReviewBasic) oldReview);
for (R4EAnomaly oldAnomaly : oldAnomalies) {
try {
importAnomaly((R4EUIReviewBasic) oldReview, oldAnomaly, aAddNewAnomalies, aMonitor);
} catch (ResourceHandlingException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
}
}
//Once the anomalies are imported, verify if we should show them (If they are now not postponed we do not show them)
CommandUtils.showPostponedElements(R4EUIModelController.getActiveReview());
} catch (OutOfSyncException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
} catch (ResourceHandlingException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
} catch (CompatibilityException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
}
if (null != aMonitor) {
aMonitor.worked(1);
}
}
}
/**
* Method getAnomalies.
*
* @param aUiOldReview
* R4EUIReviewBasic
* @return List<R4EAnomaly>
*/
private static List<R4EAnomaly> getAnomalies(R4EUIReviewBasic aUiOldReview) {
final R4EReview currentReview = R4EUIModelController.getActiveReview().getReview();
final List<R4EAnomaly> anomaliesToConsider = new ArrayList<R4EAnomaly>();
//Open all old reviews, loop through all anomalies for the review, and check if there are
//any postponed anomalies on files that are included in the current review
try {
final R4EReview oldReview = R4EUIModelController.FModelExt.openR4EReview(
((R4EUIReviewGroup) aUiOldReview.getParent()).getReviewGroup(), aUiOldReview.getReview().getName());
final EList<Topic> oldAnomalies = oldReview.getTopics();
for (Topic oldAnomaly : oldAnomalies) {
//Get parent file
R4EFileVersion oldAnomalyFile = CommandUtils.getAnomalyParentFile((R4EAnomaly) oldAnomaly);
if (null == oldAnomalyFile) {
//Global anomaly
if (null == ((R4EAnomaly) oldAnomaly).getInfoAtt().get(
R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID)) {
anomaliesToConsider.add((R4EAnomaly) oldAnomaly);
}
} else {
for (Item currentItem : currentReview.getReviewItems()) {
//Ignore R4EUIPostponedContainer for current review here
if ((R4EUIConstants.TRUE_ATTR_VALUE_STR).equals(((R4EItem) currentItem).getInfoAtt().get(
R4EUIConstants.POSTPONED_ATTR_STR))) {
continue;
}
//NOTE: We compare the URI of the files. This means that in order to be considered,
//the version of the file in the current review need to be in the workspace. This is a limitation.
EList<R4EFileContext> currentFiles = ((R4EItem) currentItem).getFileContextList();
for (R4EFileContext currentFile : currentFiles) {
if (null != currentFile.getTarget()
&& null != currentFile.getTarget().getPlatformURI()
&& currentFile.getTarget().getPlatformURI().equals(oldAnomalyFile.getPlatformURI())
&& null == ((R4EAnomaly) oldAnomaly).getInfoAtt().get(
R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID)) {
anomaliesToConsider.add((R4EAnomaly) oldAnomaly);
}
}
}
}
}
R4EUIModelController.FModelExt.closeR4EReview(oldReview);
} catch (ResourceHandlingException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
} catch (CompatibilityException e) {
R4EUIPlugin.Ftracer.traceError("Exception: " + e.toString() + " (" + e.getMessage() + ")");
R4EUIPlugin.getDefault().logError("Exception: " + e.toString(), e);
}
return anomaliesToConsider;
}
/**
* Method importAnomaly.
*
* @param aUiReview
* R4EUIReviewBasic
* @param aOldAnomaly
* R4EAnomaly
* @param aAddNewAnomalies
* - boolean
* @param aMonitor
* IProgressMonitor
* @throws ResourceHandlingException
* @throws OutOfSyncException
*/
private static void importAnomaly(R4EUIReviewBasic aUiReview, R4EAnomaly aOldAnomaly, boolean aAddNewAnomalies,
IProgressMonitor aMonitor) throws ResourceHandlingException, OutOfSyncException {
//Lazily create the postponed elements container if not already done
R4EUIPostponedContainer uiPostponedContainer = R4EUIModelController.getActiveReview().getPostponedContainer();
if (null == uiPostponedContainer) {
if (aAddNewAnomalies) {
uiPostponedContainer = R4EUIModelController.getActiveReview().createPostponedContainer();
} else {
return; //Refresh only, do not create
}
}
//Lazily create the postponed file and add it to the postponed container, if not already done
final R4EFileVersion oldFile = CommandUtils.getAnomalyParentFile(aOldAnomaly);
if (null == oldFile) {
//Global Anomaly
if (R4EUIPlugin.getDefault()
.getPreferenceStore()
.getBoolean(PreferenceConstants.P_IMPORT_GLOBAL_ANOMALIES_POSTPONED)) {
importGlobalAnomaly(aUiReview, uiPostponedContainer, aOldAnomaly, aAddNewAnomalies, aMonitor);
}
} else {
importLocalAnomaly(aUiReview, uiPostponedContainer, aOldAnomaly, oldFile, aAddNewAnomalies, aMonitor);
}
}
/**
* Method importGlobalAnomaly.
*
* @param aUiPostponedContainer
* R4EUIPostponedContainer
* @param aOldAnomaly
* R4EAnomaly
* @param aAddNewAnomalies
* - boolean
* @throws ResourceHandlingException
* @throws OutOfSyncException
*/
private static void importGlobalAnomaly(R4EUIReviewBasic aUiReview, R4EUIPostponedContainer aUiPostponedContainer,
R4EAnomaly aOldAnomaly, boolean aAddNewAnomalies, IProgressMonitor aMonitor)
throws ResourceHandlingException, OutOfSyncException {
final IR4EUIModelElement[] uiGlobalAnomalies = aUiPostponedContainer.getAnomalyContainer().getChildren();
R4EUIPostponedAnomaly foundUiAnomaly = null;
for (IR4EUIModelElement uiAnomaly : uiGlobalAnomalies) {
R4EAnomaly anomaly = ((R4EUIPostponedAnomaly) uiAnomaly).getAnomaly();
String oldAnomalyId = CommandUtils.buildOriginalAnomalyID(aOldAnomaly);
if (oldAnomalyId.equals(anomaly.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID))) {
foundUiAnomaly = (R4EUIPostponedAnomaly) uiAnomaly;
break;
}
}
if (null == foundUiAnomaly) {
if (aAddNewAnomalies) {
//If the anomaly is new and is postponed, add it
if (aOldAnomaly.getState().equals(R4EAnomalyState.R4E_ANOMALY_STATE_DEFERRED)) {
if (null != aMonitor) {
aMonitor.subTask("Importing Postponed Global Anomaly for Review: " + aUiReview.getName());
}
final R4EUIPostponedAnomaly uiPostponedAnomaly = aUiPostponedContainer.getAnomalyContainer()
.createAnomaly(aUiReview, aOldAnomaly);
//Also add all child comments
final EList<Comment> comments = aOldAnomaly.getComments();
for (Comment comment : comments) {
uiPostponedAnomaly.createComment((R4EComment) comment);
}
}
}
} else {
foundUiAnomaly.updateAnomaly(aOldAnomaly);
if (foundUiAnomaly.isEnabled()) {
//Update anomaly comments
final EList<Comment> oldComments = aOldAnomaly.getComments();
final IR4EUIModelElement[] uiComments = foundUiAnomaly.getChildren();
for (Comment oldComment : oldComments) {
R4EUIComment foundUiComment = null;
for (IR4EUIModelElement uiComment : uiComments) {
R4EComment comment = ((R4EUIComment) uiComment).getComment();
String oldCommentId = CommandUtils.buildOriginalCommentID((R4EComment) oldComment);
if (oldCommentId.equals(comment.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_COMMENT_ID))) {
foundUiComment = (R4EUIComment) uiComment;
break;
}
}
if (null == foundUiComment) {
foundUiAnomaly.createComment((R4EComment) oldComment);
} //no alternative as comments are unmodifiable
}
}
}
}
/**
* Method importLocalAnomaly.
*
* @param aUiReview
* R4EUIReviewBasic
* @param aUiPostponedContainer
* R4EUIPostponedContainer
* @param aOldAnomaly
* R4EAnomaly
* @param aOldFile
* R4EFileVersion
* @param aAddNewAnomalies
* - boolean
* @throws ResourceHandlingException
* @throws OutOfSyncException
*/
private static void importLocalAnomaly(R4EUIReviewBasic aUiReview, R4EUIPostponedContainer aUiPostponedContainer,
R4EAnomaly aOldAnomaly, R4EFileVersion aOldFile, boolean aAddNewAnomalies, IProgressMonitor aMonitor)
throws ResourceHandlingException, OutOfSyncException {
final List<R4EUIFileContext> postponedUiFileContexts = aUiPostponedContainer.getFileContexts();
R4EUIPostponedFile uiPostponedFile = null;
for (R4EUIFileContext currentFileContext : postponedUiFileContexts) {
if (currentFileContext.getFileContext().getTarget().getVersionID().equals(aOldFile.getVersionID())) {
uiPostponedFile = (R4EUIPostponedFile) currentFileContext;
break;
}
}
if (null == uiPostponedFile) {
if (aAddNewAnomalies) {
uiPostponedFile = aUiPostponedContainer.createFileContext(aOldFile);
} else {
return; //Refresh only, do not create
}
}
//Add postponed anomaly if not already present. If present just update the anomaly values
final IR4EUIModelElement[] uiAnomalies = uiPostponedFile.getChildren();
R4EUIPostponedAnomaly foundUiAnomaly = null;
for (IR4EUIModelElement uiAnomaly : uiAnomalies) {
R4EAnomaly anomaly = ((R4EUIPostponedAnomaly) uiAnomaly).getAnomaly();
String oldAnomalyId = CommandUtils.buildOriginalAnomalyID(aOldAnomaly);
if (oldAnomalyId.equals(anomaly.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID))) {
foundUiAnomaly = (R4EUIPostponedAnomaly) uiAnomaly;
break;
}
}
if (null == foundUiAnomaly) {
if (aAddNewAnomalies) {
//If the anomaly is new and is postponed, add it
if (aOldAnomaly.getState().equals(R4EAnomalyState.R4E_ANOMALY_STATE_DEFERRED)) {
if (null != aMonitor) {
aMonitor.subTask("Importing Postponed Anomaly for Review: " + aUiReview.getName());
}
final R4EUIPostponedAnomaly uiPostponedAnomaly = uiPostponedFile.createAnomaly(aOldAnomaly,
aUiReview.getReview().getName());
//Also add all child comments
final EList<Comment> comments = aOldAnomaly.getComments();
for (Comment comment : comments) {
uiPostponedAnomaly.createComment((R4EComment) comment);
}
}
}
} else {
foundUiAnomaly.updateAnomaly(aOldAnomaly);
if (foundUiAnomaly.isEnabled()) {
//Update anomaly comments
final EList<Comment> oldComments = aOldAnomaly.getComments();
final IR4EUIModelElement[] uiComments = foundUiAnomaly.getChildren();
for (Comment oldComment : oldComments) {
R4EUIComment foundUiComment = null;
for (IR4EUIModelElement uiComment : uiComments) {
R4EComment comment = ((R4EUIComment) uiComment).getComment();
String oldCommentId = CommandUtils.buildOriginalCommentID((R4EComment) oldComment);
if (oldCommentId.equals(comment.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_COMMENT_ID))) {
foundUiComment = (R4EUIComment) uiComment;
break;
}
}
if (null == foundUiComment) {
foundUiAnomaly.createComment((R4EComment) oldComment);
} //no alternative as comments are unmodifiable
}
}
}
}
/**
* Method refreshPostponedElements.
*/
public static void refreshPostponedElements(IProgressMonitor aMonitor) {
importPostponedElements(false, aMonitor);
}
}