-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Add guava compatability up to 27.0.1 #6948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
de3486b
3926f5b
cf86426
9c6d33b
b04ef2e
c1982ad
0fd0c55
64698ee
9cb2e73
5ea6c47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,16 +19,58 @@ | |
|
|
||
| package org.apache.druid.common.guava; | ||
|
|
||
| import com.google.common.base.CharMatcher; | ||
| import com.google.common.base.Preconditions; | ||
| import com.google.common.base.Strings; | ||
| import com.google.common.net.HostAndPort; | ||
| import com.google.common.primitives.Longs; | ||
| import org.apache.druid.java.util.common.IAE; | ||
| import org.apache.druid.java.util.common.StringUtils; | ||
|
|
||
| import javax.annotation.Nullable; | ||
| import javax.el.MethodNotFoundException; | ||
| import java.lang.reflect.Field; | ||
| import java.lang.reflect.InvocationTargetException; | ||
| import java.lang.reflect.Method; | ||
| import java.util.Arrays; | ||
|
|
||
| /** | ||
| * This class contains a bunch of guava helper functions to bridge compatability problems across guava versions, or | ||
| * between guava and java standard libraries. Any version compatability related entries should have a reference to | ||
| * the critical commit(s). | ||
| */ | ||
| public class GuavaUtils | ||
| { | ||
| private static final CharMatcher BREAKING_WHITESPACE_INSTANCE; | ||
|
|
||
| static { | ||
| // https://github.com/google/guava/commit/4fbb165ebf208d75100d5d47f56750d247f7d181 | ||
| // Since v19.0 | ||
| CharMatcher matcher; | ||
| try { | ||
| final Method m = CharMatcher.class.getDeclaredMethod("breakingWhitespace"); | ||
| matcher = (CharMatcher) m.invoke(null); | ||
| } | ||
| catch (IllegalAccessException | InvocationTargetException e) { | ||
| throw new IllegalStateException("Failed to fetch breakingWhitespace", e); | ||
| } | ||
| catch (NoSuchMethodException e) { | ||
| try { | ||
| final Field f = CharMatcher.class.getDeclaredField("BREAKING_WHITESPACE"); | ||
| matcher = (CharMatcher) f.get(null); | ||
| } | ||
| catch (IllegalAccessException e1) { | ||
| throw new IllegalStateException("Failed to access BREAKING_WHITESPACE", e1); | ||
| } | ||
| catch (NoSuchFieldException e1) { | ||
| throw new IllegalStateException("Cannot find breaking white space in guava", e1); | ||
| } | ||
| } | ||
| if (matcher == null) { | ||
| throw new IllegalStateException("wtf!?"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make the error message more constructive, or absent altogether |
||
| } | ||
| BREAKING_WHITESPACE_INSTANCE = matcher; | ||
| } | ||
|
|
||
| /** | ||
| * To fix semantic difference of Longs.tryParse() from Long.parseLong (Longs.tryParse() returns null for '+' started value) | ||
|
|
@@ -62,4 +104,72 @@ public static <T extends Enum<T>> T getEnumIfPresent(final Class<T> enumClass, f | |
|
|
||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Try the various methods (zero arguments) against the object. This is handy for maintaining guava compatability | ||
| * | ||
| * @param object The object to call the methods on | ||
| * @param methods The sequence of methods to call | ||
| * @param <T> The return type | ||
| * | ||
| * @return The result of invoking the method on the object | ||
| */ | ||
| private static <T> T tryMethods(Object object, Class<T> assignableTo, String... methods) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documentation should reference the specific commit and the range of lines (as a Github link) in Guava from where this was copied. Same for other non-trivial parts of the copied code.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part was not copied. The method names in the callers are copied though. I'll add a javadoc here to help make sure a "use the git tag as a reference" pattern is followed in the future for such behaviors.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
| { | ||
| for (String method : methods) { | ||
| try { | ||
| final Method m = object.getClass().getDeclaredMethod(method); | ||
| if (!assignableTo.isAssignableFrom(m.getReturnType())) { | ||
| throw new IAE( | ||
| "Cannot assign [%s] to [%s] in [%s] from [%s]", | ||
| m.getReturnType(), | ||
| assignableTo, | ||
| m, | ||
| object.getClass() | ||
| ); | ||
| } | ||
| try { | ||
| return (T) m.invoke(object); | ||
| } | ||
| catch (IllegalAccessException | InvocationTargetException e) { | ||
| throw new IAE("Failed to invoke [%s] on [%s]", m, object); | ||
| } | ||
| } | ||
| catch (NoSuchMethodException e) { | ||
| // Keep going | ||
| } | ||
| } | ||
| throw new MethodNotFoundException(StringUtils.format( | ||
| "Unable to find methods %s in [%s]", | ||
| Arrays.toString(methods), | ||
| object.getClass() | ||
| )); | ||
| } | ||
|
|
||
| /** | ||
| * Get the host portion of the {@link HostAndPort} that has the host's text. Changes in different guava versions | ||
| * | ||
| * @param hostAndPort The object to pull from | ||
| * | ||
| * @return The host portion of the host and port | ||
| */ | ||
| public static String getHostText(HostAndPort hostAndPort) | ||
| { | ||
| // https://github.com/google/guava/commit/b0babb69b05ed4d15cce74635ae96cf8ba78c85f | ||
| // Change started in v20.0 | ||
| return tryMethods(hostAndPort, String.class, "getHostText", "getHost"); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the instance of the breaking whitespace char matcher in guava. | ||
| * | ||
| * This moved starting in guava 19 | ||
| * | ||
| * @return `CharMatcher.BREAKING_WHITESPACE` or `CharMatcher.breakingWhitespace()` depending on whichever works | ||
| */ | ||
|
|
||
| public static CharMatcher breakingWhitespace() | ||
| { | ||
| return BREAKING_WHITESPACE_INSTANCE; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to break this file into sections: jackson, guava, jdk, everything else.