How can I ignore extra arguments with jargo? - java

I'm trying to allow jargo to ignore any amount of "junk-be-here" strings. How can I do that? This is the code I've come up with:
#Test
public void testUsage() throws Exception
{
Argument<Integer> nrOfPotatoes = Arguments.integerArgument("-n").build();
ParsedArguments parsedArguments = CommandLineParser.withArguments(nrOfPotatoes).parse("-n", "123", "junk-be-here");
int potatoesToPlant = parsedArguments.get(nrOfPotatoes);
System.out.println("Hold on, planting " + potatoesToPlant + " potatoes");
}
But I get:
se.softhouse.jargo.ArgumentExceptions$UnexpectedArgumentException: Unexpected argument: junk-be-here, previous argument: 123
at se.softhouse.jargo.ArgumentExceptions.forUnexpectedArgument(ArgumentExceptions.java:299)
at se.softhouse.jargo.CommandLineParserInstance.getDefinitionForCurrentArgument(CommandLineParserInstance.java:329)
at se.softhouse.jargo.CommandLineParserInstance.parseArguments(CommandLineParserInstance.java:262)
at se.softhouse.jargo.CommandLineParserInstance.parse(CommandLineParserInstance.java:234)
at se.softhouse.jargo.CommandLineParserInstance.parse(CommandLineParserInstance.java:228)
at se.softhouse.jargo.CommandLineParser.parse(CommandLineParser.java:224)
at
.....

You can use an indexed argument (by specifying no names to the argument), and set variableArity (any amount of arguments is allowed).
#Test
public void testUsage() throws Exception
{
Argument<List<String>> junk = Arguments.stringArgument().variableArity().build();
Argument<Integer> nrOfPotatoes = Arguments.integerArgument("-n").build();
ParsedArguments parsedArguments = CommandLineParser.withArguments(junk, nrOfPotatoes).parse("-n", "123", "junk-be-here");
int potatoesToPlant = parsedArguments.get(nrOfPotatoes);
System.out.println("Hold on, planting " + potatoesToPlant + " potatoes");
System.out.println("Junk:" + parsedArguments.get(junk));
}
This prints:
Hold on, planting 123 potatoes
Junk:[junk-be-here]

Related

Initialize multiple numeric fields at once in JAVA that begin with certain values

I am working on a Java class that contains a ton of numeric fields. Most of them would begin with something like 'CMTH' or 'FYTD'. Is it possible to initialize all fields of the same type that begin or end with a certain value. For example I have the following fields:
CMthRepCaseACR CMthRepUnitACR CMthRecCaseACR CMthRecUnitACR CMthHecCaseACR CMthHecUnitACR FYTDHecCaseACR FYTDHecUnitACR CMthBBKCaseACR CMthBBKUnitACR CMthPIHCaseACR .
I am trying to figure if it is possible to initialize all fields to zero that end with an 'ACR' or begin with an 'Cmth"
I know I can do something like cmtha = cmthb = cmthc = 0 but I was wondering there was a command where you can some kind of mask to initialize
Thanks
Assuming that you cannot change that said Java class (and e.g. use a collection or map to store the values) your best bet is probably reflection (see also: Trail: The Reflection API). Reflection gives you access to all fields of the class and you can then implement whatever matching you'd like.
Here's a short demo to get you started, minus error handling, sanity checks and adaptions to your actual class:
import java.util.stream.Stream;
public class Demo {
private static class DemoClass {
private int repCaseACR = 1;
private int CMthRepUnit = 2;
private int foo = 3;
private int bar = 4;
#Override
public String toString() {
return "DemoClass [repCaseACR=" + repCaseACR + ", CMthRepUnit=" + CMthRepUnit + ", foo=" + foo + ", bar="
+ bar + "]";
}
}
public static void main(String[] args) {
DemoClass demoClass = new DemoClass();
System.out.println("before: " + demoClass);
resetFields(demoClass, "CMth", null);
System.out.println("after prefix reset: " + demoClass);
resetFields(demoClass, null, "ACR");
System.out.println("after suffix reset: " + demoClass);
}
private static void resetFields(DemoClass instance, String prefix, String suffix) {
Stream.of(instance.getClass().getDeclaredFields())
.filter(field ->
(prefix != null && field.getName().startsWith(prefix))
|| (suffix != null && field.getName().endsWith(suffix)))
.forEach(field -> {
field.setAccessible(true);
try {
field.set(instance, 0);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO handle me
}
});
}
}
Output:
before: DemoClass [repCaseACR=1, CMthRepUnit=2, foo=3, bar=4]
after prefix reset: DemoClass [repCaseACR=1, CMthRepUnit=0, foo=3, bar=4]
after suffix reset: DemoClass [repCaseACR=0, CMthRepUnit=0, foo=3, bar=4]
Note: Both links are seriously dated but the core functionality of reflection is still the same.

