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