OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 151 | Rev 174 | Go to most recent revision | 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.config;
15
 
156 ilm 16
import static java.lang.System.getProperty;
17
 
18 ilm 18
import org.openconcerto.erp.action.NouvelleConnexionAction;
19
import org.openconcerto.erp.core.common.ui.PanelFrame;
20
import org.openconcerto.erp.panel.PostgreSQLFrame;
80 ilm 21
import org.openconcerto.erp.panel.UserExitConf;
18 ilm 22
import org.openconcerto.erp.panel.UserExitPanel;
41 ilm 23
import org.openconcerto.erp.preferences.UIPreferencePanel;
73 ilm 24
import org.openconcerto.erp.rights.ComptaTotalUserRight;
18 ilm 25
import org.openconcerto.ftp.updater.UpdateManager;
26
import org.openconcerto.sql.Configuration;
27
import org.openconcerto.sql.PropsConfiguration;
73 ilm 28
import org.openconcerto.sql.RemoteShell;
18 ilm 29
import org.openconcerto.sql.element.UISQLComponent;
19 ilm 30
import org.openconcerto.sql.model.SQLBase;
80 ilm 31
import org.openconcerto.sql.model.SQLDataSource;
18 ilm 32
import org.openconcerto.sql.model.SQLRequestLog;
142 ilm 33
import org.openconcerto.sql.model.SQLRowAccessor;
80 ilm 34
import org.openconcerto.sql.model.SQLSystem;
142 ilm 35
import org.openconcerto.sql.request.BaseFillSQLRequest;
18 ilm 36
import org.openconcerto.sql.request.ComboSQLRequest;
37
import org.openconcerto.sql.sqlobject.ElementComboBox;
80 ilm 38
import org.openconcerto.sql.sqlobject.IComboSelectionItem;
83 ilm 39
import org.openconcerto.sql.ui.SoftwareInfoPanel;
73 ilm 40
import org.openconcerto.sql.users.rights.UserRightsManager;
156 ilm 41
import org.openconcerto.sql.utils.ReOrder;
80 ilm 42
import org.openconcerto.sql.view.EditPanel;
156 ilm 43
import org.openconcerto.sql.view.IListFrame;
18 ilm 44
import org.openconcerto.sql.view.list.IListe;
45
import org.openconcerto.ui.FrameUtil;
80 ilm 46
import org.openconcerto.ui.component.ITextCombo;
18 ilm 47
import org.openconcerto.ui.component.WaitIndeterminatePanel;
41 ilm 48
import org.openconcerto.ui.preferences.EmailProps;
80 ilm 49
import org.openconcerto.utils.CompareUtils;
18 ilm 50
import org.openconcerto.utils.ExceptionHandler;
51
import org.openconcerto.utils.FileUtils;
144 ilm 52
import org.openconcerto.utils.ThrowableHandler;
18 ilm 53
import org.openconcerto.utils.protocol.Helper;
54
 
55
import java.awt.AWTEvent;
56
import java.awt.Component;
156 ilm 57
import java.awt.Desktop;
18 ilm 58
import java.awt.Image;
59
import java.awt.SplashScreen;
60
import java.awt.Toolkit;
61
import java.awt.event.AWTEventListener;
62
import java.awt.event.HierarchyEvent;
63
import java.awt.event.WindowAdapter;
64
import java.awt.event.WindowEvent;
151 ilm 65
import java.beans.PropertyChangeEvent;
66
import java.beans.PropertyChangeListener;
18 ilm 67
import java.io.BufferedReader;
144 ilm 68
import java.io.ByteArrayOutputStream;
18 ilm 69
import java.io.File;
156 ilm 70
import java.io.FileInputStream;
71
import java.io.FileOutputStream;
18 ilm 72
import java.io.IOException;
73
import java.io.InputStreamReader;
144 ilm 74
import java.io.PrintStream;
28 ilm 75
import java.lang.Thread.UncaughtExceptionHandler;
18 ilm 76
import java.net.InetAddress;
77
import java.net.NetworkInterface;
156 ilm 78
import java.net.URI;
73 ilm 79
import java.net.URL;
80 ilm 80
import java.net.UnknownHostException;
73 ilm 81
import java.security.AllPermission;
82
import java.security.Permission;
83
import java.security.PermissionCollection;
84
import java.security.Policy;
85
import java.security.ProtectionDomain;
80 ilm 86
import java.sql.SQLException;
18 ilm 87
import java.util.ArrayList;
88
import java.util.Enumeration;
151 ilm 89
import java.util.HashSet;
18 ilm 90
import java.util.List;
156 ilm 91
import java.util.Properties;
151 ilm 92
import java.util.Set;
18 ilm 93
 
94
import javax.swing.ImageIcon;
95
import javax.swing.JDialog;
96
import javax.swing.JFrame;
80 ilm 97
import javax.swing.JOptionPane;
18 ilm 98
import javax.swing.SwingUtilities;
99
 
