/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.deephacks.confit.internal.cached.proxy; import org.deephacks.confit.internal.cached.CachedCacheManager; import org.deephacks.confit.model.Bean; import org.deephacks.confit.model.BeanId; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * Responsible for holding references (not the actual objects) to other * configurable classes from a particular instance. * * The proxy class will be attached with field of this reference holder class. */ public class ConfigReferenceHolder { /** used by proxies to retrieve real objects from references (instance ids) */ private static CachedCacheManager cache = new CachedCacheManager(); /** propertyName -> instance ids */ private Map<String, List<String>> references = new HashMap<>(); /** cached instances that have already been generated */ private ConcurrentHashMap<BeanId, Object> instances = new ConcurrentHashMap<>(); public ConfigReferenceHolder(Map<String, List<String>> references) { this.references = references; } public ConfigReferenceHolder(Bean bean) { for (String propertyName : bean.getReferenceNames()){ ArrayList<String> instanceIds = new ArrayList<>(); for (BeanId id : bean.getReference(propertyName)) { instanceIds.add(id.getInstanceId()); } references.put(propertyName, instanceIds); } } public Map<String, List<String>> getReferences() { return references; } /**' * Called by a proxy to lookup single object reference. The proxy knows * the schema name so the hold does not need to bother storing it. */ public Object getObjectReference(String field, String schemaName) { List<String> instanceIds = references.get(field); if(instanceIds == null || instanceIds.size() == 0) { return null; } String instanceId = instanceIds.get(0); if(instanceId == null) { return null; } BeanId id = BeanId.create(instanceId, schemaName); Object instance = instances.get(id); if(instance != null) { return instance; } instance = cache.get(id); instances.put(id, instance); return instance; } /**' * Called by a proxy to lookup a list of object references. The proxy knows * the schema name so the hold does not need to bother storing it. */ public Collection<Object> getObjectReferenceList(String field, String schemaName) { List<String> instanceIds = references.get(field); if(instanceIds == null || instanceIds.size() == 0) { return null; } List<Object> objects = new ArrayList<>(); for (String instanceId : instanceIds) { BeanId id = BeanId.create(instanceId, schemaName); Object instance = instances.get(id); if(instance != null) { objects.add(instance); } else { instance = cache.get(id); instances.put(id, instance); objects.add(instance); } } return objects; } /**' * Called by a proxy to lookup a map of object references. The proxy knows * the schema name so the hold does not need to bother storing it. */ public Map<String, Object> getObjectReferenceMap(String field, String schemaName) { List<String> instanceIds = references.get(field); if(instanceIds == null || instanceIds.size() == 0) { return null; } Map<String, Object> objects = new HashMap<>(); for (String instanceId : instanceIds) { BeanId id = BeanId.create(instanceId, schemaName); Object instance = instances.get(id); if(instance != null) { objects.put(instanceId, instance); } else { instance = cache.get(id); instances.put(id, instance); objects.put(instanceId, instance); } } return objects; } }