1090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
4090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * you may not use this file except in compliance with the License.
6090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * You may obtain a copy of the License at
7090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
8090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0
9090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
10090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See the License for the specific language governing permissions and
14090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * limitations under the License.
15090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
16090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
17090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpackage com.google.common.collect;
18090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.MapConstraints.ConstrainedMap;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Primitives;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
22090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.HashMap;
23090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonimport java.util.Map;
24090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
25090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson/**
26090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * A mutable class-to-instance map backed by an arbitrary user-provided map.
27090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * See also {@link ImmutableClassToInstanceMap}.
28090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson *
29090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson * @author Kevin Bourrillion
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 2.0 (imported from Google Collections Library)
31090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson */
32090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilsonpublic final class MutableClassToInstanceMap<B>
33090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    extends ConstrainedMap<Class<? extends B>, B>
34090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    implements ClassToInstanceMap<B> {
35090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
36090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
37090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new {@code MutableClassToInstanceMap} instance backed by a {@link
38090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * HashMap} using the default initial capacity and load factor.
39090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
40090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <B> MutableClassToInstanceMap<B> create() {
41090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new MutableClassToInstanceMap<B>(
42090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson        new HashMap<Class<? extends B>, B>());
43090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
44090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
45090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  /**
46090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * Returns a new {@code MutableClassToInstanceMap} instance backed by a given
47090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * empty {@code backingMap}. The caller surrenders control of the backing map,
48090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   * and thus should not allow any direct references to it to remain accessible.
49090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson   */
50090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public static <B> MutableClassToInstanceMap<B> create(
51090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      Map<Class<? extends B>, B> backingMap) {
52090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return new MutableClassToInstanceMap<B>(backingMap);
53090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
54090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
55090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private MutableClassToInstanceMap(Map<Class<? extends B>, B> delegate) {
56090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    super(delegate, VALUE_CAN_BE_CAST_TO_KEY);
57090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
58090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
59090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  private static final MapConstraint<Class<?>, Object> VALUE_CAN_BE_CAST_TO_KEY
60090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      = new MapConstraint<Class<?>, Object>() {
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
62090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    public void checkKeyValue(Class<?> key, Object value) {
63090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson      cast(key, value);
64090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    }
65090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  };
66090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
68090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public <T extends B> T putInstance(Class<T> type, T value) {
69090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return cast(type, put(type, value));
70090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
71090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
73090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  public <T extends B> T getInstance(Class<T> type) {
74090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson    return cast(type, get(type));
75090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
76090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <B, T extends B> T cast(Class<T> type, B value) {
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Primitives.wrap(type).cast(value);
79090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson  }
80090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson
81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static final long serialVersionUID = 0;
82090f9b4c879985bc747c214f82c62471e60c7742Jesse Wilson}
83