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 package org.crsh.shell.impl.command.pipeline; 020 021 import org.crsh.command.CommandContext; 022 import org.crsh.shell.impl.command.spi.CommandException; 023 import org.crsh.stream.Consumer; 024 import org.crsh.stream.Producer; 025 import org.crsh.text.Screenable; 026 import org.crsh.text.ScreenContext; 027 import org.crsh.shell.impl.command.spi.CommandInvoker; 028 import org.crsh.text.CLS; 029 import org.crsh.text.ScreenContextConsumer; 030 import org.crsh.text.Style; 031 032 import java.io.IOException; 033 import java.lang.reflect.UndeclaredThrowableException; 034 import java.util.Map; 035 036 /** @author Julien Viet */ 037 class CommandInvokerAdapter<C, P, CONSUMER extends CommandContext<? super P>> 038 implements Consumer<Object>, Producer<P, CONSUMER>, CommandContext<Object> { 039 040 /** . */ 041 final CommandInvoker<C, P> command; 042 043 /** . */ 044 protected CONSUMER consumer; 045 046 /** . */ 047 private final Class<C> consumedType; 048 049 /** . */ 050 private final Class<P> producedType; 051 052 /** . */ 053 private ScreenContextConsumer adapter; 054 055 /** . */ 056 private ScreenContext screenContext; 057 058 /** . */ 059 private final boolean charSequenceConsumer; 060 061 /** . */ 062 private final boolean styleConsumer; 063 064 /** . */ 065 private final boolean clsConsumer; 066 067 CommandInvokerAdapter(CommandInvoker<C, P> command, Class<C> consumedType, Class<P> producedType) { 068 this.consumedType = consumedType; 069 this.producedType = producedType; 070 this.consumer = null; 071 this.command = command; 072 this.screenContext = null; 073 this.charSequenceConsumer = consumedType.isAssignableFrom(CharSequence.class); 074 this.styleConsumer = consumedType.isAssignableFrom(Style.class); 075 this.clsConsumer = consumedType.isAssignableFrom(CLS.class); 076 } 077 078 public boolean takeAlternateBuffer() throws IOException { 079 return consumer.takeAlternateBuffer(); 080 } 081 082 public boolean releaseAlternateBuffer() throws IOException { 083 return consumer.releaseAlternateBuffer(); 084 } 085 086 public String getProperty(String propertyName) { 087 return consumer.getProperty(propertyName); 088 } 089 090 public String readLine(String msg, boolean echo) throws IOException, InterruptedException { 091 return consumer.readLine(msg, echo); 092 } 093 094 public Map<String, Object> getSession() { 095 return consumer.getSession(); 096 } 097 098 public Map<String, Object> getAttributes() { 099 return consumer.getAttributes(); 100 } 101 102 public int getWidth() { 103 return screenContext != null ? screenContext.getWidth() : consumer.getWidth(); 104 } 105 106 public int getHeight() { 107 return screenContext != null ? screenContext.getHeight() : consumer.getHeight(); 108 } 109 110 public void open(final CONSUMER consumer) throws Exception { 111 112 // 113 try { 114 command.open(consumer); 115 } 116 catch (CommandException e) { 117 Throwable cause = e.getCause(); 118 if (cause instanceof Exception) { 119 throw (Exception)cause; 120 } else if (cause instanceof Error) { 121 throw (Error)cause; 122 } else { 123 throw new UndeclaredThrowableException(cause); 124 } 125 } 126 127 // 128 ScreenContext screenContext = command.getScreenContext(); 129 ScreenContextConsumer adapter = screenContext != null ? new ScreenContextConsumer(screenContext) : null; 130 131 // 132 this.screenContext = screenContext; 133 this.adapter = adapter; 134 this.consumer = consumer; 135 } 136 137 @Override 138 public Class<Object> getConsumedType() { 139 return Object.class; 140 } 141 142 @Override 143 public Class<P> getProducedType() { 144 return producedType; 145 } 146 147 @Override 148 public void provide(Object element) throws Exception { 149 if (adapter != null) { 150 adapter.provide(element); 151 } 152 if (consumedType.isInstance(element)) { 153 try { 154 command.provide(consumedType.cast(element)); 155 } 156 catch (CommandException e) { 157 Throwable cause = e.getCause(); 158 if (cause instanceof Exception) { 159 throw (Exception)cause; 160 } else if (cause instanceof Error) { 161 throw (Error)cause; 162 } else { 163 throw new UndeclaredThrowableException(cause); 164 } 165 } 166 } 167 } 168 169 @Override 170 public Appendable append(char c) throws IOException { 171 if (screenContext != null) { 172 screenContext.append(c); 173 } 174 if (charSequenceConsumer) { 175 try { 176 command.provide(consumedType.cast(Character.toString(c))); 177 } 178 catch (CommandException e) { 179 Throwable cause = e.getCause(); 180 if (cause instanceof RuntimeException) { 181 throw (RuntimeException)cause; 182 } else if (cause instanceof Error) { 183 throw (Error)cause; 184 } else { 185 throw new UndeclaredThrowableException(cause); 186 } 187 } 188 } 189 return this; 190 } 191 192 @Override 193 public Appendable append(CharSequence s) throws IOException { 194 if (screenContext != null) { 195 screenContext.append(s); 196 } 197 if (charSequenceConsumer) { 198 try { 199 command.provide(consumedType.cast(s)); 200 } 201 catch (CommandException e) { 202 Throwable cause = e.getCause(); 203 if (cause instanceof RuntimeException) { 204 throw (RuntimeException)cause; 205 } else if (cause instanceof Error) { 206 throw (Error)cause; 207 } else { 208 throw new UndeclaredThrowableException(cause); 209 } 210 } 211 } 212 return this; 213 } 214 215 @Override 216 public Appendable append(CharSequence csq, int start, int end) throws IOException { 217 if (screenContext != null) { 218 screenContext.append(csq, start, end); 219 } 220 if (charSequenceConsumer) { 221 try { 222 command.provide(consumedType.cast(csq.subSequence(start, end))); 223 } 224 catch (CommandException e) { 225 Throwable cause = e.getCause(); 226 if (cause instanceof RuntimeException) { 227 throw (RuntimeException)cause; 228 } else if (cause instanceof Error) { 229 throw (Error)cause; 230 } else { 231 throw new UndeclaredThrowableException(cause); 232 } 233 } 234 } 235 return this; 236 } 237 238 @Override 239 public Screenable append(Style style) throws IOException { 240 if (screenContext != null) { 241 screenContext.append(style); 242 } 243 if (styleConsumer) { 244 try { 245 command.provide(consumedType.cast(style)); 246 } 247 catch (CommandException e) { 248 Throwable cause = e.getCause(); 249 if (cause instanceof RuntimeException) { 250 throw (RuntimeException)cause; 251 } else if (cause instanceof Error) { 252 throw (Error)cause; 253 } else { 254 throw new UndeclaredThrowableException(cause); 255 } 256 } 257 } 258 return this; 259 } 260 261 @Override 262 public Screenable cls() throws IOException { 263 if (screenContext != null) { 264 screenContext.cls(); 265 } 266 if (clsConsumer) { 267 try { 268 command.provide(consumedType.cast(CLS.INSTANCE)); 269 } 270 catch (CommandException e) { 271 Throwable cause = e.getCause(); 272 if (cause instanceof RuntimeException) { 273 throw (RuntimeException)cause; 274 } else if (cause instanceof Error) { 275 throw (Error)cause; 276 } else { 277 throw new UndeclaredThrowableException(cause); 278 } 279 } 280 } 281 return this; 282 } 283 284 public void flush() throws IOException { 285 if (adapter != null) { 286 adapter.flush(); 287 } 288 command.flush(); 289 } 290 291 public void close() throws Exception { 292 if (adapter != null) { 293 adapter.flush(); 294 } 295 try { 296 command.close(); 297 } 298 catch (CommandException e) { 299 Throwable cause = e.getCause(); 300 if (cause instanceof Exception) { 301 throw (Exception)cause; 302 } else if (cause instanceof Error) { 303 throw (Error)cause; 304 } else { 305 throw new UndeclaredThrowableException(cause); 306 } 307 } 308 } 309 }