blob: 8bd624fb182bbb61354e36fb871bd9fff244c04f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems 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:
* IBM Corporation - initial API and implementation
* Wind River Systems - adapted to use with IToggleBreakpiontsTargetFactory extension
*******************************************************************************/
package org.eclipse.debug.internal.ui.actions;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import org.eclipse.core.expressions.EvaluationContext;
import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.expressions.ExpressionTagNames;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.core.IConfigurationElementConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.IEvaluationService;
/**
* Organizes the toggle breakpoints target factories contributed through the
* extension point and keeps track of the toggle breakpoints target that
* the factories produce. The manager is accessed as a singleton through
* the <code>getDefault()</code> method.
* <p>
* The adapter mechanism for obtaining a toggle breakpoints target is
* still supported through a specialized toggle target factory. Targets
* contributed through this mechanism are labeled as "Default" in the UI.
* </p>
*
* @see IToggleBreakpointsTargetFactory
* @see IToggleBreakpointsTarget
* @see IToggleBreakpointsTargetExtension
* @since 3.5
*/
public class ToggleBreakpointsTargetManager {
/**
* Toggle breakpoints target ID which refers to a target contributed
* through the legacy adapter mechanism.
*/
public static String DEFAULT_TOGGLE_TARGET_ID = "default"; //$NON-NLS-1$
private static Set DEFAULT_TOGGLE_TARGET_ID_SET = new HashSet();
static {
DEFAULT_TOGGLE_TARGET_ID_SET.add(DEFAULT_TOGGLE_TARGET_ID);
}
/**
* Acts as a proxy between the toggle breakpoints target manager and the factories
* contributed to the extension point. Only loads information from the plug-in xml
* and only instantiates the specified factory if required (lazy loading).
*/
private static class ToggleTargetFactory implements IToggleBreakpointsTargetFactory {
private IConfigurationElement fConfigElement;
private IToggleBreakpointsTargetFactory fFactory;
private Expression fEnablementExpression;
public ToggleTargetFactory(IConfigurationElement configElement){
fConfigElement = configElement;
}
/**
* Returns the instantiated factory specified by the class property.
*/
private IToggleBreakpointsTargetFactory getFactory() {
if (fFactory != null) return fFactory;
try{
Object obj = fConfigElement.createExecutableExtension(IConfigurationElementConstants.CLASS);
if(obj instanceof IToggleBreakpointsTargetFactory) {
fFactory = (IToggleBreakpointsTargetFactory)obj;
} else {
throw new CoreException(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactories extension failed to load breakpoint toggle target because the specified class does not implement org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory. Class specified was: " + obj, null)); //$NON-NLS-1$
}
} catch (CoreException e){
DebugUIPlugin.log(e.getStatus());
fFactory = null;
}
return fFactory;
}
/**
* Checks if the enablement expression for the factory evaluates to true for the
* given part and selection.
*/
public boolean isEnabled(IWorkbenchPart part, ISelection selection) {
boolean enabled = false;
Expression expression = getEnablementExpression();
if (expression != null) {
enabled = evalEnablementExpression(part, selection, expression);
} else {
enabled = true;
}
return enabled;
}
/**
* Returns the active debug context given the active part. It is used
* in creating the evaluation context for the factories' enablement expression.
* @param part active part
* @return current active debug context
*/
private IStructuredSelection getDebugContext(IWorkbenchPart part) {
ISelection selection = DebugUITools.getDebugContextManager().
getContextService(part.getSite().getWorkbenchWindow()).getActiveContext();
if (selection instanceof IStructuredSelection) {
return (IStructuredSelection)selection;
}
return StructuredSelection.EMPTY;
}
/**
* Evaluate the given expression within the given context and return
* the result. Returns <code>true</code> iff result is either TRUE.
*
* @param exp the enablement expression to evaluate or <code>null</code>
* @param context the context of the evaluation. Usually, the
* user's selection.
* @return the result of evaluating the expression
*/
private boolean evalEnablementExpression(IWorkbenchPart part, ISelection selection, Expression exp) {
if (exp != null){
IEvaluationContext parentContext = null;
IEvaluationService evaluationService = (IEvaluationService)PlatformUI.getWorkbench().getService(IEvaluationService.class);
if (evaluationService != null) {
parentContext = evaluationService.getCurrentState();
}
IEvaluationContext context = new EvaluationContext(parentContext, part);
List debugContextList = getDebugContext(part).toList();
context.addVariable(IConfigurationElementConstants.DEBUG_CONTEXT, debugContextList);
if (selection instanceof IStructuredSelection) {
List selectionList = ((IStructuredSelection)selection).toList();
context.addVariable(IConfigurationElementConstants.SELECTION, selectionList);
}
if (part instanceof IEditorPart) {
context.addVariable(IConfigurationElementConstants.EDITOR_INPUT, ((IEditorPart)part).getEditorInput());
}
try{
EvaluationResult result = exp.evaluate(context);
if (result == EvaluationResult.TRUE){
return true;
}
} catch (CoreException e){
// Evaluation failed
}
}
return false;
}
/**
* Returns an expression that represents the enablement logic for the
* breakpiont toggle target.
*/
private Expression getEnablementExpression(){
if (fEnablementExpression == null) {
try{
IConfigurationElement[] elements = fConfigElement.getChildren(ExpressionTagNames.ENABLEMENT);
IConfigurationElement enablement = elements.length > 0 ? elements[0] : null;
if (enablement != null) {
fEnablementExpression = ExpressionConverter.getDefault().perform(enablement);
}
} catch (CoreException e){
DebugUIPlugin.log(e.getStatus());
fEnablementExpression = null;
}
}
return fEnablementExpression;
}
/**
* Instantiates the factory and asks it to produce the IToggleBreakpointsTarget
* for the given ID
*/
public IToggleBreakpointsTarget createToggleTarget(String targetID) {
IToggleBreakpointsTargetFactory factory = getFactory();
if (factory != null) {
return factory.createToggleTarget(targetID);
}
return null;
}
/**
* Instantiates the factory and asks it for the set of toggle target
* IDs that the factory can produce for the given part and selection.
*/
public Set getToggleTargets(IWorkbenchPart part, ISelection selection) {
IToggleBreakpointsTargetFactory factory = getFactory();
if (factory != null) {
return factory.getToggleTargets(part, selection);
}
return Collections.EMPTY_SET;
}
/**
* Instantiates the factory and asks it to produce the name of the toggle target
* for the given ID.
*/
public String getToggleTargetName(String targetID) {
IToggleBreakpointsTargetFactory factory = getFactory();
if (factory != null) {
return factory.getToggleTargetName(targetID);
}
return null;
}
/**
* Instantiates the factory and asks it to produce the description of the toggle
* target for the given ID.
*/
public String getToggleTargetDescription(String targetID) {
IToggleBreakpointsTargetFactory factory = getFactory();
if (factory != null) {
return factory.getToggleTargetDescription(targetID);
}
return null;
}
/**
* Instantiates the factory and asks it for the toggle tareget ID that
* the factory considers the default for the given part and selection.
*/
public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
IToggleBreakpointsTargetFactory factory = getFactory();
if (factory != null) {
return factory.getDefaultToggleTarget(part, selection);
}
return null;
}
}
/**
* Factory for toggle breakpoints targets contributed through the
* adapter mechanism.
*/
private static class ToggleBreakpointsTargetAdapterFactory implements IToggleBreakpointsTargetFactory {
private IAdaptable getAdaptable(IWorkbenchPart part, ISelection selection) {
IAdaptable adaptable = null;
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection)selection;
if (ss.getFirstElement() instanceof IAdaptable) {
adaptable = (IAdaptable) ss.getFirstElement();
}
} else {
adaptable = part;
}
return adaptable;
}
private boolean canGetToggleBreakpointsTarget(IAdaptable adaptable) {
if (adaptable != null) {
IToggleBreakpointsTarget adapter = (IToggleBreakpointsTarget)
adaptable.getAdapter(IToggleBreakpointsTarget.class);
if (adapter == null) {
IAdapterManager adapterManager = Platform.getAdapterManager();
if (adapterManager.hasAdapter(adaptable, IToggleBreakpointsTarget.class.getName())) {
return true;
}
} else {
return true;
}
}
return false;
}
/**
* Finds the toggle breakpoints target for the active part and selection.
* It first looks for the target using the factories registered using an
* extension point. If not found it uses the <code>IAdaptable</code>
* mechanism.
* @param part active part
* @param selection active selection in part
* @return The toggle breakpoints target, or <code>null</code> if not found.
*/
private IToggleBreakpointsTarget getToggleBreakpointsTarget(IAdaptable adaptable) {
if (adaptable != null) {
IToggleBreakpointsTarget adapter = (IToggleBreakpointsTarget)
adaptable.getAdapter(IToggleBreakpointsTarget.class);
if (adapter == null) {
// attempt to force load adapter
IAdapterManager adapterManager = Platform.getAdapterManager();
if (adapterManager.hasAdapter(adaptable, IToggleBreakpointsTarget.class.getName())) {
adapter = (IToggleBreakpointsTarget)
adapterManager.loadAdapter(adaptable, IToggleBreakpointsTarget.class.getName());
}
}
return adapter;
}
return null;
}
/**
* Checks if there is an adaptable object for the given part and
* selection, and if there is, it checks whether an
* <code>IToggleBreakpointsTarget</code> can be obtained as an adapter.
*/
public boolean isEnabled(IWorkbenchPart part, ISelection selection) {
IAdaptable adaptable = getAdaptable(part, selection);
return adaptable != null && canGetToggleBreakpointsTarget(adaptable);
}
/**
* Not implemented use {@link #createDefaultToggleTarget(IWorkbenchPart, ISelection)}
* instead.
*/
public IToggleBreakpointsTarget createToggleTarget(String targetID) {
return null;
}
/**
* Returns a toggle target for the given part and selection, obtained
* through the adapter mechanism.
*/
public IToggleBreakpointsTarget createDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
IAdaptable adaptable = getAdaptable(part, selection);
return getToggleBreakpointsTarget(adaptable);
}
public Set getToggleTargets(IWorkbenchPart part, ISelection selection) {
IAdaptable adaptable = getAdaptable(part, selection);
if (canGetToggleBreakpointsTarget(adaptable)) {
return DEFAULT_TOGGLE_TARGET_ID_SET;
}
return Collections.EMPTY_SET;
}
public String getToggleTargetName(String targetID) {
return ActionMessages.ToggleBreakpointsTargetManager_defaultToggleTarget_name;
}
public String getToggleTargetDescription(String targetID) {
return ActionMessages.ToggleBreakpointsTargetManager_defaultToggleTarget_description;
}
public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
return DEFAULT_TOGGLE_TARGET_ID;
}
}
/**
* Preference key for storing the preferred targets map.
* @see {@link #storePreferredTargets()}
* @see {@link #loadPreferredTargets()}
*/
public static final String PREF_TARGETS = "preferredTargets"; //$NON-NLS-1$
/**
* There should only ever be once instance of this manager for the workbench.
*/
private static ToggleBreakpointsTargetManager fgSingleton;
public static ToggleBreakpointsTargetManager getDefault(){
if (fgSingleton == null) fgSingleton = new ToggleBreakpointsTargetManager();
return fgSingleton;
}
/**
* Maps the IDs of toggle breakpoint targets to their instances. The target
* IDs must be unique.
*/
private Map fKnownFactories;
/**
* Maps a Set of target id's to the one target id that is preferred.
*/
private Map fPreferredTargets;
/**
* Maps the IDs of toggle targets to the factory that can create them.
* There can currently only be one factory for a given toggle target.
*/
private Map fFactoriesByTargetID = new HashMap();
/**
* List of listeners to changes in the preferred toggle targets list.
*/
private ListenerList fChangedListners = new ListenerList();
/**
* Initializes the collection of known factories from extension point contributions.
*/
private void initializeFactories() {
fKnownFactories = new LinkedHashMap();
fKnownFactories.put(DEFAULT_TOGGLE_TARGET_ID, new ToggleBreakpointsTargetAdapterFactory());
IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_TOGGLE_BREAKPOINTS_TARGET_FACTORIES);
IConfigurationElement[] elements = ep.getConfigurationElements();
for (int i= 0; i < elements.length; i++) {
String id = elements[i].getAttribute(IConfigurationElementConstants.ID);
if (id != null && id.length() != 0) {
if (fKnownFactories.containsKey(id)) {
DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactory extension failed to load breakpoint toggle target because the specified id is already registered. Specified ID is: " + id, null)); //$NON-NLS-1$
} else {
fKnownFactories.put(id, new ToggleTargetFactory(elements[i]));
}
} else {
DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactory extension failed to load breakpoint toggle target because the specified id is empty.", null)); //$NON-NLS-1$
}
}
// If there are any factories contributed through the extension point,
// set a system property for use in enabling actions.
System.setProperty(IDebugUIConstants.SYS_PROP_BREAKPOINT_TOGGLE_FACTORIES_USED,
fKnownFactories.size() > 1 ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Returns the set of IToggleBreakpointsTargetFactory objects (they will be
* ToggleTargetFactory) that were contributed to the extension point and
* are enabled for the given part and selection (enabled if the factory
* does not have an enablement expression or if the enablement expression
* evaluates to true).
*
* @param part active part
* @param selection active selection in part
* @return The factories enabled for the part and selection or an empty
* collection.
*/
private Set getEnabledFactories(IWorkbenchPart part, ISelection selection) {
if (fKnownFactories == null) initializeFactories();
Set set = new LinkedHashSet();
for (Iterator itr = fKnownFactories.keySet().iterator(); itr.hasNext(); ) {
String id = (String)itr.next();
IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fKnownFactories.get(id);
if (factory instanceof ToggleTargetFactory &&
((ToggleTargetFactory)factory).isEnabled(part, selection)) {
set.add(factory);
} else if (factory instanceof ToggleBreakpointsTargetAdapterFactory &&
((ToggleBreakpointsTargetAdapterFactory)factory).isEnabled(part, selection)) {
set.add(factory);
}
}
return set;
}
/**
* Produces the set of IDs for all possible toggle targets that can be used for
* the given part and selection.
*
* @param factoriesToQuery The collection of factories to check
* @param part active part
* @param selection active selection in part
* @return Set of toggle target IDs or an empty set
*/
private Set getEnabledTargetIDs(Collection factoriesToQuery, IWorkbenchPart part, ISelection selection){
Set idsForSelection = new LinkedHashSet();
Iterator factoriesItr = factoriesToQuery.iterator();
while (factoriesItr.hasNext()) {
IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory) factoriesItr.next();
Iterator targetIDsItr = factory.getToggleTargets(part, selection).iterator();
while (targetIDsItr.hasNext()) {
String targetID = (String) targetIDsItr.next();
fFactoriesByTargetID.put(targetID, factory);
idsForSelection.add(targetID);
}
}
return idsForSelection;
}
/**
* Returns the set of <code>String</code> IDs of toggle breakpoint targets,
* which are enabled for the given active part and selection. The IDs can be used
* to create the {@link IToggleBreakpointsTarget} instance.
* @param part active part
* @param selection active selection in part
* @return Set of toggle target IDs or an empty set
*/
public Set getEnabledToggleBreakpointsTargetIDs(IWorkbenchPart part, ISelection selection) {
return getEnabledTargetIDs(getEnabledFactories(part, selection), part, selection);
}
/**
* Returns the ID of the calculated preferred toggle breakpoints target for the
* given active part and selection. The returned ID is chosen based on factory
* enablement, whether the target is a default one, and on user choice.
* @param part active part
* @param selection active selection in part
* @return The toggle target IDs or null if none.
*/
public String getPreferredToggleBreakpointsTargetID(IWorkbenchPart part, ISelection selection) {
Set factories = getEnabledFactories(part, selection);
Set possibleIDs = getEnabledTargetIDs(factories, part, selection);
return chooseToggleTargetIDInSet(possibleIDs, factories, part, selection);
}
/**
* Given the ID of toggle breakpoint target, this method will try to find the factory
* that creates it and return an instance of it.
*
* @param ID The ID of the requested toggle breakpoint target.
* @return The instantiated target or null
*/
public IToggleBreakpointsTarget getToggleBreakpointsTarget(IWorkbenchPart part, ISelection selection) {
String id = getPreferredToggleBreakpointsTargetID(part, selection);
IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
if (factory != null) {
if (DEFAULT_TOGGLE_TARGET_ID.equals(id)) {
return ((ToggleBreakpointsTargetAdapterFactory)factory).createDefaultToggleTarget(part, selection);
} else {
return factory.createToggleTarget(id);
}
}
return null;
}
/**
* Given the ID of a toggle breakpoints target, this method will try
* to find the factory that creates it and ask it for the name of it.
*
* @param ID The ID of the requested toggle breakpoint target.
* @return The name of the target.
*/
public String getToggleBreakpointsTargetName(String id) {
IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
if (factory != null) {
return factory.getToggleTargetName(id);
}
return null;
}
/**
* Given the ID of a toggle breakpoints target, this method will try
* to find the factory that creates it and ask it for the description of it.
*
* @param ID The ID of the requested toggle breakpoint target.
* @return The description of the target or null.
*/
public String getToggleBreakpointsTargetDescription(String id) {
IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
if (factory != null) {
return factory.getToggleTargetDescription(id);
}
return null;
}
/**
* Adds the given listener to the list of listeners notified when the preferred
* toggle breakpoints targets change.
* @param listener The listener to add.
*/
public void addChangedListener(IToggleBreakpointsTargetManagerListener listener) {
fChangedListners.add(listener);
}
/**
* Removes the given listener from the list of listeners notified when the preferred
* toggle breakpoints targets change.
* @param listener The listener to add.
*/
public void removeChangedListener(IToggleBreakpointsTargetManagerListener listener) {
fChangedListners.remove(listener);
}
/**
* Stores the map of preferred target IDs to the preference store in the format:
*
* Key1A,Key1B:Value1|Key2A,Key2B,Key2C:Value2|
*
* Where the sub keys (Key1A, Key1B, etc.) are the elements of the set used at the
* key in the mapping and the values are the associated String value in the mapping.
*/
private void storePreferredTargets() {
StringBuffer buffer= new StringBuffer();
Iterator iter = fPreferredTargets.entrySet().iterator();
while (iter.hasNext()) {
Entry entry = (Entry) iter.next();
Iterator setIter = ((Set)entry.getKey()).iterator();
while (setIter.hasNext()) {
String currentID = (String) setIter.next();
buffer.append(currentID);
buffer.append(',');
}
buffer.deleteCharAt(buffer.length()-1);
buffer.append(':');
buffer.append(entry.getValue());
buffer.append('|');
}
DebugUIPlugin.getDefault().getPluginPreferences().setValue(PREF_TARGETS, buffer.toString());
}
/**
* Loads the map of preferred target IDs from the preference store.
*
* @see #storePreferredTargets()
*/
private void loadPreferredTargets() {
fPreferredTargets = new HashMap();
String preferenceValue = DebugUIPlugin.getDefault().getPluginPreferences().getString(PREF_TARGETS);
StringTokenizer entryTokenizer = new StringTokenizer(preferenceValue,"|"); //$NON-NLS-1$
while (entryTokenizer.hasMoreTokens()){
String token = entryTokenizer.nextToken();
int valueStart = token.indexOf(':');
StringTokenizer keyTokenizer = new StringTokenizer(token.substring(0,valueStart),","); //$NON-NLS-1$
Set keys = new LinkedHashSet();
while (keyTokenizer.hasMoreTokens()){
keys.add(keyTokenizer.nextToken());
}
fPreferredTargets.put(keys, token.substring(valueStart+1));
}
}
/**
* Adds or updates the mapping to set which target ID is preferred for a certain
* set of possible IDs.
*
* @param possibleIDs The set of possible IDs
* @param preferredID The preferred ID in the set.
*/
public void setPreferredTarget(Set possibleIDs, String preferredID) {
if (possibleIDs == null) return;
if (fKnownFactories == null) initializeFactories();
if (fPreferredTargets == null){
loadPreferredTargets();
}
String currentKey = (String)fPreferredTargets.get(possibleIDs);
if (currentKey == null || !currentKey.equals(preferredID)){
fPreferredTargets.put(possibleIDs, preferredID);
storePreferredTargets();
firePreferredTargetsChanged();
}
}
/**
* Returns the preferred pane ID from the given set if the mapping has been set.
*
* @param possibleDetailsAreaIDs Set of possible pane IDs
* @return The preferred ID or null
*/
private String getUserPreferredTarget(Set possibleTargetIDs){
if (fPreferredTargets == null){
loadPreferredTargets();
}
return (String)fPreferredTargets.get(possibleTargetIDs);
}
/**
* Given a set of possible detail pane IDs, this method will determine which pane is
* preferred and should be used to display the selection. This method chooses a pane
* by storing previous choices and can be set using a context menu.
*
* @param possiblePaneIDs The set of possible detail pane IDs
* @return The preferred detail pane ID or null
*/
private String chooseToggleTargetIDInSet(Set possibleTargetIDs, Collection enabledFactories, IWorkbenchPart part, ISelection selection){
if (possibleTargetIDs == null || possibleTargetIDs.isEmpty()){
return null;
}
String preferredID = getUserPreferredTarget(possibleTargetIDs);
if (preferredID == null){
// If there is no preferred pane already set, check the factories to see there is a default target
Iterator factoryIterator = enabledFactories.iterator();
while (preferredID == null && factoryIterator.hasNext()) {
IToggleBreakpointsTargetFactory currentFactory = (IToggleBreakpointsTargetFactory) factoryIterator.next();
preferredID = currentFactory.getDefaultToggleTarget(part, selection);
}
// If the factories don't have a default, just pick the first one.
if (preferredID == null) {
preferredID= (String)possibleTargetIDs.iterator().next();
}
setPreferredTarget(possibleTargetIDs, preferredID);
}
return preferredID;
}
/**
* Notifies the change listeners that the preferred targets changed.
*/
private void firePreferredTargetsChanged() {
Object[] listeners = fChangedListners.getListeners();
for (int i = 0; i < listeners.length; i++) {
((IToggleBreakpointsTargetManagerListener)listeners[i]).preferredTargetsChanged();
}
}
}