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    }