001 /* 002 * Copyright (C) 2010 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.cmdline.matcher; 021 022 import org.crsh.cmdline.ArgumentDescriptor; 023 import org.crsh.cmdline.CommandDescriptor; 024 import org.crsh.cmdline.Multiplicity; 025 import org.crsh.cmdline.OptionDescriptor; 026 import org.crsh.cmdline.ParameterDescriptor; 027 import org.crsh.cmdline.binding.TypeBinding; 028 029 import java.io.IOException; 030 import java.util.ArrayList; 031 import java.util.HashMap; 032 import java.util.List; 033 import java.util.Map; 034 import java.util.Set; 035 036 /** 037 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 038 * @version $Revision$ 039 */ 040 public abstract class CommandMatch<C, D extends CommandDescriptor<C, B>, B extends TypeBinding> { 041 042 /** . */ 043 private final List<OptionMatch<B>> optionMatches; 044 045 /** . */ 046 private final List<ArgumentMatch<B>> argumentMatches; 047 048 /** . */ 049 private final String rest; 050 051 public CommandMatch(List<OptionMatch<B>> optionMatches, List<ArgumentMatch<B>> argumentMatches, String rest) { 052 this.optionMatches = optionMatches; 053 this.argumentMatches = argumentMatches; 054 this.rest = rest; 055 } 056 057 public abstract D getDescriptor(); 058 059 public final Object invoke(InvocationContext context, C command) throws CmdInvocationException, CmdSyntaxException { 060 061 // 062 Set<ParameterDescriptor<?>> unused = getParameters(); 063 Map<ParameterDescriptor<?>, Object> parameterValues = new HashMap<ParameterDescriptor<?>, Object>(); 064 065 // 066 for (ParameterMatch<?, ?> parameterMatch : getParameterMatches()) { 067 ParameterDescriptor<?> parameter = parameterMatch.getParameter(); 068 if (!unused.remove(parameter)) { 069 if (parameter instanceof ArgumentDescriptor) { 070 ArgumentDescriptor<?> argument = (ArgumentDescriptor<?>)parameter; 071 throw new CmdSyntaxException("Missing argument " + argument.getName()); 072 } else { 073 OptionDescriptor<?> option = (OptionDescriptor<?>)parameter; 074 throw new CmdSyntaxException("Missing option " + option.getNames()); 075 } 076 } 077 Object v = parameterMatch.computeValue(); 078 if (v != null) { 079 parameterValues.put(parameter, v); 080 } 081 } 082 083 // 084 return doInvoke(context, command, parameterValues); 085 } 086 087 protected abstract Object doInvoke(InvocationContext context, C command, Map<ParameterDescriptor<?>, Object> values) throws CmdInvocationException, CmdSyntaxException; 088 089 public abstract Set<ParameterDescriptor<?>> getParameters(); 090 091 public abstract List<ParameterMatch<?, ?>> getParameterMatches(); 092 093 public abstract void printMan(Appendable writer) throws IOException; 094 095 public abstract void printUsage(Appendable writer) throws IOException; 096 097 public List<OptionMatch<B>> getOptionMatches() { 098 return optionMatches; 099 } 100 101 public List<ArgumentMatch<B>> getArgumentMatches() { 102 return argumentMatches; 103 } 104 105 public String getRest() { 106 return rest; 107 } 108 }