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