List of usage examples for com.google.common.collect Sets filter
@GwtIncompatible("NavigableSet") @SuppressWarnings("unchecked") @CheckReturnValue public static <E> NavigableSet<E> filter(NavigableSet<E> unfiltered, Predicate<? super E> predicate)
From source file:org.apache.beam.sdk.options.PipelineOptionsFactory.java
/** * Using the parsed string arguments, we convert the strings to the expected * return type of the methods that are found on the passed-in class. * * <p>For any return type that is expected to be an array or a collection, we further * split up each string on ','.// w w w .jav a 2 s .c om * * <p>We special case the "runner" option. It is mapped to the class of the {@link PipelineRunner} * based off of the {@link PipelineRunner PipelineRunners} simple class name. If the provided * runner name is not registered via a {@link PipelineRunnerRegistrar}, we attempt to obtain the * class that the name represents using {@link Class#forName(String)} and use the result class if * it subclasses {@link PipelineRunner}. * * <p>If strict parsing is enabled, unknown options or options that cannot be converted to * the expected java type using an {@link ObjectMapper} will be ignored. */ private static <T extends PipelineOptions> Map<String, Object> parseObjects(Class<T> klass, ListMultimap<String, String> options, boolean strictParsing) { Map<String, Method> propertyNamesToGetters = Maps.newHashMap(); PipelineOptionsFactory.validateWellFormed(klass, REGISTERED_OPTIONS); @SuppressWarnings("unchecked") Iterable<PropertyDescriptor> propertyDescriptors = PipelineOptionsFactory .getPropertyDescriptors(FluentIterable.from(getRegisteredOptions()).append(klass).toSet()); for (PropertyDescriptor descriptor : propertyDescriptors) { propertyNamesToGetters.put(descriptor.getName(), descriptor.getReadMethod()); } Map<String, Object> convertedOptions = Maps.newHashMap(); for (final Map.Entry<String, Collection<String>> entry : options.asMap().entrySet()) { try { // Search for close matches for missing properties. // Either off by one or off by two character errors. if (!propertyNamesToGetters.containsKey(entry.getKey())) { SortedSet<String> closestMatches = new TreeSet<>( Sets.filter(propertyNamesToGetters.keySet(), new Predicate<String>() { @Override public boolean apply(@Nonnull String input) { return StringUtils.getLevenshteinDistance(entry.getKey(), input) <= 2; } })); switch (closestMatches.size()) { case 0: throw new IllegalArgumentException( String.format("Class %s missing a property named '%s'.", klass, entry.getKey())); case 1: throw new IllegalArgumentException( String.format("Class %s missing a property named '%s'. Did you mean '%s'?", klass, entry.getKey(), Iterables.getOnlyElement(closestMatches))); default: throw new IllegalArgumentException( String.format("Class %s missing a property named '%s'. Did you mean one of %s?", klass, entry.getKey(), closestMatches)); } } Method method = propertyNamesToGetters.get(entry.getKey()); // Only allow empty argument values for String, String Array, and Collection<String>. Class<?> returnType = method.getReturnType(); JavaType type = MAPPER.getTypeFactory().constructType(method.getGenericReturnType()); if ("runner".equals(entry.getKey())) { String runner = Iterables.getOnlyElement(entry.getValue()); if (SUPPORTED_PIPELINE_RUNNERS.containsKey(runner.toLowerCase())) { convertedOptions.put("runner", SUPPORTED_PIPELINE_RUNNERS.get(runner.toLowerCase())); } else { try { Class<?> runnerClass = Class.forName(runner); if (!(PipelineRunner.class.isAssignableFrom(runnerClass))) { throw new IllegalArgumentException( String.format( "Class '%s' does not implement PipelineRunner. " + "Supported pipeline runners %s", runner, getSupportedRunners())); } convertedOptions.put("runner", runnerClass); } catch (ClassNotFoundException e) { String msg = String.format( "Unknown 'runner' specified '%s', supported pipeline runners %s", runner, getSupportedRunners()); throw new IllegalArgumentException(msg, e); } } } else if (isCollectionOrArrayOfAllowedTypes(returnType, type)) { // Split any strings with "," List<String> values = FluentIterable.from(entry.getValue()) .transformAndConcat(new Function<String, Iterable<String>>() { @Override public Iterable<String> apply(@Nonnull String input) { return Arrays.asList(input.split(",")); } }).toList(); if (values.contains("")) { checkEmptyStringAllowed(returnType, type, method.getGenericReturnType().toString()); } convertedOptions.put(entry.getKey(), MAPPER.convertValue(values, type)); } else if (isSimpleType(returnType, type)) { String value = Iterables.getOnlyElement(entry.getValue()); if (value.isEmpty()) { checkEmptyStringAllowed(returnType, type, method.getGenericReturnType().toString()); } convertedOptions.put(entry.getKey(), MAPPER.convertValue(value, type)); } else { String value = Iterables.getOnlyElement(entry.getValue()); if (value.isEmpty()) { checkEmptyStringAllowed(returnType, type, method.getGenericReturnType().toString()); } try { convertedOptions.put(entry.getKey(), MAPPER.readValue(value, type)); } catch (IOException e) { throw new IllegalArgumentException("Unable to parse JSON value " + value, e); } } } catch (IllegalArgumentException e) { if (strictParsing) { throw e; } else { LOG.warn("Strict parsing is disabled, ignoring option '{}' with value '{}' because {}", entry.getKey(), entry.getValue(), e.getMessage()); } } } return convertedOptions; }