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