Project

General

Profile

Download (17.3 KB) Statistics
| Branch: | Tag: | Revision:
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.ui.dialog.selection;
11

    
12
import java.text.Collator;
13
import java.util.ArrayList;
14
import java.util.Collections;
15
import java.util.Comparator;
16
import java.util.HashSet;
17
import java.util.Iterator;
18
import java.util.List;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.apache.commons.lang.StringUtils;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.core.runtime.IStatus;
25
import org.eclipse.core.runtime.jobs.Job;
26
import org.eclipse.jface.dialogs.IDialogConstants;
27
import org.eclipse.jface.dialogs.IDialogSettings;
28
import org.eclipse.jface.viewers.ILabelProvider;
29
import org.eclipse.jface.viewers.LabelProvider;
30
import org.eclipse.jface.viewers.StructuredSelection;
31
import org.eclipse.jface.window.Window;
32
import org.eclipse.jface.wizard.WizardDialog;
33
import org.eclipse.swt.SWT;
34
import org.eclipse.swt.events.SelectionAdapter;
35
import org.eclipse.swt.events.SelectionEvent;
36
import org.eclipse.swt.events.SelectionListener;
37
import org.eclipse.swt.graphics.Cursor;
38
import org.eclipse.swt.layout.GridData;
39
import org.eclipse.swt.layout.GridLayout;
40
import org.eclipse.swt.widgets.Button;
41
import org.eclipse.swt.widgets.Composite;
42
import org.eclipse.swt.widgets.Control;
43
import org.eclipse.swt.widgets.Shell;
44
import org.eclipse.swt.widgets.Text;
45

    
46
import eu.etaxonomy.cdm.api.service.dto.EntityDTOBase;
47
import eu.etaxonomy.cdm.api.service.dto.IdentifiedEntityDTO;
48
import eu.etaxonomy.cdm.model.common.CdmBase;
49
import eu.etaxonomy.cdm.model.common.ICdmBase;
50
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
51
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
52
import eu.etaxonomy.taxeditor.l10n.Messages;
53
import eu.etaxonomy.taxeditor.model.MessagingUtils;
54
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
55
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
56
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
57
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
58

    
59
/**
60
 * <p>Abstract AbstractFilteredCdmResourceSelectionDialog class.</p>
61
 *
62
 * @author n.hoffmann
63
 * @created 04.06.2009
64
 */
65
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase> extends
66
		SearchDialog {//implements IConversationEnabled {
67

    
68
//	private final ConversationHolder conversation = null;
69

    
70
	protected List<UuidAndTitleCache<T>> model;
71
	private final Set<T> transientCdmObjects = new HashSet<T>();
72
	private final String settings;
73
	protected final Integer limitOfInitialElements = null;
74

    
75
	private T selectedObject;
76

    
77
	protected Set<UUID> cdmBaseToBeFiltered;
78

    
79
	protected Job searchJob;
80

    
81
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, //ConversationHolder conversation,
82
	        String title, boolean multi, String settings, Set<T> objectsToBeFiltered) {
83
	    super(shell, title);
84
        setShellStyle(SWT.DIALOG_TRIM);
85
        setMessage(Messages.SearchDialog_patternLabel);
86
        this.settings = settings;
87
        if (objectsToBeFiltered != null){
88
            this.cdmBaseToBeFiltered = new HashSet<>();
89
            objectsToBeFiltered.forEach(filter->this.cdmBaseToBeFiltered.add(filter.getUuid()));
90
        }
91
        Cursor cursor = shell.getCursor();
92
        shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
93
        init();
94
        shell.setCursor(cursor);
95
        setListLabelProvider(createListLabelProvider());
96

    
97
	}
98

    
99
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, //ConversationHolder conversation,
100
	        String title, boolean multi, String settings) {
101
        this(shell, title, multi, settings, (Set<T>)null);
102
	}
103

    
104
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, //ConversationHolder conversation,
105
	        String title, boolean multi, String settings, T objectToBeFiltered) {
106
	    this(shell, title, multi, settings, objectToBeFiltered!=null?Collections.singleton(objectToBeFiltered):null);
107
	}
108

    
109
	/**
110
	 * By default, we are returning the standard list label provider
111
	 *
112
	 * Override in subclasses if you want different behavior
113
	 *
114
	 * @return
115
	 */
116
	protected ILabelProvider createDetailsLabelProvider() {
117
		return createListLabelProvider();
118
	}
119

    
120
	/**
121
	 *
122
	 * @return
123
	 */
