package io.shockah.skylark.groovy; import java.util.Collection; import java.util.Map; import java.util.Set; import groovy.lang.GroovyObjectSupport; import io.shockah.skylark.UnexpectedException; import io.shockah.skylark.commands.Command; import io.shockah.skylark.commands.CommandCall; import io.shockah.skylark.commands.CommandResult; import io.shockah.skylark.event.GenericUserMessageEvent; import io.shockah.skylark.func.Func1; public class DynamicCommandHandler extends GroovyObjectSupport implements Map<String, Func1<Object, Object>> { protected final GroovyPlugin plugin; protected final GenericUserMessageEvent event; public DynamicCommandHandler(GroovyPlugin plugin, GenericUserMessageEvent event) { this.plugin = plugin; this.event = event; } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public boolean containsKey(Object key) { String skey = key.toString(); return plugin.commandsPlugin.findCommand(event, skey) != null; } @Override public boolean containsValue(Object value) { throw new UnsupportedOperationException(); } @Override public Set<Entry<String, Func1<Object, Object>>> entrySet() { throw new UnsupportedOperationException(); } @SuppressWarnings("unchecked") @Override public Func1<Object, Object> get(Object key) { String skey = key.toString(); return input -> { Command<Object, Object> objectCommand = (Command<Object, Object>)plugin.commandsPlugin.findCommand(event, skey); Object actualInput = input; try { actualInput = objectCommand.convertToInput(event, input); } catch (Exception e) { throw new UnexpectedException(e); } CommandResult<Object> result = objectCommand.call(new CommandCall(event), actualInput); if (result.error != null) throw new UnexpectedException(result.error); return result.value; }; } @Override public boolean isEmpty() { throw new UnsupportedOperationException(); } @Override public Set<String> keySet() { throw new UnsupportedOperationException(); } @Override public Func1<Object, Object> put(String key, Func1<Object, Object> value) { throw new UnsupportedOperationException(); } @Override public void putAll(Map<? extends String, ? extends Func1<Object, Object>> m) { throw new UnsupportedOperationException(); } @Override public Func1<Object, Object> remove(Object key) { throw new UnsupportedOperationException(); } @Override public int size() { throw new UnsupportedOperationException(); } @Override public Collection<Func1<Object, Object>> values() { throw new UnsupportedOperationException(); } @Override public Object invokeMethod(String methodName, Object args) { return super.invokeMethod(methodName, args); //TODO: this thing is broken, getting exceptions like ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.String /*Object obj = get(methodName); if (obj == null) throw new UnexpectedException(new NoSuchMethodException()); for (Class<?> clazz : obj.getClass().getInterfaces()) { Method[] methods = clazz.getDeclaredMethods(); if (methods.length == 1) { MethodClosure method = new MethodClosure(obj, methods[0].getName()); return method.call(args); } } throw new UnsupportedOperationException();*/ } }