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
020package org.crsh.cli.impl.parser;
021
022import org.crsh.cli.descriptor.ArgumentDescriptor;
023import org.crsh.cli.descriptor.CommandDescriptor;
024import org.crsh.cli.descriptor.OptionDescriptor;
025import org.crsh.cli.descriptor.ParameterDescriptor;
026import org.crsh.cli.impl.tokenizer.Token;
027
028import java.util.ArrayList;
029import java.util.List;
030
031public abstract class Event {
032
033//  public static final class DoubleDash extends Event {
034//
035//    /** . */
036//    protected final Token.Literal.Option.Long token;
037//
038//    public DoubleDash(Token.Literal.Option.Long token) {
039//      this.token = token;
040//    }
041//  }
042
043  public abstract static class Parameter<T extends Token.Literal, D extends ParameterDescriptor> extends Event {
044
045    /** . */
046    protected final CommandDescriptor<?> command;
047
048    /** . */
049    protected final D parameter;
050
051    /** . */
052    protected final List<T> values;
053
054    public Parameter(CommandDescriptor<?> command, D parameter, List<T> values) {
055      this.command = command;
056      this.parameter = parameter;
057      this.values = values;
058    }
059
060    public CommandDescriptor<?> getCommand() {
061      return command;
062    }
063
064    public final D getParameter() {
065      return parameter;
066    }
067
068    public final List<T> getValues() {
069      return values;
070    }
071
072    public final T peekFirst() {
073      return values.isEmpty() ? null : values.get(0);
074    }
075
076    public final T peekLast() {
077      int size = values.size();
078      return size == 0 ? null : values.get(size - 1);
079    }
080
081    public final List<String> getStrings() {
082      List<String> strings = new ArrayList<String>();
083      for (T value : values) {
084        strings.add(value.getValue());
085      }
086      return strings;
087    }
088
089    public abstract int getFrom();
090
091    public abstract int getTo();
092
093    @Override
094    public String toString() {
095      return getClass().getSimpleName() + "[descriptor=" + parameter + ",values=" + values +  "]";
096    }
097  }
098
099  public static final class Option extends Parameter<Token.Literal.Word, OptionDescriptor> {
100
101    /** . */
102    private final Token.Literal.Option token;
103
104    Option(CommandDescriptor<?> command, OptionDescriptor descriptor, Token.Literal.Option token, List<Token.Literal.Word> values) {
105      super(command, descriptor, values);
106
107      this.token = token;
108    }
109
110    public final Token.Literal.Option getToken() {
111      return token;
112    }
113
114    @Override
115    public int getFrom() {
116      return token.getFrom();
117    }
118
119    @Override
120    public int getTo() {
121      return values.size() == 0 ? token.getTo() : peekLast().getTo();
122    }
123  }
124
125  public static final class Argument extends Parameter<Token.Literal, ArgumentDescriptor> {
126
127    Argument(CommandDescriptor<?> command, ArgumentDescriptor descriptor, List<Token.Literal> values) throws IllegalArgumentException {
128      super(command, descriptor, values);
129
130      //
131      if (values.size() == 0) {
132        throw new IllegalArgumentException("No empty values");
133      }
134    }
135
136    @Override
137    public int getFrom() {
138      return peekFirst().getFrom();
139    }
140
141    @Override
142    public int getTo() {
143      return peekLast().getTo();
144    }
145  }
146
147  public static final class Separator extends Event {
148
149    /** . */
150    private final Token.Whitespace token;
151
152    Separator(Token.Whitespace token) {
153      this.token = token;
154    }
155
156    public Token.Whitespace getToken() {
157      return token;
158    }
159  }
160
161  public abstract static class Subordinate extends Event {
162
163    /** . */
164    private final CommandDescriptor<?> descriptor;
165
166    public static final class Implicit extends Subordinate {
167
168      /** . */
169      private final Token.Literal trigger;
170
171      public Implicit(CommandDescriptor<?> descriptor, Token.Literal trigger) {
172        super(descriptor);
173        this.trigger = trigger;
174      }
175
176      public Token.Literal getTrigger() {
177        return trigger;
178      }
179    }
180
181    public static final class Explicit extends Subordinate {
182
183      /** . */
184      private final Token.Literal.Word token;
185
186      public Explicit(CommandDescriptor<?> descriptor, Token.Literal.Word token) {
187        super(descriptor);
188        this.token = token;
189      }
190
191      public Token.Literal.Word getToken() {
192        return token;
193      }
194    }
195
196    Subordinate(CommandDescriptor<?> descriptor) {
197      this.descriptor = descriptor;
198    }
199
200    public CommandDescriptor<?> getDescriptor() {
201      return descriptor;
202    }
203  }
204
205  public static abstract class Stop extends Event {
206
207    public abstract int getIndex();
208
209    public static final class Done extends Stop {
210
211      /** . */
212      private final int index;
213
214      Done(int index) {
215        this.index = index;
216      }
217
218      @Override
219      public int getIndex() {
220        return index;
221      }
222    }
223
224    public static abstract class Unresolved<T extends Token> extends Stop {
225
226      /** . */
227      private final T token;
228
229      Unresolved(T token) {
230        this.token = token;
231      }
232
233      @Override
234      public final int getIndex() {
235        return token.getFrom();
236      }
237
238      public T getToken() {
239        return token;
240      }
241
242      public static final class NoSuchOption extends Unresolved<Token.Literal.Option> {
243        public NoSuchOption(Token.Literal.Option token) {
244          super(token);
245        }
246      }
247
248      public static final class TooManyArguments extends Unresolved<Token.Literal> {
249        TooManyArguments(Token.Literal token) {
250          super(token);
251        }
252      }
253    }
254  }
255}