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.util.MessageManager;
19 import jalview.ws2.WebServiceI;
20 import jalview.ws2.operations.Operation;
22 public class WebServicesMenuBuilder
25 public static interface SelectedHostChangeListener
27 public void selectedHostChanged(String opName, Operation op);
30 List<Operation> operations = new ArrayList<>();
33 * Mapping of service name to the preferred url this service is hosted at.
35 Map<String, String> selectedHost = new HashMap<>();
37 public void addOperation(Operation op)
42 public void addAllOperations(Collection<Operation> operations)
44 this.operations.addAll(operations);
47 public void removeOperation(Operation op)
49 operations.remove(op);
52 public void clearOperations()
57 public void buildMenu(JMenu atMenu, AlignFrame frame)
59 Map<String, List<Operation>> oneshotOperations = new HashMap<>();
60 Map<String, List<Operation>> interactiveOperations = new HashMap<>();
61 for (Operation op : operations)
63 var mapping = op.isInteractive() ? interactiveOperations : oneshotOperations;
64 if (!mapping.containsKey(op.getTypeName()))
65 mapping.put(op.getTypeName(), new ArrayList<>());
66 mapping.get(op.getTypeName()).add(op);
68 var keysSet = new HashSet<>(oneshotOperations.keySet());
69 keysSet.addAll(interactiveOperations.keySet());
70 var keys = new ArrayList<>(keysSet);
71 keys.sort(Comparator.<String>naturalOrder());
72 for (String opType : keys)
74 var submenu = new JMenu(opType);
75 var oneshot = oneshotOperations.get(opType);
77 addOneshotOperations(oneshot, submenu, frame);
78 var interactive = interactiveOperations.get(opType);
79 if (interactive != null)
82 submenu.addSeparator();
83 addInteractiveOperations(interactive, submenu, frame);
89 private void addOneshotOperations(List<Operation> operations, JMenu submenu,
92 operations = new ArrayList<>(operations);
93 operations.sort(Comparator
94 .<Operation, String>comparing(o -> o.getHostName())
95 .<String>thenComparing(o -> o.getName()));
96 String lastHost = null;
97 for (final Operation op : operations)
99 String host = op.getHostName();
100 if (lastHost != host)
102 if (lastHost != null)
103 submenu.addSeparator();
104 var menuItem = new JMenuItem(host);
105 menuItem.setForeground(Color.blue);
106 menuItem.addActionListener(e -> Desktop.showUrl(host));
107 submenu.add(menuItem);
110 submenu.addSeparator();
111 op.getMenuBuilder().buildMenu(submenu, frame);
115 private void addInteractiveOperations(List<Operation> operations,
116 JMenu submenu, AlignFrame frame)
118 Map<String, List<Operation>> groupedOperations = new HashMap<>();
119 for (Operation op : operations)
121 if (!groupedOperations.containsKey(op.getName()))
122 groupedOperations.put(op.getName(), new ArrayList<>());
123 groupedOperations.get(op.getName()).add(op);
125 var keys = new ArrayList<>(groupedOperations.keySet());
126 keys.sort(Comparator.<String>naturalOrder());
127 for (String opName : keys)
129 var ops = groupedOperations.get(opName);
130 var selectedHost = getSelectedHost(opName);
131 Operation selectedOperation = null;
134 if (op.getHostName().equals(selectedHost))
136 selectedOperation = op;
140 if (selectedOperation == null || selectedHost == null)
141 selectedOperation = ops.get(0);
143 final var hostName = selectedOperation.getHostName();
144 var hostItem = new JMenuItem(hostName);
145 hostItem.setForeground(Color.blue);
146 hostItem.addActionListener(e -> Desktop.showUrl(hostName));
147 submenu.add(hostItem);
149 selectedOperation.getMenuBuilder().buildMenu(submenu, frame);
152 JMenuItem alternatesMenu = new JMenuItem(MessageManager.getString("label.switch_server"));
153 submenu.add(alternatesMenu);
154 alternatesMenu.setToolTipText(JvSwingUtils.wrapTooltip(false,
155 MessageManager.getString("label.choose_jabaws_server")));
156 for (final Operation op : ops)
158 if (op == selectedOperation) continue;
159 var hostItem = new JMenuItem(op.getHostName());
160 hostItem.setForeground(Color.blue);
161 hostItem.addActionListener(e -> {
162 setSelectedHost(op.getName(), op.getHostName());
163 fireSelectedHostChanged(op.getName(), op);
165 submenu.add(hostItem);
171 public String getSelectedHost(String serviceName)
173 return selectedHost.getOrDefault(serviceName, null);
176 public void setSelectedHost(WebServiceI service)
178 setSelectedHost(service.getName(), service.getHostName());
181 public void setSelectedHost(String serviceName, String hostName)
183 selectedHost.put(serviceName, hostName);
186 List<SelectedHostChangeListener> hostChangeListeners = new CopyOnWriteArrayList<>();
188 public void addSelectedHostChangeListener(SelectedHostChangeListener l)
190 hostChangeListeners.add(l);
193 private void fireSelectedHostChanged(String opName, Operation op)
195 for (var listener : hostChangeListeners)
197 listener.selectedHostChanged(opName, op);