001    /*
002     * Copyright (C) 2003-2009 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    
020    package org.crsh.shell;
021    
022    import org.crsh.text.CharReader;
023    
024    import java.io.Serializable;
025    import java.util.Collections;
026    
027    /**
028     * The response of a shell invocation.
029     *
030     * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
031     * @version $Revision$
032     */
033    public abstract class ShellResponse implements Serializable {
034    
035      public static UnknownCommand unknownCommand(String name) {
036        return new UnknownCommand(name);
037      }
038    
039      public static NoCommand noCommand() {
040        return NoCommand.INSTANCE;
041      }
042    
043      public static Ok ok(Iterable<?> produced) {
044        return new Ok(produced);
045      }
046    
047      public static Ok ok() {
048        return new Ok();
049      }
050    
051      public static Display display(String text) {
052        return new Display(new CharReader(text));
053      }
054    
055      public static Display display(CharReader reader) {
056        return new Display(reader);
057      }
058    
059      public static Display display(Iterable<?> produced, CharReader reader) {
060        return new Display(produced, reader);
061      }
062    
063      public static Error evalError(String msg, Throwable throwable) {
064        return new Error(ErrorType.EVALUATION, msg, throwable);
065      }
066    
067      public static Error evalError(String msg) {
068        return new Error(ErrorType.EVALUATION, msg);
069      }
070    
071      public static Error internalError(String msg, Throwable throwable) {
072        return new Error(ErrorType.INTERNAL, msg, throwable);
073      }
074    
075      public static Error internalError(String msg) {
076        return new Error(ErrorType.INTERNAL, msg);
077      }
078    
079      public static Error error(ErrorType type, String msg, Throwable throwable) {
080        return new Error(type, msg, throwable);
081      }
082    
083      public static Error error(ErrorType type, String msg) {
084        return new Error(type, msg);
085      }
086    
087      public static Cancelled cancelled() {
088        return Cancelled.INSTANCE;
089      }
090    
091      public static Close close() {
092        return Close.INSTANCE;
093      }
094    
095      public abstract CharReader getReader();
096    
097      public static class UnknownCommand extends ShellResponse {
098    
099        /** . */
100        private final String name;
101    
102        private UnknownCommand(String name) {
103          this.name = name;
104        }
105    
106        public String getName() {
107          return name;
108        }
109    
110        @Override
111        public CharReader getReader() {
112          return new CharReader(name + ": command not found");
113        }
114    
115        @Override
116        public String toString() {
117          return "UnknownCommand[" + name + "]";
118        }
119      }
120    
121      public static class NoCommand extends ShellResponse {
122    
123        /** . */
124        private static final NoCommand INSTANCE = new NoCommand();
125    
126        private NoCommand() {
127        }
128    
129        @Override
130        public CharReader getReader() {
131          return new CharReader("Please type something");
132        }
133      }
134    
135      public static class Close extends ShellResponse {
136    
137        /** . */
138        private static final Close INSTANCE = new Close();
139    
140        private Close() {
141        }
142    
143        @Override
144        public CharReader getReader() {
145          return new CharReader("Have a good day!\r\n");
146        }
147      }
148    
149      /**
150       * Command execution is terminated.
151       */
152      public static class Ok extends ShellResponse {
153    
154        /** . */
155        private final transient Iterable<?> produced;
156    
157        private Ok() {
158          this(Collections.<Object>emptyList());
159        }
160    
161        private Ok(Iterable<?> produced) {
162          this.produced = produced;
163        }
164    
165        public Iterable<?> getProduced() {
166          return produced;
167        }
168    
169        @Override
170        public CharReader getReader() {
171          return new CharReader("");
172        }
173      }
174    
175      public static class Display extends Ok {
176    
177        /** . */
178        private final CharReader reader;
179    
180        private Display(CharReader reader) {
181          this.reader = reader;
182        }
183    
184        private Display(Iterable<?> produced, CharReader reader) {
185          super(produced);
186    
187          //
188          this.reader = reader;
189        }
190    
191        @Override
192        public boolean equals(Object obj) {
193          if (obj == this) {
194            return true;
195          }
196          if (obj instanceof Display) {
197            Display that = (Display)obj;
198            return reader.equals(that.reader);
199          }
200          return false;
201        }
202    
203        @Override
204        public CharReader getReader() {
205          return reader;
206        }
207      }
208    
209      public static class Cancelled extends ShellResponse {
210    
211        /** . */
212        private static final Cancelled INSTANCE = new Cancelled();
213    
214        private Cancelled() {
215        }
216    
217        @Override
218        public CharReader getReader() {
219          return new CharReader("cancelled");
220        }
221      }
222    
223      public static class Error extends ShellResponse {
224    
225        /** . */
226        private final ErrorType type;
227    
228        /** . */
229        private final Throwable throwable;
230    
231        /** . */
232        private final String msg;
233    
234        private Error(ErrorType type, String msg) {
235          this.type = type;
236          this.msg = msg;
237          this.throwable = null;
238        }
239    
240        private Error(ErrorType type, String msg, Throwable throwable) {
241          this.type = type;
242          this.msg = msg;
243          this.throwable = throwable;
244        }
245    
246        public ErrorType getType() {
247          return type;
248        }
249    
250        public Throwable getThrowable() {
251          return throwable;
252        }
253    
254        @Override
255        public CharReader getReader() {
256          return new CharReader(msg);
257        }
258    
259        public String toString() {
260          return "ShellResponse.Error[type=" + type + ",msg=" + msg + "]";
261        }
262      }
263    }