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 / fmap / dal / impl / DefaultEditingNotificationManager.java @ 45652

History | View | Annotate | Download (12.4 KB)

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

    
26
import java.awt.Dimension;
27
import java.util.Arrays;
28
import java.util.List;
29
import javax.swing.JComponent;
30
import javax.swing.SwingUtilities;
31
import org.gvsig.featureform.swing.JFeatureForm;
32
import org.gvsig.fmap.dal.DataStore;
33
import org.gvsig.fmap.dal.EditingNotification;
34
import org.gvsig.fmap.dal.EditingNotificationManager;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.EditableFeatureType;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.swing.DALSwingLocator;
42
import org.gvsig.tools.ToolsLocator;
43
import org.gvsig.tools.dynobject.DynObjectManager;
44
import org.gvsig.tools.dynobject.Tags;
45
import org.gvsig.tools.observer.ObservableHelper;
46
import org.gvsig.tools.observer.Observer;
47
import org.gvsig.tools.observer.BaseNotification;
48
import org.gvsig.tools.swing.api.ToolsSwingLocator;
49
import org.gvsig.tools.swing.api.windowmanager.Dialog;
50
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
51
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

    
55
/**
56
 *
57
 * Acts as a hub to centralize editing notification events in a single manager.
58
 *
59
 * All objects that modify a store notify this manager to reported the actions
60
 * to the objects interested in knowing when start or end editing, regardless
61
 * of where the editing work is done.
62
 *
63
 */
64
@SuppressWarnings("UseSpecificCatch")
65
public class DefaultEditingNotificationManager implements EditingNotificationManager {
66

    
67
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEditingNotificationManager.class);
68
            
69
    private static final String TAG_FORCE_SHOW_FORM_ON_INSERT = "forceShowFormOnInsert";
70
    
71
    private ObservableHelper helper = null;
72

    
73
    private static final int SOURCE = 1;
74
    private static final int DOCUMENT = 2;
75
    private static final int AUXDATA = 3;
76
    private static final int STORE = 4;
77
    private static final int FEATURE = 5;
78
    private static final int FEATURETYPE = 6;
79
    
80
    private static List cancelableNotifications = null;
81

    
82

    
83

    
84
    public class DefaultEditingNotification extends BaseNotification implements EditingNotification {
85

    
86
        private boolean validateTheFeature = true;
87
        
88
        DefaultEditingNotification(String type) {
89
            super(type, 7);
90
        }
91

    
92
        @Override
93
        public Object getSource() {
94
            return this.getValue(SOURCE);
95
        }
96

    
97
        @Override
98
        public Object getDocument() {
99
            return this.getValue(DOCUMENT);
100
        }
101

    
102
        @Override
103
        public Object getAuxData() {
104
            return this.getValue(AUXDATA);
105
        }
106

    
107
        @Override
108
        public DataStore getStore() {
109
            return (DataStore) this.getValue(STORE);
110
        }
111

    
112
        @Override
113
        public FeatureStore getFeatureStore() {
114
            return (FeatureStore) this.getValue(STORE);
115
        }
116

    
117
        @Override
118
        public Feature getFeature() {
119
            return (Feature) this.getValue(FEATURE);
120
        }
121

    
122
        @Override
123
        public EditableFeatureType getFeatureType() {
124
            return (EditableFeatureType) this.getValue(FEATURETYPE);
125
        }
126

    
127
        @Override
128
        public boolean isCancelable() {
129
            if( cancelableNotifications==null ) {
130
                String nn[] = new String[] {
131
                    BEFORE_ENTER_EDITING_STORE,
132
                    BEFORE_EXIT_EDITING_STORE,
133
                    BEFORE_INSERT_FEATURE,
134
                    BEFORE_REMOVE_FEATURE,
135
                    BEFORE_UPDATE_FEATURE,
136
                    BEFORE_UPDATE_FEATURE_TYPE
137
                };
138
                cancelableNotifications = Arrays.asList(nn);
139
            }
140
            return cancelableNotifications.contains(this.getType() );
141
        }
142

    
143
        @Override
144
        public void setSkipFeatureValidation(boolean skipTheFeatureValidation) {
145
            this.validateTheFeature = !skipTheFeatureValidation;
146
        }
147

    
148
        @Override
149
        public boolean shouldValidateTheFeature() {
150
            return this.validateTheFeature;
151
        }
152
    }
153

    
154
    public DefaultEditingNotificationManager() {
155
        this.helper = new ObservableHelper();
156
    }
157

    
158
    @Override
159
    public void addObserver(Observer o) {
160
        this.helper.addObserver(o);
161
    }
162

    
163
    @Override
164
    public void deleteObserver(Observer o) {
165
        this.helper.deleteObserver(o);
166
    }
167

    
168
    @Override
169
    public void deleteObservers() {
170
        this.helper.deleteObservers();
171
    }
172

    
173
    @Override
174
    public EditingNotification notifyObservers(EditingNotification notification) {
175
        try {
176
            this.helper.notifyObservers(this, notification);
177
        } catch(Exception ex) {
178
            LOGGER.warn("Problems notifing to observers of DefaultEditingNotificationManager.",ex);
179
        }
180
        return notification;
181
    }
182

    
183
    public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store, Feature feature, EditableFeatureType featureType) {
184
        EditingNotification notification = new DefaultEditingNotification(type);
185
        notification.setValue(SOURCE,source);
186
        notification.setValue(DOCUMENT,document);
187
        notification.setValue(AUXDATA,auxdata);
188
        notification.setValue(STORE,store);
189
        notification.setValue(FEATURE,feature);
190
        notification.setValue(FEATURETYPE,featureType);
191
        return this.notifyObservers(notification);
192
    }
