package eu.etaxonomy.taxeditor.bulkeditor.input.entitycreator;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IStatus;
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorUtil;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
import eu.etaxonomy.taxeditor.newWizard.NewDerivedUnitBaseWizard;
/**
*/
@Override
public Map<Object, String> getKeyLabelPairs() {
- Comparator<Object> comparator = new Comparator<Object>() {
- @Override
- public int compare(Object o1, Object o2) {
- String key1 = ((SpecimenOrObservationType)o1).getKey();
- String key2 = ((SpecimenOrObservationType)o2).getKey();
- return key1.compareTo(key2);
- }
- };
- Map<Object, String> result = new LinkedHashMap<Object, String>();
-
- Map<SpecimenOrObservationType, Set<SpecimenOrObservationType>> typeHierarchy = new TreeMap<SpecimenOrObservationType, Set<SpecimenOrObservationType>>(comparator);
-
- for(SpecimenOrObservationType sooType : SpecimenOrObservationType.values()) {
- Set<SpecimenOrObservationType> childList = new TreeSet<SpecimenOrObservationType>(comparator);
- // add root element as keys
- if(sooType.getKindOf()==null){
- typeHierarchy.put(sooType, childList);
- }
- // add child element to topmost parent i.e. root
- else{
- SpecimenOrObservationType root = getRootFor(sooType);
- if(typeHierarchy.containsKey(root)){
- typeHierarchy.get(root).add(sooType);
- }
- else{
- childList.add(sooType);
- typeHierarchy.put(root, childList);
- }
- }
- }
-
- // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
- for(Entry<SpecimenOrObservationType, Set<SpecimenOrObservationType>> entry:typeHierarchy.entrySet()){
- SpecimenOrObservationType root = entry.getKey();
- result.put(root, root.getMessage());
- for(SpecimenOrObservationType child:entry.getValue()){
- result.put(child, " - " + child.getMessage());
- }
- }
- return result;
- }
-
- private SpecimenOrObservationType getRootFor(SpecimenOrObservationType type){
- SpecimenOrObservationType parent = type.getKindOf();
- if(parent==null){
- return type;
- }
- else{
- return getRootFor(type.getKindOf());
- }
+ Map<Object, String> keyLabelPairs = new HashMap<Object, String>();
+ keyLabelPairs.putAll(AbstractUtility.orderTerms(Arrays.asList(SpecimenOrObservationType.values())));
+ return keyLabelPairs;
}
@Override
// $Id$
/**
* Copyright (C) 2007 EDIT
- * European Distributed Institute of Taxonomy
+ * European Distributed Institute of Taxonomy
* http://www.e-taxonomy.eu
- *
+ *
* The contents of this file are subject to the Mozilla Public License Version 1.1
* See LICENSE.TXT at the top of this package for the full license terms.
*/
package eu.etaxonomy.taxeditor.model;
import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
import org.apache.log4j.Logger;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.ui.themes.ITheme;
import org.eclipse.ui.themes.IThemeManager;
+import eu.etaxonomy.cdm.model.common.IEnumTerm;
import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
* <p>
* Abstract AbstractUtility class.
* </p>
- *
+ *
* @author n.hoffmann
* @created 11.05.2009
* @version 1.0
* <p>
* closeAll
* </p>
- *
+ *
* @return a boolean.
*/
public static boolean closeAll() {
/**
* Close the given editor.
- *
+ *
* @param editor
* The <tt>MultipageTaxonEditor</tt> to close.
* @return <tt>true</tt> on success
* <p>
* getShell
* </p>
- *
+ *
* @return a {@link org.eclipse.swt.widgets.Shell} object.
*/
public static Shell getShell() {
* <p>
* getActivePage
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.IWorkbenchPage} object.
*/
public static IWorkbenchPage getActivePage() {
* <p>
* getActivePart
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.IWorkbenchPart} object.
*/
public static IWorkbenchPart getActivePart() {
* <p>
* getWorkbenchWindow
* </p>
- *
+ *
* @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
*/
public static ApplicationWindow getWorkbenchWindow() {
* <p>
* showView
* </p>
- *
+ *
* @param id
* a {@link java.lang.String} object.
* @return a {@link org.eclipse.ui.IViewPart} object.
* <p>
* hideView
* </p>
- *
+ *
* @param view
* a {@link org.eclipse.ui.IViewPart} object.
*/
* <p>
* getView
* </p>
- *
+ *
* @param id
* a {@link java.lang.String} object.
* @param restore
* <p>
* getService
* </p>
- *
+ *
* @param api
* a {@link java.lang.Class} object.
* @return a {@link java.lang.Object} object.
* <p>
* getCurrentTheme
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.themes.ITheme} object.
*/
public static ITheme getCurrentTheme() {
* Fonts registered to the plugin may be obtained with the Eclipse themeing
* functionality. Thus fonts are chooseable by the user via
* Preferences->General->Appearance->Colors and Fonts
- *
+ *
* @return the FontRegistry for the current theme
*/
public static FontRegistry getFontRegistry() {
* <p>
* getFont
* </p>
- *
+ *
* @param symbolicName
* a {@link java.lang.String} object.
* @return a {@link org.eclipse.swt.graphics.Font} object.
* Color registered to the plugin may be obtained with the Eclipse themeing
* functionality. Thus colors are editable by the user via
* Preferences->General->Appearance->Colors and Fonts
- *
+ *
* @return the ColorRegistry for the current theme
*/
public static ColorRegistry getColorRegistry() {
* <p>
* getColor
* </p>
- *
+ *
* @param symbolicName
* a {@link java.lang.String} object.
* @return a {@link org.eclipse.swt.graphics.Color} object.
/**
* Open a message box that informs the user about unimplemented
* functionality. This method is for developer convenience.
- *
+ *
* @param source
* a {@link java.lang.Object} object.
*/
* <p>
* informationDialog
* </p>
- *
+ *
* @param title
* a {@link java.lang.String} object.
* @param message
final String message) {
Display.getDefault().asyncExec(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
MessageDialog.openInformation(getShell(), title, message);
}
});
final IStatus status) {
informationDialog(title, status.getMessage());
}
-
+
/**
* <p>
* warningDialog
* </p>
- *
+ *
* @param title
* The dialogs title
* @param source
final String message) {
Display.getDefault().asyncExec(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
MessageDialog.openWarning(getShell(), title, message);
Class<? extends Object> clazz = source != null ? source
.getClass() : AbstractUtility.class;
}
});
}
-
+
/**
* @param title
* @param termBase
* <p>
* errorDialog
* </p>
- *
+ *
* @param title
* The dialogs title
* @param source
final String message, final Throwable t) {
Display.getDefault().asyncExec(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
MessageDialog.openError(getShell(), title, message + getCauseRecursively(t));
Class<? extends Object> clazz = source != null ? source
.getClass() : this.getClass();
if(t == null){
return null;
}
-
+
if(t.getCause() != null){
return getCauseRecursively(t.getCause());
}else{
}
});
}
-
+
public static void errorDialog(final String title, final Object source,
final String message){
errorDialog(title, source, message, null);
* <p>
* errorDialog
* </p>
- *
+ *
* @param title
* a {@link java.lang.String} object.
* @param source
final IStatus status) {
Display.getDefault().asyncExec(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
MessageDialog.openError(getShell(), title, status.getMessage());
Class<? extends Object> clazz = source != null ? source
.getClass() : this.getClass();
* <p>
* confirmDialog
* </p>
- *
+ *
* @param title
* a {@link java.lang.String} object.
* @param message
* <p>
* executeOperation
* </p>
- *
+ *
* @param operation
* a
* {@link eu.etaxonomy.taxeditor.operation.AbstractPostOperation}
IRunnableWithProgress runnable = new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor)
+ @Override
+ public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
monitor.beginTask(operation.getLabel(), 100);
IStatus status = Status.CANCEL_STATUS;
} finally {
monitor.done();
}
-
+
String statusString = status.equals(Status.OK_STATUS) ? "completed"
: "cancelled";
setStatusLine(operation.getLabel() + " " + statusString + ".");
* <p>
* getOperationHistory
* </p>
- *
+ *
* @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
* object.
*/
* <p>
* setStatusLine
* </p>
- *
+ *
* @param message
* a {@link java.lang.String} object.
*/
public static void setStatusLine(final String message) {
Display.getDefault().asyncExec(new Runnable() {
- public void run() {
+ @Override
+ public void run() {
statusLineManager.setMessage(message);
}
* <p>
* getMonitor
* </p>
- *
+ *
* @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
*/
public static IProgressMonitor getMonitor() {
/**
* Starts either the given {@link IProgressMonitor} if it's not
* <code>null</code> or a new {@link NullProgressMonitor}.
- *
+ *
* @param progressMonitor
* The {@link IProgressMonitor} or <code>null</code> if no
* progress should be reported.
* Creates a {@link SubProgressMonitor} if the given
* {@link IProgressMonitor} is not <code>null</code> and not a
* {@link NullProgressMonitor}.
- *
+ *
* @param progressMonitor
* The parent {@link IProgressMonitor} of the
* {@link SubProgressMonitor} to be created.
/**
* Checks whether the user canceled this operation. If not canceled, the
* given number of steps are declared as done.
- *
+ *
* @param newMonitor
* a {@link org.eclipse.core.runtime.IProgressMonitor} object.
* @param steps
/**
* Present a progress dialog to the user. This dialog will block the UI
- *
+ *
* @param runnable
* an implementation of {@link IRunnableWithProgress}
* @throws java.lang.InterruptedException
* <p>
* runInUI
* </p>
- *
+ *
* @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
* @param runnable
* a {@link org.eclipse.jface.operation.IRunnableWithProgress}
* <p>
* run
* </p>
- *
+ *
* @param fork
* a boolean.
* @param cancelable
* <p>
* getProgressService
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.progress.IProgressService} object.
*/
public static IProgressService getProgressService() {
* <p>
* getProgressService2
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
* object.
*/
* <p>
* info
* </p>
- *
+ *
* @param message
* a {@link java.lang.String} object.
*/
* <p>
* info
* </p>
- *
+ *
* @param status
* a {@link org.eclipse.core.runtime.IStatus} object.
*/
* <p>
* warn
* </p>
- *
+ *
* @param source
* a {@link java.lang.Class} object.
* @param message
getLog4JLogger(source).warn(message);
log(status);
}
-
+
public static void warn(Class source, IStatus status) {
getLog4JLogger(source).warn(status.getMessage(), status.getException());
log(status);
}
-
+
public static void warn(Class source, Throwable t) {
IStatus status = new Status(IStatus.WARNING, getPluginId(), t.getMessage(), t);
getLog4JLogger(source).warn(t);
* <p>
* error
* </p>
- *
+ *
* @param source
* a {@link java.lang.Class} object.
* @param t
* <p>
* error
* </p>
- *
+ *
* @param source
* a {@link java.lang.Class} object.
* @param message
* <p>
* error
* </p>
- *
+ *
* @param source
* a {@link java.lang.Class} object.
* @param status
* <p>
* getLog4JLogger
* </p>
- *
+ *
* @param clazz
* a {@link java.lang.Class} object.
* @return a {@link org.apache.log4j.Logger} object.
/**
* @see {@link ILog#log(IStatus)}
- *
+ *
* @param status
*/
private static void log(IStatus status) {
* <p>
* getPluginId
* </p>
- *
+ *
* @return a {@link java.lang.String} object.
*/
public static String getPluginId() {
* <p>
* getActiveEditor
* </p>
- *
+ *
* @return a {@link org.eclipse.ui.IEditorPart} object.
*/
public static IEditorPart getActiveEditor() {
* <p>
* getDetailsView
* </p>
- *
+ *
* @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
* object.
*/
.reflow();
}
}
-
- }
+
+ /**
+ * Orders a Collection of {@link IEnumTerm}s according to the term
+ * hierarchy. The hierarchy will be reduced to two layers: one layer being
+ * the root elements (that have no parents) and the other being their
+ * children and children's children recursively.<br>
+ * The returned map will be be ordered primarily by root elements and
+ * secondarily by the child elements, both ascending alphabetically. <br>
+ * <br>
+ * The reduced hierarchy could look like this:<br>
+ * <ul>
+ * <li>Root1
+ * <ul>
+ * <li>child1
+ * <li>child2
+ * <li>childOfChild2
+ * </ul>
+ * <li>root2
+ * <ul><li>child4</ul>
+ * </ul>
+ *
+ * @param terms
+ * A {@link Collection} of {@link IEnumTerm}s for which the term
+ * hierarchy should be created
+ * @return a map which holds the terms as keys and their string
+ * representation via {@link IEnumTerm#getMessage()} as values
+ */
+ public static <T extends IEnumTerm<?>> Map<T, String> orderTerms(Collection<T> terms) {
+ Comparator<T> comparator = new Comparator<T>() {
+ @Override
+ public int compare(T t1, T t2) {
+ return t1.getKey().compareTo(t2.getKey());
+ }
+ };
+ Map<T, String> result = new LinkedHashMap<T, String>();
+ Map<T, Set<T>> termHierarchy = new TreeMap<T, Set<T>>(comparator);
+
+ for(T term : terms) {
+ Set<T> childList = new TreeSet<T>(comparator);
+ // add root element as keys
+ if(term.getKindOf()==null){
+ termHierarchy.put(term, childList);
+ }
+ // add child element to topmost parent i.e. root
+ else{
+ T root = getRootFor(term);
+ if(termHierarchy.containsKey(root)){
+ termHierarchy.get(root).add(term);
+ }
+ else{
+ childList.add(term);
+ termHierarchy.put(root, childList);
+ }
+ }
+ }
+
+ // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
+ for(Entry<T, Set<T>> entry:termHierarchy.entrySet()){
+ T root = entry.getKey();
+ result.put(root, root.getMessage());
+ for(T child:entry.getValue()){
+ result.put(child, " - " + child.getMessage());
+ }
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ /**
+ * Recursively iterates over all term parents until no more parent is found i.e. the root node
+ * @param term The term for which the parent should be found
+ * @return the root terms of the term hierarchy
+ */
+ private static<T extends IEnumTerm<?>> T getRootFor(T term){
+ // PP: cast should be safe. Why is Eclipse complaining??
+ T parent = (T) term.getKindOf();
+ if(parent==null){
+ return term;
+ }
+ else{
+ return getRootFor((T) term.getKindOf());
+ }
+ }
+
+}
// $Id$
/**
* Copyright (C) 2007 EDIT
- * European Distributed Institute of Taxonomy
+ * European Distributed Institute of Taxonomy
* http://www.e-taxonomy.eu
- *
+ *
* The contents of this file are subject to the Mozilla Public License Version 1.1
* See LICENSE.TXT at the top of this package for the full license terms.
*/
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map.Entry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Label;
-import eu.etaxonomy.cdm.model.common.IDefinedTerm;
import eu.etaxonomy.cdm.model.common.IEnumTerm;
import eu.etaxonomy.cdm.model.common.OriginalSourceType;
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
import eu.etaxonomy.cdm.model.reference.ReferenceType;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
import eu.etaxonomy.taxeditor.preference.Resources;
import eu.etaxonomy.taxeditor.store.StoreUtil;
import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
* <p>
* Abstract AbstractEnumComboElement class.
* </p>
- *
+ *
* @author n.hoffmann
* @created Mar 16, 2010
* @version 1.0
private static CdmEnumDataHolder[] cdmEnumDataHolders = {
new CdmEnumDataHolder<NomenclaturalCode>(){
-
+
@Override
public String getName() {
return "Nomenclatural Code";
public Class<NomenclaturalCode> getClazz() {
return NomenclaturalCode.class;
}
-
+
},
new CdmEnumDataHolder<ReferenceType>(){
public Class<ReferenceType> getClazz() {
return ReferenceType.class;
}
-
+
},
new CdmEnumDataHolder<SpecimenOrObservationType>(){
public Class<SpecimenOrObservationType> getClazz() {
return SpecimenOrObservationType.class;
}
-
+
},
new CdmEnumDataHolder<OriginalSourceType>(){
public Class<OriginalSourceType> getClazz() {
return OriginalSourceType.class;
}
-
+
}
-
+
};
-
+
private static final int DEFAULT_VISIBLE_ITEMS = 10;
protected T selection;
protected List<T> elementTypeList = new ArrayList<T>();
- private Label label;
+ private final Label label;
protected Combo combo;
- private Class<T> enumType;
+ private final Class<T> enumType;
/**
* <p>
* Constructor for AbstractEnumComboElement.
* </p>
- *
+ *
* @param formFactory
* a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
* object.
* </p>
*/
private void populateTypes(){
- for(T enumElement : getElementsForClass(enumType)){
- elementTypeList.add(enumElement);
- combo.add(((Enum) enumElement).name());
+ for(Entry<T, String> keyLabelPair : AbstractUtility.orderTerms(getElementsForClass(enumType)).entrySet()){
+ elementTypeList.add(keyLabelPair.getKey());
+ combo.add(keyLabelPair.getValue());
}
}
* <p>
* Setter for the field <code>selection</code>.
* </p>
- *
+ *
* @param selection
* the selection to set
*/
* <p>
* addSelectionListener
* </p>
- *
+ *
* @param listener
* a {@link org.eclipse.swt.events.SelectionListener} object.
*/
* <p>
* removeSelectionListener
* </p>
- *
+ *
* @param listener
* a {@link org.eclipse.swt.events.SelectionListener} object.
*/
}
/** {@inheritDoc} */
- public void setSelected(boolean selected) {
+ @Override
+ public void setSelected(boolean selected) {
setBackground(selected ? SELECTED : getPersistentBackground());
}
* <p>
* Getter for the field <code>selection</code>.
* </p>
- *
+ *
* @return the selection
*/
public T getSelection() {
}
/** {@inheritDoc} */
- public void setEnabled(boolean enabled) {
+ @Override
+ public void setEnabled(boolean enabled) {
combo.setEnabled(enabled);
}
/*
* (non-Javadoc)
- *
+ *
* @see
* org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
* .events.SelectionEvent)
*/
/** {@inheritDoc} */
- public void widgetSelected(SelectionEvent e) {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
selection = elementTypeList.get(combo.getSelectionIndex());
firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
}
/** {@inheritDoc} */
- public void setIrrelevant(boolean irrelevant) {
+ @Override
+ public void setIrrelevant(boolean irrelevant) {
String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
: Resources.COLOR_COMPOSITE_BACKGROUND;
}
/** {@inheritDoc} */
- public void widgetDefaultSelected(SelectionEvent e) {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
}
-
+
public void setVisibleItemCount(int visibleItems){
combo.setVisibleItemCount(visibleItems);
}
-
+
private Collection<T> getElementsForClass(Class<T> clazz){
CdmEnumDataHolder<T> dataHolder = getCdmEnumDataHolderForClass(clazz);
if (dataHolder != null) {
- return dataHolder.getElements();
+ return dataHolder.getElements();
}
return null;
}
-
+
private CdmEnumDataHolder<T> getCdmEnumDataHolderForClass(Class<T> clazz){
for (CdmEnumDataHolder dataHolder : cdmEnumDataHolders) {
if (dataHolder.getClazz().equals(clazz)){
}
return null;
}
-
+
private interface CdmEnumDataHolder<T> {
Class<T> getClazz();
String getName();