Project

General

Profile

Download (13.9 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.taxeditor.ui.dialogs.filteredSelection;
12

    
13
import java.lang.reflect.Field;
14
import java.text.Collator;
15
import java.util.Comparator;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.OperationCanceledException;
25
import org.eclipse.core.runtime.Status;
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.window.Window;
30
import org.eclipse.jface.wizard.WizardDialog;
31
import org.eclipse.swt.SWT;
32
import org.eclipse.swt.events.SelectionAdapter;
33
import org.eclipse.swt.events.SelectionEvent;
34
import org.eclipse.swt.events.SelectionListener;
35
import org.eclipse.swt.widgets.Composite;
36
import org.eclipse.swt.widgets.Control;
37
import org.eclipse.swt.widgets.Link;
38
import org.eclipse.swt.widgets.Shell;
39
import org.eclipse.swt.widgets.Text;
40
import org.eclipse.ui.IMemento;
41
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
42

    
43
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
44
import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
45
import eu.etaxonomy.cdm.model.common.CdmBase;
46
import eu.etaxonomy.cdm.model.common.ICdmBase;
47
import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
48
import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
49
import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
50
import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
51
import eu.etaxonomy.taxeditor.store.StoreUtil;
52
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
53

    
54
/**
55
 * <p>Abstract AbstractFilteredCdmResourceSelectionDialog class.</p>
56
 *
57
 * @author n.hoffmann
58
 * @created 04.06.2009
59
 * @version 1.0
60
 */
61
public abstract class AbstractFilteredCdmResourceSelectionDialog<T extends ICdmBase> extends
62
		FilteredItemsSelectionDialog implements IConversationEnabled {
63

    
64
	private ConversationHolder conversation;
65

    
66
	protected List<UuidAndTitleCache<T>> model;
67
	private Set<T> transientCdmObjects = new HashSet<T>();
68
	private String settings;	
69
	
70
	/**
71
	 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
72
	 *
73
	 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
74
	 * @param conversation 
75
	 * @param title a {@link java.lang.String} object.
76
	 * @param multi a boolean.
77
	 * @param settings a {@link java.lang.String} object.
78
	 * @param cdmObject a T object.
79
	 * @param <T> a T object.
80
	 */
81
	protected AbstractFilteredCdmResourceSelectionDialog(Shell shell, ConversationHolder conversation, String title, boolean multi, String settings, T cdmObject) {
82
		super(shell, multi);
83
		setTitle(title);
84
		setMessage("Use * for wildcard, or ? to see all entries");
85
		this.settings = settings;
86
		
87
		this.conversation = conversation;
88
		
89
		init();
90
		
91
		initModel();
92
		
93
		String objectTitle = getTitle(cdmObject);
94
		if (objectTitle != null) {
95
			setInitialPattern(objectTitle);
96
		}
97
		
98
		setListLabelProvider(createListLabelProvider());
99
		setDetailsLabelProvider(createDetailsLabelProvider());
100
		
101
		setSelectionHistory(new ResourceSelectionHistory());
102
	}
103
	
104
	/**
105
	 * By default, we are returning the standard list label provider
106
	 * 
107
	 * Override in subclasses if you want different behavior 
108
	 * 
109
	 * @return
110
	 */
111
	protected ILabelProvider createDetailsLabelProvider() {
112
		return createListLabelProvider();
113
	}
114

    
115
	/**
116
	 * 
117
	 * @return
118
	 */
119
	protected ILabelProvider createListLabelProvider() {
120
		return new FilteredCdmResourceLabelProvider();
121
	}
122

    
123
	/**
124
	 * Override in subclasses.
125
	 * Will run before initModel()
126
	 */
127
	protected void init() {
128
		
129
	}
130
	
131
	/**
132
	 * <p>getSelectionFromDialog</p>
133
	 *
134
	 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialogs.filteredSelection.AbstractFilteredCdmResourceSelectionDialog} object.
135
	 * @param <TYPE> a TYPE object.
136
	 * @return a TYPE object.
137
	 */
138
	protected static <TYPE extends CdmBase> TYPE getSelectionFromDialog(AbstractFilteredCdmResourceSelectionDialog<TYPE> dialog) {
139
		//dialog.setInitialPattern("");
140
		int result = dialog.open();
141
		
142
		if (result == Window.CANCEL) {
143
			return null;
144
		}
145
		
146
		UUID uuid = dialog.getSelectedUuidAndTitleCache().getUuid();
147
		if(uuid == null){
148
			return null;
149
		}	
150
		return dialog.getCdmObjectByUuid(uuid);
151
	}
152
	
153
	/**
154
	 * Check if object was created during the life of this dialog. If not,
155
	 * retrieve it from the CdmStore.
156
	 *
157
	 * @param cdmUuid a {@link java.util.UUID} object.
158
	 * @return a T object.
159
	 */
160
	protected T getCdmObjectByUuid(UUID cdmUuid) {
161
		for (T cdmObject : transientCdmObjects) {
162
			if (cdmObject.getUuid().equals(cdmUuid)) {
163
				return cdmObject;
164
			}
165
		}
166
		return getPersistentObject(cdmUuid);
167
	}
168
	
169
	/**
170
	 * <p>getPersistentObject</p>
171
	 *
172
	 * @param uuid a {@link java.util.UUID} object.
173
	 * @return a T object.
174
	 */
175
	abstract protected T getPersistentObject(UUID uuid);
176

    
177
	/**
178
	 * @param cdmObject
179
	 */
180
//	protected void addObjectToModel(T cdmObject) {
181
//		model.add(new UuidAndTitleCache(cdmObject.getClass(), cdmObject.getUuid(), getTitle(cdmObject)));
182
//		transientCdmObjects.add(cdmObject);
183
//	}
184

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

    
195
	/**
196
	 * <p>getTitle</p>
197
	 *
198
	 * @param cdmObject a T object.
199
	 * @return a {@link java.lang.String} object.
200
	 */
201
	protected String getTitle(T cdmObject) {
202
		if(cdmObject == null){
203
			return "";
204
		}
205
		
206
		if (cdmObject instanceof IIdentifiableEntity) {
207
			return ((IIdentifiableEntity) cdmObject).getTitleCache();			
208
		}
209
		
210
		throw new IllegalArgumentException("Generic method only" +
211
				" supports cdmObject of type IIdentifiableEntity." +
212
				" Please implement specific method in subclass.");
213
	}
214
	
215

    
216
	/** {@inheritDoc} */
217
	@Override
218
	public void refresh() {
219
		initModel();
220
		super.refresh();
221
	}
222
	
223
	/**
224
	 * <p>initModel</p>
225
	 */
226
	abstract protected void initModel();
227

    
228
	/* (non-Javadoc)
229
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
230
	 */
231
	/** {@inheritDoc} */
232
	@Override
233
	protected ItemsFilter createFilter() {
234
		return new ItemsFilter() {
235

    
236
			/**
237
			 * Always returns false to enforce refiltering even if the pattern is equal
238
			 */
239
			@Override
240
			public boolean equalsFilter(ItemsFilter filter) {
241
				return false;
242
			}
243
			
244
			@Override
245
			public boolean isConsistentItem(Object item) {
246
				return false;
247
			}
248

    
249
			@Override
250
			public boolean matchItem(Object item) {
251
				String text = null;
252
				if(item instanceof UuidAndTitleCache){
253
					text = ((UuidAndTitleCache) item).getTitleCache();
254
				}else if(item instanceof String){
255
					text = (String) item;
256
				}
257
				return text != null ? matches(text) : false;
258
			}
259
			
260
		};
261
	}
262
	
263

    
264
	/**
265
	 * Set the filter input to the Agent's title cache
266
	 *
267
	 * @param cdmObject a T object.
268
	 */
269
	protected void setPattern(T cdmObject) {
270
		// FilteredSelection does some very tricky caching to make sure it 
271
		// runs with high performance. 
272
		// This works for most use cases, but we want to change the model while the dialog is open
273
		// and all the clever caching prevents the content provider from knowing that the model has changed
274
		// I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient 
275
		// way to solve the problem.
276
		try {
277
			Field lastCompletedFilter = this.getClass().getSuperclass().getSuperclass().getDeclaredField("lastCompletedFilter");
278
			lastCompletedFilter.setAccessible(true);
279
			lastCompletedFilter.set(this, null);
280
		} catch (SecurityException e) {
281
			StoreUtil.error(getClass(), e);
282
		} catch (NoSuchFieldException e) {
283
			StoreUtil.error(getClass(), e);
284
		} catch (IllegalArgumentException e) {
285
			StoreUtil.error(getClass(), e);
286
		} catch (IllegalAccessException e) {
287
			StoreUtil.error(getClass(), e);
288
		}
289
		
290
		// this also is not the nicest way to do it. 
291
		// I am still amazed, that FilteredSelectionDialog does not offer any methods to change its data
292
		// once it was opened. Am I doing it wrong?
293
		String pattern = getTitle(cdmObject);
294
		((Text) getPatternControl()).setText(pattern);
295
	}
296
	
297
	/* (non-Javadoc)
298
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
299
	*/
300
	/** {@inheritDoc} */
301
	@Override
302
	protected void fillContentProvider(AbstractContentProvider contentProvider,
303
		ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
304
		throws CoreException {
305
		try {
306
			if(model != null){				
307
				progressMonitor.beginTask("Looking for entities", model.size());
308
				for(UuidAndTitleCache<T> element : model){
309
					contentProvider.add(element, itemsFilter);
310
					if (progressMonitor.isCanceled()) {
311
						throw new OperationCanceledException();
312
					}
313
					progressMonitor.worked(1);
314
				}
315
			}else{
316
				StoreUtil.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
317
			}
318
		}
319
		finally {
320
			progressMonitor.done();
321
		}
322
	}
323

    
324
	/* (non-Javadoc)
325
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
326
	 */
327
	/** {@inheritDoc} */
328
	@Override
329
	protected IDialogSettings getDialogSettings() {
330
		IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
331

    
332
		if (settings == null) {
333
			settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
334
		}
335
		return settings;
336
	}
337

    
338
	/* (non-Javadoc)
339
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
340
	 */
341
	/** {@inheritDoc} */
342
	@Override
343
	public String getElementName(Object item) {
344
		return ((UuidAndTitleCache) item).getTitleCache();
345
	}
346

    
347
	/* (non-Javadoc)
348
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
349
	 */
350
	/** {@inheritDoc} */
351
	@Override
352
	protected Comparator getItemsComparator() {
353
		return new Comparator<UuidAndTitleCache>() {
354
			public int compare(UuidAndTitleCache entity1,
355
					UuidAndTitleCache entity2) {
356
				Collator collator = Collator.getInstance();
357
				return collator.compare(entity1.getTitleCache(), entity2.getTitleCache());
358
			}
359
		};
360
	}
361

    
362
	/* (non-Javadoc)
363
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)
364
	 */
365
	/** {@inheritDoc} */
366
	@Override
367
	protected IStatus validateItem(Object item) {
368
		return Status.OK_STATUS;
369
	}
370
	
371
	/**
372
	 * <p>getSelectedUuidAndTitleCache</p>
373
	 *
374
	 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
375
	 */
376
	protected UuidAndTitleCache getSelectedUuidAndTitleCache() {
377
		Object[] result = getResult();
378
		return result[0] == null ? null : (UuidAndTitleCache) result[0];
379
	}
380
	
381
	/**
382
	 * <p>Getter for the field <code>settings</code>.</p>
383
	 *
384
	 * @return a {@link java.lang.String} object.
385
	 */
386
	public String getSettings()  {
387
		if(settings == null){
388
			throw new IllegalStateException("No SETTINGS set.");
389
		}
390
		return settings;
391
	}
392
	
393
	/**
394
	 * 
395
	 * @author n.hoffmann
396
	 * @created Oct 19, 2009
397
	 * @version 1.0
398
	 */
399
	private class ResourceSelectionHistory extends SelectionHistory {
400
	    /*
401
	    * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#restoreItemFromMemento(org.eclipse.ui.IMemento)
402
	   	*/
403
		protected Object restoreItemFromMemento(IMemento element) {
404
			return element.getString("resource"); //$NON-NLS-1$
405
	  	}
406
	  	/*
407
	  	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object,
408
	  	 *      org.eclipse.ui.IMemento)
409
	  	 */
410
		protected void storeItemToMemento(Object item, IMemento element) {
411
			element.putString("resource", item.toString()); //$NON-NLS-1$
412
		}
413
	}
414
	
415
	/**
416
	 * <p>getNewWizardLinkText</p>
417
	 *
418
	 * @return a {@link java.lang.String} object.
419
	 */
420
	protected abstract String getNewWizardLinkText();
421
	
422
	/**
423
	 * <p>getNewEntityWizard</p>
424
	 * @param parameter 
425
	 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
426
	 */
427
	protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
428
	
429
	public class FilteredCdmResourceLabelProvider extends LabelProvider {
430
		public String getText(Object element) {
431
			if (element == null) {
432
				return null;
433
			}
434
			return ((UuidAndTitleCache) element).getTitleCache();
435
		}			
436
	};
437

    
438
	/* (non-Javadoc)
439
	* @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
440
	*/
441
	/** {@inheritDoc} */
442
	@Override
443
	protected Control createExtendedContentArea(Composite parent) {
444
		if(getNewWizardLinkText() != null){
445
			Link link = new Link(parent, SWT.NONE);
446
			link.setText(getNewWizardLinkText());
447
			link.addSelectionListener(getNewWizardLinkSelectionListener());
448
			return link;
449
		}
450
		return null;
451
	}
452
	
453
	protected SelectionListener getNewWizardLinkSelectionListener(){
454
		return new SelectionAdapter() {
455
			
456
			/* (non-Javadoc)
457
			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
458
			 */
459
			@Override
460
			public void widgetSelected(SelectionEvent e) {
461
				
462
				AbstractNewEntityWizard wizard = getNewEntityWizard(e.text);
463
				wizard.init(null, null);
464
				WizardDialog dialog = new WizardDialog(getShell(), wizard);
465
				int status = dialog.open();
466
				
467
				if (status == IStatus.OK) {
468
					
469
					T entity = (T) wizard.getEntity();
470
					
471
//					addObjectToModel(teamOrPerson);
472
					refresh();
473
					setPattern(entity);
474
					conversation.bind();
475
				}
476
			}
477
		};
478
	}
479
	
480
	/**
481
	 * <p>getConversationHolder</p>
482
	 *
483
	 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
484
	 */
485
	public ConversationHolder getConversationHolder() {
486
		return conversation;
487
	}
488
	
489
	/** {@inheritDoc} */
490
	public void update(CdmDataChangeMap changeEvents) {}
491
}
(1-1/20)