Java commons cli parser not recognizing command line arguments - java

This should be very simple but I am not sure why its not working. I am trying pass arguments with a name (So I can pass arguments in any order) using the apache commons CLI library but It seems to be not working. I want to pass the arguments from eclipse IDE. I know this part is not the problem because I am able to print the arguments with args[0] kind.
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public class MainClass {
public static void main(String[] args) throws ParseException {
System.out.println(args[0]);
Options options = new Options();
options.addOption("d", false, "add two numbers");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse( options, args);
if(cmd.hasOption("d")) {
System.out.println("found d");
} else {
System.out.println("Not found");
}
}
The above lines are exactly like the examples given online but i dont know why its not working. I am struggling this from a day now. Please help where I am going wrong.

According to the examples name of the parameter should be present in command line
Property without value
Usage: ls [OPTION]... [FILE]...
-a, --all do not hide entries starting with .
And the respective code is:
// create the command line parser
CommandLineParser parser = new DefaultParser();
// create the Options
Options options = new Options();
options.addOption( "a", "all", false, "do not hide entries starting with ." );
In this scenario correct call is:
ls -a or ls --all
With value separated by space
-logfile <file> use given file for log
Respective code is:
Option logfile = OptionBuilder.withArgName( "file" )
.hasArg()
.withDescription( "use given file for log" )
.create( "logfile" );
And call would be:
app -logfile name.of.file.txt
With value separated by equals
-D<property>=<value> use value for given property
The code is:
Option property = OptionBuilder.withArgName( "property=value" )
.hasArgs(2)
.withValueSeparator()
.withDescription( "use value for given property" )
.create( "D" );
And call would be:
app -Dmyprop=myvalue

Related

Automatically handling / ignoring NameError in Jython

I have a setup where I execute jython scripts from a Java application. The java application feed the jython script with variables, coming from the command line, so that a user can write the following code in it's jython script:
print("Hello, %s" % foobar)
And will call the java program with this:
$ java -jar myengine.jar script.py --foobar=baz
Hello, baz
My java application parse the command-line, and create a variable of that name with the given value to give to the jython scripting environment to consume. All is well so far.
My issue is that when the user does not provide the foobar command-line parameter, I'd like to be able to easily provide a fallback in my script. For now, the user needs to write that sort of code to handle the situation where the foobar parameter is missing from the command-line:
try: foobar
except NameError: foobar = "some default value"
But this is cumbersome, especially if the number of parameters is growing. Is there a way to handle that better from the script user point of view?
I was thinking of catching the jython NameError in the Java code, initializing the variable causing the exception to a default value if the variable causing the exception "looks like" a parameter (adding a naming convention is OK), and restarting where the exception occurred. Alternatively, I can require the script user to write code such as this:
parameter(foobar, "some default value")
Or something equivalent.
Well, this is one ugly workaround I found so far. Be careful, as this will call the script in loop many times, and is O(n^2).
private void callScriptLoop(String scriptfile) {
PythonInterpreter pi = new PythonInterpreter();
pi.set("env", someEnv);
int nloop = 0;
boolean shouldRestart;
do {
shouldRestart = false;
try {
pi.execfile(scriptfile);
} catch (Throwable e) {
if (e instanceof PyException) {
PyException pe = (PyException) e;
String typ = pe.type.toString();
String val = pe.value.toString();
Matcher m = Pattern.compile("^name '(.*)' is not defined")
.matcher(val);
if (typ.equals("<type 'exceptions.NameError'>")
&& m.find()) {
String varname = m.group(1);
pi.set(varname, Py.None);
System.out.println(
"Initializing missing parameter '"
+ varname + "' to default value (None).");
shouldRestart = true;
nloop++;
if (nloop > 100)
throw new RuntimeException(
"NameError handler infinite loop detected: bailing-out.");
}
}
if (!shouldRestart)
throw e;
}
} while (shouldRestart);
}

how to get details of the pl sql package after parsing in java

I have a pkb file. It contain a package and under that package it has multiple functions.
I have to get the following details out of it:
package name
function names (for all functions one by one)
params in function
return type of function
Approach: I am parsing the pkb file. I have taken the grammar from these sources:
Presto
Antlrv4 Grammer for plsql
After getting these grammar I downloaded the jar from antlr-4.5.3-complete.jar. Then using
java -cp org.antlr.v4.Tool grammar.g
one by one I execute this command on these grammars separately to generate listener, lexer, parser and other files.
After this I created two project in eclipse one for each grammar. I imported these generated file into the respective and set antlr-4.5.3-complete.jar file into the path. After this I used following code to check if my .pkb file is correct or not?
public static void parse(String file) {
try {
SqlBaseLexer lex = new SqlBaseLexer(new org.antlr.v4.runtime.ANTLRInputStream(file));
CommonTokenStream tokens = new CommonTokenStream(lex);
SqlBaseParser parser = new SqlBaseParser(tokens);
System.err.println(parser.getNumberOfSyntaxErrors()+" Errors");
} catch (RecognitionException e) {
System.err.println(e.toString());
} catch (java.lang.OutOfMemoryError e) {
System.err.println(file + ":");
System.err.println(e.toString());
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.err.println(file + ":");
System.err.println(e.toString());
}
}
I am not getting any error in parsing the file.
But after this I am stuck with next steps. I need to get all the package name, functions, params etc.
How to get these details?
Also is my approach is correct to attain the required output.
The Presto grammar is a generic SQL grammar which is not suitable for parsing Oracle packages. The ANTLRv4 grammar for PL/SQL is the right tool for your task.
Generally an ANTLR grammar as such works as a validator. When you want to make some additional processing while parsing you should use ANTLR actions (see overview slide in this presentation). These are blocks of text written in the target language (e.g. Java) and enclosed in curly braces (see documentation).
There are at least two ways to solve your task with ANTLR actions.
Stdout output
The simplest way is to add println()s for certain rules.
To print package name modify package_body rule in plsql.g4 as follows:
package_body
: BODY package_name (IS | AS) package_obj_body*
(BEGIN seq_of_statements | END package_name?)
{System.out.println("Package name is "+$package_name.text);}
;
Similarly to print information about function's arguments and return type: add prinln()s in create_function_body rule. But there is an issue whith printing of parameters. If you use $parameter.text it will return name, type specification and default value according to parameter rule without spaces (as token sequence). If you add println() to parameter rule and use $parameter_name.text it will print all parameter's names (including parameters of procedures, not only functions). So you can add an ANTLR return value for parameter rule and assign $parameter_name.text to the return value:
parameter returns [String p_name]
: parameter_name (IN | OUT | INOUT | NOCOPY)*
type_spec? default_value_part?
{$p_name=$parameter_name.text;}
;
Thus is context of create_function_body we can access the parameter's name by $parameter.p_name:
create_function_body
: (CREATE (OR REPLACE)?)? FUNCTION function_name
{System.out.println("Parameters of function "+$function_name.text+":");}
('(' parameter {System.out.println($parameter.p_name);}
(',' parameter {System.out.println($parameter.p_name);})* ')')?
RETURN type_spec
(invoker_rights_clause|parallel_enable_clause|result_cache_clause|DETERMINISTIC)*
((PIPELINED? (IS | AS) (DECLARE? declare_spec* body | call_spec))
| (PIPELINED | AGGREGATE) USING implementation_type_name) ';'
{System.out.println("Return type of function "
+$function_name.text+" is "
+ $type_spec.text);}
;
Accumulation
Also you can save some calculations to variables and access them as parser class members. E.g. you can accumulate function's name in variable func_name. For this add #members section at beginning of the grammar:
grammar plsql;
#members{
String func_name = "";
}
And modify function_name rule as follows:
function_name
: id ('.' id_expression)? {func_name = func_name+$id.text + " ";}
;
Using lexer and parser classes
Here is an example of application to run your parser parse.java:
import org.antlr.v4.runtime.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class parse {
static String readFile(String path) throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, "UTF-8");
}
public static void main(String[] args) throws Exception {
// create input stream `in`
ANTLRInputStream in = new ANTLRInputStream( readFile(args[0]) );
// create lexer `lex` with `in` at input
plsqlLexer lex = new plsqlLexer(in);
// create token stream `tokens` with `lex` at input
CommonTokenStream tokens = new CommonTokenStream(lex);
// create parser with `tokens` at input
plsqlParser parser = new plsqlParser(tokens);
// call start rule of parser
parser.sql_script();
// print func_name
System.out.println("Function names: "+parser.func_name);
}
}
Compile and run
After this generate java code by ANTLR:
java org.antlr.v4.Tool plsql.g4
and compile your Java code:
javac plsqlLexer.java plsqlParser.java plsqlListener.java parse.java
then run it for some .pkb file:
java parse green_tools.pkb
You can find modified parse.java, plsql.g4 and green_tools.pkb here.