124
	protected ILabelProvider createListLabelProvider() {
125
		return new FilteredCdmResourceLabelProvider();
126
	}
127

    
128
	/**
129
	 * Override in subclasses.
130
	 * Will run before initModel()
131
	 */
132
	protected void init() {
133

    
134
	}
135

    
136
	/**
137
	 * <p>getSelectionFromDialog</p>
138
	 *
139
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
140
	 * @param <TYPE> a TYPE object.
141
	 * @return a TYPE object.
142
	 */
143
	protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) {
144
	    UuidAndTitleCache result = getUuidAndTitleCacheSelectionFromDialog(dialog);
145
	    if (result != null){
146
	        return dialog.getCdmObjectByUuid(result.getUuid());
147
	    } else {
148
            return null;
149
        }
150
	}
151

    
152
	/**
153
     * <p>getSelectionFromDialog</p>
154
     *
155
     * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
156
     * @param <TYPE> a TYPE object.
157
     * @return a TYPE object.
158
     */
159
    protected static UuidAndTitleCache getUuidAndTitleCacheSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog dialog) {
160
        if (dialog == null){
161
            return null;
162
        }
163
        int result = dialog.open();
164

    
165
        if (result == Window.CANCEL) {
166
            return null;
167
        }
168

    
169
        UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
170

    
171
        return uuid;
172
    }
173

    
174
	/**
175
	 * Check if object was created during the life of this dialog. If not,
176
	 * retrieve it from the CdmStore.
177
	 *
178
	 * @param cdmUuid a {@link java.util.UUID} object.
179
	 * @return a T object.
180
	 */
181
	protected T getCdmObjectByUuid(UUID cdmUuid) {
182
		for (T cdmObject : transientCdmObjects) {
183
			if (cdmObject.getUuid().equals(cdmUuid)) {
184
				return cdmObject;
185
			}
186
		}
187
		return getPersistentObject(cdmUuid);
188
	}
189

    
190
	/**
191
	 * <p>getPersistentObject</p>
192
	 *
193
	 * @param uuid a {@link java.util.UUID} object.
194
	 * @return a T object.
195
	 */
196
	abstract protected T getPersistentObject(UUID uuid);
197

    
198

    
199
	/**
200
	 * <p>isObjectTransient</p>
201
	 *
202
	 * @param cdmObject a T object.
203
	 * @return a boolean.
204
	 */
205
	protected boolean isObjectTransient(T cdmObject) {
206
		return (getPersistentObject(cdmObject.getUuid()) == null);
207
	}
208

    
209
	/**
210
	 * <p>getTitle</p>
211
	 *
212
	 * @param cdmObject a T object.
213
	 * @return a {@link java.lang.String} object.
214
	 */
215
	protected String getTitle(T cdmObject) {
216
		if(cdmObject == null){
217
			return "";
218
		}
219

    
220
		if (cdmObject instanceof IIdentifiableEntity) {
221
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
222
		}
223

    
224
		throw new IllegalArgumentException("Generic method only" +
225
				" supports cdmObject of type IIdentifiableEntity." +
226
				" Please implement specific method in subclass.");
227
	}
228

    
229

    
230

    
231
	/**
232
	 * Set the filter input to the Agent's title cache
233
	 *
234
	 * @param cdmObject a T object.
235
	 */
236
	protected void setPattern(T cdmObject) {
237
		String pattern = getTitle(cdmObject);
238
		getSearchField().setText(pattern);
239
	}
240

    
241

    
242

    
243
	/* (non-Javadoc)
244
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
245
	*/
246
	/** {@inheritDoc} */
247

    
248
	@Override
249
    protected void fillContentProvider(IProgressMonitor progressMonitor)
250
		 {
251
		try {
252
		    if (model == null){
253
		        model = new ArrayList<UuidAndTitleCache<T>>();
254
		    }
255
			if(model != null){
256
			    if (progressMonitor != null){
257
			        progressMonitor.beginTask("Looking for entities", model.size());
258
			    }
259
			    sort();
260

    
261
			    contentProvider.reset();
262
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
263
				UuidAndTitleCache<T> element;
264
				while(iterator.hasNext()){
265
				    element = iterator.next();
266

    
267
				    if (cdmBaseToBeFiltered == null || !cdmBaseToBeFiltered.contains(element.getUuid())){
268
				        contentProvider.add(element);
269
				    }
270
				    if (progressMonitor != null){
271
    					if (progressMonitor.isCanceled()) {
272
    						return;
273
    					}
274
    					progressMonitor.worked(1);
275
				    }
276
				}
277
				this.refresh();
278
			}else{
279

    
280
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
281
			}
282
		}
283
		finally {
284
		    if (progressMonitor != null) {
285
                progressMonitor.done();
286
            }
287
		}
288
	}
