Bug 442627 - Honour the stepFilters extension point in the Java debugger

Change-Id: If358305e3b40ed42a5741dbc7eafb8b546219c4f
diff --git a/org.eclipse.jdt.debug.tests/plugin.xml b/org.eclipse.jdt.debug.tests/plugin.xml
index f9378d2..bb85d96 100644
--- a/org.eclipse.jdt.debug.tests/plugin.xml
+++ b/org.eclipse.jdt.debug.tests/plugin.xml
@@ -469,5 +469,12 @@
            class="org.eclipse.jdt.debug.tests.core.VMInstallTestsLibraryLocationResolver">
      </resolver>
   </extension>
+  <extension
+        point="org.eclipse.debug.core.stepFilters">
+     <stepFilter
+           class="org.eclipse.jdt.debug.test.stepping.TestContributedStepFilter"
+           modelIdentifier="org.eclipse.jdt.debug">
+     </stepFilter>
+  </extension>
 
 </plugin>
diff --git a/org.eclipse.jdt.debug.tests/testprograms/StepFilterTwo.java b/org.eclipse.jdt.debug.tests/testprograms/StepFilterTwo.java
index b1a22b7..e00515a 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/StepFilterTwo.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/StepFilterTwo.java
@@ -24,5 +24,12 @@
 	void test() {
 		for (int i = 0; i < 10; i++);
 	}
+	
+	/**
+	 * This test method should only be called by the contributed step filter tests
+	 * @see TestContributedStepFilter
+	 */
+	void contributed() {
+	}
 }
 