Apache Commons CLI 1.3.1: Option coming after another option with multiple arguments is consumed as ARGUMENT

I'm using Apache Commons CLI 1.3.1 to process some options and some of the options can take one to unlimited number arguments. A trivia example with two options would be like this
usage: myProgram -optionX <arg1> <arg2> <arg3> < ... > [-optionY]
-optionX <arg1> <arg2> <arg3> < ... > optionX takes one to unlimited
number of arguments.
-optionY optionY is optional
What I found is that the second option optionY is always recognized as an ARGUMENT of the optionX instead of being recognized as an OPTION by itself. That means if you type
myProgram -optionX arg1 arg2 -optionY in the command line, you will get three arguments (arg1, arg2, and -optionY) associated with optionX.
Here is the code that anyone can use to reproduce the problem.
import org.apache.commons.cli.*;
public class TestCli {
public static void main(String[] args) {
Option optObj1 = Option.builder("optionX")
.argName("arg1> <arg2> <arg3> < ... ")
.desc("optionX takes one to unlimited number of arguments.")
.required()
.hasArgs()
.build();
Option optObj2 = new Option("optionY", "optionY is optional");
Options optsList = new Options();
optsList.addOption(optObj1);
optsList.addOption(optObj2);
CommandLineParser commandLineParser = new DefaultParser();
try {
CommandLine cmd = commandLineParser.parse(optsList, new String[]{"-optionX", "arg1", "arg2", "-optionY"});
System.out.println("--------------------------");
System.out.println("argument list of optionX: ");
for (String argName : cmd.getOptionValues(optObj1.getOpt())) {
System.out.println("arg: " + argName);
}
System.out.println("--------------------------");
System.out.println("value of optionY: " + cmd.hasOption(optObj2.getOpt()));
} catch (ParseException e) {
System.out.println("Unexcepted option: " + e.getMessage());
}
}
}
This is the output you'll see.
--------------------------
argument list of optionX:
arg: arg1
arg: arg2
arg: -optionY
--------------------------
value of optionY: false
Do I miss something here?
Any suggestion will be really appreciated.
The problem is that you are putting the long name in the short name of the option.
When you use Option optObj1 = Option.builder("optionX").... or new Option("optionY", "optionY is optional"), you're setting the short name of the option, which is supposed to be only 1 character long.
That work well until you have a multi arguments option. In this case, the parser cannot find "o" (the first letter of your option) in his short option list and you don't have a long name set, so the parser determines that -optionY is just another argument for -optionX.
To solve your problem, just set the long option name of your option and it should work alright.
Example
Option.builder("x").longOpt("optionX")....
Option optObj2 = new Option("y", "optionY", hasArgs, "optionY is optional");

