import jalview.ws.params.ParamDatastoreI;
import jalview.ws.params.WsParamSetI;
import jalview.ws.seqfetcher.DbSourceProxy;
-import jalview.ws.slivkaws.SlivkaWSDiscoverer;
+import jalview.ws2.slivka.SlivkaWSDiscoverer;
+import jalview.ws2.WebServiceDiscovererI;
+import jalview.ws2.gui.WebServicesMenuBuilder;
+import jalview.ws2.operations.Operation;
+
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
buildWebServicesMenu();
}
+ private void servicesChanged(WebServiceDiscovererI discoverer,
+ List<Operation> operations)
+ {
+ buildWebServicesMenu();
+ }
+
/* Set up intrinsic listeners for dynamically generated GUI bits. */
private void addServiceListeners()
{
if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
{
- WSDiscovererI discoverer = SlivkaWSDiscoverer.getInstance();
- discoverer.addServiceChangeListener(this);
+ WebServiceDiscovererI discoverer = SlivkaWSDiscoverer.getInstance();
+ discoverer.addOperationsChangeListener(this::servicesChanged);
}
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
@Override
public void internalFrameClosed(InternalFrameEvent e) {
System.out.println("deregistering discoverer listener");
- SlivkaWSDiscoverer.getInstance().removeServiceChangeListener(AlignFrame.this);
+ SlivkaWSDiscoverer.getInstance().removeOperationsChangeListener(AlignFrame.this::servicesChanged);
Jws2Discoverer.getInstance().removeServiceChangeListener(AlignFrame.this);
Desktop.getInstance().removeJalviewPropertyChangeListener("services", legacyListener);
closeMenuItem_actionPerformed(true);
}
}
+ private void buildWebServicesMenu(WebServiceDiscovererI discoverer, JMenu menu)
+ {
+ if (discoverer.hasServices())
+ {
+ var builder = new WebServicesMenuBuilder();
+ builder.addSelectedHostChangeListener((name, op) -> {
+ Cache.log.info("Rebuilding menu on host change");
+ menu.removeAll();
+ builder.buildMenu(menu, this);
+ });
+ builder.addAllOperations(discoverer.getOperations());
+ menu.removeAll();
+ builder.buildMenu(menu, this);
+ }
+ if (discoverer.isRunning())
+ {
+ JMenuItem item = new JMenuItem("Service discovery in progress.");
+ item.setEnabled(false);
+ menu.add(item);
+ }
+ else if (!discoverer.hasServices())
+ {
+ JMenuItem item = new JMenuItem("No services available.");
+ item.setEnabled(false);
+ menu.add(item);
+ }
+ }
+
/**
* construct any groupURL type service menu entries.
*
import jalview.bin.Cache;
import jalview.util.MessageManager;
import jalview.ws.WSDiscovererI;
-import jalview.ws.slivkaws.SlivkaWSDiscoverer;
+import jalview.ws2.slivka.SlivkaWSDiscoverer;
+import jalview.ws2.WebServiceDiscovererI;
import java.awt.BorderLayout;
import java.awt.Color;
setPreferredSize(new Dimension(500, 450));
}
- WSDiscovererI discoverer;
+ WebServiceDiscovererI discoverer;
private final ArrayList<String> urls = new ArrayList<>();
hasFocus, row, column);
switch ((Integer) value)
{
- case WSDiscovererI.STATUS_NO_SERVICES:
+ case WebServiceDiscovererI.STATUS_NO_SERVICES:
setForeground(Color.ORANGE);
break;
- case WSDiscovererI.STATUS_OK:
+ case WebServiceDiscovererI.STATUS_OK:
setForeground(Color.GREEN);
break;
- case WSDiscovererI.STATUS_INVALID:
+ case WebServiceDiscovererI.STATUS_INVALID:
setForeground(Color.RED);
break;
- case WSDiscovererI.STATUS_UNKNOWN:
+ case WebServiceDiscovererI.STATUS_UNKNOWN:
default:
setForeground(Color.LIGHT_GRAY);
}
{
String input = (String) JvOptionPane
.showInternalInputDialog(
- this,
+ this,
MessageManager.getString("label.url:"),
UIManager.getString("OptionPane.inputDialogTitle", MessageManager.getLocale()),
JOptionPane.QUESTION_MESSAGE,
if (input != null)
{
urls.add(input);
- statuses.add(discoverer.getServerStatusFor(input));
+ statuses.add(discoverer.getStatusForUrl(input));
urlTableModel.fireTableRowsInserted(urls.size(), urls.size());
- discoverer.setServiceUrls(urls);
+ discoverer.setUrls(urls);
}
};
if (input != null)
{
urls.set(i, input);
- statuses.set(i, discoverer.getServerStatusFor(input));
+ statuses.set(i, discoverer.getStatusForUrl(input));
urlTableModel.fireTableRowsUpdated(i, i);
- discoverer.setServiceUrls(urls);
+ discoverer.setUrls(urls);
}
}
};
urls.remove(i);
statuses.remove(i);
urlTableModel.fireTableRowsDeleted(i, i);
- discoverer.setServiceUrls(urls);
+ discoverer.setUrls(urls);
}
};
if (i > 0)
{
moveTableRow(i, i - 1);
- discoverer.setServiceUrls(urls);
+ discoverer.setUrls(urls);
}
};
if (i >= 0 && i < urls.size() - 1)
{
moveTableRow(i, i + 1);
- discoverer.setServiceUrls(urls);
+ discoverer.setUrls(urls);
}
};
};
private ActionListener resetServicesAction = (ActionEvent e) -> {
- discoverer.setServiceUrls(null);
+ discoverer.setUrls(null);
urls.clear();
statuses.clear();
- urls.addAll(discoverer.getServiceUrls());
+ urls.addAll(discoverer.getUrls());
for (String url : urls)
{
- statuses.add(discoverer.getServerStatusFor(url));
+ statuses.add(discoverer.getStatusForUrl(url));
}
urlTableModel.fireTableDataChanged();
};
{
// Initial URLs loading
discoverer = SlivkaWSDiscoverer.getInstance();
- urls.addAll(discoverer.getServiceUrls());
+ urls.addAll(discoverer.getUrls());
for (String url : urls)
{
- statuses.add(discoverer.getServerStatusFor(url));
+ statuses.add(discoverer.getStatusForUrl(url));
}
}
}
--- /dev/null
+package jalview.ws2.gui;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.ws2.WebServiceI;
+import jalview.ws2.operations.Operation;
+
+/**
+ *
+ * @author mmwarowny
+ *
+ */
+public class WebServicesMenuBuilder
+{
+ @FunctionalInterface
+ public static interface SelectedHostChangeListener
+ {
+ public void selectedHostChanged(String opName, Operation op);
+ }
+
+ List<Operation> operations = new ArrayList<>();
+
+ /**
+ * Mapping of service name to the preferred url this service is hosted at.
+ */
+ Map<String, String> selectedHost = new HashMap<>();
+
+ public void addOperation(Operation op)
+ {
+ operations.add(op);
+ }
+
+ public void addAllOperations(Collection<Operation> operations)
+ {
+ this.operations.addAll(operations);
+ }
+
+ public void removeOperation(Operation op)
+ {
+ operations.remove(op);
+ }
+
+ public void clearOperations()
+ {
+ operations.clear();
+ }
+
+ public void buildMenu(JMenu atMenu, AlignFrame frame)
+ {
+ Map<String, List<Operation>> oneshotOperations = new HashMap<>();
+ Map<String, List<Operation>> interactiveOperations = new HashMap<>();
+ for (Operation op : operations)
+ {
+ var mapping = op.isInteractive() ? interactiveOperations : oneshotOperations;
+ if (!mapping.containsKey(op.getTypeName()))
+ mapping.put(op.getTypeName(), new ArrayList<>());
+ mapping.get(op.getTypeName()).add(op);
+ }
+ var keysSet = new HashSet<>(oneshotOperations.keySet());
+ keysSet.addAll(interactiveOperations.keySet());
+ var keys = new ArrayList<>(keysSet);
+ keys.sort(Comparator.<String> naturalOrder());
+ for (String opType : keys)
+ {
+ var submenu = new JMenu(opType);
+ var oneshot = oneshotOperations.get(opType);
+ if (oneshot != null)
+ addOneshotOperations(oneshot, submenu, frame);
+ var interactive = interactiveOperations.get(opType);
+ if (interactive != null)
+ {
+ if (oneshot != null)
+ submenu.addSeparator();
+ addInteractiveOperations(interactive, submenu, frame);
+ }
+ atMenu.add(submenu);
+ }
+ }
+
+ private void addOneshotOperations(List<Operation> operations, JMenu submenu,
+ AlignFrame frame)
+ {
+ operations = new ArrayList<>(operations);
+ operations.sort(Comparator
+ .<Operation, String> comparing(o -> o.getHostName())
+ .<String> thenComparing(o -> o.getName()));
+ String lastHost = null;
+ for (final Operation op : operations)
+ {
+ String host = op.getHostName();
+ if (lastHost != host)
+ {
+ if (lastHost != null)
+ submenu.addSeparator();
+ var menuItem = new JMenuItem(host);
+ menuItem.setForeground(Color.blue);
+ menuItem.addActionListener(e -> Desktop.showUrl(host));
+ submenu.add(menuItem);
+ lastHost = host;
+ }
+ submenu.addSeparator();
+ op.getMenuBuilder().buildMenu(submenu, frame);
+ }
+ }
+
+ private void addInteractiveOperations(List<Operation> operations,
+ JMenu submenu, AlignFrame frame)
+ {
+ Map<String, List<Operation>> groupedOperations = new HashMap<>();
+ for (Operation op : operations)
+ {
+ if (!groupedOperations.containsKey(op.getName()))
+ groupedOperations.put(op.getName(), new ArrayList<>());
+ groupedOperations.get(op.getName()).add(op);
+ }
+ var keys = new ArrayList<>(groupedOperations.keySet());
+ keys.sort(Comparator.<String> naturalOrder());
+ for (String opName : keys)
+ {
+ var ops = groupedOperations.get(opName);
+ var selectedHost = getSelectedHost(opName);
+ Operation selectedOperation = null;
+ for (var op : ops)
+ {
+ if (op.getHostName().equals(selectedHost))
+ {
+ selectedOperation = op;
+ break;
+ }
+ }
+ if (selectedOperation == null || selectedHost == null)
+ selectedOperation = ops.get(0);
+ {
+ final var hostName = selectedOperation.getHostName();
+ var hostItem = new JMenuItem(hostName);
+ hostItem.setForeground(Color.blue);
+ hostItem.addActionListener(e -> Desktop.showUrl(hostName));
+ submenu.add(hostItem);
+ }
+ selectedOperation.getMenuBuilder().buildMenu(submenu, frame);
+ if (ops.size() > 1)
+ {
+ JMenu alternatesMenu = new JMenu(MessageManager.getString("label.switch_server"));
+ submenu.add(alternatesMenu);
+ alternatesMenu.setToolTipText(JvSwingUtils.wrapTooltip(false,
+ MessageManager.getString("label.choose_jabaws_server")));
+ for (final Operation op : ops)
+ {
+ if (op == selectedOperation)
+ continue;
+ var hostItem = new JMenuItem(op.getHostName());
+ hostItem.setForeground(Color.blue);
+ hostItem.addActionListener(e -> {
+ setSelectedHost(op.getName(), op.getHostName());
+ fireSelectedHostChanged(op.getName(), op);
+ });
+ alternatesMenu.add(hostItem);
+ }
+ }
+ }
+ }
+
+ public String getSelectedHost(String serviceName)
+ {
+ return selectedHost.getOrDefault(serviceName, null);
+ }
+
+ public void setSelectedHost(WebServiceI service)
+ {
+ setSelectedHost(service.getName(), service.getHostName());
+ }
+
+ public void setSelectedHost(String serviceName, String hostName)
+ {
+ selectedHost.put(serviceName, hostName);
+ }
+
+ List<SelectedHostChangeListener> hostChangeListeners = new CopyOnWriteArrayList<>();
+
+ public void addSelectedHostChangeListener(SelectedHostChangeListener l)
+ {
+ hostChangeListeners.add(l);
+ }
+
+ private void fireSelectedHostChanged(String opName, Operation op)
+ {
+ for (var listener : hostChangeListeners)
+ {
+ listener.selectedHostChanged(opName, op);
+ }
+ }
+
+}