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 41323 jjdelcerro
/**
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 42775 jjdelcerro
package org.gvsig.fmap.dal.impl;
25 41323 jjdelcerro
26 45652 fdiaz
import java.awt.Dimension;
27 41323 jjdelcerro
import java.util.Arrays;
28
import java.util.List;
29 45652 fdiaz
import javax.swing.JComponent;
30 41335 jjdelcerro
import javax.swing.SwingUtilities;
31 42775 jjdelcerro
import org.gvsig.featureform.swing.JFeatureForm;
32 41323 jjdelcerro
import org.gvsig.fmap.dal.DataStore;
33 42775 jjdelcerro
import org.gvsig.fmap.dal.EditingNotification;
34
import org.gvsig.fmap.dal.EditingNotificationManager;
35 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
36 41323 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureType;
37
import org.gvsig.fmap.dal.feature.Feature;
38 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39 41323 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStore;
40 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
41 42775 jjdelcerro
import org.gvsig.fmap.dal.swing.DALSwingLocator;
42 41335 jjdelcerro
import org.gvsig.tools.ToolsLocator;
43 45133 jjdelcerro
import org.gvsig.tools.dynobject.DynObjectManager;
44
import org.gvsig.tools.dynobject.Tags;
45 41323 jjdelcerro
import org.gvsig.tools.observer.ObservableHelper;
46
import org.gvsig.tools.observer.Observer;
47 41498 jjdelcerro
import org.gvsig.tools.observer.BaseNotification;
48 42775 jjdelcerro
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 41323 jjdelcerro
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 45133 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
65 41323 jjdelcerro
public class DefaultEditingNotificationManager implements EditingNotificationManager {
66
67 45133 jjdelcerro
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEditingNotificationManager.class);
68 41323 jjdelcerro
69 45133 jjdelcerro
    private static final String TAG_FORCE_SHOW_FORM_ON_INSERT = "forceShowFormOnInsert";
70
71 41323 jjdelcerro
    private ObservableHelper helper = null;
72
73
    private static final int SOURCE = 1;
74
    private static final int DOCUMENT = 2;
75 42775 jjdelcerro
    private static final int AUXDATA = 3;
76 41323 jjdelcerro
    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 41498 jjdelcerro
    public class DefaultEditingNotification extends BaseNotification implements EditingNotification {
85 41323 jjdelcerro
86 41335 jjdelcerro
        private boolean validateTheFeature = true;
87
88 41323 jjdelcerro
        DefaultEditingNotification(String type) {
89
            super(type, 7);
90
        }
91
92 42775 jjdelcerro
        @Override
93 41323 jjdelcerro
        public Object getSource() {
94
            return this.getValue(SOURCE);
95
        }
96
97 42775 jjdelcerro
        @Override
98 41323 jjdelcerro
        public Object getDocument() {
99
            return this.getValue(DOCUMENT);
100
        }
101
102 45133 jjdelcerro
        @Override
103 42775 jjdelcerro
        public Object getAuxData() {
104
            return this.getValue(AUXDATA);
105 41323 jjdelcerro
        }
106
107 42775 jjdelcerro
        @Override
108 41323 jjdelcerro
        public DataStore getStore() {
109
            return (DataStore) this.getValue(STORE);
110
        }
111
112 42775 jjdelcerro
        @Override
113 41323 jjdelcerro
        public FeatureStore getFeatureStore() {
114
            return (FeatureStore) this.getValue(STORE);
115
        }
116
117 42775 jjdelcerro
        @Override
118 41323 jjdelcerro
        public Feature getFeature() {
119
            return (Feature) this.getValue(FEATURE);
120
        }
121
122 42775 jjdelcerro
        @Override
123 41323 jjdelcerro
        public EditableFeatureType getFeatureType() {
124
            return (EditableFeatureType) this.getValue(FEATURETYPE);
125
        }
126
127 42775 jjdelcerro
        @Override
128 41323 jjdelcerro
        public boolean isCancelable() {
129
            if( cancelableNotifications==null ) {
130
                String nn[] = new String[] {
131 41330 jjdelcerro
                    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 41323 jjdelcerro
                };
138
                cancelableNotifications = Arrays.asList(nn);
139
            }
140
            return cancelableNotifications.contains(this.getType() );
141
        }
142 41335 jjdelcerro
143 42775 jjdelcerro
        @Override
144 41335 jjdelcerro
        public void setSkipFeatureValidation(boolean skipTheFeatureValidation) {
145
            this.validateTheFeature = !skipTheFeatureValidation;
146
        }
147
148 42775 jjdelcerro
        @Override
149 41335 jjdelcerro
        public boolean shouldValidateTheFeature() {
150 41741 jjdelcerro
            return this.validateTheFeature;
151 41335 jjdelcerro
        }
152 41323 jjdelcerro
    }
153
154
    public DefaultEditingNotificationManager() {
155
        this.helper = new ObservableHelper();
156
    }
157
158 42775 jjdelcerro
    @Override
159 41323 jjdelcerro
    public void addObserver(Observer o) {
160
        this.helper.addObserver(o);
161
    }
162
163 42775 jjdelcerro
    @Override
164 41323 jjdelcerro
    public void deleteObserver(Observer o) {
165
        this.helper.deleteObserver(o);
166
    }
167
168 42775 jjdelcerro
    @Override
169 41323 jjdelcerro
    public void deleteObservers() {
170
        this.helper.deleteObservers();
171
    }
172
173 42775 jjdelcerro
    @Override
174 41323 jjdelcerro
    public EditingNotification notifyObservers(EditingNotification notification) {
175
        try {
176
            this.helper.notifyObservers(this, notification);
177
        } catch(Exception ex) {
178 45133 jjdelcerro
            LOGGER.warn("Problems notifing to observers of DefaultEditingNotificationManager.",ex);
179 41323 jjdelcerro
        }
180
        return notification;
181
    }
182
183 42775 jjdelcerro
    public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store, Feature feature, EditableFeatureType featureType) {
184 41323 jjdelcerro
        EditingNotification notification = new DefaultEditingNotification(type);
185
        notification.setValue(SOURCE,source);
186
        notification.setValue(DOCUMENT,document);
187 42775 jjdelcerro
        notification.setValue(AUXDATA,auxdata);
188 41323 jjdelcerro
        notification.setValue(STORE,store);
189
        notification.setValue(FEATURE,feature);
190
        notification.setValue(FEATURETYPE,featureType);
191
        return this.notifyObservers(notification);
192
    }
193
194 42775 jjdelcerro
    @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 41323 jjdelcerro
    }
198
199 42775 jjdelcerro
    @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 41323 jjdelcerro
    }
203
204 42775 jjdelcerro
    @Override
205 41323 jjdelcerro
    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 42775 jjdelcerro
    @Override
210 41323 jjdelcerro
    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 42775 jjdelcerro
    @Override
215 41323 jjdelcerro
    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 42775 jjdelcerro
    @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 41323 jjdelcerro
    }
223 41335 jjdelcerro
224 42775 jjdelcerro
    @Override
225 41335 jjdelcerro
    public boolean validateFeature(Feature feature) {
226 45133 jjdelcerro
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 41335 jjdelcerro
        while( true ) {
231 45133 jjdelcerro
            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 41335 jjdelcerro
            }
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 45133 jjdelcerro
            forceShowForm = false;
250 41335 jjdelcerro
        }
251
    }
252 41323 jjdelcerro
253 41335 jjdelcerro
    private boolean needAskUser(Feature feature) {
254
        FeatureType featureType = feature.getType();
255
        FeatureAttributeDescriptor[] attributeDescriptors = featureType.getAttributeDescriptors();
256
257 42775 jjdelcerro
        for (FeatureAttributeDescriptor attrDesc : attributeDescriptors) {
258 41335 jjdelcerro
            if ( attrDesc.isAutomatic() ) {
259 43362 jjdelcerro
                continue;
260 41335 jjdelcerro
            }
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 45133 jjdelcerro
                    SwingUtilities.invokeAndWait(() -> {
281
                        showDialog(feature);
282
                    });
283 41335 jjdelcerro
                } 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 42775 jjdelcerro
                JFeatureForm form = DALSwingLocator.getSwingManager().createJFeatureForm(feature);
292 45652 fdiaz
                setPreferredSize(form.asJComponent(), 400, 400);
293 42775 jjdelcerro
                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 41335 jjdelcerro
                    this.userCancelValue = false;
304 43362 jjdelcerro
                } else {
305
                    this.userCancelValue = true;
306 41335 jjdelcerro
                }
307 42775 jjdelcerro
308 41335 jjdelcerro
            } 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 45133 jjdelcerro
                LOGGER.warn(msg);
317 41335 jjdelcerro
            } else {
318 45133 jjdelcerro
                LOGGER.warn(msg,ex);
319 41335 jjdelcerro
            }
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 45652 fdiaz
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 41335 jjdelcerro
337 45133 jjdelcerro
    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 41323 jjdelcerro
346 41335 jjdelcerro
347 41323 jjdelcerro
}