/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * 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. */ package org.kie.workbench.common.stunner.core.command.util; import java.util.logging.Logger; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.kie.workbench.common.stunner.core.command.Command; import org.kie.workbench.common.stunner.core.command.CommandManager; import org.kie.workbench.common.stunner.core.command.CommandResult; import org.kie.workbench.common.stunner.core.registry.RegistryFactory; import org.kie.workbench.common.stunner.core.registry.command.CommandRegistry; /** * This handler is an util class that achieves command "re-do" features. * It's behaviour is to keep in a command registry (usually a in-memory registry), the commands that have been * "undone" for a given context. It allows further re-do ( re-execution ) of that commands. If at some point * the user undo some commands and executes whatever new action that produces a new command, this registry is cleared * so you cannot redo older commands. * It can be used as: * <b>Inputs</b> * - Capture undo operations for commands and call the <code>onUndoCommandExecuted</code> method * - Capture regular command executions and call the <code>onCommandExecuted</code> method * <b>Output</b> * - Check <code>isEnabled</code> to figure out if a re-do operation can be done. * - Call <code>clear</code> to clear the internal commands registry and reset the re-do status. * - If <code>isEnabled</code> is <code>true</code>, you can run the <code>execute</code> method. It runs last undone command on found this handler's registry. * @param <C> The command type. */ @Dependent public class RedoCommandHandler<C extends Command> { private static Logger LOGGER = Logger.getLogger(RedoCommandHandler.class.getName()); private final CommandRegistry<C> registry; protected RedoCommandHandler() { this(null); } @Inject public RedoCommandHandler(final RegistryFactory registryFactory) { this.registry = registryFactory.newCommandRegistry(); } public boolean onUndoCommandExecuted(final C command) { registry.register(command); return isEnabled(); } @SuppressWarnings("unchecked") public boolean onCommandExecuted(final C command) { if (isEnabled()) { final C last = registry.peek(); if (last.equals(command)) { // If the recently executed command is the same in this handler' registry, means it has been // executed by this handler so it can be removed from the registry. registry.pop(); } else { // Any "new" ( e.g: not a previously undone command ) executed commands cleans the registry, // no re-do is possible. clear(); } } return isEnabled(); } @SuppressWarnings("unchecked") public CommandResult<?> execute(final Object context, final CommandManager commandManager) { if (registry.isEmpty()) { throw new IllegalStateException("Not possible to execute a command: no commands to redo."); } final C last = registry.peek(); return commandManager.execute(context, last); } public boolean isEnabled() { return !registry.isEmpty(); } public void clear() { registry.clear(); } }