OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

Rev Author Line No. Line
74 ilm 1
package org.openconcerto.modules.extensionbuilder;
2
 
3
import java.io.BufferedOutputStream;
4
import java.io.ByteArrayOutputStream;
5
import java.io.IOException;
6
import java.io.StringReader;
7
import java.io.UnsupportedEncodingException;
8
import java.math.BigDecimal;
9
import java.sql.SQLException;
10
import java.util.ArrayList;
11
import java.util.Collection;
12
import java.util.Collections;
13
import java.util.Comparator;
14
import java.util.HashSet;
15
import java.util.LinkedHashSet;
16
import java.util.List;
86 ilm 17
import java.util.Locale;
74 ilm 18
import java.util.Set;
19
import java.util.logging.Level;
20
 
21
import javax.swing.JFrame;
22
import javax.swing.JOptionPane;
23
import javax.swing.event.ChangeEvent;
24
import javax.swing.event.ChangeListener;
25
 
26
import org.jdom.Document;
27
import org.jdom.Element;
28
import org.jdom.input.SAXBuilder;
29
import org.jdom.output.Format;
30
import org.jdom.output.XMLOutputter;
31
import org.openconcerto.erp.action.CreateFrameAbstractAction;
32
import org.openconcerto.erp.config.ComptaPropsConfiguration;
33
import org.openconcerto.erp.config.Log;
34
import org.openconcerto.erp.config.MenuAndActions;
35
import org.openconcerto.erp.config.MenuManager;
36
import org.openconcerto.erp.modules.MenuContext;
37
import org.openconcerto.modules.extensionbuilder.component.ComponentDescritor;
38
import org.openconcerto.modules.extensionbuilder.list.ColumnDescriptor;
39
import org.openconcerto.modules.extensionbuilder.list.ListDescriptor;
40
import org.openconcerto.modules.extensionbuilder.menu.mainmenu.MenuDescriptor;
41
import org.openconcerto.modules.extensionbuilder.meu.actions.ActionDescriptor;
42
import org.openconcerto.modules.extensionbuilder.table.AllTableListModel;
43
import org.openconcerto.modules.extensionbuilder.table.ElementDescriptor;
44
import org.openconcerto.modules.extensionbuilder.table.FieldDescriptor;
45
import org.openconcerto.modules.extensionbuilder.table.TableDescritor;
46
import org.openconcerto.modules.extensionbuilder.translation.Translation;
47
import org.openconcerto.modules.extensionbuilder.translation.action.ActionTranslation;
48
import org.openconcerto.modules.extensionbuilder.translation.field.FieldTranslation;
49
import org.openconcerto.modules.extensionbuilder.translation.field.TableTranslation;
50
import org.openconcerto.modules.extensionbuilder.translation.menu.MenuTranslation;
51
import org.openconcerto.sql.element.GroupSQLComponent;
52
import org.openconcerto.sql.element.SQLElement;
53
import org.openconcerto.sql.model.DBRoot;
54
import org.openconcerto.sql.model.FieldPath;
55
import org.openconcerto.sql.model.SQLBase;
56
import org.openconcerto.sql.model.SQLField;
57
import org.openconcerto.sql.model.SQLName;
58
import org.openconcerto.sql.model.SQLRowAccessor;
59
import org.openconcerto.sql.model.SQLRowValues;
60
import org.openconcerto.sql.model.SQLTable;
86 ilm 61
import org.openconcerto.sql.model.graph.PathBuilder;
74 ilm 62
import org.openconcerto.sql.request.ListSQLRequest;
153 ilm 63
import org.openconcerto.sql.request.SQLFieldTranslator;
74 ilm 64
import org.openconcerto.sql.utils.AlterTable;
65
import org.openconcerto.sql.utils.ChangeTable;
66
import org.openconcerto.sql.utils.SQLCreateTable;
67
import org.openconcerto.sql.view.EditFrame;
68
import org.openconcerto.sql.view.EditPanel;
69
import org.openconcerto.sql.view.EditPanel.EditMode;
70
import org.openconcerto.sql.view.IListFrame;
71
import org.openconcerto.sql.view.ListeAddPanel;
72
import org.openconcerto.sql.view.list.BaseSQLTableModelColumn;
73
import org.openconcerto.sql.view.list.IListe;
74
import org.openconcerto.sql.view.list.IListeAction;
75
import org.openconcerto.sql.view.list.RowAction;
76
import org.openconcerto.sql.view.list.SQLTableModelColumn;
77
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
78
import org.openconcerto.ui.group.Group;
79
import org.openconcerto.ui.group.Item;
80
import org.openconcerto.ui.group.LayoutHints;
81
import org.openconcerto.ui.group.modifier.AddGroupModifier;
82
import org.openconcerto.ui.group.modifier.AddItemModifier;
83
import org.openconcerto.ui.group.modifier.MoveToGroupModifier;
84
import org.openconcerto.utils.CollectionUtils;
153 ilm 85
import org.openconcerto.utils.i18n.Grammar;
86
import org.openconcerto.utils.i18n.Grammar_fr;
87
import org.openconcerto.utils.i18n.NounClass;
88
import org.openconcerto.utils.i18n.Phrase;
86 ilm 89
import org.openconcerto.utils.i18n.TranslationManager;
74 ilm 90
 
