001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.databind; 007 008import gov.nist.secauto.metaschema.core.model.IBoundObject; 009import gov.nist.secauto.metaschema.core.util.ObjectUtils; 010import gov.nist.secauto.metaschema.databind.model.AbstractBoundModule; 011import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelComplex; 012import gov.nist.secauto.metaschema.databind.model.IBoundModule; 013import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 014import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaField; 015import gov.nist.secauto.metaschema.databind.model.impl.DefinitionAssembly; 016import gov.nist.secauto.metaschema.databind.model.impl.DefinitionField; 017 018import java.util.Map; 019import java.util.concurrent.ConcurrentHashMap; 020 021import edu.umd.cs.findbugs.annotations.NonNull; 022import edu.umd.cs.findbugs.annotations.Nullable; 023 024public class SimpleModuleLoaderStrategy implements IBindingContext.IModuleLoaderStrategy { 025 @NonNull 026 private final IBindingContext bindingContext; 027 @NonNull 028 private final Map<Class<?>, IBoundModule> modulesByClass = new ConcurrentHashMap<>(); 029 @NonNull 030 private final Map<Class<?>, IBoundDefinitionModelComplex> definitionsByClass = new ConcurrentHashMap<>(); 031 032 protected SimpleModuleLoaderStrategy(@NonNull IBindingContext bindingContext) { 033 this.bindingContext = bindingContext; 034 } 035 036 @NonNull 037 private IBindingContext getBindingContext() { 038 return bindingContext; 039 } 040 041 @Override 042 public IBoundModule loadModule(@NonNull Class<? extends IBoundModule> clazz) { 043 IBoundModule retval; 044 synchronized (this) { 045 retval = modulesByClass.get(clazz); 046 if (retval == null) { 047 retval = AbstractBoundModule.createInstance(clazz, getBindingContext()); 048 modulesByClass.put(clazz, retval); 049 } 050 } 051 return ObjectUtils.notNull(retval); 052 } 053 054 @Override 055 public IBoundDefinitionModelComplex getBoundDefinitionForClass(@NonNull Class<? extends IBoundObject> clazz) { 056 IBoundDefinitionModelComplex retval; 057 synchronized (this) { 058 retval = definitionsByClass.get(clazz); 059 if (retval == null) { 060 retval = newBoundDefinition(clazz); 061 if (retval != null) { 062 definitionsByClass.put(clazz, retval); 063 } 064 } 065 } 066 return retval; 067 } 068 069 @Nullable 070 private IBoundDefinitionModelComplex newBoundDefinition(@NonNull Class<? extends IBoundObject> clazz) { 071 IBoundDefinitionModelComplex retval = null; 072 if (clazz.isAnnotationPresent(MetaschemaAssembly.class)) { 073 retval = DefinitionAssembly.newInstance(clazz, getBindingContext()); 074 } else if (clazz.isAnnotationPresent(MetaschemaField.class)) { 075 retval = DefinitionField.newInstance(clazz, getBindingContext()); 076 } 077 return retval; 078 } 079}