Project

General

Profile

Download (17 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.common.CdmUtils;
49
import eu.etaxonomy.cdm.model.common.CdmBase;
50
import eu.etaxonomy.cdm.model.common.ICdmBase;
51
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
52
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
53
import eu.etaxonomy.taxeditor.l10n.Messages;
54
import eu.etaxonomy.taxeditor.model.MessagingUtils;
55
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
56
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
57
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
58
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
59

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

    
70
//	private final ConversationHolder conversation = null;
71

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

    
77
	private T selectedObject;
78

    
79
	protected Set<UUID> cdmBaseToBeFiltered;
80

    
81
	protected Job searchJob;
82

    
83

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

    
111
	}
112

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

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

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

    
138
	}
139

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

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

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

    
173
        UuidAndTitleCache uuid = dialog.getSelectedUuidAndTitleCache();
174

    
175
        return uuid;
176
    }
177

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

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

    
202

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

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

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

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

    
233

    
234

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

    
245

    
246

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

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

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

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

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

    
294

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

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

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

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

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

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

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

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

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

    
362

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

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

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

    
399

    
400

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

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

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

    
430
            return titleCache;
431
		}
432
	};
433

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

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

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

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

    
459

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

    
464
	        }
465

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

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

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

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

    
507
			            if (status == IStatus.OK) {
508

    
509
			                T entity = (T) wizard.getEntity();
510
			                refresh();
511
			                setPattern(entity);
512

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

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

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

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

    
550
			UuidAndTitleCache uuidAndTitleCacheToRemove = null;
551

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

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

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

    
587
    abstract void callService(String pattern);
588

    
589
}
(2-2/44)