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