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

org.opendaylight.yangtools.util.ImmutableOffsetMapTemplate Maven / Gradle / Ivy

There is a newer version: 14.0.4
Show newest version
/*
 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.yangtools.util;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiFunction;
import org.eclipse.jdt.annotation.NonNull;

/**
 * Template for instantiating {@link ImmutableOffsetMap} instances with a fixed set of keys. The template can then be
 * used as a factory for instances via using {@link #instantiateTransformed(Map, BiFunction)} or, more efficiently,
 * using {@link #instantiateWithValues(Object[])} where the argument array has values ordered corresponding to the key
 * order defined by {@link #keySet()}.
 *
 * @param  the type of keys maintained by this template
 */
public abstract sealed class ImmutableOffsetMapTemplate extends ImmutableMapTemplate {
    private static final class Ordered extends ImmutableOffsetMapTemplate {
        Ordered(final Collection keys) {
            super(OffsetMapCache.orderedOffsets(keys));
        }

        @Override
         @NonNull ImmutableOffsetMap createMap(final ImmutableMap offsets, final V[] objects) {
            return new ImmutableOffsetMap.Ordered<>(offsets, objects);
        }
    }

    private static final class Unordered extends ImmutableOffsetMapTemplate {
        Unordered(final Collection keys) {
            super(OffsetMapCache.unorderedOffsets(keys));
        }

        @Override
         @NonNull ImmutableOffsetMap createMap(final ImmutableMap offsets, final V[] objects) {
            return new ImmutableOffsetMap.Unordered<>(offsets, objects);
        }
    }

    private final @NonNull ImmutableMap offsets;

    private ImmutableOffsetMapTemplate(final ImmutableMap offsets) {
        this.offsets = requireNonNull(offsets);
    }

    /**
     * Create a template which produces Maps with specified keys, with iteration order matching the iteration order
     * of {@code keys}. {@link #keySet()} will return these keys in exactly the same order. The resulting map will
     * retain insertion order through {@link UnmodifiableMapPhase#toModifiableMap()} transformations.
     *
     * @param keys Keys in requested iteration order.
     * @param  the type of keys maintained by resulting template
     * @return A template object.
     * @throws NullPointerException if {@code keys} or any of its elements is null
     * @throws IllegalArgumentException if {@code keys} is does not have at least two keys
     */
    public static  @NonNull ImmutableOffsetMapTemplate ordered(final Collection keys) {
        checkArgument(keys.size() > 1);
        return new Ordered<>(keys);
    }

    /**
     * Create a template which produces Maps with specified keys, with unconstrained iteration order. Produced maps
     * will have the iteration order matching the order returned by {@link #keySet()}.  The resulting map will
     * NOT retain ordering through {@link UnmodifiableMapPhase#toModifiableMap()} transformations.
     *
     * @param keys Keys in any iteration order.
     * @param  the type of keys maintained by resulting template
     * @return A template object.
     * @throws NullPointerException if {@code keys} or any of its elements is null
     * @throws IllegalArgumentException if {@code keys} is does not have at least two keys
     */
    public static  @NonNull ImmutableOffsetMapTemplate unordered(final Collection keys) {
        checkArgument(keys.size() > 1);
        return new Unordered<>(keys);
    }

    @Override
    public final Set keySet() {
        return offsets.keySet();
    }

    @Override
    public final  @NonNull ImmutableOffsetMap instantiateTransformed(final Map fromMap,
            final BiFunction valueTransformer) {
        final int size = offsets.size();
        checkArgument(fromMap.size() == size);

        @SuppressWarnings("unchecked")
        final V[] objects = (V[]) new Object[size];
        for (Entry entry : fromMap.entrySet()) {
            final K key = requireNonNull(entry.getKey());
            objects[offsetOf(key)] = transformValue(key, entry.getValue(), valueTransformer);
        }

        return createMap(offsets, objects);
    }

    @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE",
        justification = "SpotBugs does not grok checkArgument()")
    private int offsetOf(final K key) {
        final Integer offset = offsets.get(key);
        checkArgument(offset != null, "Key %s present in input, but not in offsets %s", key, offsets);
        return offset;
    }

    @Override
    @SafeVarargs
    public final  @NonNull ImmutableOffsetMap instantiateWithValues(final V... values) {
        checkArgument(values.length == offsets.size());
        final V[] copy = values.clone();
        Arrays.stream(copy).forEach(Objects::requireNonNull);
        return createMap(offsets, values);
    }

    @Override
    public final String toString() {
        return MoreObjects.toStringHelper(this).add("offsets", offsets).toString();
    }

    abstract  @NonNull ImmutableOffsetMap createMap(ImmutableMap offsets, V[] objects);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy