private void parseAdditionalOptions(Object bean, Set<Object> parsedBeans) { for (Class<?> c = bean.getClass(); c != null; c = c.getSuperclass()) { for (Field f : c.getDeclaredFields()) { if (f.isAnnotationPresent(Options.class)) { Object additionalBean = null; try { additionalBean = f.get(bean); } catch (IllegalAccessException e) { throw new IllegalAnnotationError(e); } parseWithPrefix(f.getAnnotation(Options.class).prefix(), additionalBean, parsedBeans); } } } }
private List<IndependentPair<String, Class<?>>> getListStrings() throws IllegalArgumentException, IllegalAccessException { Object o = f.get(bean); if(o==null) { return new ArrayList<IndependentPair<String, Class<?>>>(); } if(!(o instanceof List)) throw new IllegalAnnotationError(Messages.ILLEGAL_FIELD_SIGNATURE.format(f)); ArrayList<IndependentPair<String, Class<?>>> ret = new ArrayList<IndependentPair<String, Class<?>>>(); for(Object obj : (List<?>) o){ Class<?> objClass = obj.getClass(); ret.add(new IndependentPair<String, Class<?>>(obj.toString(), objClass)); } return ret; }
private List<IndependentPair<String, Class<?>>> getListStrings() throws IllegalArgumentException, IllegalAccessException { Object o = f.get(bean); if(o==null) { return new ArrayList<IndependentPair<String, Class<?>>>(); } if(!(o instanceof Map)) throw new IllegalAnnotationError(Messages.ILLEGAL_FIELD_SIGNATURE.format(f)); ArrayList<IndependentPair<String, Class<?>>> ret = new ArrayList<IndependentPair<String, Class<?>>>(); for(Entry<?, ?> obj : ((Map<?,?>) o).entrySet()){ Class<?> objClass = Object.class; IndependentPair<String, Class<?>> pair = new IndependentPair<String, Class<?>>(obj.getKey().toString() + "=" + obj.getValue().toString(),objClass); ret.add(pair); } return ret; }
@SuppressWarnings("unchecked") private void parseAdditionalOptions(ClassParser classParser, Object bean, Set<Class<?>> visited) { // The top-level bean was already parsed by the superclass constructor, // so an empty visited set means we're parsing the top-level bean. if (!visited.isEmpty()) { classParser.parse(bean, this); // 'Parse' the class of the bean looking for annotations. } Class<?> beanClass = bean.getClass(); if (visited.contains(beanClass)) { throw new IllegalAnnotationError(beanClass.getCanonicalName() + " used more than once."); } else { visited.add(beanClass); } for (Field f : beanClass.getDeclaredFields()) { if (f.isAnnotationPresent(AdditionalOptions.class)) { try { // TODO(user): nicer to do this lazily in parseArgument() Object fieldValue = f.getType().newInstance(); Setters.create(f, bean).addValue(fieldValue); parseAdditionalOptions(classParser, fieldValue, visited); } catch (Exception e) { throw Throwables.propagate(e); } } } }
@SuppressWarnings("unchecked") private void parseAdditionalOptions(ClassParser classParser, Object bean, Set<Class<?>> visited) { // The top-level bean was already parsed by the superclass constructor, // so an empty visited set means we're parsing the top-level bean. if (!visited.isEmpty()) { classParser.parse(bean, this); // 'Parse' the class of the bean looking for annotations. } Class<?> beanClass = bean.getClass(); if (visited.contains(beanClass)) { throw new IllegalAnnotationError(beanClass.getCanonicalName() + " used more than once."); } else { visited.add(beanClass); } for (Field f : beanClass.getDeclaredFields()) { if (f.isAnnotationPresent(AdditionalOptions.class)) { try { // TODO(vlada): nicer to do this lazily in parseArgument() Object fieldValue = f.getType().newInstance(); Setters.create(f, bean).addValue(fieldValue); parseAdditionalOptions(classParser, fieldValue, visited); } catch (CmdLineException | IllegalAccessException | InstantiationException e) { throw new RuntimeException(e); } } } }
@Test(expected = IllegalAnnotationError.class) public void testDuplicateAdditionalOptionsClass() { new CmdLineParserAdditionalOptions(new DuplicateOptions()); }
@Test(expected = IllegalAnnotationError.class) public void testRecursiveAdditionalOptions() { new CmdLineParserAdditionalOptions(new InfiniteOptions()); }
@Test(expected = IllegalAnnotationError.class) public void testDuplicateAdditionalOptionsClass() { new AdditionalOptionsCmdLineParser(new DuplicateOptions()); }
@Test(expected = IllegalAnnotationError.class) public void testRecursiveAdditionalOptions() { new AdditionalOptionsCmdLineParser(new InfiniteOptions()); }
/** * Creates a new command line owner that parses arguments/options and set them into the given * object. * * @param bean instance of a class annotated by {@link org.kohsuke.args4j.Option} and {@link * org.kohsuke.args4j.Argument}. this object will receive values. * @throws IllegalAnnotationError if the option bean class is using args4j annotations * incorrectly. */ @Inject public CmdLineParser(OptionHandlers handlers, @Assisted final Object bean) throws IllegalAnnotationError { this.handlers = handlers; this.parser = new MyParser(bean); }