| // $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString, 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 implements the Anomaly Container element of the UI model |
| * |
| * Contributors: |
| * Sebastien Dubois - Created for Mylyn Review R4E project |
| * |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.reviews.r4e.ui.internal.model; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| 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.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.viewers.AbstractTreeViewer; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.mylyn.reviews.core.model.ILocation; |
| import org.eclipse.mylyn.reviews.core.model.IReviewComponent; |
| import org.eclipse.mylyn.reviews.core.model.ITopic; |
| 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.R4EAnomalyTextPosition; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4ECommentType; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EContent; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EDecision; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EParticipant; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewPhase; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewState; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewType; |
| import org.eclipse.mylyn.reviews.r4e.core.model.RModelFactory; |
| import org.eclipse.mylyn.reviews.r4e.core.model.drules.R4EDesignRule; |
| 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.dialogs.IAnomalyInputDialog; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.dialogs.R4EUIDialogFactory; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.navigator.ReviewNavigatorContentProvider; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.preferences.PreferenceConstants; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.utils.AnomalyUtils; |
| 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; |
| import org.eclipse.swt.widgets.Display; |
| |
| /** |
| * @author Sebastien Dubois |
| * @version $Revision: 1.0 $ |
| */ |
| public class R4EUIAnomalyContainer extends R4EUIModelElement { |
| |
| // ------------------------------------------------------------------------ |
| // Constants |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Field fAnomalyContainerFile. (value is ""icons/obj16/anmlycont_obj.gif"") |
| */ |
| public static final String ANOMALY_CONTAINER_ICON_FILE = "icons/obj16/anmlycont_obj.gif"; |
| |
| /** |
| * Field NEW_CHILD_ELEMENT_COMMAND_NAME. (value is ""New Anomaly..."") |
| */ |
| private static final String NEW_CHILD_ELEMENT_COMMAND_NAME = "New Anomaly..."; |
| |
| /** |
| * Field NEW_CHILD_ELEMENT_COMMAND_TOOLTIP. (value is ""Add a New Global Anomaly to the Current Review Item"") |
| */ |
| private static final String NEW_CHILD_ELEMENT_COMMAND_TOOLTIP = "Add a New Global Anomaly to the Current Review Item"; |
| |
| /** |
| * Field CREATE_ANOMALY_MESSAGE. (value is ""Creating New Anomaly..."") |
| */ |
| public static final String CREATE_ANOMALY_MESSAGE = "Creating New Anomaly..."; |
| |
| /** |
| * Field ANOMALY_COMPARATOR. |
| */ |
| private static final Comparator<R4EUIAnomalyBasic> ANOMALY_COMPARATOR = new Comparator<R4EUIAnomalyBasic>() { |
| // This is where the sorting happens. |
| public int compare(R4EUIAnomalyBasic aAnomaly1, R4EUIAnomalyBasic aAnomaly2) { |
| if (aAnomaly1.getPosition() == null || aAnomaly2.getPosition() == null) { |
| //Compare by date as second option i.e. Global Anomalies |
| //CreatedOn shall be present i.e.expecting well formed anomalies |
| Date date1 = aAnomaly1.fAnomaly.getCreatedOn(); |
| Date date2 = aAnomaly2.fAnomaly.getCreatedOn(); |
| return date1.compareTo(date2); |
| } |
| |
| final int sortOrder = ((R4EUITextPosition) aAnomaly1.getPosition()).getOffset() |
| - ((R4EUITextPosition) aAnomaly2.getPosition()).getOffset(); |
| if (sortOrder == 0) { |
| return ((R4EUITextPosition) aAnomaly1.getPosition()).getLength() |
| - ((R4EUITextPosition) aAnomaly2.getPosition()).getLength(); |
| } |
| return sortOrder; |
| } |
| }; |
| |
| // ------------------------------------------------------------------------ |
| // Member variables |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Field fAnomalies. |
| */ |
| protected final List<R4EUIAnomalyBasic> fAnomalies; |
| |
| // ------------------------------------------------------------------------ |
| // Constructors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Constructor for AnomalyContainerElement. |
| * |
| * @param aParent |
| * IR4EUIModelElement |
| * @param aName |
| * String |
| */ |
| public R4EUIAnomalyContainer(IR4EUIModelElement aParent, String aName) { |
| super(aParent, aName); |
| fReadOnly = aParent.isReadOnly(); |
| fAnomalies = new ArrayList<R4EUIAnomalyBasic>(); |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Methods |
| // ------------------------------------------------------------------------ |
| |
| //Attributes |
| |
| /** |
| * Method getImageLocation. |
| * |
| * @return String |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#getImageLocation() |
| */ |
| public String getImageLocation() { |
| return ANOMALY_CONTAINER_ICON_FILE; |
| } |
| |
| /** |
| * Method createDetachedAnomaly. |
| * |
| * @return R4EAnomaly |
| */ |
| public static R4EAnomaly createDetachedAnomaly(boolean aClone) { |
| //Get comment from user and set it in model data |
| R4EAnomaly tempAnomaly = null; |
| final IAnomalyInputDialog dialog; |
| if (aClone) { |
| dialog = R4EUIDialogFactory.getInstance().getCloneAnomalyInputDialog(); |
| } else { |
| dialog = R4EUIDialogFactory.getInstance().getNewAnomalyInputDialog(); |
| } |
| final int[] result = new int[1]; //We need this to be able to pass the result value outside. This is safe as we are using SyncExec |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| result[0] = dialog.open(); |
| } |
| }); |
| |
| if (result[0] == Window.OK) { |
| tempAnomaly = RModelFactory.eINSTANCE.createR4EAnomaly(); |
| final R4ECommentType tempCommentType = RModelFactory.eINSTANCE.createR4ECommentType(); |
| tempAnomaly.setTitle(dialog.getAnomalyTitleValue()); |
| tempAnomaly.setDescription(dialog.getAnomalyDescriptionValue()); |
| tempAnomaly.setDueDate(dialog.getDueDate()); |
| tempAnomaly.getAssignedTo().add(dialog.getAssigned()); |
| if (null != dialog.getRuleReferenceValue()) { |
| final R4EDesignRule rule = dialog.getRuleReferenceValue(); |
| tempCommentType.setType(rule.getClass_()); |
| tempAnomaly.setType(tempCommentType); |
| tempAnomaly.setRank(rule.getRank()); |
| tempAnomaly.setRuleID(rule.getId()); |
| } else { |
| if (null != dialog.getClass_()) { |
| final R4ECommentType commentType = RModelFactory.eINSTANCE.createR4ECommentType(); |
| commentType.setType(dialog.getClass_()); |
| tempAnomaly.setType(commentType); |
| } |
| if (null != dialog.getRank()) { |
| tempAnomaly.setRank(dialog.getRank()); |
| } |
| } |
| } |
| return tempAnomaly; |
| } |
| |
| /** |
| * Create a serialization model element object |
| * |
| * @return the new serialization element object |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#createChildModelDataElement() |
| */ |
| @Override |
| public List<IReviewComponent> createChildModelDataElement() { |
| //Get Anomaly from user and set it in model data |
| final List<IReviewComponent> tempAnomalies = new ArrayList<IReviewComponent>(); |
| R4EUIModelController.setJobInProgress(true); |
| |
| final IAnomalyInputDialog dialog = R4EUIDialogFactory.getInstance().getNewAnomalyInputDialog(); |
| final int result = dialog.open(); |
| if (result == Window.OK) { |
| final R4EAnomaly tempAnomaly = RModelFactory.eINSTANCE.createR4EAnomaly(); |
| setAnomalyWithDialogValues(tempAnomaly, dialog); |
| tempAnomalies.add(tempAnomaly); |
| } |
| R4EUIModelController.setJobInProgress(false); |
| |
| return tempAnomalies; |
| } |
| |
| //Hierarchy |
| |
| /** |
| * Method getChildren. |
| * |
| * @return IR4EUIModelElement[] |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#getChildren() |
| */ |
| @Override |
| public IR4EUIModelElement[] getChildren() { // $codepro.audit.disable |
| return fAnomalies.toArray(new R4EUIAnomalyBasic[fAnomalies.size()]); |
| } |
| |
| /** |
| * Method hasChildren. |
| * |
| * @return boolean |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#hasChildren() |
| */ |
| @Override |
| public boolean hasChildren() { |
| if (fAnomalies.size() > 0) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Close the model element (i.e. disable it) |
| * |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#close() |
| */ |
| @Override |
| public void close() { |
| //Remove all children references |
| R4EUIAnomalyBasic anomaly = null; |
| final int anomaliesSize = fAnomalies.size(); |
| for (int i = 0; i < anomaliesSize; i++) { |
| |
| anomaly = fAnomalies.get(i); |
| anomaly.close(); |
| //fireRemove(anomaly); |
| } |
| fAnomalies.clear(); |
| fOpen = false; |
| } |
| |
| /** |
| * Method open. Load the serialization model data into UI model |
| * |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#open() |
| */ |
| @Override |
| public void open() { |
| |
| R4EUIAnomalyBasic uiAnomaly = null; |
| final IR4EUIModelElement parentElement = getParent(); |
| if (parentElement instanceof R4EUIFileContext) { |
| //get anomalies that are specific to a file |
| final List<R4EAnomaly> anomalies = ((R4EUIFileContext) parentElement).getAnomalies(); |
| R4EUITextPosition position = null; |
| final int anomaliesSize = anomalies.size(); |
| R4EAnomaly anomaly = null; |
| for (int i = 0; i < anomaliesSize; i++) { |
| anomaly = anomalies.get(i); |
| if (null != anomaly.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID)) { |
| //This is a postponed anomaly, so we ignore it |
| continue; |
| } |
| |
| if (anomaly.isEnabled() |
| || R4EUIPlugin.getDefault() |
| .getPreferenceStore() |
| .getBoolean(PreferenceConstants.P_SHOW_DISABLED)) { |
| //Do not set position for global List<E>lies |
| position = null; |
| List<ILocation> locations = anomalies.get(i).getLocations(); // $codepro.audit.disable variableDeclaredInLoop |
| if (null != locations) { |
| if (null != locations.get(0)) { |
| int locationsSize = locations.size(); // $codepro.audit.disable variableDeclaredInLoop |
| for (int j = 0; j < locationsSize; j++) { |
| position = new R4EUITextPosition( |
| ((R4EContent) anomalies.get(i).getLocations().get(j)).getLocation()); // $codepro.audit.disable methodChainLength |
| if (((R4EUIReviewBasic) getParent().getParent().getParent()).getReview() |
| .getType() |
| .equals(R4EReviewType.BASIC)) { |
| uiAnomaly = new R4EUIAnomalyBasic(this, anomalies.get(i), position); |
| } else { |
| uiAnomaly = new R4EUIAnomalyExtended(this, anomalies.get(i), position); |
| uiAnomaly.setName(R4EUIAnomalyExtended.getStateString(anomalies.get(i).getState()) |
| + ": " + uiAnomaly.getName()); |
| } |
| |
| addChildren(uiAnomaly); |
| if (uiAnomaly.isEnabled()) { |
| uiAnomaly.open(); |
| } |
| } |
| } else { |
| uiAnomaly = new R4EUIAnomalyBasic(this, anomalies.get(i), null); |
| addChildren(uiAnomaly); |
| if (uiAnomaly.isEnabled()) { |
| uiAnomaly.open(); |
| } |
| } |
| } |
| } |
| } |
| } else if (parentElement instanceof R4EUIReviewBasic) { |
| //Get anomalies that do not have any location. These are global anomalies |
| final List<ITopic> anomalies = ((R4EUIReviewBasic) parentElement).getReview().getTopics(); |
| if (null != anomalies) { |
| final int anomaliesSize = anomalies.size(); |
| R4EAnomaly anomaly = null; |
| for (int i = 0; i < anomaliesSize; i++) { |
| anomaly = (R4EAnomaly) anomalies.get(i); |
| if (null != anomaly.getInfoAtt().get(R4EUIConstants.POSTPONED_ATTR_ORIG_ANOMALY_ID)) { |
| //This is a postponed anomaly, so we ignore it |
| continue; |
| } |
| if (anomaly.isEnabled() |
| || R4EUIPlugin.getDefault() |
| .getPreferenceStore() |
| .getBoolean(PreferenceConstants.P_SHOW_DISABLED)) { |
| if (0 == anomaly.getLocations().size()) { |
| if (((R4EUIReviewBasic) getParent()).getReview() |
| .getType() |
| .equals(R4EReviewType.BASIC)) { |
| uiAnomaly = new R4EUIAnomalyBasic(this, anomaly, null); |
| } else { |
| uiAnomaly = new R4EUIAnomalyExtended(this, anomaly, null); |
| uiAnomaly.setName(R4EUIAnomalyExtended.getStateString(anomaly.getState()) + ": " |
| + uiAnomaly.getName()); |
| } |
| addChildren(uiAnomaly); |
| if (uiAnomaly.isEnabled()) { |
| uiAnomaly.open(); |
| } |
| } |
| } |
| } |
| } |
| } |
| fOpen = true; |
| } |
| |
| /** |
| * Method isEnabled. |
| * |
| * @return boolean |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#isEnabled() |
| */ |
| @Override |
| public boolean isEnabled() { |
| if (getParent().isEnabled()) { |
| if (0 == fAnomalies.size()) { |
| return true; |
| } |
| for (R4EUIAnomalyBasic anomaly : fAnomalies) { |
| if (anomaly.isEnabled()) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Method setReadOnly. |
| * |
| * @param aReadOnly |
| * boolean |
| */ |
| public void setReadOnly(boolean aReadOnly) { |
| fReadOnly = aReadOnly; |
| } |
| |
| /** |
| * Method addChildren. |
| * |
| * @param aChildToAdd |
| * IR4EUIModelElement |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#addChildren(IR4EUIModelElement) |
| */ |
| @Override |
| public void addChildren(IR4EUIModelElement aChildToAdd) { |
| fAnomalies.add((R4EUIAnomalyBasic) aChildToAdd); |
| Collections.sort(fAnomalies, ANOMALY_COMPARATOR); |
| } |
| |
| /** |
| * Method createChildren |
| * |
| * @param aModelComponent |
| * - the serialization model component object |
| * @return IR4EUIModelElement |
| * @throws ResourceHandlingException |
| * @throws OutOfSyncException |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#createChildren(ReviewNavigatorContentProvider) |
| */ |
| @Override |
| public IR4EUIModelElement createChildren(IReviewComponent aModelComponent) throws ResourceHandlingException, |
| OutOfSyncException { |
| final String user = R4EUIModelController.getReviewer(); |
| final R4EAnomaly anomaly = R4EUIModelController.FModelExt.createR4EAnomaly(R4EUIModelController.getActiveReview() |
| .getParticipant(user, true)); |
| final Long bookNum = R4EUIModelController.FResourceUpdater.checkOut(anomaly, R4EUIModelController.getReviewer()); |
| anomaly.setTitle(((R4EAnomaly) aModelComponent).getTitle()); //This is needed as the global anomaly title is displayed in the navigator view |
| R4EUIModelController.FResourceUpdater.checkIn(bookNum); |
| R4EUIAnomalyBasic addedChild = null; |
| if (R4EUIModelController.getActiveReview().getReview().getType().equals(R4EReviewType.BASIC)) { |
| addedChild = new R4EUIAnomalyBasic(this, anomaly, null); |
| } else { |
| addedChild = new R4EUIAnomalyExtended(this, anomaly, null); |
| if (R4EUIModelController.getActiveReview() |
| .getReview() |
| .getType() |
| .equals(R4EReviewType.FORMAL)) { |
| ((R4EUIAnomalyExtended) addedChild).updateState(R4EAnomalyState.CREATED); |
| } else { //R4EReviewType.INFORMAL |
| ((R4EUIAnomalyExtended) addedChild).updateState(R4EAnomalyState.ASSIGNED); |
| } |
| } |
| addedChild.setModelData(aModelComponent); |
| addedChild.setExtraModelData(aModelComponent); |
| addChildren(addedChild); |
| return addedChild; |
| } |
| |
| /** |
| * Method createAnomaly Creates a new Anomaly from the user dialog |
| * |
| * @param aFile |
| * R4EFileVersion |
| * @param aUiPosition |
| * - the position of the anomaly to create |
| * @param aClone |
| * - flag set if this is a cloned anomaly |
| */ |
| public void createAnomaly(final R4EUIFileContext aFile, final R4EUITextPosition aUiPosition, boolean aClone) { |
| |
| //Get anomaly details from user |
| final IAnomalyInputDialog dialog; |
| if (aClone) { |
| dialog = R4EUIDialogFactory.getInstance().getCloneAnomalyInputDialog(); |
| } else { |
| dialog = R4EUIDialogFactory.getInstance().getNewAnomalyInputDialog(); |
| } |
| final int[] result = new int[1]; //We need this to be able to pass the result value outside. This is safe as we are using SyncExec |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| result[0] = dialog.open(); |
| } |
| }); |
| |
| //Create actual model element |
| if (result[0] == Window.OK) { |
| final Job job = new Job(CREATE_ANOMALY_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) { |
| |
| //First check if the anomaly already exist |
| final String existingAnomalyName = AnomalyUtils.isAnomalyExist(aFile, aUiPosition, |
| dialog.getAnomalyDescriptionValue()); |
| if (null == existingAnomalyName) { |
| //Create anomaly model element |
| try { |
| final R4EUIReviewBasic uiReview = R4EUIModelController.getActiveReview(); |
| final R4EParticipant participant = uiReview.getParticipant( |
| R4EUIModelController.getReviewer(), true); |
| final R4EAnomaly anomaly = R4EUIModelController.FModelExt.createR4EAnomaly(participant); |
| final Long bookNum = R4EUIModelController.FResourceUpdater.checkOut(anomaly, |
| R4EUIModelController.getReviewer()); |
| setAnomalyWithDialogValues(anomaly, dialog); |
| R4EUIModelController.FResourceUpdater.checkIn(bookNum); |
| final R4EUIAnomalyBasic uiAnomaly = createAnomalyDetails(anomaly, |
| aFile.getTargetFileVersion(), aUiPosition); |
| R4EUIModelController.setJobInProgress(false); |
| UIUtils.setNavigatorViewFocus(uiAnomaly, AbstractTreeViewer.ALL_LEVELS); |
| |
| //Add inline anomaly to editor (if applicable) |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| UIUtils.addAnnotation(uiAnomaly, aFile); |
| } |
| }); |
| |
| } catch (ResourceHandlingException e) { |
| UIUtils.displayResourceErrorDialog(e); |
| } catch (OutOfSyncException e) { |
| UIUtils.displaySyncErrorDialog(e); |
| } |
| monitor.done(); |
| return Status.OK_STATUS; |
| } else { |
| String msg = "Anomaly with same description already exist:" + R4EUIConstants.LINE_FEED |
| + "Anomaly: " + existingAnomalyName + R4EUIConstants.LINE_FEED + "File: " |
| + aFile.getFileContext().getTarget().getName() + R4EUIConstants.LINE_FEED |
| + "Position: " + aUiPosition.toString(); |
| R4EUIPlugin.Ftracer.traceWarning(msg); |
| final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, |
| "Cannot Add Anomaly", new Status(IStatus.WARNING, R4EUIPlugin.PLUGIN_ID, 0, msg, null), |
| IStatus.WARNING); |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| dialog.open(); |
| } |
| }); |
| |
| monitor.done(); |
| return Status.CANCEL_STATUS; |
| } |
| } |
| }; |
| job.setUser(true); |
| job.schedule(); |
| } |
| } |
| |
| /** |
| * Method setAnomalyWithDialogValues |
| * |
| * @param aAnomaly |
| * R4EAnomaly |
| * @param aDialog |
| * AnomalyInputDialog |
| */ |
| private void setAnomalyWithDialogValues(R4EAnomaly aAnomaly, IAnomalyInputDialog aDialog) { |
| |
| aAnomaly.setTitle(aDialog.getAnomalyTitleValue()); |
| aAnomaly.setDescription(aDialog.getAnomalyDescriptionValue()); |
| aAnomaly.setDueDate(aDialog.getDueDate()); |
| aAnomaly.getAssignedTo().clear(); |
| aAnomaly.getAssignedTo().add(aDialog.getAssigned()); |
| if (null != aDialog.getRuleReferenceValue()) { |
| final R4EDesignRule rule = aDialog.getRuleReferenceValue(); |
| final R4ECommentType commentType = RModelFactory.eINSTANCE.createR4ECommentType(); |
| commentType.setType(rule.getClass_()); |
| aAnomaly.setType(commentType); |
| aAnomaly.setRank(rule.getRank()); |
| aAnomaly.setRuleID(aDialog.getRuleID()); |
| } else { |
| if (null != aDialog.getClass_()) { |
| final R4ECommentType commentType = RModelFactory.eINSTANCE.createR4ECommentType(); |
| commentType.setType(aDialog.getClass_()); |
| aAnomaly.setType(commentType); |
| } |
| if (null != aDialog.getRank()) { |
| aAnomaly.setRank(aDialog.getRank()); |
| } |
| //This is valid when we are cloning an anomaly |
| //There is no ruleReference, but just a ruleId |
| if (null != aDialog.getRuleID()) { |
| aAnomaly.setRuleID(aDialog.getRuleID()); |
| } |
| } |
| } |
| |
| /** |
| * Method createAnomalyFromDetached Create a new anomaly from a detached model anomaly |
| * |
| * @param aAnomalyTempFileVersion |
| * R4EFileVersion |
| * @param aModelComponent |
| * R4EAnomaly |
| * @param aUiPosition |
| * R4EUITextPosition |
| * @param aClone |
| * - boolean |
| * @return R4EUIAnomalyBasic |
| * @throws ResourceHandlingException |
| * @throws OutOfSyncException |
| */ |
| public R4EUIAnomalyBasic createAnomalyFromDetached(R4EFileVersion aAnomalyTempFileVersion, |
| R4EAnomaly aModelComponent, R4EUITextPosition aUiPosition, boolean aClone) |
| throws ResourceHandlingException, OutOfSyncException { |
| final String user = R4EUIModelController.getReviewer(); |
| final R4EAnomaly anomaly = R4EUIModelController.FModelExt.createR4EAnomaly(R4EUIModelController.getActiveReview() |
| .getParticipant(user, true)); |
| final Long bookNum = R4EUIModelController.FResourceUpdater.checkOut(anomaly, R4EUIModelController.getReviewer()); |
| anomaly.setTitle(aModelComponent.getTitle()); //This is needed as the anomaly title is displayed in the navigator view |
| R4EUIModelController.FResourceUpdater.checkIn(bookNum); |
| |
| final R4EUIAnomalyBasic uiAnomaly = createAnomalyDetails(anomaly, aAnomalyTempFileVersion, aUiPosition); |
| uiAnomaly.setModelData(aModelComponent); |
| if (!aClone) { |
| uiAnomaly.setExtraModelData(aModelComponent); |
| } |
| |
| //Add inline anomaly to editor (if applicable) |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| UIUtils.addAnnotation(uiAnomaly, (R4EUIFileContext) getParent()); |
| } |
| }); |
| return uiAnomaly; |
| } |
| |
| /** |
| * Method createAnomalyDetails |
| * |
| * @param aAnomalyTempFileVersion |
| * R4EFileVersion |
| * @param aAnomaly |
| * R4EAnomaly |
| * @param aUiPosition |
| * R4EUITextPosition |
| * @return R4EUIAnomalyBasic |
| * @throws ResourceHandlingException |
| * @throws OutOfSyncException |
| */ |
| public R4EUIAnomalyBasic createAnomalyDetails(R4EAnomaly aAnomaly, R4EFileVersion aAnomalyTempFileVersion, |
| R4EUITextPosition aUiPosition) throws ResourceHandlingException, OutOfSyncException { |
| |
| R4EUIAnomalyBasic uiAnomaly = null; |
| final R4EUIReviewBasic uiReview = R4EUIModelController.getActiveReview(); |
| |
| //Set position data |
| final R4EAnomalyTextPosition position = R4EUIModelController.FModelExt.createR4EAnomalyTextPosition(R4EUIModelController.FModelExt.createR4ETextContent(aAnomaly)); |
| |
| //Set File version data |
| final R4EFileVersion anomalyFileVersion = R4EUIModelController.FModelExt.createR4EFileVersion(position); |
| final Long bookNum = R4EUIModelController.FResourceUpdater.checkOut(anomalyFileVersion, |
| R4EUIModelController.getReviewer()); |
| CommandUtils.copyFileVersionData(anomalyFileVersion, aAnomalyTempFileVersion); |
| R4EUIModelController.FResourceUpdater.checkIn(bookNum); |
| |
| //Create and set UI model element |
| if (uiReview.getReview().getType().equals(R4EReviewType.BASIC)) { |
| uiAnomaly = new R4EUIAnomalyBasic(this, aAnomaly, aUiPosition); |
| } else { |
| uiAnomaly = new R4EUIAnomalyExtended(this, aAnomaly, aUiPosition); |
| if (uiReview.getReview().getType().equals(R4EReviewType.FORMAL)) { |
| ((R4EUIAnomalyExtended) uiAnomaly).updateState(R4EAnomalyState.CREATED); |
| } else { //R4EReviewType.INFORMAL |
| ((R4EUIAnomalyExtended) uiAnomaly).updateState(R4EAnomalyState.ASSIGNED); |
| } |
| } |
| aUiPosition.setPositionInModel(position); |
| addChildren(uiAnomaly); |
| return uiAnomaly; |
| } |
| |
| /** |
| * Method removeChildren. |
| * |
| * @param aChildToRemove |
| * IR4EUIModelElement |
| * @param aFileRemove |
| * - also remove from file (hard remove) |
| * @throws ResourceHandlingException |
| * @throws OutOfSyncException |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#removeChildren(IR4EUIModelElement) |
| */ |
| @Override |
| public void removeChildren(IR4EUIModelElement aChildToRemove, boolean aFileRemove) |
| throws ResourceHandlingException, OutOfSyncException { |
| final R4EUIAnomalyBasic removedElement = fAnomalies.get(fAnomalies.indexOf(aChildToRemove)); |
| |
| //Also recursively remove all children |
| removedElement.removeAllChildren(aFileRemove); |
| |
| /* TODO uncomment when core model supports hard-removing of elements |
| if (aFileRemove) removedElement.getAnomaly().remove()); |
| else */ |
| final R4EAnomaly modelAnomaly = removedElement.getAnomaly(); |
| final Long bookNum = R4EUIModelController.FResourceUpdater.checkOut(modelAnomaly, |
| R4EUIModelController.getReviewer()); |
| modelAnomaly.setEnabled(false); |
| R4EUIModelController.FResourceUpdater.checkIn(bookNum); |
| |
| //Remove element from UI if the show disabled element option is off |
| if (!(R4EUIPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_SHOW_DISABLED))) { |
| fAnomalies.remove(removedElement); |
| //Remove inline markings (local anomalies only) |
| if (getParent() instanceof R4EUIFileContext) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| UIUtils.removeAnnotation(removedElement, (R4EUIFileContext) getParent()); |
| } |
| }); |
| } |
| } else { |
| //Update inline markings (local anomalies only) |
| if (getParent() instanceof R4EUIFileContext) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| UIUtils.updateAnnotation(removedElement, (R4EUIFileContext) getParent()); |
| } |
| }); |
| } |
| } |
| } |
| |
| /** |
| * Method removeAllChildren. |
| * |
| * @param aFileRemove |
| * boolean |
| * @throws ResourceHandlingException |
| * @throws OutOfSyncException |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#removeAllChildren(boolean) |
| */ |
| @Override |
| public void removeAllChildren(boolean aFileRemove) throws ResourceHandlingException, OutOfSyncException { |
| //Recursively remove all children |
| for (R4EUIAnomalyBasic anomaly : fAnomalies) { |
| removeChildren(anomaly, aFileRemove); |
| } |
| } |
| |
| //Commands |
| |
| /** |
| * Method isAddChildElementCmd. |
| * |
| * @return boolean |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#isNewChildElementCmd() |
| */ |
| @Override |
| public boolean isNewChildElementCmd() { |
| if (!isReadOnly() |
| && !((R4EReviewState) R4EUIModelController.getActiveReview().getReview().getState()).getState().equals( |
| R4EReviewPhase.COMPLETED) && getParent().isEnabled() |
| && getParent() instanceof R4EUIReviewBasic) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Method getAddChildElementCmdName. |
| * |
| * @return String |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#getNewChildElementCmdName() |
| */ |
| @Override |
| public String getNewChildElementCmdName() { |
| return NEW_CHILD_ELEMENT_COMMAND_NAME; |
| } |
| |
| /** |
| * Method getAddChildElementCmdTooltip. |
| * |
| * @return String |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#getNewChildElementCmdTooltip() |
| */ |
| @Override |
| public String getNewChildElementCmdTooltip() { |
| return NEW_CHILD_ELEMENT_COMMAND_TOOLTIP; |
| } |
| |
| /** |
| * Method isShowPropertiesCmd. |
| * |
| * @return boolean |
| * @see org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement#isShowPropertiesCmd() |
| */ |
| @Override |
| public boolean isShowPropertiesCmd() { |
| return false; |
| } |
| |
| /** |
| * Method checkCompletionStatus. |
| * |
| * @param aMessage |
| * AtomicReference<String> |
| * @return boolean |
| */ |
| public boolean checkCompletionStatus(AtomicReference<String> aMessage) { // $codepro.audit.disable booleanMethodNamingConvention |
| final StringBuilder sb = new StringBuilder(); |
| boolean resultOk = true; |
| for (R4EUIAnomalyBasic anomaly : fAnomalies) { |
| //Test if the anomaly is disabled or not |
| if (anomaly.isEnabled()) { |
| //Anomaly is not disabled, should test for the completion |
| if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.CREATED)) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state CREATED" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } else if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.ASSIGNED)) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state ASSIGNED" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } else if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.ACCEPTED)) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state ACCEPTED" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } else if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.FIXED)) { |
| if (null == anomaly.getAnomaly().getFixedByID() || ("").equals(anomaly.getAnomaly().getFixedByID())) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") does not have a fixer" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } |
| if (R4EUIModelController.getActiveReview() |
| .getReview() |
| .getDecision() |
| .getValue() |
| .equals(R4EDecision.ACCEPTED_FOLLOWUP)) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state FIXED, but Review" |
| + " Decision is set to Accepted with Followup" + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } |
| } else if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.VERIFIED)) { |
| if (null == anomaly.getAnomaly().getFollowUpByID() |
| || ("").equals(anomaly.getAnomaly().getFollowUpByID())) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state VERIFIED and " |
| + "does not have a follower" + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } |
| } |
| } |
| } |
| if (!resultOk) { |
| aMessage.set(sb.toString()); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Method checkCompletionStatus. |
| * |
| * @param aMessage |
| * AtomicReference<String> |
| * @return boolean |
| */ |
| public boolean checkReworkStatus(AtomicReference<String> aMessage) { |
| final StringBuilder sb = new StringBuilder(); |
| boolean resultOk = true; |
| for (R4EUIAnomalyBasic anomaly : fAnomalies) { |
| //Test if the anomaly is disabled or not |
| if (anomaly.isEnabled()) { |
| //Anomaly is not disabled, should test for the next state REWORK |
| if (anomaly.getAnomaly().getState().equals(R4EAnomalyState.CREATED)) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") is in state CREATED" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } else if (null == anomaly.getAnomaly().getDecidedByID() |
| || ("").equals(anomaly.getAnomaly().getDecidedByID())) { |
| sb.append("Anomaly (" + anomaly.getAnomaly().getTitle() + ") does not have a decider" |
| + R4EUIConstants.LINE_FEED); |
| resultOk = false; |
| } |
| } |
| } |
| if (!resultOk) { |
| aMessage.set(sb.toString()); |
| return false; |
| } |
| return true; |
| } |
| } |