Add method to sessionOwner objects to fine tune performance using property paths
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / derivate / DerivateView.java
1 package eu.etaxonomy.taxeditor.editor.view.derivate;
2
3 import java.util.Collection;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Map.Entry;
8 import java.util.Set;
9 import java.util.UUID;
10
11 import org.eclipse.core.runtime.IProgressMonitor;
12 import org.eclipse.jface.action.MenuManager;
13 import org.eclipse.jface.util.LocalSelectionTransfer;
14 import org.eclipse.jface.viewers.AbstractTreeViewer;
15 import org.eclipse.jface.viewers.ISelection;
16 import org.eclipse.jface.viewers.ISelectionChangedListener;
17 import org.eclipse.jface.viewers.SelectionChangedEvent;
18 import org.eclipse.jface.viewers.StructuredSelection;
19 import org.eclipse.jface.viewers.TreeNode;
20 import org.eclipse.jface.viewers.TreeSelection;
21 import org.eclipse.jface.viewers.TreeViewer;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.dnd.DND;
24 import org.eclipse.swt.dnd.Transfer;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Menu;
28 import org.eclipse.swt.widgets.Tree;
29 import org.eclipse.ui.IEditorInput;
30 import org.eclipse.ui.IEditorPart;
31 import org.eclipse.ui.IEditorSite;
32 import org.eclipse.ui.PartInitException;
33 import org.eclipse.ui.part.EditorPart;
34
35 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
36 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
37 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
38 import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
39 import eu.etaxonomy.cdm.model.common.CdmBase;
40 import eu.etaxonomy.cdm.model.molecular.Sequence;
41 import eu.etaxonomy.cdm.model.molecular.SingleRead;
42 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
43 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
44 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
45 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
46 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
47 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
48 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
49 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
50 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
51 import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
52 import eu.etaxonomy.taxeditor.store.CdmStore;
53 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
54 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
55
56 /**
57 * Displays the derivate hierarchy of the specimen specified in the editor input.
58 *
59 */
60 public class DerivateView extends EditorPart implements IPartContentHasFactualData, IDirtyMarkable,
61 IConversationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
62 ISelectionChangedListener, IPostOperationEnabled , ICdmEntitySessionEnabled {
63
64 public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView";
65
66 private ConversationHolder conversation;
67
68 private TreeViewer viewer;
69
70 private boolean isDirty;
71
72 private final int dndOperations = DND.DROP_MOVE;
73
74 private DerivateLabelProvider labelProvider;
75
76 private Set<SingleRead> multiLinkSingleReads;
77
78 private ISelection selection = null;
79
80 private final ICdmEntitySession cdmEntitySession;
81
82 private DerivateContentProvider contentProvider;
83
84 /**
85 * Default constructor
86 */
87 public DerivateView() {
88 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
89 }
90
91 /* (non-Javadoc)
92 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
93 */
94 @Override
95 public void createPartControl(Composite parent) {
96 viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
97 contentProvider = new DerivateContentProvider();
98 viewer.setContentProvider(contentProvider);
99 labelProvider = new DerivateLabelProvider();
100 labelProvider.setConversation(conversation);
101 viewer.setLabelProvider(labelProvider);
102 viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
103 // Propagate selection from viewer
104 getSite().setSelectionProvider(viewer);
105 //listen to selection changes
106 viewer.addSelectionChangedListener(this);
107
108 //create context menu
109 MenuManager menuManager = new MenuManager();
110 getSite().registerContextMenu(menuManager, viewer);
111 Control control = viewer.getControl();
112 Menu menu = menuManager.createContextMenu(control);
113 control.setMenu(menu);
114
115 generateMultiLinkSingleReads();
116 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
117 IEditorInput editorInput = getEditorInput();
118 viewer.setInput(((DerivateViewEditorInput) editorInput).getRootUUIDs());
119 //set selection to selected derivate if only one was selected
120 if(editorInput instanceof DerivateViewEditorInput){
121 Set<UUID> derivateUUIDs = ((DerivateViewEditorInput) editorInput).getDerivateUUIDs();
122 if(derivateUUIDs.size()==1){
123 SpecimenOrObservationBase<?> specimen = CdmStore.getService(IOccurrenceService.class).load(derivateUUIDs.iterator().next());
124 if(specimen!=null){
125 viewer.setSelection(new StructuredSelection(new TreeNode(specimen)));
126 }
127 }
128 }
129
130 //add drag'n'drop support
131 Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer(),};
132 viewer.addDragSupport(dndOperations, transfers, new DerivateDragListener(this));
133 viewer.addDropSupport(dndOperations, transfers, new DerivateDropListener(this));
134 }
135
136 /* (non-Javadoc)
137 * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
138 */
139 @Override
140 public void doSave(IProgressMonitor monitor) {
141 String taskName = "Saving hierarchy";
142 if(getEditorInput() instanceof DerivateViewEditorInput){
143 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
144 taskName += " "+derivateViewEditorInput.getName();
145 }
146 monitor.beginTask(taskName, 3);
147 if (!conversation.isBound()) {
148 conversation.bind();
149 }
150 monitor.worked(1);
151
152 // commit the conversation and start a new transaction immediately
153 conversation.commit(true);
154 CdmStore.getService(IOccurrenceService.class).merge(getRootEntities());
155 monitor.worked(1);
156
157 this.setDirty(false);
158 monitor.worked(1);
159 monitor.done();
160 firePropertyChange(PROP_DIRTY);
161 refreshTree();
162 }
163
164 /* (non-Javadoc)
165 * @see org.eclipse.ui.part.EditorPart#doSaveAs()
166 */
167 @Override
168 public void doSaveAs() {
169 }
170
171 /* (non-Javadoc)
172 * @see org.eclipse.ui.part.EditorPart#getTitleToolTip()
173 */
174 @Override
175 public String getTitleToolTip() {
176 if(getEditorInput() instanceof DerivateViewEditorInput){
177 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) getEditorInput();
178 return derivateViewEditorInput.getName();
179 }
180 return "Derivative View";
181 }
182
183 /* (non-Javadoc)
184 * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
185 */
186 @Override
187 public void init(IEditorSite site, IEditorInput input) throws PartInitException {
188 setSite(site);
189 setInput(input);
190 if(input instanceof DerivateViewEditorInput){
191 DerivateViewEditorInput derivateViewEditorInput = (DerivateViewEditorInput) input;
192 conversation = derivateViewEditorInput.getConversationHolder();
193 setPartName(derivateViewEditorInput.getName());
194 }
195 }
196
197 /* (non-Javadoc)
198 * @see org.eclipse.ui.part.EditorPart#isDirty()
199 */
200 @Override
201 public boolean isDirty() {
202 return isDirty;
203 }
204
205 /**
206 * @param isDirty the isDirty to set
207 */
208 public void setDirty(boolean isDirty) {
209 this.isDirty = isDirty;
210 }
211
212 /* (non-Javadoc)
213 * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
214 */
215 @Override
216 public boolean isSaveAsAllowed() {
217 return false;
218 }
219
220
221 /* (non-Javadoc)
222 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
223 */
224 @Override
225 public void setFocus() {
226 viewer.getControl().setFocus();
227 //make sure to bind again if maybe in another view the conversation was unbound
228 if(!conversation.isBound()){
229 conversation.bind();
230 }
231 cdmEntitySession.bind();
232 }
233
234 /* (non-Javadoc)
235 * @see eu.etaxonomy.cdm.persistence.hibernate.ICdmPostDataChangeObserver#update(eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap)
236 */
237 @Override
238 public void update(CdmDataChangeMap changeEvents) {
239 }
240
241 /* (non-Javadoc)
242 * @see eu.etaxonomy.cdm.api.conversation.IConversationEnabled#getConversationHolder()
243 */
244 @Override
245 public ConversationHolder getConversationHolder() {
246 return conversation;
247 }
248
249 /**
250 * @return the viewer
251 */
252 public TreeViewer getViewer() {
253 return viewer;
254 }
255
256 /* (non-Javadoc)
257 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#changed(java.lang.Object)
258 */
259 @Override
260 public void changed(Object element) {
261 setDirty(true);
262 firePropertyChange(IEditorPart.PROP_DIRTY);
263 viewer.refresh();
264 }
265
266 /* (non-Javadoc)
267 * @see eu.etaxonomy.taxeditor.model.IDirtyMarkableSelectionProvider#forceDirty()
268 */
269 @Override
270 public void forceDirty() {
271 changed(null);
272 }
273
274 /**
275 * Refreshes the derivate hierarchy tree and expands the tree
276 * to show and select the given object.
277 *
278 * @param expandTo the object to which the tree should be expanded
279 */
280 public void refreshTree(Object expandTo){
281 refreshTree();
282 TreeSelection selection = (TreeSelection) viewer.getSelection();
283 viewer.expandToLevel(selection.getFirstElement(), 1);
284 viewer.setSelection(new StructuredSelection(new TreeNode(expandTo)));
285 }
286
287 /**
288 * Refreshes the derivate hierarchy tree
289 */
290 public void refreshTree(){
291 generateMultiLinkSingleReads();
292 labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
293 viewer.refresh();
294 }
295
296
297 private void generateMultiLinkSingleReads() {
298 Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
299 for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
300 if(entry.getValue().size()>1){
301 multiLinkSingleReads.add(entry.getKey());
302 }
303 }
304 this.multiLinkSingleReads = multiLinkSingleReads;
305 }
306
307 /**
308 * @return a set of {@link SingleRead}s that have multiple parents
309 */
310 public Set<SingleRead> getMultiLinkSingleReads() {
311 return this.multiLinkSingleReads;
312 }
313
314 /* (non-Javadoc)
315 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
316 */
317 @Override
318 public void selectionChanged(SelectionChangedEvent event) {
319 this.selection = event.getSelection();
320 }
321
322 public ISelection getSelection() {
323 return selection;
324 }
325
326 public DerivateLabelProvider getLabelProvider() {
327 return labelProvider;
328 }
329
330 /* (non-Javadoc)
331 * @see eu.etaxonomy.taxeditor.operation.IPostOperationEnabled#postOperation(eu.etaxonomy.cdm.model.common.CdmBase)
332 */
333 @Override
334 public boolean postOperation(CdmBase objectAffectedByOperation) {
335 refreshTree();
336 if(objectAffectedByOperation!=null){
337 changed(objectAffectedByOperation);
338 }
339 return true;
340 }
341
342 /* (non-Javadoc)
343 * @see eu.etaxonomy.taxeditor.operation.IPostOperationEnabled#onComplete()
344 */
345 @Override
346 public boolean onComplete() {
347 return true;
348 }
349
350 @Override
351 public void dispose() {
352 cdmEntitySession.dispose();
353 super.dispose();
354 }
355
356 /* (non-Javadoc)
357 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getCdmEntitySession()
358 */
359 @Override
360 public ICdmEntitySession getCdmEntitySession() {
361 return cdmEntitySession;
362 }
363
364 /* (non-Javadoc)
365 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getRootEntities()
366 */
367 @Override
368 public List<SpecimenOrObservationBase> getRootEntities() {
369 return contentProvider.getRootElements();
370 }
371
372 /* (non-Javadoc)
373 * @see eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled#getPropertyPathsMap()
374 */
375 @Override
376 public Map<Object, List<String>> getPropertyPathsMap() {
377 // TODO Auto-generated method stub
378 return null;
379 }
380
381 }