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 */ 019package org.crsh.lang.java; 020 021import org.crsh.cli.impl.invocation.CommandInvoker; 022import org.crsh.cli.impl.invocation.InvocationException; 023import org.crsh.cli.impl.invocation.InvocationMatch; 024import org.crsh.cli.impl.lang.Instance; 025import org.crsh.command.BaseCommand; 026import org.crsh.command.CommandContext; 027import org.crsh.command.InvocationContext; 028import org.crsh.command.SyntaxException; 029import org.crsh.console.KeyHandler; 030import org.crsh.shell.impl.command.InvocationContextImpl; 031import org.crsh.shell.impl.command.spi.CommandCreationException; 032 033import java.io.IOException; 034import java.lang.reflect.UndeclaredThrowableException; 035 036/** 037* @author Julien Viet 038*/ 039class ProducerCommandImpl<T extends BaseCommand, P> extends CommandImpl<T, Void, P> { 040 041 private final CommandInvoker<Instance<T>, ?> invoker; 042 private final Class<P> producedType; 043 044 public ProducerCommandImpl(ShellCommandImpl<T> shellCommand, CommandInvoker<Instance<T>, ?> invoker, Class<P> producedType) { 045 super(shellCommand); 046 047 // 048 this.invoker = invoker; 049 this.producedType = producedType; 050 } 051 052 @Override 053 public InvocationMatch<?> getMatch() { 054 return invoker.getMatch(); 055 } 056 057 @Override 058 public Class<P> getProducedType() { 059 return producedType; 060 } 061 062 @Override 063 public Class<Void> getConsumedType() { 064 return Void.class; 065 } 066 067 @Override 068 BaseInvoker getInvoker(T command) throws CommandCreationException { 069 070 // 071 return new BaseInvoker(command) { 072 073 /** . */ 074 private InvocationContext<P> invocationContext; 075 076 public Class<P> getProducedType() { 077 return producedType; 078 } 079 080 public Class<Void> getConsumedType() { 081 return Void.class; 082 } 083 084 public void open(CommandContext<? super P> consumer) { 085 // Java is fine with that but not intellij.... 086 CommandContext<P> consumer2 = (CommandContext<P>)consumer; 087 open2(consumer2); 088 } 089 090 public void open2(final CommandContext<P> consumer) { 091 invocationContext = new InvocationContextImpl<P>(consumer); 092 command.pushContext(invocationContext); 093 command.unmatched = invoker.getMatch().getRest(); 094 } 095 096 097 @Override 098 public KeyHandler getKeyHandler() { 099 if (command instanceof KeyHandler) { 100 return (KeyHandler)command; 101 } else { 102 return null; 103 } 104 } 105 106 public void provide(Void element) throws IOException { 107 // Drop everything 108 } 109 110 public void flush() throws IOException { 111 } 112 113 public void close() throws IOException, UndeclaredThrowableException { 114 115 // 116 Object ret; 117 try { 118 ret = invoker.invoke(this); 119 } 120 catch (org.crsh.cli.SyntaxException e) { 121 throw new SyntaxException(e.getMessage()); 122 } catch (InvocationException e) { 123 throw command.toScript(e.getCause()); 124 } 125 126 // 127 if (ret != null && producedType.isInstance(ret)) { 128 P produced = producedType.cast(ret); 129 invocationContext.provide(produced); 130 } 131 132 // 133 invocationContext.flush(); 134 invocationContext.close(); 135 command.unmatched = null; 136 invocationContext = null; 137 } 138 }; 139 } 140}