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
 *
182 ilm 4
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
18 ilm 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.modules;
15
 
80 ilm 16
import org.openconcerto.erp.config.Gestion;
17
import org.openconcerto.erp.modules.ModuleManager.ModuleAction;
18
import org.openconcerto.erp.modules.ModuleManager.ModuleState;
19
import org.openconcerto.erp.modules.ModuleTableModel.ModuleRow;
20
import org.openconcerto.erp.panel.UserExitConf;
25 ilm 21
import org.openconcerto.sql.view.AbstractFileTransfertHandler;
61 ilm 22
import org.openconcerto.ui.component.WaitIndeterminatePanel;
156 ilm 23
import org.openconcerto.utils.CompareUtils;
19 ilm 24
import org.openconcerto.utils.ExceptionHandler;
25 ilm 25
import org.openconcerto.utils.FileUtils;
18 ilm 26
 
61 ilm 27
import java.awt.Dialog.ModalityType;
19 ilm 28
import java.awt.event.ActionEvent;
25 ilm 29
import java.io.File;
30
import java.io.IOException;
61 ilm 31
import java.text.ChoiceFormat;
32
import java.text.MessageFormat;
80 ilm 33
import java.util.Collection;
34
import java.util.HashSet;
182 ilm 35
import java.util.List;
67 ilm 36
import java.util.Set;
18 ilm 37
 
19 ilm 38
import javax.swing.AbstractAction;
80 ilm 39
import javax.swing.Action;
61 ilm 40
import javax.swing.JComponent;
41
import javax.swing.JDialog;
25 ilm 42
import javax.swing.JOptionPane;
43
import javax.swing.SwingUtilities;
61 ilm 44
import javax.swing.SwingWorker;
80 ilm 45
import javax.swing.TransferHandler;
18 ilm 46
 
80 ilm 47
public class AvailableModulesPanel {
61 ilm 48
 
49
    static final MessageFormat MODULE_FMT;
50
 
51
    static {
52
        final ChoiceFormat choiceForm = new ChoiceFormat(new double[] { 1, 2 }, new String[] { "d'un module", "de {0} modules" });
53
        MODULE_FMT = new MessageFormat("{0}");
54
        MODULE_FMT.setFormatByArgumentIndex(0, choiceForm);
55
    }
56
 
57
    // prevent the user from interacting when un/installing modules
58
    static JDialog displayDialog(JComponent parent, final String text) {
59
        final WaitIndeterminatePanel panel = new WaitIndeterminatePanel(text);
60
        final JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(parent), ModalityType.APPLICATION_MODAL);
61
        dialog.add(panel);
62
        dialog.pack();
63
        dialog.setLocationRelativeTo(parent);
64
        SwingUtilities.invokeLater(new Runnable() {
65
            @Override
66
            public void run() {
67
                dialog.setVisible(true);
68
            }
69
        });
70
        return dialog;
71
    }
72
 
80 ilm 73
    // return true if the user cancels
