[DEV] rework the whole library

This commit is contained in:
Edouard DUPIN 2021-09-23 23:55:12 +02:00
parent 1be1359bb6
commit 3545a5fb42
24 changed files with 1069 additions and 786 deletions

View File

@ -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;

View File

@ -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<String, Class<?>> 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<String> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<ArgChoice> 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<ArgChoice> list) {
this (smallOption, bigOption, list, "", false);
}
public ArgDefine(final String smallOption, final String bigOption, final List<ArgChoice> 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<ArgChoice> 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 + " }");
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<String> arguments = new ArrayList<>();
private final List<String> argumentResidual = new ArrayList<>();
private final List<String> 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<args.length; iii++) {
this.arguments.add(args[iii]);
}
this.properties = new PropertiesInterface(tmp.getClass());
if (this.enableStoreConfig) {
}
configure(tmp);
if (this.enableStoreConfig) {
}
}
public ArgumentManager(final String[] args, final Object tmp) {
this(args, tmp, false);
}
private void configure(final Object tmp) {
boolean endParsing = false;
for (int iii=0; iii<this.arguments.size(); iii++) {
String value = this.arguments.get(iii);
if (endParsing) {
this.argumentResidual.add(value);
continue;
}
if (value.startsWith("--")) {
String[] elements = value.split("=");
elements[0] = elements[0].substring(2);
Log.warning("find element (--) : " + Arrays.toString(elements));
String parameter = elements[0];
String newValue = null;
if (!this.properties.existParameter(parameter)) {
Log.critical("Parameter Does not exist for '" + value + "'");
}
if (!this.properties.haveParameter(parameter)) {
// Boolean value
if (elements.length != 1) {
Log.critical("Boolean parameter can not have parameters for '" + value + "'");
}
} else if (elements.length == 1) {
if (iii==this.arguments.size()-1) {
Log.critical("Missing parameters for '" + value + "' (no more arguments)");
}
newValue = this.arguments.get(iii+1);
if (newValue.startsWith("-")) {
Log.critical("Missing parameters for '" + value + "' (next argument is a parameter (start with '-'))");
}
iii++;
} else if (elements.length == 2) {
newValue = elements[1];
} else {
Log.critical("too much parameters for '" + value + "' (only 1 = is authorized)");
}
this.properties.setParameter(tmp, parameter, newValue);
} else if (value.startsWith("-")) {
String[] elements = value.split("=");
elements[0] = elements[0].substring(1);
Log.warning("find element (-) : " + Arrays.toString(elements));
if (elements[0].length() != 1) {
Log.critical("Can not parse alias argument with a size != 1 for '" + value + "'");
}
char parameter = elements[0].charAt(0);
String newValue = null;
if (!this.properties.existParameterAlias(parameter)) {
Log.critical("Parameter Does not exist for '" + value + "'");
}
if (!this.properties.haveParameterAlias(parameter)) {
// Boolean value
if (elements.length != 1) {
Log.critical("Boolean parameter can not have parameters for '" + value + "'");
}
} else if (elements.length == 1) {
if (iii==this.arguments.size()-1) {
Log.critical("Missing parameters for '" + value + "' (no more arguments)");
}
newValue = this.arguments.get(iii+1);
if (newValue.startsWith("-")) {
Log.critical("Missing parameters for '" + value + "' (next argument is a parameter (start with '-'))");
}
iii++;
} else if (elements.length == 2) {
newValue = elements[1];
} else {
Log.critical("too much parameters for '" + value + "' (only 1 = is authorized)");
}
this.properties.setParameterAlias(tmp, parameter, newValue);
} else {
Log.warning("find element ( ) : " + value);
if (this.properties.actions!= null && this.properties.actions.exist(value)) {
// Find end of parsing ...
endParsing = true;
this.actionDetected = value;
continue;
}
this.argumentPostConfigure.add(value);
}
}
}
public void executeAction() {
if (this.actionDetected == null) {
return;
}
Class<?> 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<Method> 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<String> getArgumentDetected() {
return this.argumentPostConfigure;
}
}

View File

@ -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<ArgInterface> listProperties = new ArrayList<>();
private List<String> 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<ArgChoice> list){
add(smallOption, bigOption, list, "");
}
public void add(final String smallOption, final String bigOption, final List<ArgChoice> 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<ArgChoice> 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<ArgElement> parse(final List<String> 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<ArgElement> parse(final List<String> args, final boolean haveUnknowArgument) {
List<ArgElement> listArgument = new ArrayList<>();// composed of list element
boolean notParseNextElement=false;
for (int iii=0; iii <args.size(); iii++){
this.lastElementParsed = iii;
// special case of parameter in some elements
if ( notParseNextElement) {
notParseNextElement = false;
continue;
}
Log.verbose("parse [" + iii + "]=" + args.get(iii));
String argument = args.get(iii);
// check if we get a stop parsing element{
if (this.listElementStop.contains(argument)) {
Log.debug("stop at position{ " + iii);
listArgument.add(new ArgElement("", argument));
break;
}
String[] optionList = argument.split("=");
Log.verbose("ListArgument = " + optionList);
String option = optionList[0];
String optionParam = "";
if (argument.length() > 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<String> 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();
}
}
}

View File

@ -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<ChoiceElement> getChoiceList() {
List<ChoiceElement> 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<ChoiceElement> 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;
}
}

View File

@ -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<FieldProperty> properties = new ArrayList<>();
ActionList actions = null;
final String classDescription;
final String classCommand;
final List<Method> executes = new ArrayList<>();
public List<Method> getExecutor() {
return this.executes;
}
public Class<?> getAction(final String action) {
if (this.actions == null) {
return null;
}
return this.actions.getInterface(action);
}
public List<FieldProperty> 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<String> 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 );
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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 {
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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 {
}

View File

@ -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
}