Project

General

Profile

Download (18.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 *
3
 */
4
package eu.etaxonomy.taxeditor.ui.selection;
5

    
6
import java.util.EnumSet;
7
import java.util.Observable;
8
import java.util.Observer;
9

    
10
import org.eclipse.core.runtime.IStatus;
11
import org.eclipse.core.runtime.NullProgressMonitor;
12
import org.eclipse.jface.wizard.WizardDialog;
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.events.SelectionAdapter;
15
import org.eclipse.swt.events.SelectionEvent;
16
import org.eclipse.swt.events.SelectionListener;
17
import org.eclipse.swt.graphics.Color;
18
import org.eclipse.swt.widgets.Button;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.Label;
21
import org.eclipse.swt.widgets.Shell;
22
import org.eclipse.swt.widgets.Text;
23
import org.springframework.security.core.GrantedAuthority;
24

    
25
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
27
import eu.etaxonomy.cdm.api.service.IAgentService;
28
import eu.etaxonomy.cdm.api.service.ICollectionService;
29
import eu.etaxonomy.cdm.api.service.INameService;
30
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
31
import eu.etaxonomy.cdm.api.service.IReferenceService;
32
import eu.etaxonomy.cdm.api.service.IService;
33
import eu.etaxonomy.cdm.api.service.IUserService;
34
import eu.etaxonomy.cdm.api.service.molecular.IAmplificationService;
35
import eu.etaxonomy.cdm.api.service.molecular.IPrimerService;
36
import eu.etaxonomy.cdm.common.CdmUtils;
37
import eu.etaxonomy.cdm.model.agent.Institution;
38
import eu.etaxonomy.cdm.model.agent.Person;
39
import eu.etaxonomy.cdm.model.agent.Team;
40
import eu.etaxonomy.cdm.model.common.CdmBase;
41
import eu.etaxonomy.cdm.model.common.Group;
42
import eu.etaxonomy.cdm.model.common.ICdmBase;
43
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
44
import eu.etaxonomy.cdm.model.common.User;
45
import eu.etaxonomy.cdm.model.molecular.Amplification;
46
import eu.etaxonomy.cdm.model.molecular.Primer;
47
import eu.etaxonomy.cdm.model.name.NonViralName;
48
import eu.etaxonomy.cdm.model.occurrence.Collection;
49
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
50
import eu.etaxonomy.cdm.model.reference.Reference;
51
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
52
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
53
import eu.etaxonomy.taxeditor.model.AbstractUtility;
54
import eu.etaxonomy.taxeditor.model.ImageResources;
55
import eu.etaxonomy.taxeditor.model.MessagingUtils;
56
import eu.etaxonomy.taxeditor.preference.Resources;
57
import eu.etaxonomy.taxeditor.store.CdmStore;
58
import eu.etaxonomy.taxeditor.store.LoginManager;
59
import eu.etaxonomy.taxeditor.store.StoreUtil;
60
import eu.etaxonomy.taxeditor.ui.dialog.selection.SelectionDialogFactory;
61
import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
62
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
63
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
64
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
65
import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
66
import eu.etaxonomy.taxeditor.ui.element.IEntityElement;
67
import eu.etaxonomy.taxeditor.ui.element.ILabeledElement;
68
import eu.etaxonomy.taxeditor.ui.element.ISelectableElement;
69
import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
70
import eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator;
71
import eu.etaxonomy.taxeditor.ui.section.grantedAuthority.GrantedAuthorityLabelTextProvider;
72

    
73
/**
74
 * <p>
75
 * Abstract AbstractSelectionElement class.
76
 * </p>
77
 *
78
 * @author n.hoffmann
79
 * @created Nov 17, 2009
80
 * @version 1.0
81
 * @param <T>
82
 */
83
public class EntitySelectionElement<T extends ICdmBase> extends
84
		AbstractCdmFormElement implements  SelectionListener, IEnableableFormElement, ISelectableElement, IEntityElement<T>, ILabeledElement, IConversationEnabled, Observer {
85

    
86
	private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
87
	private static final EnumSet<CRUD> DELETE = EnumSet.of(CRUD.DELETE);
88
	private static final EnumSet<CRUD> CREATE = EnumSet.of(CRUD.CREATE);
89

    
90
	/**
91
	 * Bitmask for configuring functionality of selection element
92
	 */
93
	public static final int NOTHING = 0; // 000
94
	public static final int EDITABLE = 1 << 0; // 001
95
	public static final int DELETABLE = 1 << 1; // 010
96
	public static final int SELECTABLE = 1 << 2; // 100
97
	public static final int ALL = EDITABLE | DELETABLE | SELECTABLE; // 111
98

    
99
	protected T entity;
100

    
101
	protected Label label;
102
	protected Text text;
103
	protected Button button_selection;
104

    
105
	private SelectionArbitrator selectionArbitrator;
106

    
107
	protected Button button_edit;
108

    
109
	private final String labelString;
110

    
111
	private Composite selectableComposite;
112

    
113
	private Button button_remove;
114

    
115
	private final boolean isEditable;
116

    
117
	private final boolean isDeletable;
118

    
119
	private final ConversationHolder conversation;
120
	private Class<T> clazz;
121

    
122
	/**
123
	 * <p>
124
	 * Constructor for AbstractSelectionElement.
125
	 * </p>
126
	 *
127
	 * @param formFactory
128
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
129
	 *            object.
130
	 * @param conversation
131
	 *            TODO
132
	 * @param parentElement
133
	 *            a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
134
	 *            object.
135
	 * @param labelString
136
	 *            a {@link java.lang.String} object.
137
	 * @param entity
138
	 *            a T object.
139
	 * @param isEditable
140
	 *            a boolean.
141
	 * @param isSelectable
142
	 *            a boolean.
143
	 * @param isDeletable
144
	 *            a boolean.
145
	 * @param style
146
	 *            a int.
147
	 * @param <T>
148
	 *            a T object.
149
	 */
150
	public EntitySelectionElement(CdmFormFactory formFactory,
151
			ConversationHolder conversation, ICdmFormElement parentElement,
152
			String labelString, T entity, int mode, int style) {
153
		super(formFactory, parentElement);
154

    
155
		this.isEditable = (mode & EDITABLE) == EDITABLE;
156
		this.isDeletable = (mode & DELETABLE) == DELETABLE;
157
		boolean isSelectable = (mode & SELECTABLE) == SELECTABLE;
158

    
159
		this.labelString = (labelString == null || labelString.equals("")) ? "" : labelString + " : ";
160

    
161
		this.conversation = conversation;
162

    
163
		if (isSelectable && formFactory.getSelectionProvider() != null) {
164
			selectionArbitrator = formFactory.createSelectionArbitrator(this);
165
		}
166

    
167
		createControls(getLayoutComposite(), SWT.NULL);
168

    
169
		setEntity(entity);
170
	}
171

    
172
	public EntitySelectionElement(CdmFormFactory formFactory,
173
			ConversationHolder conversation, ICdmFormElement parentElement, Class<T> clazz,
174
			String labelString, T entity, int mode, int style) {
175
		this(formFactory, conversation, parentElement, labelString, entity, mode, style);
176
		this.clazz = clazz;
177
	}
178

    
179
	private void createControls(Composite parent, int style) {
180

    
181
		label = formFactory.createLabel(getLayoutComposite(), labelString,
182
				SWT.NULL);
183

    
184
		addControl(label);
185

    
186
		selectableComposite = formFactory.createComposite(getLayoutComposite());
187

    
188
		int columns = 2;
189
		if (isEditable) {
190
			columns += 1;
191
		}
192
		if (isDeletable) {
193
			columns += 1;
194
		}
195

    
196
		selectableComposite.setLayout(LayoutConstants.LAYOUT(columns, false));
197
		selectableComposite.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
198

    
199
		addControl(selectableComposite);
200

    
201
		text = formFactory.createText(selectableComposite, null, SWT.WRAP);
202
		text.setEditable(false);
203
		addControl(text);
204

    
205
		text.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
206
		text.setBackground(StoreUtil
207
				.getColor(Resources.COLOR_TEXT_DISABLED_BACKGROUND));
208

    
209
		button_selection = formFactory.createButton(selectableComposite, null,
210
				SWT.PUSH);
211
		button_selection.setImage(ImageResources
212
				.getImage(ImageResources.BROWSE_ICON));
213
		button_selection.setToolTipText("Browse existing");
214

    
215
		addControl(button_selection);
216
		button_selection.addSelectionListener(this);
217

    
218
		if (isEditable) {
219
			button_edit = formFactory.createButton(selectableComposite, null,
220
					SWT.PUSH);
221
			button_edit.setImage(ImageResources
222
					.getImage(ImageResources.EDIT_ICON));
223
			button_edit.setToolTipText("Edit");
224
			addControl(button_edit);
225
			button_edit.addSelectionListener(new EditListener(this));
226
		}
227

    
228
		if (isDeletable) {
229
			button_remove = formFactory.createButton(selectableComposite, null,
230
					SWT.PUSH);
231
			button_remove.setImage(ImageResources
232
					.getImage(ImageResources.TRASH_ICON));
233
			button_remove.setToolTipText("Remove");
234
			addControl(button_remove);
235
			button_remove.addSelectionListener(new DeleteListener(this));
236
		}
237
	}
238

    
239
	@Override
240
    public void widgetSelected(SelectionEvent e) {
241
		T selection = SelectionDialogFactory.getSelectionFromDialog(clazz, getShell(), getConversationHolder(), getEntity(), getParentElement());
242
		setSelectionInternal(selection);
243
	}
244

    
245
	/**
246
	 * Return the selected object
247
	 *
248
	 * @return a T object.
249
	 */
250
	public T getSelection() {
251
		return entity;
252
	}
253

    
254
	/*
255
	 * (non-Javadoc)
256
	 *
257
	 * @see
258
	 * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
259
	 */
260
	/** {@inheritDoc} */
261
	@Override
262
	public void setEnabled(boolean enabled) {
263
		button_selection.setEnabled(enabled);
264
		if (isDeletable){
265
		    button_remove.setEnabled(enabled);
266
		}
267
		if (isEditable) {
268
			updateButtonStates();
269
		}
270
	}
271

    
272
	/* (non-Javadoc)
273
	 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
274
	 */
275
	@Override
276
	public boolean isEnabled() {
277
	    return button_selection.isEnabled();
278
	}
279

    
280
	/**
281
	 * <p>
282
	 * setSelectionInternal
283
	 * </p>
284
	 *
285
	 * @param selection
286
	 *            a T object.
287
	 */
288
	protected void setSelectionInternal(T selection) {
289
		if (selection != null && !selection.equals(this.entity)) {
290
			setEntity(selection);
291
			firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
292
		}
293
	}
294

    
295
	/**
296
	 * <p>
297
	 * Setter for the field <code>entity</code>.
298
	 * </p>
299
	 *
300
	 * @param selection
301
	 *            a T object.
302
	 */
303
	public void setEntity(T selection) {
304
		this.entity = selection;
305
		updateElement();
306
	}
307

    
308
	/**
309
	 * Updates this elements view
310
	 */
311
	protected void updateElement() {
312
		String title = CdmUtils.Nz(getTitle());
313
		text.setText(title); // title can be null
314
		if (isEditable) {
315
			updateButtonStates();
316
		}
317
	}
318

    
319
    public void updateFromWizard() {
320
		updateElement();
321
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null));
322
	}
