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.shell;
020    
021    import groovy.lang.Binding;
022    import org.crsh.command.CommandContext;
023    import org.crsh.command.InvocationContextImpl;
024    import org.crsh.command.NoSuchCommandException;
025    import org.crsh.command.ShellCommand;
026    import org.crsh.lang.groovy.closure.PipeLineClosure;
027    import org.crsh.shell.impl.command.CRaSH;
028    import org.crsh.text.Chunk;
029    
030    import java.io.IOException;
031    import java.util.Map;
032    
033    /** @author Julien Viet */
034    public 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 (NoSuchCommandException ignore) {
165              //
166            }
167            return super.getVariable(name);
168          } else {
169            return super.getVariable(name);
170          }
171        }
172      }
173    }