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

Revision 6785, 15.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.bshcommands;
31
32import java.io.ByteArrayOutputStream;
33import java.io.PrintStream;
34import java.io.PrintWriter;
35import java.io.StringWriter;
36import java.io.UnsupportedEncodingException;
37
38import javax.annotation.PostConstruct;
39
40import bsh.CallStack;
41import bsh.EvalError;
42import bsh.Interpreter;
43import bsh.InterpreterError;
44import bsh.ParseException;
45import bsh.TargetError;
46
47import com.eventrouter.SubscriptionRegistry;
48import com.eventrouter.annotation.AnnotationProcessor;
49import com.eventrouter.annotation.Subscribe;
50
51import org.springframework.beans.factory.annotation.Configurable;
52
53import com.vaadin.event.LayoutEvents.LayoutClickEvent;
54import com.vaadin.event.LayoutEvents.LayoutClickListener;
55import com.vaadin.terminal.Sizeable;
56import com.vaadin.ui.ComponentContainer;
57import com.vaadin.ui.Label;
58import com.vaadin.ui.Panel;
59import com.vaadin.ui.VerticalLayout;
60import com.vaadin.ui.VerticalSplitPanel;
61import com.vaadin.ui.Window;
62import com.vaadin.ui.Window.CloseEvent;
63import com.vaadin.ui.Window.CloseListener;
64import com.vaadin.ui.themes.Reindeer;
65
66import org.vaadin.codeeditor.DefaultCodeEditor;
67import org.vaadin.codeeditor.frontend.ace.AceFrontEnd;
68import org.vaadin.peter.contextmenu.ContextMenu;
69import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItem;
70
71import serpro.mailarchiver.view.BaseApplication;
72import serpro.mailarchiver.view.admin.AdminConsoleApp;
73import serpro.mailarchiver.util.Logger;
74
75@Configurable
76public class scriptEditor {
77
78    private static final Logger log = Logger.getLocalLogger();
79
80    @PostConstruct
81    private void postConstruct() {
82        SubscriptionRegistry subscriptionRegistry = BaseApplication.getInstance().getDispatchContext().getSubscriptionRegistry();
83        AnnotationProcessor processor = new AnnotationProcessor(subscriptionRegistry);
84        processor.process(this);
85    }
86
87    private final Interpreter globalInterpreter;
88    private final CallStack callstack;
89
90    private Interpreter interpreter;
91
92    private PrintStream interpreterOut;
93    private ByteArrayOutputStream interpreterOutByteArray;
94    private StringBuffer interpreterOutBuffer;
95
96    private PrintStream interpreterErr;
97    private ByteArrayOutputStream interpreterErrByteArray;
98    private StringBuffer interpreterErrBuffer;
99
100    private Window mainWindow;
101    private Window window;
102    private VerticalSplitPanel split;
103    private EditorComponent editor;
104    private OutputComponent output;
105
106    private scriptEditor(Interpreter interpreter, CallStack callstack) {
107        this.globalInterpreter = interpreter;
108        this.callstack = callstack;
109    }
110
111    public static void invoke(Interpreter interpreter, CallStack callstack) {
112        new scriptEditor(interpreter, callstack).init();
113    }
114
115    @Subscribe({"/mailarchiver/refresh"})
116    private void refresh() {
117        if(interpreterOutBuffer.length() > 0) {
118            String content = interpreterOutBuffer.toString();
119            interpreterOutBuffer.setLength(0);
120            for(String line : content.split("\\r?\\n")) {
121                output.printLn(line);
122            }
123        }
124        if(interpreterErrBuffer.length() > 0) {
125            String content = interpreterErrBuffer.toString();
126            interpreterErrBuffer.setLength(0);
127            for(String line : content.split("\\r?\\n")) {
128                output.printErrLn(line);
129            }
130        }
131    }
132
133    private void init() {
134
135        mainWindow = AdminConsoleApp.getInstance().getMainWindow();
136
137        interpreter = new Interpreter();
138        interpreter.setNameSpace(globalInterpreter.getNameSpace());
139        interpreter.setStrictJava(false);
140
141        interpreterOutByteArray = new ByteArrayOutputStream();
142        interpreterOutBuffer = new StringBuffer();
143
144        try {
145            interpreterOut = new PrintStream(interpreterOutByteArray, false, "UTF-8") {
146                @Override
147                public void flush() {
148                    super.flush();
149                    if(interpreterOutByteArray.size() > 0) {
150                        try {
151                            String content = interpreterOutByteArray.toString("UTF-8");
152                            interpreterOutByteArray.reset();
153                            if(!content.isEmpty()) {
154                                interpreterOutBuffer.append(content);
155                            }
156                        }
157                        catch (UnsupportedEncodingException ex) {
158                            log.error(ex);
159                        }
160                    }
161                }
162            };
163        }
164        catch (UnsupportedEncodingException ex) {
165            log.error(ex);
166        }
167
168        interpreter.setOut(interpreterOut);
169
170        interpreterErrByteArray = new ByteArrayOutputStream();
171        interpreterErrBuffer = new StringBuffer();
172
173        try {
174            interpreterErr = new PrintStream(interpreterErrByteArray, false, "UTF-8") {
175                @Override
176                public void flush() {
177                    super.flush();
178                    if(interpreterErrByteArray.size() > 0) {
179                        try {
180                            String content = interpreterErrByteArray.toString("UTF-8");
181                            interpreterErrByteArray.reset();
182                            if(!content.isEmpty()) {
183                                interpreterErrBuffer.append(content);
184                            }
185                        }
186                        catch (UnsupportedEncodingException ex) {
187                            log.error(ex);
188                        }
189                    }
190                }
191            };
192        }
193        catch (UnsupportedEncodingException ex) {
194            log.error(ex);
195        }
196
197        interpreter.setErr(interpreterErr);
198
199        window = new Window("MailArchiver ScriptEditor");
200        window.setWidth(400, Sizeable.UNITS_PIXELS);
201        window.setHeight(300, Sizeable.UNITS_PIXELS);
202
203        split = new VerticalSplitPanel();
204        split.setSizeFull();
205
206        editor = new EditorComponent();
207        editor.setStyleName("script-editor");
208        editor.setMargin(false);
209        editor.setSpacing(false);
210        editor.setSizeFull();
211        split.addComponent(editor);
212
213        output = new OutputComponent();
214        output.setSizeFull();
215        split.addComponent(output);
216
217        window.setContent(split);
218
219        mainWindow.addWindow(window);
220
221        window.addListener(new CloseListener() {
222            @Override
223            public void windowClose(CloseEvent e) {
224                mainWindow.removeWindow(window);
225            }
226        });
227    }
228
229    private void eval(String script) {
230        StringWriter sw = new StringWriter();
231        try {
232            Object ret = interpreter.eval(script);
233
234            sw.append("Script result: ").append(String.valueOf(ret)).append("\n");
235            print(sw);
236        }
237        catch(ParseException e) {
238            sw.append("Parser error: ").append(e.toString()).append("\n");
239            stackTrace(sw, e);
240            printErr(sw);
241        }
242        catch(InterpreterError e) {
243            sw.append("Internal error: ").append(e.toString()).append("\n");
244            stackTrace(sw, e);
245            printErr(sw);
246        }
247        catch(TargetError e) {
248            sw.append("Uncaught exception: ").append(e.getTarget().toString()).append("\n");
249            if(e.inNativeCode()) {
250                stackTrace(sw, e.getTarget());
251            }
252            printErr(sw);
253        }
254        catch(EvalError e) {
255            sw.append("Eval error: ").append(e.toString()).append("\n");
256            stackTrace(sw, e);
257            printErr(sw);
258        }
259        catch(Exception e) {
260            sw.append("Unknown error: ").append(e.toString()).append("\n");
261            stackTrace(sw, e);
262            printErr(sw);
263        }
264    }
265
266    private void print(StringWriter sw) {
267        for(String line : sw.toString().split("\\r?\\n")) {
268            output.printLn(line);
269        }
270    }
271
272    private void printErr(StringWriter sw) {
273        for(String line : sw.toString().split("\\r?\\n")) {
274            output.printErrLn(line);
275        }
276    }
277
278    private void stackTrace(StringWriter sw, Throwable e) {
279        PrintWriter pw = new PrintWriter(sw);
280        e.printStackTrace(pw);
281        pw.flush();
282        sw.append("\n");
283    }
284
285    private class EditorComponent extends VerticalLayout {
286
287        private final DefaultCodeEditor codeEditor;
288
289        private final ContextMenu editorMenu;
290
291        private final ContextMenuItem editorEvalItem;
292        private final ContextMenuItem editorClearItem;
293        private final ContextMenuItem editorOpenItem;
294        private final ContextMenuItem editorSaveItem;
295
296        public EditorComponent() {
297
298            codeEditor = new DefaultCodeEditor();
299            AceFrontEnd frontEnd = new AceFrontEnd();
300            codeEditor.setFrontEnd(frontEnd);
301            codeEditor.setSizeFull();
302
303            addComponent(codeEditor);
304
305            editorMenu = new ContextMenu();
306
307            editorEvalItem = editorMenu.addItem("Eval");
308            editorClearItem = editorMenu.addItem("Clear");
309            editorOpenItem = editorMenu.addItem("Open");
310            editorSaveItem = editorMenu.addItem("Save");
311
312            addListener(new LayoutClickListener() {
313                @Override
314                public void layoutClick(LayoutClickEvent event) {
315                    if(LayoutClickEvent.BUTTON_RIGHT == event.getButton()) {
316                        window.focus();
317                        editorMenu.show(event.getClientX(), event.getClientY());
318                    }
319                }
320            });
321
322            editorMenu.addListener(new ContextMenu.ClickListener() {
323                @Override
324                public void contextItemClick(ContextMenu.ClickEvent event) {
325                    ContextMenuItem clickedItem = event.getClickedItem();
326
327                    if(clickedItem == editorEvalItem) {
328                        final String script = (String)codeEditor.getValue();
329                        new Thread() {
330                            @Override
331                            public void run() {
332                                eval(script);
333                            }
334                        }
335                        .start();
336                    }
337                    else if(clickedItem == editorClearItem) {
338                        clear();
339                    }
340                    else if(clickedItem == editorOpenItem) {
341                        open();
342                    }
343                    else if(clickedItem == editorSaveItem) {
344                        save();
345                    }
346                }
347            });
348
349            editorMenu.setVisible(false);
350
351            mainWindow.addComponent(editorMenu);
352        }
353
354        private void clear() {
355            codeEditor.setValue("");
356        }
357
358        private void open() {
359            System.out.println("TODO: editor open");
360        }
361
362        private void save() {
363            System.out.println("TODO: editor save");
364        }
365    }
366
367    private class OutputComponent extends Panel {
368
369        private final VerticalLayout layout;
370
371        private final ContextMenu outputMenu;
372
373        private final ContextMenuItem outputClearItem;
374        private final ContextMenuItem outputSaveItem;
375        private final ContextMenuItem outputWrapItem;
376        private final ContextMenuItem outputUnwrapItem;
377
378        public OutputComponent() {
379
380            setScrollable(true);
381            setStyleName(Reindeer.PANEL_LIGHT);
382
383            ComponentContainer container = this.getContent();
384            layout = (VerticalLayout) container;
385            layout.setWidth(Sizeable.SIZE_UNDEFINED, Sizeable.UNITS_PIXELS);
386
387            outputMenu = new ContextMenu();
388
389            outputClearItem = outputMenu.addItem("Clear");
390            outputSaveItem = outputMenu.addItem("Save");
391            outputWrapItem = outputMenu.addItem("Wrap");
392            outputUnwrapItem = outputMenu.addItem("Unwrap");
393            outputUnwrapItem.setVisible(false);
394
395            layout.addListener(new LayoutClickListener() {
396                @Override
397                public void layoutClick(LayoutClickEvent event) {
398                    if(LayoutClickEvent.BUTTON_RIGHT == event.getButton()) {
399                        window.focus();
400                        outputMenu.show(event.getClientX(), event.getClientY());
401                    }
402                }
403            });
404
405            outputMenu.addListener(new ContextMenu.ClickListener() {
406                @Override
407                public void contextItemClick(ContextMenu.ClickEvent event) {
408                    ContextMenuItem clickedItem = event.getClickedItem();
409
410                    if(clickedItem == outputClearItem) {
411                        clear();
412                    }
413                    else if(clickedItem == outputSaveItem) {
414                        save();
415                    }
416                    else if(clickedItem == outputWrapItem) {
417                        wrap();
418                    }
419                    else if(clickedItem == outputUnwrapItem) {
420                        unwrap();
421                    }
422                }
423            });
424
425            outputMenu.setVisible(false);
426
427            mainWindow.addComponent(outputMenu);
428
429            clear();
430        }
431
432        private void clear() {
433            removeAllComponents();
434        }
435
436        private void save() {
437            System.out.println("TODO: output save");
438        }
439
440        private void wrap() {
441            layout.setWidth("100%");
442
443            outputWrapItem.setVisible(false);
444            outputUnwrapItem.setVisible(true);
445
446            requestRepaint();
447        }
448
449        private void unwrap() {
450            layout.setWidth(Sizeable.SIZE_UNDEFINED, Sizeable.UNITS_PIXELS);
451
452            outputWrapItem.setVisible(true);
453            outputUnwrapItem.setVisible(false);
454
455            requestRepaint();
456        }
457
458        public void printLn(String s) {
459            Label line = new Label(s, Label.CONTENT_TEXT);
460            line.setStyleName("script-editor-output");
461            addComponent(line);
462        }
463
464        public void printErrLn(String s) {
465            Label line = new Label(s, Label.CONTENT_TEXT);
466            line.setStyleName("script-editor-output-error");
467            addComponent(line);
468        }
469    }
470}
Note: See TracBrowser for help on using the repository browser.