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
020package org.crsh.shell.impl.command;
021
022import org.crsh.command.CommandContext;
023import org.crsh.lang.impl.script.CommandNotFoundException;
024import org.crsh.shell.ErrorKind;
025import org.crsh.text.Screenable;
026import org.crsh.shell.impl.command.spi.CommandException;
027import org.crsh.lang.impl.script.Token;
028import org.crsh.text.ScreenContext;
029import org.crsh.lang.impl.script.PipeLineFactory;
030import org.crsh.shell.impl.command.spi.CommandInvoker;
031import org.crsh.text.RenderPrintWriter;
032import org.crsh.text.Style;
033
034import java.io.IOException;
035import java.util.Map;
036
037public final class InvocationContextImpl<P> extends AbstractInvocationContext<P> {
038
039  /** . */
040  private static final int WRITTEN = 0;
041
042  /** . */
043  private static final int FLUSHED = 1;
044
045  /** . */
046  private static final int CLOSED = 2;
047
048  /** . */
049  private final CommandContext<P> commandContext;
050
051  /** . */
052  private RenderPrintWriter writer;
053
054  /** . */
055  int status;
056
057  public InvocationContextImpl(CommandContext<P> commandContext) {
058    this.commandContext = commandContext;
059    this.status = FLUSHED;
060  }
061
062  public RenderPrintWriter getWriter() {
063    if (writer == null) {
064      writer = new RenderPrintWriter(new ScreenContext() {
065        public int getWidth() {
066          return InvocationContextImpl.this.getWidth();
067        }
068        public int getHeight() {
069          return InvocationContextImpl.this.getHeight();
070        }
071        public Screenable append(CharSequence s) throws IOException {
072          InvocationContextImpl.this.append(s);
073          return this;
074        }
075        public Appendable append(char c) throws IOException {
076          InvocationContextImpl.this.append(c);
077          return this;
078        }
079        public Appendable append(CharSequence csq, int start, int end) throws IOException {
080          InvocationContextImpl.this.append(csq, start, end);
081          return this;
082        }
083        public Screenable append(Style style) throws IOException {
084          InvocationContextImpl.this.append(style);
085          return this;
086        }
087        public Screenable cls() throws IOException {
088          InvocationContextImpl.this.cls();
089          return this;
090        }
091        public void flush() throws IOException {
092          InvocationContextImpl.this.flush();
093        }
094      });
095    }
096    return writer;
097  }
098
099  public boolean takeAlternateBuffer() throws IOException {
100    return commandContext.takeAlternateBuffer();
101  }
102
103  public boolean releaseAlternateBuffer() throws IOException {
104    return commandContext.releaseAlternateBuffer();
105  }
106
107  public CommandInvoker<?, ?> resolve(String s) throws CommandException {
108    CRaSHSession session = (CRaSHSession)getSession();
109    Token token2 = Token.parse(s);
110    try {
111      PipeLineFactory factory = token2.createFactory();
112      return factory.create(session);
113    }
114    catch (CommandNotFoundException e) {
115      throw new CommandException(ErrorKind.SYNTAX, e.getMessage(), e);
116    }
117  }
118
119  public Class<P> getConsumedType() {
120    return commandContext.getConsumedType();
121  }
122
123  public String getProperty(String propertyName) {
124    return commandContext.getProperty(propertyName);
125  }
126
127  public String readLine(String msg, boolean echo) throws IOException, InterruptedException {
128    return commandContext.readLine(msg, echo);
129  }
130
131  public int getWidth() {
132    return commandContext.getWidth();
133  }
134
135  public int getHeight() {
136    return commandContext.getHeight();
137  }
138
139  public Screenable append(CharSequence s) throws IOException {
140    if (status != CLOSED) {
141      status = WRITTEN;
142      commandContext.append(s);
143    }
144    return this;
145  }
146
147  public Screenable append(char c) throws IOException {
148    if (status != CLOSED) {
149      status = WRITTEN;
150      commandContext.append(c);
151    }
152    return this;
153  }
154
155  public Screenable append(CharSequence csq, int start, int end) throws IOException {
156    if (status != CLOSED) {
157      status = WRITTEN;
158      commandContext.append(csq, start, end);
159    }
160    return this;
161  }
162
163  public Screenable append(Style style) throws IOException {
164    if (status != CLOSED) {
165      status = WRITTEN;
166      commandContext.append(style);
167    }
168    return this;
169  }
170
171  public Screenable cls() throws IOException {
172    if (status != CLOSED) {
173      status = WRITTEN;
174      commandContext.cls();
175    }
176    return this;
177  }
178
179  public void provide(P element) throws Exception {
180    if (status != CLOSED) {
181      status = WRITTEN;
182      commandContext.provide(element);
183    }
184  }
185
186  public void flush() throws IOException {
187    if (status == WRITTEN) {
188      status = FLUSHED;
189      commandContext.flush();
190    }
191  }
192
193  public void close() throws Exception {
194    if (status != CLOSED) {
195      try {
196        flush();
197      }
198      catch (Exception e) {
199        // Ignore ?
200      }
201      status = CLOSED;
202      commandContext.close();
203    }
204  }
205
206  public Map<String, Object> getSession() {
207    return commandContext.getSession();
208  }
209
210  public Map<String, Object> getAttributes() {
211    return commandContext.getAttributes();
212  }
213}