323

    
324
	/**
325
	 * <p>
326
	 * getTitle
327
	 * </p>
328
	 *
329
	 * @return a {@link java.lang.String} object.
330
	 */
331
	protected String getTitle() {
332
		if (entity != null){
333
			if(entity instanceof IIdentifiableEntity) {
334
				return ((IIdentifiableEntity) entity).getTitleCache();
335
			} else if(entity instanceof Group){
336
				return ((Group) entity).getName();
337
			} else if(entity instanceof GrantedAuthority){
338
				return GrantedAuthorityLabelTextProvider.getText(((GrantedAuthority) entity));
339
			} else if(entity instanceof User){
340
                return ((User) entity).getUsername();
341
            } else if (entity instanceof Primer){
342
                return ((Primer) entity).getLabel();
343
            } else if (entity instanceof Amplification){
344
                return ((Amplification) entity).getLabelCache();
345
            }
346

    
347
		}
348
		return "";
349
	}
350

    
351
	/** {@inheritDoc} */
352
	@Override
353
	public void setSelected(boolean selected) {
354
		setBackground(selected ? SELECTED : getPersistentBackground());
355
	}
356

    
357
	/*
358
	 * (non-Javadoc)
359
	 *
360
	 * @see eu.etaxonomy.taxeditor.forms.IEntityElement#getEntity()
361
	 */