100
public class Gestion {
101
 
25 ilm 102
    public static final File MODULES_DIR = new File("Modules");
103
 
20 ilm 104
    /**
105
     * When this system property is set to <code>true</code>, Gestion will hide most of its normal
106
     * UI. E.g. no SOCIETE selection in the login panel, minimalist menu bar, etc.
107
     */
108
    public static final String MINIMAL_PROP = "org.openconcerto.erp.minimal";
109
 
18 ilm 110
    private static List<Image> frameIcon;
111
    // Check that we are on Mac OS X. This is crucial to loading and using the OSXAdapter class.
112
    static final boolean MAC_OS_X = System.getProperty("os.name").toLowerCase().startsWith("mac os x");
113
 
114
    static boolean inWebStart() {
115
        // cannot rely on system properties since they vary from one implementation to another
116
        try {
26 ilm 117
            // ATTN on OpenJDK jnlp classes are in rt.jar, so this doesn't throw
118
            // ClassNotFoundException, we have to check the result
119
            final String[] names = (String[]) Class.forName("javax.jnlp.ServiceManager").getMethod("getServiceNames").invoke(null);
120
            return names != null && names.length > 0;
18 ilm 121
        } catch (Throwable e) {
122
            return false;
123
        }
124
    }
125
 
126
    public static void openPDF(File f) {
127
        try {
128
            FileUtils.openFile(f);
129
        } catch (IOException e) {
132 ilm 130
            JOptionPane.showMessageDialog(null,
131
                    "Impossible d'ouvrir le fichier " + f + ".\nVérifiez qu'un logiciel pour lire les fichiers PDF est installé sur votre ordinateur.\nVoir http://get.adobe.com/fr/reader.",
132
                    "Erreur d'ouverture du PDF", JOptionPane.ERROR_MESSAGE);
18 ilm 133
        }
134
    }
135
 
20 ilm 136
    public static final boolean isMinimalMode() {
137
        return Boolean.getBoolean(MINIMAL_PROP);
138
    }
139
 
73 ilm 140
    static private final PermissionCollection ALL_PERMS;
141
    static {
142
        final AllPermission allPermission = new AllPermission();
143
        ALL_PERMS = allPermission.newPermissionCollection();
144
        ALL_PERMS.add(allPermission);
145
        ALL_PERMS.setReadOnly();
146
    }
147
 
148
    // install a security manager so that we can restrict modules permissions
149
    private static void initSecurity() {
150
        // extensions (like sunjce_provider) need all permissions
151
        final String[] extDirs = System.getProperty("java.ext.dirs").split(File.pathSeparator);
152
        final List<String> canonExtDirs = new ArrayList<String>(extDirs.length);
153
        for (final String extDir : extDirs) {
154
            try {
155
                canonExtDirs.add(new File(extDir).getCanonicalPath());
156
            } catch (IOException e) {
157
                System.err.println("Couldn't add extension dir : " + extDir);
158
                e.printStackTrace();
159
            }
160
        }
161
 
162
        // our class loader gets all permission
163
        final ClassLoader mainLoader = Gestion.class.getClassLoader();
164
        Policy.setPolicy(new Policy() {
165
            private boolean isExt(ProtectionDomain domain) {
166
                final URL location = domain.getCodeSource().getLocation();
167
                if ("file".equals(location.getProtocol())) {
168
                    try {
169
                        final String canonPath = new File(location.toURI()).getCanonicalPath();
170
                        for (final String canonExtDir : canonExtDirs) {
171
                            if (canonPath.startsWith(canonExtDir))
172
                                return true;
173
                        }
174
                    } catch (Exception e) {
175
                        e.printStackTrace();
176
                    }
177
                }
178
                return false;
179
            }
180
 
181
            @Override
182
            public PermissionCollection getPermissions(ProtectionDomain domain) {
183
                if (domain != null && (domain.getClassLoader() == mainLoader || isExt(domain))) {
184
                    return ALL_PERMS;
185
                } else {
186
                    return super.getPermissions(domain);
187
                }
188
            }
189
 
190
            // have to overload since our superclass caches the permissions of the protection domain
191
            // of this instance in initPolicy()
192
            @Override
193
            public boolean implies(ProtectionDomain domain, Permission permission) {
194
                if (domain != null && domain.getClassLoader() == mainLoader) {
195
                    return true;
196
                }
142 ilm 197
                // super caches results (avoid calling expensive isExt())
198
                return super.implies(domain, permission);
199
 
73 ilm 200
            }
201
        });
202
 
203
        System.setSecurityManager(new SecurityManager());
204
    }
205
 
18 ilm 206
    public static void main(String[] args) {
144 ilm 207
        ComptaPropsConfiguration.checkJava();
156 ilm 208
        // Check MacOS Sandbox
209
        String cwd = new File(getProperty("user.dir")).toURI().toString();
210
        if (cwd.startsWith("file:/private/var/folders")) {
211
            JOptionPane.showMessageDialog(null,
212
                    "Vous éxecutez OpenConcerto depuis la sandbox de MacOS.\nVous devez déplacer le logiciel dans votre dossier Application.\n\nSi cela ne fonctionne pas, vous pouvez utiliser la commande : \nsudo xattr -r -d com.apple.quarantine /Applications/OpenConcerto",
213
                    "Sandbox", JOptionPane.ERROR_MESSAGE);
214
            return;
215
        }
216
 
28 ilm 217
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
218
 
219
            @Override
220
            public void uncaughtException(Thread t, Throwable e) {
142 ilm 221
                e.printStackTrace();
28 ilm 222
                ExceptionHandler.handle("UncaughtException on thread " + t, e);
223
            }
224
        });
