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.groovy;
020
021import groovy.lang.Binding;
022import org.crsh.command.CommandContext;
023import org.crsh.shell.impl.command.spi.CommandCreationException;
024import org.crsh.shell.impl.command.InvocationContextImpl;
025import org.crsh.shell.impl.command.spi.ShellCommand;
026import org.crsh.lang.groovy.closure.PipeLineClosure;
027import org.crsh.repl.ReplSession;
028import org.crsh.text.Chunk;
029
030import java.io.IOException;
031import java.util.Map;
032
033/** @author Julien Viet */
034class ShellBinding extends Binding {
035
036  /** . */
037  private final ReplSession session;
038
039  /** . */
040  private CommandContext<Object> current;
041
042  public ShellBinding(Map variables, ReplSession session) {
043    super(variables);
044
045    //
046    this.session = session;
047  }
048
049  private CommandContext<Object> proxy = new CommandContext<Object>() {
050    public boolean isPiped() {
051      if (current == null) {
052        throw new IllegalStateException("Not under context");
053      } else {
054        return current.isPiped();
055      }
056    }
057    public void close() throws IOException {
058      if (current == null) {
059        throw new IllegalStateException("Not under context");
060      } else {
061        current.close();
062      }
063    }
064    public boolean takeAlternateBuffer() throws IOException {
065      if (current == null) {
066        throw new IllegalStateException("Not under context");
067      } else {
068        return current.takeAlternateBuffer();
069      }
070    }
071    public boolean releaseAlternateBuffer() throws IOException {
072      if (current == null) {
073        throw new IllegalStateException("Not under context");
074      } else {
075        return current.releaseAlternateBuffer();
076      }
077    }
078    public String readLine(String msg, boolean echo) throws IOException, InterruptedException {
079      if (current == null) {
080        throw new IllegalStateException("Not under context");
081      } else {
082        return current.readLine(msg, echo);
083      }
084    }
085    public int getWidth() {
086      if (current == null) {
087        throw new IllegalStateException("Not under context");
088      } else {
089        return current.getWidth();
090      }
091    }
092    public int getHeight() {
093      if (current == null) {
094        throw new IllegalStateException("Not under context");
095      } else {
096        return current.getWidth();
097      }
098    }
099    public void provide(Object element) throws IOException {
100      if (current == null) {
101        throw new IllegalStateException("Not under context");
102      } else {
103        current.provide(element);
104      }
105    }
106    public Class<Object> getConsumedType() {
107      if (current == null) {
108        throw new IllegalStateException("Not under context");
109      } else {
110        return current.getConsumedType();
111      }
112    }
113    public void flush() throws IOException {
114      if (current == null) {
115        throw new IllegalStateException("Not under context");
116      } else {
117        current.flush();
118      }
119    }
120    public String getProperty(String propertyName) {
121      if (current == null) {
122        throw new IllegalStateException("Not under context");
123      } else {
124        return current.getProperty(propertyName);
125      }
126    }
127    public Map<String, Object> getSession() {
128      if (current == null) {
129        throw new IllegalStateException("Not under context");
130      } else {
131        return current.getSession();
132      }
133    }
134    public Map<String, Object> getAttributes() {
135      if (current == null) {
136        throw new IllegalStateException("Not under context");
137      } else {
138        return current.getAttributes();
139      }
140    }
141    public void write(Chunk chunk) throws IOException {
142      if (current == null) {
143        throw new IllegalStateException("Not under context");
144      } else {
145        current.write(chunk);
146      }
147    }
148  };
149
150  public CommandContext<Object> getCurrent() {
151    return current;
152  }
153
154  public void setCurrent(CommandContext<Object> current) {
155    this.current = current;
156  }
157
158  @Override
159  public Object getVariable(String name) {
160    if (name.equals("context")) {
161      return new InvocationContextImpl<Object>(proxy);
162    } else {
163      if (session != null) {
164        try {
165          ShellCommand<?> cmd = session.getCommand(name);
166          if (cmd != null) {
167            return new PipeLineClosure(null, name, cmd);
168          }
169        } catch (CommandCreationException ignore) {
170          //
171        }
172        return super.getVariable(name);
173      } else {
174        return super.getVariable(name);
175      }
176    }
177  }
178}