OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 25 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 /*
15
 * ExceptionHandler created on 7 mai 2004
16
 */
17
package org.openconcerto.utils;
18
 
19
import java.awt.Component;
20
import java.awt.Desktop;
21
import java.awt.Desktop.Action;
22
import java.awt.Dialog;
23
import java.awt.Dimension;
24
import java.awt.Font;
25
import java.awt.Frame;
26
import java.awt.GraphicsEnvironment;
27
import java.awt.GridBagConstraints;
28
import java.awt.GridBagLayout;
29
import java.awt.Insets;
30
import java.awt.Toolkit;
31
import java.awt.Window;
32
import java.awt.datatransfer.Clipboard;
33
import java.awt.datatransfer.StringSelection;
34
import java.awt.event.ActionEvent;
35
import java.awt.event.ActionListener;
36
import java.awt.event.WindowAdapter;
37
import java.awt.event.WindowEvent;
38
import java.net.URI;
39
import java.util.logging.Logger;
40
 
41
import javax.swing.AbstractAction;
42
import javax.swing.ImageIcon;
43
import javax.swing.JButton;
44
import javax.swing.JDialog;
45
import javax.swing.JLabel;
46
import javax.swing.JPanel;
47
import javax.swing.JScrollPane;
48
import javax.swing.JSeparator;
49
import javax.swing.JTextArea;
50
import javax.swing.ScrollPaneConstants;
51
import javax.swing.SwingUtilities;
52
import javax.swing.UIManager;
53
 
54
/**
55
 * Allow to display an exception both on the GUI and on the console.
56
 *
57
 * @author ILM Informatique 7 mai 2004
58
 */
