001    /*
002     * Copyright (C) 2012 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.cli.impl.invocation;
021    
022    import org.crsh.cli.descriptor.CommandDescriptor;
023    import org.crsh.cli.descriptor.OptionDescriptor;
024    import org.crsh.cli.descriptor.ParameterDescriptor;
025    import org.crsh.cli.impl.descriptor.CommandDescriptorImpl;
026    import org.crsh.cli.SyntaxException;
027    
028    import java.util.Collection;
029    import java.util.Collections;
030    import java.util.LinkedHashMap;
031    import java.util.LinkedList;
032    import java.util.List;
033    import java.util.Map;
034    
035    /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
036    public final class InvocationMatch<T> {
037    
038      /** . */
039      private final CommandDescriptorImpl<T> descriptor;
040    
041      /** . */
042      private Map<OptionDescriptor, OptionMatch> options;
043    
044      /** . */
045      private List<ArgumentMatch> arguments;
046    
047      /** . */
048      private String rest;
049    
050      /** . */
051      private final InvocationMatch<T> owner;
052    
053      public InvocationMatch(CommandDescriptorImpl<T> descriptor) {
054        this(null, descriptor);
055      }
056    
057      private InvocationMatch(InvocationMatch<T> owner, CommandDescriptorImpl<T> descriptor) {
058        this.owner = owner;
059        this.descriptor = descriptor;
060        this.options = Collections.emptyMap();
061        this.rest = null;
062        this.arguments = Collections.emptyList();
063      }
064    
065      public InvocationMatch<T> owner() {
066        return owner;
067      }
068    
069      public InvocationMatch<T> subordinate(String name) {
070        CommandDescriptorImpl<T> subordinate = descriptor.getSubordinate(name);
071        if (subordinate != null) {
072          return new InvocationMatch<T>(this, subordinate);
073        } else {
074          return null;
075        }
076      }
077    
078      public CommandDescriptor<T> getDescriptor() {
079        return descriptor;
080      }
081    
082      public final <D extends ParameterDescriptor> ParameterMatch<D> getParameter(D parameter) {
083        if (parameter instanceof OptionDescriptor) {
084          return (ParameterMatch<D>)options.get(parameter);
085        } else {
086          for (ArgumentMatch argumentMatch : arguments) {
087            if (argumentMatch.getParameter()  == parameter) {
088              return (ParameterMatch<D>)argumentMatch;
089            }
090          }
091          return null;
092        }
093      }
094    
095      public CommandInvoker<T> getInvoker() {
096        return descriptor.getInvoker(this);
097      }
098    
099      public Object invoke(T command) throws InvocationException, SyntaxException {
100        return invoke(Resolver.EMPTY, command);
101      }
102    
103      public Object invoke(Resolver resolver, T command) throws InvocationException, SyntaxException {
104        CommandInvoker<T> invoker = getInvoker();
105        if (invoker != null) {
106          return invoker.invoke(resolver, command);
107        } else {
108          return null;
109        }
110      }
111    
112      public Collection<OptionMatch> options() {
113        return options.values();
114      }
115    
116      public void option(OptionMatch option) {
117        if (options.isEmpty()) {
118          options = new LinkedHashMap<OptionDescriptor, OptionMatch>();
119        }
120        options.put(option.getParameter(), option);
121      }
122    
123      public Collection<ArgumentMatch> arguments() {
124        return arguments;
125      }
126    
127      public void argument(ArgumentMatch argument) {
128        if (arguments.isEmpty()) {
129          arguments = new LinkedList<ArgumentMatch>();
130        }
131        arguments.add(argument);
132      }
133    
134      public String getRest() {
135        return rest;
136      }
137    
138      public void setRest(String rest) {
139        this.rest = rest;
140      }
141    }