// // Returns true if this method is allowed to raise SQLFeatureNotSupportedException. // private boolean isExcludable(Method method) throws Exception { Class iface = method.getDeclaringClass(); HashSet<Method> excludableMethods = excludableMap.get(iface); if (excludableMethods == null) { return false; } return excludableMethods.contains(method); }
// // Initialize the hashtable of methods which are allowed to raise // SQLFeatureNotSupportedException. // private void initializeExcludableMap(HashSet<String> vanishedMethodList) throws Exception { excludableMap = new Hashtable<Class, HashSet<Method>>(); int count = rawExcludables.length; for (int i = 0; i < count; i++) { Exclusions exclusions = rawExcludables[i]; Class<?> iface = exclusions.getInterface(); MD[] mds = exclusions.getExcludedMethods(); int exclusionCount = mds.length; HashSet<Method> excludedMethodSet = new HashSet<Method>(); for (int j = 0; j < exclusionCount; j++) { MD md = mds[j]; if (!md.requiredAtThisLevel()) { continue; } // // If we are strictly enforcing the JDBC standard, // then expose the mandatory methods which we know Derby // doesn't implement. // if (STRICT_ENFORCEMENT && !md.isOptional()) { continue; } Method method = null; try { method = iface.getMethod(md.getMethodName(), md.getArgTypes()); } catch (NoSuchMethodException e) { } if (method == null) { vanishedMethodList.add( "Method has vanished from SQL interface: " + iface.getName() + "." + md); } excludedMethodSet.add(method); } excludableMap.put(iface, excludedMethodSet); } }
// // Record an unexpected error. // private void recordUnexpectedError( Object candidate, Class iface, Method method, HashSet<String> notUnderstoodList, Throwable cause) throws Exception { notUnderstoodList.add(candidate.getClass().getName() + " " + method + " raises " + cause); }
// debug print the list of methods which have disappeared from the SQL interface private void printVanishedMethodList(HashSet<String> vanishedMethodList) { int count = vanishedMethodList.size(); if (count == 0) { return; } println("--------------- VANISHED METHODS ------------------"); println("--"); String[] result = new String[count]; vanishedMethodList.toArray(result); Arrays.sort(result); for (int i = 0; i < count; i++) { println(result[i]); } }
// debug print the list of methods which throw SQLFeatureNotSupportedException private void printUnsupportedList(HashSet<String> unsupportedList) { int count = unsupportedList.size(); if (count == 0) { return; } println("--------------- UNSUPPORTED METHODS ------------------"); println("--"); String[] result = new String[count]; unsupportedList.toArray(result); Arrays.sort(result); for (int i = 0; i < count; i++) { println(result[i]); } }
// Debug print the list of method failures which we don't understand private void printNotUnderstoodList(HashSet<String> notUnderstoodList) { int count = notUnderstoodList.size(); if (count == 0) { return; } println("\n\n"); println("--------------- NOT UNDERSTOOD METHODS ------------------"); println("--"); String[] result = new String[count]; notUnderstoodList.toArray(result); Arrays.sort(result); for (int i = 0; i < count; i++) { println(result[i]); } }
// // Examine a single method to see if it raises SQLFeatureNotSupportedException. // private void vetMethod( Object candidate, Class iface, Method method, HashSet<String> unsupportedList, HashSet<String> notUnderstoodList) throws Exception { try { method.invoke(candidate, getNullArguments(method.getParameterTypes())); // it's ok for the method to succeed } catch (Throwable e) { if (!(e instanceof InvocationTargetException)) { recordUnexpectedError(candidate, iface, method, notUnderstoodList, e); } else { Throwable cause = e.getCause(); if (cause instanceof SQLFeatureNotSupportedException) { boolean isExcludable = isExcludable(method); if (!isExcludable) { StackTraceElement[] stack = cause.getStackTrace(); int i = 0; while (i < stack.length && !stack[i].getMethodName().equals("notImplemented")) { ++i; } while (i < stack.length && stack[i].getMethodName().equals("notImplemented")) { ++i; } if (i == stack.length) { // cause.printStackTrace(); } unsupportedList.add( candidate.getClass().getName() + ": " + method + "@" + (i == stack.length ? "no source" : cause.getStackTrace()[i])); } else { } } else if (cause instanceof SQLException) { // swallow other SQLExceptions, caused by bogus args } else if (cause instanceof NullPointerException) { // swallow other NPEs, caused by bogus args } else if (cause instanceof ArrayIndexOutOfBoundsException) { // swallow these, caused by bogus args } else { recordUnexpectedError(candidate, iface, method, notUnderstoodList, cause); } } } }
/** Find all methods in this framework which raise SQLFeatureNotSupportedException. */ public void testSupportedMethods() throws Exception { getTestConfiguration().setVerbosity(true); HashSet<String> vanishedMethodList = new HashSet<String>(); HashSet<String> unsupportedList = new HashSet<String>(); HashSet<String> notUnderstoodList = new HashSet<String>(); // Build map of interfaces to their methods which may raise SQLFeatureNotSupportedException. initializeExcludableMap(vanishedMethodList); vetDataSource(unsupportedList, notUnderstoodList); vetConnectionPooledDataSource(unsupportedList, notUnderstoodList); vetXADataSource(unsupportedList, notUnderstoodList); // // Print methods which behave unexpectedly. // printVanishedMethodList(vanishedMethodList); printUnsupportedList(unsupportedList); printNotUnderstoodList(notUnderstoodList); int actualErrorCount = vanishedMethodList.size() + unsupportedList.size() + notUnderstoodList.size(); assertEquals("Unexpected discrepancies.", 0, actualErrorCount); }