Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.fmap.control / src / main / java / org / gvsig / editing / impl / DefaultEditingNotificationManager.java @ 41498

History | View | Annotate | Download (11 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.editing.impl;
25

    
26
import java.util.Arrays;
27
import java.util.List;
28
import javax.swing.SwingUtilities;
29
import org.apache.commons.lang3.StringUtils;
30
import org.gvsig.editing.EditingNotificationManager;
31
import org.gvsig.editing.EditingNotification;
32
import org.gvsig.fmap.dal.DataStore;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34
import org.gvsig.fmap.dal.feature.EditableFeatureType;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.mapcontext.layers.FLayer;
40
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
41
import org.gvsig.fmap.mapcontrol.swing.dynobject.DynObjectEditor;
42
import org.gvsig.tools.ToolsLocator;
43
import org.gvsig.tools.dynobject.DynObject;
44
import org.gvsig.tools.observer.ObservableHelper;
45
import org.gvsig.tools.observer.Observer;
46
import org.gvsig.tools.observer.BaseNotification;
47
import org.slf4j.Logger;
48
import org.slf4j.LoggerFactory;
49

    
50
/**
51
 *
52
 * Acts as a hub to centralize editing notification events in a single manager.
53
 *
54
 * All objects that modify a store notify this manager to reported the actions
55
 * to the objects interested in knowing when start or end editing, regardless
56
 * of where the editing work is done.
57
 *
58
 */
59
public class DefaultEditingNotificationManager implements EditingNotificationManager {
60

    
61
    private static final Logger logger = LoggerFactory.getLogger(DefaultEditingNotificationManager.class);
62
            
63
    private ObservableHelper helper = null;
64

    
65
    private static final int SOURCE = 1;
66
    private static final int DOCUMENT = 2;
67
    private static final int LAYER = 3;
68
    private static final int STORE = 4;
69
    private static final int FEATURE = 5;
70
    private static final int FEATURETYPE = 6;
71
    
72
    private static List cancelableNotifications = null;
73

    
74

    
75

    
76
    public class DefaultEditingNotification extends BaseNotification implements EditingNotification {
77

    
78
        private boolean validateTheFeature = true;
79
        
80
        DefaultEditingNotification(String type) {
81
            super(type, 7);
82
        }
83

    
84
        public Object getSource() {
85
            return this.getValue(SOURCE);
86
        }
87

    
88
        public Object getDocument() {
89
            return this.getValue(DOCUMENT);
90
        }
91

    
92
        public FLayer getLayer() {
93
            return (FLayer) this.getValue(LAYER);
94
        }
95

    
96
        public DataStore getStore() {
97
            return (DataStore) this.getValue(STORE);
98
        }
99

    
100
        public FeatureStore getFeatureStore() {
101
            return (FeatureStore) this.getValue(STORE);
102
        }
103

    
104
        public Feature getFeature() {
105
            return (Feature) this.getValue(FEATURE);
106
        }
107

    
108
        public EditableFeatureType getFeatureType() {
109
            return (EditableFeatureType) this.getValue(FEATURETYPE);
110
        }
111

    
112
        public boolean isCancelable() {
113
            if( cancelableNotifications==null ) {
114
                String nn[] = new String[] {
115
                    BEFORE_ENTER_EDITING_STORE,
116
                    BEFORE_EXIT_EDITING_STORE,
117
                    BEFORE_INSERT_FEATURE,
118
                    BEFORE_REMOVE_FEATURE,
119
                    BEFORE_UPDATE_FEATURE,
120
                    BEFORE_UPDATE_FEATURE_TYPE
121
                };
122
                cancelableNotifications = Arrays.asList(nn);
123
            }
124
            return cancelableNotifications.contains(this.getType() );
125
        }
126

    
127
        public void setSkipFeatureValidation(boolean skipTheFeatureValidation) {
128
            this.validateTheFeature = !skipTheFeatureValidation;
129
        }
130

    
131
        public boolean shouldValidateTheFeature() {
132
            return !this.validateTheFeature;
133
        }
134
    }
135

    
136
    public DefaultEditingNotificationManager() {
137
        this.helper = new ObservableHelper();
138
    }
139

    
140
    public void addObserver(Observer o) {
141
        this.helper.addObserver(o);
142
    }
143

    
144
    public void deleteObserver(Observer o) {
145
        this.helper.deleteObserver(o);
146
    }
147

    
148
    public void deleteObservers() {
149
        this.helper.deleteObservers();
150
    }
151

    
152
    public EditingNotification notifyObservers(EditingNotification notification) {
153
        try {
154
            this.helper.notifyObservers(this, notification);
155
        } catch(Exception ex) {
156
            logger.warn("Problems notifing to observers of DefaultEditingNotificationManager.",ex);
157
        }
158
        return notification;
159
    }
160

    
161
    public EditingNotification notifyObservers(Object source, String type, Object document, FLayer layer, DataStore store, Feature feature, EditableFeatureType featureType) {
162
        EditingNotification notification = new DefaultEditingNotification(type);
163
        notification.setValue(SOURCE,source);
164
        notification.setValue(DOCUMENT,document);
165
        notification.setValue(LAYER,layer);
166
        notification.setValue(STORE,store);
167
        notification.setValue(FEATURE,feature);
168
        notification.setValue(FEATURETYPE,featureType);
169
        return this.notifyObservers(notification);
170
    }
171

    
172
    public EditingNotification notifyObservers(Object source, String type, Object document, FLayer layer, DataStore store) {
173
        return this.notifyObservers(source, type, document, layer, store, null, null);
174
    }
175

    
176
    public EditingNotification notifyObservers(Object source, String type, Object document, FLayer layer) {
177
        DataStore store = null;
178
        if ( layer instanceof FLyrVect ) {
179
            store = ((FLyrVect) layer).getDataStore();
180
        }
181
        return this.notifyObservers(source, type, document, layer, store, null, null);
182
    }
183

    
184
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store) {
185
        return this.notifyObservers(source, type, document, null, store, null, null);
186
    }
187

    
188
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, Feature feature) {
189
        return this.notifyObservers(source, type, document, null, store, feature, null);
190
    }
