workcraft/workcraft

View on GitHub
workcraft/WorkcraftCore/src/org/workcraft/utils/CommandUtils.java

Summary

Maintainability
A
0 mins
Test Coverage
package org.workcraft.utils;

import org.workcraft.Framework;
import org.workcraft.commands.Command;
import org.workcraft.commands.MenuOrdering;
import org.workcraft.commands.MenuOrdering.Position;
import org.workcraft.commands.ScriptableCommand;
import org.workcraft.commands.ScriptableDataCommand;
import org.workcraft.gui.MainWindow;
import org.workcraft.gui.tools.GraphEditor;
import org.workcraft.gui.workspace.Path;
import org.workcraft.plugins.PluginManager;
import org.workcraft.workspace.WorkspaceEntry;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.function.Function;

public class CommandUtils {

    public static String makePromotedSectionTitle(String title, int order) {
        return '!' + TextUtils.repeat(" ", 9 - order) + title;
    }

    public static List<Command> getCommands(Function<Command, Boolean> filter) {
        ArrayList<Command> result = new ArrayList<>();
        final PluginManager pm = Framework.getInstance().getPluginManager();
        for (Command command : pm.getCommands()) {
            if (filter.apply(command)) {
                result.add(command);
            }
        }
        return result;
    }

    public static <T extends Command> List<T> getCommands(Class<T> type) {
        ArrayList<T> result = new ArrayList<>();
        final PluginManager pm = Framework.getInstance().getPluginManager();
        for (Command command : pm.getCommands()) {
            try {
                result.add(type.cast(command));
            } catch (ClassCastException ignored) {
            }
        }
        return result;
    }

    public static List<Command> getApplicableVisibleCommands(WorkspaceEntry we) {
        return getCommands(command -> (command.getMenuVisibility() == Command.MenuVisibility.ALWAYS)
                || ((command.getMenuVisibility() == Command.MenuVisibility.ACTIVE_APPLICABLE)
                        && (we != null) && command.isApplicableTo(we)));
    }

    public static List<String> getSections(List<Command> commands) {
        HashSet<String> sections = new HashSet<>();
        for (Command command: commands) {
            sections.add(command.getSection());
        }
        return SortUtils.getSortedNatural(sections);
    }

    public static List<Command> getSectionCommands(String section, List<Command> commands) {
        List<Command> sectionCommands = new ArrayList<>();
        for (Command command: commands) {
            if (command.getSection().equals(section)) {
                sectionCommands.add(command);
            }
        }
        sectionCommands.sort((o1, o2) -> {
            Integer p1 = (o1 instanceof MenuOrdering) ? ((MenuOrdering) o1).getPriority() : 0;
            Integer p2 = (o2 instanceof MenuOrdering) ? ((MenuOrdering) o2).getPriority() : 0;
            int result = -p1.compareTo(p2); // Reverse the order, so low values correspond to lower priority
            if (result == 0) {
                result = o1.getDisplayName().compareTo(o2.getDisplayName());
            }
            return result;
        });
        return sectionCommands;
    }

    public static List<Command> getPositionedCommands(List<Command> commands, Position position) {
        List<Command> result = new ArrayList<>();
        for (Command command: commands) {
            if ((command instanceof MenuOrdering) && (((MenuOrdering) command).getPosition() == position)) {
                result.add(command);
            }
        }
        return result;
    }

    public static List<Command> getUnpositionedCommands(List<Command> commands) {
        List<Command> result = new ArrayList<>();
        for (Command command: commands) {
            if (!(command instanceof MenuOrdering) || (((MenuOrdering) command).getPosition() == null)) {
                result.add(command);
            }
        }
        return result;
    }

    public static void run(MainWindow mainWindow, Command command) {
        if (mainWindow != null) {
            GraphEditor currentEditor = mainWindow.getCurrentEditor();
            WorkspaceEntry we = currentEditor == null ? null : currentEditor.getWorkspaceEntry();
            checkCommandApplicability(we, command);
            command.run(we);
        }
    }

    public static void run(WorkspaceEntry we, String className) {
        Command command = findMatchingCommand(className, Command.class);
        checkCommandApplicability(we, command);
        command.run(we);
    }


    public static <R> R execute(WorkspaceEntry we, String className) {
        ScriptableCommand<R> command = findMatchingCommand(className, ScriptableCommand.class);
        checkCommandApplicability(we, command);
        return command.execute(we);
    }

    public static <R, D> R execute(WorkspaceEntry we, String className, String serialisedData) {
        ScriptableDataCommand<R, D> command = CommandUtils.findMatchingCommand(className, ScriptableDataCommand.class);
        checkCommandApplicability(we, command);
        D data = command.deserialiseData(serialisedData);
        return command.execute(we, data);
    }

    private static void checkCommandApplicability(WorkspaceEntry we, Command command) {
        if (!command.isApplicableTo(we)) {
            String commandName = command.getClass().getSimpleName();
            if (we == null) {
                throw new RuntimeException("Command '" + commandName + "' needs active workspace entry.");
            } else {
                String displayName = we.getModelEntry().getDescriptor().getDisplayName();
                Path<String> workspacePath = we.getWorkspacePath();
                throw new RuntimeException("Command '" + commandName + "' is incompatible with "
                        + displayName + " (workspace entry '" + workspacePath + "').");
            }
        }
    }

    public static <T extends Command> T findMatchingCommand(String className, Class<T> type) {
        if ((className == null) || className.isEmpty()) {
            throw new RuntimeException("Undefined command name.");
        }
        for (Command command : getCommands(type)) {
            Class<? extends Command> cls = command.getClass();
            if (className.equals(cls.getSimpleName()) || className.endsWith(cls.getName())) {
                return type.cast(command);
            }
        }
        throw new RuntimeException("Command '" + className + "' is not found.");
    }

}