コード例 #1
0
class LoginSTDialog(QDialog, DIALOG_UI):
    active_role_changed = pyqtSignal()

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.session = STSession()

        self.logger = Logger()
        self.help_strings = HelpStrings()

        self.should_emit_role_changed = False

        self.buttonBox.accepted.disconnect()
        self.buttonBox.accepted.connect(self.login)
        self.buttonBox.helpRequested.connect(self.show_help)

        self.txt_login_user.setFocus()

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)

    def login(self):
        if not self.txt_login_user.text().strip(
        ) or not self.txt_login_password.text().strip():
            msg = QCoreApplication.translate(
                "LoginSTDialog", "First enter user and password data.")
            self.show_message(msg, Qgis.Warning)
            return

        msg = self.logger.status(
            QCoreApplication.translate("LoginSTDialog",
                                       "Connecting to login service..."))
        with ProcessWithStatus(msg):
            res, msg, change_role = self.session.login(
                self.txt_login_user.text(), self.txt_login_password.text())

        if res:
            self.should_emit_role_changed = change_role
            self.logger.info(__name__, msg, EnumLogHandler.MESSAGE_BAR, 15)
            self.close()
        else:
            self.show_message(msg, Qgis.Warning, 0)

    def show_message(self, message, level, duration=15):
        self.bar.clearWidgets(
        )  # Remove previous messages before showing a new one
        self.bar.pushMessage(message, level, duration)

    def show_help(self):
        show_plugin_help('transitional_system_login')

    def reject(self):
        if self.should_emit_role_changed:
            self.logger.info(__name__, "Emit active_role_changed.")
            self.active_role_changed.emit()

        self.logger.info(__name__, "Dialog closed.")
        self.done(QDialog.Accepted)  # Any code, we don't use it anyways
コード例 #2
0
class LoginSTDialog(QDialog, DIALOG_UI):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.session = STSession()

        self.logger = Logger()
        self.help_strings = HelpStrings()

        #self.txt_help_page.setHtml(self.help_strings.DLG_WELCOME_SCREEN)
        #self.txt_help_page.anchorClicked.connect(self.save_template)

        self.buttonBox.accepted.disconnect()
        self.buttonBox.accepted.connect(self.login)
        self.buttonBox.helpRequested.connect(self.show_help)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)

    def login(self):
        if not self.txt_login_user.text().strip(
        ) or not self.txt_login_password.text().strip():
            msg = QCoreApplication.translate(
                "LoginSTDialog", "First enter user and password data.")
            self.show_message(msg, Qgis.Warning)
            return

        msg = self.logger.status(
            QCoreApplication.translate("LoginSTDialog",
                                       "Connecting to login service..."))
        with ProcessWithStatus(msg):
            res, msg = self.session.login(self.txt_login_user.text(),
                                          self.txt_login_password.text())

        if res:
            self.logger.info(__name__, msg, LogHandlerEnum.MESSAGE_BAR, 15)
            self.close()
        else:
            self.show_message(msg, Qgis.Warning, 0)

    def show_message(self, message, level, duration=15):
        self.bar.clearWidgets(
        )  # Remove previous messages before showing a new one
        self.bar.pushMessage(message, level, duration)

    def show_help(self):
        self.qgis_utils.show_help("import_from_excel")
