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

de.team33.patterns.collection.ceres.Mapping Maven / Gradle / Ivy

There is a newer version: 1.21.0
Show newest version
package de.team33.patterns.collection.ceres;

import de.team33.patterns.building.elara.LateBuilder;

import java.util.AbstractMap;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

/**
 * Some convenience methods to deal with {@link Map}s.
 */
@SuppressWarnings({"ProhibitedExceptionCaught", "unused"})
public final class Mapping {

    private Mapping() {
    }

    /**
     * Just like {@link Map#put(Object, Object) subject.put(key, value)} for a given subject,
     * but returns the subject.
     *
     * @throws UnsupportedOperationException if {@link Map#put(Object, Object)} is not supported by the
     *                                       subject.
     * @throws NullPointerException          if subject is {@code null} or ...
     * @throws NullPointerException          if the specified key or value is {@code null}
     *                                       and the subject does not permit {@code null}
     *                                       keys or values
     * @throws ClassCastException            if the class of the specified key or value prevents it
     *                                       from being put into the subject
     *                                       (may occur only if used raw or forced in a mismatched class context).
     * @throws IllegalArgumentException      if some property of the specified key or value prevents
     *                                       it from being stored in the subject.
     * @see Map#put(Object, Object)
     */
    public static > M put(final M subject, final K key, final V value) {
        subject.put(key, value);
        return subject;
    }

    /**
     * Just like {@link Map#putAll(Map) subject.putAll(origin)} for a given subject,
     * but returns the subject.
     *
     * @throws UnsupportedOperationException if {@link Map#putAll(Map)} is not supported by the subject.
     * @throws NullPointerException          if subject or origin is {@code null} or ...
     * @throws NullPointerException          if any of the specified keys or values are
     *                                       {@code null} and the {@code subject} does not permit {@code null}
     *                                       keys or values.
     * @throws ClassCastException            if the class of any specified key or value prevents it
     *                                       from being put into the subject
     *                                       (may occur only if used raw or forced in a mismatched class context).
     * @throws IllegalArgumentException      if some property of any key or value in the specified
     *                                       origin prevents it from being stored in the subject.
     * @see Map#putAll(Map)
     */
    public static > M putAll(final M subject,
                                                                       final Map origin) {
        subject.putAll(origin);
        return subject;
    }

    /**
     * Just like {@link Map#clear() subject.clear()} for a given subject
     * but returns the subject.
     *
     * @throws UnsupportedOperationException if {@link Collection#clear()} is not supported by the subject.
     * @throws NullPointerException          if subject is {@code null}.
     * @see Map#clear()
     */
    public static > M clear(final M subject) {
        subject.clear();
        return subject;
    }

