Skip unknown command line arguments - java

In a current application I have, the incoming command line parameters are parsed on several "levels".
At the highest level I only wish to parse some options and leave the rest to "lower levels". however, all libraries I've tried so far (Common Cli, args4j, JOpt, gnu.jargs) al throw an "unknown option" exception when I'm trying to feed them, well, unknown options.
I really don't want to write a yet another command line parsing class. Is there a library/class that parses these options and skips over unknown options?
Thank you

There is a better solution.
public static BiFunction<String[],CmdLineParser,String[]> stripUnusedArgs=(args,parser)->{
List<String> accepteds=parser.getOptions().stream().map(opt->opt.option.toString()).collect(Collectors.toList());
List<String> stripedArgs=new ArrayList<>();
for(int i=0; i< args.length;i++){
if(accepteds.contains(args[i])){
stripedArgs.add(args[i]);
stripedArgs.add(args[i+1]);
}
}
return stripedArgs.toArray(new String[0]);
};
And then to use it:
CmdLineParser parser = new CmdLineParser(CustomArgsObject);
stripUnusedArgs.apply(args,parser);

jopt lets you specify a default value. No exception is thrown.
parser.accepts("count").withOptionalArg().ofType(Integer.class).defaultsTo(-1);

In case of Args4j I think the SubCommandHandler could be just good enough. https://args4j.kohsuke.org/apidocs/org/kohsuke/args4j/spi/SubCommandHandler.html

Related

How to get requestUri out of Cocoon into my Java function?

I inherited some old Cocoon code, if it's obvious, please tell me where in the docs I could find it.
I have a function to clean up some page parameters. I want to hand over the content to that function, but I can't manage to get there.
This is the original code, the value must pass my "cleanPath" function.
<jdbp:page-param name="pageToLoad" value="${{request.requestURI}}/../{#page}"/>
Attempt 1:
<jdbp:page-param name="pageToLoad" value="cleanPath(${{request.requestURI}}/../{#page})"/>
My attempt was to add the function in and leave everything like that, but it's not working.
My next attempt is these nice xsp:logic blocks, where I can't get the requestURI. "request.requestURI" is unknown, evaluate complains
"Type mismatch: cannot convert from Object to String".
<xsp:logic>
String input2 = evaluate("${{request.requestURI}}", String.class);
String input = "/../<xsl:value-of select="#page"/>";
putVariable("Hase","Test "+input);
</xsp:logic>
<jdbp:page-param name="pageToLoad" value="${{request.requestURI}}/../{#page}"/>
<jdbp:page-param name="Hase" value="${{Hase}}"/>
It's easy to just call request.getRequestURI();. No need for complicated wrappers.

Why my list is empty when I am parsing correct json response?

I am trying to print the ids from a JSON response. But I am not able to understand why I am getting a blank list. I have verified the JSONpath (SECTIONS_IDS_JSONPATH) from the online website and it is giving me correct results.
public static void main(String[] args) {
String SECTIONS_IDS_JSONPATH = "$.[*].instructionEvents[*].sectionId";
String sectionsData = "{\"sections\":[{\"id\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":0,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[],\"instructionEvents\":[{\"id\":\"9d0c49e2-1579-43c3-b25a-2f85f551e62d\",\"sectionId\":\"8da1cf5d-3150-4e11-b2af-338d1df20475\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-01-01T09:45:00-05:00\",\"endTm\":\"2024-12-01T10:45:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"c26572de-f9c8-4623-ba6a-79997b33f1c6\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"role\":\"primary\",\"persons\":[{\"id\":\"c1b50d79-5505-4a33-9316-b4b1f52c0ca3\",\"names\":[{\"firstName\":\"BanColoFac-1\",\"lastName\":\"CTester\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"af8fb500-29f5-4451-95d5-a11215298cd4\",\"sectionId\":\"ad3f63ad-e642-4938-a9fd-318afd2d1ad0\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]},{\"id\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"courseCredits\":[{\"minimum\":4,\"maximum\":null,\"measure\":\"hour\",\"increment\":null}],\"academicPeriodId\":\"8b7a8e9e-5417-42a3-9c90-8d47226b5987\",\"reservedSeatsMaximum\":0,\"maxEnrollment\":20,\"hours\":[],\"sites\":[\"All Campuses\"],\"instructors\":[{\"id\":\"808daae1-3ec6-47ec-9af0-5392199bdf78\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"role\":\"primary\",\"persons\":[{\"id\":\"793cc9b3-57c7-4a2d-8984-07a1fb6834a9\",\"names\":[{\"firstName\":\"Andrew\",\"lastName\":\"Adams\",\"preferred\":true}]}]}],\"instructionEvents\":[{\"id\":\"730b4206-684d-4413-bf20-9bec5c1dc900\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"tuesday\",\"thursday\"],\"startTm\":\"2019-01-01T10:00:00-05:00\",\"endTm\":\"2024-12-01T10:50:00-05:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"},{\"id\":\"8bc059ab-a8f8-4469-8e79-bbc71f7fa3fd\",\"sectionId\":\"a1422391-e2b9-4bc4-907b-371fcea01d70\",\"courseId\":\"e8a65581-ed1c-43f0-90a7-7b9d51b35062\",\"days\":[\"monday\",\"wednesday\",\"friday\"],\"startTm\":\"2019-05-26T09:00:00-04:00\",\"endTm\":\"2021-05-26T09:50:00-04:00\",\"localizations\":[],\"instructionalMethod\":\"Lecture\"}]}]}";
List<String> ids = JsonPath.parse(sectionsData).read(SECTIONS_IDS_JSONPATH);
System.out.println(ids);
}
Alright, since this question might get delete if nothing else ever happens I better post this as an answer.
As explained by Andreas you should use JSONPath $.*[*].instructionEvents[*].sectionId instead. Quoting fromt the comment
The syntax $.[*] is undefined, I can't find any documentation/example
doing that. The JSONPath Online Evaluator [*based on
JSONPath-Plus implemented in JavaScript] treats it as $..[*], but the Java library treats
it differently. Since the outer part of the JSON is {"sections":[ ... ]}, you have an object, so you need a property selector (.prop or
.*). Once you've selected your property (.sections, or .*
since there's only one), the property is an array, so you need an
array selector ([2] or [*]). Hence you can use $.sections[*] or
$.*[*] to match all sections.
Indeed, looking at this massive JSONPath Comparision we can see that the syntax in question is not listed for any implementation.

