Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / featureform / swing / impl / DefaultJFeaturesForm.java @ 44156

History | View | Annotate | Download (19 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2014 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.featureform.swing.impl;
24

    
25
import java.awt.BorderLayout;
26
import java.awt.Dimension;
27
import java.awt.event.ActionEvent;
28
import java.io.File;
29
import java.util.ArrayList;
30
import java.util.List;
31
import javax.swing.AbstractAction;
32
import javax.swing.Action;
33

    
34
import javax.swing.JComponent;
35
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37
import org.apache.commons.lang3.StringUtils;
38
import org.gvsig.expressionevaluator.Expression;
39
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
40

    
41
import org.slf4j.Logger;
42
import org.slf4j.LoggerFactory;
43

    
44
import org.gvsig.featureform.swing.JFeaturesForm;
45
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataServerExplorer;
47
import org.gvsig.fmap.dal.exception.DataException;
48
import org.gvsig.fmap.dal.feature.Feature;
49
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
50
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
51
import org.gvsig.fmap.dal.feature.FeatureQuery;
52
import org.gvsig.fmap.dal.feature.FeatureStore;
53
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
54
import org.gvsig.fmap.dal.feature.FeatureType;
55
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
56
import org.gvsig.fmap.dal.swing.DALSwingLocator;
57
import org.gvsig.fmap.dal.swing.DataSwingManager;
58
import org.gvsig.tools.ToolsLocator;
59
import org.gvsig.tools.dataTypes.DataTypes;
60
import org.gvsig.tools.dynform.AbortActionException;
61
import org.gvsig.tools.dynform.DynFormDefinition;
62
import org.gvsig.tools.dynform.DynFormFieldDefinition;
63
import org.gvsig.tools.dynform.DynFormLocator;
64
import org.gvsig.tools.dynform.DynFormManager;
65
import org.gvsig.tools.dynform.JDynFormSet;
66
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
67
import org.gvsig.tools.dynobject.DynClass;
68
import org.gvsig.tools.dynobject.DynObject;
69
import org.gvsig.tools.dynobject.DynStruct_v2;
70
import org.gvsig.tools.dynobject.Tags;
71
import org.gvsig.tools.exception.BaseException;
72
import org.gvsig.tools.i18n.I18nManager;
73
import org.gvsig.tools.observer.Observable;
74
import org.gvsig.tools.observer.Observer;
75
import org.gvsig.tools.service.ServiceException;
76
import org.gvsig.tools.swing.api.ToolsSwingLocator;
77
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
78
import org.gvsig.tools.swing.api.windowmanager.Dialog;
79
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
80
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
81
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
82
import org.gvsig.tools.swing.icontheme.IconTheme;
83

    
84
/**
85
 * @author fdiaz
86
 *
87
 */
88
@SuppressWarnings("UseSpecificCatch")
89
public class DefaultJFeaturesForm implements JFeaturesForm {
90

    
91
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeaturesForm.class);
92

    
93
    private static final int PAGE_SIZE = 500;
94
    private final JPanel panel;
95
    private JDynFormSet formset;
96
    private FeatureStore store;
97
    private FeaturePagingHelper ph;
98
    private DynFormDefinition definition = null;
99
    private FeatureQuery currentQuery;
100
    private final List<Action> otherActions;
101

    
102
    public DefaultJFeaturesForm() {
103
        this.panel = new JPanel(new BorderLayout());
104
        this.otherActions = new ArrayList<>();
105
    }
106

    
107
    @Override
108
    public void setPreferredSize(Dimension dimension) {
109
        panel.setPreferredSize(dimension);
110
    }
111

    
112
    private void updateForm() {
113
        if (this.formset == null) {
114
            this.panel.add(this.getFormset().asJComponent(), BorderLayout.CENTER);
115
        }
116
        try {
117
            this.ph = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
118
            this.formset.setValues(ph.asListOfDynObjects());
119
        } catch (Exception ex) {
120
            throw new RuntimeException("Can't update form", ex);
121
        }
122
        this.formset.setReadOnly(false);
123
    }
124

    
125
    @Override
126
    public JComponent asJComponent() {
127
        if (this.ph == null) {
128
            try {
129
                updateForm();
130
            } catch (Exception ex) {
131
                throw new RuntimeException(ex);
132
            }
133
        }
134
        return this.panel;
135
    }
136

    
137
    @Override
138
    public void bind(FeatureStore store) {
139
        if (store == null) {
140
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
141
        }
142
        try {
143
            this.bind(store, store.getDefaultFeatureType());
144
        } catch (Exception ex) {
145
            throw new RuntimeException("Can't bind store '" + store.getName() + "' to form", ex);
146
        }
147
    }
148

    
149
    public void bind(FeatureStore store, DynClass definition) throws ServiceException, DataException {
150
        if (this.store == store) {
151
            return;
152
        }
153
        DynFormManager formManager = DynFormLocator.getDynFormManager();
154
        if( definition == null ) {
155
            DataServerExplorer explorer=null;
156
            try {
157
                explorer = store.getExplorer();
158
            } catch (Exception ex) {
159
            }
160
            FeatureType featureType = store.getDefaultFeatureType();
161
            this.definition = formManager.getDefinition(featureType);
162
            for (FeatureAttributeDescriptor descriptor : featureType) {
163
                DynFormFieldDefinition formDescriptor = this.definition.get(descriptor.getName());
164
                String profileName = descriptor.getDataProfileName();
165
                if( !StringUtils.isBlank(profileName) ) {
166
                    formDescriptor.setSubtype(profileName);
167
                }
168
                if( explorer!=null && formDescriptor.getType()==DataTypes.FILE ) {
169
                    Tags tags = formDescriptor.getTags();
170
                    if (!tags.has("path")) {    
171
                        File f = explorer.getResourcePath(store, "dat");
172
                        if( f!=null ) {
173
                            tags.set("path", f.getParentFile());
174
                        }
175
                    }
176
                }
177
                
178
            }
179
        } else {
180
            this.definition = formManager.getDefinition(definition);
181
        }
182
        if (formset != null) {
183
            this.panel.remove(formset.asJComponent());
184
            this.formset = null;
185
        }
186
        this.store = store;
187
        this.ph = null;
188

    
189
    }
190

    
191
    @Override
192
    public JDynFormSet getFormset() {
193
        if (this.formset == null) {
194
            DynFormManager formManager = DynFormLocator.getDynFormManager();
195
            try {
196
                this.formset = formManager.createJDynFormSet(this.definition);
197
            } catch (ServiceException ex) {
198
                throw new RuntimeException("Can't create form set.", ex);
199
            }
200

    
201
            //this.formset.setLayoutMode(JDynForm.USE_SEPARATORS);
202
            this.formset.setReadOnly(false);
203
            this.formset.setAllowClose(true);
204
            this.formset.setAllowDelete(false);
205
            this.formset.setAllowNew(false);
206
            this.formset.setAllowSearch(true);
207
            this.formset.setAllowUpdate(true);
208
            this.formset.setAutosave(true);
209

    
210
            this.formset.addAction(new FinishEditingAction());
211
            for( Action action : this.otherActions ) {
212
                this.formset.addAction(action);
213
            }
214

    
215
            this.formset.addListener(new FormSetListener());
216
        }
217
        return this.formset;
218
    }
219

    
220
    @Override
221
    public void addAction(Action action) {
222
        this.otherActions.add(action);
223
        if( this.formset!=null ) {
224
            this.formset.addAction(action);
225
        }
226
    }
227

    
228
    @Override
229
    public long getCurrentIndex() {
230
        if( this.formset==null ) {
231
            return -1;
232
        }
233
        return this.formset.getCurrentIndex();
234
    }
235

    
236
    @Override
237
    public Feature get(long index) {
238
        if( this.formset==null || this.ph==null ) {
239
            return null;
240
        }
241
        try {
242
            return this.ph.getFeatureAt(index);
243
        } catch (BaseException ex) {
244
            return null;
245
        }
246
    }
247

    
248
    private class FinishEditingAction extends AbstractAction implements Observer {
249

    
250
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
251
        public FinishEditingAction() {
252
            I18nManager i18nManager = ToolsLocator.getI18nManager();
253
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
254

    
255
            this.putValue(NAME,null);
256
            this.putValue(SHORT_DESCRIPTION,i18nManager.getTranslation("_Stop_editing"));
257
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
258
            this.putValue(ACTION_COMMAND_KEY, "finishEditing");
259

    
260
            this.setEnabled(store.isEditing());
261
            store.addObserver(this);
262
        }
263

    
264
        @Override
265
        public void actionPerformed(ActionEvent ae) {
266
            if( store.isEditing() ) {
267
                try {
268
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
269
                    ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
270
                    int x = dialogManager.confirmDialog(
271
                            "? Desea terminar edicion y guardar los cambios ?\n\nPulse cancelar para cancelar la edicion y los cambios.",
272
                            i18nManager.getTranslation("_Stop_editing"),
273
                            JOptionPane.YES_NO_CANCEL_OPTION,
274
                            JOptionPane.QUESTION_MESSAGE
275
                    );
276
                    switch(x) {
277
                        case JOptionPane.YES_OPTION:
278
                            store.finishEditing();
279
                            break;
280
                        case JOptionPane.NO_OPTION:
281
                            break;
282
                        case JOptionPane.CANCEL_OPTION:
283
                            store.cancelEditing();
284
                            break;
285
                    }
286
                } catch (DataException ex) {
287
                    LOGGER.warn("Can't finish editing in FeatureForm ("+store.getName()+").",ex);
288
                }
289
            }
290
        }
291

    
292
        @Override
293
        public void update(Observable observable, Object notification) {
294
            if( notification instanceof FeatureStoreNotification ) {
295
                FeatureStoreNotification n =  (FeatureStoreNotification) notification;
296
                switch( n.getType() )  {
297
                    case FeatureStoreNotification.AFTER_STARTEDITING:
298
                        this.setEnabled(true);
299
                        break;
300
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
301
                        this.setEnabled(false);
302
                        break;
303
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
304
                        this.setEnabled(false);
305
                        break;
306
                }
307
            }
308
        }
309

    
310
    }
311

    
312
    @Override
313
    public void setQuery(FeatureQuery query) {
314
        if (this.ph != null) {
315
            if (this.formset != null && this.formset.isAutosave() && this.formset.countValues() > 0) {
316
                if (!store.isEditing()) {
317
                    try {
318
                        store.edit();
319
                    } catch (DataException e1) {
320
                        throw new RuntimeException("Can't set query", e1);
321
                    }
322
                }
323
                saveChanges(this.formset);
324
            }
325
        }
326
        this.currentQuery = query;
327
        updateForm();
328
    }
329

    
330
    @Override
331
    public void showForm(MODE mode) {
332
        this.panel.add(this.getFormset().asJComponent(), BorderLayout.CENTER);
333
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
334
        String title;
335
        if( this.definition instanceof DynStruct_v2 ) {
336
            title = ((DynStruct_v2)this.definition).getLabel();
337
        } else {
338
            title = this.definition.getName();
339
        }
340
        winmgr.showWindow(this.asJComponent(), title, mode);
341
    }
342

    
343
    private void saveChanges(JDynFormSet dynformSet) {
344
        if( dynformSet.isInNewState() ) {
345
            Feature feat = null;
346
            try {
347
                feat = store.createNewFeature(false);
348
            } catch (DataException ex) {
349
                LOGGER.warn("Can't create new feature.",ex);
350
                I18nManager i18nManager = ToolsLocator.getI18nManager();
351
                dynformSet.message(i18nManager.getTranslation("error_saving_data_will_not_save"));
352
                throw new RuntimeException("Can't new save values");
353
            }
354
            DynObject dynObject = feat.getAsDynObject();
355
            dynformSet.getFormValues(dynObject);
356
            try {
357
                ph.insert(((FacadeOfAFeature)dynObject).getEditableFeature());
358
            } catch (BaseException e) {
359
                throw new RuntimeException("Can't save values", e);
360
            }
361
            try {
362
                this.formset.setValues(ph.asListOfDynObjects());
363
                this.formset.setCurrentIndex((int)(ph.getTotalSize())-1);
364
            } catch(Exception ex) {
365
                LOGGER.warn("Can't reload form data after insert.",ex);
366
            }
367
        } else {
368
            int index = dynformSet.getCurrentIndex();
369
            DynObject dynObject = dynformSet.get(index);
370

    
371
            if ( !(dynObject instanceof FacadeOfAFeature) ) {
372
                LOGGER.warn("Can't get the associated feature index " + index);
373
                I18nManager i18nManager = ToolsLocator.getI18nManager();
374
                dynformSet.message(i18nManager.getTranslation("error_saving_data_will_not_save"));
375
                throw new RuntimeException("Can't save values");
376
            }
377
            dynformSet.getFormValues(dynObject);
378
            try {
379
                ph.update(((FacadeOfAFeature)dynObject).getEditableFeature());
380
            } catch (BaseException e) {
381
                throw new RuntimeException("Can't save values", e);
382
            }
383
        }
384

    
385
    }
386

    
387
    @Override
388
    public void saveChanges() {
389
        if (this.formset != null && this.formset.countValues() > 0) {
390
            if (store != null && !store.isEditing()) {
391
                try {
392
                    store.edit();
393
                } catch (DataException e1) {
394
                    LOGGER.warn("Can't edit the store " + store.getName());
395
                    throw new RuntimeException("Can't save changes.", e1);
396
                }
397
            }
398
            this.saveChanges(this.formset);
399
        }
400
    }
401

    
402
    @Override
403
    public long getDataSetSize() {
404
        if (this.ph != null) {
405
            return ph.getTotalSize();
406
        }
407
        return 0;
408
    }
409

    
410
    @Override
411
    public FeatureStore getFeatureStore() {
412
        return this.store;
413
    }
414

    
415
    private class FormSetListener implements JDynFormSetListener {
416

    
417
        @Override
418
        public void formMessage(String message) {
419
        }
420

    
421
        @Override
422
        public void formClose() {
423
            panel.setVisible(false);
424
        }
425

    
426
        @Override
427
        public void formMovedTo(int currentPosition) throws AbortActionException {
428
            LOGGER.trace("formMovedTo " + currentPosition);
429
        }
430

    
431
        @Override
432
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
433
            LOGGER.trace("formBeforeSave");
434
            if (!store.isEditing()) {
435
                try {
436
                    store.edit();
437
                } catch (DataException e1) {
438
                    throw new StoreEditException(e1, store.getName());
439
                }
440
            }
441
        }
442

    
443
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
444
            LOGGER.trace("formBeforeNew");
445
        }
