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