Project

General

Profile

Download (15.2 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
package eu.etaxonomy.taxeditor.ui.dialog.selection;
10

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

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

    
45
import eu.etaxonomy.cdm.api.service.dto.EntityDTOBase;
46
import eu.etaxonomy.cdm.api.service.dto.IdentifiedEntityDTO;
47
import eu.etaxonomy.cdm.model.common.CdmBase;
48
import eu.etaxonomy.cdm.model.common.ICdmBase;
49
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
50
import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
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.PreferencesUtil;
56
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
57

    
58
/**
59
 * @author n.hoffmann
60
 * @created 04.06.2009
61
 */
62
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase>
63
        extends SearchDialog<T> {
64

    
65
    protected List<UuidAndTitleCache<T>> model;
66
	private final Set<T> transientCdmObjects = new HashSet<>();
67
	private final String settings;
68
	protected final Integer limitOfInitialElements = null;
69

    
70
	protected Set<UUID> cdmBaseToBeFiltered;
71

    
72
	protected Job searchJob;
73

    
74
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell,
75
	        String title, boolean multi, String settings, Set<T> objectsToBeFiltered) {
76
	    super(shell, title);
77

    
78
	    setMessage(Messages.SearchDialog_patternLabel);
79
        this.settings = settings;
80
        if (objectsToBeFiltered != null){
81
            this.cdmBaseToBeFiltered = new HashSet<>();
82
            objectsToBeFiltered.forEach(filter->this.cdmBaseToBeFiltered.add(filter.getUuid()));
83
        }
84
        Cursor cursor = null;
85
        if (shell != null){
86
        	cursor = shell.getCursor();
87
        	shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
88
        }
89

    
90
        init();
91
        if (shell != null){
92
        	shell.setCursor(cursor);
93
        }
94
        setListLabelProvider(createListLabelProvider());
95
	}
96

    
97
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell,
98
	        String title, boolean multi, String settings) {
99
        this(shell, title, multi, settings, (Set<T>)null);
100
	}
101

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

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

    
118
	protected ILabelProvider createListLabelProvider() {
119
		return new FilteredCdmResourceLabelProvider();
120
	}
121

    
122
	/**
123
	 * Override in subclasses.
124
	 * Will run before initModel()
125
	 */
126
	protected void init() {}
127

    
128
	/**
129
	 * <p>getSelectionFromDialog</p>
130
	 *
131
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
132
	 * @param <TYPE> a TYPE object.
133
	 * @return a TYPE object.
134
	 */
135
	protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) {
136
	    UuidAndTitleCache<?> result = getUuidAndTitleCacheSelectionFromDialog(dialog);
137
	    if (result != null){
138
	        return dialog.getCdmObjectByUuid(result.getUuid());
139
	    } else {
140
            return null;
141
        }
142
	}
143

    
144
	/**
145
     * getSelectionFromDialog
146
     */
147
    protected static <S extends ICdmBase> UuidAndTitleCache<S> getUuidAndTitleCacheSelectionFromDialog(
148
            AbstractFilteredCdmResourceSelectionDialog<S> dialog) {
149
        if (dialog == null){
150
            return null;
151
        }
152
        int result = dialog.open();
153

    
154
        if (result == Window.CANCEL) {
155
            return null;
156
        }
157

    
158
        UuidAndTitleCache<S> uuid = dialog.getSelectedUuidAndTitleCache();
159

    
160
        return uuid;
161
    }
162

    
163
	/**
164
	 * Check if object was created during the life of this dialog. If not,
165
	 * retrieve it from the CdmStore.
166
	 */
167
	protected T getCdmObjectByUuid(UUID cdmUuid) {
168
		for (T cdmObject : transientCdmObjects) {
169
			if (cdmObject.getUuid().equals(cdmUuid)) {
170
				return cdmObject;
171
			}
172
		}
173
		return getPersistentObject(cdmUuid);
174
	}
175

    
176
	/**
177
	 * <p>getPersistentObject</p>
178
	 *
179
	 * @param uuid a {@link java.util.UUID} object.
180
	 * @return a T object.
181
	 */
182
	abstract protected T getPersistentObject(UUID uuid);
183

    
184
	/**
185
	 * <p>isObjectTransient</p>
186
	 *
187
	 * @param cdmObject a T object.
188
	 * @return a boolean.
189
	 */
190
	protected boolean isObjectTransient(T cdmObject) {
191
		return (getPersistentObject(cdmObject.getUuid()) == null);
192
	}
193

    
194
	/**
195
	 * <p>getTitle</p>
196
	 *
197
	 * @param cdmObject a T object.
198
	 * @return a {@link java.lang.String} object.
199
	 */
200
	protected String getTitle(T cdmObject) {
201
		if(cdmObject == null){
202
			return "";
203
		}
204

    
205
		if (cdmObject instanceof IIdentifiableEntity) {
206
			return ((IIdentifiableEntity) cdmObject).getTitleCache();
207
		}
208

    
209
		throw new IllegalArgumentException("Generic method only" +
210
				" supports cdmObject of type IIdentifiableEntity." +
211
				" Please implement specific method in subclass.");
212
	}
