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.ClassDescriptor;
024    import org.crsh.cmdline.OptionDescriptor;
025    import org.crsh.cmdline.binding.ClassFieldBinding;
026    import org.crsh.cmdline.ParameterDescriptor;
027    
028    import java.io.IOException;
029    import java.lang.reflect.Field;
030    import java.util.ArrayList;
031    import java.util.HashSet;
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 class ClassMatch<T> extends CommandMatch<T, ClassDescriptor<T>, ClassFieldBinding> {
041    
042      /** . */
043      private final ClassDescriptor<T> descriptor;
044    
045      public ClassMatch(
046        ClassDescriptor<T> descriptor,
047        List<OptionMatch<ClassFieldBinding>> optionMatches,
048        List<ArgumentMatch<ClassFieldBinding>> argumentMatches,
049        String rest) {
050        super(optionMatches, argumentMatches, rest);
051    
052        //
053        this.descriptor = descriptor;
054      }
055    
056      @Override
057      public ClassDescriptor<T> getDescriptor() {
058        return descriptor;
059      }
060    
061      @Override
062      public void printMan(Appendable writer) throws IOException {
063        descriptor.printMan(writer);
064      }
065    
066      @Override
067      public void printUsage(Appendable writer) throws IOException {
068        descriptor.printUsage(writer);
069      }
070    
071      @Override
072      public Set<ParameterDescriptor<?>> getParameters() {
073        Set<ParameterDescriptor<?>> unused = new HashSet<ParameterDescriptor<?>>();
074        unused.addAll(descriptor.getArguments());
075        unused.addAll(descriptor.getOptions());
076        return unused;
077      }
078    
079      @Override
080      public List<ParameterMatch<?, ?>> getParameterMatches() {
081        List<ParameterMatch<?, ?>> matches = new ArrayList<ParameterMatch<?, ?>>();
082        matches.addAll(getOptionMatches());
083        matches.addAll(getArgumentMatches());
084        return matches;
085      }
086    
087      @Override
088      protected Object doInvoke(InvocationContext context, T command, Map<ParameterDescriptor<?>, Object> values) throws CmdInvocationException, CmdSyntaxException {
089        for (ParameterDescriptor<ClassFieldBinding> parameter : descriptor.getParameters()) {
090          Object value = values.get(parameter);
091    
092          //
093          if (value == null) {
094            if (parameter.isRequired()) {
095              if (parameter instanceof ArgumentDescriptor) {
096                ArgumentDescriptor<?> argument = (ArgumentDescriptor<?>)parameter;
097                throw new CmdSyntaxException("Missing argument " + argument.getName());
098              } else {
099                OptionDescriptor<?> option = (OptionDescriptor<?>)parameter;
100                throw new CmdSyntaxException("Missing option " + option.getNames());
101              }
102            }
103          } else {
104            Field f = parameter.getBinding().getField();
105            try {
106              f.setAccessible(true);
107              f.set(command, value);
108            }
109            catch (Exception e) {
110              throw new CmdInvocationException(e.getMessage(), e);
111            }
112          }
113        }
114    
115        //
116        return null;
117      }
118    }