org.treediagram.nina.console.Console.java Source code

Java tutorial

Introduction

Here is the source code for org.treediagram.nina.console.Console.java

Source

/*
 * Copyright 2014-2015 the original author or authors.
 *
 * 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.treediagram.nina.console;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.treediagram.nina.console.exception.CommandException;

/**
 * ?
 * 
 * @author hy
 * 
 */
public class Console {
    /**
     * 
     */
    private static final Logger logger = LoggerFactory.getLogger(Console.class);

    /**
     * ???
     */
    private boolean stop;

    /**
     * ???
     */
    private Map<String, Map<String, Command>> groupedCommands = new HashMap<String, Map<String, Command>>();

    /**
     * ??
     */
    private Map<String, Command> commands = new HashMap<String, Command>();

    /**
     * ???
     */
    private final AbstractApplicationContext applicationContext;

    /**
     * ???
     */
    private final ConversionService conversionService;

    /**
     * ???,1=???,0=???
     * */
    private int _runMode;

    /**
     * ?
     */
    public Console(AbstractApplicationContext applicationContext) {
        //  JVM ShutdownHook
        applicationContext.registerShutdownHook();
        this.applicationContext = applicationContext;
        this.conversionService = applicationContext.getBean(ConversionService.class);
        registerCommand();
        commands.put(cmdStop.name(), cmdStop);
        commands.put(cmdList.name(), cmdList);
        if (logger.isDebugEnabled()) {
            logger.debug("???");
        }
    }

    /**
     * ??
     */
    public void stop() {
        applicationContext.close();
        stop = true;
        if (logger.isInfoEnabled()) {
            logger.info("?");
        }
    }

    /**
     * ???
     * */
    public int getRunMode() {
        return _runMode;
    }

    /**
     * ????
     */
    public boolean isStop() {
        return stop;
    }

    /**
     * ???
     */
    public Command getCommand(String name, String subname) {
        Map<String, Command> group = groupedCommands.get(name);
        return (group != null ? group.get(subname) : null);
    }

    /**
     * ???
     */
    public Command getCommand(String name) {
        return commands.get(name);
    }

    /**
     * ??
     */
    public void start(String runMode) {
        this._runMode = 0;
        if (runMode.equalsIgnoreCase("open")) {
            this._runMode = 1;
        }

        ConsoleRunner runner = new ConsoleRunner(this);
        Thread thread = new Thread(runner, "?");
        thread.start();
        if (logger.isInfoEnabled()) {
            logger.info("??");
        }
    }

    /**
     * 
     */
    private MethodFilter findCommand = new MethodFilter() {
        @Override
        public boolean matches(Method method) {
            if (method.getAnnotation(ConsoleCommand.class) != null) {
                return true;
            }
            return false;
        }
    };

    /**
     * ?
     */
    private void registerCommand() {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(ConsoleBean.class);

        for (Entry<String, Object> entry : beans.entrySet()) {
            final Object bean = entry.getValue();
            final Class<? extends Object> beanClass = bean.getClass();

            final ConsoleBean consoleBean = beanClass.getAnnotation(ConsoleBean.class);
            final String groupName = consoleBean.value();

            ReflectionUtils.doWithMethods(bean.getClass(), new MethodCallback() {
                @Override
                public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                    // 
                    Command command = new MethodCommand(bean, method, conversionService);

                    // 
                    if (StringUtils.isNotBlank(groupName)) {
                        // ?
                        Map<String, Command> group = groupedCommands.get(groupName);
                        if (group == null) {
                            group = new HashMap<String, Command>();
                            groupedCommands.put(groupName, group);
                        }

                        // 
                        if (group.containsKey(command.name())) {
                            throw new IllegalStateException(
                                    "[" + groupName + "][" + command.name() + "]??");
                        }
                        group.put(command.name(), command);
                    } else {
                        // ???
                        if (groupedCommands.containsKey(command.name())) {
                            throw new IllegalStateException("[" + command.name() + "]???");
                        }
                        // 
                        if (commands.containsKey(command.name())) {
                            throw new IllegalStateException("[" + command.name() + "]??");
                        }
                        commands.put(command.name(), command);
                    }
                }
            }, findCommand);
        }
    }

    /**
     * ??
     */
    private Command cmdStop = new Command() {
        @Override
        public String name() {
            return "stop";
        }

        @Override
        public boolean execute(String[] arguments) throws CommandException {
            stop();
            return true;
        }

        @Override
        public String description() {
            return "??";
        }
    };

    /**
     * ?
     */
    private Command cmdList = new Command() {
        class Pair {
            private String name;
            private String description;

            public Pair(String name, String description) {
                this.name = name;
                this.description = description;
            }
        }

        @Override
        public String name() {
            return "list";
        }

        @Override
        public boolean execute(String[] arguments) throws CommandException {
            // 
            int longestLength = 0;

            // ??
            List<Pair> pairs = new ArrayList<Pair>();

            for (Command command : commands.values()) {
                if (command.name().length() > longestLength) {
                    longestLength = command.name().length();
                }
                pairs.add(new Pair(command.name(), command.description()));
            }

            for (Entry<String, Map<String, Command>> e : groupedCommands.entrySet()) {
                for (Command command : e.getValue().values()) {
                    String name = e.getKey() + " " + command.name();
                    int nameLength = name.length();
                    if (nameLength > longestLength) {
                        longestLength = nameLength;
                    }
                    pairs.add(new Pair(name, command.description()));
                }
            }

            // ?
            Collections.sort(pairs, new Comparator<Pair>() {
                @Override
                public int compare(Pair o1, Pair o2) {
                    return o1.name.compareTo(o2.name);
                }
            });

            // ?
            for (Pair pair : pairs) {
                String line = String.format("%-" + longestLength + "s %s", pair.name, pair.description);
                System.out.println(line);
            }

            // ?
            return true;
        }

        @Override
        public String description() {
            return "?";
        }
    };
}