Statistics
| Revision:

gvsig-projects-pool / org.gvsig.online / trunk / org.gvsig.online / org.gvsig.online.lib / org.gvsig.online.lib.impl / src / main / java / org / gvsig / online / lib / impl / workspace / FeatureStoreObserver.java @ 9512

History | View | Annotate | Download (18.7 KB)

1
package org.gvsig.online.lib.impl.workspace;
2

    
3
import java.lang.ref.WeakReference;
4
import java.sql.Timestamp;
5
import java.util.ArrayList;
6
import java.util.HashMap;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Objects;
10
import org.apache.commons.lang3.StringUtils;
11
import org.apache.commons.lang3.tuple.ImmutablePair;
12
import org.apache.commons.lang3.tuple.Pair;
13
import org.gvsig.fmap.dal.DALLocator;
14
import org.gvsig.fmap.dal.DataManager;
15
import org.gvsig.fmap.dal.EditingNotification;
16
import org.gvsig.fmap.dal.EditingNotificationManager;
17
import org.gvsig.fmap.dal.feature.EditableFeature;
18
import org.gvsig.fmap.dal.feature.Feature;
19
import org.gvsig.fmap.dal.feature.FeatureStore;
20
import static org.gvsig.fmap.dal.feature.FeatureStore.MODE_PASS_THROUGH;
21
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
22
import org.gvsig.fmap.dal.feature.FeatureType;
23
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
24
import org.gvsig.fmap.dal.swing.DALSwingLocator;
25
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
26
import org.gvsig.online.lib.api.OnlineLocator;
27
import org.gvsig.online.lib.api.OnlineManager;
28
import static org.gvsig.online.lib.api.OnlineManager.FEATURECODE_FIELD_NAME;
29
import static org.gvsig.online.lib.api.OnlineManager.FEATUREDATE_FIELD_NAME;
30
import static org.gvsig.online.lib.api.OnlineManager.FEATUREVERSION_FIELD_NAME;
31
import static org.gvsig.online.lib.api.OnlineManager.OP_DELETE;
32
import static org.gvsig.online.lib.api.OnlineManager.OP_INSERT;
33
import static org.gvsig.online.lib.api.OnlineManager.OP_UPDATE;
34
import static org.gvsig.online.lib.api.OnlineManager.TAG_ONLINE_FIELDFORLABEL;
35
import static org.gvsig.online.lib.api.OnlineManager.TAG_ONLINE_LABEL;
36
import static org.gvsig.online.lib.api.OnlineManager.TAG_ONLINE_TABLENAME;
37
import org.gvsig.online.lib.api.workingcopy.OnlineEntity;
38
import org.gvsig.tools.ToolsLocator;
39
import org.gvsig.tools.dispose.Disposable;
40
import org.gvsig.tools.dispose.DisposableInfo;
41
import org.gvsig.tools.dispose.DisposableManager;
42
import org.gvsig.tools.dispose.DisposeUtils;
43
import org.gvsig.tools.dynobject.Tags;
44
import org.gvsig.tools.observer.Observable;
45
import org.gvsig.tools.observer.Observer;
46
import org.slf4j.Logger;
47
import org.slf4j.LoggerFactory;
48

    
49
/**
50
 *
51
 * @author gvSIG Team
52
 */
