[LIB-9] Add chesshog-qrcode module
[chesshog.git] / src / main / java / org / hedgecode / chess / uci / CommandDescriptor.java
1 /*
2  * Copyright (c) 2018. Developed by Hedgecode.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.hedgecode.chess.uci;
18
19 import java.io.File;
20 import java.io.FilenameFilter;
21 import java.net.URL;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.hedgecode.chess.uci.annotation.Command;
28 import org.hedgecode.chess.uci.annotation.CommandDirection;
29
30 /**
31  *
32  *
33  * @author Dmitry Samoshin aka gotty
34  */
35 public class CommandDescriptor {
36
37     private static final char PKG_SEPARATOR = '.';
38     private static final char DIR_SEPARATOR = '/';
39     private static final String CLASS_FILE_SUFFIX = ".class";
40
41     private static final String PACKAGE_IS_NOT_EXISTS = "The package '%s' is not exists.";
42
43     private Map<String, UCICommand> commandsTo = new HashMap<>();
44     private Map<String, UCICommand> commandsFrom = new HashMap<>();
45
46     CommandDescriptor() throws Exception {
47         initCommands();
48     }
49
50     private void initCommands() throws Exception {
51         initCommands(
52                 CommandDescriptor.class.getPackage().getName()
53         );
54     }
55
56     private void initCommands(String packageName) throws Exception {
57         URL packageUrl = Thread.currentThread().getContextClassLoader().getResource(
58                 packageName.replace(PKG_SEPARATOR, DIR_SEPARATOR)
59         );
60         if (packageUrl == null)
61             throw new IllegalArgumentException(
62                     String.format(PACKAGE_IS_NOT_EXISTS, packageName)
63             );
64
65         List<Class> commandClasses = findCommands(
66                 new File(
67                         packageUrl.getFile()
68                 ),
69                 packageName
70         );
71
72         commandsTo.clear();
73         commandsFrom.clear();
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()) {
79                     case TO_ENGINE:
80                         commandsTo.put(
81                                 command.name(), uciCommand
82                         );
83                         break;
84                     case FROM_ENGINE:
85                         commandsFrom.put(
86                                 command.name(), uciCommand
87                         );
88                         break;
89                 }
90             }
91         }
92     }
93
94     private List<Class> findCommands(File dir, String packageName) throws Exception {
95         List<Class> commands = new ArrayList<>();
96
97         File[] classFiles = dir.listFiles(
98                 new FilenameFilter() {
99                     public boolean accept(File file, String name) {
100                         return name.endsWith(CLASS_FILE_SUFFIX);
101                     }
102                 }
103         );
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)) {
111                     commands.add(clazz);
112                 }
113             }
114         }
115
116         File[] subDirs = dir.listFiles(
117                 new FilenameFilter() {
118                     public boolean accept(File file, String name) {
119                         return file.isDirectory();
120                     }
121                 }
122         );
123         if (subDirs != null) {
124             for (File subDir : subDirs) {
125                 commands.addAll(
126                         findCommands(
127                                 subDir,
128                                 packageName + PKG_SEPARATOR + subDir.getName()
129                         )
130                 );
131             }
132         }
133
134         return commands;
135     }
136
137     public UCICommand getCommand(String name, CommandDirection direction) {
138         switch (direction) {
139             case TO_ENGINE:
140                 return commandsTo.get(name);
141             case FROM_ENGINE:
142                 return commandsFrom.get(name);
143         }
144         return null;
145     }
146
147
148     public static void main(String[] arg) throws Exception {
149         CommandDescriptor cd = new CommandDescriptor();
150         //cd.initCommands();
151         UCICommand command;
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);
158     }
159
160 }