// $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.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+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.TermBase;
+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;
import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
-import eu.etaxonomy.taxeditor.view.userecords.UseRecordsViewPart;
/**
* <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();
}
}
-
- public static UseRecordsViewPart getUseRecordsView() {
- return (UseRecordsViewPart) getView(UseRecordsViewPart.ID, false);
- }
- /**
- * <p>
- * refreshUseRecordsViewer
- * </p>
- */
- public static void refreshUseRecordsViewer() {
- if (getUseRecordsView() != null) {
- ((AbstractCdmDataViewer) getUseRecordsView().getViewer()).refresh();
- }
- }
- /**
- * <p>
- * reflowUseRecordsViewer
- * </p>
- */
- public static void reflowUseRecordsViewer() {
- if (getUseRecordsView() != null) {
- ((AbstractCdmDataViewer) getUseRecordsView().getViewer()).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<T>> LinkedHashMap<T, String> orderTerms(Collection<T> terms) {
+// Comparator<TermNode<T>> comparator = new Comparator<TermNode<T>>() {
+// @Override
+// public int compare(TermNode<T> t1, TermNode<T> t2) {
+// return t1.getTerm().getMessage().compareTo(t2.getTerm().getMessage());
+// }
+// };
+
+ TreeSet<TermNode<T>> parentElements = new TreeSet<TermNode<T>>();
+ parentElements.addAll(getTermHierarchy(terms));
+
+ // create list according to the type hierarchy (root elements alphabetically with recursive children also alphabetically)
+ LinkedHashMap<T, String> result = new LinkedHashMap<T, String>();
+ parseTermTree(parentElements, result, -1);
+ return result;
+ }
+
+ private static<T extends IEnumTerm<T>> void parseTermTree(Collection<TermNode<T>> children, LinkedHashMap<T, String> result, int depth){
+ depth++;
+ for(TermNode<T> node:children){
+ String indentString = "";
+ for(int i=0;i<depth;i++){
+ indentString += "- ";
+ }
+ result.put(node.term, indentString + node.term.getMessage());
+ parseTermTree(node.children, result, depth);
+ }
+ }
+
+ private static<T extends IEnumTerm<T>> void addToParents(List<TermNode<T>> parents, Collection<T> terms){
+ List<TermNode<T>> hasChildrenList = new ArrayList<TermNode<T>>();
+ for(T term:terms){
+ // only terms with parents
+ if(term.getKindOf()!=null){
+ TermNode<T> parentNode = new TermNode<T>(term.getKindOf());
+ TermNode<T> childNode = new TermNode<T>(term);
+ if(parents.contains(parentNode)){
+ // parent found in parent list -> add this term to parent's child list
+ parents.get(parents.indexOf(parentNode)).addChild(childNode);
+ if(!term.getGeneralizationOf().isEmpty()){
+ // has more children -> add to list which will be the parent for the next recursion
+ hasChildrenList.add(childNode);
+ }
+ }
+ }
+ }
+ if(!hasChildrenList.isEmpty()){
+ addToParents(hasChildrenList, terms);
+ }
+ }
+
+ private static<T extends IEnumTerm<T>> List<TermNode<T>> getTermHierarchy(Collection<T> terms){
+ List<TermNode<T>> parents = new ArrayList<TermNode<T>>();
+ // get root elements
+ for(T term:terms){
+ T parentTerm = term.getKindOf();
+ if(parentTerm==null){
+ // root element
+ parents.add(new TermNode<T>(term));
+ }
+ }
+ addToParents(parents, terms);
+ return parents;
+ }
+
+ @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>> T getParentFor(T term){
+ // PP: cast should be safe. Why is Eclipse complaining??
+ T parent = term.getKindOf();
+ if(parent==null){
+ return term;
+ }
+ else{
+ return getParentFor(term.getKindOf());
+ }
+ }
+
+ private static class TermNode<T extends IEnumTerm<T>> implements Comparable<TermNode<T>>{
+ private final T term;
+ private final TreeSet<TermNode<T>> children;
+
+ /**
+ * @param term
+ * @param children
+ */
+ public TermNode(T term) {
+ super();
+ this.term = term;
+ this.children = new TreeSet<TermNode<T>>();
+ }
+
+ public void addChild(TermNode<T> child){
+ this.children.add(child);
+ }
+
+ /**
+ * @return the children
+ */
+ public TreeSet<TermNode<T>> getChildren() {
+ return children;
+ }
+
+ /**
+ * @return the term
+ */
+ public T getTerm() {
+ return term;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((term == null) ? 0 : term.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ TermNode other = (TermNode) obj;
+ if (term == null) {
+ if (other.term != null) {
+ return false;
+ }
+ } else if (!term.equals(other.term)) {
+ return false;
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(TermNode<T> that) {
+ return this.term.getMessage().compareTo(that.term.getMessage());
+ }
+ }
+
}