src/org/sonews/daemon/CommandSelector.java
author cli
Sun, 29 Aug 2010 17:43:58 +0200
changeset 36 c404a87db5b7
parent 35 ed84c8bdd87b
child 37 74139325d305
permissions -rw-r--r--
Add some checks to prevent #13 happen.
     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
    39     = new ConcurrentHashMap<Thread, CommandSelector>();
    40   private static Map<String, Class<?>> commandClassesMapping
    41     = new ConcurrentHashMap<String, Class<?>>();
    42 
    43   static
    44   {
    45     String[] classes = Resource.getAsString("helpers/commands.list", true).split("\n");
    46     for(String className : classes)
    47     {
    48       if(className.charAt(0) == '#')
    49       {
    50         // Skip comments
    51         continue;
    52       }
    53 
    54       try
    55       {
    56         addCommandHandler(className);
    57       }
    58       catch(ClassNotFoundException ex)
    59       {
    60         Log.get().warning("Could not load command class: " + ex);
    61       }
    62       catch(InstantiationException ex)
    63       {
    64         Log.get().severe("Could not instantiate command class: " + ex);
    65       }
    66       catch(IllegalAccessException ex)
    67       {
    68         Log.get().severe("Could not access command class: " + ex);
    69       }
    70     }
    71   }
    72 
    73   public static void addCommandHandler(String className)
    74     throws ClassNotFoundException, InstantiationException, IllegalAccessException
    75   {
    76     Class<?> clazz = Class.forName(className);
    77     Command cmd = (Command)clazz.newInstance();
    78     String[] cmdStrs = cmd.getSupportedCommandStrings();
    79     for (String cmdStr : cmdStrs)
    80     {
    81       commandClassesMapping.put(cmdStr, clazz);
    82     }
    83   }
    84 
    85   public static Set<String> getCommandNames()
    86   {
    87     return commandClassesMapping.keySet();
    88   }
    89 
    90   public static CommandSelector getInstance()
    91   {
    92     CommandSelector csel = instances.get(Thread.currentThread());
    93     if(csel == null)
    94     {
    95       csel = new CommandSelector();
    96       instances.put(Thread.currentThread(), csel);
    97     }
    98     return csel;
    99   }
   100 
   101   private Map<String, Command> commandMapping = new HashMap<String, Command>();
   102   private Command              unsupportedCmd = new UnsupportedCommand();
   103 
   104   private CommandSelector()
   105   {}
   106 
   107   public Command get(String commandName)
   108   {
   109     try
   110     {
   111       commandName = commandName.toUpperCase();
   112       Command cmd = this.commandMapping.get(commandName);
   113 
   114       if(cmd == null)
   115       {
   116         Class<?> clazz = commandClassesMapping.get(commandName);
   117         if(clazz == null)
   118         {
   119           cmd = this.unsupportedCmd;
   120         }
   121         else
   122         {
   123           cmd = (Command)clazz.newInstance();
   124           this.commandMapping.put(commandName, cmd);
   125         }
   126       }
   127       else if(cmd.isStateful())
   128       {
   129         cmd = cmd.getClass().newInstance();
   130       }
   131 
   132       return cmd;
   133     }
   134     catch(Exception ex)
   135     {
   136       ex.printStackTrace();
   137       return this.unsupportedCmd;
   138     }
   139   }
   140 
   141 }