How to get an App category from play store by its package name in Android?

I want to fetch the app category from play store through its unique identifier i.e. package name, I am using the following code but does not return any data. I also tried to use this AppsRequest.newBuilder().setAppId(query) still no help.
Thanks.
String AndroidId = "dead000beef";
MarketSession session = new MarketSession();
session.login("email", "passwd");
session.getContext().setAndroidId(AndroidId);
String query = "package:com.king.candycrushsaga";
AppsRequest appsRequest = AppsRequest.newBuilder().setQuery(query).setStartIndex(0)
.setEntriesCount(10).setWithExtendedInfo(true).build();
session.append(appsRequest, new Callback<AppsResponse>() {
#Override
public void onResult(ResponseContext context, AppsResponse response) {
String response1 = response.toString();
Log.e("reponse", response1);
}
});
session.flush();
Use this script:
######## Fetch App names and genre of apps from playstore url, using pakage names #############
"""
Reuirements for running this script:
1. requests library
Note: Run this command to avoid insecureplatform warning pip install --upgrade ndg-httpsclient
2. bs4
pip install requests
pip install bs4
"""
import requests
import csv
from bs4 import BeautifulSoup
# url to be used for package
APP_LINK = "https://play.google.com/store/apps/details?id="
output_list = []; input_list = []
# get input file path
print "Need input CSV file (absolute) path \nEnsure csv is of format: <package_name>, <id>\n\nEnter Path:"
input_file_path = str(raw_input())
# store package names and ids in list of tuples
with open(input_file_path, 'rb') as csvfile:
for line in csvfile.readlines():
(p, i) = line.strip().split(',')
input_list.append((p, i))
print "\n\nSit back and relax, this might take a while!\n\n"
for package in input_list:
# generate url, get html
url = APP_LINK + package[0]
r = requests.get(url)
if not (r.status_code==404):
data = r.text
soup = BeautifulSoup(data, 'html.parser')
# parse result
x = ""; y = "";
try:
x = soup.find('div', {'class': 'id-app-title'})
x = x.text
except:
print "Package name not found for: %s" %package[0]
try:
y = soup.find('span', {'itemprop': 'genre'})
y = y.text
except:
print "ID not found for: %s" %package[0]
output_list.append([x,y])
else:
print "App not found: %s" %package[0]
# write to csv file
with open('results.csv', 'w') as fp:
a = csv.writer(fp, delimiter=",")
a.writerows(output_list)
This is what i did, best and easy solution
https://androidquery.appspot.com/api/market?app=your.unique.package.name
Or otherwise you can get source html and get the string out of it ...
https://play.google.com/store/apps/details?id=your.unique.package.name
Get this string out of it - use split or substring methods
<span itemprop="genre">Sports</span>
In this case sports is your category
use android-market-api it will gives all information of application

