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