001/*
002 * Configurate
003 * Copyright (C) zml and Configurate contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.spongepowered.configurate.util;
018
019import static java.util.Objects.requireNonNull;
020
021import java.util.Comparator;
022import java.util.LinkedHashMap;
023import java.util.Map;
024import java.util.concurrent.ConcurrentHashMap;
025import java.util.concurrent.ConcurrentMap;
026import java.util.concurrent.ConcurrentSkipListMap;
027
028/**
029 * Default implementations of {@link MapFactory}.
030 *
031 * @since 4.0.0
032 */
033public final class MapFactories {
034
035    private MapFactories() {}
036
037    /**
038     * Returns a {@link MapFactory} which creates maps without an order.
039     *
040     * @return a map factory which produces unordered maps
041     * @since 4.0.0
042     */
043    public static MapFactory unordered() {
044        return DefaultFactory.UNORDERED;
045    }
046
047    /**
048     * Returns a {@link MapFactory} which creates maps which are sorted using the given comparator.
049     *
050     * @param comparator the comparator used to sort the map keys
051     * @return a map factory which produces sorted maps
052     * @since 4.0.0
053     */
054    public static MapFactory sorted(final Comparator<Object> comparator) {
055        return new SortedMapFactory(requireNonNull(comparator, "comparator"));
056    }
057
058    /**
059     * Returns a {@link MapFactory} which creates maps which are naturally sorted.
060     *
061     * @return a map factory which produces naturally sorted maps
062     * @see Comparator#naturalOrder()
063     * @since 4.0.0
064     */
065    public static MapFactory sortedNatural() {
066        return DefaultFactory.SORTED_NATURAL;
067    }
068
069    /**
070     * Returns a {@link MapFactory} which creates maps which are sorted by insertion order.
071     *
072     * @return a map factory which produces maps sorted by insertion order
073     * @since 4.0.0
074     */
075    public static MapFactory insertionOrdered() {
076        return DefaultFactory.INSERTION_ORDERED;
077    }
078
079    private enum DefaultFactory implements MapFactory {
080        UNORDERED {
081            @Override
082            public <K, V> ConcurrentMap<K, V> create() {
083                return new ConcurrentHashMap<>();
084            }
085        },
086        SORTED_NATURAL {
087            @Override
088            public <K, V> ConcurrentMap<K, V> create() {
089                return new ConcurrentSkipListMap<>();
090            }
091        },
092        INSERTION_ORDERED {
093            @Override
094            public <K, V> Map<K, V> create() {
095                return new LinkedHashMap<>();
096            }
097        }
098    }
099
100    private static final class SortedMapFactory implements MapFactory {
101        private final Comparator<Object> comparator;
102
103        private SortedMapFactory(final Comparator<Object> comparator) {
104            this.comparator = comparator;
105        }
106
107        @Override
108        public <K, V> ConcurrentMap<K, V> create() {
109            return new ConcurrentSkipListMap<>(this.comparator);
110        }
111
112        @Override
113        public boolean equals(final Object obj) {
114            return obj instanceof SortedMapFactory && this.comparator.equals(((SortedMapFactory) obj).comparator);
115        }
116
117        @Override
118        public int hashCode() {
119            return this.comparator.hashCode();
120        }
121
122        @Override
123        public String toString() {
124            return "SortedMapFactory{comparator=" + this.comparator + '}';
125        }
126    }
127
128}