@Test void triesAllOverloads() { HasOverloads overloads = new HasOverloads(); setter.set(overloads, "value", "23"); setter.set(overloads, "value", "2s"); setter.set(overloads, "value", "{\"luckyNumber\":37}"); assertEquals(23, overloads.i); assertEquals(Duration.ofSeconds(2), overloads.d); assertEquals(singletonMap("luckyNumber", 37), overloads.m); InvalidArgumentException e = assertThrows(InvalidArgumentException.class, () -> setter.set(overloads, "value", "garbage")); assertTrue(e.getMessage().startsWith("Found multiple one-arg setters")); final Set<String> suppressedMessages = Arrays.stream(e.getSuppressed()).map(Throwable::getMessage).collect(toSet()); final Set<String> expectedSuppressedMessages = new HashSet<>(Arrays.asList( "Expected an int but got \"garbage\".", "Expected a duration qualified by a time unit (like \"2.5s\" or \"300ms\") but got \"garbage\".", "Expected a value Jackson can bind to java.util.Map<java.lang.String, java.lang.Integer> but got \"garbage\".")); assertEquals(expectedSuppressedMessages, suppressedMessages); }
public void set(Object builder, String propertyName, String propertyValue) { final String CHILD_BUILDER_ACCESSOR_SUFFIX = "Config"; try { final List<String> propertyComponents = Arrays.asList(propertyName.split("\\.", -1)); final List<String> pathToBuilder = propertyComponents.subList(0, propertyComponents.size() - 1); final String setterName = propertyComponents.get(propertyComponents.size() - 1); for (String pathComponent : pathToBuilder) { try { final String childBuilderAccessor = pathComponent + CHILD_BUILDER_ACCESSOR_SUFFIX; builder = builder.getClass().getMethod(childBuilderAccessor).invoke(builder); } catch (NoSuchMethodException e) { throw InvalidArgumentException.fromMessage("Method not found: " + e.getMessage(), e); } } final List<Method> candidates = Arrays.stream(builder.getClass().getMethods()) .filter(m -> m.getName().equals(setterName)) .filter(m -> m.getParameterCount() == 1) .collect(Collectors.toList()); if (candidates.isEmpty()) { throw InvalidArgumentException.fromMessage("No one-arg setter for property \"" + propertyName + "\" in " + builder.getClass()); } int remainingCandidates = candidates.size(); final List<Throwable> failedCandidates = new ArrayList<>(); for (Method setter : candidates) { try { final Object convertedValue = typeRegistry.convert(propertyValue, setter.getGenericParameterTypes()[0]); setter.invoke(builder, convertedValue); } catch (Throwable t) { if (candidates.size() == 1) { throw t; } failedCandidates.add(t); if (--remainingCandidates == 0) { final InvalidArgumentException e = InvalidArgumentException.fromMessage( "Found multiple one-arg setters for property \"" + propertyName + "\" in " + builder.getClass() + " but none accepted the value \"" + propertyValue + "\"."); failedCandidates.forEach(e::addSuppressed); throw e; } } } } catch (IllegalAccessException e) { throw InvalidArgumentException.fromMessage("Failed to access the corresponding builder method.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof RuntimeException) ? (RuntimeException) cause : new RuntimeException(cause); } }
BuilderPropertySetter { public void set(Object builder, String propertyName, String propertyValue) { final String CHILD_BUILDER_ACCESSOR_SUFFIX = "Config"; try { final List<String> propertyComponents = Arrays.asList(propertyName.split("\\.", -1)); final List<String> pathToBuilder = propertyComponents.subList(0, propertyComponents.size() - 1); final String setterName = propertyComponents.get(propertyComponents.size() - 1); for (String pathComponent : pathToBuilder) { try { final String childBuilderAccessor = pathComponent + CHILD_BUILDER_ACCESSOR_SUFFIX; builder = builder.getClass().getMethod(childBuilderAccessor).invoke(builder); } catch (NoSuchMethodException e) { throw InvalidArgumentException.fromMessage("Method not found: " + e.getMessage(), e); } } final List<Method> candidates = Arrays.stream(builder.getClass().getMethods()) .filter(m -> m.getName().equals(setterName)) .filter(m -> m.getParameterCount() == 1) .collect(Collectors.toList()); if (candidates.isEmpty()) { throw InvalidArgumentException.fromMessage("No one-arg setter for property \"" + propertyName + "\" in " + builder.getClass()); } int remainingCandidates = candidates.size(); final List<Throwable> failedCandidates = new ArrayList<>(); for (Method setter : candidates) { try { final Object convertedValue = typeRegistry.convert(propertyValue, setter.getGenericParameterTypes()[0]); setter.invoke(builder, convertedValue); } catch (Throwable t) { if (candidates.size() == 1) { throw t; } failedCandidates.add(t); if (--remainingCandidates == 0) { final InvalidArgumentException e = InvalidArgumentException.fromMessage( "Found multiple one-arg setters for property \"" + propertyName + "\" in " + builder.getClass() + " but none accepted the value \"" + propertyValue + "\"."); failedCandidates.forEach(e::addSuppressed); throw e; } } } } catch (IllegalAccessException e) { throw InvalidArgumentException.fromMessage("Failed to access the corresponding builder method.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof RuntimeException) ? (RuntimeException) cause : new RuntimeException(cause); } } }
BuilderPropertySetter { public void set(Object builder, String propertyName, String propertyValue) { final String CHILD_BUILDER_ACCESSOR_SUFFIX = "Config"; try { final List<String> propertyComponents = Arrays.asList(propertyName.split("\\.", -1)); final List<String> pathToBuilder = propertyComponents.subList(0, propertyComponents.size() - 1); final String setterName = propertyComponents.get(propertyComponents.size() - 1); for (String pathComponent : pathToBuilder) { try { final String childBuilderAccessor = pathComponent + CHILD_BUILDER_ACCESSOR_SUFFIX; builder = builder.getClass().getMethod(childBuilderAccessor).invoke(builder); } catch (NoSuchMethodException e) { throw InvalidArgumentException.fromMessage("Method not found: " + e.getMessage(), e); } } final List<Method> candidates = Arrays.stream(builder.getClass().getMethods()) .filter(m -> m.getName().equals(setterName)) .filter(m -> m.getParameterCount() == 1) .collect(Collectors.toList()); if (candidates.isEmpty()) { throw InvalidArgumentException.fromMessage("No one-arg setter for property \"" + propertyName + "\" in " + builder.getClass()); } int remainingCandidates = candidates.size(); final List<Throwable> failedCandidates = new ArrayList<>(); for (Method setter : candidates) { try { final Object convertedValue = typeRegistry.convert(propertyValue, setter.getGenericParameterTypes()[0]); setter.invoke(builder, convertedValue); } catch (Throwable t) { if (candidates.size() == 1) { throw t; } failedCandidates.add(t); if (--remainingCandidates == 0) { final InvalidArgumentException e = InvalidArgumentException.fromMessage( "Found multiple one-arg setters for property \"" + propertyName + "\" in " + builder.getClass() + " but none accepted the value \"" + propertyValue + "\"."); failedCandidates.forEach(e::addSuppressed); throw e; } } } } catch (IllegalAccessException e) { throw InvalidArgumentException.fromMessage("Failed to access the corresponding builder method.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof RuntimeException) ? (RuntimeException) cause : new RuntimeException(cause); } }  }
BuilderPropertySetter { public void set(Object builder, String propertyName, String propertyValue) { final String CHILD_BUILDER_ACCESSOR_SUFFIX = "Config"; try { final List<String> propertyComponents = Arrays.asList(propertyName.split("\\.", -1)); final List<String> pathToBuilder = propertyComponents.subList(0, propertyComponents.size() - 1); final String setterName = propertyComponents.get(propertyComponents.size() - 1); for (String pathComponent : pathToBuilder) { try { final String childBuilderAccessor = pathComponent + CHILD_BUILDER_ACCESSOR_SUFFIX; builder = builder.getClass().getMethod(childBuilderAccessor).invoke(builder); } catch (NoSuchMethodException e) { throw InvalidArgumentException.fromMessage("Method not found: " + e.getMessage(), e); } } final List<Method> candidates = Arrays.stream(builder.getClass().getMethods()) .filter(m -> m.getName().equals(setterName)) .filter(m -> m.getParameterCount() == 1) .collect(Collectors.toList()); if (candidates.isEmpty()) { throw InvalidArgumentException.fromMessage("No one-arg setter for property \"" + propertyName + "\" in " + builder.getClass()); } int remainingCandidates = candidates.size(); final List<Throwable> failedCandidates = new ArrayList<>(); for (Method setter : candidates) { try { final Object convertedValue = typeRegistry.convert(propertyValue, setter.getGenericParameterTypes()[0]); setter.invoke(builder, convertedValue); } catch (Throwable t) { if (candidates.size() == 1) { throw t; } failedCandidates.add(t); if (--remainingCandidates == 0) { final InvalidArgumentException e = InvalidArgumentException.fromMessage( "Found multiple one-arg setters for property \"" + propertyName + "\" in " + builder.getClass() + " but none accepted the value \"" + propertyValue + "\"."); failedCandidates.forEach(e::addSuppressed); throw e; } } } } catch (IllegalAccessException e) { throw InvalidArgumentException.fromMessage("Failed to access the corresponding builder method.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof RuntimeException) ? (RuntimeException) cause : new RuntimeException(cause); } }  void set(Object builder, String propertyName, String propertyValue); }
BuilderPropertySetter { public void set(Object builder, String propertyName, String propertyValue) { final String CHILD_BUILDER_ACCESSOR_SUFFIX = "Config"; try { final List<String> propertyComponents = Arrays.asList(propertyName.split("\\.", -1)); final List<String> pathToBuilder = propertyComponents.subList(0, propertyComponents.size() - 1); final String setterName = propertyComponents.get(propertyComponents.size() - 1); for (String pathComponent : pathToBuilder) { try { final String childBuilderAccessor = pathComponent + CHILD_BUILDER_ACCESSOR_SUFFIX; builder = builder.getClass().getMethod(childBuilderAccessor).invoke(builder); } catch (NoSuchMethodException e) { throw InvalidArgumentException.fromMessage("Method not found: " + e.getMessage(), e); } } final List<Method> candidates = Arrays.stream(builder.getClass().getMethods()) .filter(m -> m.getName().equals(setterName)) .filter(m -> m.getParameterCount() == 1) .collect(Collectors.toList()); if (candidates.isEmpty()) { throw InvalidArgumentException.fromMessage("No one-arg setter for property \"" + propertyName + "\" in " + builder.getClass()); } int remainingCandidates = candidates.size(); final List<Throwable> failedCandidates = new ArrayList<>(); for (Method setter : candidates) { try { final Object convertedValue = typeRegistry.convert(propertyValue, setter.getGenericParameterTypes()[0]); setter.invoke(builder, convertedValue); } catch (Throwable t) { if (candidates.size() == 1) { throw t; } failedCandidates.add(t); if (--remainingCandidates == 0) { final InvalidArgumentException e = InvalidArgumentException.fromMessage( "Found multiple one-arg setters for property \"" + propertyName + "\" in " + builder.getClass() + " but none accepted the value \"" + propertyValue + "\"."); failedCandidates.forEach(e::addSuppressed); throw e; } } } } catch (IllegalAccessException e) { throw InvalidArgumentException.fromMessage("Failed to access the corresponding builder method.", e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof RuntimeException) ? (RuntimeException) cause : new RuntimeException(cause); } }  void set(Object builder, String propertyName, String propertyValue);  }