/* * #%L * carewebframework * %% * Copyright (C) 2008 - 2016 Regenstrief Institute, Inc. * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This Source Code Form is also subject to the terms of the Health-Related * Additional Disclaimer of Warranty and Limitation of Liability available at * * http://www.carewebframework.org/licensing/disclaimer. * * #L% */ package org.carewebframework.ui.command; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.carewebframework.api.spring.SpringUtil; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zul.impl.XulElement; /** * Registry for commands. */ public class CommandRegistry implements Iterable<Command> { private final Map<String, Command> commands = new HashMap<>(); /** * Returns the singleton instance of the registry. * * @return Command registry instance. */ public static final CommandRegistry getInstance() { return SpringUtil.getBean("commandRegistry", CommandRegistry.class); } /** * Creates the command registry using the specified shortcut mappings. * * @param shortcuts A map of shortcut mappings, where the key is the command name and the value * contains the associated shortcut(s) in ZK format. */ public CommandRegistry(Map<Object, Object> shortcuts) { super(); bindShortcuts(shortcuts); } public void add(Command command) { if (commands.containsValue(command)) { throw new IllegalArgumentException("Command already exists: " + command.getName()); } commands.put(command.getName(), command); } public Command get(String commandName) { return get(commandName, false); } /** * Retrieves the command associated with the specified name from the registry. * * @param commandName Name of the command sought. * @param forceCreate If true and the command does not exist, one is created and added to the * registry. * @return The associated command, or null if it does not exist (and forceCreate is false). */ public Command get(String commandName, boolean forceCreate) { Command command = commands.get(commandName); if (command == null && forceCreate) { command = new Command(commandName); add(command); } return command; } /** * Binds the shortcuts specified in the map to the associated commands. The map key is the * command name and the associated value is a list of shortcuts bound to the command. * * @param shortcuts Shortcut map. */ private void bindShortcuts(Map<Object, Object> shortcuts) { for (Object commandName : shortcuts.keySet()) { bindShortcuts(commandName.toString(), shortcuts.get(commandName).toString()); } } private void bindShortcuts(String commandName, String shortcuts) { Command command = get(commandName, true); for (String shortcut : CommandUtil.parseShortcuts(shortcuts, null)) { command.bind(shortcut); } } public void process(KeyEvent event) { if (event.getReference() instanceof XulElement) { String shortcut = CommandUtil.getShortcut(event); fireCommands(shortcut, event, (XulElement) event.getReference()); } } public void fireCommands(String shortcut, Event triggerEvent, Iterable<? extends XulElement> targets) { for (Command command : this) { if (command.isBound(shortcut)) { for (XulElement target : targets) { if (command.isBound(target)) { if (!command.fire(target, triggerEvent)) { break; } } } } } } public void fireCommands(String shortcut, Event triggerEvent, XulElement target) { for (Command command : this) { if (command.isBound(shortcut) && command.isBound(target)) { command.fire(target, triggerEvent); } } } @Override public Iterator<Command> iterator() { return commands.values().iterator(); } }