    /**
     * Just like {@link Map#remove(Object) subject.remove(key)} for a given subject
     * but returns the subject.
     * 

* Avoids an unnecessary {@link ClassCastException} or {@link NullPointerException} which might be caused by * {@link Map#remove(Object)} when the subject does not support the requested key. * * @throws UnsupportedOperationException if {@link Map#remove(Object)} is not supported by the subject. * @throws NullPointerException if subject is {@code null}. */ public static > M remove(final M subject, final Object key) { try { subject.remove(key); } catch (final NullPointerException | ClassCastException caught) { if (null == subject) { throw caught; // expected to be a NullPointerException } // --> can not contain // --> simply does not contain // --> Nothing else to do. } return subject; } /** * Just like {@link Map#containsKey(Object)} for a given subject. *

* Avoids an unnecessary {@link ClassCastException} or {@link NullPointerException} which might be caused by * {@link Map#containsKey(Object)} when the subject does not support the requested key. * * @throws NullPointerException if subject is {@code null}. */ public static boolean containsKey(final Map subject, final Object key) { try { return subject.containsKey(key); } catch (final NullPointerException | ClassCastException caught) { if (null == subject) { throw caught; // expected to be a NullPointerException } else { // --> can not contain // --> simply does not contain ... return false; } } } /** * Just like {@link Map#containsValue(Object)} for a given subject. *

* Avoids an unnecessary {@link ClassCastException} or {@link NullPointerException} which might be caused by * {@link Map#containsValue(Object)} when the subject does not support the requested value. * * @throws NullPointerException if subject is {@code null}. */ public static boolean containsValue(final Map subject, final Object value) { try { return subject.containsValue(value); } catch (final NullPointerException | ClassCastException caught) { if (null == subject) { throw caught; // expected to be a NullPointerException } else { // --> can not contain // --> simply does not contain ... return false; } } } /** * Just like {@link Map#get(Object)} for a given subject. *

* Avoids an unnecessary {@link ClassCastException} or {@link NullPointerException} which might be caused by * {@link Map#get(Object)} when the subject does not support the requested key. * * @return The value or {@code null} if the subject doesn't contain (an entry for) the key. * @throws NullPointerException if subject is {@code null}. */ public static V get(final Map subject, final Object key) { try { return subject.get(key); } catch (final NullPointerException | ClassCastException caught) { if (null == subject) { throw caught; // expected to be a NullPointerException } else { // --> can not contain // --> simply does not contain // --> as specified for Map ... // noinspection ReturnOfNull return null; } } } /** * Supplies a proxy for a given {@link Map subject} that may be used to implement some {@link Map}-specific * methods, e.g.: *

    *
  • {@link Object#toString()}
  • *
  • {@link Map#equals(Object)}
  • *
  • {@link Map#hashCode()}
  • *
  • ...
  • *
* * @param subject A {@link Map}, that at least provides independently ... *
    *
  • {@link Map#entrySet()}
  • *
*/ @SuppressWarnings("AnonymousInnerClass") public static Map proxy(final Map subject) { //noinspection ReturnOfInnerClass return new AbstractMap() { @Override public Set> entrySet() { return subject.entrySet(); } }; } /** * Returns a new {@link Builder} for target instances as supplied by the given {@link Supplier}. * * @param The key type of the target instance. * @param The value type of the target instance. * @param The final type of the target instance, at least {@link Map}. */ public static > Builder builder(final Supplier newTarget) { return new Builder<>(newTarget, Builder.class); } /** * Returns a new {@link Charger} for a given target instance. * * @param The key type of the target instance. * @param The value type of the target instance. * @param The final type of the target instance, at least {@link Map}. */ public static > Charger charger(final M target) { return new Charger<>(target, Charger.class); } /** * Utility interface to set up a target instance of {@link Map}. * * @param The key type of the target instance. * @param The value type of the target instance. * @param The final type of the target instance, at least {@link Map}. * @param The final type of the Setup implementation. */ @SuppressWarnings("ClassNameSameAsAncestorName") @FunctionalInterface public interface Setup, S extends Setup> extends de.team33.patterns.building.elara.Setup { /** * Puts a pair of key / value to the instance to be set up. * * @throws UnsupportedOperationException if {@link Map#put(Object, Object)} is not supported by the instance * to be set up. * @throws NullPointerException if the specified key or value is {@code null} * and the instance to be set up does not permit {@code null} * keys or values * @throws ClassCastException if the class of the specified key or value prevents * it from being put into the instance to be set up * (may occur only if used raw or forced in a mismatched class context). * @throws IllegalArgumentException if some property of the specified key or value * prevents it from being stored in the instance to be set up. * @see Map#put(Object, Object) * @see Mapping#put(Map, Object, Object) */ default S put(final K key, final V value) { return setup(target -> Mapping.put(target, key, value)); } /** * Removes a pair of a given key and its associated value from the instance to be set up. *

* Avoids an unnecessary {@link ClassCastException} or {@link NullPointerException} which might be caused by * {@link Map#remove(Object)} when the instance to be set up does not support the requested key. * * @throws UnsupportedOperationException if {@link Map#remove(Object)} is not supported by the * subject. * @see Map#remove(Object) * @see Mapping#remove(Map, Object) */ default S remove(final Object key) { return setup(target -> Mapping.remove(target, key)); } /** * Puts multiple pairs of key / value to the instance to be set up. *

* If origin is {@code null} it will be treated as an empty {@link Map}. * * @throws UnsupportedOperationException if {@link Map#putAll(Map)} is not supported * by the instance to be set up. * @throws NullPointerException if any of the specified keys or values are * {@code null} and the instance to be set up does not permit * {@code null} keys or values. * @throws ClassCastException if the class of any specified key or value prevents it * from being put into the subject * (may occur only if used raw or forced in a mismatched class context). * @throws IllegalArgumentException if some property of any key or value in the specified * origin prevents it from being stored in the subject. * @see Map#putAll(Map) * @see Mapping#putAll(Map, Map) */ default S putAll(final Map origin) { return setup(target -> Mapping.putAll(target, (null == origin) ? Collections.emptyMap() : origin)); } /** * Removes all pairs of key / value from the instance to be set up. * * @throws UnsupportedOperationException if {@link Collection#clear()} is not supported by the subject. * @see Map#clear() * @see Mapping#clear(Map) */ default S clear() { return setup(Mapping::clear); } } /** * Builder implementation to build target instances of {@link Map}. *

* Use {@link #builder(Supplier)} to get an instance. * * @param The key type of the target instance. * @param The value type of the target instance. * @param The final type of the target instance, at least {@link Map}. */ public static class Builder> extends LateBuilder> implements Setup> { @SuppressWarnings({"rawtypes", "unchecked"}) private Builder(final Supplier newResult, final Class builderClass) { super(newResult, builderClass); } } /** * Charger implementation to charge target instances of {@link Map}. *

* Use {@link #charger(Map)} to get an instance. * * @param The key type of the target instance. * @param The value type of the target instance. * @param The final type of the target instance, at least {@link Map}. */ @SuppressWarnings("ClassNameSameAsAncestorName") public static class Charger> extends de.team33.patterns.building.elara.Charger> implements Setup> { @SuppressWarnings({"rawtypes", "unchecked"}) private Charger(final M target, final Class builderClass) { super(target, builderClass); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy