1 package jalview.ws2.gui;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Comparator;
7 import java.util.HashMap;
8 import java.util.HashSet;
11 import java.util.concurrent.CopyOnWriteArrayList;
13 import javax.swing.JMenu;
14 import javax.swing.JMenuItem;
16 import jalview.gui.AlignFrame;
17 import jalview.gui.Desktop;
18 import jalview.gui.JvSwingUtils;
19 import jalview.util.MessageManager;
20 import jalview.ws2.WebServiceI;
21 import jalview.ws2.operations.Operation;
28 public class WebServicesMenuBuilder
31 public static interface SelectedHostChangeListener
33 public void selectedHostChanged(String opName, Operation op);
36 List<Operation> operations = new ArrayList<>();
39 * Mapping of service name to the preferred url this service is hosted at.
41 Map<String, String> selectedHost = new HashMap<>();
43 public void addOperation(Operation op)
48 public void addAllOperations(Collection<Operation> operations)
50 this.operations.addAll(operations);
53 public void removeOperation(Operation op)
55 operations.remove(op);
58 public void clearOperations()
63 public void buildMenu(JMenu atMenu, AlignFrame frame)
65 Map<String, List<Operation>> oneshotOperations = new HashMap<>();
66 Map<String, List<Operation>> interactiveOperations = new HashMap<>();
67 for (Operation op : operations)
69 var mapping = op.isInteractive() ? interactiveOperations : oneshotOperations;
70 if (!mapping.containsKey(op.getTypeName()))
71 mapping.put(op.getTypeName(), new ArrayList<>());
72 mapping.get(op.getTypeName()).add(op);
74 var keysSet = new HashSet<>(oneshotOperations.keySet());
75 keysSet.addAll(interactiveOperations.keySet());
76 var keys = new ArrayList<>(keysSet);
77 keys.sort(Comparator.<String> naturalOrder());
78 for (String opType : keys)
80 var submenu = new JMenu(opType);
81 var oneshot = oneshotOperations.get(opType);
83 addOneshotOperations(oneshot, submenu, frame);
84 var interactive = interactiveOperations.get(opType);
85 if (interactive != null)
88 submenu.addSeparator();
89 addInteractiveOperations(interactive, submenu, frame);
95 private void addOneshotOperations(List<Operation> operations, JMenu submenu,
98 operations = new ArrayList<>(operations);
99 operations.sort(Comparator
100 .<Operation, String> comparing(o -> o.getHostName())
101 .<String> thenComparing(o -> o.getName()));
102 String lastHost = null;
103 for (final Operation op : operations)
105 String host = op.getHostName();
106 if (lastHost != host)
108 if (lastHost != null)
109 submenu.addSeparator();
110 var menuItem = new JMenuItem(host);
111 menuItem.setForeground(Color.blue);
112 menuItem.addActionListener(e -> Desktop.showUrl(host));
113 submenu.add(menuItem);
116 submenu.addSeparator();
117 op.getMenuBuilder().buildMenu(submenu, frame);
121 private void addInteractiveOperations(List<Operation> operations,
122 JMenu submenu, AlignFrame frame)
124 Map<String, List<Operation>> groupedOperations = new HashMap<>();
125 for (Operation op : operations)
127 if (!groupedOperations.containsKey(op.getName()))
128 groupedOperations.put(op.getName(), new ArrayList<>());
129 groupedOperations.get(op.getName()).add(op);
131 var keys = new ArrayList<>(groupedOperations.keySet());
132 keys.sort(Comparator.<String> naturalOrder());
133 for (String opName : keys)
135 var ops = groupedOperations.get(opName);
136 var selectedHost = getSelectedHost(opName);
137 Operation selectedOperation = null;
140 if (op.getHostName().equals(selectedHost))
142 selectedOperation = op;
146 if (selectedOperation == null || selectedHost == null)
147 selectedOperation = ops.get(0);
149 final var hostName = selectedOperation.getHostName();
150 var hostItem = new JMenuItem(hostName);
151 hostItem.setForeground(Color.blue);
152 hostItem.addActionListener(e -> Desktop.showUrl(hostName));
153 submenu.add(hostItem);
155 selectedOperation.getMenuBuilder().buildMenu(submenu, frame);
158 JMenu alternatesMenu = new JMenu(MessageManager.getString("label.switch_server"));
159 submenu.add(alternatesMenu);
160 alternatesMenu.setToolTipText(JvSwingUtils.wrapTooltip(false,
161 MessageManager.getString("label.choose_jabaws_server")));
162 for (final Operation op : ops)
164 if (op == selectedOperation)
166 var hostItem = new JMenuItem(op.getHostName());
167 hostItem.setForeground(Color.blue);
168 hostItem.addActionListener(e -> {
169 setSelectedHost(op.getName(), op.getHostName());
170 fireSelectedHostChanged(op.getName(), op);
172 alternatesMenu.add(hostItem);
178 public String getSelectedHost(String serviceName)
180 return selectedHost.getOrDefault(serviceName, null);
183 public void setSelectedHost(WebServiceI service)
185 setSelectedHost(service.getName(), service.getHostName());
188 public void setSelectedHost(String serviceName, String hostName)
190 selectedHost.put(serviceName, hostName);
193 List<SelectedHostChangeListener> hostChangeListeners = new CopyOnWriteArrayList<>();
195 public void addSelectedHostChangeListener(SelectedHostChangeListener l)
197 hostChangeListeners.add(l);
200 private void fireSelectedHostChanged(String opName, Operation op)
202 for (var listener : hostChangeListeners)
204 listener.selectedHostChanged(opName, op);