74
    static boolean displayDenied(final JComponent panel, final String dialogTitle, final String deniedMsg, final boolean noneAllowed) {
75
        final boolean done;
76
        if (noneAllowed) {
77
            JOptionPane.showMessageDialog(panel, deniedMsg, dialogTitle, JOptionPane.WARNING_MESSAGE);
78
            done = true;
79
        } else {
80
            final int answer = JOptionPane.showConfirmDialog(panel, deniedMsg, dialogTitle, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
81
            done = answer == JOptionPane.CANCEL_OPTION;
73 ilm 82
        }
80 ilm 83
        return done;
67 ilm 84
    }
61 ilm 85
 
156 ilm 86
    static void applySolution(final ModuleManager mngr, final ModulePanel panel, final ModulesStateChange chosen, final ModuleState targetState) {
80 ilm 87
        final String dialogTitle = "Gestion des modules";
88
        final int installSize = chosen.getReferencesToInstall().size();
89
        final int uninstallSize = chosen.getReferencesToRemove().size();
90
        if (installSize == 0 && uninstallSize == 0) {
91
            JOptionPane.showMessageDialog(panel, "Aucun changement à apporter", dialogTitle, JOptionPane.INFORMATION_MESSAGE);
67 ilm 92
            return;
93
        }
80 ilm 94
 
95
        final StringBuilder sb = new StringBuilder(128);
96
        if (uninstallSize > 0) {
97
            sb.append("Désinstallation ");
98
            sb.append(MODULE_FMT.format(new Object[] { uninstallSize }));
67 ilm 99
        }
80 ilm 100
        if (installSize > 0) {
101
            if (sb.length() > 0)
102
                sb.append(". ");
103
            sb.append("Installation ");
104
            sb.append(MODULE_FMT.format(new Object[] { installSize }));
67 ilm 105
        }
80 ilm 106
        sb.append(".");
107
        final String msg = sb.toString();
108
        if (mngr.needExit(chosen)) {
109
            Gestion.askForExit(new UserExitConf(msg, true) {
67 ilm 110
                @Override
80 ilm 111
                protected void afterWindowsClosed() throws Exception {
112
                    // since windows are closed this should minimise uninstall
113
                    // problems. As the other branch of the if, start modules
114
                    mngr.applyChange(chosen, targetState, true);
115
                };
116
            });
117
        } else {
118
            final JDialog dialog = displayDialog(panel, msg);
119
            new SwingWorker<ModulesStateChangeResult, Object>() {
120
                @Override
121
                protected ModulesStateChangeResult doInBackground() throws Exception {
156 ilm 122
                    // don't start the module in background (see below)
123
                    // don't go farther than requested
124
                    final ModuleState backgroundState = CompareUtils.min(targetState, ModuleState.REGISTERED);
125
                    return mngr.applyChange(chosen, backgroundState);
25 ilm 126
                }
67 ilm 127
 
128
                @Override
129
                protected void done() {
25 ilm 130
                    try {
80 ilm 131
                        final ModulesStateChangeResult res = this.get();
132
                        if (res.getNotCreated().size() > 0)
133
                            JOptionPane.showMessageDialog(panel, "Certains modules n'ont pu être créés : " + res.getNotCreated(), dialogTitle, JOptionPane.WARNING_MESSAGE);
134
 
135
                        // start inside the EDT, that way when we return, the
136
                        // modules are completely started. Further if any exception
137
                        // is thrown we can catch it here.
138
                        if (targetState.compareTo(ModuleState.STARTED) >= 0) {
139
                            try {
140
                                // pass all modules to start() since start/stop status might have
141
                                // changed since doInBackground()
142
                                mngr.startFactories(res.getGraph().flatten());
143
                                mngr.setPersistentModules(chosen.getUserReferencesToInstall());
144
                            } catch (Exception e) {
145
                                ExceptionHandler.handle(panel, "Impossible de démarrer les modules", e);
146
                            }
67 ilm 147
                        }
148
                    } catch (Exception e) {
80 ilm 149
                        ExceptionHandler.handle(panel, "Impossible d'appliquer les changements", e);
25 ilm 150
                    }
80 ilm 151
                    panel.reload();
67 ilm 152
                    dialog.dispose();
25 ilm 153
                }
67 ilm 154
            }.execute();
155
        }
156
    }
25 ilm 157
 
81 ilm 158
    static final Action createInstallAction(final ModulePanel panel, final boolean onlyInstall) {
80 ilm 159
        return new AbstractAction("Installer") {
160
            @Override
161
            public void actionPerformed(ActionEvent evt) {
162
                final String dialogTitle = "Installation de modules";
81 ilm 163
                final Collection<ModuleRow> checkedRows = panel.getSelection();
80 ilm 164
                if (checkedRows.isEmpty()) {
165
                    JOptionPane.showMessageDialog(panel, "Aucune ligne cochée", dialogTitle, JOptionPane.INFORMATION_MESSAGE);
166
                    return;
167
                }
156 ilm 168
                final ModuleManager mngr = panel.getModuleManager();
80 ilm 169
                final Set<ModuleReference> refs = new HashSet<ModuleReference>();
170
                final Set<ModuleReference> deniedRefs = new HashSet<ModuleReference>();
171
                for (final ModuleRow f : checkedRows) {
172
                    if (!mngr.canCurrentUser(ModuleAction.INSTALL, f))
173
                        deniedRefs.add(f.getRef());
174
                    else
175
                        refs.add(f.getRef());
176
                }
177
                if (deniedRefs.size() > 0) {
178
                    if (displayDenied(panel, dialogTitle, "Ces modules ne peuvent être installés : " + deniedRefs, refs.size() == 0))
179
                        return;
180
                }
181
                assert refs.size() > 0;
182
                final JDialog depDialog = displayDialog(panel, "Calcul des dépendences");
183
                new SwingWorker<Solutions, Object>() {
184
                    @Override
185
                    protected Solutions doInBackground() throws Exception {
186
                        // MAYBE present the user with the reason references couldn't be installed
187
                        return mngr.getSolutions(refs, 5);
188
                    }
25 ilm 189
 
80 ilm 190
                    @Override
191
                    protected void done() {
192
                        depDialog.dispose();
193
                        try {
194
                            final Solutions res = this.get();
195
                            if (res.getSolutions().size() == 0) {
196
                                JOptionPane.showMessageDialog(panel, "Aucune solution trouvée", "Installation de modules", JOptionPane.WARNING_MESSAGE);
197
                            } else {
198
                                final DepSolverResultChooserPanel cPanel = new DepSolverResultChooserPanel(res.getSolutions());
199
                                cPanel.setRunnable(new Runnable() {
200
                                    @Override
201
                                    public void run() {
156 ilm 202
                                        applySolution(mngr, panel, cPanel.getSolutionToApply(), onlyInstall ? ModuleState.INSTALLED : ModuleState.STARTED);
80 ilm 203
                                    }
204
                                });
205
                                final JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(panel), ModalityType.APPLICATION_MODAL);
206
                                dialog.add(cPanel);
207
                                dialog.pack();
208
                                dialog.setLocationRelativeTo(panel);
209
                                dialog.setVisible(true);
67 ilm 210
 
80 ilm 211
                            }
212
                        } catch (Exception e) {
213
                            ExceptionHandler.handle(panel, "Erreur lors de la recherche de solutions", e);
214
                        }
215
                    }
216
 
217
                }.execute();
25 ilm 218
            }
80 ilm 219
        };
220
    }
