/* * Copyright (C) 2012 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.crsh.cli.impl.lang; import org.crsh.cli.descriptor.CommandDescriptor; import org.crsh.cli.descriptor.Description; import org.crsh.cli.impl.descriptor.IntrospectionException; import org.crsh.cli.descriptor.OptionDescriptor; import org.crsh.cli.descriptor.ParameterDescriptor; import org.crsh.cli.impl.SyntaxException; import org.crsh.cli.impl.invocation.InvocationException; import org.crsh.cli.impl.invocation.InvocationMatch; import java.lang.reflect.Type; import java.util.HashSet; import java.util.Map; import java.util.Set; class ClassDescriptor<T> extends ObjectCommandDescriptor<T> { /** . */ private final Class<T> type; /** . */ private final Map<String, MethodDescriptor<T>> methods; ClassDescriptor(Class<T> type, String name, Map<String, MethodDescriptor<T>> methods, Description info) throws IntrospectionException { super(name, info); // this.methods = methods; this.type = type; } @Override protected void addParameter(ParameterDescriptor parameter) throws IntrospectionException { // Check we can add the option if (parameter instanceof OptionDescriptor) { OptionDescriptor option = (OptionDescriptor)parameter; Set<String> blah = new HashSet<String>(); for (String optionName : option.getNames()) { blah.add((optionName.length() == 1 ? "-" : "--") + optionName); } for (MethodDescriptor<T> method : methods.values()) { Set<String> diff = new HashSet<String>(method.getOptionNames()); diff.retainAll(blah); if (diff.size() > 0) { throw new IntrospectionException("Cannot add method " + method.getName() + " because it has common " + " options with its class: " + diff); } } } // super.addParameter(parameter); } @Override public ObjectCommandInvoker<T, ?> getInvoker(final InvocationMatch<Instance<T>> match) { if (Runnable.class.isAssignableFrom(type)) { return new ObjectCommandInvoker<T, Void>(match) { @Override public Class<Void> getReturnType() { return Void.class; } @Override public Type getGenericReturnType() { return Void.class; } @Override public Class<?>[] getParameterTypes() { return new Class<?>[0]; } @Override public Type[] getGenericParameterTypes() { return new Type[0]; } public Void invoke(Instance<T> commandInstance) throws InvocationException, SyntaxException { T command; try { command = commandInstance.get(); } catch (Exception e) { throw new InvocationException(e); } MethodDescriptor.bind(match, getParameters(), command, Util.EMPTY_ARGS); Runnable runnable = Runnable.class.cast(command); try { runnable.run(); } catch (Exception e) { throw new InvocationException(e); } return null; } }; } else { return null; } } @Override public CommandDescriptor<Instance<T>> getOwner() { return null; } @Override public Map<String, ? extends MethodDescriptor<T>> getSubordinates() { return methods; } }