1b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit/**
2b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * Copyright (C) 2008 Google Inc.
3b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit *
4b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * Licensed under the Apache License, Version 2.0 (the "License");
5b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * you may not use this file except in compliance with the License.
6b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * You may obtain a copy of the License at
7b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit *
8b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * http://www.apache.org/licenses/LICENSE-2.0
9b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit *
10b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * Unless required by applicable law or agreed to in writing, software
11b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * distributed under the License is distributed on an "AS IS" BASIS,
12b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * See the License for the specific language governing permissions and
14b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * limitations under the License.
15b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit */
16b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
17b3a8f0bda3259af41e639f1872c42377989704d9limpbizkitpackage com.google.inject.internal;
18b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
198743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.CacheBuilder;
208743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.CacheLoader;
218743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruberimport com.google.common.cache.LoadingCache;
22210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee
23b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit/**
24b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * Lazily creates (and caches) values for keys. If creating the value fails (with errors), an
25b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * exception is thrown on retrieval.
26b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit *
27b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit * @author jessewilson@google.com (Jesse Wilson)
28b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit */
29b3a8f0bda3259af41e639f1872c42377989704d9limpbizkitpublic abstract class FailableCache<K, V> {
30b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
318743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber  private final LoadingCache<K, Object> delegate = CacheBuilder.newBuilder().build(
328743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber      new CacheLoader<K, Object>() {
338743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber        public Object load(K key) {
34210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          Errors errors = new Errors();
35210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          V result = null;
36210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          try {
37210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee            result = FailableCache.this.create(key, errors);
38210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          } catch (ErrorsException e) {
39210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee            errors.merge(e.getErrors());
40210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          }
41210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee          return errors.hasErrors() ? errors : result;
42210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee        }
43210bf43ac2ce742fabe0ab881c0ebfa50a4e32b2crazyboblee      });
44b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
45b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit  protected abstract V create(K key, Errors errors) throws ErrorsException;
46b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
47b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit  public V get(K key, Errors errors) throws ErrorsException {
488743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber    Object resultOrError = delegate.getUnchecked(key);
49b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    if (resultOrError instanceof Errors) {
50b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit      errors.merge((Errors) resultOrError);
51b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit      throw errors.toException();
52b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    } else {
53fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit      @SuppressWarnings("unchecked") // create returned a non-error result, so this is safe
54fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit      V result = (V) resultOrError;
55fcbdf999a15039ecad6157c1bf44a835df826a27limpbizkit      return result;
56b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    }
57b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit  }
587df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin
597df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin  boolean remove(K key) {
608743a0bb0fb49f30117c846880a7df2e7b36657eChristian Edward Gruber    return delegate.asMap().remove(key) != null;
617df9cf3fc0067d9d44980ccbf246e44577ef03efsberlin  }
62b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit}
63