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