446

    
447
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
448
            LOGGER.trace("formBeforeDelete");
449
        }
450

    
451
        @Override
452
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
453
            LOGGER.trace("formAfterSave");
454
            saveChanges(dynformSet);
455
        }
456

    
457
        @Override
458
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
459
            LOGGER.trace("formAfterNew");
460
        }
461

    
462
        @Override
463
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
464
            LOGGER.trace("formAfterDelete");
465
        }
466

    
467
        @Override
468
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
469
            LOGGER.trace("formBeforeSearch");
470
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
471
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
472

    
473
            JExpressionBuilder builder = dataSwingmanager.createQueryFilterExpresion(store);
474
            Dialog dialog = winmgr.createDialog(
475
                    builder.asJComponent(),
476
                    "Filtro",
477
                    "Creacion de filtro sobre '"+store.getName()+"'",
478
                    WindowManager_v2.BUTTONS_OK_CANCEL
479
            );
480
            dialog.show(WindowManager.MODE.DIALOG);
481
            if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
482
                Expression expresion = builder.getExpression();
483
                try {
484
                    FeatureQuery query = store.createFeatureQuery();
485
                    if( !expresion.isPhraseEmpty() ) {
486
                        query.setFilter(expresion);
487
                    }
488
                    setQuery(query);
489
                } catch (Exception ex) {
490
                    LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
491
                }
492
            }
493
        }
494

    
495
        @Override
496
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
497
            LOGGER.trace("formAfterSearch");
498
        }
499

    
500
        @Override
501
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
502
            LOGGER.trace("formBeforeCancelNew");
503
        }
504

    
505
        @Override
506
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
507
            LOGGER.trace("formAfterCancelNew");
508
        }
509
    }
510

    
511
    private static class StoreEditException extends AbortActionException {
512

    
513
        /**
514
         *
515
         */
516
        private static final long serialVersionUID = -7682017811778577130L;
517

    
518
        public StoreEditException(Throwable cause, String storename) {
519
            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
520
            setValue("storename", storename);
521
        }
522
    }
523
}