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.lang.java;
020
021 import org.crsh.cli.impl.invocation.CommandInvoker;
022 import org.crsh.cli.impl.invocation.InvocationException;
023 import org.crsh.cli.impl.invocation.InvocationMatch;
024 import org.crsh.cli.impl.lang.Instance;
025 import org.crsh.command.BaseCommand;
026 import org.crsh.command.CommandContext;
027 import org.crsh.command.InvocationContext;
028 import org.crsh.command.SyntaxException;
029 import org.crsh.console.KeyHandler;
030 import org.crsh.shell.impl.command.InvocationContextImpl;
031 import org.crsh.shell.impl.command.spi.CommandCreationException;
032
033 import java.io.IOException;
034 import java.lang.reflect.UndeclaredThrowableException;
035
036 /**
037 * @author Julien Viet
038 */
039 class 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 }