OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 177 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
18 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
 package org.openconcerto.erp.panel;
15
 
83 ilm 16
import org.openconcerto.erp.action.SauvegardeBaseAction;
18 ilm 17
import org.openconcerto.erp.config.ComptaPropsConfiguration;
18
import org.openconcerto.erp.config.Gestion;
83 ilm 19
import org.openconcerto.erp.config.GestionLauncher;
67 ilm 20
import org.openconcerto.erp.modules.ModuleManager;
18 ilm 21
import org.openconcerto.erp.preferences.BackupNXProps;
22
import org.openconcerto.sql.Configuration;
83 ilm 23
import org.openconcerto.sql.users.rights.UserRightsManager;
18 ilm 24
import org.openconcerto.sql.utils.BackupPanel;
25
import org.openconcerto.ui.DefaultGridBagConstraints;
21 ilm 26
import org.openconcerto.ui.UserExit;
80 ilm 27
import org.openconcerto.utils.ExceptionHandler;
28
import org.openconcerto.utils.ProcessStreams;
29
import org.openconcerto.utils.prog.VMLauncher;
18 ilm 30
 
65 ilm 31
import java.awt.Frame;
18 ilm 32
import java.awt.GridBagConstraints;
33
import java.awt.GridBagLayout;
34
import java.awt.Insets;
35
import java.awt.Window;
36
import java.awt.event.ActionEvent;
37
import java.awt.event.ActionListener;
38
import java.awt.event.WindowAdapter;
39
import java.awt.event.WindowEvent;
65 ilm 40
import java.util.Set;
80 ilm 41
import java.util.concurrent.atomic.AtomicBoolean;
18 ilm 42
 
83 ilm 43
import javax.swing.AbstractAction;
18 ilm 44
import javax.swing.JButton;
45
import javax.swing.JDialog;
46
import javax.swing.JFrame;
47
import javax.swing.JLabel;
48
import javax.swing.JPanel;
49
import javax.swing.SwingUtilities;
50
 