diff --git a/org.eclipse.jdt.debug.tests/testprograms/TestContributedStepFilterClass.java b/org.eclipse.jdt.debug.tests/testprograms/TestContributedStepFilterClass.java
new file mode 100644
index 0000000..85f1597
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testprograms/TestContributedStepFilterClass.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) Aug 28, 2014 IBM Corporation 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
+ *******************************************************************************/
+
+public class TestContributedStepFilterClass {
+	
+	public static void main(String[] args) {
+		StepFilterTwo two = new StepFilterTwo();
+		two.go();
+		two.contributed();
+		two.go();
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepFilterTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepFilterTests.java
index afb26d8..12a6ec5 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepFilterTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepFilterTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2011 IBM Corporation and others.
+ *  Copyright (c) 2000, 2014 IBM Corporation 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
@@ -291,6 +291,37 @@
 	}	
 
 	/**
+	 * Tests filtering from a contributed filter
+	 * 
+	 * @throws Exception
+	 * @since 3.8.300
+	 */
+	public void testContributedFilter1() throws Exception {
+		String typeName = "TestContributedStepFilterClass";
+		getPrefStore().setValue(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, fOriginalActiveFilters + ",StepFilterTwo,"
+				+ fOriginalInactiveFilters);
+		ILineBreakpoint bp = createLineBreakpoint(17, typeName);
+		bp.setEnabled(true);
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToLineBreakpoint(typeName, bp, false);
+			IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
+			assertEquals("Wrong line number", 17, stackFrame.getLineNumber());
+			thread = stepIntoWithFilters(stackFrame);
+			assertNotNull("We should have stepped over the method call", thread);
+			stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
+			assertEquals("Wrong line number", 18, stackFrame.getLineNumber());
+			assertEquals("Should be in main", "main", stackFrame.getMethodName());
+		}
+		finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+			resetStepFilters();
+		}
+	}
+
+	/**
 	 * Reset the step filtering preferences
 	 */
 	protected void resetStepFilters() {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/TestContributedStepFilter.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/TestContributedStepFilter.java
new file mode 100644
index 0000000..1034f51
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/TestContributedStepFilter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) Aug 28, 2014 IBM Corporation 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
+ *******************************************************************************/
+package org.eclipse.jdt.debug.test.stepping;
+
+import org.eclipse.debug.core.model.IStepFilter;
+
+import com.sun.jdi.Method;
+
+/**
+ * Contributed step filter
+ */
+public class TestContributedStepFilter implements IStepFilter {
+
+	/**
+	 * 
+	 */
+	public TestContributedStepFilter() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.debug.core.model.IStepFilter#isFiltered(java.lang.Object)
+	 */
+	public boolean isFiltered(Object object) {
+		if (object instanceof Method) {
+			Method method = (Method) object;
+			return "StepFilterTwo".equals(method.declaringType().name()) && "contributed".equals(method.name());
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index 78e3488..6ee2f5f 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -192,7 +192,7 @@
 			"ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests",
 			"bug329294", "bug401270", "org.eclipse.debug.tests.targets.HcrClass2", "org.eclipse.debug.tests.targets.HcrClass3", "org.eclipse.debug.tests.targets.HcrClass4",
 			"org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8",
-			"org.eclipse.debug.tests.targets.HcrClass9"};
+			"org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass" };
 
 	final String[] LAUNCH_CONFIG_NAMES_1_8 = {"LargeSourceFile"};
 
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIMethod.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIMethod.java
index d0b1274..9686300 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIMethod.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIMethod.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2011 Jesper Steen Moller and others.
+ * Copyright (c) 2010, 2014 Jesper Steen Moller 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
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Jesper Steen Moller - initial API and implementation
+ *     IBM Corporation - Bug fixing
  *******************************************************************************/
 
 package org.eclipse.jdt.internal.debug.core.model;
@@ -19,7 +20,7 @@
  * @author jmoeller2
  * 
  */
-public abstract class JDIMethod {
+public class JDIMethod {
 
 	// Known Java byte codes, from the JVM spec
 	private static final int ALOAD_0 = 0x2a;
@@ -81,7 +82,10 @@
 	 * @return true if the method is a simple getter
 	 */
 	public static boolean isGetterMethod(Method method) {
-		if (!(method.name().startsWith("get") || method.name().startsWith("is")))return false; //$NON-NLS-1$  //$NON-NLS-2$
+		if (!(method.name().startsWith("get") || method.name().startsWith("is"))) //$NON-NLS-1$ //$NON-NLS-2$
+		 {
+			return false;
+		}
 
 		byte[] bytecodes = method.bytecodes();
 		return bytecodes.length == 5 && (bytecodes[0] & 0xFF) == ALOAD_0
@@ -101,8 +105,9 @@
 	 * @return true if the method is a simple setter
 	 */
 	public static boolean isSetterMethod(Method method) {
-		if (!method.name().startsWith("set")) //$NON-NLS-1$
+		if (!method.name().startsWith("set")) { //$NON-NLS-1$
 			return false;
+		}
 
 		byte[] bytecodes = method.bytecodes();
 		return bytecodes.length == 6 && (bytecodes[0] & 0xFF) == ALOAD_0
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
index 8d5175a..68efc2a 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
@@ -34,6 +34,7 @@
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.IStackFrame;
 import org.eclipse.debug.core.model.IStep;
+import org.eclipse.debug.core.model.IStepFilter;
 import org.eclipse.debug.core.model.ISuspendResume;
 import org.eclipse.debug.core.model.ITerminate;
 import org.eclipse.debug.core.model.IThread;
@@ -2549,8 +2550,9 @@
 						.isFilterConstructors();
 				boolean filterSetters = getJavaDebugTarget().isFilterSetters();
 				boolean filterGetters = getJavaDebugTarget().isFilterGetters();
+				IStepFilter[] contributedFilters = DebugPlugin.getStepFilters(JDIDebugPlugin.getUniqueIdentifier());
 				if (!(filterStatics || filterSynthetics || filterConstructors
-						|| filterGetters || filterSetters)) {
+ || filterGetters || filterSetters || contributedFilters.length > 0)) {
 					return false;
 				}
 
@@ -2561,6 +2563,11 @@
 						|| (filterSetters && JDIMethod.isSetterMethod(method))) {
 					return true;
 				}
+				for (int i = 0; i < contributedFilters.length; i++) {
+					if (contributedFilters[i].isFiltered(method)) {
+						return true;
+					}
+				}
 			}
 
 			return false;