213

    
214
	/**
215
	 * Set the filter input to the Agent's title cache
216
	 *
217
	 * @param cdmObject a T object.
218
	 */
219
	protected void setPattern(T cdmObject) {
220
		String pattern = getTitle(cdmObject);
221
		getSearchField().setText(pattern);
222

    
223
	}
224

    
225
	@Override
226
    protected void fillContentProvider(IProgressMonitor progressMonitor)
227
		 {
228
		try {
229
		    if (model == null){
230
		        model = new ArrayList<UuidAndTitleCache<T>>();
231
		    }
232
			if(model != null){
233
			    if (progressMonitor != null){
234
			        progressMonitor.beginTask("Looking for entities", model.size());
235
			    }
236
			    sort();
237

    
238
			    contentProvider.reset();
239
				Iterator<UuidAndTitleCache<T>> iterator = model.iterator();
240
				UuidAndTitleCache<T> element;
241
				while(iterator.hasNext()){
242
				    element = iterator.next();
243

    
244
				    if (cdmBaseToBeFiltered == null || !cdmBaseToBeFiltered.contains(element.getUuid())){
245
				        contentProvider.add(element);
246
				    }
247
				    if (progressMonitor != null){
248
    					if (progressMonitor.isCanceled()) {
249
    						return;
250
    					}
251
    					progressMonitor.worked(1);
252
				    }
253
				}
254
				this.refresh();
255
			}else{
256

    
257
				MessagingUtils.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
258
			}
259
		}
260
		finally {
261
		    if (progressMonitor != null) {
262
                progressMonitor.done();
263
            }
264
		}
265
	}
266

    
267
    protected void sort() {
268
        Collections.sort(model, getItemsComparator());
269
    }
270

    
271
	protected IDialogSettings getDialogSettings() {
272
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
273

    
274
		if (settings == null) {
275
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
276
		}
277
		return settings;
278
	}
279

    
280
	@Override
281
    protected Comparator<UuidAndTitleCache<T>> getItemsComparator() {
282
		return new Comparator<UuidAndTitleCache<T>>() {
283
			@Override
284
			public int compare(UuidAndTitleCache<T> entity1,
285
					UuidAndTitleCache<T> entity2) {
286
				Collator collator = Collator.getInstance();
287
				if (entity1 == entity2){
288
				    return 0;
289
				}else if (entity1 == null){
290
				    return -1;
291
				}else if (entity2 == null){
292
				    return 1;
293
				}else if (entity1.getUuid().equals(entity2.getUuid())){
294
                    return 0;
295
                }else if (entity1.getTitleCache() == null && entity2.getTitleCache() != null){
296
				    return -1;
297
				}else if (entity2.getTitleCache() == null){
298
				    return 1;
299
				}
300
				int result = collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
301
				if (result == 0){
302
				    result = entity1.getUuid().compareTo(entity2.getUuid());
303
				}
304
				return result;
305
			}
306
		};
307
	}
308

    
309
	/**
310
	 * getSelectedUuidAndTitleCache
311
	 */
312
	protected UuidAndTitleCache<T> getSelectedUuidAndTitleCache() {
313
		Object result = getResult();
314
		if (result instanceof UuidAndTitleCache){
315
		    return (UuidAndTitleCache<T>) result;
316
		}
317
		return null;
318
	}
319

    
320
    private Object getResult() {
321
        StructuredSelection selection = getCurrentSelection();
322
        if (selection == null){
323
            return null;
324
        }
325
        return selection.getFirstElement();
326
    }
327

    
328
    /**
329
	 * <p>Getter for the field <code>settings</code>.</p>
330
	 *
331
	 * @return a {@link java.lang.String} object.
332
	 */
333
	public String getSettings()  {
334
		if(settings == null){
335
			throw new IllegalStateException("No SETTINGS set.");
336
		}
337
		return settings;
338
	}
339

    
340
	/**
341
	 * <p>getNewWizardLinkText</p>
342
	 *
343
	 * @return a {@link java.lang.String} object.
344
	 */
345
	protected abstract String[] getNewWizardText();
346

    
347
	/**
348
	 * <p>getNewEntityWizard</p>
349
	 * @param parameter
350
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
351
	 */
352
	protected abstract AbstractNewEntityWizard<T> getNewEntityWizard(String parameter);
353

    
354
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
355
		@Override
356
		public String getText(Object element) {
357
			if (element == null) {
358
				return null;
359
			}
360
			UuidAndTitleCache<?> uuidAndTitleCache = (UuidAndTitleCache<?>) element;
361
			String titleCache = uuidAndTitleCache.getTitleCache();
362
			if(PreferencesUtil.getBooleanValue(PreferencePredicate.ShowIdInSelectionDialog.getKey())){
363
			    titleCache += " ["+uuidAndTitleCache.getId()+"]";
364
			}
365
			if (element instanceof EntityDTOBase){
366
			    titleCache += "(" + ((IdentifiedEntityDTO)element).getIdentifier().getTypeLabel() +": " + ((IdentifiedEntityDTO)element).getIdentifier().getIdentifier() + ")";
367
			}
368

    
369
            return titleCache;
370
		}
