BindingModuleLoader.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.databind.model.metaschema;
import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
import gov.nist.secauto.metaschema.core.configuration.IMutableConfiguration;
import gov.nist.secauto.metaschema.core.model.AbstractModuleLoader;
import gov.nist.secauto.metaschema.core.model.MetaschemaException;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.IBindingContext;
import gov.nist.secauto.metaschema.databind.IBindingContext.IModuleLoaderStrategy;
import gov.nist.secauto.metaschema.databind.SimpleModuleLoaderStrategy;
import gov.nist.secauto.metaschema.databind.codegen.DefaultModuleBindingGenerator;
import gov.nist.secauto.metaschema.databind.io.DeserializationFeature;
import gov.nist.secauto.metaschema.databind.io.IBoundLoader;
import gov.nist.secauto.metaschema.databind.model.IBoundDefinitionModelAssembly;
import gov.nist.secauto.metaschema.databind.model.metaschema.binding.METASCHEMA;
import gov.nist.secauto.metaschema.databind.model.metaschema.binding.METASCHEMA.Import;
import gov.nist.secauto.metaschema.databind.model.metaschema.binding.MetaschemaModelModule;
import gov.nist.secauto.metaschema.databind.model.metaschema.impl.BindingModule;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import edu.umd.cs.findbugs.annotations.NonNull;
import nl.talsmasoftware.lazy4j.Lazy;
/**
* A module loader implementation that parses Metaschema modules from a
* specified resource using the built-in model {@link MetaschemaModelModule}
* binding.
* <p>
* Metaschema modules loaded this way are automatically registered with the
* {@link IBindingContext}.
* <p>
* Use of this Metaschema module loader requires that the associated binding
* context is initialized using a {@link IModuleLoaderStrategy} that supports
* dynamic bound module loading. This can be accomplished using the
* {@link SimpleModuleLoaderStrategy} initialized using the
* {@link DefaultModuleBindingGenerator}.
*/
public class BindingModuleLoader
extends AbstractModuleLoader<METASCHEMA, IBindingMetaschemaModule>
implements IBindingModuleLoader {
private final Lazy<IBoundLoader> loader;
private final ModuleLoadingPostProcessor postProcessor;
/**
* Construct a new Metaschema loader.
*
* @param bindingContext
* the Metaschema binding context used to load bound resources
* @param postProcessor
* the post processor to use when after loading a module
*/
public BindingModuleLoader(
@NonNull IBindingContext bindingContext,
@NonNull ModuleLoadingPostProcessor postProcessor) {
this.loader = Lazy.lazy(bindingContext::newBoundLoader);
this.postProcessor = postProcessor;
}
@Override
@NonNull
public IBindingContext getBindingContext() {
return getLoader().getBindingContext();
}
@Override
protected IBindingMetaschemaModule newModule(
URI resource,
METASCHEMA binding,
List<? extends IBindingMetaschemaModule> importedModules)
throws MetaschemaException {
IBindingContext bindingContext = getLoader().getBindingContext();
IBindingMetaschemaModule module = new BindingModule(
resource,
ObjectUtils.notNull(
(IBoundDefinitionModelAssembly) bindingContext.getBoundDefinitionForClass(METASCHEMA.class)),
binding,
importedModules);
// post-process the module
postProcessor.postProcessModule(module, bindingContext);
return module;
}
@Override
protected List<URI> getImports(METASCHEMA binding) {
return ObjectUtils.notNull(binding.getImports().stream()
.map(Import::getHref)
.collect(Collectors.toUnmodifiableList()));
}
@Override
protected METASCHEMA parseModule(URI resource) throws IOException {
return getLoader().load(METASCHEMA.class, resource);
}
/**
* Get the underlying bound loader.
*
* @return the loader
*/
protected IBoundLoader getLoader() {
return ObjectUtils.notNull(loader.get());
}
@Override
public boolean isFeatureEnabled(DeserializationFeature<?> feature) {
return getLoader().isFeatureEnabled(feature);
}
@Override
public Map<DeserializationFeature<?>, Object> getFeatureValues() {
return getLoader().getFeatureValues();
}
@Override
public IMutableConfiguration<DeserializationFeature<?>>
applyConfiguration(IConfiguration<DeserializationFeature<?>> other) {
return getLoader().applyConfiguration(other);
}
@Override
public IMutableConfiguration<DeserializationFeature<?>> set(DeserializationFeature<?> feature, Object value) {
return getLoader().set(feature, value);
}
/**
* Allow inline XML entities to be automatically replaced.
*/
@Override
public void allowEntityResolution() {
enableFeature(DeserializationFeature.DESERIALIZE_XML_ALLOW_ENTITY_RESOLUTION);
}
}