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 |
} |