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