Dealing with command line options in a typesafe manner, after parsing with JOpts

When parsing options with the JOpt Simple library, the only way I know of accessing their respective types is by saving the OptionSpec instances somewhere and accessing them latter. For example:
OptionParser parser = new OptionParser();
ArgumentAcceptingOptionSpec<Path> pathOption = parser
.acceptsAll(Arrays.asList("p", "path"),
"Read message from a file")
.withRequiredArg()
.withValuesConvertedBy(new PathConverter());
/* We will use this one latter */
OptionSpec<Path> pathOptionSpec = pathOption;
OptionSet parsedOptions = parser.parse("-path", "./foo/bar");
/*
See? Unless I missed something, you need the pathOptionSpec object
(which is of type OptionSpec<Path>) to retrieve the "path"'s option type.
If I used .valueOf("path"), it would return
an OptionSet<?> and I would have to typecast it!
*/
assertThat(
parsedOptions.valueOf(pathOptionSpec),
instanceOf(OptionSpec<Path>.class));
Now, what I did was saving the OptionParser, the OptionSet and every OptionSpec as static members of the Main class, and access those options from anywhere in the program (you may now screech and raise your pitchforks now).
Is there a clean way to manage parsed CLI arguments in a typesafe way?

How to compare a element in String array in Android?

I have a String array as follows:
String [] str_cmd_arr={"cmd1", "cmd2"};
Given that, "cmd1" will output "perform command 1", while "cmd2" will output "perform command 2".
From my str_cmd_arr, how can I print the outputs individually in Java/Android? Currently, I am using this code
for (int i=0;i<str_cmd_arr.length;i++){
if(i<1){
Log.d("TAG","perform command 1");
}
else{
Log.d("TAG","perform command 2");
}
}
The real solution here: use a Map, like
Map<String, String> commandsAndOutput = new HashMap<>();
commandsAndOutput.put("cmd1", "cmd1 output");
...
to later do
String output = commandsAndOutput.get("cmd1");
for example.
Another, probably more sane way here: consider using enums, like:
public enum Command {
CMD1, CMD2;
}
if you are looking for more "compile time" support when making choices between different commands. As you now can write down:
Command cmd = ...
switch(cmd) {
case(CMD1) : ...
But another word of warning: one should be careful about such enum/switching code. In most situations, a "real OO based" design that works with an abstract base class Command and specific subclasses is the better choice.
The real lesson here: you want to study some basics, like the tutorials found here. You see, there is no point in programming for Android ... if you don't know about such basic things such as Maps. In that sense it is hard to give you "good" advise, as the "good" stuff is that abstract base class solution - which seems to be completely beyond your current skills.
Replace your if statement with
if(str_cmd_arr[i]).equals("cmd1"){
You can use a loop and a switch statement
for example
for (int i=0;i<str_cmd_arr.length;i++){
switch(str_cmd_arr[i]) {
case "cmd1":
Log.d("TAG","perform command 1");
break;
case "cmd2":
Log.d("TAG","perform command 2");
break;
}
}

Debugging parse error

I am getting a parse error at line 1 column 29.
if (xpath:{Path for file location}.equals("xname")) {
workflow.setVariable("variable);
workflow.setVariable("variable);
([column1]
,[column2]
,[column2])
VALUES
(xpath:{}
,'xpath:{}'
,'xpath:{}'
) );
}
What do I need to do to fix this?
If I had to guess, I'd say it's due to the misspelled "locaiton" in your path.
If this is Java code, there are several things wrong with it:
The xpath:{/workflow/variables/locaiton} construct is something that doesn't exist in Java. It's invalid syntax. See this tutorial for more information.
The SQL Statement should be put inside double quotes

Categories

Resources