All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.sshd.common.util.MapEntryUtils Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sshd.common.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.TreeMap;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * Represents an un-modifiable pair of values
 *
 * @author Apache MINA SSHD Project
 */
public final class MapEntryUtils {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static final Comparator> BY_KEY_COMPARATOR = (o1, o2) -> {
        Comparable k1 = o1.getKey();
        Comparable k2 = o2.getKey();
        return k1.compareTo(k2);
    };

    @SuppressWarnings("rawtypes")
    private static final Supplier CASE_INSENSITIVE_MAP_FACTORY = () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

    private MapEntryUtils() {
        throw new UnsupportedOperationException("No instance");
    }

    /**
     * @param   The {@link Comparable} key type
     * @param   The associated entry value
     * @return     A {@link Comparator} for {@link java.util.Map.Entry}-ies that compares the key values
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static , V> Comparator> byKeyEntryComparator() {
        return (Comparator) BY_KEY_COMPARATOR;
    }

    public static class GenericMapPopulator> implements Supplier {
        private final M map;

        public GenericMapPopulator(M map) {
            this.map = Objects.requireNonNull(map, "No map provided");
        }

        public GenericMapPopulator put(K k, V v) {
            if (v == null) {
                return remove(k);
            }
            map.put(Objects.requireNonNull(k, "No key provided"), v);
            return this;
        }

        public GenericMapPopulator remove(K k) {
            map.remove(k);
            return this;
        }

        public GenericMapPopulator putAll(Map other) {
            if (isNotEmpty(other)) {
                other.forEach(this::put);
            }
            return this;
        }

        public GenericMapPopulator clear() {
            map.clear();
            return this;
        }

        @Override
        public M get() {
            return map;
        }
    }

    public static class MapBuilder extends GenericMapPopulator> {
        public MapBuilder() {
            super(new LinkedHashMap<>());
        }

        @Override
        public MapBuilder put(K k, V v) {
            super.put(k, v);
            return this;
        }

        @Override
        public MapBuilder remove(K k) {
            super.remove(k);
            return this;
        }

        @Override
        public MapBuilder putAll(Map other) {
            super.putAll(other);
            return this;
        }

        @Override
        public MapBuilder clear() {
            super.clear();
            return this;
        }

        public Map build() {
            return get();
        }

        public Map immutable() {
            return Collections.unmodifiableMap(build());
        }

        public static  MapBuilder builder() {
            return new MapBuilder<>();
        }

    }

    public static class NavigableMapBuilder extends GenericMapPopulator> {
        public NavigableMapBuilder(Comparator comparator) {
            super(new TreeMap<>(Objects.requireNonNull(comparator, "No comparator provided")));
        }

        @Override
        public NavigableMapBuilder put(K k, V v) {
            super.put(k, v);
            return this;
        }

        @Override
        public NavigableMapBuilder remove(K k) {
            super.remove(k);
            return this;
        }

        @Override
        public NavigableMapBuilder putAll(Map other) {
            super.putAll(other);
            return this;
        }

        @Override
        public NavigableMapBuilder clear() {
            super.clear();
            return this;
        }

        public NavigableMap build() {
            return get();
        }

        public NavigableMap immutable() {
            return Collections.unmodifiableNavigableMap(build());
        }

        public static , V> NavigableMapBuilder builder() {
            return builder(Comparator.naturalOrder());
        }

        public static  NavigableMapBuilder builder(Comparator comparator) {
            return new NavigableMapBuilder<>(comparator);
        }
    }

    public static class EnumMapBuilder, V> extends GenericMapPopulator> {
        public EnumMapBuilder(Class keyType) {
            super(new EnumMap<>(Objects.requireNonNull(keyType, "No enum class specified")));
        }

        @Override
        public EnumMapBuilder put(K k, V v) {
            super.put(k, v);
            return this;
        }

        @Override
        public EnumMapBuilder remove(K k) {
            super.remove(k);
            return this;
        }

        @Override
        public EnumMapBuilder putAll(Map other) {
            super.putAll(other);
            return this;
        }

        @Override
        public EnumMapBuilder clear() {
            super.clear();
            return this;
        }

        public Map build() {
            return get();
        }

        public Map immutable() {
            return Collections.unmodifiableMap(build());
        }

        public static , V> EnumMapBuilder builder(Class keyType) {
            return new EnumMapBuilder<>(keyType);
        }
    }

    public static int size(Map m) {
        return (m == null) ? 0 : m.size();
    }

    public static boolean isEmpty(Map m) {
        return size(m) <= 0;
    }

    public static boolean isNotEmpty(Map m) {
        return !isEmpty(m);
    }

    /**
     * @param   Type of mapped value
     * @return     A {@link Supplier} that returns a new {@link NavigableMap} whenever its {@code get()} method
     *             is invoked
     */
    @SuppressWarnings("unchecked")
    public static  Supplier> caseInsensitiveMap() {
        return CASE_INSENSITIVE_MAP_FACTORY;
    }

    /**
     * Flips between keys and values of an input map
     *
     * @param                        Original map key type
     * @param                        Original map value type
     * @param                        Flipped map type
     * @param  map                      The original map to flip
     * @param  mapCreator               The creator of the target map
     * @param  allowDuplicates          Whether to ignore duplicates on flip
     * @return                          The flipped map result
     * @throws IllegalArgumentException if allowDuplicates is {@code false} and a duplicate value found in the
     *                                  original map.
     */
    public static > M flipMap(
            Map map, Supplier mapCreator, boolean allowDuplicates) {
        M result = Objects.requireNonNull(mapCreator.get(), "No map created");
        map.forEach((key, value) -> {
            K prev = result.put(value, key);
            if ((prev != null) && (!allowDuplicates)) {
                ValidateUtils.throwIllegalArgumentException("Multiple values for key=%s: current=%s, previous=%s", value, key,
                        prev);
            }
        });

        return result;
    }

    @SafeVarargs
    public static > M mapValues(
            Function keyMapper, Supplier mapCreator, V... values) {
        return mapValues(keyMapper, mapCreator, GenericUtils.isEmpty(values) ? Collections.emptyList() : Arrays.asList(values));
    }

    /**
     * Creates a map out of a group of values
     *
     * @param          The key type
     * @param          The value type
     * @param          The result {@link Map} type
     * @param  keyMapper  The {@link Function} that generates a key for a given value. If the returned key is
     *                    {@code null} then the value is not mapped
     * @param  mapCreator The {@link Supplier} used to create/retrieve the result map - provided non-empty group of
     *                    values
     * @param  values     The values to be mapped
     * @return            The resulting {@link Map} - Note: no validation is made to ensure that 2 (or more)
     *                    values are not mapped to the same key
     */
    public static > M mapValues(
            Function keyMapper,
            Supplier mapCreator,
            Collection values) {
        M map = mapCreator.get();
        for (V v : values) {
            K k = keyMapper.apply(v);
            if (k == null) {
                continue; // debug breakpoint
            }
            map.put(k, v);
        }

        return map;
    }

    public static  NavigableMap toSortedMap(
            Iterable values, Function keyMapper,
            Function valueMapper, Comparator comparator) {
        return GenericUtils.stream(values).collect(toSortedMap(keyMapper, valueMapper, comparator));
    }

    public static  Collector> toSortedMap(
            Function keyMapper,
            Function valueMapper,
            Comparator comparator) {
        return Collectors.toMap(keyMapper, valueMapper, throwingMerger(), () -> new TreeMap<>(comparator));
    }

    public static  BinaryOperator throwingMerger() {
        return (u, v) -> {
            throw new IllegalStateException(String.format("Duplicate key %s", u));
        };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy