OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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