Error on Oracle : ORA-29541

I'm trying to call a bash script within a oracle database through a java script. To test it I just tried a basic script :
#!/bin/bash
echo "It works !"
And the java script that I use is :
import java.lang.*;
import java.io.*;
public class UAM_TOOLS{
public static String Toto () throws IOException {
String[] unixCommand = {"/home/oz380/toto.sh"};
String pwd;
Process p = Runtime.getRuntime().exec(unixCommand);
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
pwd = input.readLine();
input.close();
return pwd;
}
};
I granted all the permissions that had to be granted and I created the function in my database :
SQL> CREATE OR REPLACE FUNCTION TOPI RETURN VARCHAR2
2 as language java
3 name 'UAM_TOOLS.Toto() return java.lang.String';
4 /
But then when I call the function :
select TOPI from dual;
or :
SQL> set serveroutput on;
SQL> DECLARE
2 G VARCHAR2(50);
3 BEGIN
4 G := UAM.TOPI;
5 DBMS_OUTPUT.PUT_LINE(G);
6 END;
7 /
It doesn't work and prints the error :
ORA-29541: class UAM.UAM_TOOLS could not be resolved
I don't really understand what the problem can be. If anyone does I would be really thankful.
Before the
CREATE FUNCTION
step you need to compile your class at command line
$>javac UAM_TOOLS.java
or using an IDE sth like Eclipse
that will generate compiled class with .class extension. For your case it will be UAM_TOOLS.class
And you still need to upload it to database on command line where the host which db runs on it
$>loadjava -user yourUserName/youPass#Yourdb UAM_TOOLS.class
after that 2 step you can resume with create function step.

Categories

Resources