001/* 002 * Configurate 003 * Copyright (C) zml and Configurate contributors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package ninja.leaping.configurate.objectmapping; 018 019import com.google.common.cache.CacheBuilder; 020import com.google.common.cache.CacheLoader; 021import com.google.common.cache.LoadingCache; 022import com.google.common.reflect.TypeToken; 023import org.checkerframework.checker.nullness.qual.NonNull; 024 025import java.util.concurrent.ExecutionException; 026 027import static java.util.Objects.requireNonNull; 028 029/** 030 * Factory for a basic {@link ObjectMapper}. 031 */ 032public class DefaultObjectMapperFactory implements ObjectMapperFactory { 033 private static final ObjectMapperFactory INSTANCE = new DefaultObjectMapperFactory(); 034 035 @NonNull 036 public static ObjectMapperFactory getInstance() { 037 return INSTANCE; 038 } 039 040 private final LoadingCache<TypeToken<?>, ObjectMapper<?>> mapperCache = CacheBuilder.newBuilder() 041 .weakKeys() 042 .maximumSize(500) 043 .build(new CacheLoader<TypeToken<?>, ObjectMapper<?>>() { 044 @Override 045 public ObjectMapper<?> load(TypeToken<?> key) throws Exception { 046 return new ObjectMapper<>(key); 047 } 048 }); 049 050 @Override 051 public @NonNull <T> ObjectMapper<T> getMapper(@NonNull Class<T> type) throws ObjectMappingException { 052 return getMapper(TypeToken.of(type)); 053 } 054 055 @NonNull 056 @Override 057 @SuppressWarnings("unchecked") 058 public <T> ObjectMapper<T> getMapper(@NonNull TypeToken<T> type) throws ObjectMappingException { 059 requireNonNull(type, "type"); 060 try { 061 return (ObjectMapper<T>) mapperCache.get(type); 062 } catch (ExecutionException e) { 063 if (e.getCause() instanceof ObjectMappingException) { 064 throw (ObjectMappingException) e.getCause(); 065 } else { 066 throw new ObjectMappingException(e); 067 } 068 } 069 } 070 071 @Override 072 public String toString() { 073 return "DefaultObjectMapperFactory{}"; 074 } 075}