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;
27 public class WebServicesMenuBuilder
30 public static interface SelectedHostChangeListener
32 public void selectedHostChanged(String opName, Operation op);
35 List<Operation> operations = new ArrayList<>();
38 * Mapping of service name to the preferred url this service is hosted at.
40 Map<String, String> selectedHost = new HashMap<>();
42 public void addOperation(Operation op)
47 public void addAllOperations(Collection<Operation> operations)
49 this.operations.addAll(operations);
52 public void removeOperation(Operation op)
54 operations.remove(op);
57 public void clearOperations()
62 public void buildMenu(JMenu atMenu, AlignFrame frame)
64 Map<String, List<Operation>> oneshotOperations = new HashMap<>();
65 Map<String, List<Operation>> interactiveOperations = new HashMap<>();
66 for (Operation op : operations)
68 var mapping = op.isInteractive() ? interactiveOperations : oneshotOperations;
69 if (!mapping.containsKey(op.getTypeName()))
70 mapping.put(op.getTypeName(), new ArrayList<>());
71 mapping.get(op.getTypeName()).add(op);
73 var keysSet = new HashSet<>(oneshotOperations.keySet());
74 keysSet.addAll(interactiveOperations.keySet());
75 var keys = new ArrayList<>(keysSet);
76 keys.sort(Comparator.<String> naturalOrder());
77 for (String opType : keys)
79 var submenu = new JMenu(opType);
80 var oneshot = oneshotOperations.get(opType);
82 addOneshotOperations(oneshot, submenu, frame);
83 var interactive = interactiveOperations.get(opType);
84 if (interactive != null)
87 submenu.addSeparator();
88 addInteractiveOperations(interactive, submenu, frame);
94 private void addOneshotOperations(List<Operation> operations, JMenu submenu,
97 operations = new ArrayList<>(operations);
98 operations.sort(Comparator
99 .<Operation, String> comparing(o -> o.getHostName())
100 .<String> thenComparing(o -> o.getName()));
101 String lastHost = null;
102 for (final Operation op : operations)
104 String host = op.getHostName();
105 if (lastHost != host)
107 if (lastHost != null)
108 submenu.addSeparator();
109 var menuItem = new JMenuItem(host);
110 menuItem.setForeground(Color.blue);
111 menuItem.addActionListener(e -> Desktop.showUrl(host));
112 submenu.add(menuItem);
115 submenu.addSeparator();
116 op.getMenuBuilder().buildMenu(submenu, frame);
120 private void addInteractiveOperations(List<Operation> operations,
121 JMenu submenu, AlignFrame frame)
123 Map<String, List<Operation>> groupedOperations = new HashMap<>();
124 for (Operation op : operations)
126 if (!groupedOperations.containsKey(op.getName()))
127 groupedOperations.put(op.getName(), new ArrayList<>());
128 groupedOperations.get(op.getName()).add(op);
130 var keys = new ArrayList<>(groupedOperations.keySet());
131 keys.sort(Comparator.<String> naturalOrder());
132 for (String opName : keys)
134 var ops = groupedOperations.get(opName);
135 var selectedHost = getSelectedHost(opName);
136 Operation selectedOperation = null;
139 if (op.getHostName().equals(selectedHost))
141 selectedOperation = op;
145 if (selectedOperation == null || selectedHost == null)
146 selectedOperation = ops.get(0);
148 final var hostName = selectedOperation.getHostName();
149 var hostItem = new JMenuItem(hostName);
150 hostItem.setForeground(Color.blue);
151 hostItem.addActionListener(e -> Desktop.showUrl(hostName));
152 submenu.add(hostItem);
154 selectedOperation.getMenuBuilder().buildMenu(submenu, frame);
157 JMenuItem alternatesMenu = new JMenuItem(MessageManager.getString("label.switch_server"));
158 submenu.add(alternatesMenu);
159 alternatesMenu.setToolTipText(JvSwingUtils.wrapTooltip(false,
160 MessageManager.getString("label.choose_jabaws_server")));
161 for (final Operation op : ops)
163 if (op == selectedOperation)
165 var hostItem = new JMenuItem(op.getHostName());
166 hostItem.setForeground(Color.blue);
167 hostItem.addActionListener(e -> {
168 setSelectedHost(op.getName(), op.getHostName());
169 fireSelectedHostChanged(op.getName(), op);
171 submenu.add(hostItem);
177 public String getSelectedHost(String serviceName)
179 return selectedHost.getOrDefault(serviceName, null);
182 public void setSelectedHost(WebServiceI service)
184 setSelectedHost(service.getName(), service.getHostName());
187 public void setSelectedHost(String serviceName, String hostName)
189 selectedHost.put(serviceName, hostName);
192 List<SelectedHostChangeListener> hostChangeListeners = new CopyOnWriteArrayList<>();
194 public void addSelectedHostChangeListener(SelectedHostChangeListener l)
196 hostChangeListeners.add(l);
199 private void fireSelectedHostChanged(String opName, Operation op)
201 for (var listener : hostChangeListeners)
203 listener.selectedHostChanged(opName, op);