59
public class ExceptionHandler extends RuntimeException {
60
 
61
    private static final String ILM_CONTACT = "http://www.ilm-informatique.fr/contact";
62
    private static String ForumURL = null;
63
 
64
    public static void setForumURL(String url) {
65
        ForumURL = url;
66
    }
67
 
68
    static private void copyToClipboard(final String s) {
69
        final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
70
        final StringSelection data = new StringSelection(s);
71
        clipboard.setContents(data, data);
72
    }
73
 
74
    static public RuntimeException handle(Component comp, String msg, Throwable originalExn) {
75
        return new ExceptionHandler(comp, msg, originalExn, false);
76
    }
77
 
78
    static public RuntimeException handle(String msg, Throwable originalExn) {
79
        return handle(null, msg, originalExn);
80
    }
81
 
82
    static public RuntimeException handle(String msg) {
83
        return handle(msg, null);
84
    }
85
 
86
    static public RuntimeException die(String msg, Throwable originalExn) {
87
        return new ExceptionHandler(null, msg, originalExn);
88
    }
89
 
90
    static public RuntimeException die(String msg) {
91
        return die(msg, null);
92
    }
93
 
94
    private static Logger getLogger() {
95
        return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
96
    }
97
 
98
    // the comp on which to display the popup, may be null
99
    private final Component comp;
100
    private static boolean forceUI;
101
 
102
    public static void setForceUI(boolean forceUI) {
103
        ExceptionHandler.forceUI = forceUI;
104
    }
105
 
106
    private void display(final boolean error) {
107
        final String msg = this.getMessage();
108
        if (error) {
109
            getLogger().severe(this.getTrace());
110
        } else {
111
            if (this.getCause() != null) {
112
                getLogger().info(this.getTrace());
113
            }
114
        }
115
        if (!GraphicsEnvironment.isHeadless() || forceUI) {
116
            if (SwingUtilities.isEventDispatchThread()) {
117
                showMsg(msg, error);
118
            } else
119
                SwingUtilities.invokeLater(new Runnable() {
120
                    public void run() {
121
                        showMsg(msg, error);
122
                    }
123
                });
124
        }
125
    }
126
 
127
    protected final void showMsg(final String msg, final boolean quit) {
128
        final JPanel p = new JPanel();
129
        p.setLayout(new GridBagLayout());
130
        final GridBagConstraints c = new GridBagConstraints();
131
        c.insets = new Insets(10, 10, 10, 10);
132
        c.gridx = 0;
133
        c.gridy = 0;
134
        c.fill = GridBagConstraints.BOTH;
135
        final JImage im = new JImage(new ImageIcon(this.getClass().getResource("error.png")));
136
        final JLabel l = new JLabel("Une erreur est survenue");
137
        l.setFont(l.getFont().deriveFont(Font.BOLD));
138
        final JLabel lError = new JLabel(msg);
139
 
140
        final JTextArea textArea = new JTextArea();
141
        textArea.setFont(textArea.getFont().deriveFont(11f));
142
 
143
        c.gridheight = 3;
144
        p.add(im, c);
145
        c.insets = new Insets(2, 4, 2, 4);
146
        c.gridheight = 1;
147
        c.gridx++;
148
        c.weightx = 1;
149
        c.gridwidth = 2;
150
        p.add(l, c);
151
        c.gridy++;
152
        p.add(lError, c);
153
 
154
        c.gridy++;
155
        p.add(new JLabel("Il s'agit probablement d'une mauvaise configuration ou installation du logiciel."), c);
156
 
157
        c.gridx = 0;
158
        c.gridwidth = 3;
159
        c.gridy++;
160
        c.weighty = 0;
161
        c.gridwidth = 1;
162
        c.gridx = 1;
163
        c.gridy++;
164
 
165
        c.fill = GridBagConstraints.NONE;
166
        c.anchor = GridBagConstraints.EAST;
167
        final Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
168
        final boolean browseSupported = desktop != null && desktop.isSupported(Action.BROWSE);
169
        if (ForumURL != null) {
170
            final javax.swing.Action communityAction;
171
            if (browseSupported) {
172
                communityAction = new AbstractAction("Consulter le forum") {
173
                    @Override
174
                    public void actionPerformed(ActionEvent e) {
175
                        try {
176
                            desktop.browse(new URI(ForumURL));
177
                        } catch (Exception e1) {
178
                            e1.printStackTrace();
179
                        }
180
                    }
181
                };
182
            } else {
183
                communityAction = new AbstractAction("Copier l'adresse du forum") {
184
                    @Override
185
                    public void actionPerformed(ActionEvent e) {
186
                        copyToClipboard(ForumURL);
187
                    }
188
                };
189
            }
190
            p.add(new JButton(communityAction), c);
191
        }
192
        c.weightx = 0;
193
        c.gridx++;
194
 
195
        final javax.swing.Action supportAction;
196
        if (browseSupported)
197
            supportAction = new AbstractAction("Contacter l'assistance") {
198
                @Override
199
                public void actionPerformed(ActionEvent e) {
200
                    try {
201
                        desktop.browse(URI.create(ILM_CONTACT));
202
                    } catch (Exception e1) {
203
                        e1.printStackTrace();
204
                    }
205
 
206
                }
207
            };
208
        else
209
            supportAction = new AbstractAction("Copier l'adresse de l'assistance") {
210
                @Override
211
                public void actionPerformed(ActionEvent e) {
212
                    copyToClipboard(ILM_CONTACT);
213
                }
214
            };
215
 
216
        p.add(new JButton(supportAction), c);
217
        c.gridy++;
218
        c.gridx = 0;
219
        c.gridwidth = 3;
220
        c.fill = GridBagConstraints.BOTH;
221
        c.insets = new Insets(0, 0, 0, 0);
222
        p.add(new JSeparator(), c);
223
 
224
        c.gridx = 0;
225
        c.gridwidth = 3;
226
        c.gridy++;
227
        c.insets = new Insets(2, 4, 2, 4);
228
        p.add(new JLabel("Détails de l'erreur:"), c);
229
        c.insets = new Insets(0, 0, 0, 0);
230
        c.gridy++;
231
        String message = this.getCause() == null ? null : this.getCause().getMessage();
232
        if (message == null) {
233
            message = msg;
234
        } else {
235
            message = msg + "\n\n" + message;
236
        }
237
        message += "\n";
238
        message += getTrace();
239
        textArea.setText(message);
240
        textArea.setEditable(false);
241
        // Scroll
242
        JScrollPane scroll = new JScrollPane(textArea);
243
        scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
244
        scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
245
        scroll.getViewport().setMinimumSize(new Dimension(200, 300));
246
        c.weighty = 1;
247
        c.gridwidth = 3;
248
        c.gridx = 0;
249
        c.gridy++;
250
        p.add(scroll, c);
251
 
252
        c.gridy++;
253
        c.fill = GridBagConstraints.NONE;
254
        c.weighty = 0;
255
        c.insets = new Insets(2, 4, 2, 4);
256
        final JButton buttonClose = new JButton("Fermer");
257
        p.add(buttonClose, c);
258
 
259
        final Window window = this.comp == null ? null : SwingUtilities.getWindowAncestor(this.comp);
260
        final JDialog f;
261
        if (window instanceof Frame) {
262
            f = new JDialog((Frame) window, "Erreur", true);
263
        } else {
264
            f = new JDialog((Dialog) window, "Erreur", true);
265
        }
266
        f.setContentPane(p);
267
        f.pack();
268
        f.setSize(580, 680);
269
        f.setMinimumSize(new Dimension(380, 380));
270
        f.setLocationRelativeTo(this.comp);
271
        final ActionListener al = new ActionListener() {
272
 
273
            @Override
274
            public void actionPerformed(ActionEvent e) {
275
                if (quit) {
276
                    System.exit(1);
277
                } else {
278
                    f.dispose();
279
                }
280
 
281
            }
282
        };
283
        buttonClose.addActionListener(al);
284
        // cannot set EXIT_ON_CLOSE on JDialog
285
        f.addWindowListener(new WindowAdapter() {
286
            @Override
287
            public void windowClosing(WindowEvent e) {
288
                al.actionPerformed(null);
289
            }
290
        });
291
        f.setVisible(true);
292
    }
293
 
294
    private String getTrace() {
295
        return ExceptionUtils.getStackTrace(this);
296
    }
297
 
298
    /**
299
     * Affiche l'erreur et quitte.
300
     *
301
     * @param comp the component upon which to display the popup.
302
     * @param msg le message d'erreur à afficher.
303
     * @param cause la cause de l'exception (peut être <code>null</code>).
304
     */
305
    private ExceptionHandler(Component comp, String msg, Throwable cause) {
306
        this(comp, msg, cause, true);
307
    }
308
 
309
    /**
310
     * Affiche l'erreur et quitte suivant l'option passée.
311
     *
312
     * @param comp the component upon which to display the popup.
313
     * @param msg the error message to display.
314
     * @param cause the cause of the exception (maybe <code>null</code>).
315
     * @param quit if the VM must exit.
316
     */
317
    private ExceptionHandler(Component comp, String msg, Throwable cause, boolean quit) {
318
        super(msg, cause);
319
        this.comp = comp;
320
        this.display(quit);
321
    }
322
 
323
    public static void main(String[] args) throws Exception {
324
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
325
        ExceptionHandler.handle("Fichier de configuration corrompu", new IllegalStateException("Id manquant"));
326
    }
327
}