| // $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) 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 |
| * |
| * Contributors: |
| * Ericsson AB - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.reviews.r4e.ui.internal.utils; |
| |
| import java.text.DecimalFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Calendar; |
| import java.util.GregorianCalendar; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.compare.ITypedElement; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.ISourceReference; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.text.TextSelection; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.mylyn.reviews.notifications.core.IMeetingData; |
| import org.eclipse.mylyn.reviews.notifications.spi.NotificationsConnector; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EDelta; |
| 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.R4EMeetingData; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EParticipant; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewComponent; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewType; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4ETextPosition; |
| import org.eclipse.mylyn.reviews.r4e.core.model.R4EUserRole; |
| 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.R4EUIDialogFactory; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4ECompareEditorInput; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileEditorInput; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileRevisionEditorInput; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileRevisionTypedElement; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.editors.R4EFileTypedElement; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.model.IR4EUIModelElement; |
| 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.R4EUIModelController; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.model.R4EUIPostponedAnomaly; |
| 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.R4EUITextPosition; |
| import org.eclipse.mylyn.reviews.r4e.ui.internal.preferences.PreferenceConstants; |
| 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.part.FileEditorInput; |
| |
| /** |
| * This class provides general utility methods used in the UI implementation |
| * |
| * @author Sebastien Dubois |
| * @version $Revision: 1.0 $ |
| */ |
| public class MailServicesProxy { |
| |
| // ------------------------------------------------------------------------ |
| // Constants |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Field LINE_FEED_MSG_PART. |
| */ |
| private static final String LINE_FEED_MSG_PART = R4EUIConstants.LINE_FEED; |
| |
| /** |
| * Field TAB_MSG_PART. (value is ""\t"") |
| */ |
| private static final String TAB_MSG_PART = "\t"; |
| |
| /** |
| * Field SUBJECT_MSG_HEADER. (value is "" Review "") |
| */ |
| private static final String SUBJECT_MSG_HEADER = " Review "; |
| |
| /** |
| * Field INTRO_MSG_BODY. (value is ""Hi,"") |
| */ |
| private static final String INTRO_MSG_BODY = "Hi,"; |
| |
| /** |
| * Field OUTRO_MSG_BODY. (value is ""Best Regards,"") |
| */ |
| private static final String OUTRO_MSG_BODY = "Best Regards,"; |
| |
| /** |
| * Field ITEMS_READY_MSG_BODY. (value is ""The following Review Item(s) and Files are Ready for you to Review"") |
| */ |
| private static final String ITEMS_READY_MSG_BODY = "The following Review Item(s) and Files are Ready for you to Review"; |
| |
| /** |
| * Field MEETING_REQUEST_MSG_BODY. (value is ""This invitation is for the decision phase." + LINE_FEED_MSG_PART + |
| * "Please review the included items prior to the meeting."") |
| */ |
| private static final String MEETING_REQUEST_MSG_BODY = "This invitation is for the decision phase." |
| + LINE_FEED_MSG_PART + "Please review the included items prior to the meeting."; |
| |
| /** |
| * Field ADDED_ITEMS_MSG_BODY. (value is ""The following Review Item(s) and Files have been Added." + |
| * LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"") |
| */ |
| private static final String ADDED_ELEMENTS_MSG_BODY = "The following Review Element(s) have been Added." |
| + LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"; |
| |
| /** |
| * Field REMOVED_ITEMS_MSG_BODY. (value is ""The following Review Item(s) and Files have been Removed." + |
| * LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"") |
| */ |
| private static final String REMOVED_ELEMENTS_MSG_BODY = "The following Element(s) have been Removed." |
| + LINE_FEED_MSG_PART + "Please Refresh your Review if it is currently Open"; |
| |
| /** |
| * Field PROGRESS_MESSAGE. (value is ""Progress Update: " + LINE_FEED_MSG_PART") |
| */ |
| private static final String PROGRESS_MESSAGE = "Progress Update: " + LINE_FEED_MSG_PART; |
| |
| /** |
| * Field COMPLETION_MESSAGE. (value is ""I have Completed this Review, see Details below: " + LINE_FEED_MSG_PART") |
| */ |
| private static final String COMPLETION_MESSAGE = "I have Completed this Review, see Details below: " |
| + LINE_FEED_MSG_PART; |
| |
| /** |
| * Field QUESTION_MSG_BODY. (value is ""I have a Question concerning the Following "") |
| */ |
| private static final String QUESTION_MSG_BODY = "I have a Question concerning the Following Elements: " |
| + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART; |
| |
| /** |
| * Field DEFAULT_MEETING_DURATION. (value is "60") |
| */ |
| private static final Integer DEFAULT_MEETING_DURATION = new Integer(60); |
| |
| /** |
| * Field DECISION_MEETING_UPDATED_MSG. (value is "" - Decision Meeting Request Updated"") |
| */ |
| private static final String DECISION_MEETING_UPDATED_MSG = " - Decision Meeting Request Updated"; |
| |
| /** |
| * Field DECISION_MEETING_INITIAL_MSG. (value is "" - Items Ready for Review & Decision Meeting Request"") |
| */ |
| private static final String DECISION_MEETING_INITIAL_MSG = " - Items Ready for Review & Decision Meeting Request"; |
| |
| // ------------------------------------------------------------------------ |
| // Methods |
| // ------------------------------------------------------------------------ |
| |
| //Notifications |
| |
| /** |
| * Method sendItemsReadyNotification |
| * |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendItemsReadyNotification() throws CoreException, ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| final String[] messageDestinations = createItemsUpdatedDestinations(); |
| final String messageSubject = createSubject() + " - Items Ready for Review"; |
| final String messageBody = createItemsReadyNotificationMessage(false); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendItemsAddedNotification |
| * |
| * @param aAddedElements |
| * List<R4EReviewComponent> |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendItemsAddedNotification(List<R4EReviewComponent> aAddedElements) throws CoreException, |
| ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| final String[] messageDestinations = createItemsUpdatedDestinations(); |
| final String messageSubject = createSubject() + " - Items Added for Review"; |
| final String messageBody = createUpdatedItemsNotificationMessage(aAddedElements, true); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendItemsRemovedNotification |
| * |
| * @param aRemovedElements |
| * List<R4EReviewComponent> |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendItemsRemovedNotification(List<R4EReviewComponent> aRemovedElements) throws CoreException, |
| ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| final String[] messageDestinations = createItemsUpdatedDestinations(); |
| final String messageSubject = createSubject() + " - Items Removed from Review"; |
| final String messageBody = createUpdatedItemsNotificationMessage(aRemovedElements, false); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendProgressNotification |
| * |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendProgressNotification() throws CoreException, ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| final String[] messageDestinations = createProgressDestinations(); |
| final String messageSubject = createSubject() + " - Participant Progress"; |
| final String messageBody = createProgressNotification(PROGRESS_MESSAGE); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendCompletionNotification |
| * |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendCompletionNotification() throws CoreException, ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| final String[] messageDestinations = createProgressDestinations(); |
| final String messageSubject = createSubject() + " - Participant Progress (Completed)"; |
| final String messageBody = createProgressNotification(COMPLETION_MESSAGE); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendQuestion |
| * |
| * @param aSource |
| * Object |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendQuestion(ISelection aSource) throws CoreException, ResourceHandlingException { |
| if (null != R4EUIDialogFactory.getInstance().getMailConnector()) { |
| String[] messageDestinations = null; |
| messageDestinations = createQuestionDestinations(); |
| final String messageSubject = createSubject() + " - Question regarding review "; |
| final String messageBody = createQuestionMessage(aSource); |
| sendMessage(messageDestinations, messageSubject, messageBody); |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method sendMessage |
| * |
| * @param aDestinations |
| * String[] |
| * @param aSubject |
| * String |
| * @param aBody |
| * String |
| * @throws CoreException |
| * @throws ResourceHandlingException |
| */ |
| public static void sendMessage(String[] aDestinations, final String aSubject, final String aBody) |
| throws ResourceHandlingException { |
| |
| final String originatorEmail = getOriginatorEmail(); |
| final String[] destinations = adjustDestinationEmails(aDestinations, originatorEmail); |
| |
| //Make sure the email is sent in the UI thread |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| try { |
| R4EUIDialogFactory.getInstance() |
| .getMailConnector() |
| .sendEmailGraphical(originatorEmail, destinations, aSubject, aBody, null, null); |
| } catch (CoreException e) { |
| UIUtils.displayCoreErrorDialog(e); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Method getOriginatorEmail |
| * |
| * @return String |
| * @throws ResourceHandlingException |
| */ |
| private static String getOriginatorEmail() throws ResourceHandlingException { |
| String originatorEmail = null; |
| final R4EParticipant user = R4EUIModelController.getActiveReview().getParticipant( |
| R4EUIModelController.getReviewer(), false); |
| if (null != user) { |
| originatorEmail = user.getEmail(); |
| } |
| |
| if (originatorEmail == null || originatorEmail.length() == 0) { |
| //if the user's email is null OR Undefined OR |
| //If current user is not part of the review, get email from preferences |
| final IPreferenceStore store = R4EUIPlugin.getDefault().getPreferenceStore(); |
| originatorEmail = store.getString(PreferenceConstants.P_USER_EMAIL); |
| } |
| return originatorEmail; |
| } |
| |
| /** |
| * Method adjustDestinationEmails (see bug 390102) |
| * |
| * @param aDestinations |
| * - String[] |
| * @param aOriginator |
| * - String |
| * @return String[] |
| * @throws ResourceHandlingException |
| */ |
| private static String[] adjustDestinationEmails(String[] aDestinations, String aOriginator) { |
| List<String> destinations = new ArrayList<String>(Arrays.asList(aDestinations)); |
| if (aOriginator != null |
| && R4EUIPlugin.getDefault() |
| .getPreferenceStore() |
| .getBoolean(PreferenceConstants.P_SEND_NOTIFICATION_TO_SENDER)) { |
| //Make sure sender is part of the destination list |
| if (!destinations.contains(aOriginator)) { |
| destinations.add(aOriginator); |
| } |
| } |
| return destinations.toArray(new String[destinations.size()]); |
| } |
| |
| /** |
| * Method createSubject |
| * |
| * @return String |
| */ |
| private static String createSubject() { |
| final StringBuilder subject = new StringBuilder(); |
| subject.append("[r4e-mail] "); |
| subject.append(SUBJECT_MSG_HEADER); |
| subject.append(R4EUIModelController.getActiveReview().getName()); |
| return subject.toString(); |
| } |
| |
| /** |
| * Method isEmailValid |
| * |
| * @param aParticipant |
| * R4EParticipant |
| * @return boolean |
| */ |
| private static boolean isEmailValid(R4EParticipant aParticipant) { |
| if (aParticipant.isEnabled() && !R4EUIModelController.getReviewer().equals(aParticipant.getId())) { |
| final String emailStr = aParticipant.getEmail(); |
| if (null != emailStr && !("".equals(emailStr))) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Method createItemsUpdatedDestinations |
| * |
| * @return String[] |
| */ |
| private static String[] createItemsUpdatedDestinations() { |
| final ArrayList<String> destinations = new ArrayList<String>(); |
| final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false); |
| for (R4EParticipant participant : participants) { |
| if (isEmailValid(participant)) { |
| //All active participants should receive this email |
| destinations.add(participant.getEmail()); |
| } |
| } |
| return destinations.toArray(new String[destinations.size()]); |
| } |
| |
| /** |
| * Method createProgressDestinations |
| * |
| * @return String[] |
| */ |
| private static String[] createProgressDestinations() { |
| final ArrayList<String> destinations = new ArrayList<String>(); |
| final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false); |
| for (R4EParticipant participant : participants) { |
| if (isEmailValid(participant)) { |
| if (!(R4EUIModelController.getActiveReview().getReview().getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL))) { |
| destinations.add(participant.getEmail()); |
| } else { |
| //If this is a formal review, only send mail if we have the proper role |
| if ((participant.getRoles().contains(R4EUserRole.R4E_ROLE_LEAD) |
| || participant.getRoles().contains(R4EUserRole.R4E_ROLE_ORGANIZER) || participant.getRoles() |
| .contains(R4EUserRole.R4E_ROLE_AUTHOR))) { |
| destinations.add(participant.getEmail()); |
| } |
| } |
| } |
| } |
| return destinations.toArray(new String[destinations.size()]); |
| } |
| |
| /** |
| * Method createQuestionDestinations |
| * |
| * @return String[] |
| */ |
| private static String[] createQuestionDestinations() { |
| final ArrayList<String> destinations = new ArrayList<String>(); |
| final List<R4EParticipant> participants = R4EUIModelController.getActiveReview().getParticipants(false); |
| for (R4EParticipant participant : participants) { |
| if (isEmailValid(participant)) { |
| if (!(R4EUIModelController.getActiveReview().getReview().getType().equals(R4EReviewType.R4E_REVIEW_TYPE_FORMAL))) { |
| destinations.add(participant.getEmail()); |
| } else { |
| //If this is a formal review, only send mail if we have the proper role |
| if ((participant.getRoles().contains(R4EUserRole.R4E_ROLE_LEAD) |
| || participant.getRoles().contains(R4EUserRole.R4E_ROLE_ORGANIZER) || participant.getRoles() |
| .contains(R4EUserRole.R4E_ROLE_AUTHOR))) { |
| destinations.add(participant.getEmail()); |
| } |
| } |
| } |
| } |
| return destinations.toArray(new String[destinations.size()]); |
| } |
| |
| /** |
| * Method createAnomalyCreatorDestination |
| * |
| * @param aAnomaly |
| * R4EUIAnomalyBasic |
| * @return String |
| */ |
| /* TODO not used for now, could be added later to narrow down destinations for anomaly questions |
| private static String[] createAnomalyCreatorDestination(R4EUIAnomalyBasic aAnomaly) { |
| final ArrayList<String> destinations = new ArrayList<String>(); |
| if (!R4EUIModelController.getReviewer().equals(aAnomaly.getAnomaly().getUser().getId())) { |
| R4EParticipant participant = (R4EParticipant) aAnomaly.getAnomaly().getUser(); |
| if (isEmailValid(participant)) { |
| destinations.add(participant.getEmail()); |
| } |
| } |
| return destinations.toArray(new String[destinations.size()]); |
| } |
| */ |
| |
| /** |
| * Method createItemsReadyNotificationMessage |
| * |
| * @param aMeetingRequestIncluded |
| * boolean |
| * @return String |
| */ |
| private static String createItemsReadyNotificationMessage(boolean aMeetingRequestIncluded) { |
| final StringBuilder msgBody = new StringBuilder(); |
| |
| msgBody.append(createIntroPart()); |
| if (aMeetingRequestIncluded) { |
| msgBody.append(MEETING_REQUEST_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| } else { |
| msgBody.append(ITEMS_READY_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| } |
| final List<R4EUIReviewItem> items = R4EUIModelController.getActiveReview().getReviewItems(); |
| for (R4EUIReviewItem item : items) { |
| if (item.isEnabled()) { |
| if (null != item.getItem().getDescription()) { |
| msgBody.append("Review Item -> " + item.getItem().getDescription() + LINE_FEED_MSG_PART); |
| } else { |
| //Always use the name of the file for Resource review items |
| msgBody.append("Review Item -> " + item.getChildren()[0].getName() + " (Resource)" |
| + LINE_FEED_MSG_PART); |
| } |
| msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]" + LINE_FEED_MSG_PART); |
| R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren(); |
| for (R4EUIFileContext context : contexts) { |
| R4EFileVersion fileVersion = context.getTargetFileVersion(); |
| if (null == fileVersion) { |
| fileVersion = context.getBaseFileVersion(); |
| } |
| if (context.isEnabled() && null != fileVersion) { |
| IResource resource = fileVersion.getResource(); |
| msgBody.append(TAB_MSG_PART); |
| //Project |
| if (null != resource) { |
| msgBody.append(resource.getProject()); |
| } |
| //Path |
| String path = fileVersion.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| msgBody.append(": " + path + " (Repository)"); |
| } else if (null != resource) { |
| msgBody.append(": " + resource.getProjectRelativePath() + " (Project)"); |
| } |
| //Line Range |
| R4EUIContent[] contents = (R4EUIContent[]) context.getContentsContainerElement().getChildren(); |
| msgBody.append(": "); |
| for (R4EUIContent content : contents) { |
| msgBody.append(content.getPosition().toString() + ", "); |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| } |
| msgBody.append(createReviewInfoPart()); |
| msgBody.append(createOutroPart()); |
| return msgBody.toString(); |
| } |
| |
| /** |
| * Method createRemovedItemsNotificationMessage |
| * |
| * @param aElements |
| * List<R4EReviewComponent> |
| * @param aIsAdded |
| * boolean |
| * @return String |
| */ |
| private static String createUpdatedItemsNotificationMessage(List<R4EReviewComponent> aElements, boolean aIsAdded) { |
| final StringBuilder msgBody = new StringBuilder(); |
| |
| msgBody.append(createIntroPart()); |
| if (aIsAdded) { |
| msgBody.append(ADDED_ELEMENTS_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| } else { |
| msgBody.append(REMOVED_ELEMENTS_MSG_BODY + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| } |
| boolean legendAppended = false; |
| for (R4EReviewComponent component : aElements) { |
| if (component instanceof R4EItem) { |
| if (null != ((R4EItem) component).getDescription()) { |
| msgBody.append("Review Item -> " + ((R4EItem) component).getDescription() + LINE_FEED_MSG_PART); |
| } |
| msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]" + LINE_FEED_MSG_PART); |
| EList<R4EFileContext> contexts = ((R4EItem) component).getFileContextList(); |
| for (R4EFileContext context : contexts) { |
| R4EFileVersion fileVersion = context.getTarget(); |
| if (null != fileVersion) { |
| IResource resource = fileVersion.getResource(); |
| msgBody.append(TAB_MSG_PART); |
| //Project |
| if (null != resource) { |
| msgBody.append(resource.getProject()); |
| } |
| //Path |
| String path = fileVersion.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| msgBody.append(": " + path + " (Repository)"); |
| } else if (null != resource) { |
| msgBody.append(": " + resource.getProjectRelativePath() + " (Project)"); |
| } |
| //Line Range |
| if (context.getDeltas().size() > 0) { |
| msgBody.append(": "); |
| EList<R4EDelta> deltas = context.getDeltas(); |
| for (R4EDelta delta : deltas) { |
| msgBody.append(buildLineTag(delta) + ", "); |
| } |
| } |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } else if (component instanceof R4EDelta) { |
| if (!legendAppended) { |
| msgBody.append("Eclipse Project: File Path (Repository | Project)[: Line range]" |
| + LINE_FEED_MSG_PART); |
| legendAppended = true; |
| } |
| R4EFileContext context = (R4EFileContext) ((R4EDelta) component).eContainer(); |
| R4EFileVersion fileVersion = context.getTarget(); |
| if (null != fileVersion) { |
| IResource resource = fileVersion.getResource(); |
| msgBody.append(TAB_MSG_PART); |
| //Project |
| if (null != resource) { |
| msgBody.append(resource.getProject()); |
| } |
| //Path |
| String path = fileVersion.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| msgBody.append(": " + path + " (Repository)"); |
| } else if (null != resource) { |
| msgBody.append(": " + resource.getProjectRelativePath() + " (Project)"); |
| } |
| msgBody.append(": " + buildLineTag((R4EDelta) component) + ", "); |
| } |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| |
| msgBody.append(createReviewInfoPart()); |
| msgBody.append(createOutroPart()); |
| return msgBody.toString(); |
| } |
| |
| /** |
| * Method createProgressNotification |
| * |
| * @param aHeader |
| * String |
| * @return String |
| */ |
| private static String createProgressNotification(String aHeader) { |
| final StringBuilder msgBody = new StringBuilder(); |
| |
| msgBody.append(createIntroPart()); |
| msgBody.append(aHeader + LINE_FEED_MSG_PART); |
| |
| //First count the number of elements to add to the message |
| int numReviewedFiles = 0; |
| int numTotalFiles = 0; |
| int numTotalAnomalies = 0; |
| final List<R4EUIReviewItem> items = R4EUIModelController.getActiveReview().getReviewItems(); |
| for (R4EUIReviewItem item : items) { |
| R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren(); |
| for (R4EUIFileContext context : contexts) { |
| if (context.isUserReviewed()) { |
| ++numReviewedFiles; |
| } |
| ++numTotalFiles; |
| R4EUIAnomalyBasic[] anomalies = (R4EUIAnomalyBasic[]) context.getAnomalyContainerElement() |
| .getChildren(); |
| for (R4EUIAnomalyBasic anomaly : anomalies) { |
| if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) { |
| ++numTotalAnomalies; //Specific anomalies |
| } |
| } |
| } |
| } |
| final R4EUIAnomalyBasic[] globalAnomalies = (R4EUIAnomalyBasic[]) R4EUIModelController.getActiveReview() |
| .getAnomalyContainer() |
| .getChildren(); |
| for (R4EUIAnomalyBasic anomaly : globalAnomalies) { |
| if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) { |
| ++numTotalAnomalies; //Global Anomalies |
| } |
| } |
| |
| //Add current review progress |
| msgBody.append("Files Reviewed: " + numReviewedFiles + TAB_MSG_PART); |
| msgBody.append("Files Total: " + numTotalFiles + TAB_MSG_PART); |
| final double progress = (numReviewedFiles / new Integer(numTotalFiles).doubleValue()) * 100; |
| final DecimalFormat fmt = new DecimalFormat("#"); |
| msgBody.append("Progress: " + fmt.format(progress) + "%"); |
| msgBody.append(LINE_FEED_MSG_PART); |
| |
| //Add anomalies created by current reviewer |
| msgBody.append("Anomalies Created by: " + R4EUIModelController.getReviewer() + LINE_FEED_MSG_PART); |
| msgBody.append("Count: " + numTotalAnomalies + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| |
| R4EUIFileContext context; |
| R4EUIAnomalyBasic anomaly; |
| for (R4EUIReviewItem item : items) { |
| R4EUIFileContext[] contexts = (R4EUIFileContext[]) item.getChildren(); |
| for (int i = 0; i < contexts.length; i++) { |
| context = contexts[i]; |
| if (0 == i) { |
| //Add format line |
| msgBody.append("FileContext: " + TAB_MSG_PART + "Eclipse Project: File Path (Repository | Project)" |
| + LINE_FEED_MSG_PART); |
| } |
| if (null != context.getAnomalyContainerElement()) { |
| R4EUIAnomalyBasic[] anomalies = (R4EUIAnomalyBasic[]) context.getAnomalyContainerElement() |
| .getChildren(); |
| |
| R4EFileVersion fileVersion = context.getTargetFileVersion(); |
| if (null == fileVersion) { |
| fileVersion = context.getBaseFileVersion(); |
| } |
| if (context.isEnabled() && null != fileVersion) { |
| IResource resource = fileVersion.getResource(); |
| msgBody.append(TAB_MSG_PART); |
| //Project |
| if (null != resource) { |
| msgBody.append(resource.getProject()); |
| } |
| //Path |
| String path = fileVersion.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| msgBody.append(": " + path + " (Repository)"); |
| } else if (null != resource) { |
| msgBody.append(": " + resource.getProjectRelativePath() + " (Project)"); |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| |
| for (int j = 0; j < anomalies.length; j++) { |
| anomaly = anomalies[j]; |
| if (0 == j) { |
| //Add format line |
| msgBody.append(TAB_MSG_PART + "Anomaly: " + "Line Range: Title: Description" |
| + LINE_FEED_MSG_PART); |
| } |
| if (anomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) { |
| //Add anomaly |
| msgBody.append(TAB_MSG_PART + TAB_MSG_PART + " " + anomaly.getPosition().toString() |
| + ": " + anomaly.getAnomaly().getTitle() + ": " |
| + anomaly.getAnomaly().getDescription() + LINE_FEED_MSG_PART); |
| |
| //Also add child comments |
| R4EUIComment[] comments = (R4EUIComment[]) anomaly.getChildren(); |
| for (R4EUIComment comment : comments) { |
| msgBody.append(TAB_MSG_PART + TAB_MSG_PART + TAB_MSG_PART + "Comment: " |
| + comment.getComment().getDescription() + LINE_FEED_MSG_PART); |
| } |
| } |
| } |
| } |
| } |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| |
| //Add global anomalies |
| if (globalAnomalies.length > 0) { |
| msgBody.append("Global Anomalies: " + LINE_FEED_MSG_PART); |
| } |
| for (R4EUIAnomalyBasic globalAnomaly : globalAnomalies) { |
| if (globalAnomaly.getAnomaly().getUser().getId().equals(R4EUIModelController.getReviewer())) { |
| //Add anomaly |
| msgBody.append(globalAnomaly.getAnomaly().getTitle() + ": " |
| + globalAnomaly.getAnomaly().getDescription() + LINE_FEED_MSG_PART); |
| |
| //Also add child comments |
| R4EUIComment[] globalComments = (R4EUIComment[]) globalAnomaly.getChildren(); |
| for (R4EUIComment globalComment : globalComments) { |
| msgBody.append(TAB_MSG_PART + "Comment: " + globalComment.getComment().getDescription() |
| + LINE_FEED_MSG_PART); |
| } |
| } |
| } |
| |
| msgBody.append(createReviewInfoPart()); |
| msgBody.append(createOutroPart()); |
| return msgBody.toString(); |
| } |
| |
| /** |
| * Method createQuestionMessage |
| * |
| * @param aSource |
| * Object |
| * @return String |
| * @throws CoreException |
| */ |
| private static String createQuestionMessage(ISelection aSource) throws CoreException { |
| final StringBuilder msgBody = new StringBuilder(); |
| msgBody.append(createIntroPart()); |
| msgBody.append(QUESTION_MSG_BODY); |
| |
| //Act differently depending on the type of selection we get |
| if (aSource instanceof ITextSelection) { |
| addElementInfo(msgBody, aSource); |
| } else if (aSource instanceof IStructuredSelection) { |
| //Iterate through all selections |
| for (final Iterator<?> iterator = ((IStructuredSelection) aSource).iterator(); iterator.hasNext();) { |
| addElementInfo(msgBody, iterator.next()); |
| msgBody.append(LINE_FEED_MSG_PART); |
| } |
| } |
| msgBody.append(LINE_FEED_MSG_PART); |
| msgBody.append(createReviewInfoPart()); |
| msgBody.append(createOutroPart()); |
| return msgBody.toString(); |
| } |
| |
| /** |
| * Method addElementInfo |
| * |
| * @param aMsgBody |
| * StringBuilder |
| * @param aSource |
| * Object |
| * @throws CoreException |
| */ |
| private static void addElementInfo(StringBuilder aMsgBody, Object aSource) throws CoreException { |
| if (aSource instanceof R4EUIPostponedAnomaly) { |
| R4EFileVersion file = ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getTargetFileVersion(); |
| if (null == file) { |
| file = ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getBaseFileVersion(); |
| } |
| if (null != file) { |
| final String path = file.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("Postponed File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != file.getResource()) { |
| aMsgBody.append("Postponed File Path (Project): " + file.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Postponed File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("Postponed File (Local): " |
| + ((R4EUIFileContext) ((R4EUIPostponedAnomaly) aSource).getParent()).getName() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Postponed Anomaly Line(s): " + ((R4EUIPostponedAnomaly) aSource).getPosition().toString() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("Postponed Anomaly Title: " + ((R4EUIPostponedAnomaly) aSource).getAnomaly().getTitle() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("Postponed Anomaly Description: " |
| + ((R4EUIPostponedAnomaly) aSource).getAnomaly().getDescription() + LINE_FEED_MSG_PART); |
| } else if (aSource instanceof R4EUIAnomalyBasic) { |
| final IR4EUIModelElement parent = ((R4EUIAnomalyBasic) aSource).getParent().getParent(); |
| if (parent instanceof R4EUIFileContext) { |
| //This is an anomaly tied to specific content |
| R4EFileVersion file = ((R4EUIFileContext) parent).getTargetFileVersion(); |
| if (null == file) { |
| file = ((R4EUIFileContext) parent).getBaseFileVersion(); |
| } |
| if (null != file) { |
| final String path = file.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != file.getResource()) { |
| aMsgBody.append("File Path (Project): " + file.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("File (Local): " |
| + ((R4EUIFileContext) ((R4EUIAnomalyBasic) aSource).getParent().getParent()).getName() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Anomaly Line(s): " + ((R4EUIAnomalyBasic) aSource).getPosition().toString() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Anomaly Title: " + ((R4EUIAnomalyBasic) aSource).getAnomaly().getTitle() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("Anomaly Description: " + ((R4EUIAnomalyBasic) aSource).getAnomaly().getDescription() |
| + LINE_FEED_MSG_PART); |
| } else if (aSource instanceof R4EUIComment) { |
| final IR4EUIModelElement parent = ((R4EUIComment) aSource).getParent().getParent().getParent(); |
| if (parent instanceof R4EUIFileContext) { |
| R4EFileVersion file = ((R4EUIFileContext) parent).getTargetFileVersion(); |
| if (null == file) { |
| file = ((R4EUIFileContext) parent).getBaseFileVersion(); |
| } |
| if (null != file) { |
| final String path = file.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != file.getResource()) { |
| aMsgBody.append("File Path (Project): " + file.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("File (Local): " |
| + ((R4EUIFileContext) ((R4EUIComment) aSource).getParent().getParent().getParent()).getName() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Anomaly Line(s): " |
| + ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getPosition().toString() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Anomaly Title: " |
| + ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getAnomaly().getTitle() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("Anomaly Description: " |
| + ((R4EUIAnomalyBasic) ((R4EUIComment) aSource).getParent()).getAnomaly().getDescription() |
| + LINE_FEED_MSG_PART); |
| |
| aMsgBody.append("Anomaly Comment: " + ((R4EUIComment) aSource).getComment().getDescription() |
| + LINE_FEED_MSG_PART); |
| } else if (aSource instanceof R4EUIReviewBasic) { |
| aMsgBody.append("Review: " + ((R4EUIReviewBasic) aSource).getReview().getName() + LINE_FEED_MSG_PART); |
| |
| } else if (aSource instanceof R4EUIReviewItem) { |
| final String description = ((R4EUIReviewItem) aSource).getItem().getDescription(); |
| if (null != description) { |
| aMsgBody.append("Review Item Description: " + description + LINE_FEED_MSG_PART); |
| } else { |
| //This is a ressource review item, so put the resource filename |
| aMsgBody.append("Review Item Resource: " |
| + ((R4EUIReviewItem) aSource).getFileContexts().get(0).getName() + LINE_FEED_MSG_PART); |
| } |
| |
| } else if (aSource instanceof R4EUIFileContext) { |
| final R4EFileVersion file = ((R4EUIFileContext) aSource).getTargetFileVersion(); |
| if (null != file) { |
| final String path = file.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("Target File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != file.getResource()) { |
| aMsgBody.append("Target File Path (Project): " + file.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Target File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("Target File (Local): " + ((R4EUIFileContext) aSource).getName() + LINE_FEED_MSG_PART); |
| aMsgBody.append("Target File Version: None" + LINE_FEED_MSG_PART); |
| } |
| final R4EFileVersion baseFile = ((R4EUIFileContext) aSource).getBaseFileVersion(); |
| if (null != baseFile) { |
| final String path = baseFile.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("Base File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != baseFile.getResource()) { |
| aMsgBody.append("Base File Path (Project): " + baseFile.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + baseFile.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Base File Version: " + baseFile.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("Base File (Local): " + ((R4EUIFileContext) aSource).getName() + LINE_FEED_MSG_PART); |
| aMsgBody.append("Base File Version: None" + LINE_FEED_MSG_PART); |
| } |
| } else if (aSource instanceof R4EUIContent) { |
| R4EFileVersion file = ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getTargetFileVersion(); |
| if (null == file) { |
| file = ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getBaseFileVersion(); |
| } |
| if (null != file) { |
| final String path = file.getRepositoryPath(); |
| if (null != path && !(path.equals(""))) { |
| aMsgBody.append("File Path (Repository): " + path + LINE_FEED_MSG_PART); |
| } else if (null != file.getResource()) { |
| aMsgBody.append("File Path (Project): " + file.getResource().getProject() |
| + R4EUIConstants.SEPARATOR + file.getResource().getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else { |
| aMsgBody.append("File (Local): " |
| + ((R4EUIFileContext) ((R4EUIContent) aSource).getParent().getParent()).getName() |
| + LINE_FEED_MSG_PART); |
| } |
| aMsgBody.append("Content Line(s): " + ((R4EUIContent) aSource).getPosition().toString() |
| + LINE_FEED_MSG_PART); |
| |
| } else if (aSource instanceof IFile) { |
| aMsgBody.append("File: " + ((IFile) aSource).getProject().getName() + R4EUIConstants.SEPARATOR |
| + ((IFile) aSource).getProjectRelativePath().toPortableString() + LINE_FEED_MSG_PART); |
| aMsgBody.append(LINE_FEED_MSG_PART); |
| aMsgBody.append("Position in File: " + CommandUtils.getPosition((IFile) aSource).toString() |
| + LINE_FEED_MSG_PART); |
| } else if (aSource instanceof TextSelection) { |
| final IEditorPart editorPart = PlatformUI.getWorkbench() |
| .getActiveWorkbenchWindow() |
| .getActivePage() |
| .getActiveEditor(); |
| final IEditorInput input = editorPart.getEditorInput(); |
| if (input instanceof R4ECompareEditorInput) { |
| //TODO: For now we give the file version of the file on the left side, regardless of whose side the selected input was. |
| // Later we want to refine this. |
| final ITypedElement element = ((R4ECompareEditorInput) input).getLeftElement(); |
| if (element instanceof R4EFileTypedElement) { |
| final R4EFileVersion file = ((R4EFileTypedElement) element).getFileVersion(); |
| aMsgBody.append("File: " + file.getResource().getProject() + R4EUIConstants.SEPARATOR |
| + file.getResource().getProjectRelativePath() + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else if (element instanceof R4EFileRevisionTypedElement) { |
| final R4EFileVersion file = ((R4EFileRevisionTypedElement) element).getFileVersion(); |
| aMsgBody.append("File Path: " + file.getRepositoryPath() + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } |
| } else if (input instanceof R4EFileRevisionEditorInput) { |
| final R4EFileVersion file = ((R4EFileRevisionEditorInput) input).getFileVersion(); |
| aMsgBody.append("File Path: " + file.getRepositoryPath() + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else if (input instanceof R4EFileEditorInput) { |
| final R4EFileVersion file = ((R4EFileEditorInput) input).getFileVersion(); |
| aMsgBody.append("File: " + file.getResource().getProject() + R4EUIConstants.SEPARATOR |
| + file.getResource().getProjectRelativePath() + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: " + file.getVersionID() + LINE_FEED_MSG_PART); |
| } else if (input instanceof FileEditorInput) { |
| final IFile file = ((FileEditorInput) input).getFile(); |
| aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART); |
| } |
| final TextSelection selectedText = (TextSelection) aSource; |
| aMsgBody.append(LINE_FEED_MSG_PART); |
| aMsgBody.append("Position in File: " + CommandUtils.getPosition(selectedText).toString() |
| + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| aMsgBody.append("Contents: " + LINE_FEED_MSG_PART); |
| aMsgBody.append(selectedText.getText()); |
| } else if (R4EUIPlugin.isJDTAvailable() && aSource instanceof ISourceReference) { |
| //NOTE: This is always true because all elements that implement ISourceReference |
| // also implement IJavaElement. The resource is always an IFile |
| final IFile file = (IFile) ((IJavaElement) aSource).getResource(); |
| aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART); |
| try { |
| final R4EUITextPosition position = CommandUtils.getPosition((ISourceReference) aSource, file); |
| aMsgBody.append("Position in File: " + position.toString() + LINE_FEED_MSG_PART + LINE_FEED_MSG_PART); |
| } catch (CoreException e) { |
| // Ignore |
| } |
| } else if (R4EUIPlugin.isCDTAvailable() && aSource 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 |
| IFile file = null; |
| if (aSource instanceof org.eclipse.cdt.core.model.ITranslationUnit) { |
| file = (IFile) ((org.eclipse.cdt.core.model.ICElement) aSource).getResource(); |
| } else if (aSource instanceof org.eclipse.cdt.core.model.ICElement) { |
| file = (IFile) ((org.eclipse.cdt.core.model.ICElement) aSource).getParent().getResource(); |
| } |
| if (null != file) { |
| aMsgBody.append("File: " + file.getProject() + R4EUIConstants.SEPARATOR + file.getProjectRelativePath() |
| + LINE_FEED_MSG_PART); |
| aMsgBody.append("File Version: (None available)" + LINE_FEED_MSG_PART); |
| try { |
| final R4EUITextPosition position = CommandUtils.getPosition( |
| (org.eclipse.cdt.core.model.ISourceReference) aSource, file); |
| aMsgBody.append("Position in File: " + position.toString() + LINE_FEED_MSG_PART |
| + LINE_FEED_MSG_PART); |
| } catch (CoreException e) { |
| // Ignore |
| } |
| } |
| } |
| } |
| |
| /** |
| * Method createReviewInfoPart |
| * |
| * @return String |
| */ |
| private static String createReviewInfoPart() { |
| final StringBuilder msgReviewInfo = new StringBuilder(); |
| |
| msgReviewInfo.append(LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Review Information"); |
| msgReviewInfo.append(LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Group: " + TAB_MSG_PART + TAB_MSG_PART |
| + R4EUIModelController.getActiveReview().getParent().getName() + LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Review: " + TAB_MSG_PART + R4EUIModelController.getActiveReview().getReview().getName() |
| + LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Components: " + TAB_MSG_PART); |
| final List<String> components = R4EUIModelController.getActiveReview().getReview().getComponents(); |
| for (String component : components) { |
| msgReviewInfo.append(component + ", "); |
| } |
| msgReviewInfo.append(LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Project: " + TAB_MSG_PART |
| + R4EUIModelController.getActiveReview().getReview().getProject() + LINE_FEED_MSG_PART); |
| msgReviewInfo.append("Participants: " + TAB_MSG_PART); |
| final List<String> participants = R4EUIModelController.getActiveReview().getParticipantIDs(); |
| for (String participant : participants) { |
| msgReviewInfo.append(participant + ", "); |
| } |
| msgReviewInfo.append(LINE_FEED_MSG_PART); |
| msgReviewInfo.append(LINE_FEED_MSG_PART); |
| |
| return msgReviewInfo.toString(); |
| } |
| |
| /** |
| * Method replaceParticipantsInBody |
| * |
| * @param aOldBody |
| * - String |
| * @return String |
| */ |
| private static String replaceParticipantsInBody(String aOldBody) { |
| StringBuffer buffer = new StringBuffer(); |
| buffer.append("Participants: " + TAB_MSG_PART); |
| final List<String> participants = R4EUIModelController.getActiveReview().getParticipantIDs(); |
| for (String participant : participants) { |
| buffer.append(participant + ", "); |
| } |
| buffer.append(LINE_FEED_MSG_PART); |
| return aOldBody.replaceFirst("Participants:.*", buffer.toString()); |
| } |
| |
| /** |
| * Method createIntroPart |
| * |
| * @return String |
| */ |
| private static String createIntroPart() { |
| final StringBuilder msgIntro = new StringBuilder(); |
| msgIntro.append(LINE_FEED_MSG_PART); |
| msgIntro.append(INTRO_MSG_BODY); |
| msgIntro.append(LINE_FEED_MSG_PART); |
| msgIntro.append(LINE_FEED_MSG_PART); |
| return msgIntro.toString(); |
| } |
| |
| /** |
| * Method createOutroPart |
| * |
| * @return String |
| */ |
| private static String createOutroPart() { |
| final StringBuilder msgOutro = new StringBuilder(); |
| msgOutro.append(OUTRO_MSG_BODY + LINE_FEED_MSG_PART); |
| msgOutro.append(R4EUIModelController.getReviewer()); |
| return msgOutro.toString(); |
| } |
| |
| //Meetings |
| |
| /** |
| * Method sendMeetingRequest |
| * |
| * @throws OutOfSyncException |
| * @throws ResourceHandlingException |
| * @throws CoreException |
| */ |
| public static void sendMeetingRequest() throws ResourceHandlingException, OutOfSyncException { |
| final NotificationsConnector mailConnector = R4EUIDialogFactory.getInstance().getMailConnector(); |
| if (null != mailConnector) { |
| |
| String originatorEmail = getOriginatorEmail(); |
| String[] destinations = adjustDestinationEmails(createItemsUpdatedDestinations(), originatorEmail); |
| |
| //Notify user if request cannot be sent when no valid destinations defined |
| if (0 == destinations.length) { |
| final ErrorDialog dialog = new ErrorDialog(null, R4EUIConstants.DIALOG_TITLE_ERROR, |
| "Cannot Send Meeting Request", new Status(IStatus.ERROR, R4EUIPlugin.PLUGIN_ID, |
| "No valid destinations for participants defined", null), IStatus.ERROR); |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| dialog.open(); |
| } |
| }); |
| return; |
| } |
| |
| IMeetingData updatedMeetingData = null; |
| |
| //Check if a meeting request already exist. If so, update it. Otherwise create a new one |
| final R4EMeetingData r4eMeetingData = R4EUIModelController.getActiveReview().getReview().getActiveMeeting(); |
| if (null != r4eMeetingData) { |
| IMeetingData oldMeetingData = null; |
| final IMeetingData localMeetingData = new R4EUIMeetingData(r4eMeetingData); |
| |
| //First update the current meeting request local data with any source/destination changes (if any) |
| localMeetingData.setSender(originatorEmail); |
| localMeetingData.clearReceivers(); |
| for (String destination : destinations) { |
| localMeetingData.addReceiver(destination); |
| } |
| localMeetingData.setBody(replaceParticipantsInBody(localMeetingData.getBody())); |
| |
| //Then try to find the meeting data on mail server |
| oldMeetingData = mailConnector.fetchSystemMeetingData(localMeetingData, |
| R4EUIModelController.getActiveReview().getReview().getStartDate()); |
| |
| if (null == oldMeetingData) { |
| //Meeting data not found on mail server, so create one from the local data |
| try { |
| updatedMeetingData = mailConnector.createMeetingRequest(createSubject() |
| + DECISION_MEETING_UPDATED_MSG, localMeetingData.getBody(), destinations, |
| localMeetingData.getStartTime(), localMeetingData.getDuration(), |
| localMeetingData.getLocation()); |
| } catch (CoreException e) { |
| R4EUIPlugin.Ftracer.traceWarning("Exception: " + e.toString() + " (" + e.getMessage() + ")"); |
| R4EUIPlugin.getDefault().logWarning("Exception: " + e.toString(), e); |
| return; |
| } |
| } else { |
| //Meeting data found on mail server, now let's compare the values |
| if (!localMeetingData.equals(oldMeetingData)) { |
| //Values are different, ask user which ones we should keep |
| final int result = UIUtils.displayMeetingDataMismatchDialog(localMeetingData, oldMeetingData); |
| if (result == R4EUIConstants.DIALOG_YES) { |
| //Update the mail server data with local data |
| updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData, |
| R4EUIModelController.getActiveReview().getReview().getStartDate(), true); |
| } else if (result == R4EUIConstants.DIALOG_NO) { |
| //Update the local data with mail server data |
| updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData, |
| R4EUIModelController.getActiveReview().getReview().getStartDate(), false); |
| } |
| } else { |
| //Use local data |
| updatedMeetingData = mailConnector.openAndUpdateMeeting(localMeetingData, |
| R4EUIModelController.getActiveReview().getReview().getStartDate(), true); |
| } |
| } |
| } else { |
| //Meeting data not found anywhere, so create a brand new one with default values |
| try { |
| updatedMeetingData = mailConnector.createMeetingRequest(createSubject() |
| + DECISION_MEETING_INITIAL_MSG, createItemsReadyNotificationMessage(true), destinations, |
| getDefaultStartTime(), DEFAULT_MEETING_DURATION, ""); |
| } catch (CoreException e) { |
| R4EUIPlugin.Ftracer.traceWarning("Exception: " + e.toString() + " (" + e.getMessage() + ")"); |
| R4EUIPlugin.getDefault().logWarning("Exception: " + e.toString(), e); |
| return; |
| } |
| } |
| if (null != updatedMeetingData) { |
| R4EUIModelController.getActiveReview().setMeetingData(updatedMeetingData); |
| } |
| } else { |
| showNoEmailConnectorDialog(); |
| } |
| } |
| |
| /** |
| * Method getDefaultStartTime |
| * |
| * @return Long |
| */ |
| public static Long getDefaultStartTime() { |
| |
| // Make sure we leave 3 days to review and don't set a meeting on the week-end |
| final GregorianCalendar meetingDate = new GregorianCalendar(); |
| switch (meetingDate.get(Calendar.DAY_OF_WEEK)) { |
| case Calendar.TUESDAY: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 518400000); |
| break; |
| case Calendar.WEDNESDAY: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 691200000); |
| break; |
| case Calendar.THURSDAY: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 604800000); |
| break; |
| case Calendar.FRIDAY: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 518400000); |
| break; |
| case Calendar.SATURDAY: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 432000000); |
| break; |
| default: |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis() + 345600000); |
| break; |
| } |
| |
| // Set start time at 10 AM |
| meetingDate.set(Calendar.HOUR_OF_DAY, 10); |
| meetingDate.set(Calendar.MINUTE, 0); |
| meetingDate.set(Calendar.SECOND, 0); |
| // Add the current time zone offset |
| meetingDate.setTimeInMillis(meetingDate.getTimeInMillis()); |
| return Long.valueOf(meetingDate.getTimeInMillis()); |
| } |
| |
| /** |
| * Method showNoEmailConnectorDialog |
| */ |
| private static void showNoEmailConnectorDialog() { |
| final ErrorDialog dialog = new ErrorDialog( |
| null, |
| R4EUIConstants.DIALOG_TITLE_WARNING, |
| "No Email connector detected" |
| + "Take note that no Automatic Email can be sent because no Mail Services Connector is Present", |
| new Status(IStatus.WARNING, R4EUIPlugin.PLUGIN_ID, 0, null, null), IStatus.WARNING); |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| dialog.open(); |
| } |
| }); |
| } |
| |
| /** |
| * Method buildLineTag |
| * |
| * @param aDelta |
| * R4EDelta |
| * @return String |
| */ |
| private static String buildLineTag(R4EDelta aDelta) { |
| if (null != aDelta.getTarget() && null != aDelta.getTarget().getLocation()) { |
| final int startLine = ((R4ETextPosition) aDelta.getTarget().getLocation()).getStartLine(); |
| final int endLineLine = ((R4ETextPosition) aDelta.getTarget().getLocation()).getEndLine(); |
| final StringBuilder buffer = new StringBuilder(R4EUIConstants.DEFAULT_LINE_TAG_LENGTH); |
| if (startLine == endLineLine) { |
| buffer.append(R4EUIConstants.LINE_TAG + startLine); |
| } else { |
| buffer.append(R4EUIConstants.LINES_TAG + startLine + "-" + endLineLine); |
| } |
| return buffer.toString(); |
| } |
| return ""; |
| } |
| } |