src/org/sonews/daemon/CommandSelector.java
author cli
Sun Sep 11 15:05:04 2011 +0200 (2011-09-11)
changeset 48 b78e77619152
parent 35 ed84c8bdd87b
permissions -rwxr-xr-x
Merge Channel and Group classes.
     1 /*
     2  *   SONEWS News Server
     3  *   see AUTHORS for the list of contributors
     4  *
     5  *   This program is free software: you can redistribute it and/or modify
     6  *   it under the terms of the GNU General Public License as published by
     7  *   the Free Software Foundation, either version 3 of the License, or
     8  *   (at your option) any later version.
     9  *
    10  *   This program is distributed in the hope that it will be useful,
    11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  *   GNU General Public License for more details.
    14  *
    15  *   You should have received a copy of the GNU General Public License
    16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 
    19 package org.sonews.daemon;
    20 
    21 import java.util.HashMap;
    22 import java.util.Map;
    23 import java.util.Set;
    24 import java.util.concurrent.ConcurrentHashMap;
    25 import org.sonews.daemon.command.Command;
    26 import org.sonews.daemon.command.UnsupportedCommand;
    27 import org.sonews.util.Log;
    28 import org.sonews.util.io.Resource;
    29 
    30 /**
    31  * Selects the correct command processing class.
    32  * @author Christian Lins
    33  * @since sonews/1.0
    34  */
    35 public class CommandSelector
    36 {
    37 
    38 	private static Map<Thread, CommandSelector> instances = new ConcurrentHashMap<Thread, CommandSelector>();
    39 	private static Map<String, Class<?>> commandClassesMapping = new ConcurrentHashMap<String, Class<?>>();
    40 
    41 	static {
    42 		String[] classes = Resource.getAsString("helpers/commands.list", true).split("\n");
    43 		for (String className : classes) {
    44 			if (className.charAt(0) == '#') {
    45 				// Skip comments
    46 				continue;
    47 			}
    48 
    49 			try {
    50 				addCommandHandler(className);
    51 			} catch (ClassNotFoundException ex) {
    52 				Log.get().warning("Could not load command class: " + ex);
    53 			} catch (InstantiationException ex) {
    54 				Log.get().severe("Could not instantiate command class: " + ex);
    55 			} catch (IllegalAccessException ex) {
    56 				Log.get().severe("Could not access command class: " + ex);
    57 			}
    58 		}
    59 	}
    60 
    61 	public static void addCommandHandler(String className)
    62 		throws ClassNotFoundException, InstantiationException,
    63 		IllegalAccessException
    64 	{
    65 		Class<?> clazz = Class.forName(className);
    66 		Command cmd = (Command) clazz.newInstance();
    67 		String[] cmdStrs = cmd.getSupportedCommandStrings();
    68 		for (String cmdStr : cmdStrs) {
    69 			commandClassesMapping.put(cmdStr, clazz);
    70 		}
    71 	}
    72 
    73 	public static Set<String> getCommandNames()
    74 	{
    75 		return commandClassesMapping.keySet();
    76 	}
    77 
    78 	public static CommandSelector getInstance()
    79 	{
    80 		CommandSelector csel = instances.get(Thread.currentThread());
    81 		if (csel == null) {
    82 			csel = new CommandSelector();
    83 			instances.put(Thread.currentThread(), csel);
    84 		}
    85 		return csel;
    86 	}
    87 	private Map<String, Command> commandMapping = new HashMap<String, Command>();
    88 	private Command unsupportedCmd = new UnsupportedCommand();
    89 
    90 	private CommandSelector()
    91 	{
    92 	}
    93 
    94 	public Command get(String commandName)
    95 	{
    96 		try {
    97 			commandName = commandName.toUpperCase();
    98 			Command cmd = this.commandMapping.get(commandName);
    99 
   100 			if (cmd == null) {
   101 				Class<?> clazz = commandClassesMapping.get(commandName);
   102 				if (clazz == null) {
   103 					cmd = this.unsupportedCmd;
   104 				} else {
   105 					cmd = (Command) clazz.newInstance();
   106 					this.commandMapping.put(commandName, cmd);
   107 				}
   108 			} else if (cmd.isStateful()) {
   109 				cmd = cmd.getClass().newInstance();
   110 			}
   111 
   112 			return cmd;
   113 		} catch (Exception ex) {
   114 			ex.printStackTrace();
   115 			return this.unsupportedCmd;
   116 		}
   117 	}
   118 }