MediaRentalSystem

Go Back

Command Line Interface (CLI) - Menu Processing

It is a menu based application, which means:

How to add a new menu item?

What’s required to add a new menu item?

How to add a new runner/handler to handle the menu item?

What’s required to add a runner/handler to handle menu item?

We saw private constructor in LoadMediaObjectsMenuItem.java and all menu items are actually having private constructors. The static block of code in MenuItemsInitializer.java is the one take care of the initialisation of all the menu items through reflection:

private static final Map<ParentMenu, Map<String, MenuItem>> ID_TO_ITEM_MAP = new HashMap<>();

static {
    // caching to avoid calculating again and again
    LOGGER.info("Initializing menu items...");

    final Reflections reflections = new Reflections(MAIN_PACKAGE);
    final Set<Class<? extends AbstractMenuItem>> menuItemsSubTypes = reflections.getSubTypesOf(AbstractMenuItem.class);
    for (Class<? extends AbstractMenuItem> menuItemClass : menuItemsSubTypes) {
        try {
            final Constructor<? extends AbstractMenuItem> classDeclaredConstructor = menuItemClass.getDeclaredConstructor();
            classDeclaredConstructor.setAccessible(true);
            final AbstractMenuItem menuItem = classDeclaredConstructor.newInstance();
            final ParentMenu parentMenu = menuItem.getParentMenu();
            ID_TO_ITEM_MAP.putIfAbsent(parentMenu, new HashMap<>());
            ID_TO_ITEM_MAP.get(parentMenu).put(menuItem.getItemId(), menuItem);
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException |
                 NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

That code above, is using reflection to load all available menu items into system. And that’s how simply creating a new menu item extended it from AbstractMenuItem.java will start working automagically.

Go Back