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 }