1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2024 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.internal; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import java.util.Collection; 20*f585d8a3SJacky Wang import java.util.Map; 21*f585d8a3SJacky Wang import java.util.Set; 22*f585d8a3SJacky Wang 23*f585d8a3SJacky Wang /** 24*f585d8a3SJacky Wang * A class keyed map that delegates to a string keyed map under the hood. 25*f585d8a3SJacky Wang * 26*f585d8a3SJacky Wang * <p>A {@code LazyClassKeyMap} is created for @LazyClassKey contributed map binding. 27*f585d8a3SJacky Wang */ 28*f585d8a3SJacky Wang public final class LazyClassKeyMap<V> implements Map<Class<?>, V> { 29*f585d8a3SJacky Wang private final Map<String, V> delegate; 30*f585d8a3SJacky Wang of(Map<String, V> delegate)31*f585d8a3SJacky Wang public static <V> Map<Class<?>, V> of(Map<String, V> delegate) { 32*f585d8a3SJacky Wang return new LazyClassKeyMap<>(delegate); 33*f585d8a3SJacky Wang } 34*f585d8a3SJacky Wang LazyClassKeyMap(Map<String, V> delegate)35*f585d8a3SJacky Wang private LazyClassKeyMap(Map<String, V> delegate) { 36*f585d8a3SJacky Wang this.delegate = delegate; 37*f585d8a3SJacky Wang } 38*f585d8a3SJacky Wang 39*f585d8a3SJacky Wang @Override get(Object key)40*f585d8a3SJacky Wang public V get(Object key) { 41*f585d8a3SJacky Wang if (!(key instanceof Class)) { 42*f585d8a3SJacky Wang throw new IllegalArgumentException("Key must be a class"); 43*f585d8a3SJacky Wang } 44*f585d8a3SJacky Wang return delegate.get(((Class<?>) key).getName()); 45*f585d8a3SJacky Wang } 46*f585d8a3SJacky Wang 47*f585d8a3SJacky Wang @Override keySet()48*f585d8a3SJacky Wang public Set<Class<?>> keySet() { 49*f585d8a3SJacky Wang // This method will load all class keys, therefore no need to use @LazyClassKey annotated 50*f585d8a3SJacky Wang // bindings. 51*f585d8a3SJacky Wang throw new UnsupportedOperationException( 52*f585d8a3SJacky Wang "Maps created with @LazyClassKey do not support usage of keySet(). Consider @ClassKey" 53*f585d8a3SJacky Wang + " instead."); 54*f585d8a3SJacky Wang } 55*f585d8a3SJacky Wang 56*f585d8a3SJacky Wang @Override values()57*f585d8a3SJacky Wang public Collection<V> values() { 58*f585d8a3SJacky Wang return delegate.values(); 59*f585d8a3SJacky Wang } 60*f585d8a3SJacky Wang 61*f585d8a3SJacky Wang @Override isEmpty()62*f585d8a3SJacky Wang public boolean isEmpty() { 63*f585d8a3SJacky Wang return delegate.isEmpty(); 64*f585d8a3SJacky Wang } 65*f585d8a3SJacky Wang 66*f585d8a3SJacky Wang @Override containsKey(Object key)67*f585d8a3SJacky Wang public boolean containsKey(Object key) { 68*f585d8a3SJacky Wang if (!(key instanceof Class)) { 69*f585d8a3SJacky Wang throw new IllegalArgumentException("Key must be a class"); 70*f585d8a3SJacky Wang } 71*f585d8a3SJacky Wang return delegate.containsKey(((Class<?>) key).getName()); 72*f585d8a3SJacky Wang } 73*f585d8a3SJacky Wang 74*f585d8a3SJacky Wang @Override containsValue(Object value)75*f585d8a3SJacky Wang public boolean containsValue(Object value) { 76*f585d8a3SJacky Wang return delegate.containsValue(value); 77*f585d8a3SJacky Wang } 78*f585d8a3SJacky Wang 79*f585d8a3SJacky Wang @Override size()80*f585d8a3SJacky Wang public int size() { 81*f585d8a3SJacky Wang return delegate.size(); 82*f585d8a3SJacky Wang } 83*f585d8a3SJacky Wang 84*f585d8a3SJacky Wang @Override entrySet()85*f585d8a3SJacky Wang public Set<Map.Entry<Class<?>, V>> entrySet() { 86*f585d8a3SJacky Wang // This method will load all class keys, therefore no need to use @LazyClassKey annotated 87*f585d8a3SJacky Wang // bindings. 88*f585d8a3SJacky Wang throw new UnsupportedOperationException( 89*f585d8a3SJacky Wang "Maps created with @LazyClassKey do not support usage of entrySet(). Consider @ClassKey" 90*f585d8a3SJacky Wang + " instead."); 91*f585d8a3SJacky Wang } 92*f585d8a3SJacky Wang 93*f585d8a3SJacky Wang // The dagger map binding should be a immutable map. 94*f585d8a3SJacky Wang @Override remove(Object key)95*f585d8a3SJacky Wang public V remove(Object key) { 96*f585d8a3SJacky Wang throw new UnsupportedOperationException("Dagger map bindings are immutable"); 97*f585d8a3SJacky Wang } 98*f585d8a3SJacky Wang 99*f585d8a3SJacky Wang @Override clear()100*f585d8a3SJacky Wang public void clear() { 101*f585d8a3SJacky Wang throw new UnsupportedOperationException("Dagger map bindings are immutable"); 102*f585d8a3SJacky Wang } 103*f585d8a3SJacky Wang 104*f585d8a3SJacky Wang @Override put(Class<?> key, V value)105*f585d8a3SJacky Wang public V put(Class<?> key, V value) { 106*f585d8a3SJacky Wang throw new UnsupportedOperationException("Dagger map bindings are immutable"); 107*f585d8a3SJacky Wang } 108*f585d8a3SJacky Wang 109*f585d8a3SJacky Wang @Override putAll(Map<? extends Class<?>, ? extends V> map)110*f585d8a3SJacky Wang public void putAll(Map<? extends Class<?>, ? extends V> map) { 111*f585d8a3SJacky Wang throw new UnsupportedOperationException("Dagger map bindings are immutable"); 112*f585d8a3SJacky Wang } 113*f585d8a3SJacky Wang 114*f585d8a3SJacky Wang /** A factory for {@code LazyClassKeyMap}. */ 115*f585d8a3SJacky Wang public static class Factory<V> implements Provider<Map<Class<?>, V>> { 116*f585d8a3SJacky Wang MapFactory<String, V> delegate; 117*f585d8a3SJacky Wang of(MapFactory<String, V> delegate)118*f585d8a3SJacky Wang public static <V> Factory<V> of(MapFactory<String, V> delegate) { 119*f585d8a3SJacky Wang return new Factory<>(delegate); 120*f585d8a3SJacky Wang } 121*f585d8a3SJacky Wang Factory(MapFactory<String, V> delegate)122*f585d8a3SJacky Wang private Factory(MapFactory<String, V> delegate) { 123*f585d8a3SJacky Wang this.delegate = delegate; 124*f585d8a3SJacky Wang } 125*f585d8a3SJacky Wang 126*f585d8a3SJacky Wang @Override get()127*f585d8a3SJacky Wang public Map<Class<?>, V> get() { 128*f585d8a3SJacky Wang return LazyClassKeyMap.of(delegate.get()); 129*f585d8a3SJacky Wang } 130*f585d8a3SJacky Wang } 131*f585d8a3SJacky Wang } 132