94 ilm 225
        System.out.println("Java version: " + System.getProperty("java.vendor", "??") + " - " + System.getProperty("java.version", "??"));
226
        System.out.println("Runtime: Java " + System.getProperty("java.runtime.version", "??") + " - " + System.getProperty("os.name", "??"));
18 ilm 227
        ExceptionHandler.setForceUI(true);
228
        ExceptionHandler.setForumURL("http://www.openconcerto.org/forum");
156 ilm 229
 
83 ilm 230
        ExceptionHandler.setSoftwareInformations(SoftwareInfoPanel.FACTORY);
132 ilm 231
        ExceptionHandler.setShowProbably(true);
144 ilm 232
        ExceptionHandler.setThrowableHandler(createDefaultThrowableHandler());
233
 
156 ilm 234
        // Guillaume : handle people importing data directly into the DB
235
        ReOrder.setAutoFixNulls(true);
236
 
142 ilm 237
        System.setProperty(SQLRowAccessor.ACCESS_DB_IF_NEEDED_PROP, "true");
28 ilm 238
        System.setProperty(PropsConfiguration.REDIRECT_TO_FILE, "true");
18 ilm 239
        // Mac
240
        // only works with Aqua laf
241
        System.setProperty("apple.laf.useScreenMenuBar", "true");
242
 
41 ilm 243
        // ToolTipManager.sharedInstance().setInitialDelay(0);
18 ilm 244
        // SpeedUp Linux
245
        System.setProperty("sun.java2d.pmoffscreen", "false");
246
 
80 ilm 247
        System.setProperty(EditPanel.NOBORDER, "true");
248
        System.setProperty(EditPanel.ADD_AT_THE_END, "true");
18 ilm 249
        System.setProperty("org.openconcerto.sql.listPanel.deafEditPanel", "true");
93 ilm 250
 
156 ilm 251
        // needed as long as IListFrame title isn't localised
252
        System.setProperty(IListFrame.SHORT_TITLE, "true");
253
 
93 ilm 254
        // Gérer avec le droit SAVE_LIST
255
        System.setProperty("org.openconcerto.sql.canSaveInList", "false");
256
 
18 ilm 257
        System.setProperty("org.openconcerto.ui.addComboButton", "true");
65 ilm 258
        System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
18 ilm 259
        // don't put any suffix, rely on Animator
260
        System.setProperty(UISQLComponent.REQUIRED_SUFFIX_PROP, "");
261
        System.setProperty(ElementComboBox.CAN_MODIFY, "true");
41 ilm 262
 
18 ilm 263
        System.setProperty("org.openconcerto.ui.removeSwapSearchCheckBox", "true");
19 ilm 264
 
265
        if (System.getProperty("org.openconcerto.oo.useODSViewer") == null) {
18 ilm 266
            System.setProperty("org.openconcerto.oo.useODSViewer", "true");
267
        }
73 ilm 268
        // Workaround for JRE 7 bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7075600
269
        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
61 ilm 270
 
80 ilm 271
        System.setProperty(ITextCombo.SIMPLE_TRAVERSAL, "true");
272
 
142 ilm 273
        // Disable FOR SHARE lock
274
        BaseFillSQLRequest.setDefaultLockSelect(false);
275
 
80 ilm 276
        ComboSQLRequest.setDefaultItemsOrder(CompareUtils.<IComboSelectionItem> naturalOrder());
18 ilm 277
        // Initialisation du splashScreen
278
        // ne pas oublier en param -splash:image.png
142 ilm 279
        try {
280
            SplashScreen.getSplashScreen();
281
        } catch (Exception e) {
282
            // Can occur on OpenJDK...
283
            System.out.println("SplashScreen failed... " + e.getMessage());
284
        }
18 ilm 285
 
132 ilm 286
        // must be done before creating UserRightsManager (which is done by
287
        // PropsConfiguration.getRoot())
288
        UserRightsManager.DEFAULT_MACRO_RIGHTS.add(new ComptaTotalUserRight());
289
 
18 ilm 290
        // Init des caches
291
        long t1 = System.currentTimeMillis();
292
        final ComptaPropsConfiguration conf = ComptaPropsConfiguration.create(true);
41 ilm 293
 
18 ilm 294
        if (conf == null) {
142 ilm 295
            System.out.println("Unable to create configuration, launching ServerFinderPanel");
18 ilm 296
            ServerFinderPanel.main(new String[0]);
297
            return;
298
        }
142 ilm 299
        // Dump conf directories
