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.ClassDescriptor;
023    import org.crsh.cmdline.CommandDescriptor;
024    import org.crsh.cmdline.Delimiter;
025    import org.crsh.cmdline.matcher.tokenizer.Tokenizer;
026    
027    import java.util.Iterator;
028    import java.util.LinkedList;
029    import java.util.NoSuchElementException;
030    
031    /**
032     * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
033     * @version $Revision$
034     */
035    public final class Parser<T> implements Iterator<Event> {
036    
037      /** . */
038      private final Tokenizer tokenizer;
039    
040      /** . */
041      private final String mainName;
042    
043      /** . */
044      private final Mode mode;
045    
046      /** . */
047      private CommandDescriptor<T, ?> command;
048    
049      /** . */
050      private Status status;
051    
052      /** . */
053      private final LinkedList<Event> next;
054    
055      public Parser(Tokenizer tokenizer, ClassDescriptor<T> command, String mainName, Mode mode) {
056        this.tokenizer = tokenizer;
057        this.command = command;
058        this.mainName = mainName;
059        this.status = new Status.ReadingOption();
060        this.mode = mode;
061        this.next = new LinkedList<Event>();
062      }
063    
064      public Mode getMode() {
065        return mode;
066      }
067    
068      public int getIndex() {
069        return tokenizer.getIndex();
070      }
071    
072      public Status getStatus() {
073        return status;
074      }
075    
076      public Delimiter getDelimiter() {
077        return tokenizer.getDelimiter();
078      }
079    
080      public boolean hasNext() {
081        if (next.isEmpty()) {
082          determine();
083        }
084        return next.size() > 0;
085      }
086    
087      public Event next() {
088        if (!hasNext()) {
089          throw new NoSuchElementException();
090        }
091        return next.removeFirst();
092      }
093    
094      public void remove() {
095        throw new UnsupportedOperationException();
096      }
097    
098      private void determine() {
099        while (next.isEmpty()) {
100          Status.Response nextStatus = status.process(new Status.Request(mode, mainName, tokenizer, command));
101          if (nextStatus.status != null) {
102            this.status = nextStatus.status;
103          }
104          if (nextStatus.events != null) {
105            next.addAll(nextStatus.events);
106          }
107          if (nextStatus.command != null) {
108            command = (CommandDescriptor<T, ?>)nextStatus.command;
109          }
110        }
111      }
112    }