- fixed compile error in test
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / dialog / selection / AbstractFilteredCdmEnumSelectionDialog.java
1 //$Id$
2
3 package eu.etaxonomy.taxeditor.ui.dialog.selection;
4
5 import java.lang.reflect.Field;
6 import java.text.Collator;
7 import java.util.Comparator;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Set;
11 import java.util.UUID;
12
13 import org.eclipse.core.runtime.CoreException;
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.core.runtime.OperationCanceledException;
17 import org.eclipse.core.runtime.Status;
18 import org.eclipse.jface.dialogs.IDialogSettings;
19 import org.eclipse.jface.viewers.ILabelProvider;
20 import org.eclipse.jface.viewers.LabelProvider;
21 import org.eclipse.jface.window.Window;
22 import org.eclipse.jface.wizard.WizardDialog;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.SelectionAdapter;
25 import org.eclipse.swt.events.SelectionEvent;
26 import org.eclipse.swt.events.SelectionListener;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Link;
30 import org.eclipse.swt.widgets.Shell;
31 import org.eclipse.swt.widgets.Text;
32 import org.eclipse.ui.IMemento;
33 import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
34
35 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
36 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
37 import eu.etaxonomy.cdm.model.common.CdmBase;
38 import eu.etaxonomy.cdm.model.common.ICdmBase;
39 import eu.etaxonomy.cdm.model.common.IEnumTerm;
40 import eu.etaxonomy.cdm.model.common.IIdentifiableEntity;
41 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
42 import eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard;
43 import eu.etaxonomy.taxeditor.store.StoreUtil;
44 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
45
46 /**
47 * <p>Abstract AbstractFilteredCdmEnumSelectionDialog class.</p>
48 *
49 * @author c.mathew
50 * @created 18.07.2013
51 * @version 1.0
52 */
53 public abstract class AbstractFilteredCdmEnumSelectionDialog<T extends IEnumTerm> extends
54 FilteredItemsSelectionDialog implements IConversationEnabled {
55
56 private ConversationHolder conversation;
57
58 protected List<T> model;
59 private String settings;
60
61
62
63 /**
64 * <p>Constructor for AbstractFilteredCdmResourceSelectionDialog.</p>
65 *
66 * @param shell a {@link org.eclipse.swt.widgets.Shell} object.
67 * @param conversation
68 * @param title a {@link java.lang.String} object.
69 * @param multi a boolean.
70 * @param settings a {@link java.lang.String} object.
71 * @param cdmEnum a T object.
72 * @param <T> a T object.
73 */
74 protected AbstractFilteredCdmEnumSelectionDialog(Shell shell,
75 ConversationHolder conversation,
76 String title,
77 boolean multi,
78 String settings,
79 T cdmEnum) {
80 super(shell, multi);
81 setTitle(title);
82 setMessage("Use * for wildcard, or ? to see all entries");
83 this.settings = settings;
84
85 this.conversation = conversation;
86
87 init();
88
89 initModel();
90
91 String objectTitle = getTitle(cdmEnum);
92 if (objectTitle != null) {
93 setInitialPattern(objectTitle);
94 }
95
96 setListLabelProvider(createListLabelProvider());
97 setDetailsLabelProvider(createDetailsLabelProvider());
98
99 setSelectionHistory(new ResourceSelectionHistory());
100 }
101
102 /**
103 * By default, we are returning the standard list label provider
104 *
105 * Override in subclasses if you want different behavior
106 *
107 * @return
108 */
109 protected ILabelProvider createDetailsLabelProvider() {
110 return createListLabelProvider();
111 }
112
113 /**
114 *
115 * @return
116 */
117 protected ILabelProvider createListLabelProvider() {
118 return new FilteredCdmResourceLabelProvider();
119 }
120
121 /**
122 * Override in subclasses.
123 * Will run before initModel()
124 */
125 protected void init() {
126
127 }
128
129 /**
130 * <p>getSelectionFromDialog</p>
131 *
132 * @param dialog a {@link eu.etaxonomy.taxeditor.ui.dialog.selection.AbstractFilteredCdmResourceSelectionDialog} object.
133 * @param <TYPE> a TYPE object.
134 * @return a TYPE object.
135 */
136 protected static <TYPE extends IEnumTerm> TYPE getSelectionFromDialog(AbstractFilteredCdmEnumSelectionDialog<TYPE> dialog) {
137
138 int result = dialog.open();
139
140 if (result == Window.CANCEL) {
141 return null;
142 }
143
144 return dialog.getSelectedEnumTerm();
145 }
146
147
148 /**
149 * <p>getTitle</p>
150 *
151 * @param cdmObject a T object.
152 * @return a {@link java.lang.String} object.
153 */
154 protected String getTitle(T cdmEnum) {
155 return cdmEnum.getMessage();
156 }
157
158
159 /** {@inheritDoc} */
160 @Override
161 public void refresh() {
162 initModel();
163 super.refresh();
164 }
165
166 /**
167 * <p>initModel</p>
168 */
169 abstract protected void initModel();
170
171 /* (non-Javadoc)
172 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
173 */
174 /** {@inheritDoc} */
175 @Override
176 protected ItemsFilter createFilter() {
177 return new ItemsFilter() {
178
179 /**
180 * Always returns false to enforce refiltering even if the pattern is equal
181 */
182 @Override
183 public boolean equalsFilter(ItemsFilter filter) {
184 return false;
185 }
186
187 @Override
188 public boolean isConsistentItem(Object item) {
189 return false;
190 }
191
192 @Override
193 public boolean matchItem(Object item) {
194 String text = null;
195 if(item instanceof IEnumTerm){
196 text = ((IEnumTerm) item).getMessage();
197 }else if(item instanceof String){
198 text = (String) item;
199 }
200 return text != null ? matches(text) : false;
201 }
202
203 };
204 }
205
206
207 /**
208 * Set the filter input to the Agent's title cache
209 *
210 * @param cdmObject a T object.
211 */
212 protected void setPattern(T cdmObject) {
213 // FilteredSelection does some very tricky caching to make sure it
214 // runs with high performance.
215 // This works for most use cases, but we want to change the model while the dialog is open
216 // and all the clever caching prevents the content provider from knowing that the model has changed
217 // I am aware, that this is a hack, but the FilteredSelectionDialog API does not offer a convenient
218 // way to solve the problem.
219 try {
220 Field lastCompletedFilter = this.getClass().getSuperclass().getSuperclass().getDeclaredField("lastCompletedFilter");
221 lastCompletedFilter.setAccessible(true);
222 lastCompletedFilter.set(this, null);
223 } catch (SecurityException e) {
224 StoreUtil.error(getClass(), e);
225 } catch (NoSuchFieldException e) {
226 StoreUtil.error(getClass(), e);
227 } catch (IllegalArgumentException e) {
228 StoreUtil.error(getClass(), e);
229 } catch (IllegalAccessException e) {
230 StoreUtil.error(getClass(), e);
231 }
232
233 // this also is not the nicest way to do it.
234 // I am still amazed, that FilteredSelectionDialog does not offer any methods to change its data
235 // once it was opened. Am I doing it wrong?
236 String pattern = getTitle(cdmObject);
237 ((Text) getPatternControl()).setText(pattern);
238 }
239
240 /* (non-Javadoc)
241 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#fillContentProvider(org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.AbstractContentProvider, org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter, org.eclipse.core.runtime.IProgressMonitor)
242 */
243 /** {@inheritDoc} */
244 @Override
245 protected void fillContentProvider(AbstractContentProvider contentProvider,
246 ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
247 throws CoreException {
248 try {
249 if(model != null){
250 progressMonitor.beginTask("Looking for entities", model.size());
251 for(T element : model){
252 contentProvider.add(element, itemsFilter);
253 if (progressMonitor.isCanceled()) {
254 throw new OperationCanceledException();
255 }
256 progressMonitor.worked(1);
257 }
258 }else{
259 StoreUtil.warn(getClass(), "Model for Filtered Selection is null:" + this.getClass().getSimpleName());
260 }
261 }
262 finally {
263 progressMonitor.done();
264 }
265 }
266
267 /* (non-Javadoc)
268 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()
269 */
270 /** {@inheritDoc} */
271 @Override
272 protected IDialogSettings getDialogSettings() {
273 IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());
274
275 if (settings == null) {
276 settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());
277 }
278 return settings;
279 }
280
281 /* (non-Javadoc)
282 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)
283 */
284 /** {@inheritDoc} */
285 @Override
286 public String getElementName(Object item) {
287 return ((IEnumTerm) item).getMessage();
288 }
289
290 /* (non-Javadoc)
291 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()
292 */
293 /** {@inheritDoc} */
294 @Override
295 protected Comparator getItemsComparator() {
296 return new Comparator<IEnumTerm>() {
297 public int compare(IEnumTerm entity1,
298 IEnumTerm entity2) {
299 Collator collator = Collator.getInstance();
300 return collator.compare(entity1.getMessage(), entity2.getMessage());
301 }
302 };
303 }
304
305 /* (non-Javadoc)
306 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)
307 */
308 /** {@inheritDoc} */
309 @Override
310 protected IStatus validateItem(Object item) {
311 return Status.OK_STATUS;
312 }
313
314 /**
315 * <p>getSelectedUuidAndTitleCache</p>
316 *
317 * @return a {@link eu.etaxonomy.cdm.model.common.UuidAndTitleCache} object.
318 */
319 protected T getSelectedEnumTerm() {
320 Object[] result = getResult();
321 return result[0] == null ? null : (T) result[0];
322 }
323
324 /**
325 * <p>Getter for the field <code>settings</code>.</p>
326 *
327 * @return a {@link java.lang.String} object.
328 */
329 public String getSettings() {
330 if(settings == null){
331 throw new IllegalStateException("No SETTINGS set.");
332 }
333 return settings;
334 }
335
336 /**
337 *
338 * @author n.hoffmann
339 * @created Oct 19, 2009
340 * @version 1.0
341 */
342 private class ResourceSelectionHistory extends SelectionHistory {
343 /*
344 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#restoreItemFromMemento(org.eclipse.ui.IMemento)
345 */
346 protected Object restoreItemFromMemento(IMemento element) {
347 return element.getString("resource"); //$NON-NLS-1$
348 }
349 /*
350 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.SelectionHistory#storeItemToMemento(java.lang.Object,
351 * org.eclipse.ui.IMemento)
352 */
353 protected void storeItemToMemento(Object item, IMemento element) {
354 element.putString("resource", item.toString()); //$NON-NLS-1$
355 }
356 }
357
358 /**
359 * <p>getNewWizardLinkText</p>
360 *
361 * @return a {@link java.lang.String} object.
362 */
363 protected abstract String getNewWizardLinkText();
364
365 /**
366 * <p>getNewEntityWizard</p>
367 * @param parameter
368 * @return a {@link eu.etaxonomy.taxeditor.newWizard.AbstractNewEntityWizard} object.
369 */
370 protected abstract AbstractNewEntityWizard getNewEntityWizard(String parameter);
371
372 public class FilteredCdmResourceLabelProvider extends LabelProvider {
373 public String getText(Object element) {
374 if (element == null) {
375 return null;
376 }
377 return ((IEnumTerm) element).getMessage();
378 }
379 };
380
381 /* (non-Javadoc)
382 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)
383 */
384 /** {@inheritDoc} */
385 @Override
386 protected Control createExtendedContentArea(Composite parent) {
387 if(getNewWizardLinkText() != null){
388 Link link = new Link(parent, SWT.NONE);
389 link.setText(getNewWizardLinkText());
390 link.addSelectionListener(getNewWizardLinkSelectionListener());
391 return link;
392 }
393 return null;
394 }
395
396 protected SelectionListener getNewWizardLinkSelectionListener(){
397 return new SelectionAdapter() {
398
399 /* (non-Javadoc)
400 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
401 */
402 @Override
403 public void widgetSelected(SelectionEvent e) {
404
405 AbstractNewEntityWizard wizard = getNewEntityWizard(e.text);
406 wizard.init(null, null);
407 WizardDialog dialog = new WizardDialog(getShell(), wizard);
408 int status = dialog.open();
409
410 if (status == IStatus.OK) {
411
412 T entity = (T) wizard.getEntity();
413
414 refresh();
415 setPattern(entity);
416 getConversationHolder().bind();
417 }
418 }
419 };
420 }
421
422 /**
423 * <p>getConversationHolder</p>
424 *
425 * @return a {@link eu.etaxonomy.cdm.api.conversation.ConversationHolder} object.
426 */
427 public ConversationHolder getConversationHolder() {
428 return conversation;
429 }
430
431 /** {@inheritDoc} */
432 public void update(CdmDataChangeMap changeEvents) {}
433
434 }