362
	/**
363
	 * <p>
364
	 * Getter for the field <code>entity</code>.
365
	 * </p>
366
	 *
367
	 * @return a T object.
368
	 */
369
	@Override
370
	public T getEntity() {
371
		return entity;
372
	}
373

    
374
	/*
375
	 * (non-Javadoc)
376
	 *
377
	 * @see eu.etaxonomy.taxeditor.forms.section.cdmdetail.ISelectableElement#
378
	 * getSelectionArbitrator()
379
	 */
380
	/**
381
	 * <p>
382
	 * Getter for the field <code>selectionArbitrator</code>.
383
	 * </p>
384
	 *
385
	 * @return a {@link eu.etaxonomy.taxeditor.ui.element.SelectionArbitrator}
386
	 *         object.
387
	 */
388
	@Override
389
	public SelectionArbitrator getSelectionArbitrator() {
390
		return selectionArbitrator;
391
	}
392

    
393
	/**
394
	 * Convenient access to current shell
395
	 *
396
	 * @return a {@link org.eclipse.swt.widgets.Shell} object.
397
	 */
398
    public Shell getShell() {
399
		return getLayoutComposite().getShell();
400
	}
401

    
402
	/** {@inheritDoc} */
403
	@Override
404
	public void setIrrelevant(boolean irrelevant) {
405
		String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
406
				: Resources.COLOR_TEXT_DISABLED_BACKGROUND;
407

    
408
		Color color = StoreUtil.getColor(colorId);
409
		text.setBackground(color);
410
	}