300
        try {
301
            System.out.println("Application data folder : " + conf.getBaseDirs().getAppDataFolder().getCanonicalPath());
302
            System.out.println("Application cache folder : " + conf.getBaseDirs().getCacheFolder().getCanonicalPath());
303
            System.out.println("Application preferences folder : " + conf.getBaseDirs().getPreferencesFolder().getCanonicalPath());
304
        } catch (IOException ex2) {
305
            ex2.printStackTrace();
306
        }
307
        System.out.println("Application working directory folder : " + conf.getWD().getAbsolutePath());
18 ilm 308
        if (inWebStart()) {
309
            // needed since our classes aren't loaded by the same loader as the library classes
310
            Helper.setURLStreamHandlerFactory();
311
            // even if we set <all-permissions/> in the jnlp, this only applies to the main jar, not
312
            // to dynamically loaded jars. So to allow OOConnexion to work we need to remove the
313
            // security manager.
314
            System.setSecurityManager(null);
315
        }
316
        Configuration.setInstance(conf);
156 ilm 317
 
318
        ExceptionHandler.setSafeToExit(!conf.getServerIp().contains("file:"));
142 ilm 319
        try {
320
            Configuration.migrateToNewDir(conf.getOldDataDir(), conf.getDataDir());
321
        } catch (IOException ex) {
322
            throw new IllegalStateException("Couldn't migrate data dir", ex);
323
        }
61 ilm 324
 
325
        final boolean logRequests = Boolean.valueOf(conf.getProperty("logRequests", "false"));
326
 
327
        if (logRequests) {
328
            SQLRequestLog.setEnabled(true);
329
        }
330
 
41 ilm 331
        if (Boolean.valueOf(conf.getProperty("minimal", "false"))) {
332
            System.setProperty(MINIMAL_PROP, Boolean.TRUE.toString());
333
        }
65 ilm 334
        if (Boolean.valueOf(conf.getProperty("statelessTable", "false"))) {
335
            System.setProperty(IListe.STATELESS_TABLE_PROP, Boolean.TRUE.toString());
336
        }
337
 
80 ilm 338
        System.setProperty("org.openconcerto.oo.useODSViewer", Boolean.TRUE.toString());
41 ilm 339
        if (conf.getProperty("odsViewer") != null) {
340
            System.setProperty("org.openconcerto.oo.useODSViewer", Boolean.valueOf(conf.getProperty("odsViewer")).toString());
341
        }
342
 
149 ilm 343
        if (conf.getProperty("rwOnDoubleClick") != null) {
344
            System.setProperty("org.openconcerto.sql.listPanel.rwOnDoubleClick", Boolean.valueOf(conf.getProperty("rwOnDoubleClick")).toString());
345
        }
83 ilm 346
 
149 ilm 347
 
132 ilm 348
        RemoteShell.startDefaultInstance(conf.getDirectory(), conf.getRoot());
349
 
41 ilm 350
        // Restore L&F and colors
351
        UIPreferencePanel.initUIFromPreferences();
352
 
353
        UpdateManager.start();
354
 
355
        Toolkit.getDefaultToolkit().setDynamicLayout(true);
356
 
357
        ComboSQLRequest.setDefaultFieldSeparator(" ");
358
 
18 ilm 359
        long t4 = System.currentTimeMillis();
360
        System.out.println("Ip:" + conf.getServerIp());
361
        if (conf.getServerIp().startsWith("127.0.0.1:6543")) {
362
            File f = new File("PostgreSQL/data/postmaster.pid");
363
            if (!f.exists()) {
364
                startDB(conf);
365
            }
366
        }
367
        try {
73 ilm 368
            // test DB connection
369
            conf.getSystemRoot();
67 ilm 370
            // Prefetch undefined
371
            conf.getRoot().getTables().iterator().next().getUndefinedID();
18 ilm 372
        } catch (Exception e) {
373
            System.out.println("Init phase 1 error:" + (System.currentTimeMillis() - t4) + "ms");
80 ilm 374
            if (conf.getSystem() == SQLSystem.H2 && e.getCause() instanceof SQLException) {
375
                final SQLException sqlExn = (SQLException) e.getCause();
376
                final String msg;
377
                if (sqlExn.getErrorCode() == 90020) {
378
                    msg = "Base de donnée déjà ouverte.";
379
                } else if (sqlExn.getSQLState().equals("08000")) {
380
                    msg = "Impossible d'ouvrir la base de donnée. Vérifier les permissions.\n" + conf.getServerIp();
381
                } else {
382
                    msg = null;
383
                }
384
                if (msg != null) {
385
                    try {
386
                        e.printStackTrace();
387
                        SwingUtilities.invokeAndWait(new Runnable() {
388
                            @Override
389
                            public void run() {
390
                                JOptionPane.showMessageDialog(null, msg, "Erreur fatale", JOptionPane.ERROR_MESSAGE);
391
                            }
392
                        });
393
                    } catch (Exception e1) {
394
                        ExceptionHandler.die("Erreur fatale", e1);
395
                    }
396
                    System.exit(1);
397
                }
398
            }
18 ilm 399
            ExceptionHandler.die("Erreur de connexion à la base de données", e);
400
        }
