From bf8e6b55a4862b531d94012a8fed08b62b442332 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Mon, 10 Oct 2016 01:39:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- .../yumc/YumCore/commands/CommandParse.java | 154 ++++++++++++++++-- 1 file changed, 137 insertions(+), 17 deletions(-) diff --git a/src/main/java/pw/yumc/YumCore/commands/CommandParse.java b/src/main/java/pw/yumc/YumCore/commands/CommandParse.java index b2e2aa5..271af3d 100644 --- a/src/main/java/pw/yumc/YumCore/commands/CommandParse.java +++ b/src/main/java/pw/yumc/YumCore/commands/CommandParse.java @@ -1,6 +1,10 @@ package pw.yumc.YumCore.commands; import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.HashMap; import java.util.LinkedList; @@ -33,15 +37,28 @@ public class CommandParse { public List parsed = new LinkedList<>(); public CommandParse(final Class[] classes, final Annotation[][] annons) { - for (final Class classe : classes) { - final Class clazz = classe; + for (int i = 0; i < classes.length; i++) { + final Class clazz = classes[i]; + final Annotation[] annotations = annons[i]; if (clazz.isAssignableFrom(CommandSender.class)) { continue; } if (!allparses.containsKey(clazz)) { throw new CommandParseException(String.format("无法解析的参数类型 %s !", clazz.getName())); } - parse.add(allparses.get(clazz)); + final Parse parse = allparses.get(clazz).clone(); + for (final Annotation annotation : annotations) { + if (annotation.annotationType() == Default.class) { + parse.setAttr("default", ((Default) annotation).value()); + } else if (annotation.annotationType() == Limit.class) { + parse.setAttr("min", ((Limit) annotation).min()); + parse.setAttr("max", ((Limit) annotation).max()); + } else if (annotation.annotationType() == KeyValue.class) { + final KeyValue kv = (KeyValue) annotation; + parse.setAttr(kv.key(), kv.value()); + } + } + this.parse.add(parse); } } @@ -66,13 +83,13 @@ public class CommandParse { pobjs.add(parse.get(i).parse(args[i])); } } catch (final Exception e) { - throw new CommandException(String.format(e.getMessage(), i + 1)); + throw new CommandException(String.format("第 %s 个参数 ", i + 1) + e.getMessage()); } } return pobjs.toArray(); } - public static class BooleanParse implements Parse { + public static class BooleanParse extends Parse { public BooleanParse() { allparses.put(Boolean.class, this); allparses.put(boolean.class, this); @@ -83,12 +100,24 @@ public class CommandParse { try { return Boolean.parseBoolean(arg); } catch (final Exception e) { - throw new CommandParseException("第 %s 个参数必须为True或者False!"); + throw new CommandParseException("必须为True或者False!"); } } } - public static class IntegerParse implements Parse { + /** + * 默认参数 + * + * @since 2016年7月23日 上午9:00:27 + * @author 喵♂呜 + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Default { + String value(); + } + + public static class IntegerParse extends Parse { public IntegerParse() { allparses.put(Integer.class, this); allparses.put(int.class, this); @@ -97,14 +126,58 @@ public class CommandParse { @Override public Integer parse(final String arg) { try { - return Integer.parseInt(arg); + final int result = Integer.parseInt(arg); + if (min > result || result > max) { + throwRange(); + } + return result; } catch (final Exception e) { - throw new CommandParseException("第 %s 个参数必须为数字!"); + throw new CommandParseException("必须为数字!"); } } } - public static class LongParse implements Parse { + /** + * 自定义参数 + * + * @since 2016年7月23日 上午9:00:27 + * @author 喵♂呜 + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface KeyValue { + /** + * @return 键 + */ + String key(); + + /** + * @return 值 + */ + String value() default ""; + } + + /** + * 参数限制 + * + * @since 2016年7月23日 上午9:00:27 + * @author 喵♂呜 + */ + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Limit { + /** + * @return 最大长度(最大值) + */ + int max() default 255; + + /** + * @return 最小长度(或最小值) + */ + int min(); + } + + public static class LongParse extends Parse { public LongParse() { allparses.put(Long.class, this); allparses.put(long.class, this); @@ -113,35 +186,82 @@ public class CommandParse { @Override public Long parse(final String arg) { try { - return Long.parseLong(arg); + final long result = Long.parseLong(arg); + if (min > result || result > max) { + throwRange(); + } + return result; } catch (final Exception e) { - throw new CommandParseException("第 %s 个参数必须为数字!"); + throw new CommandParseException("必须为数字!"); } } } - public static interface Parse { - public RT parse(String arg) throws CommandParseException; + public static abstract class Parse implements Cloneable { + protected Object def; + protected Map attrs = new HashMap<>(); + protected int min; + protected int max; + + @Override + public Parse clone() { + try { + return (Parse) super.clone(); + } catch (final CloneNotSupportedException e) { + return null; + } + } + + public Object getDefault() { + return def; + } + + public void load() { + def = attrs.get("default"); + min = (int) attrs.get("min"); + max = (int) attrs.get("max"); + } + + public abstract RT parse(String arg) throws CommandParseException; + + public void setAttr(final String name, final Object value) { + attrs.put(name, value); + } + + public void throwRange() { + throwRange(null); + } + + public void throwRange(final String str) { + throw new CommandException(String.format(str == null ? "必须在 %s 到 %s之间!" : str, min, max)); + } } - public static class PlayerParse implements Parse { + public static class PlayerParse extends Parse { public PlayerParse() { allparses.put(Player.class, this); } @Override public Player parse(final String arg) { - return Bukkit.getPlayerExact(arg); + final Player p = Bukkit.getPlayerExact(arg); + if (attrs.containsKey("check") && p == null) { + throw new CommandParseException("玩家 " + arg + "不存在或不在线!"); + } + return p; } } - public static class StringParse implements Parse { + public static class StringParse extends Parse { public StringParse() { allparses.put(String.class, this); } @Override public String parse(final String arg) { + if (min > arg.length() || arg.length() > max) { + throwRange("长度必须在 %s 和 %s 之间!"); + } return arg; } }