001package org.javasimon.console; 002 003import java.lang.reflect.Constructor; 004import java.lang.reflect.InvocationTargetException; 005 006/** 007 * Simple action bindings which is triggered by the path and produces 008 * actions of given type 009 * 010 * @author gquintana 011 */ 012@SuppressWarnings("UnusedDeclaration") 013public class SimpleActionBinding<T extends Action> implements ActionBinding<T> { 014 015 /** 016 * Path 017 */ 018 private final String path; 019 /** 020 * Constructor used to instantiate actions 021 */ 022 private final Class<T> actionClass; 023 /** 024 * Constructor used to instantiate actions 025 */ 026 private final Constructor<T> actionConstructor; 027 028 /** 029 * Constructor. 030 * 031 * @param path Supported path. 032 * @param actionClass Create Action class 033 */ 034 public SimpleActionBinding(String path, Class<T> actionClass) { 035 this.path = path; 036 this.actionClass = actionClass; 037 Constructor<T> constructor; 038 try { 039 try { 040 constructor = actionClass.getConstructor(ActionContext.class); 041 } catch (NoSuchMethodException noSuchMethodException) { 042 constructor = actionClass.getConstructor(); 043 } 044 } catch (SecurityException securityException) { 045 throw new IllegalStateException("Can get constructor for class " + actionClass.getName(), securityException); 046 } catch (NoSuchMethodException noSuchMethodException) { 047 throw new IllegalArgumentException("Can find constructor for class " + actionClass.getName()); 048 } 049 this.actionConstructor = constructor; 050 } 051 052 /** 053 * Returns true when {@link ActionContext#getPath()} equals {@link #path}. 054 */ 055 public boolean supports(ActionContext actionContext) { 056 return actionContext.getPath().equals(this.path); 057 } 058 059 /** 060 * Create a new {@link Action} using {@link #actionConstructor}. 061 */ 062 public T create(ActionContext actionContext) { 063 try { 064 T action; 065 Class[] actionConstructorParams = actionConstructor.getParameterTypes(); 066 switch (actionConstructorParams.length) { 067 case 0: 068 action = actionConstructor.newInstance(); 069 break; 070 case 1: 071 if (actionConstructorParams[0].equals(ActionContext.class)) { 072 action = actionConstructor.newInstance(actionContext); 073 } else { 074 throw new IllegalStateException("Unknown argument type in action constructor " + actionConstructorParams[0].getName()); 075 } 076 break; 077 default: 078 throw new IllegalStateException("Invalid argument number in action constructor: " + actionConstructorParams.length); 079 } 080 return action; 081 } catch (InstantiationException | InvocationTargetException | IllegalAccessException instantiationException) { 082 throw new IllegalStateException("Failed to create action", instantiationException); 083 } 084 } 085 086 public Constructor<T> getActionConstructor() { 087 return actionConstructor; 088 } 089 090 public Class<T> getActionClass() { 091 return actionClass; 092 } 093 094 public String getPath() { 095 return path; 096 } 097}