    001// Copyright 2021 The Apache Software Foundation
    002//
    003// Licensed under the Apache License, Version 2.0 (the "License");
    004// you may not use this file except in compliance with the License.
    005// You may obtain a copy of the License at
    006//
    007// http://www.apache.org/licenses/LICENSE-2.0
    008//
    009// Unless required by applicable law or agreed to in writing, software
    010// distributed under the License is distributed on an "AS IS" BASIS,
    011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012// See the License for the specific language governing permissions and
    013// limitations under the License.
    014
    015package org.apache.tapestry5.json;
    016
    017import java.util.function.Function;
    018import java.util.stream.Collector;
    019import java.util.stream.Collectors;
    020
    021/**
    022 * Implementations of {@link java.util.stream.Collector} that implement reductions
    023 * to {@code JSONArray} and to {@code JSONObject}.
    024 *
    025 * @since 5.7
    026 */
    027
    028public final class JSONCollectors
    029{
    030    private JSONCollectors()
    031    {
    032    }
    033
    034    /**
    035     * Returns a {@code Collector} that accumulates the input elements into a
    036     * new {@code JSONArray}.
    037     *
    038     * @param <T> the type of the input elements
    039     * @return a {@code Collector} which collects all the input elements into a
    040     *         {@code JSONArray}, in encounter order
    041     * @since 5.7
    042     */
    043    public static <T> Collector<T, ?, JSONArray> toArray()
    044    {
    045        return Collector.of(JSONArray::new,
    046                            JSONArray::add,
    047                            JSONArray::putAll);
    048    }
    049
    050    /**
    051     * Returns a {@code Collector} that accumulates elements into a
    052     * {@code JSONObject} whose keys and values are the result of applying the provided
    053     * mapping functions to the input elements.
    054     *
    055     * In case of duplicate keys an {@code IllegalStateException} is
    056     * thrown when the collection operation is performed.
    057     *
    058     * @param <T> the type of the input elements
    059     * @param keyMapper
    060     *            a mapping function to produce String keys
    061     * @param valueMapper
    062     *            a mapping function to produce values
    063     * @return a {@code Collector} which collects elements into a {@code JSONObject}
    064     *         whose keys and values are the result of applying mapping functions to
    065     *         the input elements
    066     * @since 5.7
    067     */
    068    public static <T> Collector<T, ?, JSONObject> toMap(Function<? super T, String> keyMapper,
    069                                                        Function<? super T, Object> valueMapper)
    070    {
    071        return Collectors.toMap(keyMapper,
    072                                valueMapper,
    073                                (u, v) -> {
    074                                    throw new IllegalStateException(String.format("Duplicate key %s", u));
    075                                },
    076                                JSONObject::new);
    077    }
    078
    079}