source: contrib/MailArchiver/sources/src/serpro/mailarchiver/util/ConsoleMediator.java @ 6785

Revision 6785, 10.4 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/**
2 * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface.
3 * Copyright (C) 2012  Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/******************************************************************************\
20*
21*  This product was developed by
22*
23*        SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO),
24*
25*  a government company established under Brazilian law (5.615/70),
26*  at Department of Development of Porto Alegre.
27*
28\******************************************************************************/
29
30package serpro.mailarchiver.util;
31
32import java.io.ByteArrayOutputStream;
33import java.io.IOException;
34import java.io.PrintStream;
35import java.io.Reader;
36import java.io.UnsupportedEncodingException;
37import java.util.Set;
38import java.util.TreeSet;
39
40import javax.annotation.PostConstruct;
41
42import bsh.ConsoleInterface;
43
44import com.eventrouter.annotation.AnnotationProcessor;
45import com.eventrouter.annotation.Subscribe;
46import com.eventrouter.SubscriptionRegistry;
47
48import org.springframework.beans.factory.annotation.Configurable;
49
50import org.vaadin.console.Console;
51import org.vaadin.console.Console.Command;
52
53import serpro.mailarchiver.view.BaseApplication;
54
55@Configurable
56public class ConsoleMediator implements ConsoleInterface, Console.Handler {
57
58    private static final Logger log = Logger.getLocalLogger();
59
60    @PostConstruct
61    private void postConstruct() {
62        SubscriptionRegistry subscriptionRegistry = BaseApplication.getInstance().getDispatchContext().getSubscriptionRegistry();
63        AnnotationProcessor processor = new AnnotationProcessor(subscriptionRegistry);
64        processor.process(this);
65    }
66
67    private static final long serialVersionUID = 1L;
68
69    private static final String ENTER = System.getProperty("line.separator");
70    private static final String EOT = new String(new char[] {'\004'});
71    private static final String LF  = new String(new char[] {'\012'});
72    private static final String CR  = new String(new char[] {'\015'});
73    private static final String ESC = new String(new char[] {'\033'});
74
75    enum AnsiEsc {
76        Reset (0),
77
78        FontWeightBolder(1),
79        FontWeightNormal(22),
80        FontWeightLighter(2),
81        FontStyleItalic(3),
82
83        TextDecorationUnderline(4),
84        TextDecorationUnderlineOff(24),
85        TextDecorationBlinkSlow(5),
86        TextDecorationBlinkRapid(6),
87        TextDecorationBlinkOff(25),
88        TextDecorationLineThrough(9),
89        TextDecorationLineThroughOff(29),
90        TextDecorationOverline(53),
91        TextDecorationOverlineOff(55),
92
93        ColorBlack(30),
94        ColorRed(31),
95        ColorGreen(32),
96        ColorYellow(33),
97        ColorBlue(34),
98        ColorPurple(35),
99        ColorTeal(36),
100        ColorSilver(37),
101
102        BackgroundColorBlack(40),
103        BackgroundColorRed(41),
104        BackgroundColorGreen(42),
105        BackgroundColorYellow(43),
106        BackgroundColorBlue(44),
107        BackgroundColorPurple(45),
108        BackgroundColorTeal(46),
109        BackgroundColorSilver(47);
110
111        @Override
112        public String toString() {
113            return ESC + '[' + code + 'm';
114        }
115
116        private final int code;
117
118        AnsiEsc(int code) {
119            this.code = code;
120        }
121    }
122
123    private final Console console;
124
125    private MyReader interpreterIn;
126
127    private PrintStream interpreterOut;
128    private PrintStream interpreterErr;
129    private ByteArrayOutputStream interpreterOutByteArray;
130    private StringBuffer interpreterOutBuffer;
131
132    public ConsoleMediator(Console console) {
133
134        this.console = console;
135        this.console.setConvertANSIToCSS(true);
136        this.console.setHandler(this);
137
138        interpreterIn = new MyReader();
139
140        interpreterOutByteArray = new ByteArrayOutputStream();
141        interpreterOutBuffer = new StringBuffer();
142
143        try {
144            interpreterOut = new PrintStream(interpreterOutByteArray, false, "UTF-8") {
145                @Override
146                public void flush() {
147                    super.flush();
148                    appendOutput();
149                }
150            };
151            interpreterErr = new PrintStream(interpreterOutByteArray, false, "UTF-8") {
152                @Override
153                public void flush() {
154                    super.flush();
155                    appendOutput();
156                }
157            };
158        }
159        catch (UnsupportedEncodingException ex) {
160            log.error(ex);
161        }
162    }
163
164
165    //<editor-fold defaultstate="collapsed" desc=" Beanshell ConsoleInterface ">
166
167    @Override
168    public Reader getIn() {
169        return interpreterIn;
170    }
171
172    @Override
173    public PrintStream getOut() {
174        return interpreterOut;
175    }
176
177    @Override
178    public PrintStream getErr() {
179        return interpreterErr;
180    }
181
182    @Override
183    public void println(Object o) {
184        String s = String.valueOf(o);
185        interpreterOut.print(AnsiEsc.ColorYellow.toString() + s + ENTER);
186        interpreterOut.flush();
187    }
188
189    @Override
190    public void print(Object o) {
191        String s = String.valueOf(o);
192        if("bsh % ".equals(s)) {
193            interpreterOut.print(EOT);
194        }
195        else {
196            interpreterOut.print(AnsiEsc.ColorYellow.toString() + s);
197        }
198        interpreterOut.flush();
199    }
200
201    @Override
202    public void error(Object o) {
203        String s = String.valueOf(o);
204        if(s.endsWith(LF)) {
205            s = s.substring(0, s.length() - 1);
206            if(s.endsWith(CR)) {
207                s = s.substring(0, s.length() - 1);
208            }
209        }
210        interpreterErr.print(AnsiEsc.ColorRed.toString() + s);
211        interpreterErr.flush();
212    }
213    //</editor-fold>
214
215
216    //<editor-fold defaultstate="collapsed" desc=" Vaadin Console.Handler ">
217
218    /**
219     * Called when user has entered input to the Console and presses enter
220     * to execute it.
221     */
222    @Override
223    public void inputReceived(Console console, String lastInput) {
224        boolean run = false;
225        if(lastInput.isEmpty()) {
226            lastInput = ";";
227            run = true;
228        }
229        else {
230            for(int i = lastInput.length() - 1; i >= 0; i--) {
231                char c = lastInput.charAt(i);
232                if(Character.isSpaceChar(c)) {
233                    continue;
234                }
235                if(c == ';') {
236                    run = true;
237                }
238                break;
239            }
240        }
241
242        interpreterIn.put(lastInput + ENTER);
243
244        if(!run) {
245            console.setPs("> ");
246            console.prompt();
247            console.focusInput();
248        }
249    }
250
251
252    /**
253     * Called when user uses TAB to complete the command entered into the
254     * Console input.
255     */
256    @Override
257    public Set<String> getSuggestions(Console console, String lastInput) {
258        //TODO ?
259        Set<String> suggestions = new TreeSet<String>();
260        return suggestions;
261    }
262
263    /**
264     * Handle an exception during a Command execution.
265     */
266    @Override
267    public void handleException(Console console, Exception e, Command cmd, String[] argv) {
268        //TODO ?
269        log.error(e);
270    }
271
272    /**
273     * Handle situation where a command could not be found.
274     */
275    @Override
276    public void commandNotFound(Console console, String[] argv) {
277        //TODO ?
278    }
279    //</editor-fold>
280
281
282    private void appendOutput() {
283        if(interpreterOutByteArray.size() > 0) {
284            try {
285                String content = interpreterOutByteArray.toString("UTF-8");
286                interpreterOutByteArray.reset();
287                if(!content.isEmpty()) {
288                    interpreterOutBuffer.append(content);
289                }
290            }
291            catch (UnsupportedEncodingException ex) {
292                log.error(ex);
293            }
294        }
295    }
296
297    @Subscribe({"/mailarchiver/refresh"})
298    private void refresh() {
299        if(interpreterOutBuffer.length() > 0) {
300            String content = interpreterOutBuffer.toString();
301            interpreterOutBuffer.setLength(0);
302            boolean eot = false;
303            if(content.endsWith(EOT)) {
304                eot = true;
305                content = content.substring(0, content.length() - 1);
306                if(content.endsWith(LF)) {
307                    content = content.substring(0, content.length() - 1);
308                    if(content.endsWith(CR)) {
309                        content = content.substring(0, content.length() - 1);
310                    }
311                }
312            }
313
314            if(!content.isEmpty()) {
315                console.print(content);
316            }
317
318            if(eot) {
319                console.setPs("{bsh}> ");
320                console.prompt();
321                console.focusInput();
322            }
323        }
324    }
325
326    private static class MyReader extends Reader {
327        private final StringBuilder buffer = new StringBuilder();
328
329        public void put(String value) {
330            synchronized(buffer) {
331                buffer.append(value);
332                buffer.notifyAll();
333            }
334        }
335
336        @Override
337        public int read(char[] cbuf, int off, int len) throws IOException {
338            int n;
339            synchronized(buffer) {
340                while(buffer.length() == 0) {
341                    try {
342                        buffer.wait();
343                    }
344                    catch (InterruptedException ex) {
345                        log.error(ex);
346                    }
347                }
348                n = Math.min(len, buffer.length());
349                for(int i = 0; i < n; i++) {
350                    cbuf[off++] = buffer.charAt(i);
351                }
352                buffer.delete(0, n);
353            }
354            return n;
355        }
356
357        @Override
358        public void close() throws IOException {
359        }
360    }
361}
Note: See TracBrowser for help on using the repository browser.