67 ilm 221
 
80 ilm 222
    static final TransferHandler createTransferHandler(final ModulePanel panel) {
223
        return new AbstractFileTransfertHandler() {
224
 
225
            @Override
226
            public void handleFile(File f) {
227
                if (!f.getName().endsWith(".jar")) {
228
                    JOptionPane.showMessageDialog(panel, "Impossible d'installer le module. Le fichier n'est pas un module.");
229
                    return;
230
                }
182 ilm 231
                final List<File> dirs = panel.getModuleManager().getFolders();
232
                final File dir = ModuleManager.getFolderToWrite(dirs);
233
                if (dir == null) {
234
                    if (dirs.isEmpty()) {
235
                        JOptionPane.showMessageDialog(panel, "Aucun dossier configuré");
142 ilm 236
                    } else {
182 ilm 237
                        JOptionPane.showMessageDialog(panel, "Impossible de créer le dossier des modules : " + dirs);
142 ilm 238
                    }
182 ilm 239
                    return;
142 ilm 240
                }
80 ilm 241
                File out = null;
242
                if (dir.canWrite()) {
243
                    try {
244
                        out = new File(dir, f.getName());
245
                        FileUtils.copyFile(f, out);
246
                    } catch (IOException e) {
247
                        JOptionPane.showMessageDialog(panel, "Impossible d'installer le module.\n" + f.getAbsolutePath() + " vers " + dir.getAbsolutePath());
248
                        return;
249
                    }
250
                } else {
251
                    JOptionPane.showMessageDialog(panel, "Impossible d'installer le module.\nVous devez disposer des droits en écriture sur le dossier:\n" + dir.getAbsolutePath());
252
                    return;
253
                }
254
                try {
156 ilm 255
                    panel.getModuleManager().addFactory(new JarModuleFactory(out));
80 ilm 256
                } catch (IOException e) {
257
                    JOptionPane.showMessageDialog(panel, "Impossible d'intégrer le module.\n" + e.getMessage());
258
                    return;
259
                }
260
                SwingUtilities.invokeLater(new Runnable() {
261
 
262
                    @Override
263
                    public void run() {
264
                        panel.reload();
265
                    }
266
                });
267
 
268
            }
269
        };
18 ilm 270
    }
271
}