001package jmri.jmrix.loconet.swing.menuitemspi;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.ServiceLoader;
006import java.util.ServiceConfigurationError;
007
008import jmri.util.swing.WindowInterface;
009
010import javax.swing.JMenu;
011
012import jmri.jmrix.loconet.LocoNetSystemConnectionMemo;
013import jmri.jmrix.loconet.swing.menuitemspi.spi.MenuItemsInterface;
014
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018/**
019 * A JAVA SPI Service to retrieve, from providers of the {@link 
020 * jmri.jmrix.loconet.swing.menuitemspi.spi.MenuItemsInterface} service, lists 
021 * of items to be added to the JMRI menu(s) associated with LocoNet connections.
022 * <br>
023 * @author Bob M.  Copyright (C) 2021
024 */
025public final class MenuItemsService {
026    private static MenuItemsService service; // (singleton pattern)
027    private final ServiceLoader <MenuItemsInterface> loader;
028
029    private MenuItemsService () {
030        loader = ServiceLoader.load(MenuItemsInterface.class);
031    }
032
033    /**
034     * Method for getting the SPI service "singleton"
035     * @return the singleton instance of this class
036     */
037    public static synchronized MenuItemsService getInstance() {
038        if (service == null) {
039            service = new MenuItemsService();
040        }
041        return service;
042    }
043
044    /**
045     * Return menu items from all LocoNet Menu Extension SPI providers.
046     * <br>
047     * @param isLocoNetInterface informs whether the connection
048     *      has actual hardware
049     * @param wi allows the extension menu items to be associated with the
050     *      JAVA WindowInterface which relates to the connection's menu
051     * @param memo the LocoNetSystemConnectionMemo associated with the menu to
052     *      which the extension's MenuItem(s) are to be attached.
053     * @return an ArrayList of JMenu objects, as populated from the menu items
054     *      reported by any available SPI extensions.  May be an empty ArrayList
055     *      if none of the SPI extensions provide menu items for this menu.
056     */
057    public List<JMenu> getMenuExtensionsItems(boolean isLocoNetInterface,
058            WindowInterface wi, LocoNetSystemConnectionMemo memo) {
059        ArrayList <JMenu> menus = new java.util.ArrayList<>();
060
061        try {
062            java.util.Iterator<MenuItemsInterface> miIterator = loader.iterator();
063            while (miIterator.hasNext()) {
064                MenuItemsInterface mii = miIterator.next();
065                log.debug("adding menu items for extension {}", mii.getClass());
066                ArrayList <JMenu> me = mii.getMenuItems(isLocoNetInterface, wi, memo);
067                menus.addAll(me);
068            }
069        } catch (ServiceConfigurationError serviceError) {
070            // ignore the exception
071        }
072        return menus;
073    }
074    private final static Logger log = LoggerFactory.getLogger(MenuItemsService.class);
075}