1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.debug.ui.actions;
15 
16 
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Iterator;
20 import java.util.List;
21 
22 import org.eclipse.jdt.debug.core.IJavaStackFrame;
23 import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
24 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
25 import org.eclipse.jdt.internal.debug.ui.JavaDebugOptionsManager;
26 import org.eclipse.jface.action.IAction;
27 import org.eclipse.jface.preference.IPreferenceStore;
28 import org.eclipse.jface.viewers.IStructuredSelection;
29 
30 /**
31  * This abstract class defines the behavior common to actions that allow the
32  * user to add step filters dynamically, as they are debugging.
33  *
34  * @since 2.1
35  */
36 public abstract class AbstractAddStepFilterAction extends ObjectActionDelegate {
37 
38 	/**
39 	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
40 	 */
41 	@Override
run(IAction action)42 	public void run(IAction action) {
43 
44 		// Make sure there is a current selection
45 		IStructuredSelection selection= getCurrentSelection();
46 		if (selection == null) {
47 			return;
48 		}
49 
50 		// For each selected stack frame, add a corresponding active step filter
51 		Iterator<IJavaStackFrame> itr = selection.iterator();
52 		while (itr.hasNext()) {
53 			IJavaStackFrame frame = itr.next();
54 			String pattern = generateStepFilterPattern(frame);
55 			if (pattern != null) {
56 				addActiveStepFilter(pattern);
57 			}
58 		}
59 	}
60 
61 	/**
62 	 * Make the specified pattern an active step filter.
63 	 */
addActiveStepFilter(String pattern)64 	private void addActiveStepFilter(String pattern) {
65 
66 		// Get the active & inactive filter preferences and convert them to Lists
67 		IPreferenceStore prefStore = getPreferenceStore();
68 		String[] activeArray = JavaDebugOptionsManager.parseList(prefStore.getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST));
69 		String[] inactiveArray = JavaDebugOptionsManager.parseList(prefStore.getString(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST));
70 		List<String> activeList = new ArrayList<>(Arrays.asList(activeArray));
71 		List<String> inactiveList = new ArrayList<>(Arrays.asList(inactiveArray));
72 
73 		// If the pattern is already in the active list, there's nothing to do
74 		// (it can't/shouldn't be in the inactive list)
75 		if (activeList.contains(pattern)) {
76 			return;
77 		}
78 
79 		// Add the pattern to the active list and update the preference store
80 		activeList.add(pattern);
81 		String activePref = JavaDebugOptionsManager.serializeList(activeList.toArray(new String[activeList.size()]));
82 		prefStore.setValue(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, activePref);
83 
84 		// If the pattern was present in the inactive list, remove it since we just
85 		// added it to the active list
86 		if (inactiveList.contains(pattern)) {
87 			inactiveList.remove(pattern);
88 			String inactivePref = JavaDebugOptionsManager.serializeList(inactiveList.toArray(new String[inactiveList.size()]));
89 			prefStore.setValue(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, inactivePref);
90 		}
91 	}
92 
93 	/**
94 	 * Convenience method to get the preference store.
95 	 */
getPreferenceStore()96 	private IPreferenceStore getPreferenceStore() {
97 		return JDIDebugUIPlugin.getDefault().getPreferenceStore();
98 	}
99 
100 	/**
101 	 * Generate an appropriate String pattern for the specified Java stack
102 	 * frame or return null if generation failed.  For example, the pattern for
103 	 * a type might look like, "com. example.MyType", while the pattern for a
104 	 * package might look like, "com. example.*".
105 	 *
106 	 * @param frame the Java stack frame used to generate a String pattern
107 	 * @return String the pattern or <code>null</code> if one could not be
108 	 * generated
109 	 */
generateStepFilterPattern(IJavaStackFrame frame)110 	protected abstract String generateStepFilterPattern(IJavaStackFrame frame);
111 
112 }
113