411

    
412
	private class DeleteListener extends SelectionAdapter {
413

    
414
		private final EntitySelectionElement<T> selectionElement;
415

    
416
		public DeleteListener(EntitySelectionElement<T> selectionElement) {
417
			this.selectionElement = selectionElement;
418
		}
419

    
420
		@Override
421
		public void widgetSelected(SelectionEvent e) {
422
			setEntity(null);
423
			firePropertyChangeEvent(new CdmPropertyChangeEvent(
424
					selectionElement, null));
425
		}
426
	}
427

    
428
	private class EditListener extends SelectionAdapter {
429

    
430
        private static final String TRANSIENT_EDITING_WARNING_TEXT = "Warning: All changes for this element are directly reflected in the data base.\nThe \"Cancel\" button has no effect";
431
        private static final String TRANSIENT_EDITING_WARNING_TITLE = "CDM element not yet saved.";
432
        private final EntitySelectionElement<T> selectionElement;
433

    
434
		public EditListener(EntitySelectionElement<T> selectionElement) {
435
			this.selectionElement = selectionElement;
436
		}
437

    
438
		/** {@inheritDoc} */
439
		@Override
440
		public void widgetSelected(SelectionEvent e) {
441
		    T originalEntity = selectionElement.getEntity();
442
		    T clonedEntity = null;
443
		    IService<T> service = null;
444
		    if(originalEntity instanceof CdmBase){
445
		        //get corresponding service
446
		        if(entity instanceof Reference<?>){
447
		            service = (IService<T>) CdmStore.getService(IReferenceService.class);
448
		        }
449
		        else if (entity instanceof Team || entity instanceof Person || entity instanceof Institution) {
450
		            service = (IService<T>) CdmStore.getService(IAgentService.class);
451
		        }
452
		        else if (entity instanceof NonViralName) {
453
		            service = (IService<T>) CdmStore.getService(INameService.class);
454
		        }
455
		        else if (entity instanceof SpecimenOrObservationBase) {
456
		            service = (IService<T>) CdmStore.getService(IOccurrenceService.class);
457
		        }
458
		        else if (entity instanceof Collection) {
459
		            service = (IService<T>) CdmStore.getService(ICollectionService.class);
460
		        }
461
		        else if (entity instanceof User) {
462
		            service = (IService<T>) CdmStore.getService(IUserService.class);
463
		        }
464
		        else if (entity instanceof Primer) {
465
		            service = (IService<T>) CdmStore.getService(IPrimerService.class);
466
		        }
467
		        else if (entity instanceof Amplification) {
468
		            service = (IService<T>) CdmStore.getService(IAmplificationService.class);
469
		        }
470
		        //check if original already exists in data base. If not then do not clone and all changes will be persisted directly -> Warning to user.
471
                if(service !=null && service.find(originalEntity.getUuid())==null && originalEntity.getId() != 0){
472
                    if(MessagingUtils.confirmDialog(TRANSIENT_EDITING_WARNING_TITLE, "["+originalEntity.getClass().getSimpleName()+"]"+originalEntity + " has to be saved before it can be edited. Save now?")){
473
                        service.save(originalEntity);
474
                        AbstractUtility.getActiveEditor().doSave(new NullProgressMonitor());
475
                    }
476
                    else{
477
                        //transient CDM elements should not be edited to avoid merge conflicts
478
                        // when the elements are cascaded
479
                        return;
480
                    }
481
                }
482
                else{
483
                    //FIXME temporarily disabled cloning re-opening bug #2645 (EditFromSelectionWizard persists data even when canceled)
484
//                    try {
485
//                        //clone original
486
//                        clonedEntity = (T) ((CdmBase) originalEntity).clone();
487
//                    } catch (CloneNotSupportedException e1) {
488
//                        MessagingUtils.warningDialog(TRANSIENT_EDITING_WARNING_TITLE, this, TRANSIENT_EDITING_WARNING_TEXT);
489
//                    }
490
                }
491

    
492
		    }
493
		    if(clonedEntity!=null){
494
		        selectionElement.setEntity(clonedEntity);
495
		    }
496
			WizardDialog dialog = new WizardDialog(selectionElement.getShell(),
497
					new EditFromSelectionWizard(selectionElement));
498
			if (dialog.open() == IStatus.OK) {
499
			    if(service!=null && clonedEntity!=null){//check if cloning happened
500
			        T editedClonedEntity = selectionElement.getEntity();
501
			        editedClonedEntity.setId(originalEntity.getId());
502
			        editedClonedEntity.setUuid(originalEntity.getUuid());
503

    
504
			        //merge clone and original
505
			        service.merge(editedClonedEntity);
506
			        originalEntity = service.load(originalEntity.getUuid());
507

    
508
			    }
509
			    selectionElement.setEntity(originalEntity);
510
				selectionElement.updateFromWizard();
511
			}
512
			//be sure to reset to original in all cases
513
			selectionElement.setEntity(originalEntity);
514
			selectionElement.refresh();
515
		}
516
	}