Criteria inside JsonPath

I'm trying to filter jsonPath by type. To extract Integers
I would expect this will return nothing as 'xx' is not integer:
JsonPath.read("{'status': 'xx'}", "$.status", Criteria.where(".status").is(Integer.class));
Similarly this
JsonPath.read("{'status': 'xx'}", "$.status", Criteria.where(".status").eq(200));
both cases returns String = "xx"
I would expect it to return either null or empty string as it doesn't match number 200.
Correct #i.bondarenko, I would simply add - for the first check of searching whether status value is an Integer - that he/she should use a Pattern to pass to the filter, like for example
Pattern numberPattern = Pattern.compile("\\d+");
Filter filter = filter(where("status").regex(numberPattern));
Object test = JsonPath.read("{\"status\": \"xx\"}", "$[?].status", filter);
System.out.println("Test : " + test);
That will print Test : []
UPDATED
It is a JSONArray indeed, therefore, you already have the Integers of your whole JSON in that array (if they exist). For example,
Pattern numberPattern = Pattern.compile("\\d+");
Filter filter = filter(where("status").regex(numberPattern));
net.minidev.json.JSONArray test = JsonPath.read("{\"status\": 300}", "$[?].status", filter);
if (!test.isEmpty()) {
for (Object object : test) {
System.out.println("Test : " + object.toString());
}
}
So, there is no need to add try-catch, it is enough to just check the size of your JSONArray result
You should use $[?].status as json path for criteria.
Also where("field").is("value") accept value but not a class.
You could have a look at implementation of Criteria.eq(...)
public Criteria eq(Object o) {
return is(o);
}
Here is the code:
public static void main(String[] args) {
Criteria criteria = Criteria.where("status").gt(10);
Object read = JsonPath.read("{'status': 18}", "$[?].status", criteria);
System.out.println("First: " + read);
read = JsonPath.read("{'status': 2}", "$[?].status", criteria);
System.out.println("Second: " + read);
criteria = Criteria.where("status").is("value");
read = JsonPath.read("{'status': 'value'}", "$[?].status", criteria);
System.out.println("Third: " + read);
criteria = Criteria.where("status").is("value");
read = JsonPath.read("{'status': 'NON'}", "$[?].status", criteria);
System.out.println("Third: " + read);
}
Output:
First: [18]
Second: []
Third: ["value"]
Third: []

Unable to write Mockito test case for my void method

I need to test this code with Mockito (JUnit):
public class Calculation {
public void logTimeTaken(String label, long estimatedTime, int size, boolean isDebug) {
String out = label + " took " + TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS) + " milliseconds for " + size + " events!";
if (isDebug) {
System.out.println(out);
} else {
System.out.println(out);
}
}
}
I search so many examples google but still not getting any idea.
You can configure System with an instance of PrintStream which you can then assert against after invoking Calculation.logTimeTaken.
Here's an example:
#Test
public void canLogTimeTaken() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream out = new PrintStream(bout);
System.setOut(out);
Calculation sut = new Calculation();
sut.logTimeTaken("label", 20 , 2, false);
assertEquals("if isDebug is false label took 0 milliseconds for 2 events!\n", bout.toString());
}
Note: there is no need for Mockito here, this is just vanilla JUnit, no mocking.
But, it might be a better design to refactor logTimeTaken into two distinct aspects:
Deriving the log message
Logging that message
For example:
public String createTimeTakenMessage(String label, long estimatedTime, int size, boolean isDebug) {
return label + " took " + TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS) + " milliseconds for " + size + " events!";
}
public void logTimeTaken(String message) {
System.out.println(message);
}
Then testing createTimeTakenMessage is trivial and you might even choose not to test logTimeTaken at all since all it does is invoke a System method. Or, perhaps you would hide the 'log action' behind an interface with an implementation using System.out now and perhaps, later, other implementations using a formal logging framework such as Logback.

