OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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