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.ScriptException;
024    import org.crsh.io.Filter;
025    import org.crsh.shell.ScreenContext;
026    import org.crsh.text.Chunk;
027    import org.crsh.text.ChunkAdapter;
028    import org.crsh.util.Safe;
029    
030    import java.io.Closeable;
031    import java.io.IOException;
032    import java.util.Map;
033    
034    /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
035    abstract class PipeFilter<C, P> implements Filter<C, P, CommandContext<P>>, CommandContext<C> {
036    
037      /** . */
038      protected CommandContext<P> context;
039    
040      /** . */
041      protected final boolean piped;
042    
043      protected PipeFilter(boolean piped) {
044        this.piped = piped;
045      }
046    
047      public final boolean isPiped() {
048        return piped;
049      }
050    
051      public final boolean takeAlternateBuffer() throws IOException {
052        return context.takeAlternateBuffer();
053      }
054    
055      public final boolean releaseAlternateBuffer() throws IOException {
056        return context.releaseAlternateBuffer();
057      }
058    
059      public final String getProperty(String propertyName) {
060        return context.getProperty(propertyName);
061      }
062    
063      public final String readLine(String msg, boolean echo) {
064        return context.readLine(msg, echo);
065      }
066    
067      public final int getWidth() {
068        return context.getWidth();
069      }
070    
071      public final int getHeight() {
072        return context.getHeight();
073      }
074    
075      public Map<String, Object> getSession() {
076        return context.getSession();
077      }
078    
079      public Map<String, Object> getAttributes() {
080        return context.getAttributes();
081      }
082    
083      static class Noop<P> extends PipeFilter<P, P> {
084    
085        Noop(boolean piped) {
086          super(piped);
087        }
088    
089        public void provide(P element) throws IOException {
090          context.provide(element);
091        }
092    
093        public Class<P> getConsumedType() {
094          return context.getConsumedType();
095        }
096    
097        public void flush() throws IOException {
098          context.flush();
099        }
100    
101        public Class<P> getProducedType() {
102          return context.getConsumedType();
103        }
104    
105        public void open(CommandContext<P> consumer) {
106          context = consumer;
107        }
108    
109        public void close() {
110          Safe.close(context);
111        }
112      }
113    
114      static class Chunkizer extends PipeFilter<Object, Chunk> {
115    
116        /** . */
117        private ChunkAdapter ca;
118    
119        Chunkizer(boolean piped) {
120          super(piped);
121        }
122    
123        public Class<Chunk> getProducedType() {
124          return Chunk.class;
125        }
126    
127        public Class<Object> getConsumedType() {
128          return Object.class;
129        }
130    
131        public void open(final CommandContext<Chunk> consumer) {
132          ca = new ChunkAdapter(new ScreenContext<Chunk>() {
133            public int getWidth() {
134              return consumer.getWidth();
135            }
136            public int getHeight() {
137              return consumer.getHeight();
138            }
139            public Class<Chunk> getConsumedType() {
140              return Chunk.class;
141            }
142            public void provide(Chunk element) throws IOException {
143              Chunkizer.this.context.provide(element);
144            }
145            public void flush() throws IOException {
146              Chunkizer.this.context.flush();
147            }
148          });
149    
150          this.context = consumer;
151        }
152    
153        public void provide(Object element) throws ScriptException, IOException {
154          ca.provide(element);
155        }
156    
157        public void flush() throws ScriptException, IOException {
158          ca.flush();
159        }
160    
161        public void close() throws ScriptException, IOException {
162          context.close();
163        }
164      }
165    
166      static class Sink<P> extends PipeFilter<Object, P> {
167    
168        /** . */
169        private final Class<P> producedType;
170    
171        Sink(Class<P> producedType, boolean piped) {
172          super(piped);
173    
174          //
175          this.producedType = producedType;
176        }
177    
178        public Class<P> getProducedType() {
179          return producedType;
180        }
181    
182        public void open(CommandContext<P> consumer) {
183          this.context = consumer;
184        }
185    
186        public void provide(Object element) throws IOException {
187        }
188    
189        public Class<Object> getConsumedType() {
190          return Object.class;
191        }
192    
193        public void flush() throws IOException {
194          context.flush();
195        }
196    
197        public void close() throws IOException {
198          context.close();
199        }
200      }
201    }