53
public class FeatureStoreObserver implements Observer {
54

    
55
    private static final Logger LOGGER = LoggerFactory.getLogger(FeatureStoreObserver.class);
56

    
57
    private OnlineManager manager;
58

    
59
    public FeatureStoreObserver() {
60
        this.manager = null;
61
    }
62
    
63
    private OnlineManager getManager() {
64
        if( this.manager==null ) {
65
            this.manager = OnlineLocator.getOnlineManager();
66
        }
67
        return this.manager;
68
    }
69
    
70
    private OnlineWorkspaceImpl getWorkspace(FeatureStore store) {
71
        return (OnlineWorkspaceImpl) this.getManager().getWorkingcopy(store);
72
    }
73
    
74
    @Override
75
    public void update(Observable observable, Object notification) {
76
        OnlineWorkspaceImpl workspace = null;
77
//        int referencesCount = this.getReferencesCount();
78
        try {
79
            if (notification instanceof EditingNotification) {
80
                EditingNotification n = (EditingNotification) notification;
81
                if (n.getType().equals(EditingNotification.BEFORE_INSERT_FEATURE)) {
82
                    FeatureStore store = n.getFeatureStore();
83
                    workspace = getWorkspace(store);
84
                    if (workspace != null) {
85
                        Feature feature = n.getFeature();
86
                        if (StringUtils.isBlank(feature.getString(FEATURECODE_FIELD_NAME)) && feature instanceof EditableFeature) {
87
                            ((EditableFeature)feature).set(FEATURECODE_FIELD_NAME, workspace.createUniqueCodeLong(store.getName()));
88
                            ((EditableFeature)feature).set(FEATUREDATE_FIELD_NAME, new Timestamp(System.currentTimeMillis()));
89
                            ((EditableFeature)feature).set(OnlineManager.FEATURELASTMODIFICATION_FIELD_NAME, new Timestamp(System.currentTimeMillis()));
90
                            ((EditableFeature)feature).set(FEATUREVERSION_FIELD_NAME, 0);
91
                            ((EditableFeature)feature).set(OnlineManager.FEATUREMODIFIEDBY_FIELD_NAME, workspace.getCurrentUserCode());
92
                        }
93
                    }
94
                }
95
                return;
96
            }
97
            FeatureStoreNotification n = (FeatureStoreNotification) notification;
98
            if( n==null ) {
99
                return;
100
            }
101
            FeatureStore store = (FeatureStore) n.getSource();
102
            switch (n.getType()) {
103
                case FeatureStoreNotification.AFTER_OPEN:
104
                    workspace = getWorkspace(store);
105
                    if( workspace!=null ) {
106
//                        store.setPsdf.format(new Date())roperty(DataManager.DAL_FEATURETYPE_MODE_EDIT, FeatureTypePanel.MODE_SHOW_ONLY);
107
                        store.setProperty(DataManager.DAL_FEATURETYPE_MODE_EDIT, FeatureTypePanel.MODE_EDIT_ALL);
108
                        store.setProperty(DataManager.DAL_FEATURETYPE_MODE_EDIT_MSG, "_The_table_is_under_version_control_The_changes_you_make_will_be_lost_next_checkout");
109
                        FeatureType ft = store.getDefaultFeatureTypeQuietly();
110
                        if( ft!=null ) {
111
                            Tags tags = ft.getTags();
112
                            tags.set(TAG_ONLINE_TABLENAME, store.getName());
113
                            OnlineEntity entity = workspace.getWorkspaceEntityByName(store.getName());
114
                            if( entity != null ) {
115
                                if( !tags.has(TAG_ONLINE_LABEL) ) {
116
                                    tags.set(TAG_ONLINE_LABEL, entity.getLabel());
117
                                }
118
//                                if( !tags.has(TAG_VCSGIS_DATAMODEL) ) {
119
//                                    tags.set(TAG_VCSGIS_DATAMODEL, entity.getDataModels());
120
//                                }
121
                                if( !tags.has(TAG_ONLINE_FIELDFORLABEL) ) {
122
                                    tags.set(TAG_ONLINE_FIELDFORLABEL, entity.getFieldForLabel());
123
                                }
124
//                                if( !tags.has(TAG_VCSGIS_RESOURCES) ) {
125
//                                    tags.set(TAG_VCSGIS_RESOURCES, entity.getResources());
126
//                                }
127
                                if( StringUtils.isBlank(ft.getLabel())) {
128
                                    ft.setLabel(entity.getLabel());
129
                                }
130
                                if( StringUtils.isBlank(ft.getDescription())) {
131
                                    ft.setDescription(entity.getDescription());
132
                                }
133
                            }
134
                        }
135
                    }
136
                    break;
137
                case FeatureStoreNotification.BEFORE_INSERT:
138
                    workspace = getWorkspace(store);
139
                    if (workspace != null) {
140
                        EditableFeature feature = (EditableFeature) n.getFeature();
141
                        if (StringUtils.isBlank(feature.getString(FEATURECODE_FIELD_NAME))) {
142
                            feature.set(FEATURECODE_FIELD_NAME, workspace.createUniqueCodeLong(store.getName()));
143
                            ((EditableFeature)feature).set(FEATUREDATE_FIELD_NAME, new Timestamp(System.currentTimeMillis()));
144
                            ((EditableFeature)feature).set(FEATUREVERSION_FIELD_NAME, 0);
145
                        }
146
                        if (store.isAppending() || store.getMode() == MODE_PASS_THROUGH) {
147
                            workspace.addChange(n.getEditingSession(), OP_INSERT, store, feature);
148
                        }
149
                    }
150
                    break;
151
                case FeatureStoreNotification.BEFORE_UPDATE:
152
                    if (store.isAppending() || store.getMode() == MODE_PASS_THROUGH) {
153
                        workspace = getWorkspace(store);
154
                        if (workspace != null) {
155
                            workspace.addChange(n.getEditingSession(),OP_UPDATE, store, n.getFeature());
156
                        }
157
                    }
158
                    break;
159
                case FeatureStoreNotification.BEFORE_DELETE:
160
                    if (store.isAppending() ) {
161
                        workspace = getWorkspace(store);
162
                        if (workspace != null) {
163
                            workspace.addChange(n.getEditingSession(),OP_DELETE, store, n.getFeature());
164
                        }
165
                        
166
                    } else if ( store.getMode() == MODE_PASS_THROUGH ) {
167
                        workspace = getWorkspace(store);
168
                        if (workspace != null) {
169
                            Feature f = n.getFeature();
170
                            if( f==null ) {
171
                                workspace.addDeleteChanges(n.getEditingSession(), store, n.getExpression());
172
                            } else {
173
                                workspace.addChange(n.getEditingSession(),OP_DELETE, store, n.getFeature());
174
                            }
175
                        }
176
                    }
177
                    break;
178
                case FeatureStoreNotification.AFTER_UPDATE_TYPE:
179
                    if (store.isAppending()) {
180

    
181
                    }
182
                    break;
183
                case FeatureStoreNotification.BEFORE_FINISHEDITING:
184
                    if (store.isEditing()) {
185
                        workspace = getWorkspace(store);
186
                        if (workspace != null) {
187
                            int stat = workspace.addChanges(
188
                                    store,
189
                                    n.getEditingSession(),
190
                                    n.getInsertedsFeatures(),
191
                                    n.getUpdatedsFeatures(),
192
                                    n.getDeletedsFeatures(),
193
                                    n.getChangedsFeatureTypes()
194
                            );
195
                            if (stat != OnlineManager.ERR_NO_ERROR) {
196
                                n.cancel();
197
                            }
198
                        }
199
                    }
200
                    break;
201
                case FeatureStoreNotification.FAILED_FINISHEDITING:
202
                    if (store.isEditing()) {
203
                        workspace = getWorkspace(store);
204
                        if(workspace != null){
205
                            workspace.cancelChanges(store,n.getEditingSession());
206
                        }
207
                    }                    
208
                    break;
209
                case FeatureStoreNotification.AFTER_FINISHEDITING:
210
                    remove_from_inediting_list(store);
211
                    workspace = getWorkspace(store);
212
                    if (workspace != null) {
213
                        workspace.acceptChanges(store, n.getEditingSession());
214
                        if( workspace.isAResourceTable(store.getName()) ) {
215
                            DALLocator.getDataManager().clearAllCachedResources();
216
                        }
217
                    }
218
                    break;
219
                case FeatureStoreNotification.AFTER_STARTEDITING:
220
                    add_to_inediting_list(store, n.getEditMode());
221
                    break;
222
                case FeatureStoreNotification.AFTER_CANCELEDITING:
223
                    remove_from_inediting_list(store);
224
                    workspace = getWorkspace(store);
225
                    if (workspace != null) {
226
                        workspace.cancelChanges(store, n.getEditingSession());
227
                    }
228
                    break;
229
            }
230
        } finally {
231
            DisposeUtils.disposeQuietly(workspace);
232
//            LOGGER.info("Disposables increment "+(getReferencesCount()- referencesCount));
233
        }
234
    }
235
    
236
    public static void install() {
237
        DataManager dataManager = DALLocator.getDataManager();
238
        FeatureStoreObserver obs = new FeatureStoreObserver();
239
        dataManager.addStoreObserver(obs);
240
        
241
        EditingNotificationManager editingNotificationManager
242
                = DALSwingLocator.getEditingNotificationManager();
243
        
244
        editingNotificationManager.addObserver(obs);
245

    
246
    }
247

    
248
    private static final List<Pair<WeakReference<FeatureStore>,Integer>> inediting_list = new ArrayList<>();
249
    
250
    static int getEditMode(FeatureStore store) {
251
        if( store == null ) {
252
            return FeatureStore.MODE_UNKNOWN;
253
        }
254
        for (int i = 0; i < inediting_list.size(); i++) {
255
            Pair<WeakReference<FeatureStore>, Integer> pair = inediting_list.get(i);
256
            if( pair!=null ) {
257
                WeakReference<FeatureStore> ref = pair.getLeft();
258
                if( ref!=null ) {
259
                    FeatureStore currentStore = ref.get();
260
                    if( currentStore == null ) {
261
                        inediting_list.set(i, null);
262
                        break;
263
                    } else {
264
                        if( StringUtils.equalsIgnoreCase(store.getFullName(), currentStore.getFullName())) {
265
                            return pair.getRight();
266
                        }
267
                    }
268
                }
269
            }
270
        }
271
        return FeatureStore.MODE_QUERY;
272
    }
273
    
274
    public static boolean isEditing(FeatureStore store) {
275
        int editMode = getEditMode(store);
276
        return editMode != FeatureStore.MODE_QUERY;
277
    }
278
    
279
    private void remove_from_inediting_list(FeatureStore store) {
280
        boolean found = false;
281
        for (int i = 0; i < inediting_list.size(); i++) {
282
            Pair<WeakReference<FeatureStore>, Integer> pair = inediting_list.get(i);
283
            if( pair!=null ) {
284
                WeakReference<FeatureStore> ref = pair.getLeft();
285
                if( ref==null  ) {
286
                    inediting_list.set(i, null);
287
                } else {
288
                    FeatureStore currentStore = ref.get();
289
                    if( currentStore==null ) {
290
                        inediting_list.set(i, null);
291
                    } else if( currentStore==store ) {
292
                        LOGGER.trace("Terminate editing "+store.getFullName());
293
                        inediting_list.set(i, null);
294
                        found = true;
295
                    } else if( currentStore.getMode()==FeatureStore.MODE_QUERY ) {
296
                        inediting_list.set(i, null);
297
                    }
298
                }
299
            }
300
        }
301
        if( !found ) {
302
            LOGGER.warn("Terminate editing of non editing store "+store.getFullName());
303
        }
304
    }
305

    
306
    private void add_to_inediting_list(FeatureStore store, int editMode) {
307
        if( store == null ) {
308
            return;
309
        }
310
        LOGGER.trace("Start editing "+store.getFullName());
311
        WeakReference<FeatureStore> newref = new WeakReference(store);
312
        for (int i = 0; i < inediting_list.size(); i++) {
313
            Pair<WeakReference<FeatureStore>, Integer> pair = inediting_list.get(i);
314
            if( pair == null || pair.getLeft()==null || pair.getLeft().get()==null) {
315
                // La posicion en la lista es utilizable.
316
                if( newref==null ) {
317
                    inediting_list.set(i,null);
318
                } else {
319
                    inediting_list.set(i,new ImmutablePair<>(newref,editMode));
320
                    newref = null;
321
                }
322
            }
323
        }
324
        if( newref!=null ) {
325
            inediting_list.add(new ImmutablePair<>(newref,editMode));
326
        }
327
    }
328
    
329

    
330
    public static List<Pair<WeakReference<FeatureStore>,Integer>> getInEditingList() {
331
        return inediting_list;
332
    }
333
    
334
    public static boolean isThereAnyStoreInEditing() {
335
        for (int i = 0; i < inediting_list.size(); i++) {
336
            Pair<WeakReference<FeatureStore>, Integer> pair = inediting_list.get(i);
337
            if( pair!=null ) {
338
                WeakReference<FeatureStore> ref = pair.getLeft();
339
                if( ref!=null ) {
340
                    FeatureStore currentStore = ref.get();
341
                    if( currentStore == null ) {
342
                        inediting_list.set(i, null);
343
                        break;
344
                    } else {
345
                        if( pair.getRight()!=FeatureStore.MODE_QUERY ) {
346
                            return true;
347
                        }
348
                    }
349
                }
350
            }
351
        }
352
        return false;
353
    }
354
    
355
    
356
    public static boolean IsThereConflictingStoresInEdition() {
357
        for (int i = 0; i < inediting_list.size(); i++) {
358
            Pair<WeakReference<FeatureStore>, Integer> pair = inediting_list.get(i);
359
            if( pair!=null ) {
360
                WeakReference<FeatureStore> ref = pair.getLeft();
361
                if( ref!=null ) {
362
                    FeatureStore currentStore = ref.get();
363
                    if( currentStore == null ) {
364
                        inediting_list.set(i, null);
365
                        break;
366
                    } else {
367
                        if( currentStore.getParameters() instanceof JDBCStoreParameters) {
368
                            if( pair.getRight()!=FeatureStore.MODE_QUERY ) {
369
                                return true;
370
                            }
371
                        }
372
                    }
373
                }
374
            }
375
        }
376
        return false;
377
    }
378
    
379
    public static int getReferencesCount() {
380
        DisposableManager disposableManager = ToolsLocator.getDisposableManager();
381
        int count = 0;
382
        for (DisposableInfo boundDisposable : disposableManager.getBoundDisposables()) {
383
            count += boundDisposable.getReferencesCount();
384
        }
385
        return count;
386
    }
387
    
388
    public static Object getReferences() {
389
        Map<Integer,Integer> references = new HashMap<>();
390
        DisposableManager disposableManager = ToolsLocator.getDisposableManager();
391
        for (DisposableInfo boundDisposable : disposableManager.getBoundDisposables()) {
392
            references.put(boundDisposable.getDisposable().hashCode(), boundDisposable.getReferencesCount());
393
        }
394
        return references;
395
    }
396

    
397
    public static void dumpDisposables(Object references) {
398
        DisposableManager disposableManager = ToolsLocator.getDisposableManager();
399
        for (DisposableInfo boundDisposable : disposableManager.getBoundDisposables()) {
400
            Disposable d = boundDisposable.getDisposable();
401
            Integer x = ((Map<Integer,Integer>)references).get(d.hashCode());
402
            if(x == null || boundDisposable.getReferencesCount() > x){
403
                String s = "";
404
                try {
405
                    s = Objects.toString(d);
406
                } catch (Throwable t) {
407
                    
408
                }
409
                LOGGER.info(String.format("%x", d.hashCode())+" "+(boundDisposable.getReferencesCount() - (x==null?0:x))+" "+d.getClass().getSimpleName() +" " + s);
410
            }
411
        }
412
    }
413
}