2 * Copyright (c) 2018. Developed by Hedgecode.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.hedgecode.chess.uci;
20 import java.io.FilenameFilter;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
27 import org.hedgecode.chess.uci.annotation.Command;
28 import org.hedgecode.chess.uci.annotation.CommandDirection;
33 * @author Dmitry Samoshin aka gotty
35 public class CommandDescriptor {
37 private static final char PKG_SEPARATOR = '.';
38 private static final char DIR_SEPARATOR = '/';
39 private static final String CLASS_FILE_SUFFIX = ".class";
41 private static final String PACKAGE_IS_NOT_EXISTS = "The package '%s' is not exists.";
43 private Map<String, UCICommand> commandsTo = new HashMap<>();
44 private Map<String, UCICommand> commandsFrom = new HashMap<>();
46 CommandDescriptor() throws Exception {
50 private void initCommands() throws Exception {
52 CommandDescriptor.class.getPackage().getName()
56 private void initCommands(String packageName) throws Exception {
57 URL packageUrl = Thread.currentThread().getContextClassLoader().getResource(
58 packageName.replace(PKG_SEPARATOR, DIR_SEPARATOR)
60 if (packageUrl == null)
61 throw new IllegalArgumentException(
62 String.format(PACKAGE_IS_NOT_EXISTS, packageName)
65 List<Class> commandClasses = findCommands(
74 for (Class commandClass : commandClasses) {
75 if (UCICommand.class.isAssignableFrom(commandClass)) {
76 UCICommand uciCommand = (UCICommand) commandClass.newInstance();
77 Command command = (Command) commandClass.getAnnotation(Command.class);
78 switch (command.direction()) {
81 command.name(), uciCommand
86 command.name(), uciCommand
94 private List<Class> findCommands(File dir, String packageName) throws Exception {
95 List<Class> commands = new ArrayList<>();
97 File[] classFiles = dir.listFiles(
98 new FilenameFilter() {
99 public boolean accept(File file, String name) {
100 return name.endsWith(CLASS_FILE_SUFFIX);
104 if (classFiles != null) {
105 for (File classFile : classFiles) {
106 String className = packageName + PKG_SEPARATOR + classFile.getName();
107 int endIndex = className.length() - CLASS_FILE_SUFFIX.length();
108 className = className.substring(0, endIndex);
109 Class clazz = Class.forName(className);
110 if (clazz.isAnnotationPresent(Command.class)) {
116 File[] subDirs = dir.listFiles(
117 new FilenameFilter() {
118 public boolean accept(File file, String name) {
119 return file.isDirectory();
123 if (subDirs != null) {
124 for (File subDir : subDirs) {
128 packageName + PKG_SEPARATOR + subDir.getName()
137 public UCICommand getCommand(String name, CommandDirection direction) {
140 return commandsTo.get(name);
142 return commandsFrom.get(name);
148 public static void main(String[] arg) throws Exception {
149 CommandDescriptor cd = new CommandDescriptor();
152 command = cd.getCommand("uci", CommandDirection.TO_ENGINE);
153 System.out.println(command);
154 command = cd.getCommand("debug", CommandDirection.TO_ENGINE);
155 System.out.println(command);
156 command = cd.getCommand("test", CommandDirection.TO_ENGINE);
157 System.out.println(command);