193

    
194
    @Override
195
    public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store) {
196
        return this.notifyObservers(source, type, document, auxdata, store, null, null);
197
    }
198

    
199
    @Override
200
    public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata) {
201
        return this.notifyObservers(source, type, document, auxdata, null, null, null);
202
    }
203

    
204
    @Override
205
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store) {
206
        return this.notifyObservers(source, type, document, null, store, null, null);
207
    }
208

    
209
    @Override
210
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, Feature feature) {
211
        return this.notifyObservers(source, type, document, null, store, feature, null);
212
    }
213

    
214
    @Override
215
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, EditableFeatureType featureType) {
216
        return this.notifyObservers(source, type, document, null, store, null, featureType);
217
    }
218
    
219
    @Override
220
    public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store, Feature feature) {
221
        return this.notifyObservers(source, type, document, auxdata, store, feature, null);
222
    }
223

    
224
    @Override
225
    public boolean validateFeature(Feature feature) {
226
        
227
        FeatureType featureType = feature.getType();
228
        Tags tags = featureType.getTags();
229
        boolean forceShowForm = tags != null && tags.getBoolean(TAG_FORCE_SHOW_FORM_ON_INSERT, false);
230
        while( true ) {
231
            if( !forceShowForm ) {
232
                if( !needAskUser(feature) ) {
233
                    // La feature se puede validar y no precisa de intervencion del
234
                    // usuario. Retornamos true.
235
                    return true;
236
                }
237
            }
238
            // No se habia podido validar la feature, se piden al
239
            // usuario los datos que faltan.
240
            AskRequiredAttributtes ask = new AskRequiredAttributtes();
241
            ask.showDialog(feature);
242
            if( ask.userCancel() ) {
243
                // No se habia podido validar la feature, se le han pedido al
244
                // usuario los datos que faltan y este ha pulsado en cancel,
245
                // asi que la feature no se puede validar, y retornamos
246
                // false.
247
                return false;
248
            }
249
            forceShowForm = false;
250
        }
251
    }
252
    
253
    private boolean needAskUser(Feature feature) {
254
        FeatureType featureType = feature.getType();
255
        FeatureAttributeDescriptor[] attributeDescriptors = featureType.getAttributeDescriptors();
256

    
257
        for (FeatureAttributeDescriptor attrDesc : attributeDescriptors) {
258
            if ( attrDesc.isAutomatic() ) {
259
                continue;
260
            }
261
            if ( (attrDesc.isPrimaryKey() || !attrDesc.allowNull())
262
                    && feature.get(attrDesc.getName()) == null ) {
263
                return true;
264
            }
265
        }
266
        return false;
267
    }
268

    
269
    private class AskRequiredAttributtes {
270

    
271
        private boolean userCancelValue = true;
272

    
273
        public boolean userCancel() {            
274
            return this.userCancelValue;
275
        }
276
        
277
        public void showDialog(final Feature feature) {
278
            if ( !SwingUtilities.isEventDispatchThread() ) {
279
                try {
280
                    SwingUtilities.invokeAndWait(() -> {
281
                        showDialog(feature);
282
                    });
283
                } catch (Exception e1) {
284
                    message("Can't show form to fill need data.",e1);
285
                    this.userCancelValue = true;
286
                    return;
287
                }
288
            }
289

    
290
            try {
291
                JFeatureForm form = DALSwingLocator.getSwingManager().createJFeatureForm(feature);
292
                setPreferredSize(form.asJComponent(), 400, 400);
293
                WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
294
                Dialog dialog = winManager.createDialog(
295
                        form.asJComponent(),
296
                        form.getDynForm().getDefinition().getLabel(),
297
                        ToolsLocator.getI18nManager().getTranslation("_Fill_the_required_fields"), 
298
                        WindowManager_v2.BUTTONS_OK_CANCEL
299
                );
300
                dialog.show(WindowManager.MODE.DIALOG);
301
                if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
302
                    form.fetch((EditableFeature) feature);
303
                    this.userCancelValue = false;
304
                } else {
305
                    this.userCancelValue = true;
306
                }
307
                
308
            } catch (Exception ex) {
309
                message("Can't show form to fill need data.",ex);
310
                this.userCancelValue = true;
311
            }
312
        }
313
        
314
        private void message(String msg, Throwable ex) {
315
            if( ex==null ) {
316
                LOGGER.warn(msg);
317
            } else {
318
                LOGGER.warn(msg,ex);
319
            }
320
//            msg = msg + "\nSee to application log for more information.";
321
//            ApplicationManager application = ApplicationLocator.getManager();
322
//            application.message(msg,JOptionPane.WARNING_MESSAGE);
323
        }
324
    }
325
    
326
    private void setPreferredSize(JComponent c, int width, int height) {
327
        Dimension d = c.getPreferredSize();
328
        if (d.width < width) {
329
            d.width = width;
330
        }
331
        if (d.height > height) {
332
            d.height = height;
333
        }
334
        c.setPreferredSize(d);
335
    }
336

    
337
    public static final void selfRegister() {
338
         DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager();
339
         dynObjectManager.registerTag(
340
                 TAG_FORCE_SHOW_FORM_ON_INSERT, 
341
                 "String value, true/false to force show form on insert features."
342
         );
343
        
344
    }
345
    
346
    
347
}