Skip to content

Commit c07ec3a

Browse files
cavoritetatsuhiro-t
authored andcommitted
Included superclasses containing annotations.
Modified the method that queries for the Arg annotation so that it also includes the fields and methods declared in superclasses.
1 parent 9e8c06a commit c07ec3a

File tree

5 files changed

+117
-67
lines changed

5 files changed

+117
-67
lines changed

.classpath

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="src/main/java"/>
4+
<classpathentry kind="src" path="src/test/java"/>
5+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
6+
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
7+
<classpathentry kind="output" path="bin"/>
8+
</classpath>

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
bin
3+
target
4+

.project

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>argparse4j</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>

src/main/java/net/sourceforge/argparse4j/internal/ArgumentParserImpl.java

+73-67
Original file line numberDiff line numberDiff line change
@@ -453,73 +453,79 @@ public void parseArgs(String[] args, Object userData)
453453
parseArgs(args, opts, userData);
454454
}
455455

456-
@Override
457-
public void parseArgs(String[] args, Map<String, Object> attrs,
458-
Object userData) throws ArgumentParserException {
459-
parseArgs(args, 0, attrs);
460-
for (Field field : userData.getClass().getDeclaredFields()) {
461-
Arg ann = field.getAnnotation(Arg.class);
462-
if (ann != null) {
463-
String argDest = ann.dest();
464-
if (argDest.isEmpty()) {
465-
argDest = field.getName();
466-
}
467-
if (!attrs.containsKey(argDest)) {
468-
continue;
469-
}
470-
Object val = attrs.get(argDest);
471-
try {
472-
field.setAccessible(true);
473-
field.set(userData,
474-
ReflectHelper.list2Array(field.getType(), val));
475-
} catch (RuntimeException e) {
476-
if (!ann.ignoreError()) {
477-
throw e;
478-
}
479-
} catch (Exception e) {
480-
if (!ann.ignoreError()) {
481-
throw new IllegalArgumentException(String.format(
482-
"Could not set %s to field %s", val,
483-
field.getName()), e);
484-
}
485-
}
486-
}
487-
}
488-
for (Method method : userData.getClass().getDeclaredMethods()) {
489-
Arg ann = method.getAnnotation(Arg.class);
490-
if (ann != null) {
491-
String argDest = ann.dest();
492-
if (argDest.isEmpty()) {
493-
argDest = method.getName();
494-
}
495-
if (!attrs.containsKey(argDest)) {
496-
continue;
497-
}
498-
Object val = attrs.get(argDest);
499-
Class<?> fargs[] = method.getParameterTypes();
500-
if (fargs.length != 1) {
501-
throw new IllegalArgumentException(String.format(
502-
"Method %s must have one formal parameter",
503-
method.getName()));
504-
}
505-
try {
506-
method.setAccessible(true);
507-
method.invoke(userData,
508-
ReflectHelper.list2Array(fargs[0], val));
509-
} catch (RuntimeException e) {
510-
if (!ann.ignoreError()) {
511-
throw e;
512-
}
513-
} catch (Exception e) {
514-
if (!ann.ignoreError()) {
515-
throw new IllegalArgumentException(String.format(
516-
"Could not call method %s with %s",
517-
method.getName(), val), e);
518-
}
519-
}
520-
}
521-
}
522-
}
456+
@Override
457+
public void parseArgs(String[] args, Map<String, Object> attrs,
458+
Object userData) throws ArgumentParserException {
459+
parseArgs(args, 0, attrs);
460+
461+
Class userClass = userData.getClass();
462+
while (userClass != null) {
463+
for (Field field : userClass.getDeclaredFields()) {
464+
Arg ann = field.getAnnotation(Arg.class);
465+
if (ann != null) {
466+
String argDest = ann.dest();
467+
if (argDest.isEmpty()) {
468+
argDest = field.getName();
469+
}
470+
if (!attrs.containsKey(argDest)) {
471+
continue;
472+
}
473+
Object val = attrs.get(argDest);
474+
try {
475+
field.setAccessible(true);
476+
field.set(userData,
477+
ReflectHelper.list2Array(field.getType(), val));
478+
} catch (RuntimeException e) {
479+
if (!ann.ignoreError()) {
480+
throw e;
481+
}
482+
} catch (Exception e) {
483+
if (!ann.ignoreError()) {
484+
throw new IllegalArgumentException(String.format(
485+
"Could not set %s to field %s", val,
486+
field.getName()), e);
487+
}
488+
}
489+
}
490+
}
491+
for (Method method : userClass.getDeclaredMethods()) {
492+
Arg ann = method.getAnnotation(Arg.class);
493+
if (ann != null) {
494+
String argDest = ann.dest();
495+
if (argDest.isEmpty()) {
496+
argDest = method.getName();
497+
}
498+
if (!attrs.containsKey(argDest)) {
499+
continue;
500+
}
501+
Object val = attrs.get(argDest);
502+
Class<?> fargs[] = method.getParameterTypes();
503+
if (fargs.length != 1) {
504+
throw new IllegalArgumentException(String.format(
505+
"Method %s must have one formal parameter",
506+
method.getName()));
507+
}
508+
try {
509+
method.setAccessible(true);
510+
method.invoke(userData,
511+
ReflectHelper.list2Array(fargs[0], val));
512+
} catch (RuntimeException e) {
513+
if (!ann.ignoreError()) {
514+
throw e;
515+
}
516+
} catch (Exception e) {
517+
if (!ann.ignoreError()) {
518+
throw new IllegalArgumentException(String.format(
519+
"Could not call method %s with %s",
520+
method.getName(), val), e);
521+
}
522+
}
523+
}
524+
}
525+
userClass = userClass.getSuperclass();
526+
}
527+
528+
}
523529

524530
public void parseArgs(String args[], int offset, Map<String, Object> attrs)
525531
throws ArgumentParserException {

src/test/java/net/sourceforge/argparse4j/internal/ArgumentParserImplTest.java

+15
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,21 @@ public void setY(int y) {
483483
assertEquals("alice", out.name);
484484
assertEquals("example.com", out.host);
485485
assertArrayEquals(new int[] { 1, 2, 3 }, out.getInts());
486+
487+
// Test inheritance
488+
class SubOut extends Out {
489+
@Arg
490+
public int port;
491+
}
492+
493+
ap.addArgument("--port").type(Integer.class);
494+
SubOut subOut = new SubOut();
495+
ap.parseArgs("--username alice --host example.com --port 8080 --attrs 1 2 3".split(" "), subOut);
496+
assertEquals("alice", subOut.name);
497+
assertEquals("example.com", subOut.host);
498+
assertArrayEquals(new int[] { 1, 2, 3 }, subOut.getInts());
499+
assertEquals(8080, subOut.port);
500+
486501
}
487502

488503
@Test

0 commit comments

Comments
 (0)