001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  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 distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.collections;
014
015import static java.util.Collections.*;
016
017import java.util.*;
018
019import org.apache.juneau.json.*;
020import org.apache.juneau.serializer.*;
021
022/**
023 * A fluent {@link TreeMap}.
024 *
025 * <p>
026 * Provides various convenience methods for creating and populating a sorted map with minimal code.
027 *
028 * <h5 class='figure'>Examples:</h5>
029 * <p class='bcode w800'>
030 *    <jc>// A map of string key/value pairs.</jc>
031 *    AMap&lt;String,String&gt; m = AMap.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>);
032 *
033 *    <jc>// Append to map.</jc>
034 *    m.a(<js>"baz"</js>, <js>"qux"</js>);
035 *
036 *    <jc>// Create an unmodifiable view of this list.</jc>
037 *    Map&lt;String,String&gt; m2 = m.unmodifiable();
038 *
039 *    <jc>// Convert to simplified JSON.</jc>
040 *    String json = m.asString();
041 *
042 *    <jc>// Convert to XML.</jc>
043 *    String json = m.asString(XmlSerializer.<jsf>DEFAULT</jsm>);
044 * </p>
045 *
046 * @param <K> The key type.
047 * @param <V> The value type.
048 */
049public final class ASortedMap<K,V> extends TreeMap<K,V> {
050
051   private static final long serialVersionUID = 1L;
052
053   //------------------------------------------------------------------------------------------------------------------
054   // Constructors.
055   //------------------------------------------------------------------------------------------------------------------
056
057   /**
058    * Constructor.
059    */
060   public ASortedMap() {
061      super();
062   }
063
064   /**
065    * Constructor.
066    *
067    * @param c Comparator to use for key comparison.
068    */
069   public ASortedMap(Comparator<K> c) {
070      super(c);
071   }
072
073   /**
074    * Copy constructor.
075    *
076    * @param copy The map to copy.
077    */
078   public ASortedMap(Map<K,V> copy) {
079      super(copy == null ? emptyMap() : copy);
080   }
081
082   //------------------------------------------------------------------------------------------------------------------
083   // Creators.
084   //------------------------------------------------------------------------------------------------------------------
085
086   /**
087    * Creates an empty map.
088    *
089    * @return A new empty map.
090    */
091   public static <K,V> ASortedMap<K,V> of() {
092      return new ASortedMap<>();
093   }
094
095   /**
096    * Creates a map with one entry.
097    *
098    * @param key Entry key.
099    * @param value Entry value.
100    * @return A new map with one entry.
101    */
102   public static <K,V> ASortedMap<K,V> of(K key, V value) {
103      return new ASortedMap<K,V>().a(key, value);
104   }
105
106   /**
107    * Creates a new map initialized with the specified contents.
108    *
109    * @param copy Initialize with these contents.  Can be <jk>null</jk>.
110    * @return A new map.  Never <jk>null</jk>.
111    */
112   public static <K,V> ASortedMap<K,V> of(Map<K,V> copy) {
113      return new ASortedMap<>(copy);
114   }
115
116   /**
117    * Convenience method for creating an unmodifiable list out of the specified collection.
118    *
119    * @param c The collection to add.
120    * @return An unmodifiable list, never <jk>null</jk>.
121    */
122   public static <K,V> SortedMap<K,V> unmodifiable(Map<K,V> c) {
123      if (c == null || c.isEmpty())
124         return Collections.emptySortedMap();
125      return new ASortedMap<>(c).unmodifiable();
126   }
127
128   /**
129    * Creates a copy of the collection if it's not <jk>null</jk>.
130    *
131    * @param c The initial values.
132    * @return A new list, or <jk>null</jk> if the collection is <jk>null</jk>.
133    */
134   public static <K,V> ASortedMap<K,V> nullable(Map<K,V> c) {
135      return c == null ? null : of(c);
136   }
137
138   //------------------------------------------------------------------------------------------------------------------
139   // Appenders.
140   //------------------------------------------------------------------------------------------------------------------
141
142   /**
143    * Add.
144    *
145    * <p>
146    * Adds an entry to this map.
147    *
148    * @param k The key.
149    * @param v The value.
150    * @return This object (for method chaining).
151    */
152   public ASortedMap<K,V> a(K k, V v) {
153      put(k, v);
154      return this;
155   }
156
157   /**
158    * Add all.
159    *
160    * <p>
161    * Appends all the entries in the specified map to this map.
162    *
163    * @param c The map to copy.
164    * @return This object (for method chaining).
165    */
166   public ASortedMap<K,V> aa(Map<K,V> c) {
167      if (c != null)
168         super.putAll(c);
169      return this;
170   }
171
172   //------------------------------------------------------------------------------------------------------------------
173   // Other methods.
174   //------------------------------------------------------------------------------------------------------------------
175
176   /**
177    * Returns an unmodifiable view of this set.
178    *
179    * @return An unmodifiable view of this set.
180    */
181   public SortedMap<K,V> unmodifiable() {
182      return isEmpty() ? emptySortedMap() : unmodifiableSortedMap(this);
183   }
184
185   /**
186    * Convert to a string using the specified serializer.
187    *
188    * @param ws The serializer to use to serialize this collection.
189    * @return This collection serialized to a string.
190    */
191   public String asString(WriterSerializer ws) {
192      return ws.toString(this);
193   }
194
195   /**
196    * Convert to Simplified JSON.
197    *
198    * @return This collection serialized to a string.
199    */
200   public String asString() {
201      return SimpleJsonSerializer.DEFAULT.toString(this);
202   }
203
204   /**
205    * Convert to Simplified JSON.
206    */
207   @Override /* Object */
208   public String toString() {
209      return asString(SimpleJsonSerializer.DEFAULT);
210   }
211}