401
        System.out.println("Init phase 1:" + (System.currentTimeMillis() - t1) + "ms");
41 ilm 402
 
156 ilm 403
        // Counter and user agreement
404
        File fTOS = new File(Configuration.getInstance().getConfDir(), "tos.properties");
405
        Properties pTOS = new Properties();
406
        pTOS.setProperty("launchCounter", "1");
407
        pTOS.setProperty("allowDebug", "false");
408
        pTOS.setProperty("hasManual", "false");
409
        pTOS.setProperty("hasCloud", "false");
410
 
411
        if (fTOS.exists()) {
412
            try {
413
                pTOS.loadFromXML(new FileInputStream(fTOS));
414
            } catch (Exception e1) {
415
                e1.printStackTrace();
416
            }
417
        }
418
        if (ComptaPropsConfiguration.getInstanceCompta().isOnCloud()) {
419
            pTOS.setProperty("hasCloud", "true");
420
        }
421
        final boolean allowDebug = pTOS.getProperty("allowDebug", "false").equals("true");
422
 
423
        ExceptionHandler.setSubmitErrorAutoEnabled(allowDebug);
424
 
425
        final int launchCounter = Integer.parseInt(pTOS.getProperty("launchCounter", "0"));
426
        pTOS.setProperty("launchCounter", String.valueOf(launchCounter + 1));
427
        saveProperties(fTOS, pTOS);
