Skip to content
Snippets Groups Projects
Commit d5ef2178 authored by Simon Barner's avatar Simon Barner
Browse files

- Sort columns alphabetically using a TreeSet of the newly introduced ColumnHandles.

- Ensure that "Create" columns for dynamic multi-instance annotations are right to the corresponding instances.
- Simplify column handling. Merge updateSingleInstanceAnnotationColumns() / updateMultiInstanceAnnotationColumns() into update()
refs 1841
parent 793757ed
No related branches found
No related tags found
No related merge requests found
...@@ -19,9 +19,9 @@ package org.fortiss.tooling.base.ui.annotation.view; ...@@ -19,9 +19,9 @@ package org.fortiss.tooling.base.ui.annotation.view;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Set;
import java.util.TreeSet;
import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.EditingSupport;
...@@ -55,10 +55,6 @@ import org.fortiss.tooling.base.ui.annotation.valueprovider.IAnnotationValueProv ...@@ -55,10 +55,6 @@ import org.fortiss.tooling.base.ui.annotation.valueprovider.IAnnotationValueProv
*/ */
public class GenericAnnotationView extends AnnotationViewPartBase { public class GenericAnnotationView extends AnnotationViewPartBase {
/** mapping of {@link IAnnotatedSpecification} -> TableViewerColumn */
protected HashMap<Class<? extends IAnnotatedSpecification>, TableViewerColumn> annotationSpecColumns =
new HashMap<Class<? extends IAnnotatedSpecification>, TableViewerColumn>();
/** /**
* List containing the columns that are responsible for creating new keys. Required for * List containing the columns that are responsible for creating new keys. Required for
* disposing when updating the view. * disposing when updating the view.
...@@ -66,104 +62,185 @@ public class GenericAnnotationView extends AnnotationViewPartBase { ...@@ -66,104 +62,185 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
private List<CreateAnnotationInstanceColumn> createColumns = private List<CreateAnnotationInstanceColumn> createColumns =
new ArrayList<CreateAnnotationInstanceColumn>(); new ArrayList<CreateAnnotationInstanceColumn>();
/** The table viewer */
protected TableViewer tableViewer;
/** /**
* Map for associating those specifications that allow multiple values with their according * Character used to separte the annotation name from the instance name for multi-instance
* AnnotationEntries. * annotations.
*/ */
private Map<IAnnotatedSpecification, AnnotationEntry> specsAllowingMultipleValues = private final static String MULTIINSTANCE_NAME_SEPARATOR = ":";
new HashMap<IAnnotatedSpecification, AnnotationEntry>();
/** The table viewer */ /**
protected TableViewer tableViewer; * Data required to identify a column displaying a particular {@link IAnnotatedSpecification} in
* a column of the {@link GenericAnnotationView}. Used to sort columns (see
* {@link #compareTo(ColumnHandle)}).
*/
private class ColumnHandle implements Comparable<ColumnHandle> {
/**
* {@link AnnotationEntry} from which a particular {@link IAnnotatedSpecification} is to be
* displayed in the column represented by this {@link ColumnHandle}.
*/
private AnnotationEntry entry;
/**
* {@link IAnnotatedSpecification} from {@code entry} to be displayed in the column
* represented by this {@link ColumnHandle}.
*/
private IAnnotatedSpecification annotatedSpecification;
/**
* Instance key identifying the particular instance of an {@link IAnnotatedSpecification}
* from {@code entry} to be displayed in the column represented by this {@link ColumnHandle}
* .
*/
private String instanceKey;
/** Flag if this {@link ColumnHandle} represents a {@link CreateAnnotationInstanceColumn}. */
private boolean isCreateColumn;
/** Constructs a new {@link ColumnHandle}. */
public ColumnHandle(AnnotationEntry entry, IAnnotatedSpecification annotatedSpecification,
String instanceKey, boolean isCreateColumn) {
this.entry = entry;
this.annotatedSpecification = annotatedSpecification;
this.instanceKey = instanceKey;
this.isCreateColumn = isCreateColumn;
}
/**
* Returns the {@link AnnotationEntry} from which a particular
* {@link IAnnotatedSpecification} is to be
* displayed in the column represented by this {@link ColumnHandle}.
*/
public AnnotationEntry getEntry() {
return entry;
}
/**
* Returns the {@link IAnnotatedSpecification} from {@code entry} to be displayed in the
* column represented by this {@link ColumnHandle}.
*/
public IAnnotatedSpecification getAnnotatedSpecification() {
return annotatedSpecification;
}
/**
* Returns the instance key identifying the particular instance of an
* {@link IAnnotatedSpecification} from {@code entry} to be displayed in the column
* represented by this {@link ColumnHandle} .
*/
public String getInstanceKey() {
return instanceKey;
}
/**
* Returns a flag if this {@link ColumnHandle} represents a
* {@link CreateAnnotationInstanceColumn}.
*/
public boolean isCreateColumn() {
return isCreateColumn;
}
/** {@inheritDoc} */
@Override
public int compareTo(ColumnHandle other) {
String columnName = getColumnName(this);
String annotationName;
int columnNameSeparatorIndex = columnName.indexOf(MULTIINSTANCE_NAME_SEPARATOR);
if(columnNameSeparatorIndex != -1) {
annotationName = columnName.substring(0, columnNameSeparatorIndex);
} else {
annotationName = columnName;
}
String otherColumnName = getColumnName(other);
String otherAnnotationName;
int otherColumnNameSeparatorIndex =
otherColumnName.indexOf(MULTIINSTANCE_NAME_SEPARATOR);
if(otherColumnNameSeparatorIndex != -1) {
otherAnnotationName = otherColumnName.substring(0, otherColumnNameSeparatorIndex);
} else {
otherAnnotationName = otherColumnName;
}
// Place "create" columns (label: "<specification name>") after their instances
// (which are labeled "<specification name>: <instance name>").
if(annotationName.equals(otherAnnotationName)) {
// Ensure uniqueness of "create" columns"
if(isCreateColumn && other.isCreateColumn) {
return 0;
}
if(isCreateColumn) {
return 1;
}
if(other.isCreateColumn) {
return -1;
}
}
// Sort alphabetically by specification column label
return columnName.compareTo(otherColumnName);
}
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
protected void update(Collection<AnnotationEntry> annotationEntries) { protected void update(Collection<AnnotationEntry> annotationEntries) {
updateSingleInstanceAnnotationColumns(annotationEntries); /*
updateMultiInstanceAnnotationColumns(annotationEntries); * Sorted set of {@link ColumnHandle} used to instantiate this {@link
} * GenericAnnotationView}'s columns in the right order.
*/
Set<ColumnHandle> sortedColumnHandles = new TreeSet<ColumnHandle>();
/** Create columns for ordinary (single instance) {@link IAnnotatedSpecification}s */
private void
updateSingleInstanceAnnotationColumns(Collection<AnnotationEntry> annotationEntries) {
/* /*
* disposes all columns of the table viewer, except the first column, which holds the names * Dispose all columns of the table viewer, except the first column, which holds the names
* of the model elements * of the model elements
*/ */
while(tableViewer.getTable().getColumnCount() > 1) { while(tableViewer.getTable().getColumnCount() > 1) {
tableViewer.getTable().getColumn(1).dispose(); tableViewer.getTable().getColumn(1).dispose();
} }
annotationSpecColumns.clear();
/*
* Create a column for each annotation specification provided by any AnnotationEntry. There
* is no additional columns created for those specification which already have an associated
* column or provide complex values.
*/
for(AnnotationEntry entry : annotationEntries) {
for(IAnnotatedSpecification spec : entry.getSpecificationsList()) {
if(!isExistingColumn(spec) &&
!entry.allowsDynamicAnnotationInstances(spec.getClass()) &&
entry.getInstanceKeys(spec.getClass()).isEmpty()) {
createAnnotationColumn(entry, spec, null);
}
}
}
if(!tableViewer.getTable().isDisposed())
tableViewer.setInput(annotationEntries);
}
/** Create columns for multi-instance {@link IAnnotatedSpecification}s */
private void
updateMultiInstanceAnnotationColumns(Collection<AnnotationEntry> annotationEntries) {
for(CreateAnnotationInstanceColumn col : createColumns) { for(CreateAnnotationInstanceColumn col : createColumns) {
col.dispose(); col.dispose();
} }
specsAllowingMultipleValues.clear(); // Aggregate required columns. Column order is defined by ColumnHandle.compareTo().
/*
* Iterate over all available specifications in the model. Columns for specifications
* with simple values have already been created by the superclass 'GenericAnnotationView',
* others are stored in the map 'specsAllowingMultipleValues'.
* Each annotation specification type may exist only once in the table view or the map
* 'code specsAllowingMultipleValues'.
*/
List<String> specClassNamesMult = new ArrayList<String>();
for(AnnotationEntry entry : annotationEntries) { for(AnnotationEntry entry : annotationEntries) {
for(IAnnotatedSpecification spec : entry.getSpecificationsList()) { for(IAnnotatedSpecification spec : entry.getSpecificationsList()) {
if((!entry.getInstanceKeys(spec.getClass()).isEmpty() || entry // Create new column for each instance of the current multi-instance annotation
.allowsDynamicAnnotationInstances(spec.getClass())) && if((entry.allowsDynamicAnnotationInstances(spec.getClass())) ||
!specClassNamesMult.contains(spec.getClass().getSimpleName())) { !entry.getInstanceKeys(spec.getClass()).isEmpty()) {
specsAllowingMultipleValues.put(spec, entry);
specClassNamesMult.add(spec.getClass().getSimpleName());
}
}
}
// Iterate over all specification supporting multiple values. for(String instanceKey : entry.getInstanceKeys(spec.getClass())) {
for(IAnnotatedSpecification spec : specsAllowingMultipleValues.keySet().toArray( sortedColumnHandles.add(new ColumnHandle(entry, spec, instanceKey, false));
new IAnnotatedSpecification[specsAllowingMultipleValues.keySet().size()])) { }
AnnotationEntry entry = specsAllowingMultipleValues.get(spec); }
// Create new column for each instance of the current multi-instance annotation // Create a new column for
for(String key : entry.getInstanceKeys(spec.getClass())) { // - ordinary (single-instance) annotations
createAnnotationColumn(entry, spec, key); // - "create" column for multi-instance annotations for which instances can be
} // created dynamically
if(entry.getInstanceKeys(spec.getClass()).isEmpty() ||
entry.allowsDynamicAnnotationInstances(spec.getClass())) {
sortedColumnHandles.add(new ColumnHandle(entry, spec, null, entry
.allowsDynamicAnnotationInstances(spec.getClass())));
if(entry.allowsDynamicAnnotationInstances(spec.getClass())) { }
// Create column that contains a button for adding new instances of the
// current annotation type.
createColumns.add(new CreateAnnotationInstanceColumn(tableViewer, SWT.NONE, spec,
entry));
(createColumns.get(createColumns.size() - 1)).getColumn().setWidth(125);
} }
}
// Instantiate columns
for(ColumnHandle columnHandle : sortedColumnHandles) {
createAnnotationColumn(columnHandle);
} }
// Refresh table to trigger the update method of the create columns in order to actually // Register content provider
// instantiate the "Create" buttons if(!tableViewer.getTable().isDisposed()) {
tableViewer.setInput(annotationEntries);
}
tableViewer.refresh(); tableViewer.refresh();
} }
...@@ -195,42 +272,58 @@ public class GenericAnnotationView extends AnnotationViewPartBase { ...@@ -195,42 +272,58 @@ public class GenericAnnotationView extends AnnotationViewPartBase {
} }
/** Creates a column in tableViewer that displays the annotation given in spec */ /** Creates a column in tableViewer that displays the annotation given in spec */
protected void createAnnotationColumn(AnnotationEntry entry, IAnnotatedSpecification spec, protected void createAnnotationColumn(ColumnHandle columnHandle) {
String instanceKey) {
if(columnHandle.isCreateColumn()) {
// Determine column name // Create column that contains a button for adding new instances of the
String specName = entry.getSpecificationAnnotationName(spec.getClass()); // current annotation type.
if(specName == null || specName.isEmpty()) { createColumns.add(new CreateAnnotationInstanceColumn(tableViewer, SWT.NONE,
specName = "<Unnamed Annotation>"; columnHandle.getAnnotatedSpecification(), columnHandle.getEntry()));
(createColumns.get(createColumns.size() - 1)).getColumn().setWidth(125);
return;
} }
if(instanceKey != null) { String specName = getColumnName(columnHandle);
specName += ": " + instanceKey;
}
// Add new new column // Add new new column
TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
column.getColumn().setText(specName); column.getColumn().setText(specName);
Class<? extends IAnnotatedSpecification> annotationClass =
columnHandle.getAnnotatedSpecification().getClass();
column.getColumn().setWidth(125); column.getColumn().setWidth(125);
annotationSpecColumns.put(spec.getClass(), column);
// Have the matching EditingSupport created for the current annotated specification // Have the matching EditingSupport created for the current annotated specification
// (work is delegated to respective IAnnotationValueProvider implementation) // (work is delegated to respective IAnnotationValueProvider implementation)
EditingSupport editingSupport = EditingSupport editingSupport =
entry.createSpecificationEditElement(tableViewer, spec.getClass(), instanceKey); columnHandle.getEntry().createSpecificationEditElement(tableViewer,
annotationClass, columnHandle.getInstanceKey());
// Add column label provider, and set EditingSupport // Add column label provider, and set EditingSupport
column.setLabelProvider(new AnnotationLabelProvider(spec.getClass(), this, instanceKey)); column.setLabelProvider(new AnnotationLabelProvider(annotationClass, this, columnHandle
.getInstanceKey()));
column.setEditingSupport(editingSupport); column.setEditingSupport(editingSupport);
} }
/** Checks if column for given specification already exists */ /**
protected boolean isExistingColumn(IAnnotatedSpecification specification) { * Returns the name of a column for a given {@link IAnnotatedSpecification} represented by the
if(annotationSpecColumns.containsKey(specification.getClass())) * given {@link ColumnHandle}.
return true; */
return false; protected String getColumnName(ColumnHandle columnHandle) {
// Determine column name
String specName =
columnHandle.getEntry().getSpecificationAnnotationName(
columnHandle.getAnnotatedSpecification().getClass());
if(specName == null || specName.isEmpty()) {
specName = "<Unnamed Annotation>";
}
if(columnHandle.getInstanceKey() != null) {
specName += MULTIINSTANCE_NAME_SEPARATOR + " " + columnHandle.getInstanceKey();
}
return specName;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment