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.shell.impl.command.pipeline;
021    
022    import org.crsh.command.CommandContext;
023    import org.crsh.shell.ErrorKind;
024    import org.crsh.shell.impl.command.spi.CommandException;
025    import org.crsh.shell.impl.command.spi.CommandInvoker;
026    import org.crsh.keyboard.KeyHandler;
027    
028    import java.io.IOException;
029    
030    public class  PipeLine extends CommandInvoker<Void, Object> {
031    
032      /** . */
033      private final CommandInvoker[] invokers;
034    
035      /** . */
036      private CommandContext<?> current;
037    
038      public PipeLine(CommandInvoker[] invokers) {
039        this.invokers = invokers;
040        this.current = null;
041      }
042    
043      public Class<Void> getConsumedType() {
044        return Void.class;
045      }
046    
047      public Class<Object> getProducedType() {
048        return Object.class;
049      }
050    
051      public void open(CommandContext<? super Object> consumer) throws IOException, CommandException {
052        open(0, consumer);
053      }
054    
055      private CommandContext open(final int index, final CommandContext last) throws IOException, CommandException {
056        if (index < invokers.length) {
057    
058          //
059          final CommandInvoker invoker = invokers[index];
060          CommandContext next = open(index + 1, last);
061    
062          //
063          Class produced = invoker.getProducedType();
064          Class<?> consumed = invoker.getConsumedType();
065          CommandInvokerAdapter filterContext = new CommandInvokerAdapter(invoker, consumed, produced);
066          try {
067            filterContext.open(next);
068          }
069          catch (Exception e) {
070            throw new CommandException(ErrorKind.EVALUATION, e);
071          }
072    
073          // Save current filter in field
074          // so if anything wrong happens it will be closed
075          current = filterContext;
076    
077          //
078          return filterContext;
079        } else {
080          current = last;
081          return last;
082        }
083      }
084    
085      @Override
086      public KeyHandler getKeyHandler() {
087        for (CommandInvoker<?, ?> invoker : invokers) {
088          KeyHandler handler = invoker.getKeyHandler();
089          if (handler != null) {
090            return handler;
091          }
092        }
093        return null;
094      }
095    
096      public void provide(Void element) throws IOException {
097        // Ignore
098      }
099    
100      public void flush() throws IOException {
101        current.flush();
102      }
103    
104      public void close() throws IOException, CommandException {
105        try {
106          current.close();
107        }
108        catch (Exception e) {
109          throw new CommandException(ErrorKind.EVALUATION, e);
110        }
111      }
112    }