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.parser;
021    
022    import org.crsh.cli.descriptor.ArgumentDescriptor;
023    import org.crsh.cli.descriptor.CommandDescriptor;
024    import org.crsh.cli.descriptor.OptionDescriptor;
025    import org.crsh.cli.descriptor.ParameterDescriptor;
026    import org.crsh.cli.impl.tokenizer.Token;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    public 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    }