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 @ 42775

History | View | Annotate | Download (17.6 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.util.ArrayList;
29
import java.util.List;
30
import javax.swing.AbstractAction;
31
import javax.swing.Action;
32

    
33
import javax.swing.JComponent;
34
import javax.swing.JOptionPane;
35
import javax.swing.JPanel;
36
import org.apache.commons.lang3.StringUtils;
37

    
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

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

    
78
/**
79
 * @author fdiaz
80
 *
81
 */
82
public class DefaultJFeaturesForm implements JFeaturesForm {
83

    
84
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeaturesForm.class);
85

    
86
    private static final int PAGE_SIZE = 500;
87
    private final JPanel panel;
88
    private JDynFormSet formset;
89
    private FeatureStore store;
90
    private FeaturePagingHelper ph;
91
    private DynClass definition = null;
92
    private FeatureQuery currentQuery;
93
    private List<Action> otherActions;
94

    
95
    public DefaultJFeaturesForm() {
96
        this.panel = new JPanel(new BorderLayout());
97
        this.otherActions = new ArrayList<>();
98
    }
99

    
100
    @Override
101
    public void setPreferredSize(Dimension dimension) {
102
        panel.setPreferredSize(dimension);
103
    }
104

    
105
    private void updateForm() {
106
        if (this.formset == null) {
107
            this.panel.add(this.getFormset().asJComponent(), BorderLayout.CENTER);
108
        }
109
        try {
110
            this.ph = DALLocator.getDataManager().createFeaturePagingHelper(store, this.currentQuery, PAGE_SIZE);
111
            this.formset.setValues(ph.asListOfDynObjects());
112
        } catch (Exception ex) {
113
            throw new RuntimeException("Can't update form", ex);
114
        }
115
        this.formset.setReadOnly(false);
116
    }
117

    
118
    @Override
119
    public JComponent asJComponent() {
120
        if (this.ph == null) {
121
            try {
122
                updateForm();
123
            } catch (Exception ex) {
124
                throw new RuntimeException(ex);
125
            }
126
        }
127
        return this.panel;
128
    }
129

    
130
    @Override
131
    public void bind(FeatureStore store) {
132
        if (store == null) {
133
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
134
        }
135
        try {
136
            this.bind(store, store.getDefaultFeatureType());
137
        } catch (Exception ex) {
138
            throw new RuntimeException("Can't bind store '" + store.getName() + "' to form", ex);
139
        }
140
    }
141

    
142
    public void bind(FeatureStore store, DynClass definition) throws ServiceException, DataException {
143
        if (this.store == store) {
144
            return;
145
        }
146
        if( definition == null ) {
147
            definition = store.getDefaultFeatureType();
148
        }
149
        if (formset != null) {
150
            this.panel.remove(formset.asJComponent());
151
            this.formset = null;
152
        }
153
        this.store = store;
154
        this.ph = null;
155
        this.definition = definition;
156
    }
157

    
158
    @Override
159
    public JDynFormSet getFormset() {
160
        if (this.formset == null) {
161
            DynFormManager formManager = DynFormLocator.getDynFormManager();
162
            try {
163
                this.formset = formManager.createJDynFormSet(this.definition);
164
            } catch (ServiceException ex) {
165
                throw new RuntimeException("Can't create form set.", ex);
166
            }
167

    
168
            //this.formset.setLayoutMode(JDynForm.USE_SEPARATORS);
169
            this.formset.setReadOnly(false);
170
            this.formset.setAllowClose(true);
171
            this.formset.setAllowDelete(false);
172
            this.formset.setAllowNew(false);
173
            this.formset.setAllowSearch(true);
174
            this.formset.setAllowUpdate(true);
175
            this.formset.setAutosave(true);
176

    
177
            this.formset.addAction(new FinishEditingAction());
178
            for( Action action : this.otherActions ) {
179
                this.formset.addAction(action);
180
            }
181

    
182
            this.formset.addListener(new FormSetListener());
183
        }
184
        return this.formset;
185
    }
186

    
187
    @Override
188
    public void addAction(Action action) {
189
        this.otherActions.add(action);
190
        if( this.formset!=null ) {
191
            this.formset.addAction(action);
192
        }
193
    }
194

    
195
    @Override
196
    public long getCurrentIndex() {
197
        if( this.formset==null ) {
198
            return -1;
199
        }
200
        return this.formset.getCurrentIndex();
201
    }
202

    
203
    @Override
204
    public Feature get(long index) {
205
        if( this.formset==null || this.ph==null ) {
206
            return null;
207
        }
208
        try {
209
            return this.ph.getFeatureAt(index);
210
        } catch (BaseException ex) {
211
            return null;
212
        }
213
    }
214

    
215
    private class FinishEditingAction extends AbstractAction implements Observer {
216

    
217
        public FinishEditingAction() {
218
            I18nManager i18nManager = ToolsLocator.getI18nManager();
219
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
220

    
221
            this.putValue(NAME,null);
222
            this.putValue(SHORT_DESCRIPTION,i18nManager.getTranslation("_Stop_editing"));
223
            this.putValue(SMALL_ICON, iconTheme.get("table-stop-editing"));
224
            this.putValue(ACTION_COMMAND_KEY, "finishEditing");
225

    
226
            this.setEnabled(store.isEditing());
227
            store.addObserver(this);
228
        }
229

    
230
        @Override
231
        public void actionPerformed(ActionEvent ae) {
232
            if( store.isEditing() ) {
233
                try {
234
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
235
                    ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
236
                    int x = dialogManager.confirmDialog(
237
                            "? Desea terminar edicion y guardar los cambios ?\n\nPulse cancelar para cancelar la edicion y los cambios.",
238
                            i18nManager.getTranslation("_Stop_editing"),
239
                            JOptionPane.YES_NO_CANCEL_OPTION,
240
                            JOptionPane.QUESTION_MESSAGE
241
                    );
242
                    switch(x) {
243
                        case JOptionPane.YES_OPTION:
244
                            store.finishEditing();
245
                            break;
246
                        case JOptionPane.NO_OPTION:
247
                            break;
248
                        case JOptionPane.CANCEL_OPTION:
249
                            store.cancelEditing();
250
                            break;
251
                    }
252
                } catch (DataException ex) {
253
                    LOGGER.warn("Can't finish editing in FeatureForm ("+store.getName()+").",ex);
254
                }
255
            }
256
        }
257

    
258
        @Override
259
        public void update(Observable observable, Object notification) {
260
            if( notification instanceof FeatureStoreNotification ) {
261
                FeatureStoreNotification n =  (FeatureStoreNotification) notification;
262
                switch( n.getType() )  {
263
                    case FeatureStoreNotification.AFTER_STARTEDITING:
264
                        this.setEnabled(true);
265
                        break;
266
                    case FeatureStoreNotification.AFTER_FINISHEDITING:
267
                        this.setEnabled(false);
268
                        break;
269
                    case FeatureStoreNotification.AFTER_CANCELEDITING:
270
                        this.setEnabled(false);
271
                        break;
272
                }
273
            }
274
        }
275

    
276
    }
277

    
278
    @Override
279
    public void setQuery(FeatureQuery query) {
280
        if (this.ph != null) {
281
            if (this.formset != null && this.formset.isAutosave() && this.formset.countValues() > 0) {
282
                if (!store.isEditing()) {
283
                    try {
284
                        store.edit();
285
                    } catch (DataException e1) {
286
                        throw new RuntimeException("Can't set query", e1);
287
                    }
288
                }
289
                saveChanges(this.formset);
290
            }
291
        }
292
        this.currentQuery = query;
293
        updateForm();
294
    }
295

    
296
    @Override
297
    public void showForm(MODE mode) {
298
        this.panel.add(this.getFormset().asJComponent(), BorderLayout.CENTER);
299
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
300
        String title;
301
        if( this.definition instanceof DynStruct_v2 ) {
302
            title = ((DynStruct_v2)this.definition).getLabel();
303
        } else {
304
            title = this.definition.getName();
305
        }
306
        winmgr.showWindow(this.asJComponent(), title, mode);
307
    }
308

    
309
    private void saveChanges(JDynFormSet dynformSet) {
310
        if( dynformSet.isInNewState() ) {
311
            Feature feat = null;
312
            try {
313
                feat = store.createNewFeature(false);
314
            } catch (DataException ex) {
315
                LOGGER.warn("Can't create new feature.",ex);
316
                I18nManager i18nManager = ToolsLocator.getI18nManager();
317
                dynformSet.message(i18nManager.getTranslation("error_saving_data_will_not_save"));
318
                throw new RuntimeException("Can't new save values");
319
            }
320
            DynObject dynObject = feat.getAsDynObject();
321
            dynformSet.getFormValues(dynObject);
322
            try {
323
                ph.insert(((FacadeOfAFeature)dynObject).getEditableFeature());
324
            } catch (BaseException e) {
325
                throw new RuntimeException("Can't save values", e);
326
            }
327
            try {
328
                this.formset.setValues(ph.asListOfDynObjects());
329
                this.formset.setCurrentIndex((int)(ph.getTotalSize())-1);
330
            } catch(Exception ex) {
331
                LOGGER.warn("Can't reload form data after insert.",ex);
332
            }
333
        } else {
334
            int index = dynformSet.getCurrentIndex();
335
            DynObject dynObject = dynformSet.get(index);
336

    
337
            if ( !(dynObject instanceof FacadeOfAFeature) ) {
338
                LOGGER.warn("Can't get the associated feature index " + index);
339
                I18nManager i18nManager = ToolsLocator.getI18nManager();
340
                dynformSet.message(i18nManager.getTranslation("error_saving_data_will_not_save"));
341
                throw new RuntimeException("Can't save values");
342
            }
343
            dynformSet.getFormValues(dynObject);
344
            try {
345
                ph.update(((FacadeOfAFeature)dynObject).getEditableFeature());
346
            } catch (BaseException e) {
347
                throw new RuntimeException("Can't save values", e);
348
            }
349
        }
350

    
351
    }
352

    
353
    @Override
354
    public void saveChanges() {
355
        if (this.formset != null && this.formset.countValues() > 0) {
356
            if (store != null && !store.isEditing()) {
357
                try {
358
                    store.edit();
359
                } catch (DataException e1) {
360
                    LOGGER.warn("Can't edit the store " + store.getName());
361
                    throw new RuntimeException("Can't save changes.", e1);
362
                }
363
            }
364
            this.saveChanges(this.formset);
365
        }
366
    }
367

    
368
    @Override
369
    public long getDataSetSize() {
370
        if (this.ph != null) {
371
            return ph.getTotalSize();
372
        }
373
        return 0;
374
    }
375

    
376
    @Override
377
    public FeatureStore getFeatureStore() {
378
        return this.store;
379
    }
380

    
381
    private class FormSetListener implements JDynFormSetListener {
382

    
383
        @Override
384
        public void formMessage(String message) {
385
        }
386

    
387
        @Override
388
        public void formClose() {
389
            panel.setVisible(false);
390
        }
391

    
392
        @Override
393
        public void formMovedTo(int currentPosition) throws AbortActionException {
394
            LOGGER.trace("formMovedTo " + currentPosition);
395
        }
396

    
397
        @Override
398
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
399
            LOGGER.trace("formBeforeSave");
400
            if (!store.isEditing()) {
401
                try {
402
                    store.edit();
403
                } catch (DataException e1) {
404
                    throw new StoreEditException(e1, store.getName());
405
                }
406
            }
407
        }
408

    
409
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
410
            LOGGER.trace("formBeforeNew");
411
        }
