diff --git a/src/module-info.java b/src/module-info.java index 1520d57..9143ab7 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -4,6 +4,7 @@ open module org.atriasoft.death { exports org.atriasoft.death; + exports org.atriasoft.death.annotation; requires transitive io.scenarium.logger; requires java.base; diff --git a/src/org/atriasoft/death/ActionList.java b/src/org/atriasoft/death/ActionList.java new file mode 100644 index 0000000..3cb084f --- /dev/null +++ b/src/org/atriasoft/death/ActionList.java @@ -0,0 +1,33 @@ +package org.atriasoft.death; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.atriasoft.death.internal.Log; + +public class ActionList { + private final Map> subActions = new HashMap<>(); + + public void add(final Class clazz) { + String name = PropertiesInterface.getCommand(clazz); + if (name == null || name.isEmpty()) { + Log.error("Can not add an action without name. for: " + clazz.getCanonicalName()); + return; + } + this.subActions.put(name, clazz); + } + + public Set getActions() { + return this.subActions.keySet(); + } + + public Class getInterface(final String action) { + return this.subActions.get(action); + } + + public boolean exist(final String value) { + return this.subActions.get(value) != null; + } + +} diff --git a/src/org/atriasoft/death/ArgChoice.java b/src/org/atriasoft/death/ArgChoice.java deleted file mode 100644 index d805624..0000000 --- a/src/org/atriasoft/death/ArgChoice.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.atriasoft.death; - -public class ArgChoice { - private String val; - private String description; - - public ArgChoice(final String val, final String description) { - this.val = val; - this.description = description; - } - public String getVal() { - return this.val; - } - public void setVal(final String val) { - this.val = val; - } - public String getDescription() { - return this.description; - } - public void setDescription(final String description) { - this.description = description; - } - -} diff --git a/src/org/atriasoft/death/ArgDefine.java b/src/org/atriasoft/death/ArgDefine.java deleted file mode 100644 index 0f9cb71..0000000 --- a/src/org/atriasoft/death/ArgDefine.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.atriasoft.death; - -import java.util.ArrayList; -import java.util.List; - -import org.atriasoft.death.internal.Log; - -/** - * Declare a possibility of an argument value -*/ -public class ArgDefine implements ArgInterface { - private String optionSmall = ""; - private String optionBig = ""; - private String description = ""; - private boolean haveParam = false; - private List list = new ArrayList<>(); - - public ArgDefine() { - this ("", "", new ArrayList<>(), "", false); - } - public ArgDefine(final String smallOption ) { - this (smallOption, "", new ArrayList<>(), "", false); - } - public ArgDefine(final String smallOption, final String bigOption ) { - this (smallOption, bigOption, new ArrayList<>(), "", false); - } - public ArgDefine(final String smallOption, final String bigOption, final List list) { - this (smallOption, bigOption, list, "", false); - } - public ArgDefine(final String smallOption, final String bigOption, final List list, final String desc) { - this (smallOption, bigOption, list, desc, false); - } - /** - * Constructor. - * @param this Class handle - * @param smallOption (char) Value for the small option ex{ '-v' '-k' ... 1 single char element (no need of '-') - * @param bigOption (string) Value of the big option name ex{ '--verbose' '--kill' ... stated with -- and with the full name (no need of '--') - * @param list ([[string,string],...]) Optionnal list of availlable option{ '--mode=debug' ==> [['debug', 'debug mode'],['release', 'release the software']] - * @param desc (string) user friendly description with this parameter (default "") - * @param haveParam (bool) The option must have a parameter (default False) - */ - public ArgDefine(final String smallOption, final String bigOption, final List list, final String desc, final boolean haveParam){ - this.optionSmall = smallOption; - this.optionBig = bigOption; - this.list = list; - if (this.list == null) { - this.list = new ArrayList<>(); - } - if (this.list.size()!=0) { - this.haveParam = true; - } else if (haveParam) { - this.haveParam = true; - } else { - this.haveParam = false; - } - this.description = desc; - } - - @Override - public boolean isParsable() { - return true; - } - /** - * Get the small name of the option ex{ '-v' - * @param this Class handle - * @return (string) Small name value - */ - @Override - public String getOptionSmall(){ - return this.optionSmall; - } - - /** - * Get the big name of the option ex{ '--verbose' - * @param this Class handle - * @return (string) Big name value - */ - @Override - public String getOptionBig() { - return this.optionBig; - } - - /** - * Get the status of getting user parameter value - * @param this Class handle - * @return true; The user must write a value - * @return false; The user must NOT write a value - */ - @Override - public boolean needParameters(){ - return this.haveParam; - } - /** - * Compatibility with @ref ArgSection class - * @param this Class handle - * @return (string) empty string - */ - @Override - public String getPorperties(){ - return ""; - } - - /** - * Check if the user added value is correct or not with the list of availlable value - * @param this Class handle - * @param argument (string) User parameter value (string) - * @return true; The parameter is OK - * @return false; The parameter is NOT Availlable - */ - @Override - public boolean checkAvaillable(final String argument){ - if (this.list.isEmpty()) { - return true; - } - for (ArgChoice elem : this.list){ - if (elem.getVal().equals(argument)){ - return true; - } - } - return false; - } - /** - * Display the argument property when user request help - * @param this Class handle - */ - @Override - public void display() { - if (!this.optionSmall.isEmpty() && !this.optionBig.isEmpty()){ - Log.print(" -" + this.optionSmall + " / --" + this.optionBig); - } else if (!this.optionSmall.isEmpty()){ - Log.print(" -" + this.optionSmall); - } else if (!this.optionBig.isEmpty()){ - Log.print(" --" + this.optionBig); - } else { - Log.print(" ???? ==> internal error ..."); - } - if (!this.description.isEmpty()){ - Log.print(" " + this.description); - } - if (!this.list.isEmpty()){ - boolean hasDescriptiveElement = false; - for (ArgChoice elem : this.list) { - if (!elem.getDescription().isEmpty()) { - hasDescriptiveElement = true; - break; - } - } - if (hasDescriptiveElement) { - for (ArgChoice elem : this.list){ - Log.print(" " + elem.getVal() + " : " + elem.getDescription()); - } - } else { - String tmpElementPrint = ""; - for (ArgChoice elem : this.list){ - if (!tmpElementPrint.isEmpty()) { - tmpElementPrint += " / "; - } - tmpElementPrint += elem.getVal(); - } - Log.print(" { " + tmpElementPrint + " }"); - } - } - } -} diff --git a/src/org/atriasoft/death/ArgElement.java b/src/org/atriasoft/death/ArgElement.java deleted file mode 100644 index 27903d0..0000000 --- a/src/org/atriasoft/death/ArgElement.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.atriasoft.death; - -import org.atriasoft.death.internal.Log; - -/** - * Single argument class. It permit to define the getted argument. - */ -public class ArgElement { - private final String option; - private final String arg; - /** - * Constructor. - * @param this Class handle - * @param option (string) Option name (write in fullmode ex{ '--verbose' even if user write '-v') - * @param value (string) Writed value by the user (defult '') - */ - public ArgElement(final String option, final String value) { - this.option = option; - this.arg = value; - } - /** - * Get the name of the argument{ (write in fullmode ex{ '--verbose' even if user write '-v') - * @param this Class handle - * @return (string) The argument name - */ - public String getOptionName(){ - return this.option; - } - - /** - * Get argument data set by the user - * @param this Class handle - * @return (string) The argument value - */ - public String getArg(){ - return this.arg; - } - - /** - * Display the Argument property - * @param this Class handle - */ - public void display() { - if (this.arg.isEmpty()) { - Log.info("option { " + this.option); - } else if ( this.option.isEmpty()) { - Log.info("element { " + this.arg); - }else{ - Log.info("option { " + this.option + "{" + this.arg); - } - } - -} diff --git a/src/org/atriasoft/death/ArgInterface.java b/src/org/atriasoft/death/ArgInterface.java deleted file mode 100644 index e636ba1..0000000 --- a/src/org/atriasoft/death/ArgInterface.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.atriasoft.death; - -/** - * Declare an argument value and store it in a parameter - */ -public interface ArgInterface { - boolean isParsable(); - /** - * Get the small name of the option ex{ '-v' - * @param this Class handle - * @return (string) Small name value - */ - public String getOptionSmall(); - - /** - * Get the big name of the option ex{ '--verbose' - * @param this Class handle - * @return (string) Big name value - */ - public String getOptionBig(); - - /** - * Get the status of getting user parameter value - * @param this Class handle - * @return true; The user must write a value - * @return false; The user must NOT write a value - */ - public boolean needParameters(); - /** - * Compatibility with @ref ArgSection class - * @param this Class handle - * @return (string) empty string - */ - public String getPorperties(); - - /** - * Check if the user added value is correct or not with the list of availlable value - * @param this Class handle - * @param argument (string) User parameter value (string) - * @return true; The parameter is OK - * @return false; The parameter is NOT Availlable - */ - public boolean checkAvaillable(final String argument); - /** - * Display the argument property when user request help - * @param this Class handle - */ - public void display() ; - - default boolean isOptionnal() { - return false; - } -} diff --git a/src/org/atriasoft/death/ArgSection.java b/src/org/atriasoft/death/ArgSection.java deleted file mode 100644 index 5aae7d2..0000000 --- a/src/org/atriasoft/death/ArgSection.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.atriasoft.death; - -import org.atriasoft.death.internal.Log; - -/** - * Section Class definition (permit to add a comment when requesting help - */ -public class ArgSection implements ArgInterface { - private final String description; - private final String section; - /** - * Constructor - * @param this Class handle - * @param sectionName (string) Name of the cestion ex{ "option" is displayed [option] - * @param desc (string) Comment assiciated with the group - */ - public ArgSection(final String sectionName, final String desc) { - this.section = sectionName; - this.description = desc; - } - public ArgSection(final String sectionName) { - this(sectionName,""); - } - public ArgSection() { - this(""); - } - @Override - public boolean isParsable(){ - return false; - } - /** - * Compatibility with @ref ArgDefine class - * @param this Class handle - * @return empty string - */ - @Override - public String getOptionSmall(){ - return ""; - } - - /** - * Compatibility with @ref ArgDefine class - * @param this Class handle - * @return empty string - */ - @Override - public String getOptionBig(){ - return ""; - } - - /** - * get property print value with the correct writing mode - * @param this Class handle - * @return String to display in the short line help - */ - @Override - public String getPorperties(){ - return " [" + this.section + "]"; - } - /** - * Display the argument property when user request help - * @param this Class handle - */ - @Override - public void display(){ - Log.print(" [" + this.section + "] { " + this.description); - } - @Override - public boolean needParameters() { - // TODO Auto-generated method stub - return false; - } - @Override - public boolean checkAvaillable(final String argument) { - // TODO Auto-generated method stub - return false; - } -} diff --git a/src/org/atriasoft/death/ArgVolatile.java b/src/org/atriasoft/death/ArgVolatile.java deleted file mode 100644 index e3f576d..0000000 --- a/src/org/atriasoft/death/ArgVolatile.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.atriasoft.death; - -import org.atriasoft.death.internal.Log; - -/** - * Declare an argument value and store it in a parameter - */ -public class ArgVolatile implements ArgInterface { - private final String destOption; - private final boolean optionnal; - private final String description; - private int count = 0; - - public ArgVolatile() { - this(""); - } - public ArgVolatile(final String destOption) { - this(destOption, false); - } - public ArgVolatile(final String destOption, final boolean optionnal) { - this(destOption, optionnal, ""); - } - /** - * Contructor. - * @param this Class handle - * @param destOption (string) Where to store the option name - * @param optionnal (bool) this element can be not present - * @param desc (string) user friendly description with this parameter (default "") - */ - public ArgVolatile(final String destOption, final boolean optionnal, final String desc ) { - this.destOption = destOption; - if (destOption.isEmpty()) { - Log.critical("volatil argument must be store in an argument name"); - } - this.optionnal = optionnal; - this.description = desc; - } - @Override - public boolean isParsable(){ - return false; - } - /** - * Get the small name of the option ex{ '-v' - * @param this Class handle - * @return (string) Small name value - */ - @Override - public String getOptionSmall(){ - return ""; - } - - /** - * Get the big name of the option ex{ '--verbose' - * @param this Class handle - * @return (string) Big name value - */ - @Override - public String getOptionBig(){ - return this.destOption; - } - - /** - * Get the status of getting user parameter value - * @param this Class handle - * @return true; The user must write a value - * @return false; The user must NOT write a value - */ - @Override - public boolean needParameters(){ - if (this.count == 0) { - this.count++; - return true; - } - return false; - } - /** - * Compatibility with @ref ArgSection class - * @param this Class handle - * @return (string) empty string - */ - @Override - public String getPorperties() { - return " [" + this.destOption + "]"; - } - - /** - * Check if the user added value is correct or not with the list of availlable value - * @param this Class handle - * @param argument (string) User parameter value (string) - * @return true; The parameter is OK - * @return false; The parameter is NOT Availlable - */ - @Override - public boolean checkAvaillable(final String argument){ - return true; - } - /** - * Display the argument property when user request help - * @param this Class handle - */ - @Override - public void display() { - Log.print(" [" + this.destOption + "]"); - if (this.optionnal) { - Log.print("(OPTIONNAL)"); - } - if (this.description != "") { - Log.print(" " + this.description); - } - } - @Override - public boolean isOptionnal() { - return this.optionnal; - } -} diff --git a/src/org/atriasoft/death/ArgumentManager.java b/src/org/atriasoft/death/ArgumentManager.java new file mode 100644 index 0000000..ba86980 --- /dev/null +++ b/src/org/atriasoft/death/ArgumentManager.java @@ -0,0 +1,229 @@ +package org.atriasoft.death; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.atriasoft.death.internal.Log; + +public class ArgumentManager { + private final List arguments = new ArrayList<>(); + private final List argumentResidual = new ArrayList<>(); + private final List argumentPostConfigure = new ArrayList<>(); + private String actionDetected = null; + private final PropertiesInterface properties; + private final boolean enableStoreConfig; + + public ArgumentManager(final String[] args, final Object tmp, final boolean enableStoreConfig) { + this.enableStoreConfig = enableStoreConfig; + for (int iii=0; iii actionClass = this.properties.getAction(this.actionDetected); + if (actionClass == null) { + return; + } + Object obj; + try { + obj = actionClass.getConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + ArgumentManager localManager = new ArgumentManager(this.argumentResidual.toArray(new String[0]), obj); + + //localManager.showHelp(); + int nbParameters = localManager.argumentPostConfigure.size(); + boolean findExecutor = false; + List executor = localManager.properties.getExecutor(); + for (Method exec : executor) { + if (nbParameters != exec.getParameterCount()) { + Log.warning("Rejected executor, " + exec.getName() + " nbParameter=" + exec.getParameterCount() + " require=" + nbParameters); + continue; + } + Log.warning("find executor, " + exec.getName()); + try { + switch(nbParameters) { + case 0: + exec.invoke(obj); + break; + case 1: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0)); + break; + case 2: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1)); + break; + case 3: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1), + localManager.argumentPostConfigure.get(2)); + break; + case 4: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1), + localManager.argumentPostConfigure.get(2), + localManager.argumentPostConfigure.get(3)); + break; + case 5: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1), + localManager.argumentPostConfigure.get(2), + localManager.argumentPostConfigure.get(3), + localManager.argumentPostConfigure.get(4)); + break; + case 6: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1), + localManager.argumentPostConfigure.get(2), + localManager.argumentPostConfigure.get(3), + localManager.argumentPostConfigure.get(4), + localManager.argumentPostConfigure.get(5)); + break; + case 7: + exec.invoke(obj, + localManager.argumentPostConfigure.get(0), + localManager.argumentPostConfigure.get(1), + localManager.argumentPostConfigure.get(2), + localManager.argumentPostConfigure.get(3), + localManager.argumentPostConfigure.get(4), + localManager.argumentPostConfigure.get(5), + localManager.argumentPostConfigure.get(6)); + break; + default: + Log.error("Does not manage more than 7 arguments"); + break; + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + public void showHelp() { + this.properties.displayHelp(); + } + + public boolean hasDetectedAction() { + return this.actionDetected != null; + } + + public boolean hasArgumentDetected() { + return this.argumentPostConfigure.size() != 0; + } + public List getArgumentDetected() { + return this.argumentPostConfigure; + } +} diff --git a/src/org/atriasoft/death/Arguments.java b/src/org/atriasoft/death/Arguments.java deleted file mode 100644 index d880f8f..0000000 --- a/src/org/atriasoft/death/Arguments.java +++ /dev/null @@ -1,299 +0,0 @@ -package org.atriasoft.death; - -import java.util.ArrayList; -import java.util.List; - -import org.atriasoft.death.internal.Log; - -/** - * Class to define the argument list available for a program - */ -public class Arguments { - private final List listProperties = new ArrayList<>(); - private List listElementStop = new ArrayList<>(); - private int lastElementParsed = 0; - - /** - * Constructor. - * @param this Class handle - */ - public Arguments(){ - } - public void add(){ - add(""); - } - public void add(final String smallOption){ - add(smallOption, ""); - } - public void add(final String smallOption, final String bigOption){ - add(smallOption, bigOption, new ArrayList<>()); - } - public void add(final String smallOption, final String bigOption, final List list){ - add(smallOption, bigOption, list, ""); - } - public void add(final String smallOption, final String bigOption, final List list, final String desc){ - add(smallOption, bigOption, list, desc, false); - } - /** - * Add a new argument possibilities... - * @param this Class handle - * @param smallOption (char) Value for the small option ex{ '-v' '-k' ... 1 single char element (no need of '-') - * @param bigOption (string) Value of the big option name ex{ '--verbose' '--kill' ... stated with -- and with the full name (no need of '--') - * @param list ([[string,string],...]) Optionnal list of availlable option{ '--mode=debug' ==> [['debug', 'debug mode'],['release', 'release the software']] - * @param desc (string) user friendly description with this parameter (default "") - * @param haveParam (bool) The option must have a parameter (default false) - */ - public ArgDefine add(final String smallOption, final String bigOption, final List list, final String desc, final boolean haveParam){ - ArgDefine tmp = new ArgDefine(smallOption, bigOption, list, desc, haveParam); - this.listProperties.add(tmp); - return tmp; - } - public void addArg(){ - addArg(""); - } - public void addArg(final String destOption){ - addArg(destOption, false); - } - public void addArg(final String destOption, final boolean optionnal){ - addArg(destOption, optionnal, ""); - } - public void addArg(final String destOption, final boolean optionnal, final String desc){ - this.listProperties.add(new ArgVolatile(destOption, optionnal, desc)); - } - /** - * Add section on argument list - * @param this Class handle - * @param sectionName (string) Name of the cestion ex{ "option" is displayed [option] - * @param sectionDesc (string) Comment assiciated with the group - */ - public void addSection(final String sectionName, final String sectionDesc){ - this.listProperties.add(new ArgSection(sectionName, sectionDesc)); - } - - public List parse(final List args) { - return parse(args, false); - } - - /** - * Parse the argument set in the command line - * @param this Class handle - * @param startPositionParsing position to start the parsing in the arguments - */ - public List parse(final List args, final boolean haveUnknowArgument) { - List listArgument = new ArrayList<>();// composed of list element - boolean notParseNextElement=false; - for (int iii=0; iii option.length()+1) { - optionParam = argument.substring(option.length()+1); - } - Log.verbose(" option= " + option); - Log.verbose(" optionParam= " + optionParam); - boolean argumentFound=false; - if (option.startsWith("--")){ - // big argument - for (ArgInterface prop :this.listProperties) { - if (!prop.isParsable()){ - continue; - } - if (prop.getOptionBig().isEmpty()){ - continue; - } - if (prop.getOptionBig().equals(option.substring(2))){ - // find it - Log.verbose("find argument 2 { " + option.substring(2)); - if (prop.needParameters()) { - String internalSub = option.substring(2+prop.getOptionBig().length()); - if (!internalSub.isEmpty()) { - if (!optionParam.isEmpty()){ - // wrong argument ... - Log.warning("maybe wrong argument for { '" + prop.getOptionBig() + "' cmdLine='" + argument + "'"); - prop.display(); - continue; - } - optionParam = internalSub; - } - if (optionParam.isEmpty()) { - // Get the next parameters - if (args.size() > iii+1) { - optionParam = args.get(iii+1); - notParseNextElement=true; - } else { - // missing arguments - Log.warning("parsing argument error { '" + prop.getOptionBig() + "' Missing { subParameters ... cmdLine='" + argument + "'"); - prop.display(); - System.exit(-1); - } - } - if (!prop.checkAvaillable(optionParam)){ - Log.warning("argument error { '" + prop.getOptionBig() + "' SubParameters not availlable ... cmdLine='" + argument + "' option='" + optionParam + "'"); - prop.display(); - System.exit(-1); - } - listArgument.add(new ArgElement(prop.getOptionBig(),optionParam)); - argumentFound = true; - } else { - if (!optionParam.isEmpty()) { - Log.warning("parsing argument error { '" + prop.getOptionBig() + "' need no subParameters { '" + optionParam + "' cmdLine='" + argument + "'"); - prop.display(); - } - listArgument.add(new ArgElement(prop.getOptionBig(), "")); - argumentFound = true; - } - break; - } - } - if (!argumentFound) { - if (!haveUnknowArgument) { - Log.error("UNKNOW argument { '" + argument + "'"); - } - } - } else if (option.startsWith("-")) { - // small argument - for (ArgInterface prop : this.listProperties) { - if (!prop.isParsable()){ - continue; - } - if (prop.getOptionSmall().isEmpty()){ - continue; - } - if (prop.getOptionSmall() == option.substring(1, 1+prop.getOptionSmall().length())) { - // find it - Log.verbose("find argument 1 { " + option.substring(1, 1+prop.getOptionSmall().length())); - if (prop.needParameters()) { - String internalSub = option.substring(1+prop.getOptionSmall().length()); - if (!internalSub.isEmpty()){ - if (!optionParam.isEmpty()) { - // wrong argument ... - Log.warning("maybe wrong argument for { '" + prop.getOptionBig() + "' cmdLine='" + argument + "'"); - prop.display(); - continue; - } - optionParam = internalSub; - } - if (optionParam.isEmpty()){ - // Get the next parameters - if (args.size() > iii+1) { - optionParam = args.get(iii+1); - notParseNextElement=true; - } else { - // missing arguments - Log.warning("parsing argument error { '" + prop.getOptionBig() + "' Missing { subParameters cmdLine='" + argument + "'"); - prop.display(); - System.exit(-1); - } - } - if (!prop.checkAvaillable(optionParam)) { - Log.warning("argument error { '" + prop.getOptionBig() + "' SubParameters not availlable ... cmdLine='" + argument + "' option='" + optionParam + "'"); - prop.display(); - System.exit(-1); - } - listArgument.add(new ArgElement(prop.getOptionBig(),optionParam)); - argumentFound = true; - }else{ - if (!optionParam.isEmpty()){ - Log.warning("parsing argument error { '" + prop.getOptionBig() + "' need no subParameters { '" + optionParam + "' cmdLine='" + argument + "'"); - prop.display(); - } - listArgument.add(new ArgElement(prop.getOptionBig(), "")); - argumentFound = true; - } - break; - } - } - } - if (!argumentFound) { - // small argument - for (ArgInterface prop : this.listProperties) { - if (prop.isParsable() || prop.getOptionBig().isEmpty()) { - continue; - } - if (prop.needParameters()) { - listArgument.add(new ArgElement(prop.getOptionBig(), argument)); - argumentFound = true; - break; - } - } - } - if (!argumentFound) { - // unknow element ... ==> just add in the list ... - Log.verbose("unknow argument { " + argument); - listArgument.add(new ArgElement("", argument)); - } - } - // for prop in this.list_properties{ - // Log.info(" opt=[" + prop.get_option_big() + "] parsable=" + str(prop.is_parsable())) - - // This is a real specific case in home user will have an help that is printed "help" - boolean helpIsRequest = false; - for ( ArgElement argument : listArgument) { - // argument.display() - if (argument.getOptionName().equals("help")) { - helpIsRequest = true; - } - } - - for (ArgInterface prop : this.listProperties) { - if (prop.isParsable() || prop.getOptionBig().isEmpty() ){ - continue; - } - if (prop.needParameters() && !prop.isOptionnal()) { - Log.critical("Missing argument{ [" + prop.getOptionBig() + "]");//, crash = (help_is_request==false)); - } - } - // for argument in list_argument{ - // argument.display() - // exit(0) - return listArgument; - } - - /** - * Stop parsing at a specific position - * @param this Class handle - * @param listOfElement List of element that stop the parsing - */ - public void setStopAt(final List listOfElement){ - this.listElementStop = listOfElement; - } - - /** - * get the last element parsed. - * @param this Class handle - */ - public int getLastParsed(){ - return this.lastElementParsed; - } - /** - * Display help on console output - * @param this Class handle - * @param actionName opation to set at the end of the application name - */ - public void display(final String actionName){ - Log.print("usage:"); - String listOfPropertiesArg = ""; - for (ArgInterface element : this.listProperties) { - listOfPropertiesArg += element.getPorperties(); - } - Log.print(" " + actionName + " " + listOfPropertiesArg + " ..."); - for (ArgInterface element : this.listProperties) { - element.display(); - } - } -} diff --git a/src/org/atriasoft/death/FieldProperty.java b/src/org/atriasoft/death/FieldProperty.java new file mode 100644 index 0000000..6abac47 --- /dev/null +++ b/src/org/atriasoft/death/FieldProperty.java @@ -0,0 +1,111 @@ +package org.atriasoft.death; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.atriasoft.death.internal.Log; + +public class FieldProperty { + + public Field field; + public String name; + public Character alias; + public String description; + public String[] choice; + public Class[] types; + + public FieldProperty(final Field elem) { + try { + this.name = ReflectTools.getName(elem); + this.alias = ReflectTools.getAlias(elem); + this.description = ReflectTools.getDescription(elem); + this.choice = ReflectTools.getChoice(elem); + this.types = ReflectTools.getTypeField(elem); + if (this.name == null && this.alias == null) { + this.field = null; + } + this.field = elem; + } catch (Exception e) { + this.name = null; + this.alias = null; + this.description = null; + this.choice = null; + Class[] types = null; + if (this.name == null && this.alias == null) { + this.field = null; + } + this.field = elem; + e.printStackTrace(); + } + } + public boolean isValid() { + return this.field != null; + } + public void print() { + if (this.name != null) { + Log.print("Detect element: --" + this.name); + } + if (this.alias != null) { + Log.print(" alias: -" + this.alias); + } + if (this.types[1] == null) { + Log.print(" type: " + this.types[0].getCanonicalName()); + } else { + Log.print(" type: " + this.types[0].getCanonicalName() + " / " + this.types[1].getCanonicalName()); + } + Log.print(" description: " + this.description); + if (this.choice != null) { + Log.print(" choice: " + Arrays.toString(this.choice)); + } + } + + public record ChoiceElement(String origin, String destination) {} + + List getChoiceList() { + List out = new ArrayList<>(); + for (String value : this.choice) { + String[] split = value.split(">>"); + if (split.length == 1) { + out.add(new ChoiceElement(split[0], null)); + } else { + out.add(new ChoiceElement(split[0], split[1])); + } + } + return out; + } + + public String convertChoice(final String newValue) { + if (this.choice == null) { + return newValue; + } + List available = getChoiceList(); + for (ChoiceElement elem : available) { + if (elem.destination == null) { + if (elem.origin.contentEquals(newValue)) { + return newValue; + } + } else { + if (elem.origin.contentEquals(newValue)) { + return elem.destination; + } + if (elem.destination.contentEquals(newValue)) { + return elem.destination; + } + } + } + String list = null; + for (ChoiceElement elem : available) { + if (list == null) { + list = "["; + } else { + list += ","; + } + list += elem; + } + list += "]"; + Log.critical("Can not find property '" + newValue + "'in the choice values : " + list); + return null; + } +} diff --git a/src/org/atriasoft/death/PropertiesInterface.java b/src/org/atriasoft/death/PropertiesInterface.java new file mode 100644 index 0000000..8640781 --- /dev/null +++ b/src/org/atriasoft/death/PropertiesInterface.java @@ -0,0 +1,277 @@ +package org.atriasoft.death; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.atriasoft.death.FieldProperty.ChoiceElement; +import org.atriasoft.death.internal.Log; + +public class PropertiesInterface { + final List properties = new ArrayList<>(); + ActionList actions = null; + final String classDescription; + final String classCommand; + final List executes = new ArrayList<>(); + + public List getExecutor() { + return this.executes; + } + + public Class getAction(final String action) { + if (this.actions == null) { + return null; + } + return this.actions.getInterface(action); + } + + public List parseFields() { + return this.properties; + } + public static String getCommand(final Class clazz) { + try { + return ReflectTools.getCommand(clazz); + } catch (Exception ex) { + // TODO Auto-generated catch block + ex.printStackTrace(); + } + return null; + } + public static String getDescription(final Class clazz) { + try { + return ReflectTools.getDescription(clazz); + } catch (Exception ex) { + // TODO Auto-generated catch block + ex.printStackTrace(); + } + return null; + } + + public PropertiesInterface(final Class clazz) { + // ------------------------------------------------------------------------ + // -- Find class description + // ------------------------------------------------------------------------ + this.classDescription = PropertiesInterface.getDescription(clazz); + this.classCommand = PropertiesInterface.getCommand(clazz); + // ------------------------------------------------------------------------ + // -- Find property Field + // ------------------------------------------------------------------------ + final Field[] fields = clazz.getFields(); + Log.verbose(" Fields: (" + fields.length + ")"); + for (final Field elem : fields) { + // we does not manage static field + if (Modifier.isStatic(elem.getModifiers())) { + try { + boolean subAction = ReflectTools.isSubAction(elem); + if (!subAction) { + continue; + } + Class[] type = ReflectTools.getTypeField(elem); + if (type[0] == ActionList.class) { + Object data = elem.get(null); + if (data == null) { + Log.error("set a @ArgSubActions on a wrong field"); + } else if (data instanceof ActionList tmp) { + this.actions = tmp; + } + } + } catch (Exception e) { + Log.error("get error on @ArgSubActions !!!"); + e.printStackTrace(); + } + continue; + } + // we does not manage private field + // NOTE: if the field is private I do not check the elements ==> the user want a private API !!! (maybe change ...) + if (!Modifier.isPublic(elem.getModifiers())) { + continue; + } + final FieldProperty element = new FieldProperty(elem); + if (!element.isValid()) { + continue; + } + if (element.types[0] == boolean.class + || element.types[0] == Boolean.class + || element.types[0] == int.class + || element.types[0] == Integer.class + || element.types[0] == short.class + || element.types[0] == Short.class + || element.types[0] == long.class + || element.types[0] == Long.class + || element.types[0] == float.class + || element.types[0] == Float.class + || element.types[0] == double.class + || element.types[0] == Double.class + || element.types[0] == String.class) { + // all is good + } else { + Log.error("Can not manage other type than: [boolean,Boolean,String,int,Integer,long,Long,short,Short,float,Float,double,Double]"); + } + this.properties.add(element); + //element.print(); + } + // ------------------------------------------------------------------------ + // -- find execution element + // ------------------------------------------------------------------------ + final Method[] methods = clazz.getMethods(); + for (final Method elem : methods) { + Log.verbose("Detect function : " + elem.getName()); + // we does not manage static field + if (Modifier.isStatic(elem.getModifiers())) { + continue; + } + // we does not manage private field + // NOTE: if the field is private I do not check the elements ==> the user want a private API !!! (maybe change ...) + if (!Modifier.isPublic(elem.getModifiers())) { + continue; + } + try { + if (ReflectTools.isExecutable(elem)) { + this.executes.add(elem); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public FieldProperty findFieldAlias(final char parameterName) { + for (FieldProperty elem : this.properties) { + if (elem.alias != null && elem.alias == parameterName) { + return elem; + } + } + return null; + } + public FieldProperty findField(final String parameterName) { + for (FieldProperty elem : this.properties) { + if (elem.name != null && elem.name.contentEquals(parameterName)) { + return elem; + } + } + return null; + } + + public boolean haveParameter(final FieldProperty field) { + if (field.types[0] == boolean.class || field.types[0] == Boolean.class) { + return false; + } + return true; + } + public boolean haveParameter(final String parameterName) { + FieldProperty field = findField(parameterName); + return haveParameter(field); + } + public boolean haveParameterAlias(final char parameterName) { + FieldProperty field = findFieldAlias(parameterName); + return haveParameter(field); + } + public boolean existParameter(final String parameterName) { + return findField(parameterName) != null; + } + public boolean existParameterAlias(final char parameterName) { + return findFieldAlias(parameterName) != null; + } + + public void setParameter(final Object tmp, final String parameter, String newValue) { + try { + FieldProperty property = findField(parameter); + newValue = property.convertChoice(newValue); + if (property.types[0] == boolean.class || property.types[0] == Boolean.class) { + //Boolean value = Boolean.valueOf(newValue); + //property.field.setBoolean(tmp, value); + property.field.setBoolean(tmp, true); + } else if (property.types[0] == int.class || property.types[0] == Integer.class) { + Integer value = Integer.valueOf(newValue); + property.field.setInt(tmp, value); + } else if (property.types[0] == short.class || property.types[0] == Short.class) { + Short value = Short.valueOf(newValue); + property.field.setShort(tmp, value); + } else if (property.types[0] == long.class || property.types[0] == Long.class) { + Long value = Long.valueOf(newValue); + property.field.setLong(tmp, value); + } else if (property.types[0] == float.class || property.types[0] == Float.class) { + Float value = Float.valueOf(newValue); + property.field.setFloat(tmp, value); + } else if (property.types[0] == double.class || property.types[0] == Double.class) { + Double value = Double.valueOf(newValue); + property.field.setDouble(tmp, value); + } else if (property.types[0] == String.class) { + property.field.set(parameter, newValue); + } else { + // Impossible case !!! + Log.critical("Dead code"); + } + } catch (IllegalArgumentException | IllegalAccessException e) { + // TODO Auto-generated catch block + Log.critical("Can not SET the value : " + parameter + " : " + newValue); + } + + } + public void setParameterAlias(final Object tmp, final char parameter, final String newValue) { + FieldProperty property = findFieldAlias(parameter); + setParameter(tmp, property.name, newValue); + } + + public void displayHelp() { + Log.print("Usage:"); + String applicationLine = " "; + if (this.classCommand != null) { + applicationLine += this.classCommand + " "; + } else { + applicationLine += "XXX "; + } + if (this.properties.size() != 0) { + applicationLine += "[options] "; + } + if (this.actions != null && this.actions.getActions().size() != 0) { + applicationLine += "[actions] ..."; + } + Log.print(applicationLine); + if (this.classDescription != null) { + Log.print("" + this.classDescription); + } + if (this.properties.size() != 0) { + Log.print(" [options]"); + for (FieldProperty prop : this.properties) { + String parameterExpect = haveParameter(prop) ? " [PARAMETER]" : ""; + if (prop.alias != null && prop.name != null) { + Log.print(" -" + prop.alias + " / --" + prop.name + parameterExpect); + } else if (prop.alias != null) { + Log.print(" -" + prop.alias + parameterExpect); + } else if (prop.name != null) { + Log.print(" --" + prop.name + parameterExpect); + } + if (prop.description != null) { + Log.print(" " + prop.description); + } + if (prop.choice != null) { + for (ChoiceElement elem: prop.getChoiceList()) { + if (elem.destination() == null) { + Log.print(" - " + elem.origin()); + } else { + Log.print(" - " + elem.origin() + " ==> " + elem.destination()); + } + } + } + } + } + if (this.actions != null && this.actions.getActions().size() != 0) { + Log.print(" [actions]"); + Set actions = this.actions.getActions(); + for (String action : actions) { + Class clazz = this.actions.getInterface(action); + String description = PropertiesInterface.getDescription(clazz); + if (description == null || description.isEmpty()) { + Log.print(" " + action); + } else { + Log.print(" " + action + ": " + description ); + } + } + } + } +} diff --git a/src/org/atriasoft/death/ReflectTools.java b/src/org/atriasoft/death/ReflectTools.java new file mode 100644 index 0000000..87a8acd --- /dev/null +++ b/src/org/atriasoft/death/ReflectTools.java @@ -0,0 +1,200 @@ +package org.atriasoft.death; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; + +import org.atriasoft.death.annotation.ArgAlias; +import org.atriasoft.death.annotation.ArgChoice; +import org.atriasoft.death.annotation.ArgCommand; +import org.atriasoft.death.annotation.ArgDescription; +import org.atriasoft.death.annotation.ArgExecute; +import org.atriasoft.death.annotation.ArgName; +import org.atriasoft.death.annotation.ArgParams; +import org.atriasoft.death.annotation.ArgSample; +import org.atriasoft.death.annotation.ArgSubActions; +import org.atriasoft.death.internal.Log; + +public class ReflectTools { + private ReflectTools() {} + + public static Class[] getTypeField(final Field fieldDescription) { + Class type = fieldDescription.getType(); + Class subType = null; + Type empppe = fieldDescription.getGenericType(); + if (empppe instanceof ParameterizedType plopppppp) { + Type[] realType = plopppppp.getActualTypeArguments(); + if (realType.length > 0) { + try { + subType = Class.forName(realType[0].getTypeName()); + } catch (ClassNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + return new Class[] {type, subType}; + } + + + public static Class[] getTypeReturnFunction(/*@NotNull*/ final Method getter) throws Exception { + Class type = null; + Class subType = null; + type = getter.getReturnType(); + if (!Enum.class.isAssignableFrom(type)) { + Type empppe = getter.getGenericReturnType(); + if (empppe instanceof ParameterizedType plopppppp) { + Type[] realType = plopppppp.getActualTypeArguments(); + if (realType.length > 0) { + subType = Class.forName(realType[0].getTypeName()); + } + } + } + return new Class[] {type, subType}; + } + + public static Class[] getTypeParameterfunction(final Method setter) throws Exception { + Class type = null; + Class subType = null; + + type = setter.getParameters()[0].getType(); + if (List.class.isAssignableFrom(type)) { + Class internalModelClass = null; + Type[] empppe = setter.getGenericParameterTypes(); + if (empppe.length > 0) { + if (empppe[0] instanceof ParameterizedType plopppppp) { + Type[] realType = plopppppp.getActualTypeArguments(); + if (realType.length > 0) { + Log.warning(" -->> " + realType[0]); + internalModelClass = Class.forName(realType[0].getTypeName()); + } + } + } + subType = internalModelClass; + } + return new Class[] {type, subType}; + } + + public static Class[] getTypeParameterfunction(final Constructor elem, final int paramId) throws ClassNotFoundException { + Class type = null; + Class subType = null; + + type = elem.getParameters()[paramId].getType(); + if (List.class.isAssignableFrom(type)) { + Class internalModelClass = null; + Type[] empppe = elem.getGenericParameterTypes(); + if (empppe.length > paramId) { + if (empppe[paramId] instanceof ParameterizedType plopppppp) { + Type[] realType = plopppppp.getActualTypeArguments(); + //Log.info("ppplllppp: " + realType.length); + if (realType.length > 0) { + Log.warning(" -->> " + realType[0]); + internalModelClass = Class.forName(realType[0].getTypeName()); + } + } + } + subType = internalModelClass; + } + return new Class[] {type, subType}; + } + + public static Character getAlias(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgAlias.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgAlias on " + element.getClass().getCanonicalName()); + } + return ((ArgAlias) annotation[0]).value(); + } + + public static String[] getChoice(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgChoice.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgChoice on " + element.getClass().getCanonicalName()); + } + return ((ArgChoice) annotation[0]).value(); + } + public static String getDescription(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgDescription.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgDescription on " + element.getClass().getCanonicalName()); + } + return ((ArgDescription) annotation[0]).value(); + } + public static String getDescription(final Class clazz) throws Exception { + final Annotation[] annotation = clazz.getDeclaredAnnotationsByType(ArgDescription.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgDescription on " + clazz.getCanonicalName()); + } + return ((ArgDescription) annotation[0]).value(); + } + public static String getName(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgName.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgName on " + element.getClass().getCanonicalName()); + } + return ((ArgName) annotation[0]).value(); + } + public static String getCommand(final Class clazz) throws Exception { + final Annotation[] annotation = clazz.getDeclaredAnnotationsByType(ArgCommand.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgCommand on " + clazz.getCanonicalName()); + } + return ((ArgCommand) annotation[0]).value(); + } + public static String[] getParams(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgParams.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgParams on " + element.getClass().getCanonicalName()); + } + return ((ArgParams) annotation[0]).value(); + } + public static String[] getSample(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgSample.class); + if (annotation.length == 0) { + return null; + } + if (annotation.length > 1) { + throw new Exception("Must not have more than 1 element @ArgSample on " + element.getClass().getCanonicalName()); + } + return ((ArgSample) annotation[0]).value(); + } + public static boolean isSubAction(final Field element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgSubActions.class); + if (annotation.length == 0) { + return false; + } + return true; + } + public static boolean isExecutable(final Method element) throws Exception { + final Annotation[] annotation = element.getDeclaredAnnotationsByType(ArgExecute.class); + if (annotation.length == 0) { + return false; + } + return true; + } +} diff --git a/src/org/atriasoft/death/annotation/ArgAlias.java b/src/org/atriasoft/death/annotation/ArgAlias.java new file mode 100644 index 0000000..dbd0c50 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgAlias.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgAlias { + /** + * Short argument of this value (-n) (Without -) + * @return The short argument + */ + char value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgChoice.java b/src/org/atriasoft/death/annotation/ArgChoice.java new file mode 100644 index 0000000..faaf609 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgChoice.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgChoice { + /** + * List of available value with a transcription of type like : "warning>>45" ==> "45" and "warning" are both available, and warning is transformed in 45 when detected. + * @return list of available values + */ + String[] value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgCommand.java b/src/org/atriasoft/death/annotation/ArgCommand.java new file mode 100644 index 0000000..6697e65 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgCommand.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgCommand { + /** + * Short argument of this value (-n) (Without -) + * @return The short argument + */ + String value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgDescription.java b/src/org/atriasoft/death/annotation/ArgDescription.java new file mode 100644 index 0000000..eedcfdc --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgDescription.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target({ ElementType.FIELD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgDescription { + /** + * Short argument of this value (-n) (Without -) + * @return The short argument + */ + String value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgExecute.java b/src/org/atriasoft/death/annotation/ArgExecute.java new file mode 100644 index 0000000..411bf3b --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgExecute.java @@ -0,0 +1,17 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgExecute { + +} diff --git a/src/org/atriasoft/death/annotation/ArgName.java b/src/org/atriasoft/death/annotation/ArgName.java new file mode 100644 index 0000000..639f59b --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgName.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target( ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgName { + /** + * Names of the argument (--NyBeautifullName) (Without --) + * @return The name of the argument + */ + String value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgParams.java b/src/org/atriasoft/death/annotation/ArgParams.java new file mode 100644 index 0000000..32e2988 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgParams.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgParams { + /** + * Names of the argument of the function + * @return The names of the arguments + */ + String[] value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgParamsDescription.java b/src/org/atriasoft/death/annotation/ArgParamsDescription.java new file mode 100644 index 0000000..7beca67 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgParamsDescription.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgParamsDescription { + /** + * Names of the argument of the function + * @return The names of the arguments + */ + String[] value(); + +} diff --git a/src/org/atriasoft/death/annotation/ArgSample.java b/src/org/atriasoft/death/annotation/ArgSample.java new file mode 100644 index 0000000..e3f2d0a --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgSample.java @@ -0,0 +1,21 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that can be used to define an other name of the attribute or the Element name. + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgSample { + /** + * All sample available for the specific Command + * @return Descriptive string of the commands samples + */ + String[] value(); +} \ No newline at end of file diff --git a/src/org/atriasoft/death/annotation/ArgSubActions.java b/src/org/atriasoft/death/annotation/ArgSubActions.java new file mode 100644 index 0000000..e5b6bc9 --- /dev/null +++ b/src/org/atriasoft/death/annotation/ArgSubActions.java @@ -0,0 +1,13 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target( ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@DepthArgAnnotation +public @interface ArgSubActions { + +} diff --git a/src/org/atriasoft/death/annotation/DepthArgAnnotation.java b/src/org/atriasoft/death/annotation/DepthArgAnnotation.java new file mode 100644 index 0000000..218bfb4 --- /dev/null +++ b/src/org/atriasoft/death/annotation/DepthArgAnnotation.java @@ -0,0 +1,20 @@ +package org.atriasoft.death.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Meta-annotation (annotations used on other annotations) + * used for marking all annotations that are + * part of Death package. Can be used for recognizing all + * Death annotations generically, and in future also for + * passing other generic annotation configuration. + */ +@Target(ElementType.ANNOTATION_TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DepthArgAnnotation { + // for now, a pure tag annotation, no parameters + +} \ No newline at end of file