| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.team.internal.ui.synchronize; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialogWithToggle; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.team.core.TeamException; |
| import org.eclipse.team.internal.ui.IPreferenceIds; |
| import org.eclipse.team.internal.ui.TeamUIMessages; |
| import org.eclipse.team.internal.ui.TeamUIPlugin; |
| import org.eclipse.team.internal.ui.Utils; |
| import org.eclipse.team.internal.ui.registry.SynchronizeParticipantDescriptor; |
| import org.eclipse.team.internal.ui.registry.SynchronizeParticipantRegistry; |
| import org.eclipse.team.internal.ui.registry.SynchronizeWizardDescription; |
| import org.eclipse.team.internal.ui.registry.SynchronizeWizardRegistry; |
| import org.eclipse.team.ui.synchronize.ISynchronizeManager; |
| import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; |
| import org.eclipse.team.ui.synchronize.ISynchronizeParticipantDescriptor; |
| import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener; |
| import org.eclipse.team.ui.synchronize.ISynchronizeParticipantReference; |
| import org.eclipse.team.ui.synchronize.ISynchronizeView; |
| import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IPerspectiveDescriptor; |
| import org.eclipse.ui.IPerspectiveRegistry; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.Saveable; |
| import org.eclipse.ui.WorkbenchException; |
| import org.eclipse.ui.XMLMemento; |
| |
| /** |
| * Manages the registered synchronize participants. It handles notification of |
| * participant lifecycles, creation of <code>static</code> participants, management |
| * of dynamic participants, and the re-creation of persisted participants. |
| * <p> |
| * A participant is defined in a plugin manifest and can have several properties: |
| * <ul> |
| * <li>static: means that they always exist and don't have to be added to the manager |
| * <li>dynamic: will be added to the manager at some later time |
| * </ul> |
| * |
| * Part (title, id, icon, composite) - described in plugin.xml (IPartInstance) |
| * Can have multiple parts of the same type at runtime -> (IPart) |
| * <ul> |
| * <li>must acquire a part (IPartInstance.createPart()) |
| * <li>must released to part when done (IPartInstance.releasePart()) |
| * </ul> |
| * Some parts can added dynamically to the registry and events are fired to listeners. Listeners can create the newly added part via |
| * the #createPart() method. |
| * Parts can be persisted/restored with some state |
| * |
| * |
| * <p> |
| * Lifecycle: |
| * </p><p> |
| * startup -> registry read and stored in a participant instance |
| * createParticipant(id) -> |
| * releaseParticipant(IParticipantDescriptor) -> |
| * getParticipantRegistry -> return IParticipantDescriptors that describe the participants |
| * shutdown -> persist all settings |
| * </p> |
| * |
| * @see ISynchronizeView |
| * @see ISynchronizeParticipant |
| * @since 3.0 |
| */ |
| public class SynchronizeManager implements ISynchronizeManager { |
| /** |
| * Synchronize participants listeners |
| */ |
| private ListenerList<ISynchronizeParticipantListener> fListeners = null; |
| |
| /** |
| * Contains the participant descriptions |
| */ |
| private SynchronizeParticipantRegistry participantRegistry = new SynchronizeParticipantRegistry(); |
| |
| /** |
| * Contains the synchronize wizard descriptions |
| */ |
| private SynchronizeWizardRegistry wizardRegistry = new SynchronizeWizardRegistry(); |
| |
| /** |
| * Contains a table of the state saved between sessions for a participant. The set is keyed |
| * as such {String key -> ISynchronizeParticipantReference}. |
| */ |
| private Map<String, ISynchronizeParticipantReference> participantReferences = Collections.synchronizedMap(new HashMap<>(10)); |
| |
| // change notification constants |
| private final static int ADDED = 1; |
| private final static int REMOVED = 2; |
| |
| // save context constants |
| private final static String CTX_PARTICIPANTS = "syncparticipants"; //$NON-NLS-1$ |
| private final static String CTX_PARTICIPANT = "participant"; //$NON-NLS-1$ |
| private final static String CTX_ID = "id"; //$NON-NLS-1$ |
| private final static String CTX_SECONDARY_ID = "secondary_id"; //$NON-NLS-1$ |
| private final static String CTX_PARTICIPANT_DISPLAY_NAME = "displayName"; //$NON-NLS-1$ |
| private final static String CTX_PARTICIPANT_DATA = "data"; //$NON-NLS-1$ |
| private final static String FILENAME = "syncParticipants.xml"; //$NON-NLS-1$ |
| |
| /** |
| * Notifies a participant listeners of additions or removals of participant references. |
| */ |
| class SynchronizeViewPageNotifier implements ISafeRunnable { |
| |
| private ISynchronizeParticipantListener fListener; |
| private int fType; |
| private ISynchronizeParticipant[] fChanged; |
| |
| @Override |
| public void handleException(Throwable exception) { |
| TeamUIPlugin.log(IStatus.ERROR, TeamUIMessages.SynchronizeManager_7, exception); |
| } |
| |
| @Override |
| public void run() throws Exception { |
| switch (fType) { |
| case ADDED : |
| fListener.participantsAdded(fChanged); |
| break; |
| case REMOVED : |
| fListener.participantsRemoved(fChanged); |
| break; |
| } |
| } |
| |
| /** |
| * Notifies the given listener of the adds/removes |
| * @param participants the participants that changed |
| * @param update the type of change |
| */ |
| public void notify(ISynchronizeParticipant[] participants, int update) { |
| if (fListeners == null) { |
| return; |
| } |
| fChanged = participants; |
| fType = update; |
| Object[] copiedListeners = fListeners.getListeners(); |
| for (Object copiedListener : copiedListeners) { |
| fListener = (ISynchronizeParticipantListener) copiedListener; |
| SafeRunner.run(this); |
| } |
| fChanged = null; |
| fListener = null; |
| } |
| } |
| |
| /** |
| * Represents a participant instance and allows lazy initialization of the instance |
| * only when the participant is required. |
| */ |
| private class ParticipantInstance implements ISynchronizeParticipantReference { |
| private Map<String, ISynchronizeParticipant> participants; |
| private IMemento savedState; |
| private SynchronizeParticipantDescriptor descriptor; |
| private String secondaryId; |
| private String displayName; |
| private boolean dead; |
| |
| public ParticipantInstance(SynchronizeParticipantDescriptor descriptor, String secondaryId, String displayName, IMemento savedState) { |
| this.participants = new HashMap<>(); |
| this.secondaryId = secondaryId; |
| this.savedState = savedState; |
| this.descriptor = descriptor; |
| this.displayName = displayName; |
| } |
| |
| public void save(IMemento memento) { |
| if (dead) return; |
| String key = Utils.getKey(descriptor.getId(), getSecondaryId()); |
| ISynchronizeParticipant ref = participants.get(key); |
| if(ref != null) { |
| ref.saveState(memento); |
| } else if(savedState != null) { |
| memento.putMemento(savedState); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object other) { |
| if(other == this) return true; |
| if (! (other instanceof ISynchronizeParticipantReference)) return false; |
| ISynchronizeParticipantReference otherRef = (ISynchronizeParticipantReference) other; |
| String otherSecondaryId = otherRef.getSecondaryId(); |
| return otherRef.getId().equals(getId()) && Utils.equalObject(getSecondaryId(), otherSecondaryId); |
| } |
| |
| @Override |
| public String getId() { |
| return descriptor.getId(); |
| } |
| |
| @Override |
| public String getSecondaryId() { |
| return secondaryId; |
| } |
| |
| |
| @Override |
| public String getDisplayName() { |
| String key = Utils.getKey(descriptor.getId(), getSecondaryId()); |
| ISynchronizeParticipant participant = participants.get(key); |
| if(participant != null) { |
| return participant.getName(); |
| } |
| return displayName != null ? displayName : descriptor.getName(); |
| } |
| |
| public boolean isInstantiated() { |
| String key = Utils.getKey(descriptor.getId(), getSecondaryId()); |
| return participants.get(key) != null; |
| } |
| |
| @Override |
| public ISynchronizeParticipant getParticipant() throws TeamException { |
| if (dead) return null; |
| String key = Utils.getKey(descriptor.getId(), getSecondaryId()); |
| try { |
| ISynchronizeParticipant participant = participants.get(key); |
| if (participant == null) { |
| participant = instantiate(); |
| if(participant != null) |
| participants.put(key, participant); |
| } |
| return participant; |
| } catch (TeamException e) { |
| TeamUIPlugin.log(e); |
| participantReferences.remove(key); |
| throw new TeamException(TeamUIMessages.SynchronizeManager_8, e); |
| } |
| } |
| |
| public void setParticipant(ISynchronizeParticipant participant) { |
| String key = Utils.getKey(descriptor.getId(), getSecondaryId()); |
| participants.put(key, participant); |
| } |
| |
| @Override |
| public ISynchronizeParticipantDescriptor getDescriptor() { |
| return descriptor; |
| } |
| |
| private ISynchronizeParticipant instantiate() throws TeamException { |
| try { |
| ISynchronizeParticipant participant = (ISynchronizeParticipant) TeamUIPlugin.createExtension(descriptor.getConfigurationElement(), SynchronizeParticipantDescriptor.ATT_CLASS); |
| participant.setInitializationData(descriptor.getConfigurationElement(), null, null); |
| participant.init(getSecondaryId(), savedState); |
| savedState = null; |
| return participant; |
| } catch (PartInitException e) { |
| throw new TeamException(NLS.bind(TeamUIMessages.SynchronizeManager_11, new String[] { descriptor.getName() }), e); |
| } catch (CoreException e) { |
| throw TeamException.asTeamException(e); |
| } catch(Exception e) { |
| throw new TeamException(NLS.bind(TeamUIMessages.SynchronizeManager_11, new String[] { descriptor.getName() }), e); |
| } |
| } |
| |
| /** |
| * Dispose of the reference |
| */ |
| public void dispose() { |
| try { |
| ISynchronizeParticipant participant = getParticipant(); |
| if (participant != null) |
| participant.dispose(); |
| } catch (TeamException e) { |
| // Ignore since we are disposing anyway; |
| } finally { |
| dead = true; |
| } |
| } |
| } |
| |
| public SynchronizeManager() { |
| init(); |
| } |
| |
| @Override |
| public void addSynchronizeParticipantListener(ISynchronizeParticipantListener listener) { |
| if (fListeners == null) { |
| fListeners = new ListenerList<>(ListenerList.IDENTITY); |
| } |
| fListeners.add(listener); |
| } |
| |
| @Override |
| public void removeSynchronizeParticipantListener(ISynchronizeParticipantListener listener) { |
| if (fListeners != null) { |
| fListeners.remove(listener); |
| } |
| } |
| |
| /** |
| * Creates a new participant reference with of the provided type. If the secondayId is specified it |
| * is used as the qualifier for multiple instances of the same type. |
| * <p> |
| * The returned participant reference is a light weight handle describing the participant. The plug-in |
| * defining the participant is not loaded. To instantiate a participant a client must call |
| * {@link ISynchronizeParticipantReference#createParticipant()} and must call |
| * {@link ISynchronizeParticipantReference#releaseParticipant()} when finished with the participant. |
| * </p> |
| * @param type the type of the participant |
| * @param secondaryId a unique id for multiple instance support |
| * @return a reference to a participant |
| */ |
| private ParticipantInstance createParticipantReference(String type, String secondaryId, String displayName) throws PartInitException { |
| SynchronizeParticipantDescriptor desc = participantRegistry.find(type); |
| // ensure that the view id is valid |
| if (desc == null) |
| throw new PartInitException(NLS.bind(TeamUIMessages.SynchronizeManager_19, new String[] { type })); |
| // ensure that multiple instances are allowed if a secondary id is given |
| if (secondaryId != null) { |
| // if (!desc.isMultipleInstances()) { |
| // throw new PartInitException(Policy.bind("SynchronizeManager.20", type)); //$NON-NLS-1$ |
| // } |
| } |
| String key = Utils.getKey(type, secondaryId); |
| ParticipantInstance ref = (ParticipantInstance) participantReferences.get(key); |
| if (ref == null) { |
| ref = new ParticipantInstance(desc, secondaryId, displayName, null); |
| } |
| return ref; |
| } |
| |
| @Override |
| public synchronized void addSynchronizeParticipants(ISynchronizeParticipant[] participants) { |
| // renamed to createSynchronizeParticipant(id) |
| List<ISynchronizeParticipant> added = new ArrayList<>(participants.length); |
| for (ISynchronizeParticipant participant : participants) { |
| String key = Utils.getKey(participant.getId(), participant.getSecondaryId()); |
| if(! participantReferences.containsKey(key)) { |
| try { |
| ParticipantInstance ref = createParticipantReference(participant.getId(), participant.getSecondaryId(), participant.getName()); |
| ref.setParticipant(participant); |
| removeMatchingParticipant(participant.getId()); |
| participantReferences.put(key, ref); |
| added.add(participant); |
| } catch (PartInitException e) { |
| TeamUIPlugin.log(e); |
| continue; |
| } |
| } |
| } |
| if (!added.isEmpty()) { |
| saveState(); |
| fireUpdate(added.toArray(new ISynchronizeParticipant[added.size()]), ADDED); |
| } |
| } |
| |
| private void removeMatchingParticipant(String id) { |
| ISynchronizeParticipantReference[] refs = get(id); |
| if (refs.length > 0) { |
| // Find an un-pinned participant and replace it |
| for (ISynchronizeParticipantReference reference : refs) { |
| ISynchronizeParticipant p; |
| try { |
| p = reference.getParticipant(); |
| if (!p.isPinned() && !isDirty(p)) { |
| removeSynchronizeParticipants(new ISynchronizeParticipant[]{p}); |
| break; |
| } |
| } catch (TeamException e) { |
| continue; |
| } |
| } |
| } |
| } |
| |
| private boolean isDirty(ISynchronizeParticipant p) { |
| if (p instanceof ModelSynchronizeParticipant) { |
| ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) p; |
| Saveable s = msp.getActiveSaveable(); |
| if (s != null && s.isDirty()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public synchronized void removeSynchronizeParticipants(ISynchronizeParticipant[] participants) { |
| List<ISynchronizeParticipant> removed = new ArrayList<>(participants.length); |
| for (ISynchronizeParticipant participant : participants) { |
| String key = Utils.getKey(participant.getId(), participant.getSecondaryId()); |
| if(participantReferences.containsKey(key)) { |
| ParticipantInstance ref = (ParticipantInstance)participantReferences.remove(key); |
| if(ref.isInstantiated()) { |
| ref.dispose(); |
| } |
| removed.add(participant); |
| } |
| } |
| if (!removed.isEmpty()) { |
| saveState(); |
| fireUpdate(removed.toArray(new ISynchronizeParticipant[removed.size()]), REMOVED); |
| } |
| } |
| |
| @Override |
| public ISynchronizeParticipantReference get(String id, String secondaryId) { |
| String key = Utils.getKey(id, secondaryId); |
| return participantReferences.get(key); |
| } |
| |
| @Override |
| public ISynchronizeParticipantReference[] get(String id) { |
| ISynchronizeParticipantReference[] refs = getSynchronizeParticipants(); |
| ArrayList<ISynchronizeParticipantReference> refsForId = new ArrayList<>(); |
| for (ISynchronizeParticipantReference reference : refs) { |
| if(reference.getId().equals(id)) { |
| refsForId.add(reference); |
| } |
| } |
| return refsForId.toArray(new ISynchronizeParticipantReference[refsForId.size()]); |
| } |
| |
| @Override |
| public synchronized ISynchronizeParticipantReference[] getSynchronizeParticipants() { |
| return participantReferences.values().toArray(new ISynchronizeParticipantReference[participantReferences.values().size()]); |
| } |
| |
| @Override |
| public ISynchronizeView showSynchronizeViewInActivePage() { |
| IWorkbench workbench = PlatformUI.getWorkbench(); |
| IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); |
| |
| boolean switchPerspectives = promptForPerspectiveSwitch(); |
| IWorkbenchPage activePage = null; |
| if(switchPerspectives) { |
| try { |
| String pId = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE); |
| activePage = workbench.showPerspective(pId, window); |
| } catch (WorkbenchException e) { |
| Utils.handleError(window.getShell(), e, TeamUIMessages.SynchronizeView_14, e.getMessage()); |
| } |
| } |
| try { |
| if (activePage == null) { |
| activePage = TeamUIPlugin.getActivePage(); |
| if (activePage == null) |
| return null; |
| } |
| //IViewPart part = activePage.showView(ISynchronizeView.VIEW_ID, Long.toString(System.currentTimeMillis()), IWorkbenchPage.VIEW_ACTIVATE); |
| IViewPart part = activePage.showView(ISynchronizeView.VIEW_ID); |
| try { |
| return (ISynchronizeView) part; |
| } catch (ClassCastException e) { |
| // Strange that we cannot cast the part (see bug 53671) |
| TeamUIPlugin.log(IStatus.ERROR, NLS.bind(TeamUIMessages.SynchronizeManager_18, new String[] { part.getClass().getName() }), e); |
| return null; |
| } |
| } catch (PartInitException pe) { |
| Utils.handleError(window.getShell(), pe, TeamUIMessages.SynchronizeView_16, pe.getMessage()); |
| return null; |
| } |
| } |
| |
| /** |
| * Decides what action to take when switching perspectives and showing the synchronize view. Basically there are a |
| * set of user preferences that control how perspective switching. |
| */ |
| private boolean promptForPerspectiveSwitch() { |
| // Decide if a prompt is even required |
| IPreferenceStore store = TeamUIPlugin.getPlugin().getPreferenceStore(); |
| String option = store.getString(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE); |
| if(option.equals(MessageDialogWithToggle.ALWAYS)) { |
| return true; |
| } else if(option.equals(MessageDialogWithToggle.NEVER)) { |
| return false; |
| } |
| |
| // Otherwise determine if a prompt is required |
| IPerspectiveRegistry registry= PlatformUI.getWorkbench().getPerspectiveRegistry(); |
| String defaultSyncPerspectiveId = store.getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE); |
| IPerspectiveDescriptor perspectiveDescriptor = registry.findPerspectiveWithId(defaultSyncPerspectiveId); |
| IWorkbenchPage page = TeamUIPlugin.getActivePage(); |
| if(page != null) { |
| IPerspectiveDescriptor p = page.getPerspective(); |
| if(p != null && p.getId().equals(defaultSyncPerspectiveId)) { |
| // currently in default perspective |
| return false; |
| } |
| } |
| |
| if(perspectiveDescriptor != null) { |
| |
| String message;; |
| String desc = perspectiveDescriptor.getDescription(); |
| if (desc == null) { |
| message = NLS.bind(TeamUIMessages.SynchronizeManager_30, new String[] { perspectiveDescriptor.getLabel() }); |
| } else { |
| message = NLS.bind(TeamUIMessages.SynchronizeManager_32, new String[] { perspectiveDescriptor.getLabel(), desc }); |
| } |
| MessageDialogWithToggle m = MessageDialogWithToggle.openYesNoQuestion(Utils.getShell(null), |
| TeamUIMessages.SynchronizeManager_27, |
| message, |
| TeamUIMessages.SynchronizeManager_31, |
| false /* toggle state */, |
| store, |
| IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE); |
| |
| int result = m.getReturnCode(); |
| switch (result) { |
| // yes, ok |
| case IDialogConstants.YES_ID: |
| case IDialogConstants.OK_ID : |
| return true; |
| // no |
| case IDialogConstants.NO_ID : |
| return false; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Creates the participant registry and restore any saved participants. |
| * Will also instantiate any static participants. |
| */ |
| public void init() { |
| try { |
| // Initialize the participant registry - reads all participant extension descriptions. |
| participantRegistry.readRegistry(Platform.getExtensionRegistry(), TeamUIPlugin.ID, SynchronizeParticipantRegistry.PT_SYNCPARTICIPANTS); |
| // Initialize the wizard registry |
| wizardRegistry.readRegistry(Platform.getExtensionRegistry(), TeamUIPlugin.ID, SynchronizeWizardRegistry.PT_SYNCHRONIZE_WIZARDS); |
| |
| // Instantiate and register any dynamic participants saved from a |
| // previous session. |
| restoreSavedParticipants(); |
| } catch (CoreException e) { |
| TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.SynchronizeManager_8, e)); |
| } |
| } |
| |
| /** |
| * Allow participant instances to clean-up. |
| */ |
| public void dispose() { |
| // save state and settings for existing participants. |
| saveState(); |
| for (Iterator it = participantReferences.values().iterator(); it.hasNext();) { |
| ParticipantInstance ref = (ParticipantInstance) it.next(); |
| if((ref).isInstantiated()) { |
| try { |
| ref.getParticipant().dispose(); |
| } catch (TeamException e) { |
| continue; |
| } |
| } |
| } |
| participantReferences = null; |
| } |
| |
| /** |
| * Restores participants that have been saved between sessions. |
| */ |
| private void restoreSavedParticipants() throws CoreException { |
| File file = getStateFile(); |
| Reader reader; |
| try { |
| reader = new BufferedReader(new FileReader(file)); |
| } catch (FileNotFoundException e) { |
| return; |
| } |
| IMemento memento = XMLMemento.createReadRoot(reader); |
| IMemento[] participantNodes = memento.getChildren(CTX_PARTICIPANT); |
| for (IMemento memento2 : participantNodes) { |
| String id = memento2.getString(CTX_ID); |
| String secondayId = memento2.getString(CTX_SECONDARY_ID); |
| if (secondayId != null) { |
| String displayName = memento2.getString(CTX_PARTICIPANT_DISPLAY_NAME); |
| SynchronizeParticipantDescriptor desc = participantRegistry.find(id); |
| if (desc != null) { |
| String key = Utils.getKey(id, secondayId); |
| participantReferences.put(key, new ParticipantInstance(desc, secondayId, displayName, memento2.getChild(CTX_PARTICIPANT_DATA))); |
| } else { |
| TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, NLS.bind(TeamUIMessages.SynchronizeManager_9, new String[] { id }), null)); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Saves a file containing the list of participant ids that are registered |
| * with this manager. Each initialized participant is also given the chance to save |
| * it's state. |
| */ |
| private void saveState() { |
| XMLMemento xmlMemento = XMLMemento.createWriteRoot(CTX_PARTICIPANTS); |
| for (Iterator it = participantReferences.values().iterator(); it.hasNext(); ) { |
| ParticipantInstance ref = (ParticipantInstance) it.next(); |
| // Participants can opt out of being saved between sessions |
| if(! ref.getDescriptor().isPersistent()) continue; |
| // Create the state placeholder for a participant |
| IMemento participantNode = xmlMemento.createChild(CTX_PARTICIPANT); |
| participantNode.putString(CTX_ID, ref.getId()); |
| String secondaryId = ref.getSecondaryId(); |
| if(secondaryId != null) { |
| participantNode.putString(CTX_SECONDARY_ID,secondaryId); |
| } |
| participantNode.putString(CTX_PARTICIPANT_DISPLAY_NAME, ref.getDisplayName()); |
| IMemento participantData = participantNode.createChild(CTX_PARTICIPANT_DATA); |
| ref.save(participantData); |
| } |
| try { |
| try (Writer writer = new BufferedWriter(new FileWriter(getStateFile()))) { |
| xmlMemento.save(writer); |
| } |
| } catch (IOException e) { |
| TeamUIPlugin.log(new Status(IStatus.ERROR, TeamUIPlugin.ID, 1, TeamUIMessages.SynchronizeManager_10, e)); |
| } |
| } |
| |
| private File getStateFile() { |
| IPath pluginStateLocation = TeamUIPlugin.getPlugin().getStateLocation(); |
| return pluginStateLocation.append(FILENAME).toFile(); |
| } |
| |
| /** |
| * Fires notification. |
| * |
| * @param participants |
| * participants added/removed |
| * @param type |
| * ADDED or REMOVED |
| * @see SynchronizeManager#ADDED |
| * @see SynchronizeManager#REMOVED |
| */ |
| private void fireUpdate(ISynchronizeParticipant[] participants, int type) { |
| new SynchronizeViewPageNotifier().notify(participants, type); |
| } |
| |
| @Override |
| public ISynchronizeParticipantDescriptor getParticipantDescriptor(String id) { |
| return participantRegistry.find(id); |
| } |
| |
| public SynchronizeWizardDescription[] getWizardDescriptors() { |
| return wizardRegistry.getSynchronizeWizards(); |
| } |
| } |