/******************************************************************************* *******************************************************************************/ package at.gv.egiz.eaaf.core.impl.utils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import org.apache.commons.lang3.StringUtils; /** * @author tlenz * */ public class KeyValueUtils { public static final String KEY_DELIMITER = "."; public static final String CSV_DELIMITER = ","; /** * Convert Java properties into a Map *

* Important: The key/values from properties must be of type String! * * @param properties * @return */ public static Map convertPropertiesToMap(Properties properties) { return new HashMap((Map) properties); //INFO Java8 solution ;) // return properties.entrySet().stream().collect( // Collectors.toMap( // e -> e.getKey().toString(), // e -> e.getValue().toString() // ) // ); } /** * Extract the first child of an input key after a the prefix * * @param key Full input key * @param prefix Prefix * @return Child key {String} if it exists or null */ public static String getFirstChildAfterPrefix(String key, String prefix) { String idAfterPrefix = removePrefixFromKey(key, prefix); if (idAfterPrefix != null) { int index = idAfterPrefix.indexOf(KEY_DELIMITER); if (index > 0) { String adding = idAfterPrefix.substring(0, index); if (!(adding.isEmpty())) { return adding; } } else if (!(idAfterPrefix.isEmpty())) { return idAfterPrefix; } } return null; } /** * Extract the prefix from an input key * * @param key Full input key * @param suffix Suffix of this key * @return Prefix {String} of the key or null if input key does not ends with postfix string */ public static String getPrefixFromKey(String key, String suffix) { if (key != null && key.endsWith(suffix)) { String idPreforeSuffix = key.substring(0, key.length()-suffix.length()); if (idPreforeSuffix.endsWith(KEY_DELIMITER)) return idPreforeSuffix.substring(0, idPreforeSuffix.length()-1); else return idPreforeSuffix; } return null; } /** * Remove a prefix string from a key * * @param key Full input key * @param prefix Prefix, which should be removed * @return The suffix of the input key or null if the input does not starts with the prefix */ public static String removePrefixFromKey(String key, String prefix) { if (prefix == null) prefix = new String(); if (key!=null && key.startsWith(prefix)) { String afterPrefix = key.substring(prefix.length()); int index = afterPrefix.indexOf(KEY_DELIMITER); if (index == 0) { afterPrefix = afterPrefix.substring(1); } return afterPrefix; } return null; } /** * Remove a prefix string from all keys in {Map} of key/value pairs * * @param keys Input data of key/value pairs * @param prefix Prefix which should be removed * @return {Map} of key/value pairs without prefix in key, but never null */ public static Map removePrefixFromKeys(Map keys, String prefix) { Map result = new HashMap(); Iterator> interator = keys.entrySet().iterator(); while(interator.hasNext()) { Entry el = interator.next(); String newKey = removePrefixFromKey(el.getKey(), prefix); if (StringUtils.isNotEmpty(newKey)) { result.put(newKey, el.getValue()); } } return result; } /** * Get a subset of key/value pairs which starts with a prefix string * The Prefix is removed from the key * * @param keys Input data of key/value pairs * @param prefix Prefix string * @return {Map} of key/value pairs without prefix in key, but never null */ public static Map getSubSetWithPrefix(Map keys, String prefix) { return removePrefixFromKeys(keys, prefix); } /** * Add a prefix to key/value pairs to make the key absolute according to key namespace convention * * @param input Input key/value pairs which should be updated * @param prefix Key prefix, which should be added if the key is not absolute * @param absolutIdentifier Key identifier, which indicates an absolute key * @return {Map} of key/value pairs in which all keys are absolute but never null */ public static Map makeKeysAbsolut(Map input, String prefix, String absolutIdentifier) { Map result = new HashMap(); Iterator> interator = input.entrySet().iterator(); while(interator.hasNext()) { Entry el = interator.next(); if (!el.getKey().startsWith(absolutIdentifier)) { //key is not absolute -> add prefix result.put(prefix + KEY_DELIMITER + el.getKey(), el.getValue()); } else { //key is absolute result.put(el.getKey(), el.getValue()); } } return result; } /** * Get the parent key string from an input key * * @param key input key * @return parent key or the empty String if no parent exists */ public static String getParentKey(String key) { if (StringUtils.isNotEmpty(key)) { int index = key.lastIndexOf(KEY_DELIMITER); if (index > 0) { return key.substring(0, index); } } return new String(); } /** * Find the highest free list counter * * @param input Array of list keys * @param listPrefix {String} prefix of the list * @return {int} highest free list counter */ public static int findNextFreeListCounter(String[] input, String listPrefix) { List counters = new ArrayList(); if (input == null || input.length == 0) return 0; else { for (String key : input) { String listIndex = getFirstChildAfterPrefix(key, listPrefix); counters.add(Integer.parseInt(listIndex)); } Collections.sort(counters); return counters.get(counters.size()-1) + 1; } } /** * Find the highest free list counter * * @param keySet {Set} of list keys * @param listPrefix {String} prefix of the list * @return {int} highest free list counter */ public static int findNextFreeListCounter(Set keySet, String listPrefix) { if (keySet.isEmpty()) return 0; String[] array = new String[keySet.size()]; keySet.toArray(array); return findNextFreeListCounter(array, listPrefix); } /** * Normalize a CSV encoded list of value of an key/value pair * * This method removes all whitespace at the begin or the * end of CSV values and remove newLine signs at the end of value. * The ',' is used as list delimiter * * @param value CSV encoded input data * @return normalized CSV encoded data or null if {value} is null or empty */ public static String normalizeCSVValueString(String value) { String normalizedCodes = null; if (StringUtils.isNotEmpty(value)) { String[] codes = value.split(CSV_DELIMITER); for (String el: codes) { if (normalizedCodes == null) normalizedCodes = StringUtils.chomp(el.trim()); else normalizedCodes += "," + StringUtils.chomp(el.trim()); } } return normalizedCodes; } /** * Check a String if it is a comma separated list of values * * This method uses the ',' as list delimiter. * * @param value CSV encoded input data * @return true if the input data contains a ',' and has more then 1 list element, otherwise false */ public static boolean isCSVValueString(String value) { if (StringUtils.isNotEmpty(value)) { String[] codes = value.split(CSV_DELIMITER); if (codes.length >= 2) { if (StringUtils.isNotEmpty(codes[1].trim())) return true; } } return false; } /** * Convert a CSV list to a List of CSV values *

* This method removes all whitespace at the begin or the * end of CSV values and remove newLine signs at the end of value. * The ',' is used as list delimiter * * @param csv CSV encoded input data * @return List of CSV normalized values, but never null */ public static List getListOfCSVValues(String csv) { List list = new ArrayList(); if (StringUtils.isNotEmpty(csv)) { String[] values = csv.split(CSV_DELIMITER); for (String el: values) list.add(el.trim()); } return list; } /** * This method remove all newline delimiter (\n or \r\n) from input data * * @param value Input String * @return Input String without newline characters */ public static String removeAllNewlineFromString(String value) { return value.replaceAll("(\\t|\\r?\\n)+", ""); } }