ref #6909 Implement canExecute() for remoting handler
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / e4 / TaxonNavigatorDataChangeBehaviorE4.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.taxeditor.navigation.navigator.e4;
11
12 import java.util.HashSet;
13 import java.util.Set;
14
15 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.Status;
18 import org.eclipse.core.runtime.jobs.Job;
19 import org.eclipse.swt.widgets.Display;
20
21 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
22 import eu.etaxonomy.cdm.model.common.CdmBase;
23 import eu.etaxonomy.cdm.model.name.TaxonName;
24 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
25 import eu.etaxonomy.cdm.model.taxon.Taxon;
26 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent;
27 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent.EventType;
28 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
29 import eu.etaxonomy.taxeditor.model.AbstractDataChangeBehaviour;
30 import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
31 import eu.etaxonomy.taxeditor.navigation.l10n.Messages;
32
33 /**
34 * <p>TaxonNavigatorDataChangeBehavior class.</p>
35 *
36 * @author n.hoffmann
37 * @created 01.04.2009
38 * @version 1.0
39 */
40 public class TaxonNavigatorDataChangeBehaviorE4 extends AbstractDataChangeBehaviour implements
41 IDataChangeBehavior {
42
43 private static final String UPDATING_TAXON_NAVIGATOR = Messages.TaxonNavigatorDataChangeBehavior_UPDATE_NAVIGATOR;
44
45 private final TaxonNavigatorE4 source;
46
47 private Set<CdmBase> staleObjects;
48
49 /**
50 * <p>Constructor for TaxonNavigatorDataChangeBehavior.</p>
51 *
52 * @param taxonNavigator a {@link eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator} object.
53 */
54 public TaxonNavigatorDataChangeBehaviorE4(TaxonNavigatorE4 taxonNavigator) {
55 source = taxonNavigator;
56 }
57
58 /* (non-Javadoc)
59 * @see eu.etaxonomy.taxeditor.store.model.IDataChangeBehavior#isRelevant(java.lang.Object, eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
60 */
61 /**
62 * <p>isRelevant</p>
63 *
64 * @param events a {@link eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap} object.
65 * @return a boolean.
66 */
67 public boolean isRelevant(CdmDataChangeMap events) {
68
69 // TODO react only on insert/update/delete of taxon and synonym objects
70 // and on update of name objects
71 boolean relevant = false;
72 staleObjects = new HashSet<CdmBase>();
73
74 for(CdmDataChangeEvent event : events.getAllEvents()){
75 EventType eventType = event.getEventType();
76 CdmBase eventEntity = event.getEntity();
77
78 Set<CdmBase> affectedObjects = event.getAffectedObjects();
79 if(affectedObjects != null) {
80 for(CdmBase cb : affectedObjects) {
81 staleObjects.add(HibernateProxyHelper.deproxy(cb));
82 }
83 }
84
85 // all tree node changes are relevant
86 if((eventType == EventType.INSERT || eventType == EventType.DELETE || eventType == EventType.UPDATE)
87 && event.getEntity() instanceof ITaxonTreeNode){
88 return true;
89 }
90
91 if (eventType == EventType.DELETE){
92 return true;
93 }
94
95
96
97 if(eventType == EventType.UPDATE && event.getEntity() instanceof Taxon){
98 TaxonName name = null;
99 if(eventEntity instanceof Taxon){
100 name = ((Taxon) eventEntity).getName();
101 }else{
102 continue;
103 }
104
105 // Set<IEditorPart> openEditors = NavigationUtil.getOpenEditors();
106 /*for(IEditorPart editor : openEditors){
107
108 if(name.equals(((TaxonEditorInput) editor.getEditorInput()).getTaxon().getName())){
109 return true;
110 }
111 }*/
112 }
113
114 // if(eventType == EventType.UPDATE){
115 // relevant = true;
116 // CdmBase entity = event.getEntity();
117 // if((entity instanceof TaxonNameBase)
118 // || (entity instanceof Taxon)
119 // || (entity instanceof Synonym)){
120 // staleObjects.add(entity);
121 // }
122 // }
123 }
124
125 return false;
126
127 // @deprecated
128 // react on everything except load
129 // if(events.sizeByEventType(EventType.INSERT) > 0){
130 // return true;
131 // }else if(events.sizeByEventType(EventType.UPDATE) > 0){
132 // return true;
133 // }else if(events.sizeByEventType(EventType.DELETE) > 0){
134 // return true;
135 // }else{
136 // return false;
137 // }
138 }
139
140 /** {@inheritDoc} */
141 @Override
142 public void reactOnDataChange(CdmDataChangeMap events) {
143 if(isRelevant(events)){
144
145 final Display display = Display.getCurrent();
146 Job job = new Job(UPDATING_TAXON_NAVIGATOR) {
147
148 @Override
149 protected IStatus run(IProgressMonitor monitor) {
150 monitor.beginTask(UPDATING_TAXON_NAVIGATOR, 3);
151 monitor.worked(1);
152
153 // clear the session completely
154 monitor.subTask(Messages.TaxonNavigatorDataChangeBehavior_CLEAR_SESSION);
155 display.asyncExec(new Runnable() {
156 @Override
157 public void run() {
158 source.getConversationHolder().clear();
159 }
160 });
161 // FIXME completely clearing the session is a brute force approach.
162 // It would be much more elegant to clear only those elements that have been changed.
163 // I could not get that to work but we should consider workin on this because we might
164 // run into serious performance issues, especially when it comes to large trees
165 //
166 // at least, we moved this to a job so it can run in a background thred
167 // seems to improve the situation but not sure if final solution
168 monitor.worked(1);
169
170 monitor.subTask(Messages.TaxonNavigatorDataChangeBehavior_REFRESH_VIEWER);
171
172 display.asyncExec(new Runnable() {
173 @Override
174 public void run() {
175 if(staleObjects != null && staleObjects.size() > 0) {
176 source.refresh(staleObjects);
177 } else {
178 source.refresh();
179 }
180 }
181 });
182
183
184
185 monitor.worked(1);
186 monitor.done();
187 return Status.OK_STATUS;
188 }
189 };
190
191 job.setPriority(Job.SHORT);
192 job.schedule();
193
194 }
195 }
196 }