/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you 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. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ package org.opensearch.gradle; import org.gradle.api.Named; import org.gradle.api.tasks.Input; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; import java.util.function.Supplier; import java.util.stream.Collectors; public class LazyPropertyMap extends AbstractLazyPropertyCollection implements Map { private final Map> delegate = new LinkedHashMap<>(); private final BiFunction normalizationMapper; public LazyPropertyMap(String name) { this(name, null); } public LazyPropertyMap(String name, Object owner) { this(name, owner, null); } public LazyPropertyMap(String name, Object owner, BiFunction normalizationMapper) { super(name, owner); this.normalizationMapper = normalizationMapper; } @Override public int size() { return delegate.size(); } @Override public boolean isEmpty() { return delegate.isEmpty(); } @Override public boolean containsKey(Object key) { return delegate.containsKey(key); } @Override public boolean containsValue(Object value) { return delegate.values().stream().map(PropertyMapEntry::getValue).anyMatch(v -> v.equals(value)); } @Override public V get(Object key) { PropertyMapEntry entry = delegate.get(key); if (entry != null) { V value = entry.getValue(); assertNotNull(value, "value for key '" + key + "'"); return value; } else { return null; } } @Override public V put(K key, V value) { return put(key, value, PropertyNormalization.DEFAULT); } public V put(K key, V value, PropertyNormalization normalization) { assertNotNull(value, "value for key '" + key + "'"); return put(key, () -> value, normalization); } public V put(K key, Supplier supplier) { return put(key, supplier, PropertyNormalization.DEFAULT); } public V put(K key, Supplier supplier, PropertyNormalization normalization) { assertNotNull(supplier, "supplier for key '" + key + "'"); PropertyMapEntry previous = delegate.put(key, new PropertyMapEntry<>(key, supplier, normalization)); return previous == null ? null : previous.getValue(); } @Override public V remove(Object key) { PropertyMapEntry previous = delegate.remove(key); return previous == null ? null : previous.getValue(); } @Override public void putAll(Map m) { throw new UnsupportedOperationException(this.getClass().getName() + " does not support putAll()"); } @Override public void clear() { delegate.clear(); } @Override public Set keySet() { return delegate.keySet(); } @Override public Collection values() { return delegate.values().stream().peek(this::validate).map(PropertyMapEntry::getValue).collect(Collectors.toList()); } @Override public Set> entrySet() { return delegate.entrySet() .stream() .peek(this::validate) .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getValue())) .entrySet(); } @Override public List getNormalizedCollection() { return delegate.values() .stream() .peek(this::validate) .filter(entry -> entry.getNormalization() != PropertyNormalization.IGNORE_VALUE) .map(entry -> normalizationMapper == null ? entry : normalizationMapper.apply(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); } private void validate(Map.Entry> entry) { validate(entry.getValue()); } private void validate(PropertyMapEntry supplier) { assertNotNull(supplier, "key '" + supplier.getKey() + "' supplier value"); } private static class PropertyMapEntry implements Named { private final K key; private final Supplier value; private final PropertyNormalization normalization; PropertyMapEntry(K key, Supplier value, PropertyNormalization normalization) { this.key = key; this.value = value; this.normalization = normalization; } @Input public PropertyNormalization getNormalization() { return normalization; } @Override @Input public String getName() { return getKey().toString(); } @Input public K getKey() { return key; } @Input public V getValue() { return value.get(); } } }