/** * Performs the actual work as advertised by the {@code parse()} method. * This method delegates to {@link #flatten(Object, int)} without specifying * a limit. * * @param value the value to be processed * @return a "flat" collection containing all primitive values of * the passed in object */ private Collection<?> flatten(final Object value) { return flatten(value, Integer.MAX_VALUE); }
/** * {@inheritDoc} This implementation handles the case that the passed in * string is <b>null</b>. In this case, an empty collection is returned. * Otherwise, this method delegates to {@link #splitString(String, boolean)}. */ @Override public Collection<String> split(final String s, final boolean trim) { if (s == null) { return new ArrayList<>(0); } return splitString(s, trim); }
return split((String) value, true); if (value instanceof Iterable) flattenIterator(result, ((Iterable<?>) value).iterator(), limit); flattenIterator(result, (Iterator<?>) value, limit); && size < limit; idx++, size = result.size()) result.addAll(flatten(Array.get(value, idx), limit - size));
/** * {@inheritDoc} This implementation checks whether the object to be escaped * is a string. If yes, it delegates to {@link #escapeString(String)}, * otherwise no escaping is performed. Eventually, the passed in transformer * is invoked so that additional encoding can be performed. */ @Override public Object escape(final Object value, final ValueTransformer transformer) { final Object escValue = (value instanceof String) ? escapeString((String) value) : value; return transformer.transformValue(escValue); }
/** * Extracts a maximum number of values contained in the given source object * and returns them as flat collection. This method is useful if the caller * only needs a subset of values, e.g. only the first one. * * @param source the source object (may be a single value or a complex * object) * @param limit the number of elements to extract * @return a collection with all extracted values */ protected Collection<?> extractValues(final Object source, final int limit) { return EXTRACTOR.flatten(source, limit); }
/** * {@inheritDoc} Depending on the type of the passed in object the following * things happen: * <ul> * <li>Strings are checked for delimiter characters and split if necessary. * This is done by calling the {@code split()} method.</li> * <li>For objects implementing the {@code Iterable} interface, the * corresponding {@code Iterator} is obtained, and contained elements are * added to the resulting iteration.</li> * <li>Arrays are treated as {@code Iterable} objects.</li> * <li>All other types are directly inserted.</li> * <li>Recursive combinations are supported, e.g. a collection containing an * array that contains strings: The resulting collection will only contain * primitive objects.</li> * </ul> */ @Override public Iterable<?> parse(final Object value) { return flatten(value); }
/** * Flattens the given iterator. For each element in the iteration * {@code flatten()} is called recursively. * * @param target the target collection * @param it the iterator to process * @param limit a limit for the number of elements to extract */ private void flattenIterator(final Collection<Object> target, final Iterator<?> it, final int limit) { int size = target.size(); while (size < limit && it.hasNext()) { target.addAll(flatten(it.next(), limit - size)); size = target.size(); } } }