428
        if (!allowDebug && (launchCounter - 2) % 30 == 0) {
429
            SwingUtilities.invokeLater(new Runnable() {
430
                public void run() {
431
                    Object[] options = { "J'accepte", "Non, merci" };
432
                    int n = JOptionPane.showOptionDialog(null,
433
                            "Afin d'améliorer plus rapidement le logiciel, nous avons intégré l'envoi automatique de rapports d'erreur.\nIl contient les informations techniques nécessaires à la corrections de bugs.\nSouhaitez-vous activer l'envoi automatique ?",
434
                            "Rapport d'erreur", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
435
                    if (n == JOptionPane.YES_OPTION) {
436
                        pTOS.setProperty("allowDebug", "true");
437
                        saveProperties(fTOS, pTOS);
438
                        ExceptionHandler.setSubmitErrorAutoEnabled(true);
439
                    }
440
 
441
                }
442
            });
443
        }
444
        final boolean hasManual = pTOS.getProperty("hasManual", "false").equals("true");
445
        if (!hasManual && (launchCounter - 5) % 100 == 0) {
446
            SwingUtilities.invokeLater(new Runnable() {
447
                public void run() {
448
                    Object[] options = { "Je l'ai déjà", "Bonne idée!" };
449
                    int n = JOptionPane.showOptionDialog(null,
450
                            "Afin de maîtriser le logiciel, nous conseillons vivement l'acquisition du manuel.\nSon achat vous permet de soutenir les développements d'OpenConcerto et d'avoir une documentation papier de plus de 250 pages.\nVous pouvez le commmander avec port gratuit depuis le site internet : https://www.openconcerto.org ",
451
                            "Le manuel utilisateur", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
452
                    if (n == JOptionPane.YES_OPTION) {
453
                        pTOS.setProperty("hasManual", "true");
454
                        saveProperties(fTOS, pTOS);
455
                    } else {
456
                        try {
457
                            Desktop.getDesktop().browse(new URI("https://www.openconcerto.org/fr/documentation.html"));
458
                        } catch (Exception e) {
459
                            e.printStackTrace();
460
                        }
461
                    }
462
                }
463
            });
464
        }
465
        final boolean hasCloud = pTOS.getProperty("hasCloud", "false").equals("true");
466
        if (!hasCloud && (launchCounter - 30) % 100 == 0 && ComptaPropsConfiguration.getInstanceCompta().isServerless()) {
467
            SwingUtilities.invokeLater(new Runnable() {
468
                public void run() {
469
                    JOptionPane.showMessageDialog(null,
470
                            "Vous utilisez actuellement le logiciel en version monoposte.\nLes données sont stockées sur votre ordinateur, ce qui peut poser problème en cas de vol ou de panne.\nNous proposons une offre cloud qui vous permet de travailler à plusieurs et de ne plus avoir à vous soucier de la sauvegarde de vos données.\nVous aurez juste besoin d'une connexion internet.\nPlus d'informations sur https://cloud.openconcerto.org",
471
                            "Cloud", JOptionPane.INFORMATION_MESSAGE);
472
                    try {
473
                        Desktop.getDesktop().browse(new URI("https://cloud.openconcerto.org"));
474
                    } catch (Exception e) {
475
                        e.printStackTrace();
476
                    }
477
 
478
                }
479
            });
480
        }
481
 
41 ilm 482
        // Email props in .java
483
        File fMail2 = new File(Configuration.getInstance().getConfDir(), "Email.properties");
156 ilm 484
        EmailProps.getInstance().setDefaultPropsFileName(fMail2.toString());
41 ilm 485
        EmailProps.getInstance().setPropsFileName(fMail2.toString());
486
 
18 ilm 487
        SwingUtilities.invokeLater(new Runnable() {
488
 
489
            public void run() {
490
                long t1 = System.currentTimeMillis();
491
 
93 ilm 492
                IListe.setForceAlternateCellRenderer(true);
493
 
18 ilm 494
                AWTEventListener awtListener = new AWTEventListener() {
151 ilm 495
                    Set<Integer> frames = new HashSet<Integer>();
496
                    String prefix;
497
 
18 ilm 498
                    @Override
499
                    public final void eventDispatched(final AWTEvent event) {
500
                        assert event != null;
501
                        if (event instanceof HierarchyEvent && event.getID() == HierarchyEvent.HIERARCHY_CHANGED) {
502
                            // This event represents a change in the containment hierarcy.
503
                            // Now let's figure out what kind.
504
                            final HierarchyEvent hevent = (HierarchyEvent) event;
505
                            final Component changed = hevent.getChanged();
506
                            if (changed instanceof JFrame && ((hevent.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) && changed.isDisplayable()) {
151 ilm 507
                                final JFrame frame = (JFrame) changed;
18 ilm 508
                                frame.setIconImages(getFrameIcon());
151 ilm 509
                                if (!frames.contains(frame.hashCode())) {
510
                                    frames.add(frame.hashCode());
511
                                    frame.addPropertyChangeListener(new PropertyChangeListener() {
512
 
513
                                        @Override
514
                                        public void propertyChange(PropertyChangeEvent evt) {
515
                                            if (prefix == null) {
516
                                                if (ComptaPropsConfiguration.getInstance() != null && ComptaPropsConfiguration.getInstanceCompta().getRowSociete() != null) {
517
                                                    prefix = "[" + ComptaPropsConfiguration.getInstanceCompta().getRowSociete().getString("NOM") + "] ";
518
                                                } else {
519
                                                    return;
520
                                                }
521
                                            }
522
                                            String title = frame.getTitle();
523
                                            if (title != null && !title.startsWith(prefix)) {
524
                                                frame.setTitle(prefix + title);
525
                                            }
526
                                        }
527
                                    });
528
                                }
18 ilm 529
                            }
530
                        }
531
                    }
532
                };
533
                final Toolkit toolkit = Toolkit.getDefaultToolkit();
534
                assert toolkit != null;
535
                toolkit.addAWTEventListener(awtListener, AWTEvent.HIERARCHY_EVENT_MASK);
536
                if (logRequests) {
537
                    SQLRequestLog.showFrame();
538
                }
539
 
540
                JFrame f = null;
541
                try {
156 ilm 542
                    f = new NouvelleConnexionAction(conf).createFrame();
18 ilm 543
                    // happens with quick login
544
                    if (f != null) {
545
                        f.pack();
546
                        f.setResizable(false);
547
                        f.addWindowListener(new WindowAdapter() {
548
                            public void windowClosing(WindowEvent e) {
144 ilm 549
                                try {
550
                                    askForExit();
551
                                } catch (Exception ex) {
552
                                    ex.printStackTrace();
553
                                    // Broken state
554
                                    System.exit(2);
555
                                }
18 ilm 556
                            };
557
                        });
558
                        // f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
559
                    }
560
                } catch (Exception e) {
561
                    Thread.dumpStack();
562
                    e.printStackTrace();
563
                    ExceptionHandler.handle("Erreur lors de la tentative de connexion à la base.", e);
564
 
565
                } finally {
566
                    if (f != null) {
567
                        FrameUtil.show(f);
568
                    }
569
                    System.out.println("Init phase 2:" + (System.currentTimeMillis() - t1) + "ms");
570
                }
571
            }
572
        });
19 ilm 573
 
574
        // needed so that we can uninstall modules
575
        System.setProperty(SQLBase.ALLOW_OBJECT_REMOVAL, "true");
156 ilm 576
    }
577
 
578
    private static void saveProperties(File fTOS, Properties pTOS) {
25 ilm 579
        try {
156 ilm 580
            final FileOutputStream outputStream = new FileOutputStream(fTOS);
581
            pTOS.storeToXML(outputStream, "tos", "UTF-8");
582
            outputStream.close();
583
        } catch (Exception e) {
584
            e.printStackTrace();
25 ilm 585
        }
18 ilm 586
    }
587
 
144 ilm 588
    public static ThrowableHandler createDefaultThrowableHandler() {
589
 
590
        return new ThrowableHandler() {
591
 
592
            @Override
593
            public boolean handle(String message, Throwable throwable) {
594
                if (throwable == null)
595
                    return false;
596
 
597
                final ByteArrayOutputStream out = new ByteArrayOutputStream();
598
                throwable.printStackTrace(new PrintStream(out));
599
                String s = new String(out.toByteArray());
600
                if (s.contains("Database may be already in use")) {
601
                    JOptionPane.showMessageDialog(null,
602
                            "Votre base de données est déjà en cours d'utilisation.\nEn version monoposte, vous ne pouvez lancer qu'un seul programme OpenConcerto à la fois.");
603
                    System.exit(1);
604
                    return true;
605
                } else if (s.contains("PSQLException: Connexion") && ComptaPropsConfiguration.getInstanceCompta().isOnCloud()) {
606
                    JOptionPane.showMessageDialog(null, "Suite à une coupure de votre connexion internet, vous avez été déconnecté du Cloud.\nMerci de redémarrer le logiciel.");
607
                    System.exit(1);
608
                    return true;
609
                } else if (s.contains("File corrupted while reading")) {
610
                    JOptionPane.showMessageDialog(null,
611
                            "Votre fichier de base de données est endommagé.\nLes causes possibles sont variées : problème matériel (mémoire, disque dur...), coupure brutale du PC, virus, antivirus, erreur de fichiers...\n\nIl vous faudra restaurer votre base de données depuis une sauvegarde\nou contacter notre service technique pour réparation (voir https://www.openconcerto.org).");
612
                    System.exit(1);
613
                    return true;
156 ilm 614
                } else if (s.contains("h2") && (s.contains("File corrupted while reading") || s.contains("data leaf table"))) {
144 ilm 615
                    JOptionPane.showMessageDialog(null,
616
                            "Votre fichier de base de données est endommagé.\nLes causes possibles sont variées : problème matériel (mémoire, disque dur...), coupure brutale du PC, virus, antivirus, erreur de fichiers...\n\nIl vous faudra restaurer votre base de données depuis une sauvegarde\nou contacter notre service technique pour réparation (voir https://www.openconcerto.org).");
617
                    System.exit(1);
618
                    return true;
619
                } else if (s.contains("/private/var/folders/")) {
620
                    JOptionPane.showMessageDialog(null,
621
                            "Votre installation d'OpenConcerto n'est pas correcte!\nOpenConcerto ne doit pas s'executer dans l'app Sandbox de MacOS.\nVeuillez débloquer l'application.");
622
                    System.exit(1);
623
                    return true;
624
                } else if (s.contains("com.sun.java.swing.plaf.windows.WindowsTableHeaderUI")) {
625
                    // bug connu de Java sur les TableHeader
626
                    return true;
156 ilm 627
                } else if (s.contains("WInputMethod.openCandidateWindow") && s.contains("java.lang.NullPointerException: peer")) {
628
                    // bug windows...
629
                    // Caused by: java.lang.NullPointerException: peer
630
                    // at sun.awt.windows.WInputMethod.openCandidateWindow(Native Method)
631
                    // at sun.awt.windows.WInputMethod.access$400(Unknown Source)
632
                    // at sun.awt.windows.WInputMethod$1.run(Unknown Source)
633
                    // at java.awt.event.InvocationEvent.dispatch(Unknown Source)
634
                    return true;
144 ilm 635
                }
156 ilm 636
 
637
                else if (s.contains("No application is associated with the specified file for this operation")) {
638
                    JOptionPane.showMessageDialog(null, "Merci d'installer LibreOffice ou tout autre application succeptible d'ouvrir ce fichier");
639
                    return true;
640
                } else if (s.contains("java.net.SocketTimeoutException: connect timed out")) {
641
                    JOptionPane.showMessageDialog(null, "Le serveur de base de données n'est pas joignable.\n" + message);
642
                    return true;
643
                } else if (s.contains("java.lang.NoSuchMethodError")) {
644
                    JOptionPane.showMessageDialog(null, "Un de vos modules n'est pas à jour.\n" + message);
645
                    return true;
646
                } else if (s.contains("InvalidTemplateException")) {
647
                    JOptionPane.showMessageDialog(null, "Votre modèle de document n'est pas valide.\n" + message, "Modèle incorrect", JOptionPane.ERROR_MESSAGE);
648
                    return true;
649
                }
144 ilm 650
                return false;
651
            }
652
        };
653
    }
654
 
18 ilm 655
    /**
656
     * Si la base est 127.0.0.1 ou localhost alors on essaye de lancer postgres.
657
     *
658
     * @param conf the configuration to connect to.
659
     */
660
    private static void startDB(PropsConfiguration conf) {
661
 
662
        List<String> l = new ArrayList<String>();
663
        l.add("Lancement de la base de données");
664
        PostgreSQLFrame pgFrame = null;
665
        try {
666
            pgFrame = new PostgreSQLFrame("Démarrage en cours");
667
            pgFrame.setVisible(true);
668
        } catch (Exception e) {
669
            e.printStackTrace();
670
        }
671
        System.err.println("start DB");
672
        final WaitIndeterminatePanel panel = new WaitIndeterminatePanel(l);
673
        final PanelFrame f = new PanelFrame(panel, "Gestion NX");
674
        f.setResizable(false);
675
        f.setLocationRelativeTo(null);
676
        f.setVisible(true);
677
 
678
        // on recupere les properties
679
        final String serverAdr = conf.getProperty("server.ip");
680
        // si la base est en local on relance postgres
681
        if (serverAdr.startsWith("127.0.0.1") || serverAdr.startsWith("localhost")) {
682
 
683
            Runtime runtime = Runtime.getRuntime();
684
            try {
685
                File file = new File(".\\PostgreSQL\\bin\\");
686
                if (!file.canWrite()) {
687
                    ExceptionHandler.die("Vous n'avez pas le droit en écriture sur la base de données.\nImpossible de lancer le logiciel!");
688
                }
689
                final Process p = runtime.exec(new String[] { "cmd.exe", "/C", "launchPostGres.bat" }, null, file);
690
                // Consommation de la sortie standard de l'application externe dans un Thread
691
                // separe
692
                new Thread() {
693
                    public void run() {
694
                        try {
695
                            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
696
                            String line = "";
697
                            try {
698
                                while ((line = reader.readLine()) != null) {
699
                                    System.out.println(line);
700
                                }
701
                            } finally {
702
                                reader.close();
703
                            }
704
                        } catch (IOException ioe) {
705
                            ioe.printStackTrace();
706
                        }
707
                    }
708
                }.start();
709
 
710
                // Consommation de la sortie d'erreur de l'application externe dans un Thread
711
                // separe
712
                new Thread() {
713
                    public void run() {
714
                        try {
715
                            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
716
                            String line = "";
717
                            try {
718
                                while ((line = reader.readLine()) != null) {
719
                                    System.err.println(line);
720
                                }
721
                            } finally {
722
                                reader.close();
723
                            }
724
                        } catch (IOException ioe) {
725
                            ioe.printStackTrace();
726
                        }
727
                    }
728
                }.start();
729
                try {
730
                    p.waitFor();
731
                } catch (InterruptedException e2) {
732
                    e2.printStackTrace();
733
                }
734
            } catch (IOException e1) {
735
                e1.printStackTrace();
736
            }
737
        } else {
738
            System.err.println("L'adresse du serveur n'est pas en local (" + serverAdr + ").");
739
        }
740
 
741
        panel.taskEnded(0);
742
        if (pgFrame != null) {
743
            pgFrame.dispose();
744
        }
745
        f.dispose();
746
        String realIp = "127.0.0.1";
747
        realIp = getIp();
748
        try {
749
            pgFrameStart = new PostgreSQLFrame(realIp + " port " + "6543");
750
            pgFrameStart.setVisible(true);
751
        } catch (Exception e) {
752
            e.printStackTrace();
753
        }
754
 
755
    }
756
 
757
    private static String getIp() {
758
        String realIp = "127.0.0.1";
759
        try {
760
            InetAddress Ip = InetAddress.getLocalHost();
761
            realIp = Ip.getHostAddress();
762
        } catch (Exception e) {
763
            e.printStackTrace();
764
        }
765
        try {
67 ilm 766
            Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
18 ilm 767
            while (e.hasMoreElements()) {
768
                NetworkInterface ni = (NetworkInterface) e.nextElement();
67 ilm 769
                Enumeration<InetAddress> e2 = ni.getInetAddresses();
18 ilm 770
                while (e2.hasMoreElements()) {
771
                    InetAddress ip = (InetAddress) e2.nextElement();
772
                    final String iip = ip.toString().replace('/', ' ').trim();
773
                    if (iip.startsWith("192")) {
774
                        return iip;
775
                    }
776
                }
777
            }
778
        } catch (Exception e) {
779
            e.printStackTrace();
780
        }
781
        return realIp;
782
    }
783
 
784
    public static PostgreSQLFrame pgFrameStart = null;
785
 
786
    private static JDialog frameExit = null;
787
 
80 ilm 788
    static public void askForExit() {
789
        askForExit(UserExitConf.DEFAULT);
790
    }
791
 
792
    static public void askForExit(UserExitConf conf) {
18 ilm 793
        JDialog exitDialog = new JDialog();
794
        exitDialog.setModal(true);
795
 
796
        if (frameExit == null) {
797
            frameExit = new JDialog();
798
            frameExit.setTitle("Quitter");
799
            frameExit.setModal(true);
800
            frameExit.setIconImages(Gestion.getFrameIcon());
801
            frameExit.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
802
        }
803
 
80 ilm 804
        frameExit.setContentPane(new UserExitPanel(conf));
18 ilm 805
        frameExit.pack();
806
        frameExit.setResizable(false);
807
        frameExit.setLocationRelativeTo(null);
808
        frameExit.setAlwaysOnTop(true);
809
        frameExit.setVisible(true);
810
    }
811
 
93 ilm 812
    public static synchronized List<Image> getFrameIcon() {
18 ilm 813
        if (frameIcon == null) {
814
            frameIcon = new ArrayList<Image>();
815
            int[] sizes = { 16, 32, 48, 96 };
816
            for (int i = 0; i < sizes.length; i++) {
817
                int v = sizes[i];
818
                try {
819
                    frameIcon.add(new ImageIcon(Gestion.class.getResource(v + ".png")).getImage());
820
                } catch (Exception e) {
821
                    ExceptionHandler.die("Impossible de charger l'icone de fenetre " + v + ".png");
822
                }
823
            }
824
        }
825
        return frameIcon;
826
    }
827
}