001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.model;
007
008import java.lang.reflect.Constructor;
009import java.lang.reflect.InvocationTargetException;
010import java.net.URI;
011import java.util.Collection;
012import java.util.List;
013
014import dev.metaschema.core.model.IModuleExtended;
015import dev.metaschema.core.util.ObjectUtils;
016import dev.metaschema.databind.IBindingContext;
017import edu.umd.cs.findbugs.annotations.NonNull;
018
019/**
020 * Represents a bound Metaschema module that provides access to its field and
021 * assembly definitions through Java class bindings.
022 */
023public interface IBoundModule
024    extends IModuleExtended<
025        IBoundModule,
026        IBoundDefinitionModelComplex,
027        IBoundDefinitionFlag,
028        IBoundDefinitionModelField<?>,
029        IBoundDefinitionModelAssembly> {
030
031  /**
032   * Create a new instance of a bound module using reflection.
033   *
034   * @param clazz
035   *          the bound module class to instantiate
036   * @param bindingContext
037   *          the binding context for the module
038   * @param importedModules
039   *          the list of modules imported by this module
040   * @return the new module instance
041   * @throws IllegalArgumentException
042   *           if the module cannot be instantiated
043   */
044  @NonNull
045  static IBoundModule newInstance(
046      @NonNull Class<? extends IBoundModule> clazz,
047      @NonNull IBindingContext bindingContext,
048      @NonNull List<? extends IBoundModule> importedModules) {
049
050    Constructor<? extends IBoundModule> constructor;
051    try {
052      constructor = clazz.getDeclaredConstructor(List.class, IBindingContext.class);
053    } catch (NoSuchMethodException ex) {
054      throw new IllegalArgumentException(ex);
055    }
056
057    try {
058      return ObjectUtils.notNull(constructor.newInstance(importedModules, bindingContext));
059    } catch (InstantiationException | IllegalAccessException | InvocationTargetException ex) {
060      throw new IllegalArgumentException(ex);
061    }
062  }
063
064  /**
065   * Get the Module binding context.
066   *
067   * @return the context
068   */
069  @NonNull
070  IBindingContext getBindingContext();
071
072  @Override
073  default URI getLocation() {
074    // not known
075    return null;
076  }
077
078  @Override
079  Collection<IBoundDefinitionModelAssembly> getAssemblyDefinitions();
080
081  @Override
082  IBoundDefinitionModelAssembly getAssemblyDefinitionByName(@NonNull Integer name);
083
084  @Override
085  Collection<IBoundDefinitionModelField<?>> getFieldDefinitions();
086
087  @Override
088  IBoundDefinitionModelField<?> getFieldDefinitionByName(@NonNull Integer name);
089}