diff options
Diffstat (limited to 'dicore3/command/src/main/java/io/dico/dicore/command/parameter')
11 files changed, 1127 insertions, 1125 deletions
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java index aa69730..5646814 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java @@ -1,295 +1,295 @@ -package io.dico.dicore.command.parameter; - -import io.dico.dicore.command.CommandException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -/** - * Buffer for the arguments. - * Easy to traverse for the parser. - */ -public class ArgumentBuffer extends AbstractList<String> implements Iterator<String>, RandomAccess { - private String[] array; - private int cursor = 0; // index of the next return value - private transient ArgumentBuffer unaffectingCopy = null; // see #getUnaffectingCopy() - - public ArgumentBuffer(String label, String[] args) { - this(combine(label, args)); - } - - private static String[] combine(String label, String[] args) { - String[] result; - //if (args.length > 0 && "".equals(args[args.length - 1])) { - // // drop the last element of args if it is empty - // result = args; - //} else { - result = new String[args.length + 1]; - //} - System.arraycopy(args, 0, result, 1, result.length - 1); - result[0] = Objects.requireNonNull(label); - return result; - } - - /** - * Constructs a new ArgumentBuffer using the given array, without copying it first. - * None of the array its elements should be empty. - * - * @param array the array - * @throws NullPointerException if the array or any of its elements are null - */ - public ArgumentBuffer(String[] array) { - for (String elem : array) { - if (elem == null) throw new NullPointerException("ArgumentBuffer array element"); - } - this.array = array; - - } - - public int getCursor() { - return cursor; - } - - public @NotNull ArgumentBuffer setCursor(int cursor) { - if (cursor <= 0) { - cursor = 0; - } else if (size() <= cursor) { - cursor = size(); - } - this.cursor = cursor; - return this; - } - - @Override - public int size() { - return array.length; - } - - @Override - public @NotNull String get(int index) { - return array[index]; - } - - public int nextIndex() { - return cursor; - } - - public int previousIndex() { - return cursor - 1; - } - - public int remainingElements() { - return size() - nextIndex() - 1; - } - - @Override - public boolean hasNext() { - return nextIndex() < size(); - } - - public boolean hasPrevious() { - return 0 <= previousIndex(); - } - - /** - * Unlike conventional ListIterator implementations, this returns null if there is no next element - * - * @return the next value, or null - */ - @Override - public @Nullable String next() { - return hasNext() ? get(cursor++) : null; - } - - public @NotNull String requireNext(String parameterName) throws CommandException { - String next = next(); - if (next == null) { - throw CommandException.missingArgument(parameterName); - } - return next; - } - - // useful for completion code - public @NotNull String nextOrEmpty() { - return hasNext() ? get(cursor++) : ""; - } - - /** - * Unlike conventional ListIterator implementations, this returns null if there is no previous element - * - * @return the previous value, or null - */ - public @Nullable String previous() { - return hasPrevious() ? get(--cursor) : null; - } - - public @Nullable String peekNext() { - return hasNext() ? get(cursor) : null; - } - - public @Nullable String peekPrevious() { - return hasPrevious() ? get(cursor - 1) : null; - } - - public @NotNull ArgumentBuffer advance() { - return advance(1); - } - - public @NotNull ArgumentBuffer advance(int amount) { - cursor = Math.min(Math.max(0, cursor + amount), size()); - return this; - } - - public @NotNull ArgumentBuffer rewind() { - return rewind(1); - } - - public @NotNull ArgumentBuffer rewind(int amount) { - return advance(-amount); - } - - @NotNull String[] getArray() { - return array; - } - - public @NotNull String[] getArrayFromCursor() { - return getArrayFromIndex(cursor); - } - - public @NotNull String[] getArrayFromIndex(int index) { - return Arrays.copyOfRange(array, index, array.length); - } - - public @NotNull String getRawInput() { - return String.join(" ", array); - } - - public @NotNull String[] toArray() { - return array.clone(); - } - - @Override - public @NotNull Iterator<String> iterator() { - return this; - } - - @Override - public @NotNull ListIterator<String> listIterator() { - return new ListIterator<String>() { - @Override - public boolean hasNext() { - return ArgumentBuffer.this.hasNext(); - } - - @Override - public String next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - return ArgumentBuffer.this.next(); - } - - @Override - public boolean hasPrevious() { - return ArgumentBuffer.this.hasPrevious(); - } - - @Override - public String previous() { - if (!hasPrevious()) { - throw new NoSuchElementException(); - } - return ArgumentBuffer.this.previous(); - } - - @Override - public int nextIndex() { - return ArgumentBuffer.this.nextIndex(); - } - - @Override - public int previousIndex() { - return ArgumentBuffer.this.previousIndex(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void set(String s) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(String s) { - throw new UnsupportedOperationException(); - } - }; - } - - public void dropTrailingEmptyElements() { - int removeCount = 0; - String[] array = this.array; - for (int i = array.length - 1; i >= 0; i--) { - if ("".equals(array[i])) { - removeCount++; - } - } - - if (removeCount > 0) { - String[] newArray = new String[array.length - removeCount]; - System.arraycopy(array, 0, newArray, 0, newArray.length); - this.array = newArray; - - if (cursor > newArray.length) { - cursor = newArray.length; - } - } - } - - /** - * Preprocess this argument buffer with the given preprocessor - * - * @param preProcessor preprocessor - * @return a new ArgumentBuffer with processed contents. Might be this buffer if nothing changed. - */ - public @NotNull ArgumentBuffer preprocessArguments(IArgumentPreProcessor preProcessor) { - return preProcessor.process(this, -1); - } - - /** - * Allows a piece of code to traverse this buffer without modifying its cursor. - * After this method has been called for the first time on this instance, if this method - * or the {@link #clone()} method are called, the operation carried out on the prior result has finished. - * As such, the same instance might be returned again. - * - * @return A view of this buffer that doesn't affect this buffer's cursor. - */ - public ArgumentBuffer getUnaffectingCopy() { - // the copy doesn't alter the cursor of this ArgumentBuffer when moved, but traverses the same array reference. - // there is only ever one copy of an ArgumentBuffer, the cursor of which is updated on every call to this method. - - ArgumentBuffer unaffectingCopy = this.unaffectingCopy; - if (unaffectingCopy == null) { - this.unaffectingCopy = unaffectingCopy = new ArgumentBuffer(array); - } - unaffectingCopy.cursor = this.cursor; - return unaffectingCopy; - } - - @SuppressWarnings("MethodDoesntCallSuperMethod") - public @NotNull ArgumentBuffer clone() { - ArgumentBuffer result = getUnaffectingCopy(); - this.unaffectingCopy = null; - return result; - } - - @Override - public String toString() { - return String.format("ArgumentBuffer(size = %d, cursor = %d)", size(), getCursor()); - } - -} +package io.dico.dicore.command.parameter;
+
+import io.dico.dicore.command.CommandException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * Buffer for the arguments.
+ * Easy to traverse for the parser.
+ */
+public class ArgumentBuffer extends AbstractList<String> implements Iterator<String>, RandomAccess {
+ private String[] array;
+ private int cursor = 0; // index of the next return value
+ private transient ArgumentBuffer unaffectingCopy = null; // see #getUnaffectingCopy()
+
+ public ArgumentBuffer(String label, String[] args) {
+ this(combine(label, args));
+ }
+
+ private static String[] combine(String label, String[] args) {
+ String[] result;
+ //if (args.length > 0 && "".equals(args[args.length - 1])) {
+ // // drop the last element of args if it is empty
+ // result = args;
+ //} else {
+ result = new String[args.length + 1];
+ //}
+ System.arraycopy(args, 0, result, 1, result.length - 1);
+ result[0] = Objects.requireNonNull(label);
+ return result;
+ }
+
+ /**
+ * Constructs a new ArgumentBuffer using the given array, without copying it first.
+ * None of the array its elements should be empty.
+ *
+ * @param array the array
+ * @throws NullPointerException if the array or any of its elements are null
+ */
+ public ArgumentBuffer(String[] array) {
+ for (String elem : array) {
+ if (elem == null) throw new NullPointerException("ArgumentBuffer array element");
+ }
+ this.array = array;
+
+ }
+
+ public int getCursor() {
+ return cursor;
+ }
+
+ public @NotNull ArgumentBuffer setCursor(int cursor) {
+ if (cursor <= 0) {
+ cursor = 0;
+ } else if (size() <= cursor) {
+ cursor = size();
+ }
+ this.cursor = cursor;
+ return this;
+ }
+
+ @Override
+ public int size() {
+ return array.length;
+ }
+
+ @Override
+ public @NotNull String get(int index) {
+ return array[index];
+ }
+
+ public int nextIndex() {
+ return cursor;
+ }
+
+ public int previousIndex() {
+ return cursor - 1;
+ }
+
+ public int remainingElements() {
+ return size() - nextIndex() - 1;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return nextIndex() < size();
+ }
+
+ public boolean hasPrevious() {
+ return 0 <= previousIndex();
+ }
+
+ /**
+ * Unlike conventional ListIterator implementations, this returns null if there is no next element
+ *
+ * @return the next value, or null
+ */
+ @Override
+ public @Nullable String next() {
+ return hasNext() ? get(cursor++) : null;
+ }
+
+ public @NotNull String requireNext(String parameterName) throws CommandException {
+ String next = next();
+ if (next == null) {
+ throw CommandException.missingArgument(parameterName);
+ }
+ return next;
+ }
+
+ // useful for completion code
+ public @NotNull String nextOrEmpty() {
+ return hasNext() ? get(cursor++) : "";
+ }
+
+ /**
+ * Unlike conventional ListIterator implementations, this returns null if there is no previous element
+ *
+ * @return the previous value, or null
+ */
+ public @Nullable String previous() {
+ return hasPrevious() ? get(--cursor) : null;
+ }
+
+ public @Nullable String peekNext() {
+ return hasNext() ? get(cursor) : null;
+ }
+
+ public @Nullable String peekPrevious() {
+ return hasPrevious() ? get(cursor - 1) : null;
+ }
+
+ public @NotNull ArgumentBuffer advance() {
+ return advance(1);
+ }
+
+ public @NotNull ArgumentBuffer advance(int amount) {
+ cursor = Math.min(Math.max(0, cursor + amount), size());
+ return this;
+ }
+
+ public @NotNull ArgumentBuffer rewind() {
+ return rewind(1);
+ }
+
+ public @NotNull ArgumentBuffer rewind(int amount) {
+ return advance(-amount);
+ }
+
+ @NotNull String[] getArray() {
+ return array;
+ }
+
+ public @NotNull String[] getArrayFromCursor() {
+ return getArrayFromIndex(cursor);
+ }
+
+ public @NotNull String[] getArrayFromIndex(int index) {
+ return Arrays.copyOfRange(array, index, array.length);
+ }
+
+ public @NotNull String getRawInput() {
+ return String.join(" ", array);
+ }
+
+ public @NotNull String[] toArray() {
+ return array.clone();
+ }
+
+ @Override
+ public @NotNull Iterator<String> iterator() {
+ return this;
+ }
+
+ @Override
+ public @NotNull ListIterator<String> listIterator() {
+ return new ListIterator<String>() {
+ @Override
+ public boolean hasNext() {
+ return ArgumentBuffer.this.hasNext();
+ }
+
+ @Override
+ public String next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return ArgumentBuffer.this.next();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return ArgumentBuffer.this.hasPrevious();
+ }
+
+ @Override
+ public String previous() {
+ if (!hasPrevious()) {
+ throw new NoSuchElementException();
+ }
+ return ArgumentBuffer.this.previous();
+ }
+
+ @Override
+ public int nextIndex() {
+ return ArgumentBuffer.this.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return ArgumentBuffer.this.previousIndex();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void set(String s) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void add(String s) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ public void dropTrailingEmptyElements() {
+ int removeCount = 0;
+ String[] array = this.array;
+ for (int i = array.length - 1; i >= 0; i--) {
+ if ("".equals(array[i])) {
+ removeCount++;
+ }
+ }
+
+ if (removeCount > 0) {
+ String[] newArray = new String[array.length - removeCount];
+ System.arraycopy(array, 0, newArray, 0, newArray.length);
+ this.array = newArray;
+
+ if (cursor > newArray.length) {
+ cursor = newArray.length;
+ }
+ }
+ }
+
+ /**
+ * Preprocess this argument buffer with the given preprocessor
+ *
+ * @param preProcessor preprocessor
+ * @return a new ArgumentBuffer with processed contents. Might be this buffer if nothing changed.
+ */
+ public @NotNull ArgumentBuffer preprocessArguments(IArgumentPreProcessor preProcessor) {
+ return preProcessor.process(this, -1);
+ }
+
+ /**
+ * Allows a piece of code to traverse this buffer without modifying its cursor.
+ * After this method has been called for the first time on this instance, if this method
+ * or the {@link #clone()} method are called, the operation carried out on the prior result has finished.
+ * As such, the same instance might be returned again.
+ *
+ * @return A view of this buffer that doesn't affect this buffer's cursor.
+ */
+ public ArgumentBuffer getUnaffectingCopy() {
+ // the copy doesn't alter the cursor of this ArgumentBuffer when moved, but traverses the same array reference.
+ // there is only ever one copy of an ArgumentBuffer, the cursor of which is updated on every call to this method.
+
+ ArgumentBuffer unaffectingCopy = this.unaffectingCopy;
+ if (unaffectingCopy == null) {
+ this.unaffectingCopy = unaffectingCopy = new ArgumentBuffer(array);
+ }
+ unaffectingCopy.cursor = this.cursor;
+ return unaffectingCopy;
+ }
+
+ @SuppressWarnings("MethodDoesntCallSuperMethod")
+ public @NotNull ArgumentBuffer clone() {
+ ArgumentBuffer result = getUnaffectingCopy();
+ this.unaffectingCopy = null;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ArgumentBuffer(size = %d, cursor = %d)", size(), getCursor());
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java index ce818b7..a9ccd20 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java @@ -1,177 +1,177 @@ -package io.dico.dicore.command.parameter; - -public class ArgumentMergingPreProcessor implements IArgumentPreProcessor { - private final String tokens; - private final char escapeChar; - - public ArgumentMergingPreProcessor(String tokens, char escapeChar) { - if ((tokens.length() & 1) != 0 || tokens.isEmpty()) throw new IllegalArgumentException(); - this.tokens = tokens; - this.escapeChar = escapeChar; - } - - @Override - public ArgumentBuffer process(ArgumentBuffer buffer, int count) { - Parser parser = new Parser(buffer.getArray().clone(), buffer.getCursor(), count); - String[] array = parser.doProcess(); - ArgumentBuffer result = new ArgumentBuffer(array); - parser.updateBuffer(result); - return result; - } - - private class Parser { - private final String[] args; - private final int start; - private final int count; - - private int foundSectionCount; - private int currentIndex; - private int sectionStart; - private char closingToken; - private int sectionEnd; - private int removeCount; - - Parser(String[] args, int start, int count) { - this.start = start; - this.args = args; - this.count = count; - } - - private void reset() { - foundSectionCount = 0; - currentIndex = start; - sectionStart = -1; - closingToken = 0; - sectionEnd = -1; - removeCount = 0; - } - - private boolean findNextSectionStart() { - if (count >= 0 && foundSectionCount >= count) return false; - - while (currentIndex < args.length) { - String arg = args[currentIndex]; - if (arg == null) { - throw new IllegalArgumentException(); - } - - if (arg.isEmpty()) { - ++currentIndex; - continue; - } - - int openingTokenIndex = tokens.indexOf(arg.charAt(0)); - if (openingTokenIndex == -1 || (openingTokenIndex & 1) != 0) { - ++currentIndex; - continue; - } - - // found - closingToken = tokens.charAt(openingTokenIndex | 1); - sectionStart = currentIndex; - return true; - } - - return false; - } - - private boolean findNextSectionEnd() { - while (currentIndex < args.length) { - String arg = args[currentIndex]; - if (arg == null) { - throw new IllegalArgumentException(); - } - - if (arg.isEmpty() - || arg.charAt(arg.length() - 1) != closingToken - || (sectionStart == currentIndex && arg.length() == 1)) { - ++currentIndex; - continue; - } - - if (escapeChar != 0 - && arg.length() > 1 - && arg.charAt(arg.length() - 2) == escapeChar) { - // escaped - ++currentIndex; - continue; - } - - // found - closingToken = 0; - sectionEnd = currentIndex; - ++currentIndex; - return true; - } - - return false; - } - - private void processFoundSection() { - if (sectionStart == sectionEnd) { - String arg = args[sectionStart]; - args[sectionStart] = arg.substring(1, arg.length() - 1); - return; - } - - removeCount += sectionEnd - sectionStart; - - StringBuilder sb = new StringBuilder(); - sb.append(args[sectionStart].substring(1)); - - for (int i = sectionStart + 1; i < sectionEnd; i++) { - sb.append(' '); - sb.append(args[i]); - args[i] = null; - } - sb.append(' '); - sb.append(args[sectionEnd].substring(0, args[sectionEnd].length() - 1)); - args[sectionEnd] = null; - - args[sectionStart] = sb.toString(); - - sectionStart = -1; - sectionEnd = -1; - - ++foundSectionCount; - } - - String[] doProcess() { - reset(); - - while (findNextSectionStart()) { - if (findNextSectionEnd()) { - processFoundSection(); - } else { - currentIndex = sectionStart + 1; - } - } - - if (removeCount == 0) { - return args; - } - - String[] result = new String[args.length - removeCount]; - int i = 0; - for (String arg : args) { - if (arg != null) { - result[i++] = arg; - } - } - - return result; - } - - void updateBuffer(ArgumentBuffer buffer) { - if (count < 0) { - buffer.setCursor(start); - } else { - buffer.setCursor(currentIndex); - } - } - - } - -} - - +package io.dico.dicore.command.parameter;
+
+public class ArgumentMergingPreProcessor implements IArgumentPreProcessor {
+ private final String tokens;
+ private final char escapeChar;
+
+ public ArgumentMergingPreProcessor(String tokens, char escapeChar) {
+ if ((tokens.length() & 1) != 0 || tokens.isEmpty()) throw new IllegalArgumentException();
+ this.tokens = tokens;
+ this.escapeChar = escapeChar;
+ }
+
+ @Override
+ public ArgumentBuffer process(ArgumentBuffer buffer, int count) {
+ Parser parser = new Parser(buffer.getArray().clone(), buffer.getCursor(), count);
+ String[] array = parser.doProcess();
+ ArgumentBuffer result = new ArgumentBuffer(array);
+ parser.updateBuffer(result);
+ return result;
+ }
+
+ private class Parser {
+ private final String[] args;
+ private final int start;
+ private final int count;
+
+ private int foundSectionCount;
+ private int currentIndex;
+ private int sectionStart;
+ private char closingToken;
+ private int sectionEnd;
+ private int removeCount;
+
+ Parser(String[] args, int start, int count) {
+ this.start = start;
+ this.args = args;
+ this.count = count;
+ }
+
+ private void reset() {
+ foundSectionCount = 0;
+ currentIndex = start;
+ sectionStart = -1;
+ closingToken = 0;
+ sectionEnd = -1;
+ removeCount = 0;
+ }
+
+ private boolean findNextSectionStart() {
+ if (count >= 0 && foundSectionCount >= count) return false;
+
+ while (currentIndex < args.length) {
+ String arg = args[currentIndex];
+ if (arg == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (arg.isEmpty()) {
+ ++currentIndex;
+ continue;
+ }
+
+ int openingTokenIndex = tokens.indexOf(arg.charAt(0));
+ if (openingTokenIndex == -1 || (openingTokenIndex & 1) != 0) {
+ ++currentIndex;
+ continue;
+ }
+
+ // found
+ closingToken = tokens.charAt(openingTokenIndex | 1);
+ sectionStart = currentIndex;
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean findNextSectionEnd() {
+ while (currentIndex < args.length) {
+ String arg = args[currentIndex];
+ if (arg == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (arg.isEmpty()
+ || arg.charAt(arg.length() - 1) != closingToken
+ || (sectionStart == currentIndex && arg.length() == 1)) {
+ ++currentIndex;
+ continue;
+ }
+
+ if (escapeChar != 0
+ && arg.length() > 1
+ && arg.charAt(arg.length() - 2) == escapeChar) {
+ // escaped
+ ++currentIndex;
+ continue;
+ }
+
+ // found
+ closingToken = 0;
+ sectionEnd = currentIndex;
+ ++currentIndex;
+ return true;
+ }
+
+ return false;
+ }
+
+ private void processFoundSection() {
+ if (sectionStart == sectionEnd) {
+ String arg = args[sectionStart];
+ args[sectionStart] = arg.substring(1, arg.length() - 1);
+ return;
+ }
+
+ removeCount += sectionEnd - sectionStart;
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(args[sectionStart].substring(1));
+
+ for (int i = sectionStart + 1; i < sectionEnd; i++) {
+ sb.append(' ');
+ sb.append(args[i]);
+ args[i] = null;
+ }
+ sb.append(' ');
+ sb.append(args[sectionEnd].substring(0, args[sectionEnd].length() - 1));
+ args[sectionEnd] = null;
+
+ args[sectionStart] = sb.toString();
+
+ sectionStart = -1;
+ sectionEnd = -1;
+
+ ++foundSectionCount;
+ }
+
+ String[] doProcess() {
+ reset();
+
+ while (findNextSectionStart()) {
+ if (findNextSectionEnd()) {
+ processFoundSection();
+ } else {
+ currentIndex = sectionStart + 1;
+ }
+ }
+
+ if (removeCount == 0) {
+ return args;
+ }
+
+ String[] result = new String[args.length - removeCount];
+ int i = 0;
+ for (String arg : args) {
+ if (arg != null) {
+ result[i++] = arg;
+ }
+ }
+
+ return result;
+ }
+
+ void updateBuffer(ArgumentBuffer buffer) {
+ if (count < 0) {
+ buffer.setCursor(start);
+ } else {
+ buffer.setCursor(currentIndex);
+ }
+ }
+
+ }
+
+}
+
+
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java index a5afce5..7418c4a 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java @@ -89,6 +89,8 @@ public class ContextParser { m_curRepeatingList = null; assignDefaultValuesToUncomputedParams(); arrayifyRepeatedParamValue(); + + m_done = true; } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java index 0b8198e..5495cce 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java @@ -1,41 +1,41 @@ -package io.dico.dicore.command.parameter; - -/** - * An interface to process tokens such as quotes - */ -@Deprecated -public interface IArgumentPreProcessor { - - /** - * Preprocess the arguments contained within the given ArgumentBuffer. - * If no changes are made, this might return the same buffer. - * Any arguments preceding {@code buffer.getCursor()} will not be affected. - * - * <p> - * If {@code count} is non-negative, it declares a limit on the number of arguments after preprocessing. - * In that case, the buffer's cursor is set to the index of the first argument following processed arguments. - * </p> - * - * @param buffer the argument buffer - * @param count the maximum number of (processed) arguments - * @return the arguments after preprocessing - */ - ArgumentBuffer process(ArgumentBuffer buffer, int count); - - IArgumentPreProcessor NONE = (buffer, count) -> buffer; - - /** - * Get an IArgumentPreProcessor that merges arguments between any two tokens - * - * @param tokens The tokens that the merged arguments should be enclosed by, in subsequent pairs. - * Example: []{}"" - * This would mean the following would be merged: [ hello this is a merged argument] - * @param escapeChar the char that can be used to escape the given tokens - * @return The IArgumentPreProcessor - */ - static IArgumentPreProcessor mergeOnTokens(String tokens, char escapeChar) { - return new ArgumentMergingPreProcessor(tokens, escapeChar); - } - -} - +package io.dico.dicore.command.parameter;
+
+/**
+ * An interface to process tokens such as quotes
+ */
+@Deprecated
+public interface IArgumentPreProcessor {
+
+ /**
+ * Preprocess the arguments contained within the given ArgumentBuffer.
+ * If no changes are made, this might return the same buffer.
+ * Any arguments preceding {@code buffer.getCursor()} will not be affected.
+ *
+ * <p>
+ * If {@code count} is non-negative, it declares a limit on the number of arguments after preprocessing.
+ * In that case, the buffer's cursor is set to the index of the first argument following processed arguments.
+ * </p>
+ *
+ * @param buffer the argument buffer
+ * @param count the maximum number of (processed) arguments
+ * @return the arguments after preprocessing
+ */
+ ArgumentBuffer process(ArgumentBuffer buffer, int count);
+
+ IArgumentPreProcessor NONE = (buffer, count) -> buffer;
+
+ /**
+ * Get an IArgumentPreProcessor that merges arguments between any two tokens
+ *
+ * @param tokens The tokens that the merged arguments should be enclosed by, in subsequent pairs.
+ * Example: []{}""
+ * This would mean the following would be merged: [ hello this is a merged argument]
+ * @param escapeChar the char that can be used to escape the given tokens
+ * @return The IArgumentPreProcessor
+ */
+ static IArgumentPreProcessor mergeOnTokens(String tokens, char escapeChar) {
+ return new ArgumentMergingPreProcessor(tokens, escapeChar);
+ }
+
+}
+
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java index 613d057..f35628c 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java @@ -1,148 +1,148 @@ -package io.dico.dicore.command.parameter; - -import java.util.*; - -/** - * IParameter definition for a command - */ -@SuppressWarnings("UnusedReturnValue") -public class ParameterList { - //private ParameterList parent; - private List<Parameter<?, ?>> indexedParameters; - private Map<String, Parameter<?, ?>> byName; - //private IArgumentPreProcessor argumentPreProcessor = IArgumentPreProcessor.NONE; - private int requiredCount = -1; - private boolean repeatFinalParameter; - - // if the final parameter is repeated and the command is implemented through reflection, - // the repeated parameter is simply the last parameter of the method, rather than the last - // indexed parameter. This might be a flag. As such, this field exists to ensure the correct - // parameter is taken for repeating - private boolean finalParameterMayBeFlag; - - /* - public ParameterList(ParameterList parent) { - this(); - if (parent.repeatFinalParameter) { - throw new IllegalArgumentException("Parent may not have repeating parameters"); - } - this.parent = parent; - }*/ - - public ParameterList() { - this.indexedParameters = new ArrayList<>(); - this.byName = new LinkedHashMap<>(); - this.repeatFinalParameter = false; - } - - /* - public IArgumentPreProcessor getArgumentPreProcessor() { - return argumentPreProcessor; - } - - public ParameterList setArgumentPreProcessor(IArgumentPreProcessor argumentPreProcessor) { - this.argumentPreProcessor = argumentPreProcessor == null ? IArgumentPreProcessor.NONE : argumentPreProcessor; - return this; - }*/ - - public boolean repeatFinalParameter() { - return repeatFinalParameter; - } - - public ParameterList setRepeatFinalParameter(boolean repeatFinalParameter) { - this.repeatFinalParameter = repeatFinalParameter; - return this; - } - - public boolean finalParameterMayBeFlag() { - return finalParameterMayBeFlag; - } - - public ParameterList setFinalParameterMayBeFlag(boolean finalParameterMayBeFlag) { - this.finalParameterMayBeFlag = finalParameterMayBeFlag; - return this; - } - - public int getRequiredCount() { - return requiredCount == -1 ? indexedParameters.size() : requiredCount; - } - - public ParameterList setRequiredCount(int requiredCount) { - this.requiredCount = requiredCount; - return this; - } - - public boolean hasAnyParameters() { - return !byName.isEmpty(); - } - - public int getIndexedParameterCount() { - return indexedParameters.size(); - } - - public List<Parameter<?, ?>> getIndexedParameters() { - return Collections.unmodifiableList(indexedParameters); - } - - public Parameter<?, ?> getParameterByName(String name) { - return byName.get(name); - } - - public String getIndexedParameterName(int index) { - return indexedParameters.get(index).getName(); - } - - public Map<String, Parameter<?, ?>> getParametersByName() { - return Collections.unmodifiableMap(byName); - } - - /** - * Add the given parameter to the end of this parameter list - * Can be a flag - * - * @param parameter the parameter - * @return this - */ - public ParameterList addParameter(Parameter<?, ?> parameter) { - return addParameter(-1, parameter); - } - - /** - * Add the given parameter to this parameter list - * If the parameter is a flag, the index is ignored - * - * @param index parameter index number, -1 if end - * @param parameter the parameter - * @return this - * @throws NullPointerException if parameter is null - */ - public ParameterList addParameter(int index, Parameter<?, ?> parameter) { - //System.out.println("Added parameter " + parameter.getName() + ", flag: " + parameter.isFlag()); - byName.put(parameter.getName(), parameter); - if (!parameter.isFlag()) { - indexedParameters.add(index == -1 ? indexedParameters.size() : index, parameter); - } - return this; - } - - public Parameter<?, ?> getRepeatedParameter() { - if (!repeatFinalParameter) { - return null; - } - if (finalParameterMayBeFlag) { - Iterator<Parameter<?, ?>> iterator = byName.values().iterator(); - Parameter<?, ?> result = null; - while (iterator.hasNext()) { - result = iterator.next(); - } - return result; - } - - if (indexedParameters.isEmpty()) { - return null; - } - - return indexedParameters.get(indexedParameters.size() - 1); - } - -} +package io.dico.dicore.command.parameter;
+
+import java.util.*;
+
+/**
+ * IParameter definition for a command
+ */
+@SuppressWarnings("UnusedReturnValue")
+public class ParameterList {
+ //private ParameterList parent;
+ private List<Parameter<?, ?>> indexedParameters;
+ private Map<String, Parameter<?, ?>> byName;
+ //private IArgumentPreProcessor argumentPreProcessor = IArgumentPreProcessor.NONE;
+ private int requiredCount = -1;
+ private boolean repeatFinalParameter;
+
+ // if the final parameter is repeated and the command is implemented through reflection,
+ // the repeated parameter is simply the last parameter of the method, rather than the last
+ // indexed parameter. This might be a flag. As such, this field exists to ensure the correct
+ // parameter is taken for repeating
+ private boolean finalParameterMayBeFlag;
+
+ /*
+ public ParameterList(ParameterList parent) {
+ this();
+ if (parent.repeatFinalParameter) {
+ throw new IllegalArgumentException("Parent may not have repeating parameters");
+ }
+ this.parent = parent;
+ }*/
+
+ public ParameterList() {
+ this.indexedParameters = new ArrayList<>();
+ this.byName = new LinkedHashMap<>();
+ this.repeatFinalParameter = false;
+ }
+
+ /*
+ public IArgumentPreProcessor getArgumentPreProcessor() {
+ return argumentPreProcessor;
+ }
+
+ public ParameterList setArgumentPreProcessor(IArgumentPreProcessor argumentPreProcessor) {
+ this.argumentPreProcessor = argumentPreProcessor == null ? IArgumentPreProcessor.NONE : argumentPreProcessor;
+ return this;
+ }*/
+
+ public boolean repeatFinalParameter() {
+ return repeatFinalParameter;
+ }
+
+ public ParameterList setRepeatFinalParameter(boolean repeatFinalParameter) {
+ this.repeatFinalParameter = repeatFinalParameter;
+ return this;
+ }
+
+ public boolean finalParameterMayBeFlag() {
+ return finalParameterMayBeFlag;
+ }
+
+ public ParameterList setFinalParameterMayBeFlag(boolean finalParameterMayBeFlag) {
+ this.finalParameterMayBeFlag = finalParameterMayBeFlag;
+ return this;
+ }
+
+ public int getRequiredCount() {
+ return requiredCount == -1 ? indexedParameters.size() : requiredCount;
+ }
+
+ public ParameterList setRequiredCount(int requiredCount) {
+ this.requiredCount = requiredCount;
+ return this;
+ }
+
+ public boolean hasAnyParameters() {
+ return !byName.isEmpty();
+ }
+
+ public int getIndexedParameterCount() {
+ return indexedParameters.size();
+ }
+
+ public List<Parameter<?, ?>> getIndexedParameters() {
+ return Collections.unmodifiableList(indexedParameters);
+ }
+
+ public Parameter<?, ?> getParameterByName(String name) {
+ return byName.get(name);
+ }
+
+ public String getIndexedParameterName(int index) {
+ return indexedParameters.get(index).getName();
+ }
+
+ public Map<String, Parameter<?, ?>> getParametersByName() {
+ return Collections.unmodifiableMap(byName);
+ }
+
+ /**
+ * Add the given parameter to the end of this parameter list
+ * Can be a flag
+ *
+ * @param parameter the parameter
+ * @return this
+ */
+ public ParameterList addParameter(Parameter<?, ?> parameter) {
+ return addParameter(-1, parameter);
+ }
+
+ /**
+ * Add the given parameter to this parameter list
+ * If the parameter is a flag, the index is ignored
+ *
+ * @param index parameter index number, -1 if end
+ * @param parameter the parameter
+ * @return this
+ * @throws NullPointerException if parameter is null
+ */
+ public ParameterList addParameter(int index, Parameter<?, ?> parameter) {
+ //System.out.println("Added parameter " + parameter.getName() + ", flag: " + parameter.isFlag());
+ byName.put(parameter.getName(), parameter);
+ if (!parameter.isFlag()) {
+ indexedParameters.add(index == -1 ? indexedParameters.size() : index, parameter);
+ }
+ return this;
+ }
+
+ public Parameter<?, ?> getRepeatedParameter() {
+ if (!repeatFinalParameter) {
+ return null;
+ }
+ if (finalParameterMayBeFlag) {
+ Iterator<Parameter<?, ?>> iterator = byName.values().iterator();
+ Parameter<?, ?> result = null;
+ while (iterator.hasNext()) {
+ result = iterator.next();
+ }
+ return result;
+ }
+
+ if (indexedParameters.isEmpty()) {
+ return null;
+ }
+
+ return indexedParameters.get(indexedParameters.size() - 1);
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java index c23e09b..063d381 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java @@ -1,46 +1,46 @@ -package io.dico.dicore.command.parameter.type; - -import io.dico.dicore.command.CommandException; -import io.dico.dicore.command.parameter.ArgumentBuffer; -import io.dico.dicore.command.parameter.Parameter; -import org.bukkit.Location; -import org.bukkit.command.CommandSender; - -import java.util.ArrayList; -import java.util.List; - -public class EnumParameterType<E extends Enum> extends SimpleParameterType<E, Void> { - private final E[] universe; - - public EnumParameterType(Class<E> returnType) { - super(returnType); - universe = returnType.getEnumConstants(); - if (universe == null) { - throw new IllegalArgumentException("returnType must be an enum"); - } - } - - @Override - protected E parse(Parameter<E, Void> parameter, CommandSender sender, String input) throws CommandException { - for (E constant : universe) { - if (constant.name().equalsIgnoreCase(input)) { - return constant; - } - } - - throw CommandException.invalidArgument(parameter.getName(), "the enum value does not exist"); - } - - @Override - public List<String> complete(Parameter<E, Void> parameter, CommandSender sender, Location location, ArgumentBuffer buffer) { - String input = buffer.next().toUpperCase(); - List<String> result = new ArrayList<>(); - for (E constant : universe) { - if (constant.name().toUpperCase().startsWith(input.toUpperCase())) { - result.add(constant.name().toLowerCase()); - } - } - return result; - } - -} +package io.dico.dicore.command.parameter.type;
+
+import io.dico.dicore.command.CommandException;
+import io.dico.dicore.command.parameter.ArgumentBuffer;
+import io.dico.dicore.command.parameter.Parameter;
+import org.bukkit.Location;
+import org.bukkit.command.CommandSender;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EnumParameterType<E extends Enum> extends SimpleParameterType<E, Void> {
+ private final E[] universe;
+
+ public EnumParameterType(Class<E> returnType) {
+ super(returnType);
+ universe = returnType.getEnumConstants();
+ if (universe == null) {
+ throw new IllegalArgumentException("returnType must be an enum");
+ }
+ }
+
+ @Override
+ protected E parse(Parameter<E, Void> parameter, CommandSender sender, String input) throws CommandException {
+ for (E constant : universe) {
+ if (constant.name().equalsIgnoreCase(input)) {
+ return constant;
+ }
+ }
+
+ throw CommandException.invalidArgument(parameter.getName(), "the enum value does not exist");
+ }
+
+ @Override
+ public List<String> complete(Parameter<E, Void> parameter, CommandSender sender, Location location, ArgumentBuffer buffer) {
+ String input = buffer.next().toUpperCase();
+ List<String> result = new ArrayList<>();
+ for (E constant : universe) {
+ if (constant.name().toUpperCase().startsWith(input.toUpperCase())) {
+ result.add(constant.name().toLowerCase());
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/IParameterTypeSelector.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/IParameterTypeSelector.java index 780ea0d..381b15c 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/IParameterTypeSelector.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/IParameterTypeSelector.java @@ -1,44 +1,44 @@ -package io.dico.dicore.command.parameter.type; - -import java.lang.annotation.Annotation; - -/** - * An interface for an object that stores parameter types by {@link ParameterKey} and finds appropriate types for {@link ParameterKey parameterKeys} - */ -public interface IParameterTypeSelector { - - <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(ParameterKey key); - - //<TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(ParameterKey key); - - <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(ParameterKey key); - - - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(Class<?> returnType) { - return selectExact(returnType, null); - } - - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(Class<?> returnType, Class<? extends Annotation> annotationClass) { - return selectExact(new ParameterKey(returnType, annotationClass)); - } - - /* - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(Class<?> returnType) { - return selectExactOrSubclass(returnType, null); - } - - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(Class<?> returnType, Class<? extends Annotation> annotationClass) { - return selectExactOrSubclass(new ParameterKey(returnType, annotationClass)); - } - */ - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(Class<?> returnType) { - return selectAny(returnType, null); - } - - default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(Class<?> returnType, Class<? extends Annotation> annotationClass) { - return selectAny(new ParameterKey(returnType, annotationClass)); - } - - void addType(boolean infolessAlias, ParameterType<?, ?> type); - -} +package io.dico.dicore.command.parameter.type;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * An interface for an object that stores parameter types by {@link ParameterKey} and finds appropriate types for {@link ParameterKey parameterKeys}
+ */
+public interface IParameterTypeSelector {
+
+ <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(ParameterKey key);
+
+ //<TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(ParameterKey key);
+
+ <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(ParameterKey key);
+
+
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(Class<?> returnType) {
+ return selectExact(returnType, null);
+ }
+
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(Class<?> returnType, Class<? extends Annotation> annotationClass) {
+ return selectExact(new ParameterKey(returnType, annotationClass));
+ }
+
+ /*
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(Class<?> returnType) {
+ return selectExactOrSubclass(returnType, null);
+ }
+
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExactOrSubclass(Class<?> returnType, Class<? extends Annotation> annotationClass) {
+ return selectExactOrSubclass(new ParameterKey(returnType, annotationClass));
+ }
+ */
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(Class<?> returnType) {
+ return selectAny(returnType, null);
+ }
+
+ default <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(Class<?> returnType, Class<? extends Annotation> annotationClass) {
+ return selectAny(new ParameterKey(returnType, annotationClass));
+ }
+
+ void addType(boolean infolessAlias, ParameterType<?, ?> type);
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java index d407f87..ef86eab 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/MapBasedParameterTypeSelector.java @@ -1,114 +1,114 @@ -package io.dico.dicore.command.parameter.type; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.Map; - -/** - * Map based implementation of {@link IParameterTypeSelector} - */ -public class MapBasedParameterTypeSelector implements IParameterTypeSelector { - static final MapBasedParameterTypeSelector defaultSelector = new MapBasedParameterTypeSelector(false); - private final Map<ParameterKey, ParameterType<?, ?>> parameterTypeMap; - private final boolean useDefault; - - public MapBasedParameterTypeSelector(boolean useDefault) { - this.parameterTypeMap = new HashMap<>(); - this.useDefault = useDefault; - } - - @Override - public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(ParameterKey key) { - ParameterType<?, ?> out = parameterTypeMap.get(key); - if (useDefault && out == null) { - out = defaultSelector.selectExact(key); - } - if (out == null && key.getReturnType().isEnum()) { - //noinspection unchecked - out = new EnumParameterType(key.getReturnType()); - addType(false, out); - } - return cast(out); - } - - @Override - public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(ParameterKey key) { - ParameterType<TReturn, TParamInfo> exact = selectExact(key); - if (exact != null) { - return exact; - } - - if (key.getAnnotationClass() != null) { - exact = selectExact(new ParameterKey(key.getReturnType())); - if (exact != null) { - return exact; - } - } - - Class<?> returnType = key.getReturnType(); - Class<? extends Annotation> annotationClass = key.getAnnotationClass(); - - ParameterType<?, ?> out = selectByReturnType(parameterTypeMap, returnType, annotationClass, false); - if (out == null && useDefault) { - out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, false); - } - if (out == null) { - out = selectByReturnType(parameterTypeMap, returnType, annotationClass, true); - } - if (out == null && useDefault) { - out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, true); - } - return cast(out); - } - - private static ParameterType<?, ?> selectByReturnType(Map<ParameterKey, ParameterType<?, ?>> map, Class<?> returnType, - Class<? extends Annotation> annotationClass, boolean allowSubclass) { - ParameterType<?, ?> out = null; - if (allowSubclass) { - for (ParameterType<?, ?> type : map.values()) { - if (returnType.isAssignableFrom(type.getReturnType())) { - if (annotationClass == type.getAnnotationClass()) { - out = type; - break; - } - if (out == null) { - out = type; - } - } - } - } else { - for (ParameterType<?, ?> type : map.values()) { - if (returnType == type.getReturnType()) { - if (annotationClass == type.getAnnotationClass()) { - out = type; - break; - } - if (out == null) { - out = type; - } - } - } - } - return out; - } - - private static <T> T cast(Object o) { - //noinspection unchecked - return (T) o; - } - - @Override - public void addType(boolean infolessAlias, ParameterType<?, ?> type) { - parameterTypeMap.put(type.getTypeKey(), type); - - if (infolessAlias) { - parameterTypeMap.putIfAbsent(type.getInfolessTypeKey(), type); - } - } - - static { - // registers default parameter types - ParameterTypes.clinit(); - } - -} +package io.dico.dicore.command.parameter.type;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Map based implementation of {@link IParameterTypeSelector}
+ */
+public class MapBasedParameterTypeSelector implements IParameterTypeSelector {
+ static final MapBasedParameterTypeSelector defaultSelector = new MapBasedParameterTypeSelector(false);
+ private final Map<ParameterKey, ParameterType<?, ?>> parameterTypeMap;
+ private final boolean useDefault;
+
+ public MapBasedParameterTypeSelector(boolean useDefault) {
+ this.parameterTypeMap = new HashMap<>();
+ this.useDefault = useDefault;
+ }
+
+ @Override
+ public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectExact(ParameterKey key) {
+ ParameterType<?, ?> out = parameterTypeMap.get(key);
+ if (useDefault && out == null) {
+ out = defaultSelector.selectExact(key);
+ }
+ if (out == null && key.getReturnType().isEnum()) {
+ //noinspection unchecked
+ out = new EnumParameterType(key.getReturnType());
+ addType(false, out);
+ }
+ return cast(out);
+ }
+
+ @Override
+ public <TReturn, TParamInfo> ParameterType<TReturn, TParamInfo> selectAny(ParameterKey key) {
+ ParameterType<TReturn, TParamInfo> exact = selectExact(key);
+ if (exact != null) {
+ return exact;
+ }
+
+ if (key.getAnnotationClass() != null) {
+ exact = selectExact(new ParameterKey(key.getReturnType()));
+ if (exact != null) {
+ return exact;
+ }
+ }
+
+ Class<?> returnType = key.getReturnType();
+ Class<? extends Annotation> annotationClass = key.getAnnotationClass();
+
+ ParameterType<?, ?> out = selectByReturnType(parameterTypeMap, returnType, annotationClass, false);
+ if (out == null && useDefault) {
+ out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, false);
+ }
+ if (out == null) {
+ out = selectByReturnType(parameterTypeMap, returnType, annotationClass, true);
+ }
+ if (out == null && useDefault) {
+ out = selectByReturnType(defaultSelector.parameterTypeMap, returnType, annotationClass, true);
+ }
+ return cast(out);
+ }
+
+ private static ParameterType<?, ?> selectByReturnType(Map<ParameterKey, ParameterType<?, ?>> map, Class<?> returnType,
+ Class<? extends Annotation> annotationClass, boolean allowSubclass) {
+ ParameterType<?, ?> out = null;
+ if (allowSubclass) {
+ for (ParameterType<?, ?> type : map.values()) {
+ if (returnType.isAssignableFrom(type.getReturnType())) {
+ if (annotationClass == type.getAnnotationClass()) {
+ out = type;
+ break;
+ }
+ if (out == null) {
+ out = type;
+ }
+ }
+ }
+ } else {
+ for (ParameterType<?, ?> type : map.values()) {
+ if (returnType == type.getReturnType()) {
+ if (annotationClass == type.getAnnotationClass()) {
+ out = type;
+ break;
+ }
+ if (out == null) {
+ out = type;
+ }
+ }
+ }
+ }
+ return out;
+ }
+
+ private static <T> T cast(Object o) {
+ //noinspection unchecked
+ return (T) o;
+ }
+
+ @Override
+ public void addType(boolean infolessAlias, ParameterType<?, ?> type) {
+ parameterTypeMap.put(type.getTypeKey(), type);
+
+ if (infolessAlias) {
+ parameterTypeMap.putIfAbsent(type.getInfolessTypeKey(), type);
+ }
+ }
+
+ static {
+ // registers default parameter types
+ ParameterTypes.clinit();
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterConfig.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterConfig.java index dbd7590..d33932b 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterConfig.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterConfig.java @@ -1,80 +1,80 @@ -package io.dico.dicore.command.parameter.type; - -import io.dico.dicore.Reflection; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; - -/** - * This class serves the purpose of having annotated parameter configurations (such as ranges for number parameters). - * Such configurations must be possible to obtain without using annotations, and as such, there should be a class conveying the information - * that is separate from the annotation itself. This class acts as a bridge from the annotation to said class conveying the information. - * - * @param <TAnnotation> the annotation type for parameters - * @param <TParamInfo> the object type that holds the information required in memory - */ -public abstract class ParameterConfig<TAnnotation extends Annotation, TParamInfo> implements Comparable<ParameterConfig<?, ?>> { - private final Class<TAnnotation> annotationClass; - // protected final TParamInfo defaultValue; - - public ParameterConfig(Class<TAnnotation> annotationClass/*, TParamInfo defaultValue*/) { - this.annotationClass = annotationClass; - //this.defaultValue = defaultValue; - } - - public final Class<TAnnotation> getAnnotationClass() { - return annotationClass; - } - /* - public TParamInfo getDefaultValue() { - return defaultValue; - }*/ - - protected abstract TParamInfo toParameterInfo(TAnnotation annotation); - - public TParamInfo getParameterInfo(Annotation annotation) { - //noinspection unchecked - return toParameterInfo((TAnnotation) annotation); - } - - public static <TAnnotation extends Annotation, TParamInfo> ParameterConfig<TAnnotation, TParamInfo> - includeMemoryClass(Class<TAnnotation> annotationClass, Class<TParamInfo> memoryClass) { - Constructor<TParamInfo> constructor; - //TParamInfo defaultValue; - try { - constructor = memoryClass.getConstructor(annotationClass); - //defaultValue = Reflection.getStaticFieldValue(annotationClass, "DEFAULT"); - } catch (NoSuchMethodException | IllegalArgumentException ex) { - throw new IllegalArgumentException(ex); - } - /* - if (defaultValue == null) try { - defaultValue = memoryClass.newInstance(); - } catch (IllegalAccessException | InstantiationException ex) { - throw new IllegalArgumentException("Failed to get a default value for the param info", ex); - }*/ - - return new ParameterConfig<TAnnotation, TParamInfo>(annotationClass/*, defaultValue*/) { - - @Override - public TParamInfo toParameterInfo(TAnnotation annotation) { - try { - return constructor.newInstance(annotation); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - }; - } - - public static <TAnnotation extends Annotation, TParamInfo> ParameterConfig<TAnnotation, TParamInfo> getMemoryClassFromField(Class<TAnnotation> annotationClass) { - return ParameterConfig.includeMemoryClass(annotationClass, Reflection.getStaticFieldValue(annotationClass, "MEMORY_CLASS")); - } - - @Override - public int compareTo(ParameterConfig<?, ?> o) { - return 0; - } - -} - +package io.dico.dicore.command.parameter.type;
+
+import io.dico.dicore.Reflection;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+
+/**
+ * This class serves the purpose of having annotated parameter configurations (such as ranges for number parameters).
+ * Such configurations must be possible to obtain without using annotations, and as such, there should be a class conveying the information
+ * that is separate from the annotation itself. This class acts as a bridge from the annotation to said class conveying the information.
+ *
+ * @param <TAnnotation> the annotation type for parameters
+ * @param <TParamInfo> the object type that holds the information required in memory
+ */
+public abstract class ParameterConfig<TAnnotation extends Annotation, TParamInfo> implements Comparable<ParameterConfig<?, ?>> {
+ private final Class<TAnnotation> annotationClass;
+ // protected final TParamInfo defaultValue;
+
+ public ParameterConfig(Class<TAnnotation> annotationClass/*, TParamInfo defaultValue*/) {
+ this.annotationClass = annotationClass;
+ //this.defaultValue = defaultValue;
+ }
+
+ public final Class<TAnnotation> getAnnotationClass() {
+ return annotationClass;
+ }
+ /*
+ public TParamInfo getDefaultValue() {
+ return defaultValue;
+ }*/
+
+ protected abstract TParamInfo toParameterInfo(TAnnotation annotation);
+
+ public TParamInfo getParameterInfo(Annotation annotation) {
+ //noinspection unchecked
+ return toParameterInfo((TAnnotation) annotation);
+ }
+
+ public static <TAnnotation extends Annotation, TParamInfo> ParameterConfig<TAnnotation, TParamInfo>
+ includeMemoryClass(Class<TAnnotation> annotationClass, Class<TParamInfo> memoryClass) {
+ Constructor<TParamInfo> constructor;
+ //TParamInfo defaultValue;
+ try {
+ constructor = memoryClass.getConstructor(annotationClass);
+ //defaultValue = Reflection.getStaticFieldValue(annotationClass, "DEFAULT");
+ } catch (NoSuchMethodException | IllegalArgumentException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ /*
+ if (defaultValue == null) try {
+ defaultValue = memoryClass.newInstance();
+ } catch (IllegalAccessException | InstantiationException ex) {
+ throw new IllegalArgumentException("Failed to get a default value for the param info", ex);
+ }*/
+
+ return new ParameterConfig<TAnnotation, TParamInfo>(annotationClass/*, defaultValue*/) {
+
+ @Override
+ public TParamInfo toParameterInfo(TAnnotation annotation) {
+ try {
+ return constructor.newInstance(annotation);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ }
+
+ public static <TAnnotation extends Annotation, TParamInfo> ParameterConfig<TAnnotation, TParamInfo> getMemoryClassFromField(Class<TAnnotation> annotationClass) {
+ return ParameterConfig.includeMemoryClass(annotationClass, Reflection.getStaticFieldValue(annotationClass, "MEMORY_CLASS"));
+ }
+
+ @Override
+ public int compareTo(ParameterConfig<?, ?> o) {
+ return 0;
+ }
+
+}
+
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java index e1a62fa..e9cca7f 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java @@ -1,149 +1,149 @@ -package io.dico.dicore.command.parameter.type; - -import io.dico.dicore.Reflection; -import io.dico.dicore.command.CommandException; -import io.dico.dicore.command.ExecutionContext; -import io.dico.dicore.command.annotation.Range; -import io.dico.dicore.command.parameter.ArgumentBuffer; -import io.dico.dicore.command.parameter.Parameter; -import org.bukkit.Location; -import org.bukkit.command.CommandSender; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * A parameter type. - * Takes care of parsing, default values as well as completions. - * - * @param <TReturn> type of the parameter - * @param <TParamInfo> the info object type for the parameter (Example: {@link Range.Memory} - */ -public abstract class ParameterType<TReturn, TParamInfo> { - private final Class<TReturn> returnType; - private final ParameterConfig<?, TParamInfo> parameterConfig; - protected final ParameterType<TReturn, TParamInfo> otherType; // flag or non-flag, depending on current - - public ParameterType(Class<TReturn> returnType) { - this(returnType, null); - } - - public ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> paramConfig) { - this.returnType = Objects.requireNonNull(returnType); - this.parameterConfig = paramConfig; - - ParameterType<TReturn, TParamInfo> otherType = flagTypeParameter(); - this.otherType = otherType == null ? this : otherType; - } - - protected ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> parameterConfig, ParameterType<TReturn, TParamInfo> otherType) { - this.returnType = returnType; - this.parameterConfig = parameterConfig; - this.otherType = otherType; - } - - public int getExpectedAmountOfConsumedArguments() { - return 1; - } - - public boolean canBeFlag() { - return this == otherType; - } - - public boolean isFlagExplicitly() { - return this instanceof FlagParameterType; - } - - /** - * @return The return type - */ - public final Class<TReturn> getReturnType() { - return returnType; - } - - public final Class<?> getAnnotationClass() { - return parameterConfig == null ? null : parameterConfig.getAnnotationClass(); - } - - public final ParameterConfig<?, TParamInfo> getParameterConfig() { - return parameterConfig; - } - - public ParameterKey getTypeKey() { - return new ParameterKey(returnType, parameterConfig != null ? parameterConfig.getAnnotationClass() : null); - } - - public ParameterKey getInfolessTypeKey() { - return new ParameterKey(returnType, null); - } - - protected FlagParameterType<TReturn, TParamInfo> flagTypeParameter() { - return null; - } - - public ParameterType<TReturn, TParamInfo> asFlagParameter() { - return canBeFlag() ? this : otherType; - } - - public ParameterType<TReturn, TParamInfo> asNormalParameter() { - return isFlagExplicitly() ? otherType : this; - } - - public abstract TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException; - - public TReturn parseForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException { - return parse(parameter, context.getSender(), buffer); - } - - public TReturn getDefaultValue(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException { - return null; - } - - public TReturn getDefaultValueForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException { - return getDefaultValue(parameter, context.getSender(), buffer); - } - - public List<String> complete(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, Location location, ArgumentBuffer buffer) { - return Collections.emptyList(); - } - - public List<String> completeForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, Location location, ArgumentBuffer buffer) { - return complete(parameter, context.getSender(), location, buffer); - } - - protected static abstract class FlagParameterType<TResult, TParamInfo> extends ParameterType<TResult, TParamInfo> { - - protected FlagParameterType(ParameterType<TResult, TParamInfo> otherType) { - super(otherType.returnType, otherType.parameterConfig, otherType); - } - - @Override - public int getExpectedAmountOfConsumedArguments() { - return otherType.getExpectedAmountOfConsumedArguments(); - } - - @Override - public boolean canBeFlag() { - return true; - } - - @Override - protected final FlagParameterType<TResult, TParamInfo> flagTypeParameter() { - return this; - } - - @Override - public ParameterType<TResult, TParamInfo> asFlagParameter() { - return this; - } - - @Override - public ParameterType<TResult, TParamInfo> asNormalParameter() { - return otherType; - } - - } - -} +package io.dico.dicore.command.parameter.type;
+
+import io.dico.dicore.Reflection;
+import io.dico.dicore.command.CommandException;
+import io.dico.dicore.command.ExecutionContext;
+import io.dico.dicore.command.annotation.Range;
+import io.dico.dicore.command.parameter.ArgumentBuffer;
+import io.dico.dicore.command.parameter.Parameter;
+import org.bukkit.Location;
+import org.bukkit.command.CommandSender;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A parameter type.
+ * Takes care of parsing, default values as well as completions.
+ *
+ * @param <TReturn> type of the parameter
+ * @param <TParamInfo> the info object type for the parameter (Example: {@link Range.Memory}
+ */
+public abstract class ParameterType<TReturn, TParamInfo> {
+ private final Class<TReturn> returnType;
+ private final ParameterConfig<?, TParamInfo> parameterConfig;
+ protected final ParameterType<TReturn, TParamInfo> otherType; // flag or non-flag, depending on current
+
+ public ParameterType(Class<TReturn> returnType) {
+ this(returnType, null);
+ }
+
+ public ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> paramConfig) {
+ this.returnType = Objects.requireNonNull(returnType);
+ this.parameterConfig = paramConfig;
+
+ ParameterType<TReturn, TParamInfo> otherType = flagTypeParameter();
+ this.otherType = otherType == null ? this : otherType;
+ }
+
+ protected ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> parameterConfig, ParameterType<TReturn, TParamInfo> otherType) {
+ this.returnType = returnType;
+ this.parameterConfig = parameterConfig;
+ this.otherType = otherType;
+ }
+
+ public int getExpectedAmountOfConsumedArguments() {
+ return 1;
+ }
+
+ public boolean canBeFlag() {
+ return this == otherType;
+ }
+
+ public boolean isFlagExplicitly() {
+ return this instanceof FlagParameterType;
+ }
+
+ /**
+ * @return The return type
+ */
+ public final Class<TReturn> getReturnType() {
+ return returnType;
+ }
+
+ public final Class<?> getAnnotationClass() {
+ return parameterConfig == null ? null : parameterConfig.getAnnotationClass();
+ }
+
+ public final ParameterConfig<?, TParamInfo> getParameterConfig() {
+ return parameterConfig;
+ }
+
+ public ParameterKey getTypeKey() {
+ return new ParameterKey(returnType, parameterConfig != null ? parameterConfig.getAnnotationClass() : null);
+ }
+
+ public ParameterKey getInfolessTypeKey() {
+ return new ParameterKey(returnType, null);
+ }
+
+ protected FlagParameterType<TReturn, TParamInfo> flagTypeParameter() {
+ return null;
+ }
+
+ public ParameterType<TReturn, TParamInfo> asFlagParameter() {
+ return canBeFlag() ? this : otherType;
+ }
+
+ public ParameterType<TReturn, TParamInfo> asNormalParameter() {
+ return isFlagExplicitly() ? otherType : this;
+ }
+
+ public abstract TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException;
+
+ public TReturn parseForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException {
+ return parse(parameter, context.getSender(), buffer);
+ }
+
+ public TReturn getDefaultValue(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
+ return null;
+ }
+
+ public TReturn getDefaultValueForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException {
+ return getDefaultValue(parameter, context.getSender(), buffer);
+ }
+
+ public List<String> complete(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, Location location, ArgumentBuffer buffer) {
+ return Collections.emptyList();
+ }
+
+ public List<String> completeForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, Location location, ArgumentBuffer buffer) {
+ return complete(parameter, context.getSender(), location, buffer);
+ }
+
+ protected static abstract class FlagParameterType<TResult, TParamInfo> extends ParameterType<TResult, TParamInfo> {
+
+ protected FlagParameterType(ParameterType<TResult, TParamInfo> otherType) {
+ super(otherType.returnType, otherType.parameterConfig, otherType);
+ }
+
+ @Override
+ public int getExpectedAmountOfConsumedArguments() {
+ return otherType.getExpectedAmountOfConsumedArguments();
+ }
+
+ @Override
+ public boolean canBeFlag() {
+ return true;
+ }
+
+ @Override
+ protected final FlagParameterType<TResult, TParamInfo> flagTypeParameter() {
+ return this;
+ }
+
+ @Override
+ public ParameterType<TResult, TParamInfo> asFlagParameter() {
+ return this;
+ }
+
+ @Override
+ public ParameterType<TResult, TParamInfo> asNormalParameter() {
+ return otherType;
+ }
+
+ }
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/SimpleParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/SimpleParameterType.java index ecf19ce..667b2c7 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/SimpleParameterType.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/SimpleParameterType.java @@ -1,31 +1,31 @@ -package io.dico.dicore.command.parameter.type; - -import io.dico.dicore.command.CommandException; -import io.dico.dicore.command.parameter.ArgumentBuffer; -import io.dico.dicore.command.parameter.Parameter; -import org.bukkit.command.CommandSender; - -/** - * An abstraction for parameter types that only parse a single argument - * - * @param <TReturn> the parameter type - * @param <TParamInfo> parameter info object type - */ -public abstract class SimpleParameterType<TReturn, TParamInfo> extends ParameterType<TReturn, TParamInfo> { - - public SimpleParameterType(Class<TReturn> returnType) { - super(returnType); - } - - public SimpleParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> paramConfig) { - super(returnType, paramConfig); - } - - protected abstract TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, String input) throws CommandException; - - @Override - public TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException { - return parse(parameter, sender, buffer.requireNext(parameter.getName())); - } - -} +package io.dico.dicore.command.parameter.type;
+
+import io.dico.dicore.command.CommandException;
+import io.dico.dicore.command.parameter.ArgumentBuffer;
+import io.dico.dicore.command.parameter.Parameter;
+import org.bukkit.command.CommandSender;
+
+/**
+ * An abstraction for parameter types that only parse a single argument
+ *
+ * @param <TReturn> the parameter type
+ * @param <TParamInfo> parameter info object type
+ */
+public abstract class SimpleParameterType<TReturn, TParamInfo> extends ParameterType<TReturn, TParamInfo> {
+
+ public SimpleParameterType(Class<TReturn> returnType) {
+ super(returnType);
+ }
+
+ public SimpleParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> paramConfig) {
+ super(returnType, paramConfig);
+ }
+
+ protected abstract TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, String input) throws CommandException;
+
+ @Override
+ public TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
+ return parse(parameter, sender, buffer.requireNext(parameter.getName()));
+ }
+
+}
|