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;
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.shell.impl.command.spi.CommandInvoker;
027 import org.crsh.shell.impl.command.InvocationContextImpl;
028 import org.crsh.lang.groovy.closure.PipeLineInvoker;
029 import org.crsh.repl.EvalResponse;
030 import org.crsh.repl.Repl;
031 import org.crsh.repl.ReplSession;
032 import org.crsh.cli.impl.line.LineParser;
033 import org.crsh.shell.impl.command.CRaSHSession;
034
035 import java.io.IOException;
036
037 /**
038 * Groovy REPL implementation.
039 *
040 * @author Julien Viet
041 */
042 public class GroovyReplImpl implements Repl {
043
044 public GroovyReplImpl() {
045 // Force to load Groovy here or fail
046 Object o = GroovyShell.class;
047 }
048
049 @Override
050 public boolean isActive() {
051 return true;
052 }
053
054 public String getName() {
055 return "groovy";
056 }
057
058 @Override
059 public String getDescription() {
060 return "The Groovy REPL provides a Groovy interpreter able to interact with shell commands";
061 }
062
063 public EvalResponse eval(final ReplSession session, final String r2) {
064
065
066 GroovyLineEscaper foo = new GroovyLineEscaper();
067 LineParser parser = new LineParser(foo);
068 parser.append(r2);
069 final String request = foo.buffer.toString();
070
071
072 //
073 CommandInvoker<Void, Object> invoker = new CommandInvoker<Void, Object>() {
074 public void provide(Void element) throws IOException {
075 throw new UnsupportedOperationException("Should not be invoked");
076 }
077 public Class<Void> getConsumedType() {
078 return Void.class;
079 }
080 public void flush() throws IOException {
081 }
082 public Class<Object> getProducedType() {
083 return Object.class;
084 }
085 CommandContext<Object> foo;
086 public void open(CommandContext<? super Object> consumer) {
087 this.foo = (CommandContext<Object>)consumer;
088 GroovyShell shell = GroovyCommandManagerImpl.getGroovyShell((CRaSHSession)session);
089 ShellBinding binding = (ShellBinding)shell.getContext();
090 binding.setCurrent(foo);
091 Object o;
092 try {
093 o = shell.evaluate(request);
094 }
095 finally {
096 binding.setCurrent(null);
097 }
098 if (o instanceof PipeLineInvoker) {
099 PipeLineInvoker eval = (PipeLineInvoker)o;
100 try {
101 eval.invoke(new InvocationContextImpl<Object>(foo));
102 }
103 catch (Exception e) {
104 throw new UnsupportedOperationException("handle me gracefully", e);
105 }
106 } else {
107 try {
108 if (o != null) {
109 consumer.provide(o);
110 }
111 }
112 catch (IOException e) {
113 throw new UnsupportedOperationException("handle me gracefully", e);
114 }
115 }
116 }
117 public void close() throws IOException {
118 foo.flush();
119 foo.close();
120 }
121 };
122 return new EvalResponse.Invoke(invoker);
123 }
124
125 public CompletionMatch complete(ReplSession session, String prefix) {
126 return new CompletionMatch(Delimiter.EMPTY, Completion.create());
127 }
128 }