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.groovy.repl;
020
021 import groovy.lang.GroovyShell;
022 import org.crsh.cli.impl.Delimiter;
023 import org.crsh.cli.impl.completion.CompletionMatch;
024 import org.crsh.cli.spi.Completion;
025 import org.crsh.command.CommandContext;
026 import org.crsh.command.CommandInvoker;
027 import org.crsh.command.InvocationContextImpl;
028 import org.crsh.lang.groovy.closure.PipeLineInvoker;
029 import org.crsh.lang.groovy.shell.ShellBinding;
030 import org.crsh.lang.groovy.shell.GroovyCommandManager;
031 import org.crsh.repl.EvalResponse;
032 import org.crsh.repl.REPL;
033 import org.crsh.repl.REPLSession;
034
035 import java.io.IOException;
036
037 /**
038 * Groovy REPL implementation.
039 *
040 * @author Julien Viet
041 */
042 public class GroovyREPL implements REPL {
043
044 public String getName() {
045 return "groovy";
046 }
047
048 public EvalResponse eval(final REPLSession session, final String request) {
049 CommandInvoker<Void, Object> invoker = new CommandInvoker<Void, Object>() {
050 public void provide(Void element) throws IOException {
051 throw new UnsupportedOperationException("Should not be invoked");
052 }
053 public Class<Void> getConsumedType() {
054 return Void.class;
055 }
056 public void flush() throws IOException {
057 }
058 public Class<Object> getProducedType() {
059 return Object.class;
060 }
061 CommandContext<Object> foo;
062 public void open(CommandContext<? super Object> consumer) {
063 this.foo = (CommandContext<Object>)consumer;
064 GroovyShell shell = GroovyCommandManager.getGroovyShell(session.getContext(), session);
065 ShellBinding binding = (ShellBinding)shell.getContext();
066 binding.setCurrent(foo);
067 Object o;
068 try {
069 o = shell.evaluate(request);
070 }
071 finally {
072 binding.setCurrent(null);
073 }
074 if (o instanceof PipeLineInvoker) {
075 PipeLineInvoker eval = (PipeLineInvoker)o;
076 try {
077 eval.invoke(new InvocationContextImpl<Object>(foo));
078 }
079 catch (Exception e) {
080 throw new UnsupportedOperationException("handle me gracefully", e);
081 }
082 } else {
083 try {
084 if (o != null) {
085 consumer.provide(o);
086 }
087 }
088 catch (IOException e) {
089 throw new UnsupportedOperationException("handle me gracefully", e);
090 }
091 }
092 }
093 public void close() throws IOException {
094 foo.flush();
095 foo.close();
096 }
097 };
098 return new EvalResponse.Invoke(invoker);
099 }
100
101 public CompletionMatch complete(REPLSession session, String prefix) {
102 return new CompletionMatch(Delimiter.EMPTY, Completion.create());
103 }
104 }