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;
021    
022    import org.crsh.command.CommandContext;
023    import org.crsh.command.CommandInvoker;
024    import org.crsh.command.ScriptException;
025    import org.crsh.io.Filter;
026    import org.crsh.io.ProducerContext;
027    import org.crsh.text.Chunk;
028    
029    import java.io.IOException;
030    
031    class PipeLine implements CommandInvoker {
032    
033      /** . */
034      private final CRaSHSession session;
035    
036      /** . */
037      private final Filter[] pipes;
038    
039      PipeLine(CRaSHSession session, Filter[] pipes) {
040        this.session = session;
041        this.pipes = pipes;
042      }
043    
044      public void invoke(ProducerContext<?> context) throws ScriptException, IOException {
045        open(context);
046        flush();
047        close();
048      }
049    
050      public void setSession(CommandContext session) {
051        // Should we use it ?
052      }
053    
054      public Class getConsumedType() {
055        throw new UnsupportedOperationException();
056      }
057    
058      public Class getProducedType() {
059        throw new UnsupportedOperationException();
060      }
061    
062      public void setPiped(boolean piped) {
063        throw new UnsupportedOperationException("This should not be called");
064      }
065    
066      public void open(ProducerContext context) {
067        ProducerContext<?> last = context;
068    
069        for (int i = pipes.length - 1;i >= 0;i--) {
070    
071          //
072          ProducerContext<?> next;
073    
074          //
075          Class produced = pipes[i].getProducedType();
076          Class<?> consumed = last.getConsumedType();
077    
078          if (consumed.isAssignableFrom(produced)) {
079            next = last;
080          } else {
081    
082            // Try to adapt
083            if (produced.equals(Void.class)) {
084              throw new UnsupportedOperationException(produced.getSimpleName() + " -> " + consumed.getSimpleName());
085            } else if (consumed.equals(Void.class)) {
086              SinkPipeFilter filter = new SinkPipeFilter(consumed);
087              filter.open(last);
088              next = filter;
089            } else if (consumed.equals(Chunk.class)) {
090              ToChunkPipeFilter filter = new ToChunkPipeFilter();
091              filter.open((ProducerContext<Chunk>)last);
092              next = filter;
093            } else {
094              SinkPipeFilter filter = new SinkPipeFilter(consumed);
095              filter.open(last);
096              next = filter;
097            }
098          }
099    
100          //
101          if (i > 0) {
102            pipes[i].setPiped(true);
103          }
104    
105          //
106          pipes[i].open(next);
107    
108          //
109          last = pipes[i];
110        }
111      }
112    
113      public void close() {
114        pipes[0].close();
115      }
116    
117      public void provide(Object element) throws IOException {
118        pipes[0].provide(element);
119      }
120    
121      public void flush() throws IOException {
122        pipes[0].flush();
123      }
124    }