289

    
290

    
291
    protected void sort() {
292
        Collections.sort(model, getItemsComparator());
293
    }
294

    
295
    /* (non-Javadoc)
296
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
297
	 */
298
	/** {@inheritDoc} */
299

    
300
	protected IDialogSettings getDialogSettings() {
301
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
302

    
303
		if (settings == null) {
304
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
305
		}
306
		return settings;
307
	}
308

    
309
	/* (non-Javadoc)
310
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
311
	 */
312
	/** {@inheritDoc} */
313

    
314
	public String getElementName(Object item) {
315
		return ((UuidAndTitleCache) item).getTitleCache();
316
	}
317

    
318
	/* (non-Javadoc)
319
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
320
	 */
321
	/** {@inheritDoc} */
322

    
323
	@Override
324
    protected Comparator getItemsComparator() {
325
		return new Comparator<UuidAndTitleCache>() {
326
			@Override
327
			public int compare(UuidAndTitleCache entity1,
328
					UuidAndTitleCache entity2) {
329
				Collator collator = Collator.getInstance();
330
				if (entity1 == entity2){
331
				    return 0;
332
				}
333

    
334
				if (entity1 == null && entity2 != null){
335
				    return -1;
336
				}
337
				if (entity2 == null && entity1 != null){
338
				    return 1;
339
				}
340
				if (entity1.getUuid().equals(entity2.getUuid())){
341
                    return 0;
342
                }
343
				if (entity1.getTitleCache() == null && entity2.getTitleCache() != null){
344
				    return -1;
345
				}
346
				if (entity2.getTitleCache() == null){
347
				    return 1;
348
				}
349
				int result = collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
350
				if (result == 0){
351
				    result = entity1.getUuid().compareTo(entity2.getUuid());
352
				}
353
				return result;
354
			}
355
		};
356
	}
357

    
358

    
359
	/**
360
	 * <p>getSelectedUuidAndTitleCache</p>
361
	 *
362
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
363
	 */
364
	protected UuidAndTitleCache getSelectedUuidAndTitleCache() {
365
		Object result = getResult();
366
		if (result instanceof UuidAndTitleCache){
367
		    return (UuidAndTitleCache) result;
368
		}
369
		return null;
370
	}
371

    
372
	/**
373
     * @return
374
     */
375
    private Object getResult() {
376
        StructuredSelection selection = getCurrentSelection();
377
        if (selection == null){
378
            return null;
379
        }
380
        return selection.getFirstElement();
381
    }
382

    
383
    /**
384
	 * <p>Getter for the field <code>settings</code>.</p>
385
	 *
386
	 * @return a {@link java.lang.String} object.
387
	 */
388
	public String getSettings()  {
389
		if(settings == null){
390
			throw new IllegalStateException("No SETTINGS set.");
391
		}
392
		return settings;
393
	}
394

    
395

    
396

    
397
	/**
398
	 * <p>getNewWizardLinkText</p>
399
	 *
400
	 * @return a {@link java.lang.String} object.
401
	 */
402
	protected abstract String[] getNewWizardText();
403

    
404
	/**
405
	 * <p>getNewEntityWizard</p>
406
	 * @param parameter
407
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
408
	 */
409
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
410

    
411
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
412
		@Override
413
		public String getText(Object element) {
414
			if (element == null) {
415
				return null;
416
			}
417
			UuidAndTitleCache uuidAndTitleCache = (UuidAndTitleCache) element;
418
			String titleCache = uuidAndTitleCache.getTitleCache();
419
			if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_ID_IN_ENTITY_SELECTION_DIAOLOG)){
420
			    titleCache += " ["+uuidAndTitleCache.getId()+"]";
421
			}
422
			if (element instanceof EntityDTOBase){
423
			    titleCache += "(" + ((IdentifiedEntityDTO)element).getIdentifier().getTypeLabel() +": " + ((IdentifiedEntityDTO)element).getIdentifier().getIdentifier() + ")";
424
			}
425

    
426
            return titleCache;
427
		}
428
	};
429

    
430
	/* (non-Javadoc)
431
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
432
	*/
433
	/** {@inheritDoc} */
