package sk.stuba.fiit.perconik.core.ui.preferences;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.base.Function;
import com.google.common.collect.Ordering;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.osgi.framework.Version;
import jersey.repackaged.com.google.common.collect.Maps;
import sk.stuba.fiit.perconik.core.Listener;
import sk.stuba.fiit.perconik.core.ResourceNotRegistredException;
import sk.stuba.fiit.perconik.core.persistence.Registrations;
import sk.stuba.fiit.perconik.core.persistence.data.ListenerPersistenceData;
import sk.stuba.fiit.perconik.core.preferences.ListenerPreferences;
import sk.stuba.fiit.perconik.eclipse.jface.viewers.SortingViewerComparator;
import sk.stuba.fiit.perconik.ui.TableColumns;
import sk.stuba.fiit.perconik.utilities.configuration.Options;
import static java.lang.String.format;
import static org.eclipse.jface.dialogs.MessageDialog.openError;
import static sk.stuba.fiit.perconik.osgi.framework.Versions.toVersion;
import static sk.stuba.fiit.perconik.utilities.MoreStrings.toStringComparator;
/**
* Listeners preference page.
*
* @author Pavol Zbell
* @since 1.0
*/
public final class ListenersPreferencePage extends AbstractPreferencePage<ListenerPreferences, ListenerPersistenceData> {
public ListenersPreferencePage() {}
@Override
String name() {
return "listener";
}
@Override
Class<ListenerPersistenceData> type() {
return ListenerPersistenceData.class;
}
@Override
protected ListenerLabelProvider createContentProvider() {
return new ListenerLabelProvider();
}
@Override
protected ListenerOptionsDialog createOptionsDialog() {
return new ListenerOptionsDialog(this.getShell());
}
@Override
protected ListenerViewerComparator createViewerComparator() {
return new ListenerViewerComparator();
}
@Override
protected void createTableColumns(final Table table, final TableColumnLayout layout, final GC gc) {
TableColumn listenerColumn = TableColumns.create(table, layout, "Listener implementation", gc, 4);
TableColumn versionColumn = TableColumns.create(table, layout, "Version", gc, 1);
TableColumn notesColumn = TableColumns.create(table, layout, "Notes", gc, 1);
LocalSetTableSorter listenerSorter = new LocalSetTableSorter(table, Ordering.from(toStringComparator()).onResultOf(new Function<ListenerPersistenceData, String>() {
public String apply(@Nonnull final ListenerPersistenceData data) {
return data.getListenerClass().getName();
}
}));
LocalSetTableSorter versionSorter = new LocalSetTableSorter(table, Ordering.natural().onResultOf(new Function<ListenerPersistenceData, Version>() {
public Version apply(@Nonnull final ListenerPersistenceData data) {
return toVersion(((ListenerLabelProvider) ListenersPreferencePage.this.tableViewer.getLabelProvider()).getVersion(data));
}
}).compound(listenerSorter.getComparator()));
LocalSetTableSorter notesSorter = new LocalSetTableSorter(table, Ordering.from(toStringComparator()).onResultOf(new Function<ListenerPersistenceData, String>() {
public String apply(@Nonnull final ListenerPersistenceData data) {
return ((ListenerLabelProvider) ListenersPreferencePage.this.tableViewer.getLabelProvider()).getNotes(data);
}
}).compound(listenerSorter.getComparator()));
listenerSorter.attach(listenerColumn);
versionSorter.attach(versionColumn);
notesSorter.attach(notesColumn);
}
private static final class ListenerLabelProvider extends AbstractLabelProvider<ListenerPersistenceData> {
ListenerLabelProvider() {}
public String getColumnText(final Object element, final int column) {
ListenerPersistenceData data = (ListenerPersistenceData) element;
switch (column) {
case 0:
return data.getListenerClass().getName() + (data.isProvided() ? "" : " (unknown)");
case 1:
return this.getVersion(data);
case 2:
return this.getNotes(data);
default:
throw new IllegalStateException();
}
}
}
private static class ListenerViewerComparator extends SortingViewerComparator {
ListenerViewerComparator() {}
@Override
public int compare(final Viewer viewer, final Object a, final Object b) {
if ((a instanceof ListenerPersistenceData) && (b instanceof ListenerPersistenceData)) {
ListenerPersistenceData data = (ListenerPersistenceData) a;
ListenerPersistenceData other = (ListenerPersistenceData) b;
return toStringComparator().compare(data.getListenerClass().getName(), other.getListenerClass().getName());
}
return super.compare(viewer, a, b);
}
}
@Override
ListenerPreferences defaultPreferences() {
return ListenerPreferences.getDefault();
}
@Override
ListenerPreferences sharedPreferences() {
return ListenerPreferences.getShared();
}
@Override
Set<ListenerPersistenceData> registrations(final ListenerPreferences preferences) {
return preferences.getListenerPersistenceData();
}
@Override
void apply() {
ListenerPreferences preferences = this.getPreferences();
try {
Set<ListenerPersistenceData> data = Registrations.applyRegisteredMark(this.registrations);
preferences.setListenerPersistenceData(data);
} catch (ResourceNotRegistredException failure) {
StringBuilder message = new StringBuilder();
message.append("Listener registration failed due to one or more unregistered but required resources. ");
message.append("Select only listeners with registered resources.");
message.append(format("%n%n%s.", failure.getLocalizedMessage()));
openError(this.getShell(), "Listener registration", message.toString());
this.performRefresh();
return;
}
if (this.restoreOptions.compareAndSet(true, false)) {
preferences.setListenerConfigurationData(Maps.<Class<? extends Listener>, Options>newHashMap());
}
}
@Override
void load(final ListenerPreferences preferences) {
this.setListenerPreferences(preferences);
}
@Override
void save() {
this.getPreferences().flush();
}
public void setListenerPreferences(final ListenerPreferences preferences) {
this.setPreferences(preferences);
this.registrations = preferences.getListenerPersistenceData();
}
public ListenerPreferences getListenerPreferences() {
return this.getPreferences();
}
}