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.io.Consumer;
024import org.crsh.shell.ScreenContext;
025import org.crsh.shell.ShellProcessContext;
026import org.crsh.text.Chunk;
027import org.crsh.text.ChunkAdapter;
028import org.crsh.text.ChunkBuffer;
029
030import java.io.Closeable;
031import java.io.IOException;
032import java.util.Map;
033
034class CRaSHProcessContext implements CommandContext<Object>, Closeable {
035
036  /** . */
037  private final CRaSHSession session;
038
039  /** . */
040  private final ShellProcessContext processContext;
041
042  /** . */
043  private final ChunkAdapter adapter;
044
045  /** . */
046  private boolean useAlternateBuffer;
047
048  CRaSHProcessContext(CRaSHSession session, final ShellProcessContext processContext) {
049
050    // We use this chunk buffer to buffer stuff
051    // but also because it optimises the chunks
052    // which provides better perormances on the client
053    final ChunkBuffer buffer = new ChunkBuffer(new Consumer<Chunk>() {
054      public void provide(Chunk element) throws IOException {
055        processContext.write(element);
056      }
057      public Class<Chunk> getConsumedType() {
058        return Chunk.class;
059      }
060      public void flush() throws IOException {
061        processContext.flush();
062      }
063    });
064
065    //
066    final ChunkAdapter adapter = new ChunkAdapter(new ScreenContext() {
067      public int getWidth() {
068        return processContext.getWidth();
069      }
070
071      public int getHeight() {
072        return processContext.getHeight();
073      }
074
075      public void write(Chunk chunk) throws IOException {
076        provide(chunk);
077      }
078
079      public Class<Chunk> getConsumedType() {
080        return Chunk.class;
081      }
082
083      public void provide(Chunk element) throws IOException {
084        buffer.provide(element);
085      }
086
087      public void flush() throws IOException {
088        buffer.flush();
089      }
090    });
091
092    //
093    this.session = session;
094    this.processContext = processContext;
095    this.adapter = adapter;
096    this.useAlternateBuffer = false;
097  }
098
099  public boolean isPiped() {
100    throw new UnsupportedOperationException();
101  }
102
103  public boolean takeAlternateBuffer() throws IOException {
104    return useAlternateBuffer = processContext.takeAlternateBuffer();
105  }
106
107  public boolean releaseAlternateBuffer() throws IOException {
108    return useAlternateBuffer = processContext.releaseAlternateBuffer();
109  }
110
111  public String getProperty(String propertyName) {
112    return processContext.getProperty(propertyName);
113  }
114
115  public String readLine(String msg, boolean echo) throws IOException, InterruptedException {
116    return processContext.readLine(msg, echo);
117  }
118
119  public int getWidth() {
120    return processContext.getWidth();
121  }
122
123  public int getHeight() {
124    return processContext.getHeight();
125  }
126
127  public Class<Object> getConsumedType() {
128    return Object.class;
129  }
130
131  public void write(Chunk chunk) throws IOException {
132    adapter.provide(chunk);
133  }
134
135  public void provide(Object element) throws IOException {
136    adapter.provide(element);
137  }
138
139  public void flush() throws IOException {
140    adapter.flush();
141  }
142
143  public Map<String, Object> getSession() {
144    return session;
145  }
146
147  public Map<String, Object> getAttributes() {
148    return session.crash.getContext().getAttributes();
149  }
150
151  public void close() throws IOException {
152    if (useAlternateBuffer) {
153      releaseAlternateBuffer();
154    }
155  }
156}