434

    
435
//	@Override
436
//    protected Control createExtendedContentArea(Composite parent) {
437
//		String newWizardLinkText = getNewWizardLinkText();
438
////        if(newWizardLinkText != null){
439
////            newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
440
////
441
////            newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
442
////			return newButton1;
443
////		}
444
//		return null;
445
//	}
446

    
447
	@Override
448
    protected void createButtonsForButtonBar(Composite parent) {
449
	    String[] newButtonText = getNewWizardText();
450

    
451
	    if (newButtonText!= null){
452
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
453
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
454

    
455

    
456
	        if (newButtonText.length > 1){
457
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
458
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
459

    
460
	        }
461

    
462
	    }
463
	    Button space = createButton(parent, this.space_id, " ", false);
464
	    space.setEnabled(false);
465
	    space.setVisible(false);
466
	    GridData gridData = new GridData();
467
        gridData.grabExcessHorizontalSpace = false;
468
        gridData.widthHint = 3;
469
	    space.setLayoutData(gridData);
470
	    GridLayout gridLayout = new GridLayout();
471
	    gridLayout.makeColumnsEqualWidth= false;
472
	    if (newButtonText != null){
473
	    	gridLayout.numColumns=newButtonText.length+2;
474
	    }else{
475
	    	gridLayout.numColumns=2;
476
	    }
477
	    parent.setLayout(gridLayout);
478

    
479
        super.createButtonsForButtonBar(parent);
480
        super.getButton(IDialogConstants.OK_ID).setEnabled(false);
481
    }
482

    
483
	protected SelectionListener getNewWizardButtonSelectionListener(){
484
		return new SelectionAdapter() {
485

    
486
			@Override
487
			public void widgetSelected(SelectionEvent e) {
488
			    Object source = e.getSource();
489
			    String text = null;
490
			    if (source instanceof Button){
491
			        Button sourceButton = (Button) source;
492
			        text = sourceButton.getText();
493
			    }
494
			    AbstractNewEntityWizard wizard = getNewEntityWizard(text);
495
			    if(wizard!=null){
496
			        if (wizard.getEntity() == null){
497
			            wizard.init(null, null);
498
			        }
499
			        if(wizard.getEntity() != null) {
500
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
501
			            int status = dialog.open();
502

    
503
			            if (status == IStatus.OK) {
504

    
505
			                T entity = (T) wizard.getEntity();
506
			                refresh();
507
			                setPattern(entity);
508

    
509
//			                if (getConversationHolder() != null){
510
//			                    getConversationHolder().bind();
511
//			                }
512
			            }
513
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
514
//			            if (getConversationHolder() != null){
515
//			                getConversationHolder().commit();
516
//			            }
517
			        }
518
			    }
519
			}
520
		};
521
	}
522

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

    
533
	/** {@inheritDoc} */
534
//	@Override
535
//	public void update(CdmDataChangeMap changeEvents) {}
536

    
537
	/**
538
	 * Don't want to add for example a taxon or synonym to itself
539
	 * so filter the list to remove the taxon in question
540
	 * (<code>cdmBaseToBeFiltered</code>)
541
	 * so it is not available in the filtered list.
542
	 */
543
	private void filterExcludedObjects() {
544
		if (model != null && cdmBaseToBeFiltered != null) {
545

    
546
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
547

    
548
			for (UuidAndTitleCache uuidAndTitleCache : model){
549
				if (cdmBaseToBeFiltered != null && cdmBaseToBeFiltered.contains(uuidAndTitleCache.getUuid())) {
550
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
551
				}
552
			}
553
			model.remove(uuidAndTitleCacheToRemove);
554
		}
555
	}
556
	@Override
557
	void createFilterButton(Composite searchAndFilter){
558
	    //as default no filter button available
559
	}
560

    
561
	/** {@inheritDoc} */
562
    @Override
563
    protected void search() {
564
        Control control =getSearchField();
565
        String pattern = null;
566
        if (control != null){
567
            pattern = ((Text)control).getText();
568
            if (pattern.equals("*") || pattern.equals("?")){
569
                callService(null);
570
            }else if (StringUtils.isNotBlank(pattern)){
571
//                callService(CdmUtils.replaceNonWordCharacters(pattern, "."));
572
                callService(pattern);
573
            }
574
            fillContentProvider(null);
575
        }
576

    
577
//        if (pattern.equals("?")){
578
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(null, null);
579
//        }else if (pattern != null){
580
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(limitOfInitialElements, pattern);
581
//        }
582
    }
583

    
584
    abstract void callService(String pattern);
585

    
586
}
(2-2/44)