コード例 #3
0
class QualityRuleLayerManager(QObject):
    """
    Responsible for managing all layers during a Quality Rule execution
    session. It goes for LADM-COL layers only once and also manages
    intermediate layers (after snapping).
    """
    def __init__(self, db, rule_keys, tolerance):
        QObject.__init__(self)
        self.logger = Logger()
        self.app = AppInterface()

        self.__db = db
        self.__rule_keys = rule_keys
        self.__tolerance = tolerance

        self.__quality_rule_layers_config = QualityRuleConfig.get_quality_rules_layer_config(
            self.__db.names)

        # {rule_key: {QUALITY_RULE_LAYERS: {layer_name: layer},
        #             QUALITY_RULE_LADM_COL_LAYERS: {layer_name: layer}}
        self.__layers = dict()

        self.__adjusted_layers_cache = dict()

    def initialize(self, rule_keys):
        """
        Objects of this class are reusable calling initialize()
        """
        self.__rule_keys = rule_keys
        self.__layers = dict()

    def __prepare_layers(self):
        """
        Get layers from DB and prepare snapped layers for all rules
        """
        self.logger.info(
            __name__,
            QCoreApplication.translate("QualityRuleLayerManager",
                                       "Preparing layers..."))
        # First go for ladm-col layers
        ladm_layers = dict()
        for rule_key, rule_layers_config in self.__quality_rule_layers_config.items(
        ):
            if rule_key in self.__rule_keys:  # Only get selected rules' layers
                for layer_name in rule_layers_config[
                        QUALITY_RULE_LADM_COL_LAYERS]:
                    ladm_layers[layer_name] = None

        self.logger.debug(
            __name__,
            QCoreApplication.translate("QualityRuleLayerManager",
                                       "Getting {} LADM-COL layers...").format(
                                           len(ladm_layers)))
        self.app.core.get_layers(self.__db, ladm_layers, load=True)
        if ladm_layers is None:  # If there are errors with get_layers, ladm_layers is None
            self.logger.critical(
                __name__,
                QCoreApplication.translate(
                    "QualityRuleLayerManager",
                    "Couldn't finish preparing required layers!"))
            return False

        # If tolerance > 0, prepare adjusted layers
        #   We create an adjusted_layers dict to override ladm_layers per rule.
        #   For that, we need to read the config and, if not yet calculated,
        #   adjust the layers and store them in temporary cache.

        # {rule_key: {layer_name: layer}}, because each rule might need
        # different adjustments for the same layer, compared to other rules
        adjusted_layers = {rule_key: dict() for rule_key in self.__rule_keys}

        if self.__tolerance:
            self.logger.debug(
                __name__,
                QCoreApplication.translate(
                    "QualityRuleLayerManager",
                    "Tolerance > 0, adjusting layers..."))
            self.__adjusted_layers_cache = dict()  # adjusted_layers_key: layer
            count_rules = 0
            total_rules = len([
                rk for rk in self.__rule_keys
                if rk in self.__quality_rule_layers_config
            ])

            with ProcessWithStatus(
                    QCoreApplication.translate(
                        "QualityRuleLayerManager",
                        "Preparing tolerance on layers...")):
                for rule_key, rule_layers_config in self.__quality_rule_layers_config.items(
                ):
                    if rule_key in self.__rule_keys:  # Only get selected rules' layers
                        count_rules += 1
                        self.logger.status(
                            QCoreApplication.translate(
                                "QualityRuleLayerManager",
                                "Preparing tolerance on layers... {}%").format(
                                    int(count_rules / total_rules * 100)))
                        if QUALITY_RULE_ADJUSTED_LAYERS in rule_layers_config:

                            for layer_name, snap_config in rule_layers_config[
                                    QUALITY_RULE_ADJUSTED_LAYERS].items():
                                # Read from config
                                input_name = snap_config[
                                    ADJUSTED_INPUT_LAYER]  # input layer name
                                reference_name = snap_config[
                                    ADJUSTED_REFERENCE_LAYER]  # reference layer name
                                fix = snap_config[
                                    FIX_ADJUSTED_LAYER] if FIX_ADJUSTED_LAYER in snap_config else False

                                # Get input and reference layers (note that they could be adjusted layers)
                                input = self.__adjusted_layers_cache[
                                    input_name] if input_name in self.__adjusted_layers_cache else ladm_layers[
                                        input_name]
                                reference = self.__adjusted_layers_cache[
                                    reference_name] if reference_name in self.__adjusted_layers_cache else ladm_layers[
                                        reference_name]

                                # Try to reuse if already calculated!
                                adjusted_layers_key = get_key_for_quality_rule_adjusted_layer(
                                    input_name, reference_name, fix)
                                if adjusted_layers_key not in self.__adjusted_layers_cache:
                                    self.__adjusted_layers_cache[
                                        adjusted_layers_key] = self.app.core.adjust_layer(
                                            input, reference, self.__tolerance,
                                            fix)

                                adjusted_layers[rule_key][
                                    layer_name] = self.__adjusted_layers_cache[
                                        adjusted_layers_key]

            self.logger.debug(
                __name__,
                QCoreApplication.translate("QualityRuleLayerManager",
                                           "Layers adjusted..."))

        # Now that we have both ladm_layers and adjusted_layers, use them
        # in a single member dict of layers per rule (preserving original LADM-COL layers)
        self.__layers = {
            rule_key: {
                QUALITY_RULE_LAYERS: dict(),
                QUALITY_RULE_LADM_COL_LAYERS: dict()
            }
            for rule_key in self.__rule_keys
        }
        for rule_key, rule_layers_config in self.__quality_rule_layers_config.items(
        ):
            if rule_key in self.__rule_keys:  # Only get selected rules' layers
                for layer_name in rule_layers_config[
                        QUALITY_RULE_LADM_COL_LAYERS]:
                    # Fill both subdicts
                    # In LADM-COL layers we send all original layers
                    self.__layers[rule_key][QUALITY_RULE_LADM_COL_LAYERS][
                        layer_name] = ladm_layers[
                            layer_name] if layer_name in ladm_layers else None

                    # In QR_Layers we store the best layer we have available (preferring adjusted over ladm-col)
                    if layer_name in adjusted_layers[rule_key]:
                        self.__layers[rule_key][QUALITY_RULE_LAYERS][
                            layer_name] = adjusted_layers[rule_key][layer_name]
                    elif layer_name in ladm_layers:
                        self.__layers[rule_key][QUALITY_RULE_LAYERS][
                            layer_name] = ladm_layers[layer_name]

                # Let QRs know if they should switch between dicts looking for original geometries
                self.__layers[rule_key][HAS_ADJUSTED_LAYERS] = bool(
                    self.__tolerance)

        # Register adjusted layers so that Processing can properly find them
        if self.__adjusted_layers_cache:
            load_to_registry = [
                layer for key, layer in self.__adjusted_layers_cache.items()
                if layer is not None
            ]
            self.logger.debug(
                __name__,
                "{} adjusted layers loaded to QGIS registry...".format(
                    len(load_to_registry)))
            QgsProject.instance().addMapLayers(load_to_registry, False)

        return True

    def get_layer(self, layer_name, rule_key):
        return self.get_layers([layer_name], rule_key)

    def get_layers(self, rule_key):
        """
        Gets the layers a quality rule requires to run. This is based on the quality rule layer config.

        :param rule_key: Key of the quality rule.
        :return: Dict of layers for the given rule_key. This dict has both a 'layers' dict which has the best available
                 layer (which means, if an adjusted layer is required, it will be preferred, and if no adjusted layer is
                 required, just pass the LADM-COL layer) and a 'ladm-col' dict with the original LADM-COL layers,
                 because the quality rule might need to refer to the original object (or geometry) to build its result.
        """
        # Make sure we only call Prepare layers once for each call to run quality validations.
        if not self.__layers:
            if not self.__prepare_layers():
                return None

        return self.__layers[rule_key]

    def clean_temporary_layers(self):
        # Removes adjusted layers from registry
        unload_from_registry = [
            layer.id() for key, layer in self.__adjusted_layers_cache.items()
            if layer is not None
        ]
        self.logger.debug(
            __name__,
            "{} adjusted layers removed from QGIS registry...".format(
                len(unload_from_registry)))
        QgsProject.instance().removeMapLayers(unload_from_registry)