517

    
518
	// not used
519
	/** {@inheritDoc} */
520
	@Override
521
	public void widgetDefaultSelected(SelectionEvent e) {
522
	}
523

    
524
	/**
525
	 * <p>
526
	 * getConversationHolder
527
	 * </p>
528
	 *
529
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder}
530
	 *         object.
531
	 */
532
	@Override
533
	public ConversationHolder getConversationHolder() {
534
		return conversation;
535
	}
536

    
537
	/** {@inheritDoc} */
538
	@Override
539
	public void setBackground(Color color) {
540
	    if(!label.isDisposed()){
541
	        label.setBackground(color);
542
	    }
543
	}
544

    
545
	/** {@inheritDoc} */
546
	@Override
547
	public void setLabel(String labelString) {
548
		if (label != null) {
549
			label.setText(labelString);
550
		}
551
	}
552

    
553
	/**
554
	 * <p>
555
	 * Getter for the field <code>label</code>.
556
	 * </p>
557
	 *
558
	 * @return a {@link java.lang.String} object.
559
	 */
560
	@Override
561
	public String getLabel() {
562
		if (label != null) {
563
			return label.getText() + " : ";
564
		}
565
		return null;
566
	}
567

    
568
	/** {@inheritDoc} */
569
	@Override
570
	public void update(CdmDataChangeMap changeEvents) {
571
	}
572

    
573
	/* (non-Javadoc)
574
	 * @see eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement#removeElements()
575
	 */
576
	@Override
577
    public void removeElements(){
578
		super.removeElements();
579
		LoginManager loginManager = CdmStore.getLoginManager();
580
		loginManager.addObserver(this);
581
	}
582

    
583
	@Override
584
	public void update(Observable o, Object arg) {
585
		if(o instanceof LoginManager){
586
			updateButtonStates();
587
		}
588
	}
589

    
590
	private void updateButtonStates() {
591
	    if(button_edit != null && !button_selection.isDisposed()){
592
	        button_edit.setEnabled(isEditable && button_selection.isEnabled() && getEntity() != null  && CdmStore.currentAuthentiationHasPermission((CdmBase) getEntity(), UPDATE));
593
	    }
594
	}
595
}
(2-2/5)