Merge branch 'develop' into remoting-4.0
[taxeditor.git] / eu.etaxonomy.taxeditor.navigation / src / main / java / eu / etaxonomy / taxeditor / navigation / navigator / TaxonNavigatorDataChangeBehavior.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;
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 import org.eclipse.ui.IEditorPart;
21
22 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
23 import eu.etaxonomy.cdm.model.common.CdmBase;
24 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
25 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
26 import eu.etaxonomy.cdm.model.taxon.Taxon;
27 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent;
28 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeEvent.EventType;
29 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
30 import eu.etaxonomy.taxeditor.model.AbstractDataChangeBehaviour;
31 import eu.etaxonomy.taxeditor.model.IDataChangeBehavior;
32 import eu.etaxonomy.taxeditor.navigation.NavigationUtil;
33
34 /**
35 * <p>TaxonNavigatorDataChangeBehavior class.</p>
36 *
37 * @author n.hoffmann
38 * @created 01.04.2009
39 * @version 1.0
40 */
41 public class TaxonNavigatorDataChangeBehavior extends AbstractDataChangeBehaviour implements
42 IDataChangeBehavior {
43
44 private final TaxonNavigator source;
45
46 private Set<CdmBase> staleObjects;
47
48 /**
49 * <p>Constructor for TaxonNavigatorDataChangeBehavior.</p>
50 *
51 * @param taxonNavigator a {@link eu.etaxonomy.taxeditor.navigation.navigator.TaxonNavigator} object.
52 */
53 public TaxonNavigatorDataChangeBehavior(TaxonNavigator taxonNavigator) {
54 source = taxonNavigator;
55 }
56
57 /* (non-Javadoc)
58 * @see eu.etaxonomy.taxeditor.store.model.IDataChangeBehavior#isRelevant(java.lang.Object, eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
59 */
60 /**
61 * <p>isRelevant</p>
62 *
63 * @param events a {@link eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap} object.
64 * @return a boolean.
65 */
66 public boolean isRelevant(CdmDataChangeMap events) {
67
68 // TODO react only on insert/update/delete of taxon and synonym objects
69 // and on update of name objects
70 boolean relevant = false;
71 staleObjects = new HashSet<CdmBase>();
72
73 for(CdmDataChangeEvent event : events.getAllEvents()){
74 EventType eventType = event.getEventType();
75 CdmBase eventEntity = event.getEntity();
76
77 Set<CdmBase> affectedObjects = event.getAffectedObjects();
78 if(affectedObjects != null) {
79 for(CdmBase cb : affectedObjects) {
80 staleObjects.add((CdmBase)HibernateProxyHelper.deproxy(cb));
81 }
82 }
83
84 // all tree node changes are relevant
85 if((eventType == EventType.INSERT || eventType == EventType.DELETE || eventType == EventType.UPDATE)
86 && event.getEntity() instanceof ITaxonTreeNode){
87 return true;
88 }
89
90 // name updates of the accepted taxon of open editors are relevant
91 if(eventType == EventType.UPDATE && event.getEntity() instanceof TaxonNameBase){
92 TaxonNameBase name = null;
93 if(eventEntity instanceof TaxonNameBase){
94 name = (TaxonNameBase) eventEntity;
95 }else if(eventEntity instanceof Taxon){
96 name = ((Taxon) eventEntity).getName();
97 }else{
98 continue;
99 }
100
101 Set<IEditorPart> openEditors = NavigationUtil.getOpenEditors();
102 /*for(IEditorPart editor : openEditors){
103
104 if(name.equals(((TaxonEditorInput) editor.getEditorInput()).getTaxon().getName())){
105 return true;
106 }
107 }*/
108 }
109 if (eventType == EventType.DELETE){
110 return true;
111 }
112
113
114
115 if(eventType == EventType.UPDATE && event.getEntity() instanceof Taxon){
116 TaxonNameBase name = null;
117 if(eventEntity instanceof Taxon){
118 name = ((Taxon) eventEntity).getName();
119 }else{
120 continue;
121 }
122
123 // Set<IEditorPart> openEditors = NavigationUtil.getOpenEditors();
124 /*for(IEditorPart editor : openEditors){
125
126 if(name.equals(((TaxonEditorInput) editor.getEditorInput()).getTaxon().getName())){
127 return true;
128 }
129 }*/
130 }
131
132 // if(eventType == EventType.UPDATE){
133 // relevant = true;
134 // CdmBase entity = event.getEntity();
135 // if((entity instanceof TaxonNameBase)
136 // || (entity instanceof Taxon)
137 // || (entity instanceof Synonym)){
138 // staleObjects.add(entity);
139 // }
140 // }
141 }
142
143 return false;
144
145 // @deprecated
146 // react on everything except load
147 // if(events.sizeByEventType(EventType.INSERT) > 0){
148 // return true;
149 // }else if(events.sizeByEventType(EventType.UPDATE) > 0){
150 // return true;
151 // }else if(events.sizeByEventType(EventType.DELETE) > 0){
152 // return true;
153 // }else{
154 // return false;
155 // }
156 }
157
158 /* (non-Javadoc)
159 * @see eu.etaxonomy.taxeditor.store.model.IDataChangeBehavior#reactOnDataChange(java.lang.Object, eu.etaxonomy.cdm.persistence.hibernate.CdmCrudEvent)
160 */
161 /** {@inheritDoc} */
162 @Override
163 public void reactOnDataChange(CdmDataChangeMap events) {
164 if(isRelevant(events)){
165
166 final Display display = Display.getCurrent();
167 Job job = new Job("Updating Taxon Navigator") {
168
169 @Override
170 protected IStatus run(IProgressMonitor monitor) {
171 monitor.beginTask("Updating Taxon Navigator", 3);
172 monitor.worked(1);
173
174 // clear the session completely
175 monitor.subTask("Clearing Taxon Navigators session");
176 display.asyncExec(new Runnable() {
177 @Override
178 public void run() {
179 source.getConversationHolder().clear();
180 }
181 });
182 // FIXME completely clearing the session is a brute force approach.
183 // It would be much more elegant to clear only those elements that have been changed.
184 // I could not get that to work but we should consider workin on this because we might
185 // run into serious performance issues, especially when it comes to large trees
186 //
187 // at least, we moved this to a job so it can run in a background thred
188 // seems to improve the situation but not sure if final solution
189 monitor.worked(1);
190
191 monitor.subTask("Refreshing viewer");
192
193 display.asyncExec(new Runnable() {
194 @Override
195 public void run() {
196 if(staleObjects != null && staleObjects.size() > 0) {
197 source.refresh(staleObjects);
198 } else {
199 source.refresh();
200 }
201 }
202 });
203
204
205
206 monitor.worked(1);
207 monitor.done();
208 return Status.OK_STATUS;
209 }
210 };
211
212 job.setPriority(Job.SHORT);
213 job.schedule();
214
215 }
216 }
217 }