Java tutorial
/* * This file is part of HeavySpleef. * Copyright (c) 2014-2016 Matthias Werning * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.xaniox.heavyspleef.commands.base.proxy; import com.google.common.collect.Lists; import de.xaniox.heavyspleef.commands.base.*; import de.xaniox.heavyspleef.commands.base.proxy.ProxyPriority.Priority; import org.apache.commons.lang.Validate; import java.util.Collections; import java.util.Iterator; import java.util.List; public class ProxyExecution implements CommandExecution { private CommandExecution delegate; private List<ProxyHolder> proxies; public static ProxyExecution decorate(CommandExecution execution) { ProxyExecution proxyExecution = new ProxyExecution(execution); return proxyExecution; } public static ProxyExecution inject(CommandManagerService service, String path) { CommandContainer container = service.containerOf(path); Validate.notNull(container, "Non-existent command path '" + path + "'"); CommandExecution execution = container.getExecution(); if (!(execution instanceof ProxyExecution)) { execution = decorate(execution); } container.setExecution(execution); return (ProxyExecution) execution; } protected ProxyExecution(CommandExecution delegate) { this.delegate = delegate; this.proxies = Lists.newArrayList(); } @Override public void execute(CommandContext context, MessageBundle bundle, PermissionChecker checker, Object[] executionArgs) { Redirection redirection = Redirection.EXECUTE; //Execute proxies for (ProxyHolder holder : proxies) { if (!applyFilter(context, holder)) { //This filter is not appliable to this execution continue; } Proxy proxy = holder.proxy; ProxyContext proxyContext = new ProxyContext(context); try { proxy.execute(proxyContext, executionArgs); } catch (CommandException e) { context.getSender().sendMessage(e.getMessage()); continue; } redirection = proxyContext.redirection(); } if (redirection == Redirection.EXECUTE) { delegate.execute(context, bundle, checker, executionArgs); } } private boolean applyFilter(CommandContext context, ProxyHolder holder) { String[] filter = holder.filter; if (filter == null) { return true; } String fullName = context.getCommand().getFullyQualifiedName(); for (String filterStr : filter) { if (fullName.equals(filterStr)) { return true; } } return false; } public void attachProxy(Proxy proxy) { Validate.isTrue(!isProxyAttached(proxy), "Proxy already attached"); Class<? extends Proxy> clazz = proxy.getClass(); Priority priority = Priority.NORMAL; if (clazz.isAnnotationPresent(ProxyPriority.class)) { ProxyPriority priorityAnnotation = clazz.getAnnotation(ProxyPriority.class); priority = priorityAnnotation.value(); } String[] filter = null; if (clazz.isAnnotationPresent(Filter.class)) { Filter filterAnnotation = clazz.getAnnotation(Filter.class); filter = filterAnnotation.value(); } ProxyHolder holder = new ProxyHolder(); holder.proxy = proxy; holder.priority = priority; holder.filter = filter; proxies.add(holder); //Finally sort the list to get an appropriate order Collections.sort(proxies); } public void unattachProxy(Proxy proxy) { Validate.isTrue(isProxyAttached(proxy), "Proxy is not attached"); Iterator<ProxyHolder> iterator = proxies.iterator(); while (iterator.hasNext()) { ProxyHolder holder = iterator.next(); if (holder.proxy != proxy) { continue; } iterator.remove(); break; } } private boolean isProxyAttached(Proxy proxy) { for (ProxyHolder holder : proxies) { if (holder.proxy.equals(proxy)) { return true; } } return false; } @Override public List<String> tabComplete(CommandContext context, PermissionChecker permissionChecker, Object[] args) { return delegate.tabComplete(context, permissionChecker, args); } private class ProxyHolder implements Comparable<ProxyHolder> { private Proxy proxy; private String[] filter; private ProxyPriority.Priority priority; @Override public int compareTo(ProxyHolder o) { return Integer.valueOf(priority.getPriorityInt()).compareTo(o.priority.getPriorityInt()); } } }