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.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 }