package com.comphenix.protocol.wrappers; import java.util.Collection; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.comphenix.protocol.wrappers.collection.ConvertedSet; import com.google.common.collect.Multimap; import com.google.common.collect.Multiset; /** * Represents wrappers for Minecraft's own version of Guava. * @author Kristian */ class GuavaWrappers { private static volatile boolean USE_REFLECTION_FALLBACK = false; /** * Wrap a Bukkit multimap around Minecraft's internal multimap. * @param multimap - the multimap to wrap. * @return The Bukkit multimap. */ public static Multimap getBukkitMultimap( final com.google.common.collect.Multimap multimap) { if (USE_REFLECTION_FALLBACK) { return GuavaReflection.getBukkitMultimap(multimap); } Multimap result = new Multimap() { @Override public Map> asMap() { return multimap.asMap(); } @Override public void clear() { multimap.clear(); } @Override public boolean containsEntry(Object arg0, Object arg1) { return multimap.containsEntry(arg0, arg1); } @Override public boolean containsKey(Object arg0) { return multimap.containsKey(arg0); } @Override public boolean containsValue(Object arg0) { return multimap.containsValue(arg0); } @Override public Collection> entries() { return multimap.entries(); } @Override public boolean equals(Object arg0) { return multimap.equals(arg0); } @Override public Collection get(TKey arg0) { return multimap.get(arg0); } @Override public int hashCode() { return multimap.hashCode(); } @Override public boolean isEmpty() { return multimap.isEmpty(); } @Override public Set keySet() { return multimap.keySet(); } @Override public Multiset keys() { return getBukkitMultiset(multimap.keys()); } @Override public boolean put(TKey arg0, TValue arg1) { return multimap.put(arg0, arg1); } @Override public boolean putAll(com.google.common.collect.Multimap arg0) { boolean result = false; // Add each entry for (Entry entry : arg0.entries()) { result |= multimap.put(entry.getKey(), entry.getValue()); } return result; } @Override public boolean putAll(TKey arg0, Iterable arg1) { return multimap.putAll(arg0, arg1); } @Override public boolean remove(Object arg0, Object arg1) { return multimap.remove(arg0, arg1); } @Override public Collection removeAll(Object arg0) { return multimap.removeAll(arg0); } @Override public Collection replaceValues(TKey arg0, Iterable arg1) { return multimap.replaceValues(arg0, arg1); } @Override public int size() { return multimap.size(); } @Override public Collection values() { return multimap.values(); } }; try { result.size(); // Test return result; } catch (LinkageError e) { // Occurs on Cauldron 1.7.10 USE_REFLECTION_FALLBACK = true; return GuavaReflection.getBukkitMultimap(multimap); } } public static Multiset getBukkitMultiset(final com.google.common.collect.Multiset multiset) { if (USE_REFLECTION_FALLBACK) { return GuavaReflection.getBukkitMultiset(multiset); } Multiset result = new Multiset() { @Override public int add(TValue arg0, int arg1) { return multiset.add(arg0, arg1); } @Override public boolean add(TValue arg0) { return multiset.add(arg0); } @Override public boolean addAll(Collection c) { return multiset.addAll(c); } @Override public void clear() { multiset.clear(); } @Override public boolean contains(Object arg0) { return multiset.contains(arg0); } @Override public boolean containsAll(Collection arg0) { return multiset.containsAll(arg0); } @Override public int count(Object arg0) { return multiset.count(arg0); } @Override public Set elementSet() { return multiset.elementSet(); } @Override public Set> entrySet() { return new ConvertedSet< com.google.common.collect.Multiset.Entry, Multiset.Entry> (multiset.entrySet()) { @Override protected com.google.common.collect.Multiset.Entry toOuter( com.google.common.collect.Multiset.Entry inner) { return getBukkitEntry(inner); } @Override protected com.google.common.collect.Multiset.Entry toInner( com.google.common.collect.Multiset.Entry outer) { throw new UnsupportedOperationException("Cannot convert " + outer); } }; } @Override public boolean equals(Object arg0) { return multiset.equals(arg0); } @Override public int hashCode() { return multiset.hashCode(); } @Override public boolean isEmpty() { return multiset.isEmpty(); } @Override public Iterator iterator() { return multiset.iterator(); } @Override public int remove(Object arg0, int arg1) { return multiset.remove(arg0, arg1); } @Override public boolean remove(Object arg0) { return multiset.remove(arg0); } @Override public boolean removeAll(Collection arg0) { return multiset.removeAll(arg0); } @Override public boolean retainAll(Collection arg0) { return multiset.retainAll(arg0); } @Override public boolean setCount(TValue arg0, int arg1, int arg2) { return multiset.setCount(arg0, arg1, arg2); } @Override public int setCount(TValue arg0, int arg1) { return multiset.setCount(arg0, arg1); } @Override public int size() { return multiset.size(); } @Override public Object[] toArray() { return multiset.toArray(); } @Override public T[] toArray(T[] a) { return multiset.toArray(a); } @Override public String toString() { return multiset.toString(); } }; try { result.size(); // Test return result; } catch (LinkageError e) { USE_REFLECTION_FALLBACK = true; return GuavaReflection.getBukkitMultiset(multiset); } } private static Multiset.Entry getBukkitEntry(final com.google.common.collect.Multiset.Entry entry) { return new Multiset.Entry() { @Override public boolean equals(Object arg0) { return entry.equals(arg0); } @Override public int getCount() { return entry.getCount(); } @Override public TValue getElement() { return entry.getElement(); } @Override public int hashCode() { return entry.hashCode(); } @Override public String toString() { return entry.toString(); } }; } }