191

    
192
    public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, EditableFeatureType featureType) {
193
        return this.notifyObservers(source, type, document, null, store, null, featureType);
194
    }
195
    
196
    public EditingNotification notifyObservers(Object source, String type, Object document, FLayer layer, DataStore store, Feature feature) {
197
        return this.notifyObservers(source, type, document, layer, store, feature, null);
198
    }
199

    
200
    public boolean validateFeature(Feature feature) {
201
        while( true ) {
202
            if( !needAskUser(feature) ) {
203
                // La feature se puede validar y no precisa de intervencion del
204
                // usuario. Retornamos true.
205
                return true;
206
            }
207
            // No se habia podido validar la feature, se piden al
208
            // usuario los datos que faltan.
209
            AskRequiredAttributtes ask = new AskRequiredAttributtes();
210
            ask.showDialog(feature);
211
            if( ask.userCancel() ) {
212
                // No se habia podido validar la feature, se le han pedido al
213
                // usuario los datos que faltan y este ha pulsado en cancel,
214
                // asi que la feature no se puede validar, y retornamos
215
                // false.
216
                return false;
217
            }
218
        }
219
    }
220
    
221
    private boolean needAskUser(Feature feature) {
222
        FeatureType featureType = feature.getType();
223
        FeatureAttributeDescriptor[] attributeDescriptors = featureType.getAttributeDescriptors();
224

    
225
        for ( int i = 0; i < attributeDescriptors.length; i++ ) {
226
            FeatureAttributeDescriptor attrDesc = attributeDescriptors[i];
227
            if ( attrDesc.isAutomatic() ) {
228
                break;
229
            }
230
            if ( (attrDesc.isPrimaryKey() || !attrDesc.allowNull())
231
                    && feature.get(attrDesc.getName()) == null ) {
232
                return true;
233
            }
234
        }
235
        return false;
236
    }
237

    
238
    private class AskRequiredAttributtes {
239

    
240
        private boolean userCancelValue = true;
241

    
242
        public boolean userCancel() {            
243
            return this.userCancelValue;
244
        }
245
        
246
        public void showDialog(final Feature feature) {
247
            if ( !SwingUtilities.isEventDispatchThread() ) {
248
                try {
249
                    SwingUtilities.invokeAndWait(new Runnable() {
250
                        public void run() {
251
                            showDialog(feature);
252
                        }
253
                    }
254
                    );
255
                } catch (Exception e1) {
256
                    message("Can't show form to fill need data.",e1);
257
                    this.userCancelValue = true;
258
                    return;
259
                }
260
            }
261

    
262
            try {
263
                DynObject data = feature.getAsDynObject();
264
                DynObjectEditor editor;
265
                editor = new DynObjectEditor(data);
266
                
267
                String title = data.getDynClass().getDescription();
268
                if( StringUtils.isEmpty(title) ) {
269
                        title = data.getDynClass().getName();
270
                } 
271
                editor.setTitle(
272
                    ToolsLocator.getI18nManager().getTranslation("_Fill_the_required_fields")+
273
                    " - "+ 
274
                    title);
275
                
276
                editor.editObject(true);
277
                if ( editor.isCanceled() ) {
278
                    this.userCancelValue = true;
279
                } else {
280
                    editor.getData(data);
281
                    this.userCancelValue = false;
282
                }
283
            } catch (Exception ex) {
284
                message("Can't show form to fill need data.",ex);
285
                this.userCancelValue = true;
286
            }
287
        }
288
        
289
        private void message(String msg, Throwable ex) {
290
            if( ex==null ) {
291
                logger.warn(msg);
292
            } else {
293
                logger.warn(msg,ex);
294
            }
295
//            msg = msg + "\nSee to application log for more information.";
296
//            ApplicationManager application = ApplicationLocator.getManager();
297
//            application.message(msg,JOptionPane.WARNING_MESSAGE);
298
        }
299
    }
300

    
301
    
302
    
303
}