All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.pmd.util.DataMap Maven / Gradle / Ivy

Go to download

PMD is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with Java and Apex, but supports 16 other languages. It comes with 400+ built-in rules. It can be extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query. Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce, Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL. Scala is supported, but there are currently no Scala rules available. Additionally, it includes CPD, the copy-paste-detector. CPD finds duplicated code in Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin, Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL.

There is a newer version: 7.5.0-metrics
Show newest version
/*
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 */

package net.sourceforge.pmd.util;

import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * An opaque, strongly typed heterogeneous data container. Data maps can
 * be set to accept only a certain type of key, with the type parameter.
 * The key can itself constrain the type of values, using its own type
 * parameter {@code T}.
 *
 * @param  Type of keys in this map.
 */
public final class DataMap {

    private Map, Object> map;

    private DataMap() {

    }

    /**
     * Set the mapping to the given data.
     *
     * @param key  Key
     * @param data Data mapped to the key
     * @param   Type of the data
     *
     * @return Previous value associated with the key (nullable)
     */
    @SuppressWarnings("unchecked")
    public  @Nullable T set(DataKey key, T data) {
        return (T) getMap().put(key, data);
    }

    /**
     * Retrieves the data currently mapped to the key.
     *
     * @param key Key
     * @param  Type of the data
     *
     * @return Value associated with the key (nullable)
     */
    @SuppressWarnings("unchecked")
    public  @Nullable T get(DataKey key) {
        return map == null ? null : (T) map.get(key);
    }

    @SuppressWarnings("unchecked")
    public  T getOrDefault(DataKey key, T defaultValue) {
        return map == null ? defaultValue : (T) map.getOrDefault(key, defaultValue);
    }

    /**
     * Retrieve the value, or compute it if it is missing.
     *
     * @param key      Key
     * @param supplier Supplier for a value
     * @param       Type of the data
     *
     * @return Value associated with the key (as nullable as the
     */
    @SuppressWarnings("unchecked")
    public  T computeIfAbsent(DataKey key, Supplier supplier) {
        return (T) getMap().computeIfAbsent(key, k -> supplier.get());
    }

    /**
     * Create or replace a mapping with a value computed from the current
     * value (or null if missing).
     *
     * @param key      Key
     * @param function Supplier for a value
     * @param       Type of the data
     *
     * @return Value returned by the parameter function
     */
    @SuppressWarnings("unchecked")
    public  T compute(DataKey key, Function function) {
        return (T) getMap().compute(key, (k, v) -> function.apply((T) v));
    }

    /**
     * @see Map#merge(Object, Object, BiFunction)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public  T merge(DataKey key, T value, BiFunction function) {
        return (T) getMap().merge(key, value, (BiFunction) function);
    }

    private Map, Object> getMap() {
        // the map is lazily created, it's only needed if set() is called
        // at least once, but get() might be called many more times, as
        // sometimes you cache a key sparsely on some nodes, and default
        // to the first parent for which the key is set. The default expected
        // max size is also 21, which is *way* bigger than what data maps
        // typically contain (1/2 keys)
        if (map == null) {
            map = new IdentityHashMap<>(1);
        }
        return map;
    }

    /**
     * Returns true if the given key has a non-null value in the map.
     *
     * @param key Key
     *
     * @return True if some value is set
     */
    public boolean isSet(DataKey key) {
        return map != null && map.containsKey(key);
    }

    public static  DataMap newDataMap() {
        return new DataMap<>();
    }

    public static  SimpleDataKey simpleDataKey(final String name) {
        return new SimpleDataKey<>(name);
    }

    /**
     * A key for type-safe access into a {@link DataMap}. Data keys use
     * reference identity and are only compared by reference within
     * {@link DataMap}.
     *
     * @param  Type of the family of keys this is a part of
     * @param  Type of the addressed data
     */
    public interface DataKey, T> {

    }

    public static class SimpleDataKey implements DataKey, T> {

        private final String name;

        SimpleDataKey(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy