View Javadoc
1   package org.cyclopsgroup.jmxterm.cc;
2   
3   import org.apache.commons.configuration2.Configuration;
4   import org.apache.commons.lang3.ArrayUtils;
5   import org.apache.commons.lang3.Validate;
6   import org.cyclopsgroup.jmxterm.Command;
7   import org.cyclopsgroup.jmxterm.CommandFactory;
8   import org.cyclopsgroup.jmxterm.utils.ConfigurationUtils;
9   
10  import java.io.FileNotFoundException;
11  import java.io.IOException;
12  import java.util.HashMap;
13  import java.util.Map;
14  
15  /**
16   * Factory class of commands which knows how to create Command class with given command name
17   * 
18   * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
19   */
20  class PredefinedCommandFactory implements CommandFactory {
21    private final CommandFactory delegate;
22  
23    /**
24     * Default constructor
25     * 
26     * @throws IOException Thrown when Jar is corrupted
27     */
28    PredefinedCommandFactory() throws IOException {
29      this("META-INF/cyclopsgroup/jmxterm.properties");
30    }
31  
32    /**
33     * Constructor which builds up command types
34     * 
35     * @param configPath Path of configuration file in classpath
36     * @throws IOException Thrown when Jar is corrupted
37     */
38    @SuppressWarnings("unchecked")
39    public PredefinedCommandFactory(String configPath) throws IOException {
40      Validate.notNull(configPath, "configPath can't be NULL");
41      ClassLoader classLoader = getClass().getClassLoader();
42      Configuration props = ConfigurationUtils.loadFromOverlappingResources(configPath, classLoader);
43      if (props == null) {
44        throw new FileNotFoundException(
45            "Couldn't load configuration from " + configPath + ", classpath has problem");
46      }
47      props = props.subset("jmxterm.commands");
48      if (props == null) {
49        throw new IOException("Expected configuration doesn't appear in " + configPath);
50      }
51      HashMap<String, Class<? extends Command>> commands =
52          new HashMap<String, Class<? extends Command>>();
53      for (String name : props.getStringArray("name")) {
54        String type = props.getString(name + ".type");
55        Class<? extends Command> commandType;
56        try {
57          commandType = (Class<? extends Command>) classLoader.loadClass(type);
58        } catch (ClassNotFoundException e) {
59          throw new RuntimeException("Couldn't load type " + type, e);
60        }
61        commands.put(name, commandType);
62        String[] aliases = props.getStringArray(name + ".alias");
63        if (!ArrayUtils.isEmpty(aliases)) {
64          for (String alias : aliases) {
65            commands.put(alias, commandType);
66          }
67        }
68      }
69      commands.put("help", HelpCommand.class);
70      delegate = new TypeMapCommandFactory(commands);
71    }
72  
73    @Override
74    public Command createCommand(String commandName) {
75      return delegate.createCommand(commandName);
76    }
77  
78    @Override
79    public Map<String, Class<? extends Command>> getCommandTypes() {
80      return delegate.getCommandTypes();
81    }
82  }