412

    
413
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
414
            LOGGER.trace("formBeforeDelete");
415
        }
416

    
417
        @Override
418
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
419
            LOGGER.trace("formAfterSave");
420
            saveChanges(dynformSet);
421
        }
422

    
423
        @Override
424
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
425
            LOGGER.trace("formAfterNew");
426
        }
427

    
428
        @Override
429
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
430
            LOGGER.trace("formAfterDelete");
431
        }
432

    
433
        @Override
434
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
435
            LOGGER.trace("formBeforeSearch");
436
            DataManager dataManager = DALLocator.getDataManager();
437
            DataSwingManager dataSwingmanager = DALSwingLocator.getSwingManager();
438
            WindowManager_v2 winmgr = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
439

    
440
            QueryFilterExpresion querypanel = dataSwingmanager.createQueryFilterExpresion(store);
441
            Dialog dialog = winmgr.createDialog(
442
                    querypanel.asJComponent(),
443
                    "Filtro",
444
                    "Creacion de filtro sobre '"+store.getName()+"'",
445
                    WindowManager_v2.BUTTONS_OK_CANCEL
446
            );
447
            dialog.show(WindowManager.MODE.DIALOG);
448

    
449
            if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
450
                String expresion = querypanel.getExpresion();
451
                try {
452
                    FeatureQuery query = store.createFeatureQuery();
453
                    if( !StringUtils.isEmpty(expresion) ) {
454
                        query.setFilter(dataManager.createExpresion(expresion));
455
                    }
456
                    FeatureSet set = store.getFeatureSet(query);
457
                    setQuery(query);
458
                } catch (Exception ex) {
459
                    LOGGER.warn("Can't apply filter '" + expresion + "'.", ex);
460
                    return;
461
                }
462
            }
463
        }
464

    
465
        @Override
466
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
467
            LOGGER.trace("formAfterSearch");
468
        }
469

    
470
        @Override
471
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
472
            LOGGER.trace("formBeforeCancelNew");
473
        }
474

    
475
        @Override
476
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
477
            LOGGER.trace("formAfterCancelNew");
478
        }
479
    }
480

    
481
    private static class StoreEditException extends AbortActionException {
482

    
483
        /**
484
         *
485
         */
486
        private static final long serialVersionUID = -7682017811778577130L;
487

    
488
        public StoreEditException(Throwable cause, String storename) {
489
            super("Can't edit the store '%(storename)'", cause, "cant_edit_the store_XstorenameX", serialVersionUID);
490
            setValue("storename", storename);
491
        }
492
    }
493
}