code: package it.unibz.inf.ontop.injection.impl;
  
  import it.unibz.inf.ontop.exception.OBDASpecificationException;
  import it.unibz.inf.ontop.exception.InvalidOntopConfigurationException;
  import it.unibz.inf.ontop.injection.OntopSQLOWLAPIConfiguration;
  import it.unibz.inf.ontop.injection.OntopStandaloneSQLSettings;
  import it.unibz.inf.ontop.injection.impl.OntopMappingOntologyBuilders.OntopMappingOntologyOptions;
  import it.unibz.inf.ontop.injection.impl.OntopMappingOntologyBuilders.StandardMappingOntologyBuilderFragment;
  import it.unibz.inf.ontop.spec.OBDASpecification;
  import org.semanticweb.owlapi.model.OWLOntology;
  import org.semanticweb.owlapi.model.OWLOntologyCreationException;
  
  import javax.annotation.Nonnull;
  import java.io.File;
  import java.io.Reader;
  import java.net.URL;
  import java.util.Optional;
  
  
  public class OntopSQLOWLAPIConfigurationImpl extends OntopStandaloneSQLConfigurationImpl
          implements OntopSQLOWLAPIConfiguration {
  
  
      private final OntopMappingOntologyConfigurationImpl mappingOWLConfiguration;
  
      OntopSQLOWLAPIConfigurationImpl(OntopStandaloneSQLSettings settings, OntopSQLOWLAPIOptions options) {
          super(settings, options.sqlOptions);
          mappingOWLConfiguration = new OntopMappingOntologyConfigurationImpl(settings, options.ontologyOptions);
      }
  
      @Override
      public OBDASpecification loadOBDASpecification() throws OBDASpecificationException {
          return loadSpecification(mappingOWLConfiguration::loadOntology);
      }
  
      @Override
      public Optional<OWLOntology> loadInputOntology() throws OWLOntologyCreationException {
          return mappingOWLConfiguration.loadInputOntology();
      }
  
      static class OntopSQLOWLAPIOptions {
          final OntopStandaloneSQLOptions sqlOptions;
          final OntopMappingOntologyOptions ontologyOptions;
  
          OntopSQLOWLAPIOptions(OntopStandaloneSQLOptions sqlOptions, OntopMappingOntologyOptions ontologyOptions) {
              this.sqlOptions = sqlOptions;
              this.ontologyOptions = ontologyOptions;
          }
      }
  
      static abstract class OntopSQLOWLAPIBuilderMixin<B extends OntopSQLOWLAPIConfiguration.Builder<B>>
              extends OntopStandaloneSQLBuilderMixin<B>
              implements OntopSQLOWLAPIConfiguration.Builder<B> {
  
          private final StandardMappingOntologyBuilderFragment<B> ontologyBuilderFragment;
          private boolean isOntologyDefined = false;
  
          OntopSQLOWLAPIBuilderMixin() {
              B builder = (B) this;
              ontologyBuilderFragment = new StandardMappingOntologyBuilderFragment<>(builder,
                      this::declareOntologyDefined
                      );
          }
  
          @Override
          public B ontologyFile(@Nonnull String urlOrPath) {
              return ontologyBuilderFragment.ontologyFile(urlOrPath);
          }
  
          @Override
          public B xmlCatalogFile(@Nonnull String xmlCatalogFile) {
              return ontologyBuilderFragment.xmlCatalogFile(xmlCatalogFile);
          }
  
          @Override
          public B ontologyFile(@Nonnull URL url) {
              return ontologyBuilderFragment.ontologyFile(url);
          }
  
          @Override
          public B ontologyFile(@Nonnull File owlFile) {
              return ontologyBuilderFragment.ontologyFile(owlFile);
          }
  
          @Override
          public B ontologyReader(@Nonnull Reader reader) {
              return ontologyBuilderFragment.ontologyReader(reader);
          }
  
          void declareOntologyDefined() {
              if (isOntologyDefined) {
                  throw new InvalidOntopConfigurationException("Ontology already defined!");
              }
              isOntologyDefined = true;
          }
  
          final OntopSQLOWLAPIOptions generateSQLOWLAPIOptions() {
              OntopStandaloneSQLOptions standaloneSQLOptions = generateStandaloneSQLOptions();
              OntopMappingOntologyOptions mappingOntologyOptions = ontologyBuilderFragment.generateMappingOntologyOptions(
                      standaloneSQLOptions.mappingOptions.mappingSQLOptions.mappingOptions);
  
              return new OntopSQLOWLAPIOptions(standaloneSQLOptions, mappingOntologyOptions);
          }
      }
  
  
      public static class BuilderImpl<B extends OntopSQLOWLAPIConfiguration.Builder<B>>
              extends OntopSQLOWLAPIBuilderMixin<B> {
  
          @Override
          public OntopSQLOWLAPIConfiguration build() {
              OntopStandaloneSQLSettings settings = new OntopStandaloneSQLSettingsImpl(generateProperties(), isR2rml());
              OntopSQLOWLAPIOptions options = generateSQLOWLAPIOptions();
              return new OntopSQLOWLAPIConfigurationImpl(settings, options);
          }
      }
  }
  