Exemplo n.º 1
0
    def register_cim1(self, **kwargs):

        request = kwargs.pop("request", None)

        try:
            self.file.open()
            ontology_content = et.parse(self.file)
            self.file.close()
        except IOError:
            msg = "Error opening file: %s" % self.file
            if request:
                messages.add_message(request, messages.ERROR, msg)
                return

        recategorization_needed = False

        old_model_proxies = list(self.model_proxies.all())  # list forces qs evaluation immediately
        new_model_proxies = []

        for i, model_proxy in enumerate(xpath_fix(ontology_content, "//classes/class")):

            model_proxy_ontology = self
            model_proxy_name = xpath_fix(model_proxy, "name/text()")[0]
            model_proxy_stereotype = get_index(xpath_fix(model_proxy, "@stereotype"), 0)
            model_proxy_namespace = get_index(xpath_fix(model_proxy, "@namespace"), 0)
            model_proxy_package = get_index(xpath_fix(model_proxy, "@package"), 0)
            model_proxy_documentation = get_index(xpath_fix(model_proxy, "description/text()"), 0)
            if model_proxy_documentation:
                model_proxy_documentation = remove_spaces_and_linebreaks(model_proxy_documentation)
            else:
                model_proxy_documentation = u""

            (new_model_proxy, created_model_proxy) = QModelProxy.objects.get_or_create(
                ontology=model_proxy_ontology,
                name=model_proxy_name,
            )

            if created_model_proxy:
                recategorization_needed = True

            new_model_proxy.order = i + 1
            new_model_proxy.stereotype = model_proxy_stereotype
            new_model_proxy.namespace = model_proxy_namespace
            new_model_proxy.package = model_proxy_package
            new_model_proxy.documentation = model_proxy_documentation
            new_model_proxy.save()
            new_model_proxies.append(new_model_proxy)

            old_property_proxies = list(new_model_proxy.standard_properties.all())  # list forces qs evaluation immediately
            new_property_proxies = []

            for j, property_proxy in enumerate(xpath_fix(model_proxy, "attributes/attribute")):

                property_proxy_name = re.sub(r'\.', '_', str(xpath_fix(property_proxy, "name/text()")[0]))
                property_proxy_field_type = xpath_fix(property_proxy, "type/text()")[0]
                property_proxy_is_label = get_index(xpath_fix(property_proxy, "@is_label"), 0)
                property_proxy_stereotype = get_index(xpath_fix(property_proxy, "@stereotype"), 0)
                property_proxy_namespace = get_index(xpath_fix(property_proxy, "@namespace"), 0)
                property_proxy_required = get_index(xpath_fix(property_proxy, "@required"), 0)
                property_proxy_documentation = get_index(xpath_fix(property_proxy, "description/text()"), 0)
                if property_proxy_documentation:
                    property_proxy_documentation = remove_spaces_and_linebreaks(property_proxy_documentation)
                else:
                    property_proxy_documentation = u""
                property_proxy_atomic_type = get_index(xpath_fix(property_proxy, "atomic/atomic_type/text()"), 0)
                if property_proxy_atomic_type:
                    if property_proxy_atomic_type == u"STRING":
                        property_proxy_atomic_type = u"DEFAULT"
                    property_proxy_atomic_type = QAtomicPropertyTypes.get(property_proxy_atomic_type)
                property_proxy_enumeration_choices = []
                for property_proxy_enumeration_choice in xpath_fix(property_proxy, "enumeration/choice"):
                    property_proxy_enumeration_choices.append(xpath_fix(property_proxy_enumeration_choice, "text()")[0])
                property_proxy_relationship_cardinality_min = get_index(xpath_fix(property_proxy, "relationship/cardinality/@min"), 0)
                property_proxy_relationship_cardinality_max = get_index(xpath_fix(property_proxy, "relationship/cardinality/@max"), 0)
                property_proxy_relationship_target_name = get_index(xpath_fix(property_proxy, "relationship/target/text()"), 0)

                (new_property_proxy, created_property) = QStandardPropertyProxy.objects.get_or_create(
                    model_proxy=new_model_proxy,
                    name=property_proxy_name,
                    field_type=property_proxy_field_type
                )

                if created_property:
                    recategorization_needed = True

                new_property_proxy.order = j + 1
                new_property_proxy.documentation = property_proxy_documentation
                new_property_proxy.is_label = property_proxy_is_label == "true"
                new_property_proxy.stereotype = property_proxy_stereotype
                new_property_proxy.namespace = property_proxy_namespace
                if property_proxy_field_type == QPropertyTypes.RELATIONSHIP:
                    if property_proxy_relationship_cardinality_min and property_proxy_relationship_cardinality_max:
                        new_property_proxy.cardinality = u"%s|%s" % (property_proxy_relationship_cardinality_min, property_proxy_relationship_cardinality_max)
                else:
                    if property_proxy_required:
                        new_property_proxy.cardinality = u"1|1"
                new_property_proxy.atomic_type = property_proxy_atomic_type
                new_property_proxy.enumeration_choices = "|".join(property_proxy_enumeration_choices)
                new_property_proxy.relationship_target_name = property_proxy_relationship_target_name
                new_property_proxy.save()
                new_property_proxies.append(new_property_proxy)

            # if there's anything in old_property_proxies not in new_property_proxies, delete it
            for old_property_proxy in old_property_proxies:
                if old_property_proxy not in new_property_proxies:
                    old_property_proxy.delete()

            new_model_proxy.save()  # save parent again for the m2m relationship

        # if there's anything in old_model_proxies not in new_model_proxies, delete it
        for old_model_proxy in old_model_proxies:
            if old_model_proxy not in new_model_proxies:
                old_model_proxy.delete()

        # reset whatever's left
        for model_proxy in QModelProxy.objects.filter(ontology=self):
            for property_proxy in model_proxy.standard_properties.all():
                property_proxy.reset()
                property_proxy.save()

        if recategorization_needed:
            msg = "Since you are re-registering an existing version, you will also have to re-register the corresponding categorization"
            if request:
                messages.add_message(request, messages.WARNING, msg)
    def parse_schema(self, **kwargs):
        """
        registers a CIM2 ontology schema QXML file
        :param kwargs:
        :return:
        """

        request = kwargs.pop("request", None)

        try:
            self.file.open()
            ontology_content = et.parse(self.file)
            self.file.close()
        except IOError as e:
            msg = "Error opening file: {0}".format(self.file)
            if request:
                messages.add_message(request, messages.ERROR, msg)
            raise e

        recategorization_needed = False

        # name can be anything...
        ontology_name = get_index(xpath_fix(ontology_content, "name/text()"), 0)

        # version should match(ish) the instance field...
        ontology_version = get_index(xpath_fix(ontology_content, "version/text()"), 0)
        if self.version.major() != Version(ontology_version).major():
            msg = "The major version of this ontology instance does not match the major version of the QXML file"
            if request:
                messages.add_message(request, messages.WARNING, msg)

        # description can overwrite the instance field...
        ontology_description = get_index(xpath_fix(ontology_content, "description/text()"), 0)
        if ontology_description:
            self.description = remove_spaces_and_linebreaks(ontology_description)

        old_model_proxies = list(self.model_proxies.all())  # list forces qs evaluation immediately
        new_model_proxies = []

        for i, model_proxy in enumerate(xpath_fix(ontology_content, "//classes/class"), start=1):
            model_proxy_package = xpath_fix(model_proxy, "@package")[0]
            model_proxy_schema = self
            model_proxy_name = xpath_fix(model_proxy, "name/text()")[0]
            model_proxy_stereotype = get_index(xpath_fix(model_proxy, "@stereotype"), 0)
            model_proxy_documentation = get_index(xpath_fix(model_proxy, "description/text()"), 0)
            if model_proxy_documentation:
                model_proxy_documentation = remove_spaces_and_linebreaks(model_proxy_documentation)
            else:
                model_proxy_documentation = u""

            (new_model_proxy, created_model_proxy) = QModelProxy.objects.get_or_create(
                package=model_proxy_package, ontology=model_proxy_schema, name=model_proxy_name
            )

            if created_model_proxy:
                recategorization_needed = True

            new_model_proxy.order = i
            new_model_proxy.stereotype = model_proxy_stereotype
            new_model_proxy.documentation = model_proxy_documentation
            new_model_proxy.save()
            new_model_proxies.append(new_model_proxy)

            old_property_proxies = list(new_model_proxy.property_proxies.all())  # list forces qs evaluation immediately
            new_property_proxies = []

            for j, property_proxy in enumerate(xpath_fix(model_proxy, "attributes/attribute"), start=1):
                property_proxy_name = re.sub(r"\.", "_", str(xpath_fix(property_proxy, "name/text()")[0]))
                property_proxy_field_type = xpath_fix(property_proxy, "type/text()")[0]
                property_proxy_stereotype = get_index(xpath_fix(property_proxy, "@stereotype"), 0)
                property_proxy_documentation = get_index(xpath_fix(property_proxy, "description/text()"), 0)
                if property_proxy_documentation:
                    property_proxy_documentation = remove_spaces_and_linebreaks(property_proxy_documentation)
                else:
                    property_proxy_documentation = u""
                property_proxy_cardinality_min = get_index(xpath_fix(property_proxy, "cardinality/@min"), 0)
                property_proxy_cardinality_max = get_index(xpath_fix(property_proxy, "cardinality/@max"), 0)
                property_proxy_is_nillable = get_index(xpath_fix(property_proxy, "@is_nillable"), 0)

                (new_property_proxy, created_property) = QPropertyProxy.objects.get_or_create(
                    model_proxy=new_model_proxy, name=property_proxy_name, field_type=property_proxy_field_type
                )

                if created_property:
                    recategorization_needed = True

                new_property_proxy.order = j
                new_property_proxy.documentation = property_proxy_documentation
                new_property_proxy.stereotype = property_proxy_stereotype
                new_property_proxy.cardinality = "{0}|{1}".format(
                    property_proxy_cardinality_min,
                    property_proxy_cardinality_max if property_proxy_cardinality_max != "N" else "*",
                )
                new_property_proxy.is_nillable = property_proxy_is_nillable

                # atomic properties...
                property_proxy_atomic_type = get_index(xpath_fix(property_proxy, "atomic/atomic_type/text()"), 0)
                if property_proxy_atomic_type:
                    if property_proxy_atomic_type == u"STRING":
                        property_proxy_atomic_type = u"DEFAULT"
                    property_proxy_atomic_type = QAtomicPropertyTypes.get(property_proxy_atomic_type)
                    new_property_proxy.atomic_type = property_proxy_atomic_type

                # relationship properties...
                property_proxy_relationship_target_names = "|".join(
                    # note that each target_name is fully-qualified
                    xpath_fix(property_proxy, "relationship/targets/target/text()")
                )
                new_property_proxy.relationship_target_names = property_proxy_relationship_target_names

                # enumeration properties...
                property_proxy_enumeration_is_open = get_index(xpath_fix(property_proxy, "enumeration/@is_open"), 0)
                property_proxy_enumeration_is_multi = get_index(xpath_fix(property_proxy, "enumeration/@is_multi"), 0)
                if property_proxy_enumeration_is_open:
                    new_property_proxy.enumeration_is_open = property_proxy_enumeration_is_open == "true"
                if property_proxy_enumeration_is_multi:
                    new_property_proxy.enumeration_is_multi = property_proxy_enumeration_is_multi == "true"
                property_proxy_enumeration = []
                for k, enumeration_member_proxy in enumerate(
                    xpath_fix(property_proxy, "enumeration/choices/choice"), start=1
                ):
                    enumeration_member_proxy_value = get_index(xpath_fix(enumeration_member_proxy, "value/text()"), 0)
                    enumeration_member_proxy_documentation = get_index(
                        xpath_fix(enumeration_member_proxy, "description/text()"), 0
                    )
                    property_proxy_enumeration_member = {
                        "order": k,
                        "value": enumeration_member_proxy_value,
                        "name": enumeration_member_proxy_value,
                        "documentation": enumeration_member_proxy_documentation,
                    }
                    property_proxy_enumeration.append(property_proxy_enumeration_member)
                new_property_proxy.enumeration = property_proxy_enumeration

                new_property_proxy.save()
                new_property_proxies.append(new_property_proxy)

            # if there's anything in old_property_proxies not in new_property_proxies, delete it
            for old_property_proxy in old_property_proxies:
                if old_property_proxy not in new_property_proxies:
                    old_property_proxy.delete()

            new_model_proxy.save()  # save parent again for the m2m relationship

        # if there's anything in old_model_proxies not in new_model_proxies, delete it
        for old_model_proxy in old_model_proxies:
            if old_model_proxy not in new_model_proxies:
                old_model_proxy.delete()

        # reset whatever's left
        for model_proxy in QModelProxy.objects.filter(ontology=self):
            for property_proxy in model_proxy.property_proxies.all():
                property_proxy.reset()
                property_proxy.save()

        if recategorization_needed:
            msg = "Since you are re-registering an existing version, you will also have to re-register the corresponding categorization"
            if request:
                messages.add_message(request, messages.WARNING, msg)