001package com.ganteater.ae.desktop.view;
002
003import java.awt.BorderLayout;
004import java.awt.Color;
005import java.awt.Desktop;
006import java.awt.FileDialog;
007import java.awt.Font;
008import java.awt.event.ActionEvent;
009import java.awt.event.ActionListener;
010import java.awt.event.ComponentAdapter;
011import java.awt.event.ComponentEvent;
012import java.awt.event.KeyAdapter;
013import java.awt.event.KeyEvent;
014import java.awt.event.MouseAdapter;
015import java.awt.event.MouseEvent;
016import java.io.File;
017import java.io.FileOutputStream;
018import java.io.IOException;
019import java.io.PrintWriter;
020import java.io.StringReader;
021import java.io.StringWriter;
022import java.io.UnsupportedEncodingException;
023import java.net.URI;
024import java.net.URISyntaxException;
025import java.net.URL;
026import java.util.ArrayList;
027import java.util.List;
028import java.util.Map;
029import java.util.Set;
030
031import javax.swing.AbstractButton;
032import javax.swing.BorderFactory;
033import javax.swing.JButton;
034import javax.swing.JComboBox;
035import javax.swing.JComponent;
036import javax.swing.JOptionPane;
037import javax.swing.JPanel;
038import javax.swing.JScrollPane;
039import javax.swing.JTextArea;
040import javax.swing.JTextField;
041import javax.swing.ScrollPaneConstants;
042import javax.swing.SwingUtilities;
043import javax.swing.border.BevelBorder;
044import javax.swing.text.BadLocationException;
045import javax.swing.text.DefaultCaret;
046import javax.swing.text.Utilities;
047import javax.xml.XMLConstants;
048import javax.xml.transform.OutputKeys;
049import javax.xml.transform.Source;
050import javax.xml.transform.Transformer;
051import javax.xml.transform.TransformerFactory;
052import javax.xml.transform.stream.StreamResult;
053import javax.xml.transform.stream.StreamSource;
054
055import org.apache.commons.io.IOUtils;
056import org.apache.commons.lang.ArrayUtils;
057import org.apache.commons.lang.ObjectUtils;
058import org.apache.commons.lang.StringEscapeUtils;
059import org.apache.commons.lang.StringUtils;
060import org.apache.http.NameValuePair;
061import org.apache.http.client.utils.URLEncodedUtils;
062import org.apache.sling.commons.json.JSONObject;
063
064import com.ganteater.ae.desktop.editor.TaskEditor;
065import com.ganteater.ae.desktop.ui.AEFrame;
066import com.ganteater.ae.desktop.ui.TextPrompt;
067import com.ganteater.ae.desktop.view.ListLogPresenter.LogRecord;
068import com.ganteater.ae.processor.Processor;
069import com.ganteater.ae.util.AEUtils;
070
071public class TextLogPresenter extends LogPresenter {
072
073        private static final long serialVersionUID = 1L;
074
075        private static final int MAX_FORMAT_LENGTH = 10240;
076
077        private JTextArea fLogTextArea;
078
079        private JPanel toolBar = new JPanel(new BorderLayout());
080        private JTextField statusLineLable = new JTextField("");
081        private JButton emailMaskButton = new JButton(AEFrame.getIcon("email-mask.png"));
082        private JScrollPane fLogScrollPanel;
083
084        private List<String> supportedTypes = new ArrayList<>();
085        {
086                supportedTypes.add("txt");
087                supportedTypes.add("html");
088                supportedTypes.add("xml");
089                supportedTypes.add("json");
090                supportedTypes.add("~json");
091                supportedTypes.add("url");
092                supportedTypes.add("path");
093                supportedTypes.add("uri");
094                supportedTypes.add("csv");
095        }
096
097        private JTextField fFindText = new JTextField(12);
098
099        JButton formatButton = new JButton(AEFrame.getIcon("format.png"));
100
101        private Processor processor;
102
103        private FileDialog fileDialog;
104
105        private JComboBox<String> propertiesNames = new JComboBox<String>();
106
107        private JComboBox<String> typeBox = new JComboBox<>(supportedTypes.toArray(new String[supportedTypes.size()]));
108
109        private Object originData;
110
111        public TextLogPresenter(TaskEditor aTaskEditor, String aName) {
112                super(aName, aTaskEditor.getConfigNode());
113
114                fLogTextArea = new JTextArea();
115                DefaultCaret c = new DefaultCaret() {
116                        @Override
117                        public void setSelectionVisible(boolean visible) {
118                                super.setSelectionVisible(true);
119                        }
120                };
121                fLogTextArea.setCaret(c);
122
123                fLogTextArea.setFont(new Font("Courier New", Font.PLAIN, 12));
124                fLogTextArea.setEditable(true);
125                fLogTextArea.addKeyListener(new KeyAdapter() {
126                        @Override
127                        public void keyTyped(KeyEvent e) {
128                                printStatusLine();
129                        }
130                });
131
132                fLogTextArea.addMouseListener(new MouseAdapter() {
133                        @Override
134                        public void mouseReleased(MouseEvent e) {
135                                printStatusLine();
136                        }
137                });
138
139                fLogTextArea.addComponentListener(new ComponentAdapter() {
140                        @Override
141                        public void componentResized(ComponentEvent e) {
142                                if (fLogTextArea.getLineWrap()) {
143                                        printStatusLine();
144                                }
145                        }
146                });
147
148                fLogScrollPanel = new JScrollPane();
149                fLogScrollPanel.getViewport().add(fLogTextArea);
150
151                add(fLogScrollPanel, BorderLayout.CENTER);
152
153                formatButton.setToolTipText("Pretty print");
154
155                JPanel bar = new JPanel();
156                formatButton.addActionListener(new ActionListener() {
157                        public void actionPerformed(ActionEvent e) {
158                                format();
159                        }
160                });
161
162                bar.add(propertiesNames);
163                bar.add(typeBox);
164                bar.add(formatButton);
165
166                JButton button = new JButton(AEFrame.getIcon("placeholder.png"));
167                button.setToolTipText("Placeholder parsing");
168
169                button.addActionListener(new ActionListener() {
170                        public void actionPerformed(ActionEvent e) {
171                                String text = fLogTextArea.getText();
172                                try {
173                                        int caretPosition = fLogTextArea.getCaretPosition();
174                                        String replaceProperties = processor.replaceProperties(text);
175                                        replaceProperties = replaceProperties.replaceAll("<br/>", "\n");
176                                        // replaceProperties =
177                                        // EasyParser.replaseReferense(replaceProperties);
178                                        setText(replaceProperties);
179                                        printStatusLine();
180                                        fLogTextArea.setCaretPosition(0);
181                                        if (caretPosition < replaceProperties.length())
182                                                fLogTextArea.setCaretPosition(caretPosition);
183                                } catch (Exception e1) {
184                                        e1.printStackTrace();
185                                        JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(TextLogPresenter.this),
186                                                        "$...{} replacer failed.");
187                                }
188                        }
189                });
190
191                propertiesNames.addActionListener(new ActionListener() {
192                        public void actionPerformed(ActionEvent e) {
193                                print();
194                        }
195                });
196
197                bar.add(button);
198
199                button = new JButton(AEFrame.getIcon("open.png"));
200                button.setToolTipText("Open in defaulf editor");
201
202                button.addActionListener(new ActionListener() {
203                        public void actionPerformed(ActionEvent e) {
204                                try {
205                                        String selectedItem = (String) typeBox.getSelectedItem();
206                                        String text = fLogTextArea.getText();
207                                        openFile(text, selectedItem);
208                                } catch (IOException e1) {
209                                        JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(TextLogPresenter.this),
210                                                        "File opening failed.");
211                                }
212                        }
213
214                });
215                bar.add(button);
216
217                button = new JButton(AEFrame.getIcon("save.png"));
218                button.setToolTipText("Save to file");
219
220                button.addActionListener(new ActionListener() {
221                        public void actionPerformed(ActionEvent e) {
222                                saveToFile();
223                        }
224                });
225                bar.add(button);
226
227                emailMaskButton.setToolTipText("Masking");
228                emailMaskButton.setVisible(log.isFilterEnabled());
229
230                emailMaskButton.addActionListener(new ActionListener() {
231                        public void actionPerformed(ActionEvent e) {
232                                String text = fLogTextArea.getText();
233                                String maskedText = log.filter(text);
234                                setText(maskedText);
235                                printStatusLine();
236                                fLogTextArea.setCaretPosition(0);
237                        }
238                });
239                bar.add(emailMaskButton);
240
241                button = new JButton(AEFrame.getIcon("unescape.png"));
242                button.setToolTipText("Unescape");
243
244                button.addActionListener(new ActionListener() {
245                        public void actionPerformed(ActionEvent e) {
246                                String text = fLogTextArea.getText();
247                                text = StringEscapeUtils.unescapeXml(text).trim();
248                                text = text.replace("\\n", "\n");
249                                text = text.replace("\\r", "\r");
250                                text = text.replace("\\\"", "\"");
251                                setText(text);
252                        }
253
254                });
255                bar.add(button);
256
257                bar.add(fFindText);
258                new TextPrompt("Search", fFindText);
259
260                fFindText.addKeyListener(new KeyAdapter() {
261                        @Override
262                        public void keyPressed(KeyEvent e) {
263                                switch (e.getKeyChar()) {
264                                case KeyEvent.VK_ESCAPE:
265                                        fFindText.setText("");
266                                        break;
267
268                                case KeyEvent.VK_ENTER:
269                                        findText();
270                                }
271                        }
272                });
273
274                add(toolBar, BorderLayout.NORTH);
275
276                statusLineLable.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
277                statusLineLable.setEditable(false);
278                add(statusLineLable, BorderLayout.SOUTH);
279
280                fLogTextArea.setEditable(true);
281
282                toolBar.add(bar, BorderLayout.WEST);
283        }
284
285        public void saveToFile() {
286                try {
287                        String text = fLogTextArea.getText();
288
289                        text = filter(text);
290
291                        if (fileDialog == null)
292                                fileDialog = new FileDialog(JOptionPane.getRootFrame(), "Save log record.", FileDialog.SAVE);
293
294                        String type = getType();
295                        if (StringUtils.startsWith(type, "~")) {
296                                type = StringUtils.substringAfter(type, "~");
297                        }
298
299                        String fileName = StringUtils.defaultString(super.getName());
300
301                        if (StringUtils.isNotEmpty(type)) {
302                                fileName = fileName + "." + StringUtils.defaultString(type, "txt");
303                        }
304
305                        fileDialog.setFile(fileName);
306                        fileDialog.setVisible(true);
307                        if (fileDialog.getFile() != null) {
308                                File theFile = new File(fileDialog.getDirectory(), fileDialog.getFile());
309                                FileOutputStream theFileOutputStream = new FileOutputStream(theFile);
310                                theFileOutputStream.write(text.getBytes("UTF-8"));
311                                theFileOutputStream.close();
312                        }
313                } catch (Exception e1) {
314                        e1.printStackTrace();
315                        JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this), "File is not saved.");
316                }
317        }
318
319        protected void printStatusLine() {
320
321                String text = fLogTextArea.getText();
322                formatButton.setEnabled(text.length() < MAX_FORMAT_LENGTH);
323                int count = countLines(text);
324
325                if (fLogTextArea.getLineWrap() && text.length() < 100000) {
326                        int totalCharacters = fLogTextArea.getText().length();
327                        count = (totalCharacters == 0) ? 1 : 0;
328
329                        try {
330                                int offset = totalCharacters;
331                                while (offset > 0) {
332                                        offset = Utilities.getRowStart(fLogTextArea, offset) - 1;
333                                        count++;
334                                }
335                        } catch (BadLocationException e) {
336                                e.printStackTrace();
337                        }
338
339                        statusLineLable.setText("Lines: " + count + " (Wrapped)");
340
341                } else {
342                        int selectedCount = 0;
343                        String selectedText = fLogTextArea.getSelectedText();
344                        if (selectedText != null) {
345                                selectedCount = countLines(selectedText);
346                        }
347
348                        statusLineLable
349                                        .setText("Lines: " + count + (selectedCount > 0 ? "; Selected lines: " + selectedCount : ""));
350                }
351        }
352
353        private int countLines(String text) {
354                char someChar = '\n';
355                int count = 0;
356
357                if (text != null) {
358                        if (text.length() > 0) {
359                                count = 1;
360                        }
361
362                        for (int i = 0; i < text.length(); i++) {
363                                if (text.charAt(i) == someChar) {
364                                        count++;
365                                }
366                        }
367                }
368                return count;
369        }
370
371        public void info(Object o, Processor processor) {
372                this.processor = processor;
373                setType(o);
374                appendText(o);
375        }
376
377        public void format() {
378                SwingUtilities.invokeLater(() -> {
379                        String text = fLogTextArea.getText();
380                        if (text.length() < MAX_FORMAT_LENGTH) {
381
382                                String type = StringUtils.upperCase(getType());
383
384                                switch (type) {
385                                case "XML":
386                                        xmlPrettyPrint(text);
387                                        break;
388
389                                case "JSON":
390                                        try {
391                                                String jsonBody = StringUtils.trim(text);
392                                                setText(new JSONObject(jsonBody).toString(4));
393                                                printStatusLine();
394                                                fLogTextArea.setCaretPosition(0);
395
396                                        } catch (Exception e1) {
397                                                setText(text);
398                                                printStatusLine();
399                                                fLogTextArea.setCaretPosition(0);
400                                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this), "JSON formating failed.");
401                                        }
402                                        break;
403
404                                case "~JSON":
405                                        try {
406                                                setText(AEUtils.format(text));
407                                                printStatusLine();
408                                                fLogTextArea.setCaretPosition(0);
409                                        } catch (Exception e1) {
410                                                setText(text);
411                                                printStatusLine();
412                                                fLogTextArea.setCaretPosition(0);
413                                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this), "JSON formating failed.");
414                                        }
415                                        break;
416
417                                case "URL":
418                                        try {
419                                                StringBuilder formatedText = new StringBuilder();
420                                                String trim = text.replace(" ", "");
421                                                trim = trim.replace("\n", "");
422                                                URL url = new URL(trim);
423                                                formatedText.append(url.getProtocol() + "://");
424                                                formatedText.append(url.getHost());
425                                                if (url.getPort() > 0)
426                                                        formatedText.append(":" + url.getPort());
427                                                formatedText.append(url.getPath());
428
429                                                List<NameValuePair> parse = URLEncodedUtils.parse(url.toURI(), "UTF-8");
430                                                if (parse.size() > 0) {
431                                                        formatedText.append("\n");
432                                                        String delim = "?";
433                                                        for (NameValuePair nameValuePair : parse) {
434                                                                formatedText.append(
435                                                                                delim + nameValuePair.getName() + "=" + nameValuePair.getValue() + "\n");
436                                                                delim = "&";
437                                                        }
438                                                }
439                                                setText(formatedText.toString());
440                                                printStatusLine();
441                                                fLogTextArea.setCaretPosition(0);
442                                        } catch (Exception e1) {
443                                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this),
444                                                                "URI transformation failed.\n" + e1.getMessage());
445                                        }
446                                        break;
447
448                                case "TXT":
449                                        if (fLogTextArea.getText().length() < MAX_FORMAT_LENGTH) {
450                                                boolean wrap = !fLogTextArea.getLineWrap();
451                                                fLogScrollPanel
452                                                                .setHorizontalScrollBarPolicy(wrap ? ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
453                                                                                : ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
454
455                                                fLogTextArea.setLineWrap(wrap);
456                                        } else {
457                                                fLogTextArea.setLineWrap(false);
458                                        }
459                                        break;
460
461                                }
462                        }
463                        printStatusLine();
464                });
465        }
466
467        private void xmlPrettyPrint(String text) {
468                try {
469                        Source xmlInput = new StreamSource(new StringReader(text));
470                        StringWriter stringWriter = new StringWriter();
471                        StreamResult xmlOutput = new StreamResult(stringWriter);
472                        TransformerFactory transformerFactory = TransformerFactory.newInstance();
473                        transformerFactory.setAttribute("indent-number", 2);
474                        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
475                        transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
476                        Transformer transformer = transformerFactory.newTransformer();
477                        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
478                        transformer.transform(xmlInput, xmlOutput);
479
480                        setText(xmlOutput.getWriter().toString());
481                        printStatusLine();
482                        fLogTextArea.setCaretPosition(0);
483
484                } catch (Exception e1) {
485                        setText(text);
486                        printStatusLine();
487                        fLogTextArea.setCaretPosition(0);
488                        JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this), "XML formating failed.");
489                }
490        }
491
492        private void setText(String text) {
493                String trim = text.trim();
494                fLogTextArea.setText(trim);
495        }
496
497        protected void setType(Object o) {
498                String type = StringUtils.defaultString(((LogRecord) o).getType(), "txt");
499
500                if (o instanceof LogRecord) {
501                        if (((LogRecord) o).getMessage() instanceof String) {
502
503                                if (StringUtils.startsWith((String) ((LogRecord) o).getMessage(), "<?xml")) {
504                                        type = "xml";
505                                }
506
507                                type = StringUtils.defaultString(type, supportedTypes.get(0));
508                                if (!supportedTypes.contains(type.toLowerCase())) {
509                                        supportedTypes.add(type);
510                                        this.typeBox.addItem(type);
511                                }
512                                this.typeBox.setSelectedItem(type);
513
514                        } else if (StringUtils.isNotBlank(type)) {
515                                if (StringUtils.startsWith(ObjectUtils.toString(o), "<?xml")) {
516                                        type = "xml";
517                                        this.typeBox.setSelectedItem(type);
518                                } else {
519                                        this.typeBox.setSelectedItem(type);
520                                        if (!StringUtils.equals(this.typeBox.getSelectedItem().toString(), type)) {
521                                                this.typeBox.addItem(type);
522                                        }
523                                        this.typeBox.setSelectedItem(type);
524                                }
525                        }
526                }
527        }
528
529        private void setPropertiesList(Set keySet) {
530                for (Object object : keySet) {
531                        String key = (String) object;
532                        if (StringUtils.isNotBlank(key)) {
533                                propertiesNames.addItem(key);
534                        }
535                }
536                propertiesNames.setVisible(true);
537        }
538
539        private void cleanPropertiesList() {
540                propertiesNames.removeAllItems();
541                propertiesNames.setVisible(false);
542        }
543
544        @Override
545        public Object debug(Object o) {
546                setType(o);
547                if (o instanceof Throwable) {
548                        StringWriter theStringWriter = new StringWriter();
549                        ((Throwable) o).printStackTrace(new PrintWriter(theStringWriter));
550                        appendText(theStringWriter.toString());
551                } else {
552                        appendText(o);
553                }
554                return o;
555        }
556
557        @Override
558        public Object debug(Object o, Throwable aThrowable) {
559                print(o, aThrowable);
560                return o;
561        }
562
563        private void print(Object o, Throwable aThrowable) {
564                setType(o);
565                appendText(o);
566
567                if (aThrowable != null) {
568                        StringWriter theStringWriter = new StringWriter();
569                        aThrowable.printStackTrace(new PrintWriter(theStringWriter));
570                        appendText(theStringWriter.toString());
571                }
572        }
573
574        @Override
575        public Object error(Object o) {
576                print(o, null);
577                return o;
578        }
579
580        @Override
581        public Object error(Object o, Throwable aThrowable) {
582                print(o, aThrowable);
583                return o;
584        }
585
586        public Object warn(Object o) {
587                print(o, null);
588                return o;
589        }
590
591        private void appendText(Object o) {
592                this.originData = o;
593                cleanPropertiesList();
594
595                LogRecord record = (LogRecord) o;
596                String type = record.getType();
597
598                Object message = record.getMessage();
599                if (message instanceof Map && !"json".equals(type)) {
600                        Map propertiesData = (Map) ((LogRecord) o).getMessage();
601                        setPropertiesList(propertiesData.keySet());
602                }
603
604                print();
605        }
606
607        private void print() {
608                if (originData instanceof LogRecord) {
609                        LogRecord rec = (LogRecord) originData;
610                        Object data = rec.getMessage();
611
612                        String type = getType();
613                        if (data instanceof Map && "map".equals(type)) {
614                                data = ((Map) data).get(propertiesNames.getSelectedItem());
615                        }
616
617                        String text;
618
619                        if (data instanceof byte[]) {
620                                try {
621                                        text = new String((byte[]) data, "UTF-8");
622                                } catch (UnsupportedEncodingException e) {
623                                        throw new IllegalArgumentException(e);
624                                }
625                        } else if (data != null && data.getClass().isArray()) {
626                                Object[] array = (Object[]) data;
627                                text = ArrayUtils.toString(array);
628
629                        } else if (data != null && data instanceof List) {
630                                text = StringUtils.join((List) data, "\n");
631
632                        } else if ("json".equals(type)) {
633                                if (data instanceof Map) {
634                                        text = new JSONObject((Map) data).toString();
635                                } else {
636                                        text = ObjectUtils.toString(data, "<null>");
637                                }
638                        } else {
639                                text = ObjectUtils.toString(data, "<null>");
640                        }
641
642                        setText(text);
643
644                } else {
645
646                        setText(ObjectUtils.toString(originData));
647                }
648
649                fLogTextArea.setCaretPosition(0);
650                printStatusLine();
651        }
652
653        public String getType() {
654                return (String) TextLogPresenter.this.typeBox.getSelectedItem();
655        }
656
657        public void warn(Object o, Throwable aThrowable) {
658                print(o, aThrowable);
659        }
660
661        public void findText() {
662                String text = fFindText.getText();
663                String content = fLogTextArea.getText();
664                int caretPosition = fLogTextArea.getCaretPosition();
665
666                int indexOf = StringUtils.indexOfIgnoreCase(content, text, caretPosition);
667                if (indexOf >= 0) {
668                        fLogTextArea.setSelectionStart(indexOf);
669                        int selectionEnd = indexOf + text.length();
670                        fLogTextArea.setSelectionEnd(selectionEnd);
671
672                } else {
673                        caretPosition = 0;
674                        indexOf = StringUtils.indexOfIgnoreCase(content, text, caretPosition);
675
676                        if (indexOf >= 0) {
677                                fLogTextArea.setSelectionStart(indexOf);
678                                int selectionEnd = indexOf + text.length();
679                                fLogTextArea.setSelectionEnd(selectionEnd);
680
681                        } else {
682                                JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(this),
683                                                "Text: \"" + text + "\" is not found.");
684                        }
685                }
686
687        }
688
689        public void setEnabled(boolean enabled) {
690                if (enabled == false)
691                        fLogTextArea.setBackground(Color.lightGray);
692                else
693                        fLogTextArea.setBackground(Color.white);
694        }
695
696        public void clear() {
697                setText("");
698                printStatusLine();
699        }
700
701        public JComponent getLogTextArea() {
702                return fLogTextArea;
703        }
704
705        public static void openFile(Object originData, String type) throws IOException {
706
707                switch (StringUtils.upperCase(StringUtils.defaultString(type, "txt"))) {
708                case "URL":
709                        try {
710                                String string = ObjectUtils.toString(originData, "");
711                                URL url = new URL(string);
712                                URI uri = url.toURI();
713                                openWebpage(uri);
714                        } catch (URISyntaxException e) {
715                                new IOException(e);
716                        }
717                        break;
718
719                case "URI":
720                        try {
721                                openWebpage(new URI(ObjectUtils.toString(originData, "")));
722                        } catch (URISyntaxException e) {
723                                new IOException(e);
724                        }
725                        break;
726
727                case "PATH":
728                        Desktop.getDesktop().open(new File(ObjectUtils.toString(originData, "").trim()));
729                        break;
730
731                default:
732                        if (StringUtils.startsWith(type, "~")) {
733                                type = StringUtils.substringAfter(type, "~");
734                        }
735                        File file = File.createTempFile("anteater", "." + StringUtils.defaultString(type, "txt"));
736                        byte[] data;
737                        if (originData instanceof LogRecord) {
738                                Object logdata = ((LogRecord) originData).getMessage();
739                                if (logdata instanceof byte[]) {
740                                        data = (byte[]) logdata;
741                                } else {
742                                        data = ((LogRecord) originData).toString().getBytes();
743                                }
744                        } else {
745                                data = ObjectUtils.toString(originData).getBytes();
746                        }
747
748                        FileOutputStream output = new FileOutputStream(file);
749                        IOUtils.write(data, output);
750                        output.flush();
751                        Desktop.getDesktop().open(file);
752                        output.close();
753                }
754        }
755
756        public static void openWebpage(URI uri) {
757                Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
758                if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
759                        try {
760                                desktop.browse(uri);
761                        } catch (Exception e) {
762                                e.printStackTrace();
763                        }
764                }
765        }
766
767        public void addButton(AbstractButton onTop) {
768                toolBar.add(onTop, BorderLayout.EAST);
769        }
770
771        @Override
772        public LogPresenter copyAndClean() {
773                return null;
774        }
775
776        @Override
777        public boolean isFilterEnabled() {
778                return log.isFilterEnabled();
779        }
780
781        @Override
782        public String filter(Object message) {
783                return log.filter(message);
784        }
785}