371
	}
372

    
373
//	@Override
374
//    protected Control createExtendedContentArea(Composite parent) {
375
//		String newWizardLinkText = getNewWizardLinkText();
376
////        if(newWizardLinkText != null){
377
////            newButton1 = this.createButton(this.getShell(), new_id, newWizardLinkText, false);
378
////
379
////            newButton1.addSelectionListener(getNewWizardLinkSelectionListener());
380
////			return newButton1;
381
////		}
382
//		return null;
383
//	}
384

    
385
	@Override
386
    protected void createButtonsForButtonBar(Composite parent) {
387
	    String[] newButtonText = getNewWizardText();
388

    
389
	    if (newButtonText!= null){
390
	        this.newButton1 = createButton(parent, this.new_id, newButtonText[0], false);
391
	        newButton1.addSelectionListener(getNewWizardButtonSelectionListener());
392

    
393
	        if (newButtonText.length > 1){
394
	            newButton2 = createButton(parent, this.new_id2, newButtonText[1], false);
395
	            newButton2.addSelectionListener(getNewWizardButtonSelectionListener());
396
	        }
397
	    }
398
	    Button space = createButton(parent, this.space_id, " ", false);
399
	    space.setEnabled(false);
400
	    space.setVisible(false);
401
	    GridData gridData = new GridData();
402
        gridData.grabExcessHorizontalSpace = false;
403
        gridData.widthHint = 3;
404
	    space.setLayoutData(gridData);
405
	    GridLayout gridLayout = new GridLayout();
406
	    gridLayout.makeColumnsEqualWidth= false;
407
	    if (newButtonText != null){
408
	    	gridLayout.numColumns=newButtonText.length+2;
409
	    }else{
410
	    	gridLayout.numColumns=2;
411
	    }
412
	    parent.setLayout(gridLayout);
413

    
414
        super.createButtonsForButtonBar(parent);
415
        super.getButton(IDialogConstants.OK_ID).setEnabled(false);
416
    }
417

    
418
	protected SelectionListener getNewWizardButtonSelectionListener(){
419
		return new SelectionAdapter() {
420

    
421
			@Override
422
			public void widgetSelected(SelectionEvent e) {
423
			    Object source = e.getSource();
424
			    String text = null;
425
			    if (source instanceof Button){
426
			        Button sourceButton = (Button) source;
427
			        text = sourceButton.getText();
428
			    }
429
			    AbstractNewEntityWizard<?> wizard = getNewEntityWizard(text);
430
			    if(wizard != null){
431
			        if (wizard.getEntity() == null){
432
			            wizard.init(null, null);
433
			        }
434
			        if(wizard.getEntity() != null) {
435
			            WizardDialog dialog = new WizardDialog(getShell(), wizard);
436
			            int status = dialog.open();
437

    
438
			            if (status == IStatus.OK) {
439

    
440
			                T entity = (T) wizard.getEntity();
441
			                refresh();
442
			                setPattern(entity);
443
			            }
444
			        }
445
			    }
446
			}
447
		};
448
	}
449

    
450
	/**
451
	 * Don't want to add for example a taxon or synonym to itself
452
	 * so filter the list to remove the taxon in question
453
	 * (<code>cdmBaseToBeFiltered</code>)
454
	 * so it is not available in the filtered list.
455
	 */
456
	private void filterExcludedObjects() {
457
		if (model != null && cdmBaseToBeFiltered != null) {
458

    
459
			UuidAndTitleCache<?> uuidAndTitleCacheToRemove = null;
460

    
461
			for (UuidAndTitleCache<?> uuidAndTitleCache : model){
462
				if (cdmBaseToBeFiltered != null && cdmBaseToBeFiltered.contains(uuidAndTitleCache.getUuid())) {
463
					uuidAndTitleCacheToRemove = uuidAndTitleCache;
464
				}
465
			}
466
			model.remove(uuidAndTitleCacheToRemove);
467
		}
468
	}
469

    
470
	@Override
471
	void createFilterButton(Composite searchAndFilter){
472
	    //as default no filter button available
473
	}
474

    
475
    @Override
476
    protected void search() {
477
        Control control =getSearchField();
478
        String pattern = null;
479
        if (control != null){
480
            pattern = ((Text)control).getText();
481
            if (pattern.equals("*") || pattern.equals("?") || (this instanceof CollectorSelectionDialog && StringUtils.isBlank(pattern) && ((CollectorSelectionDialog)this).collectorTeam != null)){
482
                callService(null);
483
            }else if (StringUtils.isNotBlank(pattern)){
484
//                callService(CdmUtils.replaceNonWordCharacters(pattern, "."));
485
                callService(pattern);
486
            }
487
            fillContentProvider(null);
488
        }
489

    
490
//        if (pattern.equals("?")){
491
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(null, null);
492
//        }else if (pattern != null){
493
//            model = CdmStore.getService(INameService.class).getUuidAndTitleCache(limitOfInitialElements, pattern);
494
//        }
495
    }
496

    
497
    protected abstract void callService(String pattern);
498

    
499
}
(2-2/46)