コード例 #4
0
class BasketExporter(QObject):
    total_progress_updated = pyqtSignal(int)  # percentage

    def __init__(self, db, basket_dict, export_dir):
        QObject.__init__(self)
        self._db = db
        self._basket_dict = basket_dict  # {t_ili_tids: receiver_name}
        self._export_dir = export_dir
        self.logger = Logger()

        self.log = ''
        self.java_dependency = JavaDependency()
        self.java_dependency.download_dependency_completed.connect(self.download_java_complete)

        self._dbs_supported = ConfigDBsSupported()

    def export_baskets(self):
        java_home_set = self.java_dependency.set_java_home()
        if not java_home_set:
            message_java = QCoreApplication.translate("BasketExporter", """Configuring Java {}...""").format(
                JAVA_REQUIRED_VERSION)
            self.logger.status(message_java)
            self.java_dependency.get_java_on_demand()
            return

        self.base_configuration = BaseConfiguration()
        self.ilicache = IliCache(self.base_configuration)

        db_factory = self._dbs_supported.get_db_factory(self._db.engine)
        self.configuration = ExportConfiguration()
        db_factory.set_ili2db_configuration_params(self._db.dict_conn_params, self.configuration)
        self.configuration.with_exporttid = True
        full_java_exe_path = JavaDependency.get_full_java_exe_path()
        if full_java_exe_path:
            self.base_configuration.java_path = full_java_exe_path

        # Check custom model directories
        if QSettings().value('Asistente-LADM-COL/models/custom_model_directories_is_checked', DEFAULT_USE_CUSTOM_MODELS, type=bool):
            custom_model_directories = QSettings().value('Asistente-LADM-COL/models/custom_models', DEFAULT_MODELS_DIR)
            if not custom_model_directories:
                self.base_configuration.custom_model_directories_enabled = False
            else:
                self.base_configuration.custom_model_directories = custom_model_directories
                self.base_configuration.custom_model_directories_enabled = True

        self.ilicache.refresh()  # Always call it after setting custom_model_directories

        self.configuration.base_configuration = self.base_configuration
        if self.get_ili_models():
            self.configuration.ilimodels = ';'.join(self.get_ili_models())

        self.exporter = iliexporter.Exporter()
        self.exporter.tool = db_factory.get_model_baker_db_ili_mode()
        self.exporter.process_started.connect(self.on_process_started)
        self.exporter.stderr.connect(self.on_stderr)
        #self.exporter.process_finished.connect(self.on_process_finished)

        res = dict()
        count = 0
        total = len(self._basket_dict)

        with OverrideCursor(Qt.WaitCursor):
            for basket,name in self._basket_dict.items():
                self.log = ''
                self.configuration.xtffile = os.path.join(self._export_dir, "{}.xtf".format(name))
                self.configuration.baskets = basket
                self.exporter.configuration = self.configuration

                try:
                    if self.exporter.run() != iliexporter.Exporter.SUCCESS:
                        msg = QCoreApplication.translate("BasketExporter", "An error occurred when exporting the data for '{}' (check the QGIS log panel).").format(name)
                        res[basket] = (False, msg)
                        QgsMessageLog.logMessage(self.log, QCoreApplication.translate("BasketExporter", "Allocate to coordinators"), Qgis.Critical)
                    else:
                        res[basket] = (True, QCoreApplication.translate("BasketExporter", "XTF export for '{}' successful!").format(name) )
                except JavaNotFoundError:
                    msg = QCoreApplication.translate("BasketExporter", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again.").format(JAVA_REQUIRED_VERSION)
                    res[basket] = (False, msg)

                count += 1
                self.total_progress_updated.emit(count/total*100)

        return res

    def get_ili_models(self):
        ili_models = list()
        model_names = self._db.get_models()
        if model_names:
            for model in LADMColModelRegistry().supported_models():
                if not model.hidden() and model.full_name() in model_names:
                    ili_models.append(model.full_name())

        return ili_models

    def download_java_complete(self):
        self.export_baskets()

    #def on_process_finished(self):
    #    self.run_export()
    #if self._basket_dict:
    #    basket, = self._basket_dict.popitem()

    def on_process_started(self, command):
        self.log += command + '\n'

    def on_stderr(self, text):
        self.log += text
コード例 #5
0
class Ili2DB(QObject):
    """
    Execute ili2db operations via Model Baker API
    """
    stdout = pyqtSignal(str)
    stderr = pyqtSignal(str)
    process_started = pyqtSignal(str)
    process_finished = pyqtSignal(int, int)

    def __init__(self):
        QObject.__init__(self)

        self.logger = Logger()

        self._java_path = ''
        self._java_dependency = JavaDependency()

        self.dbs_supported = ConfigDBsSupported()

        self._base_configuration = None
        self._ilicache = None
        self._log = ''

    def get_full_java_exe_path(self):
        if not self._java_path:
            self._java_path = JavaDependency.get_full_java_exe_path()

        return self._java_path

    def configure_java(self):
        if not self._java_dependency.set_java_home():
            message_java = QCoreApplication.translate(
                "Ili2DB",
                """Configuring Java {}...""").format(JAVA_REQUIRED_VERSION)
            self.logger.status(message_java)
            self._java_dependency.get_java_on_demand(asynchronous=False)

        res = True
        msg = 'Success!'

        java_path = self.get_full_java_exe_path()
        if not java_path:
            res = False
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be confiured for you. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)

        return res, msg

    def _get_base_configuration(self):
        """
        :return: BaseConfiguration object. If it's already configured, it returns the existing object, so that it can
                 be shared among chained operations (e.g., export DB1-->schema import DB2-->import DB2).
        """
        if not self._base_configuration:
            self._base_configuration = BaseConfiguration()
            self._ilicache = IliCache(self._base_configuration)

            self._base_configuration.java_path = self.get_full_java_exe_path(
            )  # It is well configured at this point!

            # Check custom model directories
            if QSettings().value(
                    'Asistente-LADM-COL/models/custom_model_directories_is_checked',
                    DEFAULT_USE_CUSTOM_MODELS,
                    type=bool):
                custom_model_directories = QSettings().value(
                    'Asistente-LADM-COL/models/custom_models',
                    DEFAULT_MODELS_DIR)
                if not custom_model_directories:
                    self._base_configuration.custom_model_directories_enabled = False
                else:
                    self._base_configuration.custom_model_directories = custom_model_directories
                    self._base_configuration.custom_model_directories_enabled = True

            # Debug mode
            self._base_configuration.debugging_enabled = \
                QSettings().value('Asistente-LADM-COL/models/debug', DEFAULT_ILI2DB_DEBUG_MODE, type=bool)

            self._base_configuration.logfile_path = QSettings().value(
                'Asistente-LADM-COL/models/log_file_path', '')

            self._ilicache.refresh(
            )  # Always call it after setting custom_model_directories

        return self._base_configuration

    def _get_ili_models(self, db):
        ili_models = list()
        model_names = db.get_models()
        if model_names:
            for model in LADMColModelRegistry().supported_models():
                if not model.hidden() and model.full_name() in model_names:
                    ili_models.append(model.full_name())

        return ili_models

    def get_import_schema_configuration(self,
                                        db,
                                        ili_models=list(),
                                        create_basket_col=False):
        db_factory = self.dbs_supported.get_db_factory(db.engine)

        configuration = SchemaImportConfiguration()
        db_factory.set_ili2db_configuration_params(db.dict_conn_params,
                                                   configuration)
        configuration.inheritance = ILI2DBNames.DEFAULT_INHERITANCE
        configuration.create_basket_col = create_basket_col
        configuration.create_import_tid = ILI2DBNames.CREATE_IMPORT_TID
        configuration.stroke_arcs = ILI2DBNames.STROKE_ARCS
        configuration.tomlfile = TOML_FILE_DIR

        configuration.base_configuration = self._get_base_configuration()
        configuration.ilimodels = ';'.join(ili_models)

        if db.engine == 'gpkg':
            # EPSG:9377 support for GPKG (Ugly, I know) We need to send known parameters, we'll fix this in the post_script
            configuration.srs_auth = 'EPSG'
            configuration.srs_code = 3116
            configuration.post_script = CTM12_GPKG_SCRIPT_PATH
        elif db.engine == 'pg':
            configuration.srs_auth = 'EPSG'
            configuration.srs_code = 9377
            configuration.pre_script = CTM12_PG_SCRIPT_PATH

        return configuration

    def get_import_data_configuration(self,
                                      db,
                                      xtf_path,
                                      dataset='',
                                      baskets=list(),
                                      disable_validation=False):
        db_factory = self.dbs_supported.get_db_factory(db.engine)
        configuration = ImportDataConfiguration()
        db_factory.set_ili2db_configuration_params(db.dict_conn_params,
                                                   configuration)
        configuration.with_importtid = True
        configuration.xtffile = xtf_path
        configuration.disable_validation = disable_validation
        configuration.dataset = dataset
        configuration.baskets = baskets  # list with basket UUIDs

        configuration.base_configuration = self._get_base_configuration()
        ili_models = self._get_ili_models(db)
        if ili_models:
            configuration.ilimodels = ';'.join(ili_models)

        return configuration

    def get_export_configuration(self,
                                 db,
                                 xtf_path,
                                 dataset='',
                                 baskets=list(),
                                 disable_validation=False):
        db_factory = self.dbs_supported.get_db_factory(db.engine)
        configuration = ExportConfiguration()
        db_factory.set_ili2db_configuration_params(db.dict_conn_params,
                                                   configuration)
        configuration.with_exporttid = True
        configuration.xtffile = xtf_path
        configuration.disable_validation = disable_validation
        configuration.dataset = dataset
        configuration.baskets = baskets  # List with basket UUIDs

        configuration.base_configuration = self._get_base_configuration()
        ili_models = self._get_ili_models(db)
        if ili_models:
            configuration.ilimodels = ';'.join(ili_models)

        return configuration

    def get_update_configuration(self, db_factory, db, xtf_path, dataset_name):
        configuration = UpdateDataConfiguration()
        db_factory.set_ili2db_configuration_params(db.dict_conn_params,
                                                   configuration)

        configuration.base_configuration = self._get_base_configuration()
        ili_models = self._get_ili_models(db)
        if ili_models:
            configuration.ilimodels = ';'.join(ili_models)

        configuration.dataset = dataset_name
        configuration.with_importbid = True
        configuration.with_importtid = True
        configuration.xtffile = xtf_path

        return configuration

    def get_validate_configuration(self, db_factory, db, model_names,
                                   xtflog_path, configfile_path):
        configuration = ValidateDataConfiguration()
        db_factory.set_ili2db_configuration_params(db.dict_conn_params,
                                                   configuration)

        configuration.base_configuration = self._get_base_configuration()
        # Since BaseConfiguration can be shared, avoid a --trace in --validate operation (not supported by ili2db)
        configuration.base_configuration.debugging_enabled = False

        if model_names:
            configuration.ilimodels = ';'.join(model_names)
        if xtflog_path:
            configuration.xtflogfile = xtflog_path
        if configfile_path:
            configuration.configfile = configfile_path

        return configuration

    @with_override_cursor
    def import_schema(self, db, configuration: SchemaImportConfiguration):
        # Check prerequisite
        if not self.get_full_java_exe_path():
            res_java, msg_java = self.configure_java()
            if not res_java:
                return res_java, msg_java

        # Configure command parameters
        db_factory = self.dbs_supported.get_db_factory(db.engine)

        # Configure run
        importer = iliimporter.Importer()
        importer.tool = db_factory.get_model_baker_db_ili_mode()
        importer.configuration = configuration

        self._connect_ili_executable_signals(importer)

        # Run!
        res = True
        msg = QCoreApplication.translate("Ili2DB",
                                         "Schema import ran successfully!")
        self._log = ''
        self.logger.status(
            QCoreApplication.translate(
                "Ili2Db", "Creating LADM-COL structure into {}...").format(
                    db.engine.upper()))
        try:
            if importer.run() != iliimporter.Importer.SUCCESS:
                msg = QCoreApplication.translate(
                    "Ili2DB",
                    "An error occurred when importing a schema into a DB (check the QGIS log panel)."
                )
                res = False
                QgsMessageLog.logMessage(
                    self._log,
                    QCoreApplication.translate("Ili2DB", "DB Schema Import"),
                    Qgis.Critical)

        except JavaNotFoundError:
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)
            res = False

        self._disconnect_ili_executable_signals(importer)
        self.logger.clear_status()
        return res, msg

    @with_override_cursor
    def import_data(self, db, configuration: ImportDataConfiguration):
        # Check prerequisite
        if not self.get_full_java_exe_path():
            res_java, msg_java = self.configure_java()
            if not res_java:
                return res_java, msg_java

        # Configure command parameters
        db_factory = self.dbs_supported.get_db_factory(db.engine)

        # Configure run
        importer = iliimporter.Importer(dataImport=True)
        importer.tool = db_factory.get_model_baker_db_ili_mode()
        importer.configuration = configuration

        self._connect_ili_executable_signals(importer)

        # Run!
        res = True
        msg = QCoreApplication.translate(
            "Ili2DB",
            "XTF '{}' imported successfully!").format(configuration.xtffile)
        self._log = ''
        self.logger.status(
            QCoreApplication.translate("Ili2Db",
                                       "Importing XTF into {}...").format(
                                           db.engine.upper()))
        try:
            if importer.run() != iliimporter.Importer.SUCCESS:
                msg = QCoreApplication.translate(
                    "Ili2DB",
                    "An error occurred when importing from XTF (check the QGIS log panel)."
                )
                res = False
                QgsMessageLog.logMessage(
                    self._log,
                    QCoreApplication.translate("Ili2DB", "Import from XTF"),
                    Qgis.Critical)

        except JavaNotFoundError:
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)
            res = False

        self._disconnect_ili_executable_signals(importer)
        self.logger.clear_status()
        return res, msg

    @with_override_cursor
    def export(self, db, configuration: ExportConfiguration):
        # Check prerequisite
        if not self.get_full_java_exe_path():
            res_java, msg_java = self.configure_java()
            if not res_java:
                return res_java, msg_java

        # Configure command parameters
        db_factory = self.dbs_supported.get_db_factory(db.engine)

        # Configure run
        exporter = iliexporter.Exporter()
        exporter.tool = db_factory.get_model_baker_db_ili_mode()
        exporter.configuration = configuration

        self._connect_ili_executable_signals(exporter)

        # Run!
        res = True
        msg = QCoreApplication.translate(
            "Ili2DB",
            "XTF '{}' exported successfully!").format(configuration.xtffile)
        self._log = ''
        self.logger.status(
            QCoreApplication.translate("Ili2Db",
                                       "Exporting from {} to XTF...").format(
                                           db.engine.upper()))
        try:
            if exporter.run() != iliexporter.Exporter.SUCCESS:
                msg = QCoreApplication.translate(
                    "Ili2DB",
                    "An error occurred when exporting data to XTF (check the QGIS log panel)."
                )
                res = False
                QgsMessageLog.logMessage(
                    self._log,
                    QCoreApplication.translate("Ili2DB", "Export to XTF"),
                    Qgis.Critical)
            else:
                self.logger.info(__name__, msg)

        except JavaNotFoundError:
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)
            res = False

        self._disconnect_ili_executable_signals(exporter)
        self.logger.clear_status()
        return res, msg

    @with_override_cursor
    def update(self, db, xtf_path, dataset_name):
        # Check prerequisite
        if not self.get_full_java_exe_path():
            res_java, msg_java = self.configure_java()
            if not res_java:
                return res_java, msg_java

        # Configure command parameters
        db_factory = self.dbs_supported.get_db_factory(db.engine)
        configuration = self.get_update_configuration(db_factory, db, xtf_path,
                                                      dataset_name)

        # Configure run
        updater = iliupdater.Updater()
        updater.tool = db_factory.get_model_baker_db_ili_mode()
        updater.configuration = configuration

        self._connect_ili_executable_signals(updater)

        # Run!
        res = True
        msg = QCoreApplication.translate(
            "Ili2DB",
            "DB updated successfully from XTF file '{}'!").format(xtf_path)
        self._log = ''
        self.logger.status(
            QCoreApplication.translate(
                "Ili2Db", "Updating {} DB from XTF '{}'...").format(
                    db.engine.upper(), xtf_path))
        try:
            if updater.run() != iliupdater.Updater.SUCCESS:
                msg = QCoreApplication.translate(
                    "Ili2DB",
                    "An error occurred when updating the DB from an XTF (check the QGIS log panel)."
                )
                res = False
                QgsMessageLog.logMessage(
                    self._log,
                    QCoreApplication.translate("Ili2DB", "Update DB from XTF"),
                    Qgis.Critical)
            else:
                self.logger.info(__name__, msg)

        except JavaNotFoundError:
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)
            res = False

        self._disconnect_ili_executable_signals(updater)
        self.logger.clear_status()
        return res, msg

    @with_override_cursor
    def validate(self,
                 db,
                 model_names=list(),
                 xtflog_path='',
                 configfile_path=''):
        # Check prerequisite
        if not self.get_full_java_exe_path():
            res_java, msg_java = self.configure_java()
            if not res_java:
                return res_java, msg_java

        # Configure command parameters
        db_factory = self.dbs_supported.get_db_factory(db.engine)
        configuration = self.get_validate_configuration(
            db_factory, db, model_names, xtflog_path, configfile_path)

        # Configure run
        validator = ili2dbvalidator.Ili2DBValidator()
        validator.tool = db_factory.get_model_baker_db_ili_mode()
        validator.process_started.connect(self.on_process_started)
        validator.stderr.connect(self.on_stderr)
        validator.configuration = configuration

        # Run!
        res = True
        msg = QCoreApplication.translate(
            "Ili2DB", "Data successfully validated from DB '{}'!").format(
                db.get_description_conn_string())
        self._log = ''
        self.logger.status(
            QCoreApplication.translate(
                "Ili2Db", "Validating data from '{}' DB...").format(
                    db.get_description_conn_string()))
        try:
            res_validation = validator.run()
            if (res_validation != ili2dbvalidator.Ili2DBValidator.SUCCESS
                    and res_validation != ili2dbvalidator.Ili2DBValidator.
                    SUCCESS_WITH_VALIDATION_ERRORS):
                msg = QCoreApplication.translate(
                    "Ili2DB",
                    "An error occurred when validating data from a DB (check the QGIS log panel)."
                )
                res = False
                QgsMessageLog.logMessage(
                    self._log,
                    QCoreApplication.translate("Ili2DB",
                                               "Validate data from DB"),
                    Qgis.Critical)
            else:
                self.logger.info(__name__, msg)
        except JavaNotFoundError:
            msg = QCoreApplication.translate(
                "Ili2DB",
                "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again."
            ).format(JAVA_REQUIRED_VERSION)
            res = False

        self.logger.clear_status()
        return res, msg

    def on_process_started(self, command):
        self._log += command + '\n'

    def on_stderr(self, text):
        self._log += text

    def _connect_ili_executable_signals(self, ili_executable: IliExecutable):
        ili_executable.process_started.connect(self.process_started)
        ili_executable.stderr.connect(self.stderr)
        ili_executable.stdout.connect(self.stdout)
        ili_executable.process_finished.connect(self.process_finished)

        ili_executable.process_started.connect(self.on_process_started)
        ili_executable.stderr.connect(self.on_stderr)

    def _disconnect_ili_executable_signals(self,
                                           ili_executable: IliExecutable):
        ili_executable.process_started.disconnect(self.process_started)
        ili_executable.stderr.disconnect(self.stderr)
        ili_executable.stdout.disconnect(self.stdout)
        ili_executable.process_finished.disconnect(self.process_finished)

        ili_executable.process_started.disconnect(self.on_process_started)
        ili_executable.stderr.disconnect(self.on_stderr)