Coverage Summary for Class: MutableClassToInstanceMap (com.google.common.collect)

Class Method, % Line, %
MutableClassToInstanceMap 53.8% (7/13) 45% (9/20)
MutableClassToInstanceMap$1 0% (0/3) 0% (0/3)
MutableClassToInstanceMap$2 0% (0/7) 0% (0/8)
MutableClassToInstanceMap$2$1 0% (0/2) 0% (0/2)
MutableClassToInstanceMap$SerializedForm 0% (0/2) 0% (0/3)
Total 25.9% (7/27) 25% (9/36)


1 /* 2  * Copyright (C) 2007 The Guava 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 com.google.common.collect; 18  19 import static com.google.common.base.Preconditions.checkNotNull; 20  21 import com.google.common.annotations.GwtIncompatible; 22 import com.google.common.primitives.Primitives; 23 import com.google.errorprone.annotations.CanIgnoreReturnValue; 24 import java.io.Serializable; 25 import java.util.HashMap; 26 import java.util.Iterator; 27 import java.util.LinkedHashMap; 28 import java.util.Map; 29 import java.util.Set; 30 import java.util.Spliterator; 31  32 /** 33  * A mutable class-to-instance map backed by an arbitrary user-provided map. See also {@link 34  * ImmutableClassToInstanceMap}. 35  * 36  * <p>See the Guava User Guide article on <a href= 37  * "https://github.com/google/guava/wiki/NewCollectionTypesExplained#classtoinstancemap"> {@code 38  * ClassToInstanceMap}</a>. 39  * 40  * @author Kevin Bourrillion 41  * @since 2.0 42  */ 43 @GwtIncompatible 44 @SuppressWarnings("serial") // using writeReplace instead of standard serialization 45 public final class MutableClassToInstanceMap<B> extends ForwardingMap<Class<? extends B>, B> 46  implements ClassToInstanceMap<B>, Serializable { 47  48  /** 49  * Returns a new {@code MutableClassToInstanceMap} instance backed by a {@link HashMap} using the 50  * default initial capacity and load factor. 51  */ 52  public static <B> MutableClassToInstanceMap<B> create() { 53  return new MutableClassToInstanceMap<B>(new HashMap<Class<? extends B>, B>()); 54  } 55  56  /** 57  * Returns a new {@code MutableClassToInstanceMap} instance backed by a given empty {@code 58  * backingMap}. The caller surrenders control of the backing map, and thus should not allow any 59  * direct references to it to remain accessible. 60  */ 61  public static <B> MutableClassToInstanceMap<B> create(Map<Class<? extends B>, B> backingMap) { 62  return new MutableClassToInstanceMap<B>(backingMap); 63  } 64  65  private final Map<Class<? extends B>, B> delegate; 66  67  private MutableClassToInstanceMap(Map<Class<? extends B>, B> delegate) { 68  this.delegate = checkNotNull(delegate); 69  } 70  71  @Override 72  protected Map<Class<? extends B>, B> delegate() { 73  return delegate; 74  } 75  76  /** 77  * Wraps the {@code setValue} implementation of an {@code Entry} to enforce the class constraint. 78  */ 79  private static <B> Entry<Class<? extends B>, B> checkedEntry( 80  final Entry<Class<? extends B>, B> entry) { 81  return new ForwardingMapEntry<Class<? extends B>, B>() { 82  @Override 83  protected Entry<Class<? extends B>, B> delegate() { 84  return entry; 85  } 86  87  @Override 88  public B setValue(B value) { 89  return super.setValue(cast(getKey(), value)); 90  } 91  }; 92  } 93  94  @Override 95  public Set<Entry<Class<? extends B>, B>> entrySet() { 96  return new ForwardingSet<Entry<Class<? extends B>, B>>() { 97  98  @Override 99  protected Set<Entry<Class<? extends B>, B>> delegate() { 100  return MutableClassToInstanceMap.this.delegate().entrySet(); 101  } 102  103  @Override 104  public Spliterator<Entry<Class<? extends B>, B>> spliterator() { 105  return CollectSpliterators.map( 106  delegate().spliterator(), MutableClassToInstanceMap::checkedEntry); 107  } 108  109  @Override 110  public Iterator<Entry<Class<? extends B>, B>> iterator() { 111  return new TransformedIterator<Entry<Class<? extends B>, B>, Entry<Class<? extends B>, B>>( 112  delegate().iterator()) { 113  @Override 114  Entry<Class<? extends B>, B> transform(Entry<Class<? extends B>, B> from) { 115  return checkedEntry(from); 116  } 117  }; 118  } 119  120  @Override 121  public Object[] toArray() { 122  return standardToArray(); 123  } 124  125  @Override 126  public <T> T[] toArray(T[] array) { 127  return standardToArray(array); 128  } 129  }; 130  } 131  132  @Override 133  @CanIgnoreReturnValue 134  public B put(Class<? extends B> key, B value) { 135  return super.put(key, cast(key, value)); 136  } 137  138  @Override 139  public void putAll(Map<? extends Class<? extends B>, ? extends B> map) { 140  Map<Class<? extends B>, B> copy = new LinkedHashMap<>(map); 141  for (Entry<? extends Class<? extends B>, B> entry : copy.entrySet()) { 142  cast(entry.getKey(), entry.getValue()); 143  } 144  super.putAll(copy); 145  } 146  147  @CanIgnoreReturnValue 148  @Override 149  public <T extends B> T putInstance(Class<T> type, T value) { 150  return cast(type, put(type, value)); 151  } 152  153  @Override 154  public <T extends B> T getInstance(Class<T> type) { 155  return cast(type, get(type)); 156  } 157  158  @CanIgnoreReturnValue 159  private static <B, T extends B> T cast(Class<T> type, B value) { 160  return Primitives.wrap(type).cast(value); 161  } 162  163  private Object writeReplace() { 164  return new SerializedForm(delegate()); 165  } 166  167  /** Serialized form of the map, to avoid serializing the constraint. */ 168  private static final class SerializedForm<B> implements Serializable { 169  private final Map<Class<? extends B>, B> backingMap; 170  171  SerializedForm(Map<Class<? extends B>, B> backingMap) { 172  this.backingMap = backingMap; 173  } 174  175  Object readResolve() { 176  return create(backingMap); 177  } 178  179  private static final long serialVersionUID = 0; 180  } 181 }