Project

General

Profile

Download (17.1 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
 * @version 1.0
65
 */
66
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase> extends
67
		SearchDialog {//implements IConversationEnabled {
68

    
69
//	private final ConversationHolder conversation = null;
70

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

    
76
	private T selectedObject;
77

    
78
	protected Set<UUID> cdmBaseToBeFiltered;
79

    
80
	protected Job searchJob;
81

    
82

    
83
	/**
84
	 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
85
	 *
86
	 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
87
	 * @param conversation
88
	 * @param title a {@link java.lang.String} object.
89
	 * @param multi a boolean.
90
	 * @param settings a {@link java.lang.String} object.
91
	 * @param cdmObject a T object.
92
	 * @param <T> a T object.
93
	 */
94
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, //ConversationHolder conversation,
95
	        String title, boolean multi, String settings, T cdmObject) {
96
		super(shell, title);
97
		setShellStyle(SWT.DIALOG_TRIM);
98
		setMessage(Messages.SearchDialog_patternLabel);
99
		this.settings = settings;
100
        if (cdmObject != null){
101
            this.cdmBaseToBeFiltered = new HashSet<>();
102
            this.cdmBaseToBeFiltered.add(cdmObject.getUuid());
103
        }
104
		Cursor cursor = shell.getCursor();
105
		shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
106
		init();
107
		shell.setCursor(cursor);
108
		setListLabelProvider(createListLabelProvider());
109

    
110
	}
111

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

    
123
	/**
124
	 *
125
	 * @return
126
	 */
127
	protected ILabelProvider createListLabelProvider() {
128
		return new FilteredCdmResourceLabelProvider();
129
	}
130

    
131
	/**
132
	 * Override in subclasses.
133
	 * Will run before initModel()
134
	 */
135
	protected void init() {
136

    
137
	}
138

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

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

    
168
        if (result == Window.CANCEL) {
169
            return null;
170
        }
171

    
172
        UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
173

    
174
        return uuid;
175
    }
176

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

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

    
201

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

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

    
223
		if (cdmObject instanceof IIdentifiableEntity) {
224
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
225
		}
226

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

    
232

    
233

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

    
244

    
245

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

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

    
264
			    contentProvider.reset();
265
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
266
				UuidAndTitleCache<T> element;
267
				while(iterator.hasNext()){
268
				    element = iterator.next();
269

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

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

    
293

    
294
    protected void sort() {
295
        Collections.sort(model, getItemsComparator());
296
    }
297

    
298
    /* (non-Javadoc)
299
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
300
	 */
301
	/** {@inheritDoc} */
302

    
303
	protected IDialogSettings getDialogSettings() {
304
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
305

    
306
		if (settings == null) {
307
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
308
		}
309
		return settings;
310
	}
311

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

    
317
	public String getElementName(Object item) {
318
		return ((UuidAndTitleCache) item).getTitleCache();
319
	}
320

    
321
	/* (non-Javadoc)
322
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
323
	 */
324
	/** {@inheritDoc} */
325

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

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

    
361

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

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

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

    
398

    
399

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

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

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

    
429
            return titleCache;
430
		}
431
	};
432

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

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

    
450
	@Override
451
    protected void createButtonsForButtonBar(Composite parent) {
452
	    String[] newButtonText = getNewWizardText();
453

    
454
	    if (newButtonText!= null){
455
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
456
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
457

    
458

    
459
	        if (newButtonText.length > 1){
460
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
461
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
462

    
463
	        }
464

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

    
482
        super.createButtonsForButtonBar(parent);
483
        super.getButton(IDialogConstants.OK_ID).setEnabled(false);
484
    }
485

    
486
	protected SelectionListener getNewWizardButtonSelectionListener(){
487
		return new SelectionAdapter() {
488

    
489
			/* (non-Javadoc)
490
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
491
			 */
492
			@Override
493
			public void widgetSelected(SelectionEvent e) {
494
			    Object source = e.getSource();
495
			    String text = null;
496
			    if (source instanceof Button){
497
			        Button sourceButton = (Button) source;
498
			        text = sourceButton.getText();
499
			    }
500
			    AbstractNewEntityWizard wizard = getNewEntityWizard(text);
501
			    if(wizard!=null){
502
			        if (wizard.getEntity() == null){
503
			            wizard.init(null, null);
504
			        }
505
			        if(wizard.getEntity() != null) {
506
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
507
			            int status = dialog.open();
508

    
509
			            if (status == IStatus.OK) {
510

    
511
			                T entity = (T) wizard.getEntity();
512
			                refresh();
513
			                setPattern(entity);
514

    
515
//			                if (getConversationHolder() != null){
516
//			                    getConversationHolder().bind();
517
//			                }
518
			            }
519
			            //FIXME : Need to make sure this is a stable fix (ticket 3822)
520
//			            if (getConversationHolder() != null){
521
//			                getConversationHolder().commit();
522
//			            }
523
			        }
524
			    }
525
			}
526
		};
527
	}
528

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

    
539
	/** {@inheritDoc} */
540
//	@Override
541
//	public void update(CdmDataChangeMap changeEvents) {}
542

    
543
	/**
544
	 * Don't want to add for example a taxon or synonym to itself
545
	 * so filter the list to remove the taxon in question
546
	 * (<code>cdmBaseToBeFiltered</code>)
547
	 * so it is not available in the filtered list.
548
	 */
549
	private void filterExcludedObjects() {
550
		if (model != null && cdmBaseToBeFiltered != null) {
551

    
552
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
553

    
554
			for (UuidAndTitleCache uuidAndTitleCache : model){
555
				if (cdmBaseToBeFiltered != null && cdmBaseToBeFiltered.contains(uuidAndTitleCache.getUuid())) {
556
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
557
				}
558
			}
559
			model.remove(uuidAndTitleCacheToRemove);
560
		}
561
	}
562
	@Override
563
	void createFilterButton(Composite searchAndFilter){
564
	    //as default no filter button available
565
	}
566

    
567
	/** {@inheritDoc} */
568
    @Override
569
    protected void search() {
570
        Control control =getSearchField();
571
        String pattern = null;
572
        if (control != null){
573
            pattern = ((Text)control).getText();
574
            if (pattern.equals("*") || pattern.equals("?")){
575
                callService("*");
576
            }else if (StringUtils.isNotBlank(pattern)){
577
                callService(pattern);
578
            }
579
            fillContentProvider(null);
580
        }
581

    
582
//        if (pattern.equals("?")){
583
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(null, null);
584
//        }else if (pattern != null){
585
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(limitOfInitialElements, pattern);
586
//        }
587
    }
588

    
589
    abstract void callService(String pattern);
590

    
591
}
(2-2/44)