91
public class Extension {
92
 
93
    // Descriptors of the extension
181 ilm 94
    private List<ElementDescriptor> elementList = new ArrayList<>();
95
    private List<TableDescritor> createTableList = new ArrayList<>();
96
    private List<TableDescritor> modifyTableList = new ArrayList<>();
97
    private List<ListDescriptor> createListList = new ArrayList<>();
98
    private List<TableTranslation> tableTranslations = new ArrayList<>();
99
    private List<FieldTranslation> fieldTranslations = new ArrayList<>();
100
    private List<MenuTranslation> menuTranslations = new ArrayList<>();
101
    private List<ActionTranslation> actionTranslations = new ArrayList<>();
102
    private List<ComponentDescritor> createComponentList = new ArrayList<>();
103
    private List<ComponentDescritor> modifyComponentList = new ArrayList<>();
104
    private List<MenuDescriptor> createMenuList = new ArrayList<>();
105
    private List<MenuDescriptor> removeMenuList = new ArrayList<>();
106
    private List<ActionDescriptor> createActionList = new ArrayList<>();
74 ilm 107
 
108
    // Listeners
181 ilm 109
    private List<ChangeListener> listeners = new ArrayList<>();
74 ilm 110
 
111
    private String name;
112
    private boolean notSaved;
113
    private boolean autoStart;
114
    private boolean isStarted;
115
 
116
    public Extension(String name) {
117
        this.name = name;
118
        this.notSaved = true;
119
    }
120
 
121
    public void clearAll() {
181 ilm 122
        this.elementList.clear();
123
        this.createTableList.clear();
124
        this.modifyTableList.clear();
125
        this.createListList.clear();
126
        this.tableTranslations.clear();
127
        this.fieldTranslations.clear();
128
        this.menuTranslations.clear();
129
        this.actionTranslations.clear();
130
        this.createComponentList.clear();
131
        this.modifyComponentList.clear();
132
        this.createMenuList.clear();
133
        this.removeMenuList.clear();
134
        this.createActionList.clear();
135
        this.listeners.clear();
74 ilm 136
 
181 ilm 137
        this.notSaved = true;
138
        this.autoStart = false;
139
        this.isStarted = false;
74 ilm 140
 
141
    }
142
 
143
    boolean isStarted() {
144
        return this.isStarted;
145
    }
146
 
147
    public boolean isAutoStart() {
181 ilm 148
        return this.autoStart;
74 ilm 149
    }
150
 
86 ilm 151
    public void start(DBRoot root, boolean inModuleStart) throws SQLException {
74 ilm 152
 
153
        // Ensure that database is configured
154
        boolean databaseOk = setupDatabase(root);
155
        if (!databaseOk) {
156
            Log.get().severe("Extension " + this.getName() + " not started due to database error");
157
            return;
158
        }
181 ilm 159
        // Create menus
160
        final MenuAndActions copy = MenuManager.getInstance().copyMenuAndActions();
161
        registerMenuActions(copy);
162
        // Register translations before setting menu
153 ilm 163
        registerTranslations(root);
181 ilm 164
        MenuManager.getInstance().setMenuAndActions(copy);
165
 
74 ilm 166
        Log.get().info("Extension " + this.getName() + " started");
167
        this.isStarted = true;
168
        this.autoStart = true;
169
        fireChanged();
170
    }
171
 
153 ilm 172
    private void registerTranslations(DBRoot root) {
86 ilm 173
        final String locale = Locale.getDefault().toString();
174
        for (MenuTranslation mTranslation : this.menuTranslations) {
175
            if (locale.equals(mTranslation.getLocale())) {
176
                TranslationManager.getInstance().setTranslationForMenu(mTranslation.getId(), mTranslation.getLabel());
177
            }
178
        }
179
        for (ActionTranslation mTranslation : this.actionTranslations) {
180
            if (locale.equals(mTranslation.getLocale())) {
181
                TranslationManager.getInstance().setTranslationForAction(mTranslation.getId(), mTranslation.getLabel());
182
            }
183
        }
184
        for (FieldTranslation mTranslation : this.fieldTranslations) {
185
            if (locale.equals(mTranslation.getLocale())) {
186
                TranslationManager.getInstance().setTranslationForItem(mTranslation.getTableName() + "." + mTranslation.getFieldName(), mTranslation.getLabel());
153 ilm 187
                // TODO: getDescFor SQLFieldTranslator
86 ilm 188
            }
189
        }
190
        for (TableTranslation mTranslation : this.tableTranslations) {
191
            if (locale.equals(mTranslation.getLocale())) {
153 ilm 192
                // FIXME voir avec Sylvain, impossible pour l'instant
193
                SQLElement e = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(mTranslation.getTableName());
194
                e.setDefaultName(createPhrase(mTranslation.getSingular(), mTranslation.getPlural()));
86 ilm 195
            }
196
        }
197
    }
198
 
153 ilm 199
    private static Phrase createPhrase(String singular, String plural) {
200
        final NounClass nounClass;
201
        final String base;
202
        if (singular.startsWith("une ")) {
203
            nounClass = NounClass.FEMININE;
204
            base = singular.substring(4);
205
        } else if (singular.startsWith("un ")) {
206
            nounClass = NounClass.MASCULINE;
207
            base = singular.substring(3);
208
        } else {
209
            nounClass = null;
210
            base = singular;
211
        }
212
        final Phrase res = new Phrase(Grammar_fr.getInstance(), base, nounClass);
213
        if (nounClass != null)
214
            res.putVariant(Grammar.INDEFINITE_ARTICLE_SINGULAR, singular);
215
        res.putVariant(Grammar.PLURAL, plural);
216
        return res;
217
    }
218
 
86 ilm 219
    private void registerMenuActions(MenuAndActions menuAndActions) {
74 ilm 220
        // register actions
153 ilm 221
        for (final MenuDescriptor menuDescriptor : getCreateMenuList()) {
222
            if (menuDescriptor.getType().equals(MenuDescriptor.CREATE)) {
223
                Log.get().info("Registering action for menu creation id:'" + menuDescriptor.getId() + "'");
74 ilm 224
 
86 ilm 225
                menuAndActions.putAction(new CreateFrameAbstractAction() {
226
 
74 ilm 227
                    @Override
228
                    public JFrame createFrame() {
229
 
230
                        JFrame editFrame = new JFrame();
153 ilm 231
                        String componentId = menuDescriptor.getComponentId();
86 ilm 232
                        if (componentId == null) {
153 ilm 233
                            throw new IllegalStateException("No ComponentId for menu " + menuDescriptor.getId());
86 ilm 234
                        }
74 ilm 235
                        ComponentDescritor n = getCreateComponentFromId(componentId);
86 ilm 236
                        if (n == null) {
237
                            throw new IllegalStateException("No ComponentDescritor for " + componentId);
238
                        }
74 ilm 239
                        final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(n.getTable());
240
                        if (t == null) {
241
                            throw new IllegalStateException("No table  " + n.getTable());
242
                        }
243
                        final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
244
 
153 ilm 245
                        final GroupSQLComponent gComponent = new ExtensionGroupSQLComponent(element, n.getGroup());
74 ilm 246
                        editFrame.setTitle(EditFrame.getCreateMessage(element));
247
                        editFrame.setContentPane(new EditPanel(gComponent, EditMode.CREATION));
248
                        editFrame.pack();
249
                        return editFrame;
250
 
251
                    }
153 ilm 252
                }, menuDescriptor.getId(), true);
74 ilm 253
 
153 ilm 254
            } else if (menuDescriptor.getType().equals(MenuDescriptor.LIST)) {
255
                if (menuDescriptor.getListId() != null) {
139 ilm 256
                    menuAndActions.putAction(new CreateFrameAbstractAction() {
74 ilm 257
 
139 ilm 258
                        @Override
259
                        public JFrame createFrame() {
153 ilm 260
                            final String componentId = menuDescriptor.getListId();
139 ilm 261
                            if (componentId == null) {
153 ilm 262
                                throw new IllegalStateException("null ListId for MenuDescriptor " + menuDescriptor.getId());
139 ilm 263
                            }
264
                            final ListDescriptor listDesc = getCreateListFromId(componentId);
265
                            if (listDesc == null) {
266
                                throw new IllegalStateException("No ListDescriptor  " + componentId);
267
                            }
268
                            final SQLTable t = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(listDesc.getMainTable());
269
                            if (t == null) {
270
                                throw new IllegalStateException("No table  " + listDesc.getMainTable());
271
                            }
272
                            final SQLElement element = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElement(t);
273
                            final ListSQLRequest req = new ListSQLRequest(element.getTable(), new ArrayList<String>(0));
153 ilm 274
                            SQLTableModelSourceOnline source = createSource(element, req, listDesc);
86 ilm 275
 
139 ilm 276
                            final IListe list = new IListe(source);
277
                            final IListFrame editFrame = new IListFrame(new ListeAddPanel(element, list));
278
                            editFrame.pack();
279
                            return editFrame;
74 ilm 280
 
139 ilm 281
                        }
153 ilm 282
                    }, menuDescriptor.getId(), true);
139 ilm 283
                }
181 ilm 284
            } else if (menuDescriptor.getType().equals(MenuDescriptor.GROUP)) {
285
                // TODO
74 ilm 286
            } else {
153 ilm 287
                Log.get().warning("unknown type " + menuDescriptor.getType());
74 ilm 288
            }
289
        }
290
 
86 ilm 291
        initMenuGroup(menuAndActions.getGroup());
74 ilm 292
    }
293
 
153 ilm 294
    public SQLTableModelSourceOnline createSource(SQLElement element, ListSQLRequest req, ListDescriptor listDesc) {
295
        final SQLTableModelSourceOnline source = new SQLTableModelSourceOnline(req, element);
296
        final List<SQLTableModelColumn> cols = new ArrayList<>();
297
        for (ColumnDescriptor cDesc : listDesc.getColumns()) {
298
            final String fieldspath = cDesc.getFieldsPaths();
299
            final String[] paths = fieldspath.split(",");
181 ilm 300
            final Set<FieldPath> fps = new LinkedHashSet<>();
153 ilm 301
            for (int i = 0; i < paths.length; i++) {
302
                // LOCAL, id_batiment.id_site.nom
303
                final SQLName name = SQLName.parse(paths[i].trim());
304
 
305
                final PathBuilder p = new PathBuilder(element.getTable());
306
                final int stop = name.getItemCount() - 1;
307
                for (int j = 0; j < stop; j++) {
308
                    String it = name.getItem(j);
309
                    p.addForeignField(it);
310
                }
311
                final FieldPath fp = new FieldPath(p.build(), name.getName());
312
                fps.add(fp);
313
 
314
            }
315
            String columnName = cDesc.getId();
316
            if (!columnName.contains(".")) {
317
                columnName = element.getTable().getTable().getName() + "." + columnName;
318
            }
319
            String tranlatedName = TranslationManager.getInstance().getTranslationForItem(columnName);
320
            if (tranlatedName == null) {
321
                tranlatedName = SQLFieldTranslator.getDefaultDesc(fps.iterator().next().getField()).getTitleLabel();
322
            }
323
            if (tranlatedName == null) {
324
                tranlatedName = cDesc.getId();
325
            }
326
 
327
            cols.add(new BaseSQLTableModelColumn(tranlatedName, String.class) {
328
 
329
                @Override
330
                protected Object show_(SQLRowAccessor r) {
331
                    final List<String> l = new ArrayList<>();
332
                    for (final FieldPath fp : fps) {
333
                        final String string = fp.getString((SQLRowValues) r);
334
                        if (string != null)
335
                            l.add(string);
336
                    }
337
                    return CollectionUtils.join(l, " ");
338
                }
339
 
340
                @Override
341
                public Set<FieldPath> getPaths() {
342
                    return fps;
343
                }
344
            });
345
 
346
        }
347
 
348
        source.getColumns().addAll(cols);
349
        return source;
350
    }
351
 
74 ilm 352
    public void initMenuGroup(final Group group) {
353
        for (MenuDescriptor element : getCreateMenuList()) {
354
            if (element.getType().equals(MenuDescriptor.GROUP)) {
355
                AddGroupModifier add = new AddGroupModifier(element.getId());
356
                if (group.getDescFromID(element.getId()) == null) {
357
                    // only add if not exists
358
                    add.applyOn(group);
359
                }
360
                String menuId = element.getInsertInMenu();
361
                Group dest = (Group) group.getDescFromID(menuId);
362
                if (dest != null) {
363
                    MoveToGroupModifier mode = new MoveToGroupModifier(element.getId(), dest);
364
                    mode.applyOn(group);
365
                } else {
366
                    Log.get().severe("No group " + menuId + " found to move item " + element.getId());
367
                }
368
            }
369
        }
370
        // create items
371
        for (MenuDescriptor element : getCreateMenuList()) {
372
            if (!element.getType().equals(MenuDescriptor.GROUP)) {
373
                AddItemModifier add = new AddItemModifier(element.getId());
374
                if (group.getDescFromID(element.getId()) == null) {
375
                    // only add if not exists
376
                    add.applyOn(group);
377
                }
378
 
379
                String menuId = element.getInsertInMenu();
380
                Group dest = (Group) group.getDescFromID(menuId);
381
                if (dest != null) {
382
                    MoveToGroupModifier mode = new MoveToGroupModifier(element.getId(), dest);
383
                    mode.applyOn(group);
384
                } else {
385
                    Log.get().severe("No group " + menuId + " found to move group " + element.getId());
386
                }
387
            }
388
        }
389
        for (MenuDescriptor element : getRemoveMenuList()) {
390
            String eId = element.getId();
391
            Item item = group.getDescFromID(eId);
392
            if (item != null) {
393
                item.setLocalHint(item.getLocalHint().getBuilder().setVisible(false).build());
394
            } else {
395
                Log.get().severe("No Item " + eId + " found in group " + group.getId());
396
            }
397
        }
398
        System.err.println("Extension.initMenuGroup()" + group.printTree());
399
 
400
    }
401
 
402
    public ComponentDescritor getCreateComponentFromId(String id) {
403
        for (ComponentDescritor menuDescriptor : this.createComponentList) {
404
            if (menuDescriptor.getId().equals(id)) {
405
                return menuDescriptor;
406
            }
407
        }
408
        return null;
409
    }
410
 
411
    private boolean setupDatabase(DBRoot root) throws SQLException {
181 ilm 412
        List<ChangeTable<?>> changesToApply = new ArrayList<>();
413
        List<SQLCreateTable> createToApply = new ArrayList<>();
74 ilm 414
        // Create fields and tables if needed
181 ilm 415
        final List<TableDescritor> t = new ArrayList<>();
74 ilm 416
        t.addAll(this.createTableList);
417
        t.addAll(this.modifyTableList);
181 ilm 418
        Set<String> tableNames = new HashSet<>();
74 ilm 419
        for (TableDescritor tDesc : t) {
420
            String tableName = tDesc.getName();
421
            tableNames.add(tableName);
422
            final SQLTable table = root.getTable(tableName);
423
            final ChangeTable<?> createTable;
424
            if (table == null) {
425
                createTable = new SQLCreateTable(root, tableName);
426
                createToApply.add((SQLCreateTable) createTable);
427
            } else {
428
                createTable = new AlterTable(table);
429
 
430
            }
431
            // fields creation
432
            boolean mustAdd = false;
162 ilm 433
            final Set<String> addedFieldNames = new HashSet<>();
74 ilm 434
            for (FieldDescriptor fDesc : tDesc.getFields()) {
162 ilm 435
                final String fieldName = fDesc.getName();
436
                final SQLField f = (table == null) ? null : table.getFieldRaw(fieldName);
437
                if (f == null && !addedFieldNames.contains(fieldName)) {
74 ilm 438
                    final String type = fDesc.getType();
162 ilm 439
                    addedFieldNames.add(fieldName);
74 ilm 440
                    if (type.equals(FieldDescriptor.TYPE_STRING)) {
441
                        int l = 256;
442
                        try {
443
                            l = Integer.parseInt(fDesc.getLength());
444
                        } catch (Exception e) {
445
                            Log.get().log(Level.WARNING, "Extension: unable to parse length: " + fDesc.getLength(), e);
446
                        }
162 ilm 447
                        createTable.addVarCharColumn(fieldName, l);
74 ilm 448
                    } else if (type.equals(FieldDescriptor.TYPE_INTEGER)) {
449
                        int defaultVal = 0;
450
                        try {
451
                            defaultVal = Integer.parseInt(fDesc.getDefaultValue());
452
                        } catch (Exception e) {
453
                            Log.get().log(Level.WARNING, "Extension: unable to parse default integer value : " + fDesc.getDefaultValue(), e);
454
                        }
162 ilm 455
                        createTable.addIntegerColumn(fieldName, defaultVal);
74 ilm 456
                    } else if (type.equals(FieldDescriptor.TYPE_DECIMAL)) {
457
                        BigDecimal defaultVal = BigDecimal.ZERO;
458
                        try {
459
                            defaultVal = new BigDecimal(fDesc.getDefaultValue());
460
                        } catch (Exception e) {
461
                            Log.get().log(Level.WARNING, "Extension: unable to parse default bigdecimal value : " + fDesc.getDefaultValue(), e);
462
                        }
162 ilm 463
                        createTable.addNumberColumn(fieldName, BigDecimal.class, defaultVal, false);
74 ilm 464
                    } else if (type.equals(FieldDescriptor.TYPE_BOOLEAN)) {
465
                        String defaultValue = "false";
466
                        if (fDesc.getDefaultValue() != null && fDesc.getDefaultValue().equals("true")) {
467
                            defaultValue = "true";
468
                        }
162 ilm 469
                        createTable.addColumn(fieldName, "boolean", defaultValue, false);
74 ilm 470
                    } else if (type.equals(FieldDescriptor.TYPE_DATE)) {
162 ilm 471
                        createTable.addColumn(fieldName, "date");
74 ilm 472
                    } else if (type.equals(FieldDescriptor.TYPE_TIME)) {
162 ilm 473
                        createTable.addColumn(fieldName, "time");
74 ilm 474
                    } else if (type.equals(FieldDescriptor.TYPE_DATETIME)) {
162 ilm 475
                        createTable.addDateAndTimeColumn(fieldName);
74 ilm 476
                    } else if (type.equals(FieldDescriptor.TYPE_REF)) {
477
                        // created later
478
                    }
479
                    mustAdd = true;
480
                } else {
481
                    // Le champs existe, on ne fait rien
482
                    // checker les types
483
                }
484
            }
485
            if (mustAdd && !(createTable instanceof SQLCreateTable)) {
486
                changesToApply.add(createTable);
487
            }
488
        }
489
        // Let's do it
490
        // FIXME : if changesToApply create field that createToApply : bing
491
        if (!createToApply.isEmpty()) {
492
            root.createTables(createToApply);
493
        }
494
        if (!changesToApply.isEmpty()) {
495
            for (String change : ChangeTable.cat(changesToApply)) {
496
                root.getDBSystemRoot().getDataSource().execute(change);
497
            }
498
 
499
        }
500
        // Refetch if needed
501
        if (!changesToApply.isEmpty() || !createToApply.isEmpty()) {
502
            root.getSchema().updateVersion();
503
            root.refetch(tableNames);
504
            Log.get().info("Fetching table changes (" + changesToApply.size() + " fields and " + createToApply.size() + " tables)");
505
        }
506
        // Compute foreign keys to create
507
        changesToApply.clear();
508
        for (TableDescritor tDesc : t) {
509
            final SQLTable table = root.getTable(tDesc.getName());
510
            for (FieldDescriptor fDesc : tDesc.getFields()) {
511
                final SQLField f = (table == null) ? null : table.getFieldRaw(fDesc.getName());
512
                if (f == null && fDesc.getType().equals(FieldDescriptor.TYPE_REF)) {
513
                    final String fTableName = fDesc.getForeignTable();
181 ilm 514
                    if (fTableName == null || fTableName.isEmpty()) {
515
                        JOptionPane.showMessageDialog(new JFrame(),
516
                                "L'extension ne peut pas s'installer car le champs référence " + fDesc.getName() + " de la table " + tDesc.getName() + " ne définit pas de table étrangère");
517
                        return false;
74 ilm 518
                    } else {
181 ilm 519
                        final SQLTable fTable = root.getTable(fTableName);
520
                        if (fTable != null) {
521
                            final AlterTable mTable = new AlterTable(table);
522
                            mTable.addForeignColumn(fDesc.getName(), fTable);
523
                            changesToApply.add(mTable);
524
                        } else {
525
                            JOptionPane.showMessageDialog(new JFrame(), "L'extension ne peut pas s'installer car la table " + fTableName + " n'existe pas.");
526
                            return false;
527
                        }
74 ilm 528
                    }
529
                }
530
            }
531
        }
532
        // Create foreign keys
533
        if (!changesToApply.isEmpty()) {
534
            for (String change : ChangeTable.cat(changesToApply)) {
535
                root.getDBSystemRoot().getDataSource().execute(change);
536
            }
537
            root.getSchema().updateVersion();
538
            root.refetch(tableNames);
539
            Log.get().info("Fetching " + changesToApply.size() + " foreign fields creation");
540
        }
541
        // Create elements for created tables
542
        for (TableDescritor tDesc : t) {
543
 
544
            tDesc.createElement(this);
545
        }
546
        return true;
547
    }
548
 
549
    public void stop() {
550
        this.isStarted = false;
551
        this.autoStart = false;
552
        Log.get().info("Extension " + this.getName() + " stopped");
86 ilm 553
        // TODO : remove menu changes
74 ilm 554
        fireChanged();
555
    }
556
 
557
    public String getName() {
181 ilm 558
        return this.name;
74 ilm 559
    }
560
 
561
    @SuppressWarnings("unchecked")
562
    public void importFromXML(String xml) {
563
 
564
        System.out.println("Extension.importFromXML():" + xml);
565
        if (xml.length() > 0) {
566
            final SAXBuilder sxb = new SAXBuilder();
567
            try {
568
                final Document doc = sxb.build(new StringReader(xml));
569
                final Element root = doc.getRootElement();
570
                if (root.getAttributeValue("autostart", "false").equals("true")) {
571
                    this.autoStart = true;
572
                }
573
                // elements parsing
574
                final List<Element> elements = root.getChildren("element");
575
                for (Element eElement : elements) {
576
                    final String id = eElement.getAttributeValue("id");
577
                    final String tableName = eElement.getAttributeValue("tableName");
578
                    ElementDescriptor eDesc = new ElementDescriptor(id, tableName);
579
                    // TODO : fkeyaction
580
                    this.elementList.add(eDesc);
581
                }
582
                // tables parsing
583
                final List<Element> tables = root.getChildren("table");
584
                for (Element eTable : tables) {
585
                    final String type = eTable.getAttributeValue("type");
586
                    final String name = eTable.getAttributeValue("name");
587
                    final TableDescritor tDesc = new TableDescritor(name);
588
                    final List<Element> fields = eTable.getChildren("field");
589
                    for (Element field : fields) {
590
                        FieldDescriptor f = createFieldDescriptorFrom(name, field);
591
                        tDesc.add(f);
592
                    }
181 ilm 593
                    if (!tDesc.getFields().isEmpty()) {
74 ilm 594
                        if (type.equals("create")) {
595
                            this.createTableList.add(tDesc);
596
                        } else if (type.equals("modify")) {
597
                            this.modifyTableList.add(tDesc);
598
                        } else {
599
                            throw new IllegalStateException("Unknown table type: " + type);
600
                        }
601
                    }
602
 
603
                }
604
                // translations
605
                final List<Element> translations = root.getChildren("translation");
606
                for (Element eTranslation : translations) {
607
                    final String lang = eTranslation.getAttributeValue("locale");
608
                    if (lang == null) {
609
                        throw new IllegalArgumentException("no locale found in translation element");
610
                    }
611
                    final List<Element> tTables = eTranslation.getChildren("element");
612
                    for (Element element : tTables) {
613
                        final String tableName = element.getAttributeValue("refid");
614
                        final TableTranslation t = new TableTranslation(lang, tableName);
615
                        t.setSingular(element.getAttributeValue("singular"));
616
                        t.setPlural(element.getAttributeValue("plural"));
617
                        this.tableTranslations.add(t);
618
                        final List<Element> tFields = element.getChildren("item");
619
                        for (Element elementF : tFields) {
620
                            final FieldTranslation tF = new FieldTranslation(lang, tableName, elementF.getAttributeValue("id"));
621
                            tF.setLabel(elementF.getAttributeValue("label"));
622
                            tF.setDocumentation(elementF.getAttributeValue("doc"));
623
                            this.fieldTranslations.add(tF);
624
                        }
625
                    }
626
 
627
                    final List<Element> tMenu = eTranslation.getChildren("menu");
628
                    for (Element element : tMenu) {
629
                        final MenuTranslation t = new MenuTranslation(lang, element.getAttributeValue("refid"));
630
                        t.setLabel(element.getAttributeValue("label"));
631
                        this.menuTranslations.add(t);
632
                    }
633
                    final List<Element> tActions = eTranslation.getChildren("action");
634
                    for (Element element : tActions) {
635
                        final ActionTranslation t = new ActionTranslation(lang, element.getAttributeValue("refid"));
636
                        t.setLabel(element.getAttributeValue("label"));
637
                        this.actionTranslations.add(t);
638
                    }
639
                }
640
 
641
                // list parsing
642
                final List<Element> lists = root.getChildren("list");
643
                for (Element eList : lists) {
644
                    final String type = eList.getAttributeValue("type");
645
                    final String id = eList.getAttributeValue("id");
646
                    final String refid = eList.getAttributeValue("refid");
647
 
648
                    final ListDescriptor listDesc = new ListDescriptor(id);
649
                    String mainTable = this.getTableNameForElementId(refid);
650
                    if (mainTable == null) {
651
                        // fallback to table name
652
                        mainTable = refid;
653
                    }
654
                    listDesc.setMainTable(mainTable);
655
                    final List<Element> columns = eList.getChildren("column");
656
                    for (Element field : columns) {
181 ilm 657
                        ColumnDescriptor f = createColumnDescriptorFrom(field);
74 ilm 658
                        listDesc.add(f);
659
                    }
660
                    if (listDesc.getColumnCount() > 0) {
661
                        if (type.equals("create")) {
662
                            this.createListList.add(listDesc);
663
                        } else {
664
                            throw new IllegalStateException("Unknown table type: " + type);
665
                        }
666
                    }
667
 
668
                } // component parsing
669
                final List<Element> components = root.getChildren("component");
670
                for (Element eList : components) {
671
                    final String type = eList.getAttributeValue("type");
672
                    if (type.equals("create")) {
673
                        final String id = eList.getAttributeValue("id");
674
                        final String table = eList.getAttributeValue("table");
675
                        final ComponentDescritor tDesc = new ComponentDescritor(id);
676
                        tDesc.setTable(table);
677
                        walkGroup(eList, tDesc.getGroup());
678
                        System.out.println("SimpleXMLAddon.importFromXML() " + tDesc);
679
                        this.createComponentList.add(tDesc);
680
                    }
681
                }
682
                // Menu
683
                final List<Element> menus = root.getChildren("menu");
684
                for (Element eList : menus) {
685
                    final String type = eList.getAttributeValue("type");
686
                    if (type.equals("create")) {
687
                        final List<Element> actions = eList.getChildren("action");
688
                        for (Element action : actions) {
689
                            final String id = action.getAttributeValue("id");
690
                            final String insertInMenu = action.getAttributeValue("insertInMenu");
691
                            final String actionType = action.getAttributeValue("type");
692
                            if (actionType.equals(MenuDescriptor.LIST)) {
693
                                // a list frame
694
                                final String listId = action.getAttributeValue("listId");
695
                                final MenuDescriptor mDesc = new MenuDescriptor(id);
696
                                mDesc.setInsertInMenu(insertInMenu);
697
                                mDesc.setType(actionType);
698
                                mDesc.setListId(listId);
699
                                this.createMenuList.add(mDesc);
700
                            } else if (actionType.equals(MenuDescriptor.CREATE)) {
701
                                // a create frame
702
                                final String componentId = action.getAttributeValue("componentId");
703
                                final MenuDescriptor mDesc = new MenuDescriptor(id);
704
                                mDesc.setInsertInMenu(insertInMenu);
705
                                mDesc.setType(actionType);
706
                                mDesc.setComponentId(componentId);
707
                                this.createMenuList.add(mDesc);
708
                            } else if (actionType.equals(MenuDescriptor.GROUP)) {
709
                                // a create frame
710
                                final MenuDescriptor mDesc = new MenuDescriptor(id);
711
                                mDesc.setInsertInMenu(insertInMenu);
712
                                mDesc.setType(actionType);
713
                                this.createMenuList.add(mDesc);
714
                            } else {
715
                                throw new IllegalStateException("Unknown action type " + actionType + " for action " + id);
716
                            }
717
 
718
                        }
719
                    } else if (type.equals("remove")) {
720
                        final List<Element> actions = eList.getChildren("action");
721
                        for (Element action : actions) {
722
                            final String id = action.getAttributeValue("id");
723
                            this.removeMenuList.add(new MenuDescriptor(id));
724
                        }
725
                    }
726
                }
727
 
728
                // Actions
729
                final List<Element> actions = root.getChildren("action");
730
                for (Element actionElement : actions) {
731
                    final String type = actionElement.getAttributeValue("type");
732
                    if (type.equals("create")) {
733
 
734
                        final String id = actionElement.getAttributeValue("id");
735
                        final String location = actionElement.getAttributeValue("location");
736
                        final String table = actionElement.getAttributeValue("table");
737
                        final String componentId = actionElement.getAttributeValue("componentId");
738
                        ActionDescriptor action = new ActionDescriptor(id);
739
                        action.setLocation(location);
740
                        action.setTable(table);
741
                        action.setComponentId(componentId);
742
                        this.createActionList.add(action);
743
 
744
                    } else {
745
                        // TODO: remove
746
                        throw new IllegalStateException("Unknown action type " + type);
747
                    }
748
 
749
                }
750
 
751
            } catch (Exception e) {
752
                System.err.println("SimpleXMLAddon.importFromXML(): parsing error :" + e.getMessage());
753
                e.printStackTrace();
754
            }
755
        }
181 ilm 756
        this.notSaved = false;
74 ilm 757
 
758
        fireChanged();
759
    }
760
 
761
    String toXML() {
762
        final Element rootElement = new Element("extension");
763
        rootElement.setAttribute("id", this.name);
764
        rootElement.setAttribute("autostart", String.valueOf(this.isStarted));
765
        rootElement.setAttribute("format", "1.0");
766
        final Document document = new Document(rootElement);
767
 
768
        // Element
769
        for (ElementDescriptor eDescriptor : this.elementList) {
770
            final Element eElement = new Element("element");
771
            eElement.setAttribute("tableName", eDescriptor.getTableName());
772
            eElement.setAttribute("id", eDescriptor.getId());
773
            // TODO: fkey action : <fkeyaction action="set_empty|cascade|restrict"
774
            // fields="id_language"/>
775
            rootElement.addContent(eElement);
776
        }
777
 
778
        // Table create
779
        for (TableDescritor tDescriptor : this.createTableList) {
780
            final Element eTable = new Element("table");
781
            eTable.setAttribute("type", "create");
782
            eTable.setAttribute("name", tDescriptor.getName());
783
            for (FieldDescriptor fDescriptor : tDescriptor.getFields()) {
784
                final Element eField = new Element("field");
785
                eField.setAttribute("name", fDescriptor.getName());
786
                eField.setAttribute("type", fDescriptor.getType());
787
                if (fDescriptor.getLength() != null) {
788
                    eField.setAttribute("length", fDescriptor.getLength());
789
                }
790
                if (fDescriptor.getDefaultValue() != null) {
791
                    eField.setAttribute("default", fDescriptor.getDefaultValue());
792
                }
793
                if (fDescriptor.getForeignTable() != null) {
794
                    eField.setAttribute("ftable", fDescriptor.getForeignTable());
795
                }
796
                eTable.addContent(eField);
797
            }
798
            rootElement.addContent(eTable);
799
        }
800
 
801
        // Table modify
802
        for (TableDescritor tDescriptor : this.modifyTableList) {
803
            final Element eTable = new Element("table");
804
            eTable.setAttribute("type", "modify");
805
            eTable.setAttribute("name", tDescriptor.getName());
806
            for (FieldDescriptor fDescriptor : tDescriptor.getFields()) {
807
                final Element eField = new Element("field");
808
                eField.setAttribute("name", fDescriptor.getName());
809
                eField.setAttribute("type", fDescriptor.getType());
810
                if (fDescriptor.getLength() != null) {
811
                    eField.setAttribute("length", fDescriptor.getLength());
812
                }
813
                if (fDescriptor.getDefaultValue() != null) {
814
                    eField.setAttribute("default", fDescriptor.getDefaultValue());
815
                }
816
                if (fDescriptor.getForeignTable() != null) {
817
                    eField.setAttribute("ftable", fDescriptor.getForeignTable());
818
                }
819
                eTable.addContent(eField);
820
            }
821
            rootElement.addContent(eTable);
822
        }
823
        // Translations
181 ilm 824
        final HashSet<String> locales = new HashSet<>();
825
        for (Translation tr : this.tableTranslations) {
74 ilm 826
            locales.add(tr.getLocale());
827
        }
181 ilm 828
        for (Translation tr : this.fieldTranslations) {
74 ilm 829
            locales.add(tr.getLocale());
830
        }
181 ilm 831
        for (Translation tr : this.menuTranslations) {
74 ilm 832
            locales.add(tr.getLocale());
833
        }
181 ilm 834
        for (Translation tr : this.actionTranslations) {
74 ilm 835
            locales.add(tr.getLocale());
836
        }
181 ilm 837
        final List<String> lLocales = new ArrayList<>(locales);
74 ilm 838
        Collections.sort(lLocales);
839
        for (String locale : lLocales) {
840
            final Element eTranslation = new Element("translation");
841
            eTranslation.setAttribute("locale", locale);
842
            rootElement.addContent(eTranslation);
843
            // Tables
181 ilm 844
            for (TableTranslation tTranslation : this.tableTranslations) {
74 ilm 845
                if (tTranslation.getLocale().equals(locale)) {
846
                    final Element eTable = new Element("element");
847
                    eTable.setAttribute("refid", tTranslation.getTableName());
848
                    final String singular = tTranslation.getSingular();
849
                    if (singular != null && !singular.isEmpty()) {
850
                        eTable.setAttribute("singular", singular);
851
                    }
852
                    final String plural = tTranslation.getPlural();
853
                    if (plural != null && !plural.isEmpty()) {
854
                        eTable.setAttribute("plural", plural);
855
                    }
181 ilm 856
                    for (FieldTranslation fTranslation : this.fieldTranslations) {
74 ilm 857
                        // Fields
858
                        if (fTranslation.getLocale().equals(locale) && fTranslation.getTableName().equals(tTranslation.getTableName())) {
859
                            final Element eField = new Element("item");
860
                            eField.setAttribute("id", fTranslation.getFieldName());
861
                            eField.setAttribute("label", fTranslation.getLabel());
862
                            if (fTranslation.getDocumentation() != null) {
863
                                eField.setAttribute("doc", fTranslation.getDocumentation());
864
                            }
865
                            eTable.addContent(eField);
866
                        }
867
                    }
868
                    eTranslation.addContent(eTable);
869
 
870
                }
871
            }
872
            // Menus
181 ilm 873
            for (MenuTranslation tMenu : this.menuTranslations) {
74 ilm 874
                if (tMenu.getLocale().equals(locale)) {
875
                    final Element eMenu = new Element("menu");
876
                    eMenu.setAttribute("refid", tMenu.getId());
877
                    eMenu.setAttribute("label", tMenu.getLabel());
878
                    eTranslation.addContent(eMenu);
879
                }
880
            }
881
 
882
            // Actions
181 ilm 883
            for (ActionTranslation tAction : this.actionTranslations) {
74 ilm 884
                if (tAction.getLocale().equals(locale)) {
885
                    final Element eMenu = new Element("action");
886
                    eMenu.setAttribute("refid", tAction.getId());
887
                    eMenu.setAttribute("label", tAction.getLabel());
888
                    eTranslation.addContent(eMenu);
889
                }
890
            }
891
        }
892
 
893
        // Actions
894
        for (ActionDescriptor action : this.createActionList) {
895
            final Element eAction = new Element("action");
896
            eAction.setAttribute("type", "create");
897
            eAction.setAttribute("id", action.getId());
898
            eAction.setAttribute("location", action.getLocation());
899
            eAction.setAttribute("table", action.getTable());
900
            eAction.setAttribute("componentId", action.getComponentId());
901
            rootElement.addContent(eAction);
902
        }
903
        // Menu create
904
        if (!this.createMenuList.isEmpty()) {
905
            final Element eMenu = new Element("menu");
906
            eMenu.setAttribute("type", "create");
907
            for (MenuDescriptor menu : this.createMenuList) {
908
                final Element eActionMenu = new Element("action");
909
                eActionMenu.setAttribute("id", menu.getId());
910
                eActionMenu.setAttribute("insertInMenu", menu.getInsertInMenu());
911
                final String type = menu.getType();
912
                eActionMenu.setAttribute("type", type);
913
                if (!type.equals(MenuDescriptor.CREATE) && !type.equals(MenuDescriptor.LIST) && !type.equals(MenuDescriptor.GROUP)) {
914
                    throw new IllegalStateException("Menu type " + type + " not supported");
915
                }
916
 
917
                if (type.endsWith("list") && menu.getListId() != null) {
918
                    eActionMenu.setAttribute("listId", menu.getListId());
919
                } else if (type.endsWith("create") && menu.getComponentId() != null) {
920
                    eActionMenu.setAttribute("componentId", menu.getComponentId());
921
                }
922
                eMenu.addContent(eActionMenu);
923
            }
924
            rootElement.addContent(eMenu);
925
 
926
        }
927
        // Menu remove
928
        if (!this.removeMenuList.isEmpty()) {
929
            final Element eMenu = new Element("menu");
930
            eMenu.setAttribute("type", "remove");
931
            for (MenuDescriptor menu : this.removeMenuList) {
932
                final Element eActionMenu = new Element("action");
933
                eActionMenu.setAttribute("id", menu.getId());
934
                eMenu.addContent(eActionMenu);
935
            }
936
            rootElement.addContent(eMenu);
937
        }
938
        // List create
939
        for (ListDescriptor listDescriptor : this.createListList) {
940
            final Element eList = new Element("list");
941
            eList.setAttribute("type", "create");
942
            eList.setAttribute("id", listDescriptor.getId());
943
            String refFromTable = getRefFromTable(listDescriptor.getMainTable());
944
            if (refFromTable == null) {
945
                refFromTable = listDescriptor.getMainTable();
946
            }
947
            if (refFromTable != null) {
948
                eList.setAttribute("refid", refFromTable);
949
                for (ColumnDescriptor fieldDescriptor : listDescriptor.getColumns()) {
950
                    final Element eField = new Element("column");
951
                    eField.setAttribute("id", fieldDescriptor.getId());
952
                    eField.setAttribute("fields", fieldDescriptor.getFieldsPaths());
953
                    eField.setAttribute("style", fieldDescriptor.getStyle());
954
                    eList.addContent(eField);
955
                }
956
 
957
                rootElement.addContent(eList);
958
            }
959
 
960
        }
961
        // Component create
962
        for (ComponentDescritor componentDescriptor : this.createComponentList) {
963
            final Element eComponent = new Element("component");
964
            eComponent.setAttribute("type", "create");
965
            eComponent.setAttribute("id", componentDescriptor.getId());
966
            eComponent.setAttribute("table", componentDescriptor.getTable());
967
            appendGroup(eComponent, componentDescriptor.getGroup());
968
 
969
            rootElement.addContent(eComponent);
970
        }
971
        // Component modify
972
        for (ComponentDescritor componentDescriptor : this.modifyComponentList) {
973
            System.out.println(componentDescriptor);
974
            throw new IllegalAccessError("Not yet implemented");
975
        }
976
        // Output
977
        XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
978
        final ByteArrayOutputStream bOut = new ByteArrayOutputStream();
979
        final BufferedOutputStream oStream = new BufferedOutputStream(bOut);
980
        try {
981
            out.output(document, oStream);
982
        } catch (IOException e) {
983
            e.printStackTrace();
984
        } finally {
985
            try {
986
                oStream.close();
987
            } catch (IOException e) {
988
                e.printStackTrace();
989
            }
990
        }
991
        try {
992
            return bOut.toString("utf8");
993
        } catch (UnsupportedEncodingException e) {
994
            e.printStackTrace();
995
            return "";
996
        }
997
    }
998
 
999
    private void appendGroup(Element eComponent, Group group) {
1000
        int size = group.getSize();
1001
        for (int i = 0; i < size; i++) {
1002
            Item it = group.getItem(i);
1003
            final Element gr;
1004
            if (it instanceof Group) {
1005
                gr = new Element("group");
1006
                appendGroup(gr, (Group) it);
1007
            } else {
1008
                gr = new Element("item");
1009
            }
1010
            gr.setAttribute("id", it.getId());
1011
            if (it.getLocalHint() != null) {
1012
                final LayoutHints hints = it.getLocalHint();
1013
                final String type;
1014
                if (hints.largeWidth()) {
1015
                    type = "verylarge";
1016
                } else if (hints.fillWidth()) {
1017
                    type = "large";
1018
                } else {
1019
                    type = "normal";
1020
                }
1021
                gr.setAttribute("type", type);
1022
                if (hints.isSeparated()) {
1023
                    gr.setAttribute("isSeparated", "true");
1024
                }
1025
                if (hints.showLabel()) {
1026
                    gr.setAttribute("showLabel", "true");
1027
                }
1028
            }
1029
 
1030
            eComponent.addContent(gr);
1031
 
1032
        }
1033
 
1034
    }
1035
 
1036
    private void walkGroup(Element e, Group group) {
1037
        @SuppressWarnings("unchecked")
1038
        final List<Element> elements = e.getChildren();
1039
        for (Element element : elements) {
1040
            String id = element.getAttributeValue("id", "unknown");
1041
            String type = element.getAttributeValue("type", "default");
1042
            String showLabel = element.getAttributeValue("showLabel", "true");
1043
            String isSeparated = element.getAttributeValue("isSeparated", "false");
1044
            if (element.getName().equals("item")) {
1045
                final Item it = new Item(id);
1046
                if (type.equals("large")) {
1047
                    it.setLocalHint(new LayoutHints(false, false, showLabel.equals("true"), isSeparated.equals("true"), true, false));
1048
                } else if (type.equals("verylarge")) {
1049
                    it.setLocalHint(new LayoutHints(true, false, showLabel.equals("true"), isSeparated.equals("true"), true, false));
1050
                } else {
1051
                    it.setLocalHint(new LayoutHints(false, false, showLabel.equals("true"), isSeparated.equals("true"), false, false));
1052
                }
1053
                System.out.println("Extension.walkGroup()" + it + " " + it.getLocalHint() + " from " + type);
1054
                group.add(it);
1055
 
1056
            } else if (element.getName().equals("group")) {
1057
                final Group g = new Group(id);
1058
                group.add(g);
1059
                walkGroup(element, g);
1060
            } else {
1061
                throw new IllegalStateException("Unknown element: " + element.getName());
1062
            }
1063
        }
1064
    }
1065
 
1066
    private FieldDescriptor createFieldDescriptorFrom(String table, Element field) {
1067
        FieldDescriptor f = new FieldDescriptor(table, field.getAttributeValue("name"), field.getAttributeValue("type"), field.getAttributeValue("default"), field.getAttributeValue("length"),
1068
                field.getAttributeValue("ftable"));
1069
        Element child = field.getChild("field");
1070
        if (child != null) {
1071
            f.setLink(createFieldDescriptorFrom(field.getAttributeValue("ftable"), child));
1072
        }
1073
        return f;
1074
    }
1075
 
181 ilm 1076
    private ColumnDescriptor createColumnDescriptorFrom(Element field) {
74 ilm 1077
        final ColumnDescriptor f = new ColumnDescriptor(field.getAttributeValue("id"));
1078
        f.setFieldsPaths(field.getAttributeValue("fields"));
1079
        f.setStyle(field.getAttributeValue("style"));
1080
        return f;
1081
    }
1082
 
1083
    private void fireChanged() {
181 ilm 1084
        for (ChangeListener listener : this.listeners) {
74 ilm 1085
            listener.stateChanged(new ChangeEvent(this));
1086
        }
1087
 
1088
    }
1089
 
1090
    public List<TableDescritor> getCreateTableList() {
181 ilm 1091
        return this.createTableList;
74 ilm 1092
    }
1093
 
1094
    public void addCreateTable(TableDescritor value) {
1095
        this.createTableList.add(value);
1096
        setChanged();
1097
    }
1098
 
1099
    public void removeCreateTable(TableDescritor value) {
1100
        this.createTableList.remove(value);
1101
        setChanged();
1102
    }
1103
 
1104
    public List<TableDescritor> getModifyTableList() {
181 ilm 1105
        return this.modifyTableList;
74 ilm 1106
    }
1107
 
1108
    public List<ListDescriptor> getCreateListList() {
181 ilm 1109
        return this.createListList;
74 ilm 1110
    }
1111
 
1112
    public ListDescriptor getCreateListFromId(String id) {
1113
        for (ListDescriptor listDescriptor : this.createListList) {
1114
            if (listDescriptor.getId().equals(id)) {
1115
                return listDescriptor;
1116
            }
1117
        }
1118
        return null;
1119
    }
1120
 
1121
    public void addCreateList(ListDescriptor item) {
1122
        this.createListList.add(item);
1123
        setChanged();
1124
 
1125
    }
1126
 
1127
    public void removeCreateList(ListDescriptor item) {
1128
        this.createListList.remove(item);
1129
        setChanged();
1130
    }
1131
 
1132
    public void addChangeListener(ChangeListener listener) {
1133
        if (!this.listeners.contains(listener))
1134
            this.listeners.add(listener);
1135
 
1136
    }
1137
 
1138
    public TableDescritor getOrCreateTableDescritor(String tableName) {
1139
 
1140
        for (TableDescritor td : this.modifyTableList) {
1141
            if (td.getName().equalsIgnoreCase(tableName)) {
1142
                return td;
1143
            }
1144
        }
1145
        // create table descritor for the table
1146
        final TableDescritor td = new TableDescritor(tableName);
1147
        this.modifyTableList.add(td);
1148
        setChanged();
1149
        return td;
1150
    }
1151
 
1152
    public SQLTable getSQLTable(TableDescritor tableDesc) {
1153
        try {
181 ilm 1154
            return ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(tableDesc.getName());
74 ilm 1155
        } catch (Exception e) {
1156
            return null;
1157
        }
1158
    }
1159
 
1160
    public boolean isNotSaved() {
1161
        return this.notSaved;
1162
    }
1163
 
1164
    public void setChanged() {
1165
        this.notSaved = true;
1166
        this.fireChanged();
1167
        String xml = this.toXML();
1168
        System.out.println(xml);
1169
    }
1170
 
1171
    // FIXME: filter textfield pour eviter les pb d'insert/update
1172
    // TODO: eviter les doublons lors du renommage
1173
 
1174
    public void save() {
1175
        String xml = this.toXML();
1176
        System.out.println(xml);
1177
        // insert new version
1178
        final SQLTable extensionTable = getExtensionTable();
1179
        SQLRowValues v = new SQLRowValues(extensionTable);
1180
        v.put("IDENTIFIER", this.getName());
153 ilm 1181
        v.put("XML", xml);
74 ilm 1182
        try {
153 ilm 1183
            // delete old version
1184
            deleteFromDB();
74 ilm 1185
            v.insert();
1186
            this.notSaved = false;
1187
        } catch (SQLException e) {
1188
            e.printStackTrace();
1189
            JOptionPane.showMessageDialog(new JFrame(), "Error while saving extension");
1190
        }
1191
 
1192
        this.fireChanged();
1193
    }
1194
 
1195
    private SQLTable getExtensionTable() {
1196
        return ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTable(ExtensionBuilderModule.TABLE_NAME);
1197
    }
1198
 
1199
    private void deleteFromDB() {
1200
        final SQLTable extensionTable = getExtensionTable();
1201
        String query = "DELETE FROM " + extensionTable.getSQL() + " WHERE \"IDENTIFIER\" = " + SQLBase.quoteStringStd(this.getName());
1202
        extensionTable.getDBSystemRoot().getDataSource().execute(query);
1203
    }
1204
 
1205
    public List<String> getAllKnownTableNames() {
181 ilm 1206
        final List<String> l = new ArrayList<>();
1207
        final Set<String> s = new HashSet<>();
74 ilm 1208
        for (SQLTable t : AllTableListModel.getAllDatabaseTables()) {
1209
            s.add(t.getName());
1210
        }
1211
        for (TableDescritor td : this.getCreateTableList()) {
1212
            s.add(td.getName());
1213
        }
1214
        s.remove("FWK_MODULE_METADATA");
1215
        s.remove("FWK_SCHEMA_METADATA");
1216
        s.remove("FWK_UNDEFINED_IDS");
1217
        s.remove(ExtensionBuilderModule.TABLE_NAME);
1218
        l.addAll(s);
1219
        Collections.sort(l, new Comparator<String>() {
1220
            @Override
1221
            public int compare(String o1, String o2) {
1222
                return o1.compareToIgnoreCase(o2);
1223
            }
1224
        });
1225
 
1226
        return l;
1227
    }
1228
 
1229
    public TableDescritor getTableListDescriptor(String tableName) {
1230
        for (TableDescritor td : this.createTableList) {
1231
            if (td.getName().equalsIgnoreCase(tableName)) {
1232
                return td;
1233
            }
1234
        }
1235
        return null;
1236
    }
1237
 
1238
    public List<String> getTranslatedFieldOfTable(String tableName) {
181 ilm 1239
        final List<String> l = new ArrayList<>();
74 ilm 1240
        for (FieldTranslation tr : this.fieldTranslations) {
1241
            if (tr.getTableName().equals(tableName)) {
1242
                l.add(tr.getFieldName());
1243
            }
1244
        }
1245
        return l;
1246
    }
1247
 
1248
    public TableTranslation getTableTranslation(String lang, String tableName) {
1249
        for (TableTranslation tr : this.tableTranslations) {
1250
            if (tr.getLocale().equals(lang) && tr.getTableName().equals(tableName)) {
1251
                return tr;
1252
            }
1253
        }
1254
        return null;
1255
    }
1256
 
1257
    public String getFieldTranslation(String lang, String tableName, String fName) {
1258
        for (FieldTranslation tr : this.fieldTranslations) {
1259
            if (tr.getLocale().equals(lang) && tr.getTableName().equals(tableName) && tr.getFieldName().equals(fName)) {
1260
                return tr.getLabel();
1261
            }
1262
        }
1263
        return null;
1264
    }
1265
 
1266
    public List<ComponentDescritor> getCreateComponentList() {
1267
        return this.createComponentList;
1268
    }
1269
 
1270
    public void addCreateComponent(ComponentDescritor desc) {
1271
        this.createComponentList.add(desc);
1272
    }
1273
 
1274
    public void removeCreateComponent(ComponentDescritor desc) {
1275
        this.createComponentList.remove(desc);
1276
        setChanged();
1277
    }
1278
 
1279
    public List<MenuDescriptor> getCreateMenuList() {
181 ilm 1280
        return this.createMenuList;
74 ilm 1281
    }
1282
 
1283
    public void addCreateMenu(MenuDescriptor desc) {
1284
        this.createMenuList.add(desc);
1285
    }
1286
 
1287
    public MenuDescriptor getCreateMenuItemFromId(String id) {
1288
        for (MenuDescriptor menuDescriptor : this.createMenuList) {
1289
            if (menuDescriptor.getId().equals(id)) {
1290
                return menuDescriptor;
1291
            }
1292
        }
1293
        return null;
1294
    }
1295
 
1296
    public List<MenuDescriptor> getRemoveMenuList() {
181 ilm 1297
        return this.removeMenuList;
74 ilm 1298
    }
1299
 
1300
    public void addRemoveMenu(MenuDescriptor desc) {
1301
        this.removeRemoveMenuForId(desc.getId());
1302
        this.removeMenuList.add(desc);
1303
    }
1304
 
1305
    public List<String> getAllKnownFieldName(String tableName) {
181 ilm 1306
        final Set<String> l = new HashSet<>();
74 ilm 1307
        // fields created in the extension
1308
 
1309
        final List<TableDescritor> desc = getCreateTableList();
1310
        for (TableDescritor tableDescritor : desc) {
1311
            if (tableDescritor.getName().equals(tableName)) {
1312
                final List<FieldDescriptor> fDescs = tableDescritor.getFields();
1313
                for (FieldDescriptor fieldDescriptor : fDescs) {
1314
                    l.add(fieldDescriptor.getName());
1315
                }
1316
            }
1317
        }
1318
        // + champs dans la base
1319
        final Set<SQLTable> tables = ComptaPropsConfiguration.getInstanceCompta().getRootSociete().getTables();
1320
        for (SQLTable sqlTable : tables) {
1321
            final String tName = sqlTable.getName();
1322
            if (tName.equals(tableName)) {
1323
                Set<String> f = sqlTable.getFieldsName();
1324
                for (String string : f) {
1325
                    l.add(string);
1326
                }
1327
 
1328
            }
1329
        }
1330
 
181 ilm 1331
        return new ArrayList<>(l);
74 ilm 1332
    }
1333
 
1334
    public List<String> getAllKnownActionNames() {
181 ilm 1335
        final Set<String> s = new HashSet<>();
74 ilm 1336
        Collection<SQLElement> elements = ComptaPropsConfiguration.getInstanceCompta().getDirectory().getElements();
1337
        for (SQLElement element : elements) {
1338
            Collection<IListeAction> actions = element.getRowActions();
1339
            for (IListeAction action : actions) {
1340
                if (action instanceof RowAction) {
1341
                    RowAction rAction = (RowAction) action;
1342
                    final String id = rAction.getID();
1343
                    if (id != null)
1344
                        s.add(id);
1345
                }
1346
            }
1347
        }
181 ilm 1348
        final List<String> list = new ArrayList<>(s);
1349
        Collections.sort(list);
1350
        return list;
74 ilm 1351
    }
1352
 
1353
    public List<String> getActionNames() {
181 ilm 1354
        ArrayList<String> s = new ArrayList<>();
74 ilm 1355
        for (ActionDescriptor action : this.createActionList) {
1356
            s.add(action.getId());
1357
        }
1358
        Collections.sort(s);
1359
        return s;
1360
    }
1361
 
1362
    public List<ActionDescriptor> getActionDescriptors() {
1363
        Collections.sort(this.createActionList, new Comparator<ActionDescriptor>() {
1364
 
1365
            @Override
1366
            public int compare(ActionDescriptor o1, ActionDescriptor o2) {
1367
                return o1.getId().compareTo(o2.getId());
1368
            }
1369
        });
1370
        return this.createActionList;
1371
    }
1372
 
181 ilm 1373
    public void addCreateAction(ActionDescriptor obj) {
1374
        this.createActionList.add(obj);
1375
        setChanged();
1376
    }
1377
 
1378
    public void removeCreateAction(ActionDescriptor obj) {
1379
        this.createActionList.remove(obj);
1380
        setChanged();
1381
    }
1382
 
74 ilm 1383
    public boolean isEmpty() {
181 ilm 1384
        return this.createTableList.isEmpty() && this.modifyTableList.isEmpty() && this.createListList.isEmpty() && this.tableTranslations.isEmpty() && this.fieldTranslations.isEmpty()
1385
                && this.menuTranslations.isEmpty() && this.actionTranslations.isEmpty() && this.createComponentList.isEmpty() && this.modifyComponentList.isEmpty() && this.createMenuList.isEmpty()
1386
                && this.removeMenuList.isEmpty() && this.createActionList.isEmpty();
74 ilm 1387
    }
1388
 
1389
    public String getTableNameForElementId(String id) {
1390
        for (ElementDescriptor element : this.elementList) {
1391
            if (element.getId().equals(id)) {
1392
                return element.getTableName();
1393
            }
1394
        }
1395
        return null;
1396
    }
1397
 
1398
    private String getRefFromTable(String table) {
1399
        for (ElementDescriptor element : this.elementList) {
1400
            if (element.getTableName().equals(table)) {
1401
                return element.getId();
1402
            }
1403
        }
1404
        return null;
1405
    }
1406
 
1407
    public List<MenuTranslation> getMenuTranslations() {
181 ilm 1408
        return this.menuTranslations;
74 ilm 1409
    }
1410
 
181 ilm 1411
    public MenuTranslation getMenuTranslation(String menuId, String locale) {
1412
        for (MenuTranslation tr : this.menuTranslations) {
1413
            if (tr.getId().equals(menuId) && tr.getLocale().equals(locale)) {
1414
                return tr;
1415
            }
1416
        }
1417
        return null;
1418
    }
1419
 
74 ilm 1420
    public List<ActionTranslation> getActionTranslations() {
181 ilm 1421
        return this.actionTranslations;
74 ilm 1422
    }
1423
 
1424
    public List<FieldTranslation> getFieldTranslations() {
181 ilm 1425
        return this.fieldTranslations;
74 ilm 1426
    }
1427
 
1428
    public void removeChangeListener(ChangeListener listener) {
1429
        this.listeners.remove(listener);
1430
 
1431
    }
1432
 
1433
    public void setName(String name) {
1434
        if (!name.equals(this.name)) {
1435
            deleteFromDB();
1436
            this.name = name;
1437
            save();
1438
            setChanged();
1439
        }
1440
    }
1441
 
1442
    public void setupMenu(MenuContext ctxt) {
1443
        final Group group = ctxt.getMenuAndActions().getGroup();
1444
        initMenuGroup(group);
86 ilm 1445
        registerMenuActions(ctxt.getMenuAndActions());
74 ilm 1446
    }
1447
 
1448
    public void removeRemoveMenuForId(String id) {
181 ilm 1449
        for (int i = this.removeMenuList.size() - 1; i >= 0; i--) {
1450
            final MenuDescriptor m = this.removeMenuList.get(i);
74 ilm 1451
            if (m.getId().equals(id)) {
181 ilm 1452
                this.removeMenuList.remove(i);
74 ilm 1453
            }
1454
        }
1455
 
1456
    }
1457
 
1458
    public void removeCreateMenuForId(String id) {
181 ilm 1459
        for (int i = this.createMenuList.size() - 1; i >= 0; i--) {
1460
            final MenuDescriptor m = this.createMenuList.get(i);
74 ilm 1461
            if (m.getId().equals(id)) {
181 ilm 1462
                this.createMenuList.remove(i);
74 ilm 1463
            }
1464
        }
1465
 
1466
    }
1467
 
1468
    public MenuDescriptor getRemoveMenuItemFromId(String itemId) {
181 ilm 1469
        for (MenuDescriptor m : this.removeMenuList) {
74 ilm 1470
            if (m.getId().equals(itemId)) {
1471
                return m;
1472
            }
1473
        }
1474
        return null;
1475
    }
1476
 
1477
    public void renameMenuItem(String previousId, String newId) {
1478
        if (!previousId.equals(newId)) {
181 ilm 1479
            final List<MenuDescriptor> descs = new ArrayList<>(this.createMenuList.size() + this.removeMenuList.size());
1480
            descs.addAll(this.createMenuList);
1481
            descs.addAll(this.removeMenuList);
74 ilm 1482
            for (MenuDescriptor m : descs) {
1483
                if (m.getId().equals(previousId)) {
1484
                    m.setId(newId);
1485
                }
1486
            }
1487
 
1488
        }
1489
 
1490
    }
1491
 
1492
    public void moveMenuItem(String itemId, String parentId) {
181 ilm 1493
        for (MenuDescriptor m : this.createMenuList) {
74 ilm 1494
            if (m.getId().equals(itemId)) {
1495
                m.setInsertInMenu(parentId);
1496
            }
1497
        }
1498
 
1499
    }
86 ilm 1500
 
1501
    public void setMenuTranslation(String id, String text, Locale locale) {
1502
        MenuTranslation mTranslation = null;
1503
        for (MenuTranslation mTr : this.menuTranslations) {
1504
            if (mTr.getId().equals(id) && mTr.getLocale().equals(locale.toString())) {
1505
                mTranslation = mTr;
1506
                break;
1507
            }
1508
 
1509
        }
1510
        if (mTranslation == null) {
1511
            mTranslation = new MenuTranslation(locale.toString(), id);
1512
            this.menuTranslations.add(mTranslation);
1513
        }
1514
        mTranslation.setLabel(text);
1515
 
1516
    }
139 ilm 1517
 
1518
    private TableTranslation getTableTranslation(String tableName, Locale locale) {
1519
        TableTranslation tTranslation = null;
1520
        for (TableTranslation mTr : this.tableTranslations) {
1521
            if (mTr.getTableName().equals(tableName) && mTr.getLocale().equals(locale.toString())) {
1522
                tTranslation = mTr;
1523
                break;
1524
            }
1525
        }
1526
        if (tTranslation == null) {
1527
            tTranslation = new TableTranslation(locale.toString(), tableName);
1528
            this.tableTranslations.add(tTranslation);
1529
        }
1530
        return tTranslation;
1531
    }
1532
 
1533
    public void setTableSingularTranslation(String tableName, Locale locale, String text) {
1534
        TableTranslation mTranslation = getTableTranslation(tableName, locale);
1535
        mTranslation.setSingular(text);
1536
 
1537
    }
1538
 
1539
    public void setTablePluralTranslation(String tableName, Locale locale, String text) {
1540
        TableTranslation mTranslation = getTableTranslation(tableName, locale);
1541
        mTranslation.setPlural(text);
1542
 
1543
    }
1544
 
1545
    public void setFieldTranslation(String tableName, String fieldName, Locale locale, String text) {
1546
        FieldTranslation fTranslation = null;
1547
        for (FieldTranslation mTr : this.fieldTranslations) {
1548
            if (mTr.getTableName().equals(tableName) && mTr.getFieldName().equals(fieldName) && mTr.getLocale().equals(locale.toString())) {
1549
                fTranslation = mTr;
1550
                break;
1551
            }
1552
        }
1553
        if (fTranslation == null) {
1554
            fTranslation = new FieldTranslation(locale.toString(), tableName, fieldName);
1555
            this.fieldTranslations.add(fTranslation);
1556
        }
1557
        fTranslation.setLabel(text);
1558
 
1559
    }
181 ilm 1560
 
74 ilm 1561
}