diff --git a/src/com/massivecraft/massivecore/command/type/TypeAbstractChoice.java b/src/com/massivecraft/massivecore/command/type/TypeAbstractChoice.java index 91e85776..e5317392 100644 --- a/src/com/massivecraft/massivecore/command/type/TypeAbstractChoice.java +++ b/src/com/massivecraft/massivecore/command/type/TypeAbstractChoice.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.regex.Pattern; import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -16,6 +17,7 @@ import com.massivecraft.massivecore.collections.MassiveMap; import com.massivecraft.massivecore.collections.MassiveSet; import com.massivecraft.massivecore.collections.MassiveTreeSet; import com.massivecraft.massivecore.command.type.collection.AllAble; +import com.massivecraft.massivecore.util.ReflectionUtil; import com.massivecraft.massivecore.util.Txt; public abstract class TypeAbstractChoice extends TypeAbstract implements AllAble @@ -41,6 +43,19 @@ public abstract class TypeAbstractChoice extends TypeAbstract implements A public String getHelp() { return this.help; } public TypeAbstractChoice setHelp(String help) { this.help = help; return this; } + protected boolean canSeeOverridden = calcCanSeeOverriden(); + public boolean isCanSeeOverridden() { return this.canSeeOverridden; } + public void setCanSeeOverridden(boolean canSeeOverridden) { this.canSeeOverridden = canSeeOverridden; } + public boolean calcCanSeeOverriden() + { + return ! TypeAbstractChoice.class.equals(ReflectionUtil.getSuperclassDeclaringMethod(this.getClass(), true, "canSee")); + } + + // TODO: cache stuff... the options? + protected boolean cachable = false; + public boolean isCachable() { return this.cachable; } + public void setCachable(boolean cachable) { this.cachable = cachable; } + // -------------------------------------------- // // OVERRIDE: TYPE // -------------------------------------------- // @@ -51,13 +66,22 @@ public abstract class TypeAbstractChoice extends TypeAbstract implements A // NPE Evade if (arg == null) return null; + // Exact + T exact = this.getExactMatch(arg); + if (exact != null) return exact; + // Get All Collection all = this.getAll(sender); // Get Options + // NOTE: These keys are prepared. + // TODO: Optimization should be possible here. + // TODO: If the "all" never changes AKA are cached... we can cache the options as well. + // TODO: If they are different for visibility but do not change... we can Map options = this.getOptions(all); // Get Matches + // NOTE: I can probably not optimize this method further? List matches = this.getMatches(options, arg, false); // Exact @@ -159,6 +183,9 @@ public abstract class TypeAbstractChoice extends TypeAbstract implements A @Override public Collection getAll(CommandSender sender) { + // No Can See Override? + if ( ! this.isCanSeeOverridden()) return this.getAll(); + // Create Set ret = new MassiveSet(); @@ -192,24 +219,22 @@ public abstract class TypeAbstractChoice extends TypeAbstract implements A @SuppressWarnings("unchecked") public List getMatches(Map options, String arg, boolean levenshtein) { - // Exact - T exact = this.getExactMatch(arg); - if (exact != null) return new MassiveList(exact); - // Create List ret = new MassiveList(); // Prepare arg = this.prepareKey(arg); + // Exact + T exact = options.get(arg); + if (exact != null) return new MassiveList(exact); + // Fill for (Entry entry : options.entrySet()) { String key = entry.getKey(); T value = entry.getValue(); - if (arg.equals(key)) return new MassiveList(value); - if (levenshtein) { if ( ! isLevenshteinSimilar(arg, key)) continue; @@ -292,12 +317,14 @@ public abstract class TypeAbstractChoice extends TypeAbstract implements A } // The purpose of this method is to strip down a string to a comparable string key. + protected static Pattern PATTERN_KEY_UNWANTED = Pattern.compile("[_\\-\\s]+"); public String prepareKey(String string) { if (string == null) return null; string = string.trim(); string = string.toLowerCase(); - string = string.replaceAll("[_\\-\\s]+", ""); + // SLOW: string = string.replaceAll("[_\\-\\s]+", ""); + string = PATTERN_KEY_UNWANTED.matcher(string).replaceAll(""); return string; } diff --git a/src/com/massivecraft/massivecore/util/ReflectionUtil.java b/src/com/massivecraft/massivecore/util/ReflectionUtil.java index 1e5b5786..190d5e9f 100644 --- a/src/com/massivecraft/massivecore/util/ReflectionUtil.java +++ b/src/com/massivecraft/massivecore/util/ReflectionUtil.java @@ -1,10 +1,13 @@ package com.massivecraft.massivecore.util; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import com.massivecraft.massivecore.Predicate; + public class ReflectionUtil { // -------------------------------------------- // @@ -174,6 +177,50 @@ public class ReflectionUtil return transferFields(clazz, from, to, null); } - + // -------------------------------------------- // + // SUPERCLASSES + // -------------------------------------------- // + + public static List> getSuperclasses(Class clazz, boolean includeSelf) + { + // Create + List> ret = new ArrayList>(); + + // Fill + if ( ! includeSelf) clazz = clazz.getSuperclass(); + while (clazz != null) + { + ret.add(clazz); + clazz = clazz.getSuperclass(); + } + + // Return + return ret; + } + + public static Class getSuperclassPredicate(Class clazz, boolean includeSelf, Predicate> predicate) + { + for (Class superClazz : getSuperclasses(clazz, includeSelf)) + { + if (predicate.apply(superClazz)) return superClazz; + } + return null; + } + + public static Class getSuperclassDeclaringMethod(Class clazz, boolean includeSelf, final String methodName) + { + return getSuperclassPredicate(clazz, includeSelf, new Predicate>() + { + @Override + public boolean apply(Class clazz) + { + for (Method method : clazz.getDeclaredMethods()) + { + if (method.getName().equals(methodName)) return true; + } + return false; + } + }); + } } diff --git a/src/com/massivecraft/massivecore/util/Txt.java b/src/com/massivecraft/massivecore/util/Txt.java index 399f1068..3016074b 100644 --- a/src/com/massivecraft/massivecore/util/Txt.java +++ b/src/com/massivecraft/massivecore/util/Txt.java @@ -233,7 +233,7 @@ public class Txt { if (string == null) return null; if (string.length() == 0) return string; - return string.substring(0, 1).toUpperCase()+string.substring(1); + return string.substring(0, 1).toUpperCase() + string.substring(1); } public static String repeat(String string, int times) @@ -400,10 +400,11 @@ public class Txt // Material name tools // -------------------------------------------- // + protected static Pattern PATTERN_ENUM_SPLIT = Pattern.compile("[\\s_]+"); public static String getNicedEnumString(String str) { List parts = new ArrayList(); - for (String part : str.toLowerCase().split("[\\s_]+")) + for (String part : PATTERN_ENUM_SPLIT.split(str.toLowerCase())) { parts.add(upperCaseFirst(part)); }