| // *************************************************************************************************************************** |
| // * 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.juneau.collections; |
| |
| import static java.util.Collections.*; |
| |
| import java.util.*; |
| import java.util.function.*; |
| |
| import org.apache.juneau.*; |
| import org.apache.juneau.json.*; |
| import org.apache.juneau.serializer.*; |
| |
| /** |
| * A fluent {@link LinkedHashMap}. |
| * |
| * <p> |
| * Provides various convenience methods for creating and populating a map with minimal code. |
| * |
| * <h5 class='figure'>Examples:</h5> |
| * <p class='bcode w800'> |
| * <jc>// A map of string key/value pairs.</jc> |
| * AMap<String,String> m = AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>); |
| * |
| * <jc>// Append to map.</jc> |
| * m.a(<js>"baz"</js>, <js>"qux"</js>); |
| * |
| * <jc>// Create an unmodifiable view of this list.</jc> |
| * Map<String,String> m2 = m.unmodifiable(); |
| * |
| * <jc>// Convert to simplified JSON.</jc> |
| * String json = m.asString(); |
| * |
| * <jc>// Convert to XML.</jc> |
| * String json = m.asString(XmlSerializer.<jsf>DEFAULT</jsm>); |
| * </p> |
| * |
| * @param <K> The key type. |
| * @param <V> The value type. |
| */ |
| public class AMap<K,V> extends LinkedHashMap<K,V> { |
| |
| private static final long serialVersionUID = 1L; |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| // Constructors. |
| //------------------------------------------------------------------------------------------------------------------ |
| |
| /** |
| * Constructor. |
| */ |
| public AMap() {} |
| |
| /** |
| * Copy constructor. |
| * |
| * @param copy The map to copy. Can be <jk>null</jk>. |
| */ |
| public AMap(Map<K,V> copy) { |
| super(copy == null ? emptyMap() : copy); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| // Creators. |
| //------------------------------------------------------------------------------------------------------------------ |
| |
| /** |
| * Creates an empty map. |
| * |
| * @return A new empty map. |
| */ |
| public static <K,V> AMap<K,V> create() { |
| return new AMap<>(); |
| } |
| |
| /** |
| * Creates a map with one entry. |
| * |
| * @param key Entry key. |
| * @param value Entry value. |
| * @return A new map with one entry. |
| */ |
| public static <K,V> AMap<K,V> of(K key, V value) { |
| return new AMap<K,V>().a(key, value); |
| } |
| |
| /** |
| * Creates a map out of a list of key/value pairs. |
| * |
| * @param <K> The key type. |
| * @param <V> The value type. |
| * @param parameters |
| * The parameters. |
| * <br>Must be an even number of parameters. |
| * <br>It's up to you to ensure that the parameters are the correct type. |
| * @return A new map. |
| */ |
| @SuppressWarnings("unchecked") |
| public static <K,V> AMap<K,V> ofPairs(Object...parameters) { |
| AMap<K,V> m = AMap.create(); |
| if (parameters.length % 2 != 0) |
| throw new BasicRuntimeException("Odd number of parameters passed into AMap.ofPairs()"); |
| for (int i = 0; i < parameters.length; i+=2) |
| m.put((K)parameters[i], (V)parameters[i+1]); |
| return m; |
| } |
| |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2) { |
| return AMap.of(k1,v1).a(k2,v2); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3).a(k4,v4); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3).a(k4,v4).a(k5,v5); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3).a(k4,v4).a(k5,v5).a(k6,v6); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3).a(k4,v4).a(k5,v5).a(k6,v6).a(k7,v7); |
| } |
| |
| @SuppressWarnings("javadoc") |
| public static <K,V> AMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { |
| return AMap.of(k1,v1).a(k2,v2).a(k3,v3).a(k4,v4).a(k5,v5).a(k6,v6).a(k7,v7).a(k8,v8); |
| } |
| |
| /** |
| * Creates a new map initialized with the specified contents. |
| * |
| * @param copy Initialize with these contents. Can be <jk>null</jk>. |
| * @return A new map. Never <jk>null</jk>. |
| */ |
| public static <K,V> AMap<K,V> of(Map<K,V> copy) { |
| return new AMap<>(copy); |
| } |
| |
| /** |
| * Creates an unmodifiable copy of the specified map. |
| * |
| * @param copy The map to copy. |
| * @return A new unmodifiable map, never <jk>null</jk>. |
| */ |
| public static <K,V> Map<K,V> unmodifiable(Map<K,V> copy) { |
| if (copy == null || copy.isEmpty()) |
| return emptyMap(); |
| return new AMap<>(copy).unmodifiable(); |
| } |
| |
| /** |
| * Creates a copy of the collection if it's not <jk>null</jk>. |
| * |
| * @param c The initial values. |
| * @return A new list, or <jk>null</jk> if the collection is <jk>null</jk>. |
| */ |
| public static <K,V> AMap<K,V> nullable(Map<K,V> c) { |
| return c == null ? null : of(c); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| // Appenders. |
| //------------------------------------------------------------------------------------------------------------------ |
| |
| /** |
| * Adds an entry to this map. |
| * |
| * @param key The key. |
| * @param value The value. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> append(K key, V value) { |
| put(key, value); |
| return this; |
| } |
| |
| /** |
| * Appends all the entries in the specified map to this map. |
| * |
| * @param values The map to copy. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> append(Map<K,V> values) { |
| super.putAll(values); |
| return this; |
| } |
| |
| /** |
| * Same as {@link #append(Object,Object)}. |
| * |
| * @param key The key. |
| * @param value The value. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> a(K key, V value) { |
| return append(key, value); |
| } |
| |
| /** |
| * Same as {@link #append(Map)}. |
| * |
| * @param values The map to copy. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> a(Map<K,V> values) { |
| return append(values); |
| } |
| |
| /** |
| * Add if flag is <jk>true</jk>. |
| * |
| * @param flag The flag to check. |
| * @param key The key. |
| * @param value The value. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> appendIf(boolean flag, K key, V value) { |
| if (flag) |
| append(key, value); |
| return this; |
| } |
| |
| /** |
| * Add if predicate matches value. |
| * |
| * @param test The predicate to match against. |
| * @param key The key. |
| * @param value The value. |
| * @return This object (for method chaining). |
| */ |
| public AMap<K,V> appendIf(Predicate<Object> test, K key, V value) { |
| return appendIf(test.test(value), key, value); |
| } |
| |
| //------------------------------------------------------------------------------------------------------------------ |
| // Other methods. |
| //------------------------------------------------------------------------------------------------------------------ |
| |
| /** |
| * Returns an unmodifiable view of this map. |
| * |
| * @return An unmodifiable view of this map. |
| */ |
| public Map<K,V> unmodifiable() { |
| return this.isEmpty() ? emptyMap() : unmodifiableMap(this); |
| } |
| |
| /** |
| * Convert to a string using the specified serializer. |
| * |
| * @param ws The serializer to use to serialize this collection. |
| * @return This collection serialized to a string. |
| */ |
| public String asString(WriterSerializer ws) { |
| return ws.toString(this); |
| } |
| |
| /** |
| * Convert to Simplified JSON. |
| * |
| * @return This collection serialized to a string. |
| */ |
| public String asString() { |
| return SimpleJsonSerializer.DEFAULT.toString(this); |
| } |
| |
| /** |
| * Convert to Simplified JSON. |
| */ |
| @Override /* Object */ |
| public String toString() { |
| return asString(SimpleJsonSerializer.DEFAULT); |
| } |
| } |