From e0a2873c99f2b1dd5b167e4f7c9a606a257b1f7a Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 5 Apr 2014 14:44:41 -0700 Subject: [PATCH] Removed use of Guava's Cache because Bukkit uses an ancient version of Guava. --- .../util/annotation/RequiresNewerGuava.java | 33 +++++++++ .../worldedit/util/eventbus/EventBus.java | 47 ++----------- .../util/eventbus/HierarchyCache.java | 69 +++++++++++++++++++ 3 files changed, 109 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/util/annotation/RequiresNewerGuava.java create mode 100644 src/main/java/com/sk89q/worldedit/util/eventbus/HierarchyCache.java diff --git a/src/main/java/com/sk89q/worldedit/util/annotation/RequiresNewerGuava.java b/src/main/java/com/sk89q/worldedit/util/annotation/RequiresNewerGuava.java new file mode 100644 index 000000000..b7511be71 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/annotation/RequiresNewerGuava.java @@ -0,0 +1,33 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Marks features that should be replaced with Google Guava but cannot + * yet because Bukkit uses such an old version of Guava. + */ +@Retention(RetentionPolicy.SOURCE) +@Documented +public @interface RequiresNewerGuava { +} diff --git a/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java b/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java index 0634a0788..4afd0914f 100644 --- a/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java +++ b/src/main/java/com/sk89q/worldedit/util/eventbus/EventBus.java @@ -20,16 +20,14 @@ package com.sk89q.worldedit.util.eventbus; import com.google.common.base.Supplier; -import com.google.common.base.Throwables; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.collect.*; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.common.collect.SetMultimap; import com.google.common.eventbus.DeadEvent; +import com.sk89q.worldedit.util.annotation.RequiresNewerGuava; import java.lang.reflect.InvocationTargetException; import java.util.*; -import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; @@ -66,35 +64,8 @@ public class EventBus { */ private final SubscriberFindingStrategy finder = new AnnotatedSubscriberFinder(); - /** - * A thread-safe cache for flattenHierarchy(). The Class class is immutable. - */ - private Cache, Set>> flattenHierarchyCache = - CacheBuilder.newBuilder() - .weakKeys() - .build(new CacheLoader, Set>>() { - @Override - public Set> load(Class concreteClass) throws Exception { - List> parents = Lists.newLinkedList(); - Set> classes = Sets.newHashSet(); - - parents.add(concreteClass); - - while (!parents.isEmpty()) { - Class clazz = parents.remove(0); - classes.add(clazz); - - Class parent = clazz.getSuperclass(); - if (parent != null) { - parents.add(parent); - } - - Collections.addAll(parents, clazz.getInterfaces()); - } - - return classes; - } - }); + @RequiresNewerGuava + private HierarchyCache flattenHierarchyCache = new HierarchyCache(); /** * Registers the given handler for the given class to receive events. @@ -251,11 +222,7 @@ public class EventBus { * @return {@code clazz}'s complete type hierarchy, flattened and uniqued. */ Set> flattenHierarchy(Class concreteClass) { - try { - return flattenHierarchyCache.get(concreteClass); - } catch (ExecutionException e) { - throw Throwables.propagate(e.getCause()); - } + return flattenHierarchyCache.get(concreteClass); } } diff --git a/src/main/java/com/sk89q/worldedit/util/eventbus/HierarchyCache.java b/src/main/java/com/sk89q/worldedit/util/eventbus/HierarchyCache.java new file mode 100644 index 000000000..04c7f508c --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/eventbus/HierarchyCache.java @@ -0,0 +1,69 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.eventbus; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.sk89q.worldedit.util.annotation.RequiresNewerGuava; + +import java.util.*; + +/** + * Holds a cache of class hierarcy. + *

+ * This exists because Bukkit has an ancient version of Guava and the cache + * library in Guava has since changed. + */ +@RequiresNewerGuava +class HierarchyCache { + + private final Map, Set>> cache = new WeakHashMap, Set>>(); + + public Set> get(Class concreteClass) { + Set> ret = cache.get(concreteClass); + if (ret == null) { + ret = build(concreteClass); + cache.put(concreteClass, ret); + } + return ret; + } + + protected Set> build(Class concreteClass) { + List> parents = Lists.newLinkedList(); + Set> classes = Sets.newHashSet(); + + parents.add(concreteClass); + + while (!parents.isEmpty()) { + Class clazz = parents.remove(0); + classes.add(clazz); + + Class parent = clazz.getSuperclass(); + if (parent != null) { + parents.add(parent); + } + + Collections.addAll(parents, clazz.getInterfaces()); + } + + return classes; + } + +}