/******************************************************************************* * Copyright 2017 Capital One Services, LLC and Bitwise, Inc. * Licensed 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 hydrograph.engine.core.component.utils; import java.util.*; /** * The Class OrderedProperties. * * @author Bitwise * */ public class OrderedProperties extends Properties { private static final long serialVersionUID = -1037857012056350940L; /** * This object stores the property keys in order. This object is merely a * copy of the property keys and has no connection to the actual underlying * properties object. Care should be taken to properly maintain the keys in * this object. Also, this object should not be directly exposed to the * consumers. Any additions / deletion of the keys to this object will have * no effect on the underlying property object. */ private Set<Object> keySet = new LinkedHashSet<Object>(); /** * Creates an empty property list with no default values. */ public OrderedProperties() { super(); } /** * Returns an enumeration of the property keys. The order of keys is * maintained. * * @return an enumeration of the property keys in order. * @see Enumeration * @see java.util.Hashtable#elements() * @see #keySet() * @see Map * @see java.util.Hashtable#keys() */ @Override public Enumeration<Object> keys() { return Collections.enumeration(keySet); } /** * Returns a {@link Set} of the property keys in order. This method just * returns a read-only object. Changes made on this object have no effect on * the actual properties object. Use {@link #put(Object, Object) put()} or * {@link #remove(Object) remove()} methods to add or remove keys / values * from the properties object. * * @return a {@link Set} of the property keys in order. */ @Override public Set<Object> keySet() { // Defensive copying to avoid modifying internal object by the consumer return new LinkedHashSet<Object>(keySet); } /** * Maps the specified <code>key</code> to the specified <code>value</code> * in this properties object. Neither the key nor the value can be * <code>null</code>. * <p> * * The value can be retrieved by calling the <code>get</code> method with a * key that is equal to the original key. * <p> * * The order of the keys is retained in this properties object. Keys can be * retreived in the same order they are put in the properties object. * * @param key * the property key * @param value * the value * @return the previous value of the specified key, or <code>null</code> if * it did not have one * @exception NullPointerException * if the key or value is <code>null</code> * @see Object#equals(Object) * @see #get(Object) * * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object) */ @Override public synchronized Object put(Object key, Object value) { if (!keySet.contains(key)) { keySet.add(key); } return super.put(key, value); } /** * Removes the key (and its corresponding value) from this properties * object. This method does nothing if the key is not present. * * @param key * the key that needs to be removed * @return the value to which the key had been mapped in this properties * object, or <code>null</code> if the key did not have a mapping * @throws NullPointerException * if the key is <code>null</code> * @see java.util.Hashtable#remove(java.lang.Object) */ @Override public synchronized Object remove(Object key) { keySet.remove(key); return super.remove(key); } /** * Copies all of the mappings from the specified map to this properties * object. These mappings will replace any mappings that this properties * object had for any of the keys currently in the specified map. * <p> * * The map implementation used for <code>values</code> parameter drives the * order of the keys in this properties object. * * @param values * mappings to be stored in this map * @throws NullPointerException * if the specified map is null * * @see java.util.Hashtable#putAll(java.util.Map) */ @Override public synchronized void putAll(Map values) { for (Object key : values.keySet()) { if (!containsKey(key)) { keySet.add(key); } } super.putAll(values); } /** * Returns an enumeration of all the keys in this property list in the * order. * * @return an enumeration of all the keys in this property list in order * @throws ClassCastException * if any key in this property list is not a string. * @see java.util.Enumeration * @see java.util.Properties#defaults * @see #stringPropertyNames * @see java.util.Properties#propertyNames() */ @Override public Enumeration<?> propertyNames() { return Collections.enumeration(keySet); } /** * Returns a {@link Set} view of the mappings contained in this properties * object. The order of property keys is maintained. * * @see java.util.Hashtable#entrySet() */ @Override public Set<Map.Entry<Object, Object>> entrySet() { Map<Object, Object> map = new LinkedHashMap<Object, Object>(); for (Object key : keySet) { map.put(key, this.get(key)); } return map.entrySet(); } /** * Returns an enumeration of all the keys in this property list in the * order. The key fields are explicitly cast to String. * * @return an enumeration of all the keys in this property list in order * @throws ClassCastException * if any key in this property list is not a string. * @see java.util.Enumeration * @see java.util.Properties#defaults * @see #propertyNames * @see java.util.Properties#stringPropertyNames() */ @Override public Set<String> stringPropertyNames() { Set<String> stringKeySet = new LinkedHashSet<String>(); for (Object key : keySet) { stringKeySet.add(key.toString()); // Convert Set<Object> to // Set<String> } return stringKeySet; } }