How do I use Java methods correctly?

So, I am SUPER new to Java, but I am trying to make a class-specific program so that I can work on a game within Java. Here is my code:
import java.util.Scanner;
public class boxtype {
public static void main(String args[]) {
String[] melee = {"Crowbar", "Bowie Knife", "Butterfly Knife", "Knuckleduster"};
String[] pistol = {"Colt .22", "Magnum .45", "P250", "9mm Pistol"};
String[] assault = {"AK47", "M4A1", "M16", "SMG", "Mac10", "Minigun (HGE)"};
String[] shotgunsniper = {"Shotgun", "Benelli S90", "Sniper Rifle"};
String[] attachments = {"Laser Sight", "Silencer", "Scope", "Auto-target"};
Scanner scan = new Scanner(System.in);
String xy = scan.nextLine();
if (xy.equals("spyclass")) {
spyClass();
}
}
private static void spyClass(String[] assault, String[] attachments, String[] pistol) {
// TODO Auto-generated method stub
System.out.println("Spy class: ");
System.out.println("Primary weapon: " + assault[2] + " + " + attachments[2]);
System.out.println("Secondary weapon: " + pistol[1] + " + " + attachments[2]);
System.out.println("");
}
}
Basically what happens, is Eclipse returns an error saying that "spyClass is not applicable". I'm still researching how to fix, but yeah.
in the call to spyClass you're not passing the parameeters
It should be:
if (xy.equals("spyclass")) {
spyClass(assault, attachments, pistol);
}
Your spyClass method expects a bunch of arguments, but you aren't giving it any. The line that says
spyClass();
should perhaps be something like
spyClass(assault, attachments, piston);
spyClass probably shouldn't be static and you need to pass the arguments to it when you call it in your main method. spyClass(assault, attachments, pistol);

Create Custom InputFormat of ColumnFamilyInputFormat for cassandra

I am working on a project, using cassandra 1.2, hadoop 1.2
I have created my normal cassandra mapper and reducer, but I want to create my own Input format class, which will read the records from cassandra, and I'll get the desired column's value, by splitting that value using splitting and indexing ,
so, I planned to create custom Format class. but I'm confused and not able to know, how would I make it? What classes are to be extend and implement, and how I will able to fetch the row key, column name, columns value etc.
I have my Mapperclass as follow:
public class MyMapper extends
Mapper<ByteBuffer, SortedMap<ByteBuffer, IColumn>, Text, Text> {
private Text word = new Text();
MyJDBC db = new MyJDBC();
public void map(ByteBuffer key, SortedMap<ByteBuffer, IColumn> columns,
Context context) throws IOException, InterruptedException {
long std_id = Long.parseLong(ByteBufferUtil.string(key));
long newSavePoint = 0;
if (columns.values().isEmpty()) {
System.out.println("EMPTY ITERATOR");
sb.append("column_N/A" + ":" + "N/A" + " , ");
} else {
for (IColumn cell : columns.values()) {
name = ByteBufferUtil.string(cell.name());
String value = null;
if (name.contains("int")) {
value = String.valueOf(ByteBufferUtil.toInt(cell.value()));
} else {
value = ByteBufferUtil.string(cell.value());
}
String[] data = value.toString().split(",");
// if (data[0].equalsIgnoreCase("login")) {
Long[] dif = getDateDiffe(d1, d2);
// logics i want to perform inside my custominput class , rather here, i just want a simple mapper class
if (condition1 && condition2) {
myhits++;
sb.append(":\t " + data[0] + " " + data[2] + " "+ data[1] /* + " " + data[3] */+ "\n");
newSavePoint = d2;
}
}
sb.append("~" + like + "~" + newSavePoint + "~");
word.set(sb.toString().replace("\t", ""));
}
db.setInterval(Long.parseLong(ByteBufferUtil.string(key)), newSavePoint);
db.setHits(Long.parseLong(ByteBufferUtil.string(key)), like + "");
context.write(new Text(ByteBufferUtil.string(key)), word);
}
I want to decrease my Mapper Class logics, and want to perform same calculations on my custom input class.
Please help, i wish for the positive r4esponse from stackies...
You can do the intended task by moving the Mapper logic to your custom input class (as you have indicated already)
I found this nice post which explains a similar problem statement as you have. I think it might solve your problem.

Categories

Resources