2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.util;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import com.google.common.annotations.Beta;
13 import java.util.Collection;
16 import java.util.function.BiFunction;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.concepts.Immutable;
21 * Template for instantiating {@link UnmodifiableMapPhase} instances with a fixed set of keys. The template can then be
22 * used as a factory for instances via using {@link #instantiateTransformed(Map, BiFunction)} or, more efficiently,
23 * using {@link #instantiateWithValues(Object[])} where the argument array has values ordered corresponding to the key
24 * order defined by {@link #keySet()}.
27 * If the keySet is static known to contain only a single key, consider using {@link SharedSingletonMapTemplate}. If
28 * it is statically known to contain multiple keys, consider using {@link ImmutableOffsetMapTemplate}.
30 * @param <K> the type of keys maintained by this template
33 public abstract class ImmutableMapTemplate<K> implements Immutable {
34 ImmutableMapTemplate() {
39 * Create a template which produces Maps with specified keys, with iteration order matching the iteration order
40 * of {@code keys}. {@link #keySet()} will return these keys in exactly the same order. The resulting map will
41 * retain insertion order through {@link UnmodifiableMapPhase#toModifiableMap()} transformations.
43 * @param keys Keys in requested iteration order.
44 * @param <K> the type of keys maintained by resulting template
45 * @return A template object.
46 * @throws NullPointerException if {@code keys} or any of its elements is null
47 * @throws IllegalArgumentException if {@code keys} is empty
49 public static <K> @NonNull ImmutableMapTemplate<K> ordered(final Collection<K> keys) {
50 switch (keys.size()) {
52 throw new IllegalArgumentException("Proposed keyset must not be empty");
54 return SharedSingletonMapTemplate.ordered(keys.iterator().next());
56 return ImmutableOffsetMapTemplate.ordered(keys);
61 * Create a template which produces Maps with specified keys, with unconstrained iteration order. Produced maps
62 * will have the iteration order matching the order returned by {@link #keySet()}. The resulting map will
63 * NOT retain ordering through {@link UnmodifiableMapPhase#toModifiableMap()} transformations.
65 * @param keys Keys in any iteration order.
66 * @param <K> the type of keys maintained by resulting template
67 * @return A template object.
68 * @throws NullPointerException if {@code keys} or any of its elements is null
69 * @throws IllegalArgumentException if {@code keys} is empty
71 public static <K> @NonNull ImmutableMapTemplate<K> unordered(final Collection<K> keys) {
72 switch (keys.size()) {
74 throw new IllegalArgumentException("Proposed keyset must not be empty");
76 return SharedSingletonMapTemplate.unordered(keys.iterator().next());
78 return ImmutableOffsetMapTemplate.unordered(keys);
83 * Instantiate an immutable map by applying specified {@code transformer} to values of {@code fromMap}.
85 * @param fromMap Input map
86 * @param keyValueTransformer Transformation to apply to values
87 * @param <T> the type of input values
88 * @param <V> the type of mapped values
89 * @return An immutable map
90 * @throws NullPointerException if any of the arguments is null or if the transformer produces a {@code null} value
91 * @throws IllegalArgumentException if {@code fromMap#keySet()} does not match this template's keys
93 public abstract <T, V> @NonNull UnmodifiableMapPhase<K, V> instantiateTransformed(Map<K, T> fromMap,
94 BiFunction<K, T, V> keyValueTransformer);
97 * Instantiate an immutable map by filling values from provided array. The array MUST be ordered to match key order
98 * as returned by {@link #keySet()}.
100 * @param values Values to use
101 * @param <V> the type of mapped values
102 * @return An immutable map
103 * @throws NullPointerException if {@code values} or any of its elements is null
104 * @throws IllegalArgumentException if {@code values.length} does not match the number of keys in this template
106 @SuppressWarnings("unchecked")
107 public abstract <V> @NonNull UnmodifiableMapPhase<K, V> instantiateWithValues(V... values);
110 * Returns the set of keys expected by this template, in the iteration order Maps resulting from instantiation
113 * @return This template's key set
116 public abstract Set<K> keySet();
118 final <T, V> @NonNull V transformValue(final K key, final T input, final BiFunction<K, T, V> transformer) {
119 final V value = transformer.apply(key, input);
120 checkArgument(value != null, "Transformer returned null for input %s at key %s", input, key);