<commit_before>/*
 *  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 dk.statsbiblioteket.summa.common.util;

import dk.statsbiblioteket.summa.common.configuration.ConfigurationStorageException;
import dk.statsbiblioteket.util.qa.QAInfo;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A wrapper of a Map which provides convenience-methods for accessing specific
 * types stored in the map. The map is forgiving, so storing an integer with
 * put("foo", "87") and retrieving it with getInt("foo") will work.
 * </p><p>
 * For all the convenience methods it holds true that empty underlying String-
 * values are equaled to null.
 * </p><p>
 * As a deviation from normal map-practice, the convenience methods and
 * {@link #get(String)} throws a NullPointerException if no value can be found
 * for the given key.
 */
@QAInfo(level = QAInfo.Level.NORMAL,
        state = QAInfo.State.QA_NEEDED,
        author = "te",
        comment = "Some methods needs JavaDoc")
public class ConvenientMap extends HashMap<String, Serializable> {
    public static final long serialVersionUID = 384681318L;
    private static Log log = LogFactory.getLog(ConvenientMap.class);

    public ConvenientMap(Serializable... args) {
        super();
        log.trace("Constructing with " + args.length + " arguments");
        if (args.length % 2 != 0) {
            throw new IllegalArgumentException("There must be an even number of arguments. Argument count was "
                                               + args.length);
        }
        for (int i = 0 ; i < args.length ; i += 2) {
            put((String)args[i], args[i+1]);
        }
    }

    /**
     * Partial JSON-absorber. Adds all readily available JSON key:value-pairs
     * to the map.
     * @param json a list of key:value-pairs.
     */
    public void addJSON(String json) {
        log.trace("Adding JSON-object " + json);
        JSONObject jsonObject = JSONObject.fromObject(json);
        addJSON(jsonObject);
    }

    private void addJSON(JSONObject jsonObject) {
        for (int i = 0 ; i < jsonObject.size() ; i++) {
            for (Object o: jsonObject.entrySet()) {
                ListOrderedMap.Entry entry = (ListOrderedMap.Entry)o;
                if (log.isTraceEnabled()) {
                    log.trace("Putting " + entry.getKey() + ", " + entry.getValue());
                }
                // TODO Make better error messages on cast fail
                put((String)entry.getKey(), (Serializable)entry.getValue());
            }
        }
    }

    public Serializable get(String key) {
        Serializable value = super.get(key);
        if (value == null) {
            throw new NullPointerException("Unable to locate key '" + key + "'");
        }
        return value;
    }
    private String getStringNONPE(String key) {
        Object o = super.get(key);
        return o == null ? null : "".equals(o) ? null : (String)o;
    }

    public String getString(String key) {
        Object o = get(key);
        if (o instanceof String) {
            return (String)o;
        }
        return o.toString();
    }
    public String getString(String key, String defaultValue) {
        String res = getStringNONPE(key);
        return res == null ? defaultValue : res;
    }

    public Integer getInt(String key) {
        Object o = get(key);
        //noinspection OverlyBroadCatchBlock
        try {
            if (o instanceof Integer) {
                return (Integer)o;
            }
            /* Converting to a String and parsing that is a catch-all method
             * for cases where the value is an Long or Character */
            return Integer.parseInt(o.toString());
        } catch (Exception e) {
            log.warn(String.format("Exception extracting int for key '%s'", key), e);
            return null;
        }
    }
    public Integer getInt(String key, Integer defaultValue) {
        try {
            return getInt(key);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public Long getLong(String key) {
        Object o = get(key);
        //noinspection OverlyBroadCatchBlock
        try {
            if (o instanceof Long) {<commit_msg>Feature: Added String-getter with support for the empty String<commit_after>/*
 *  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 dk.statsbiblioteket.summa.common.util;

import dk.statsbiblioteket.summa.common.configuration.ConfigurationStorageException;
import dk.statsbiblioteket.util.qa.QAInfo;
import net.sf.json.JSONObject;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.Serializable;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A wrapper of a Map which provides convenience-methods for accessing specific
 * types stored in the map. The map is forgiving, so storing an integer with
 * put("foo", "87") and retrieving it with getInt("foo") will work.
 * </p><p>
 * For all the convenience methods it holds true that empty underlying String-
 * values are equaled to null.
 * </p><p>
 * As a deviation from normal map-practice, the convenience methods and
 * {@link #get(String)} throws a NullPointerException if no value can be found
 * for the given key.
 */
@QAInfo(level = QAInfo.Level.NORMAL,
        state = QAInfo.State.QA_NEEDED,
        author = "te",
        comment = "Some methods needs JavaDoc")
public class ConvenientMap extends HashMap<String, Serializable> {
    public static final long serialVersionUID = 384681319L;
    private static Log log = LogFactory.getLog(ConvenientMap.class);

    public ConvenientMap(Serializable... args) {
        super();
        log.trace("Constructing with " + args.length + " arguments");
        if (args.length % 2 != 0) {
            throw new IllegalArgumentException("There must be an even number of arguments. Argument count was "
                                               + args.length);
        }
        for (int i = 0 ; i < args.length ; i += 2) {
            put((String)args[i], args[i+1]);
        }
    }

    /**
     * Partial JSON-absorber. Adds all readily available JSON key:value-pairs
     * to the map.
     * @param json a list of key:value-pairs.
     */
    public void addJSON(String json) {
        log.trace("Adding JSON-object " + json);
        JSONObject jsonObject = JSONObject.fromObject(json);
        addJSON(jsonObject);
    }

    private void addJSON(JSONObject jsonObject) {
        for (int i = 0 ; i < jsonObject.size() ; i++) {
            for (Object o: jsonObject.entrySet()) {
                ListOrderedMap.Entry entry = (ListOrderedMap.Entry)o;
                if (log.isTraceEnabled()) {
                    log.trace("Putting " + entry.getKey() + ", " + entry.getValue());
                }
                // TODO Make better error messages on cast fail
                put((String)entry.getKey(), (Serializable)entry.getValue());
            }
        }
    }

    public Serializable get(String key) {
        Serializable value = super.get(key);
        if (value == null) {
            throw new NullPointerException("Unable to locate key '" + key + "'");
        }
        return value;
    }
    private String getStringNONPE(String key) {
        Object o = super.get(key);
        return o == null ? null : "".equals(o) ? null : (String)o;
    }

    public String getString(String key) {
        Object o = get(key);
        if (o instanceof String) {
            return (String)o;
        }
        return o.toString();
    }
    public String getString(String key, String defaultValue) {
        String res = getStringNONPE(key);
        return res == null ? defaultValue : res;
    }

    public String getStringAlsoEmpty(String key, String defaultValue) {
        Object o = super.get(key);
        return o == null ? defaultValue : (String)o;
    }

    public Integer getInt(String key) {
        Object o = get(key);
        //noinspection OverlyBroadCatchBlock
        try {
            if (o instanceof Integer) {
                return (Integer)o;
            }
            /* Converting to a String and parsing that is a catch-all method
             * for cases where the value is an Long or Character */
            return Integer.parseInt(o.toString());
        } catch (Exception e) {
            log.warn(String.format("Exception extracting int for key '%s'", key), e);
            return null;
        }
    }
    public Integer getInt(String key, Integer defaultValue) {
        try {
            return getInt(key);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public Long getLong(String key) {
        Object o = get(key);
        //noinspection OverlyBroadCatchBlock
        try {
            if (o instanceof Long) {
{'fraction_non_alphanumeric': 0.1012918379330593, 'fraction_numerical': 0.004110393423370522, 'mean_word_length': 2.333007175472929, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6204932', 'n_tokens_mistral': 2844, 'n_tokens_neox': 2774, 'n_words': 918}