/**
* Copyright (C) 2015 Valkyrie RCP
*
* 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.valkyriercp.command.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.valkyriercp.application.config.ApplicationConfig;
import org.valkyriercp.command.*;
import org.valkyriercp.command.config.CommandButtonConfigurer;
import org.valkyriercp.command.config.CommandFaceDescriptor;
import org.valkyriercp.factory.ButtonFactory;
import org.valkyriercp.factory.ComponentFactory;
import org.valkyriercp.factory.MenuFactory;
import org.valkyriercp.util.ValkyrieRepository;
import java.util.List;
/**
* @author Keith Donald
*/
@Component
public class DefaultCommandManager implements CommandManager, BeanPostProcessor, BeanFactoryAware {
private final Log logger = LogFactory.getLog(getClass());
private BeanFactory beanFactory;
private final DefaultCommandRegistry commandRegistry = new DefaultCommandRegistry();
private CommandServices commandServices;
@Autowired
private CommandConfigurer commandConfigurer;
@Autowired
private ApplicationConfig applicationConfig;
public DefaultCommandManager() {
}
public DefaultCommandManager(CommandRegistry parent) {
setParent(parent);
}
public DefaultCommandManager(CommandServices commandServices) {
setCommandServices(commandServices);
}
public void setCommandServices(CommandServices commandServices) {
Assert.notNull(commandServices, "A command services implementation is required");
this.commandServices = commandServices;
}
public CommandServices getCommandServices() {
if(commandServices == null) {
commandServices = getApplicationConfig().commandServices();
}
return commandServices;
}
public ApplicationConfig getApplicationConfig() {
if(applicationConfig == null)
return ValkyrieRepository.getInstance().getApplicationConfig();
return applicationConfig;
}
public void setParent(CommandRegistry parent) {
commandRegistry.setParent(parent);
}
public CommandConfigurer getCommandConfigurer() {
if(commandConfigurer == null)
return ValkyrieRepository.getInstance().getApplicationConfig().commandConfigurer();
return commandConfigurer;
}
public void setCommandConfigurer(CommandConfigurer commandConfigurer) {
Assert.notNull(commandConfigurer, "command configurer must not be null");
this.commandConfigurer = commandConfigurer;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public ComponentFactory getComponentFactory(){
return getCommandServices().getComponentFactory();
}
public ButtonFactory getToolBarButtonFactory() {
return getCommandServices().getButtonFactory();
}
public ButtonFactory getButtonFactory() {
return getCommandServices().getButtonFactory();
}
public MenuFactory getMenuFactory() {
return getCommandServices().getMenuFactory();
}
public CommandButtonConfigurer getDefaultButtonConfigurer() {
return getCommandServices().getDefaultButtonConfigurer();
}
public CommandButtonConfigurer getToolBarButtonConfigurer() {
return getCommandServices().getToolBarButtonConfigurer();
}
public CommandButtonConfigurer getMenuItemButtonConfigurer() {
return getCommandServices().getMenuItemButtonConfigurer();
}
public CommandButtonConfigurer getPullDownMenuButtonConfigurer() {
return getCommandServices().getPullDownMenuButtonConfigurer();
}
public CommandFaceDescriptor getFaceDescriptor(AbstractCommand command, String faceDescriptorId) {
if (beanFactory == null) {
return null;
}
try {
return (CommandFaceDescriptor)beanFactory.getBean(command.getId() + "." + faceDescriptorId,
CommandFaceDescriptor.class);
}
catch (NoSuchBeanDefinitionException e) {
try {
return (CommandFaceDescriptor)beanFactory.getBean(faceDescriptorId, CommandFaceDescriptor.class);
}
catch (NoSuchBeanDefinitionException ex) {
return null;
}
}
}
public ActionCommand getActionCommand(String commandId) {
return (ActionCommand) commandRegistry.getCommand(commandId, ActionCommand.class);
}
public CommandGroup getCommandGroup(String groupId) {
return (CommandGroup)commandRegistry.getCommand(groupId, CommandGroup.class);
}
public boolean containsCommandGroup(String groupId) {
return commandRegistry.containsCommandGroup(groupId);
}
public boolean containsActionCommand(String commandId) {
return commandRegistry.containsActionCommand(commandId);
}
public void addCommandInterceptor(String commandId, ActionCommandInterceptor interceptor) {
getActionCommand(commandId).addCommandInterceptor(interceptor);
}
public void removeCommandInterceptor(String commandId, ActionCommandInterceptor interceptor) {
getActionCommand(commandId).removeCommandInterceptor(interceptor);
}
public void registerCommand(AbstractCommand command) {
if (logger.isDebugEnabled()) {
logger.debug("Configuring and registering new command '" + command.getId() + "'");
}
configure(command);
commandRegistry.registerCommand(command);
}
public void setTargetableActionCommandExecutor(String commandId, ActionCommandExecutor executor) {
commandRegistry.setTargetableActionCommandExecutor(commandId, executor);
}
public void addCommandRegistryListener(CommandRegistryListener l) {
this.commandRegistry.addCommandRegistryListener(l);
}
public void removeCommandRegistryListener(CommandRegistryListener l) {
this.commandRegistry.removeCommandRegistryListener(l);
}
public TargetableActionCommand createTargetableActionCommand(String commandId, ActionCommandExecutor delegate) {
Assert.notNull(commandId, "Registered targetable action commands must have an id.");
TargetableActionCommand newCommand = new TargetableActionCommand(commandId, delegate);
registerCommand(newCommand);
return newCommand;
}
public ExclusiveCommandGroup createExclusiveCommandGroup(String groupId, Object[] members) {
Assert.notNull(groupId, "Registered exclusive command groups must have an id.");
CommandGroupFactoryBean newGroupFactory = new CommandGroupFactoryBean(groupId, this.commandRegistry, this,
members);
newGroupFactory.setExclusive(true);
registerCommand(newGroupFactory.getCommandGroup());
return (ExclusiveCommandGroup)newGroupFactory.getCommandGroup();
}
public AbstractCommand configure(AbstractCommand command) {
return getCommandConfigurer().configure(command);
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AbstractCommand) {
registerCommand((AbstractCommand)bean);
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof CommandGroupFactoryBean) {
CommandGroupFactoryBean factory = (CommandGroupFactoryBean)bean;
factory.setCommandRegistry(commandRegistry);
}
else if (bean instanceof AbstractCommand) {
configure((AbstractCommand)bean);
}
return bean;
}
/**
* {@inheritDoc}
*/
public boolean containsCommand(String commandId) {
return this.commandRegistry.containsCommand(commandId);
}
/**
* {@inheritDoc}
*/
public Object getCommand(String commandId, Class requiredType) throws CommandNotOfRequiredTypeException {
return this.commandRegistry.getCommand(commandId, requiredType);
}
/**
* {@inheritDoc}
*/
public Object getCommand(String commandId) {
return this.commandRegistry.getCommand(commandId);
}
/**
* {@inheritDoc}
*/
public Class getType(String commandId) {
return this.commandRegistry.getType(commandId);
}
/**
* {@inheritDoc}
*/
public boolean isTypeMatch(String commandId, Class targetType) {
return this.commandRegistry.isTypeMatch(commandId, targetType);
}
/**
* Create a command group which holds all the given members.
*
* @param members members to add to the group.
* @return a {@link CommandGroup} which contains all the members.
*/
@Override
public CommandGroup createCommandGroup(List<? extends Object> members) {
return createCommandGroup(null, members.toArray(), false, null);
}
/**
* Create a command group which holds all the given members.
*
* @param groupId the id to configure the group.
* @param members members to add to the group.
* @return a {@link CommandGroup} which contains all the members.
*/
@Override
public CommandGroup createCommandGroup(String groupId, Object[] members) {
return createCommandGroup(groupId, members, false, null);
}
/**
* Create a command group which holds all the given members.
*
* @param groupId the id to configure the group.
* @param members members to add to the group.
* @return a {@link CommandGroup} which contains all the members.
*/
@Override
public CommandGroup createCommandGroup(String groupId, List<? extends AbstractCommand> members) {
return createCommandGroup(groupId, members.toArray(), false, null);
}
/**
* Create a command group which holds all the given members.
*
* @param groupId the id to configure the group.
* @param members members to add to the group.
* @param configurer the configurer to use.
* @return a {@link CommandGroup} which contains all the members.
*/
@Override
public CommandGroup createCommandGroup(String groupId, Object[] members, CommandConfigurer configurer) {
return createCommandGroup(groupId, members, false, configurer);
}
/**
* Creates a command group, configuring the group using the ObjectConfigurer
* service (pulling visual configuration properties from an external
* source). This method will also auto-configure contained Command members
* that have not yet been configured.
*
* @param groupId id to configure this commandGroup.
* @param members members to add to the group.
* @return a {@link CommandGroup} that holds the given members.
*/
@Override
public CommandGroup createCommandGroup(final String groupId, final Object[] members,
final boolean exclusive, final CommandConfigurer configurer) {
final CommandGroupFactoryBean groupFactory = new CommandGroupFactoryBean(groupId, null, getCommandConfigurer(), members);
groupFactory.setExclusive(exclusive);
return groupFactory.getCommandGroup();
}
public ActionCommand createDummyCommand(final String id, final String msg)
{
ActionCommand newCommand = new ActionCommand(id)
{
protected void doExecuteCommand()
{
System.out.println(msg);
}
};
getCommandConfigurer().configure(newCommand);
return newCommand;
}
}