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
020package org.crsh.shell.impl.command.pipeline;
021
022import org.crsh.command.CommandContext;
023import org.crsh.shell.ErrorKind;
024import org.crsh.shell.impl.command.spi.CommandException;
025import org.crsh.shell.impl.command.spi.CommandInvoker;
026import org.crsh.keyboard.KeyHandler;
027
028import java.io.IOException;
029
030public 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}