51
public class UserExitPanel extends JPanel {
52
 
80 ilm 53
    static private final AtomicBoolean CLOSING = new AtomicBoolean(false);
54
 
55
    static public final boolean isClosing() {
56
        return CLOSING.get();
57
    }
58
 
59
    private final UserExitConf conf;
60
 
61
    public UserExitPanel(final UserExitConf conf) {
62
        if (conf == null)
63
            throw new NullPointerException("Null conf");
64
        this.conf = conf;
18 ilm 65
        this.setLayout(new GridBagLayout());
66
        final GridBagConstraints c = new DefaultGridBagConstraints();
67
        c.anchor = GridBagConstraints.CENTER;
68
        c.insets = new Insets(2, 2, 5, 2);
69
        c.weightx = 1;
70
        c.gridwidth = 2;
71
 
80 ilm 72
        String text = "Voulez-vous vraiment " + (this.conf.shouldRestart() ? "relancer " : "quitter ") + Configuration.getInstance().getAppName() + " ?";
73
        if (this.conf.getMessage() != null) {
74
            text = this.conf.getMessage() + "<br/>" + text;
75
        }
76
        final JLabel labelQuit = new JLabel("<html>" + text + "</html>");
18 ilm 77
        JButton buttonCancel = new JButton("Annuler");
80 ilm 78
        final String verb = this.conf.shouldRestart() ? "Relancer" : "Quitter";
79
        JButton buttonExit = new JButton(verb);
18 ilm 80
        this.add(labelQuit, c);
81
 
82
        c.gridy++;
83
        c.fill = GridBagConstraints.NONE;
84
        c.gridwidth = 1;
85
        this.add(buttonExit, c);
86
        final ComptaPropsConfiguration comptaPropsConfiguration = (ComptaPropsConfiguration) Configuration.getInstance();
83 ilm 87
            final javax.swing.Action backupAction = createBackupAction(verb);
88
            if (backupAction != null && comptaPropsConfiguration.getRowSociete() != null) {
18 ilm 89
                c.gridx++;
83 ilm 90
                this.add(new JButton(backupAction), c);
18 ilm 91
            }
92
        c.gridx++;
93
        this.add(buttonCancel, c);
94
        buttonCancel.addActionListener(new ActionListener() {
95
            public void actionPerformed(ActionEvent arg0) {
96
                // not use getRoot if frame is Jdialog modal, not return the jdialog but the root of
97
                // jdialog
98
                SwingUtilities.getWindowAncestor(UserExitPanel.this).dispose();
99
            }
100
        });
101
 
102
        final ActionListener listenerExit = new ActionListener() {
103
            public void actionPerformed(ActionEvent arg0) {
104
 
105
                closeGNx();
106
            }
107
 
108
        };
109
 
83 ilm 110
        buttonExit.addActionListener(listenerExit);
111
    }
18 ilm 112
 
83 ilm 113
    protected javax.swing.Action createBackupAction(final String verb) {
114
        if (!UserRightsManager.getCurrentUserRights().haveRight(BackupPanel.RIGHT_CODE))
115
            return null;
116
        return new AbstractAction("Sauvegarder et " + verb.toLowerCase()) {
117
 
18 ilm 118
            @Override
119
            public void actionPerformed(ActionEvent e) {
120
                JDialog frame = new JDialog();
83 ilm 121
                frame.setContentPane(new BackupPanel(null, SauvegardeBaseAction.getDirs(), false, BackupNXProps.getInstance()) {
18 ilm 122
                    @Override
123
                    public void doOnClose() {
124
                        super.doOnClose();
125
                        closeGNx();
126
                    }
127
                });
128
                frame.setTitle("Sauvegarde des données");
129
                // so that the application can exit
130
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
131
                // ATTN works because BackupPanel do not open a new window when doing backup
132
                frame.addWindowListener(new WindowAdapter() {
133
                    @Override
134
                    public void windowClosed(WindowEvent e) {
135
                        startTimeOut();
136
                    }
137
                });
138
                frame.setLocationRelativeTo(null);
139
                frame.pack();
140
                frame.setMinimumSize(frame.getSize());
141
 
142
                ((Window) SwingUtilities.getRoot(UserExitPanel.this)).dispose();
143
                frame.setModal(true);
144
                frame.setIconImages(Gestion.getFrameIcon());
145
                frame.setAlwaysOnTop(true);
146
                frame.setVisible(true);
147
            }
83 ilm 148
        };
18 ilm 149
    }
150
 
149 ilm 151
    private void closeGNx() {
152
        exit(this.conf);
153
    }
18 ilm 154
 
149 ilm 155
    static public void exit(final UserExitConf c) {
80 ilm 156
        assert SwingUtilities.isEventDispatchThread();
157
        if (!CLOSING.compareAndSet(false, true)) {
158
            // already closing
159
            return;
160
        }
21 ilm 161
        UserExit.closeAllWindows(null);
80 ilm 162
        try {
163
            // add shutdown hook first, since the user already agreed to restart
164
            Runtime.getRuntime().addShutdownHook(new Thread() {
165
                @Override
166
                public void run() {
167
                    try {
168
                        // MAYBE only run beforeShutdown() if afterWindowsClosed() is successful
169
                        c.beforeShutdown();
170
 
83 ilm 171
                        if (c.shouldRestart())
177 ilm 172
                            VMLauncher.restart(ProcessStreams.DISCARD, GestionLauncher.class);
80 ilm 173
                    } catch (Exception e) {
174
                        // in shutdown sequence : don't use the GUI
175
                        e.printStackTrace();
176
                    }
177
                }
178
            });
179
            c.afterWindowsClosed();
83 ilm 180
            ModuleManager.tearDown();
181
            ComptaPropsConfiguration.closeOOConnexion();
80 ilm 182
        } catch (Exception exn) {
183
            // all windows already closed
184
            ExceptionHandler.handle("Erreur lors de la fermeture", exn);
185
        }
18 ilm 186
        // ((JFrame) SwingUtilities.getRoot(UserExitingPanel.this)).dispose();
187
        if (Gestion.pgFrameStart != null) {
188
            Gestion.pgFrameStart.setVisible(false);
189
        }
190
        new Thread() {
149 ilm 191
 
83 ilm 192
            @Override
18 ilm 193
            public void run() {
194
                try {
83 ilm 195
                    Configuration.getInstance().destroy();
18 ilm 196
 
156 ilm 197
                    ComptaPropsConfiguration.getInstanceCompta().tearDownLogging(true);
18 ilm 198
                } finally {
182 ilm 199
 
18 ilm 200
                    startTimeOut();
201
                    // System.exit(0);
202
                }
203
            }
204
        }.start();
205
    }
206
 
207
    // (especially important with embedded h2, since the database is locked)
149 ilm 208
    static private final void startTimeOut() {
18 ilm 209
        final Thread timeOut = new Thread(new Runnable() {
210
            @Override
211
            public void run() {
212
                try {
41 ilm 213
                    // 5 s d'attente
67 ilm 214
                    // TODO make ModuleManager.install() atomic
41 ilm 215
                    Thread.sleep(5 * 1000);
18 ilm 216
                    System.err.println("Warning: Forcing exit");
65 ilm 217
                    Frame[] l = Frame.getFrames();
218
                    for (int i = 0; i < l.length; i++) {
219
                        Frame f = l[i];
83 ilm 220
                        System.err.println("Frame " + f.getName() + " " + f + " Displayable: " + f.isDisplayable() + " Valid: " + f.isValid() + " Active: " + f.isActive());
65 ilm 221
                    }
222
                    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
223
                    for (Thread thread : threadSet) {
224
                        if (!thread.isDaemon()) {
83 ilm 225
                            System.err.println("Thread " + thread.getName() + " " + thread.getId() + " not daemon");
65 ilm 226
                        }
227
                    }
83 ilm 228
                } catch (Throwable e) {
18 ilm 229
                    e.printStackTrace();
230
                }
83 ilm 231
                try {
232
                    Configuration.getInstance().destroy();
156 ilm 233
                    ComptaPropsConfiguration.getInstanceCompta().tearDownLogging(true);
83 ilm 234
                } catch (Throwable e) {
235
                    e.printStackTrace();
236
                }
237
 
18 ilm 238
                // Dans tous les cas, on arrete le programme
239
                System.exit(1);
240
            }
241
        });
242
        timeOut.setName("TimeOut Thread");
243
        timeOut.setDaemon(true);
244
        timeOut.start();
245
    }
246
}