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.Binding;
022    import org.crsh.command.CommandContext;
023    import org.crsh.shell.impl.command.spi.CommandCreationException;
024    import org.crsh.shell.impl.command.InvocationContextImpl;
025    import org.crsh.shell.impl.command.spi.ShellCommand;
026    import org.crsh.lang.groovy.closure.PipeLineClosure;
027    import org.crsh.repl.ReplSession;
028    import org.crsh.text.Chunk;
029    
030    import java.io.IOException;
031    import java.util.Map;
032    
033    /** @author Julien Viet */
034    class 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    }