Example #1
0
def is_schema_valid(object_type, content, name=None):
    # is the name unique?
    if name is not None:
        if object_type.lower() == 'template':
            names = Template.objects.all().values_list('title')
        elif object_type.lower() == 'type':
            names = Type.objects.all().values_list('title')
        if name in names:
            raise MDCSError(
                'A {} with the same name already exists'.format(object_type))

    # is it a valid XML document?
    try:
        try:
            xsd_tree = etree.parse(BytesIO(content.encode('utf-8')))
        except Exception:
            xsd_tree = etree.parse(BytesIO(content))
    except Exception:
        raise XMLError('Uploaded file is not well formatted XML.')

    # is it supported by the MDCS?
    errors = common.getValidityErrorsForMDCS(xsd_tree, object_type)
    if len(errors) > 0:
        errors_str = ", ".join(errors)
        raise MDCSError(errors_str)

    # is it a valid XML schema?
    error = validate_xml_schema(xsd_tree)
    if error is not None:
        raise XSDError(error)
    def check_result(self, expected_code=200):
        """
        Check that the result template is valid
        :return:
        """
        self.assertEqual(self.response.status_code, expected_code)

        composed_template = self.request.session['newXmlTemplateCompose']
        self.assertEquals(validate_xml_schema(etree.fromstring(composed_template)), None)
def resolve_dependencies(request):
    print 'BEGIN def resolveDependencies(request)'
    schema_locations = request.POST.getlist('schemaLocations[]')
    dependencies = request.POST.getlist('dependencies[]')

    if ('uploadObjectName' in request.session and request.session['uploadObjectName'] is not None and
        'uploadObjectFilename' in request.session and request.session['uploadObjectFilename'] is not None and
        'uploadObjectContent' in request.session and request.session['uploadObjectContent'] is not None and
        'uploadObjectType' in request.session and request.session['uploadObjectType'] is not None):
        object_content = request.session['uploadObjectContent']
        name = request.session['uploadObjectName']
        filename = request.session['uploadObjectFilename']
        object_type = request.session['uploadObjectType']

    # Load a parser able to clean the XML from blanks, comments and processing instructions
    clean_parser = etree.XMLParser(remove_blank_text=True, remove_comments=True, remove_pis=True)
    # set the parser
    etree.set_default_parser(parser=clean_parser)

    xsd_tree = etree.XML(str(object_content.encode('utf-8')))

    # replace includes/imports by API calls (get dependencies starting by the imports)
    update_dependencies(xsd_tree, dict(zip(schema_locations, dependencies)))

    # validate the schema
    error = validate_xml_schema(xsd_tree)

    if error is None:
        object_content = etree.tostring(xsd_tree)
        # create a new version
        if 'uploadVersion' in request.session and request.session['uploadVersion'] is not None:
            object_versions_id = request.session['uploadVersion']
            if object_type == 'Template':
                new_template = create_template_version(object_content, filename, object_versions_id)
                redirect = '/admin/manage_versions?type={0}&id={1}'.format(object_type, str(new_template.id))
            elif object_type == 'Type':
                new_type = create_type_version(object_content, filename, object_versions_id)
                redirect = '/admin/manage_versions?type={0}&id={1}'.format(object_type, str(new_type.id))
        # create new object
        else:
            # save the object
            if object_type == "Template":
                create_template(object_content, name, filename, dependencies)
                redirect = '/admin/xml-schemas/manage-schemas'
            elif object_type == "Type":
                if 'uploadBuckets' in request.session and request.session['uploadBuckets'] is not None:
                    buckets = request.session['uploadBuckets']
                create_type(object_content, name, filename, buckets, dependencies)
                redirect = '/admin/xml-schemas/manage-types'

        response_dict = {'redirect': redirect}
        messages.add_message(request, messages.INFO, '{} uploaded with success.'.format(object_type))
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
    else:
        response_dict = {'errorDependencies': error.replace("'", "")}
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
Example #4
0
    def test_basic(self):
        # load template
        template_path = join(RESOURCES_PATH, 'basic.xsd')
        self.load_template(template_path)

        # test LXML
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
Example #5
0
    def test_include_filesystem(self):
        # load template
        template_path = join(RESOURCES_PATH, 'include.xsd')
        self.load_template(template_path)

        # test LXML
        if TEST_LXML:
            self.assertNotEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertNotEquals(validate_xml_schema(self.xsd_tree), None)
    def test_basic(self):
        # load template
        template_path = join(RESOURCES_PATH, 'basic.xsd')
        self.load_template(template_path)

        # test LXML
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
    def test_include_filesystem(self):
        # load template
        template_path = join(RESOURCES_PATH, 'include.xsd')
        self.load_template(template_path)

        # test LXML
        if TEST_LXML:
            self.assertNotEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertNotEquals(validate_xml_schema(self.xsd_tree), None)
Example #8
0
    def test_1_1(self):
        # load template
        template_path = join(RESOURCES_PATH, '1.1.xsd')
        self.load_template(template_path)

        # test LXML
        # TODO: LXML fails to validate
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
    def test_1_1(self):
        # load template
        template_path = join(RESOURCES_PATH, '1.1.xsd')
        self.load_template(template_path)

        # test LXML
        # TODO: LXML fails to validate
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
    def test_import_django(self):
        # load type
        type_path = join(RESOURCES_PATH, 'to-import.xsd')
        type_object = self.load_type(type_path)

        # load template
        template_path = join(RESOURCES_PATH, 'import.xsd')
        self.load_template(template_path)

        update_dependencies(self.xsd_tree, {'to-import.xsd': str(type_object.id)})
        self.xsd_string = etree.tostring(self.xsd_tree)

        # test LXML
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
Example #11
0
    def test_import_django(self):
        # load type
        type_path = join(RESOURCES_PATH, 'to-import.xsd')
        type_object = self.load_type(type_path)

        # load template
        template_path = join(RESOURCES_PATH, 'import.xsd')
        self.load_template(template_path)

        update_dependencies(self.xsd_tree,
                            {'to-import.xsd': str(type_object.id)})
        self.xsd_string = etree.tostring(self.xsd_tree)

        # test LXML
        if TEST_LXML:
            self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None)
        # test global method
        self.assertEquals(validate_xml_schema(self.xsd_tree), None)
Example #12
0
################################################################################
def save_template(request):
    template_name = request.POST['templateName']
    content = request.session['newXmlTemplateCompose']

    response_dict = {}

    # Validate XML document
    try:
        xml_tree = etree.parse(BytesIO(content.encode('utf-8')))
    except Exception, e:
        response_dict['errors'] = e.message.replace("'", "")
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')

    # validate the schema
    error = validate_xml_schema(xml_tree)

    if error is not None:
        response_dict['errors'] = 'This is not a valid XML schema.' + error.replace("'", "")
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')

    dependencies = []

    for uri in request.session["includedTypesCompose"]:
        url = urlparse(uri)
        id = url.query.split("=")[1]
        dependencies.append(id)

    create_template(content, template_name, template_name, dependencies, user=str(request.user.id))

    return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
Example #13
0
def insert_element_sequence(request):
    try:
        type_id = request.POST['typeID']
        client_type_name = request.POST['typeName']
        xpath = request.POST['xpath']

        xml_tree_str = request.session['newXmlTemplateCompose']

        # build the dom tree of the schema being built
        xsd_tree = etree.parse(BytesIO(xml_tree_str.encode('utf-8')))
        # get namespaces information for the schema
        namespaces = get_namespaces(BytesIO(str(xml_tree_str)))
        default_prefix = get_default_prefix(namespaces)
        # get target namespace information
        target_namespace, target_namespace_prefix = get_target_namespace(
            namespaces, xsd_tree)
        # build xpath to element
        xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE)
        if type_id == 'built_in_type':
            type_name = default_prefix + ':' + client_type_name
            xsd_tree.find(xpath).append(
                etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                              attrib={
                                  'type': type_name,
                                  'name': client_type_name
                              }))
            # validate XML schema
            error = validate_xml_schema(xsd_tree)
            new_xsd_str = etree.tostring(xsd_tree)
        else:
            # get the type being included
            type_object = Type.objects().get(pk=type_id)
            type_xsd_tree = etree.parse(
                BytesIO(type_object.content.encode('utf-8')))
            # get namespaces information for the type
            type_namespaces = get_namespaces(BytesIO(str(type_object.content)))
            type_target_namespace, type_target_namespace_prefix = get_target_namespace(
                type_namespaces, type_xsd_tree)

            # get the type from the included/imported file
            # If there is a complex type
            element_type = type_xsd_tree.find(
                "{}complexType".format(LXML_SCHEMA_NAMESPACE))
            if element_type is None:
                # If there is a simple type
                element_type = type_xsd_tree.find(
                    "{}simpleType".format(LXML_SCHEMA_NAMESPACE))
            type_name = element_type.attrib["name"]

            if type_target_namespace is not None:
                ns_type_name = "{0}:{1}".format(type_target_namespace_prefix,
                                                type_name)
            else:
                if target_namespace is not None:
                    ns_type_name = "{0}:{1}".format(target_namespace_prefix,
                                                    type_name)
                else:
                    ns_type_name = '{}'.format(type_name)
            nsmap = {type_target_namespace_prefix: type_target_namespace}
            update_nsmap = False

            # get link to the type to include
            include_url = getSchemaLocation(str(type_id))

            # Schema without target namespace
            if target_namespace is None:
                # Type without target namespace
                if type_target_namespace is None:
                    # add include
                    xsd_tree.getroot().insert(
                        0,
                        etree.Element(
                            "{}include".format(LXML_SCHEMA_NAMESPACE),
                            attrib={'schemaLocation': include_url}))
                    # add element
                    xsd_tree.find(xpath).append(
                        etree.Element(
                            "{}element".format(LXML_SCHEMA_NAMESPACE),
                            attrib={
                                'type': type_name,
                                'name': client_type_name
                            }))
                # Type with target namespace
                else:
                    # add import
                    xsd_tree.getroot().insert(
                        0,
                        etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE),
                                      attrib={
                                          'schemaLocation': include_url,
                                          'namespace': type_target_namespace
                                      }))
                    # create the element to add
                    element = etree.Element(
                        "{}element".format(LXML_SCHEMA_NAMESPACE),
                        attrib={
                            'name': client_type_name,
                            'type': ns_type_name
                        },
                    )
                    # add the element
                    xsd_tree.find(xpath).append(element)

                    update_nsmap = True

            # Schema with target namespace
            else:
                # Type without target namespace
                if type_target_namespace is None:
                    # add include
                    xsd_tree.getroot().insert(
                        0,
                        etree.Element(
                            "{}include".format(LXML_SCHEMA_NAMESPACE),
                            attrib={'schemaLocation': include_url}))
                    # add element
                    xsd_tree.find(xpath).append(
                        etree.Element(
                            "{}element".format(LXML_SCHEMA_NAMESPACE),
                            attrib={
                                'name': client_type_name,
                                'type': ns_type_name
                            }))
                # Type with target namespace
                else:
                    # Same target namespace as base template
                    if target_namespace == type_target_namespace:
                        # add include
                        xsd_tree.getroot().insert(
                            0,
                            etree.Element(
                                "{}include".format(LXML_SCHEMA_NAMESPACE),
                                attrib={'schemaLocation': include_url}))
                        # add element
                        xsd_tree.find(xpath).append(
                            etree.Element(
                                "{}element".format(LXML_SCHEMA_NAMESPACE),
                                attrib={
                                    'name': client_type_name,
                                    'type': ns_type_name
                                }))
                    # Different target namespace as base template
                    else:
                        # add import
                        xsd_tree.getroot().insert(
                            0,
                            etree.Element(
                                "{}import".format(LXML_SCHEMA_NAMESPACE),
                                attrib={
                                    'schemaLocation': include_url,
                                    'namespace': type_target_namespace
                                }))
                        # create the element to add
                        element = etree.Element(
                            "{}element".format(LXML_SCHEMA_NAMESPACE),
                            attrib={
                                'name': client_type_name,
                                'type': ns_type_name
                            },
                        )
                        # add the element
                        xsd_tree.find(xpath).append(element)

                        update_nsmap = True

            # add the id of the type if not already present
            if include_url not in request.session['includedTypesCompose']:
                request.session['includedTypesCompose'].append(include_url)

            if update_nsmap:
                root = xsd_tree.getroot()
                root_nsmap = root.nsmap

                if type_target_namespace_prefix in root_nsmap.keys() and\
                                root_nsmap[type_target_namespace_prefix] != type_target_namespace:
                    raise MDCSError(
                        'The namespace prefix is already declared for a different namespace.'
                    )
                else:
                    root_nsmap[
                        type_target_namespace_prefix] = type_target_namespace
                    new_root = etree.Element(root.tag, nsmap=root_nsmap)
                    new_root[:] = root[:]

                    # validate XML schema
                    error = validate_xml_schema(new_root)
                    new_xsd_str = etree.tostring(new_root)

            else:
                # validate XML schema
                error = validate_xml_schema(xsd_tree)
                new_xsd_str = etree.tostring(xsd_tree)

        if error is not None:
            raise MDCSError(error)

        # save the tree in the session
        request.session['newXmlTemplateCompose'] = new_xsd_str
    except Exception, e:
        return HttpResponseBadRequest(e.message,
                                      content_type='application/javascript')
Example #14
0
def resolve_dependencies(request):
    print 'BEGIN def resolveDependencies(request)'
    schema_locations = request.POST.getlist('schemaLocations[]')
    dependencies = request.POST.getlist('dependencies[]')

    if ('uploadObjectName' in request.session
            and request.session['uploadObjectName'] is not None
            and 'uploadObjectFilename' in request.session
            and request.session['uploadObjectFilename'] is not None
            and 'uploadObjectContent' in request.session
            and request.session['uploadObjectContent'] is not None
            and 'uploadObjectType' in request.session
            and request.session['uploadObjectType'] is not None):
        object_content = request.session['uploadObjectContent']
        name = request.session['uploadObjectName']
        filename = request.session['uploadObjectFilename']
        object_type = request.session['uploadObjectType']

    # Load a parser able to clean the XML from blanks, comments and processing instructions
    clean_parser = etree.XMLParser(remove_blank_text=True,
                                   remove_comments=True,
                                   remove_pis=True)
    # set the parser
    etree.set_default_parser(parser=clean_parser)

    xsd_tree = etree.XML(str(object_content.encode('utf-8')))

    # replace includes/imports by API calls (get dependencies starting by the imports)
    update_dependencies(xsd_tree, dict(zip(schema_locations, dependencies)))

    # validate the schema
    error = validate_xml_schema(xsd_tree)

    if error is None:
        object_content = etree.tostring(xsd_tree)
        # create a new version
        if 'uploadVersion' in request.session and request.session[
                'uploadVersion'] is not None:
            object_versions_id = request.session['uploadVersion']
            if object_type == 'Template':
                new_template = create_template_version(object_content,
                                                       filename,
                                                       object_versions_id)
                redirect = '/admin/manage_versions?type={0}&id={1}'.format(
                    object_type, str(new_template.id))
            elif object_type == 'Type':
                new_type = create_type_version(object_content, filename,
                                               object_versions_id)
                redirect = '/admin/manage_versions?type={0}&id={1}'.format(
                    object_type, str(new_type.id))
        # create new object
        else:
            # save the object
            if object_type == "Template":
                create_template(object_content, name, filename, dependencies)
                redirect = '/admin/xml-schemas/manage-schemas'
            elif object_type == "Type":
                if 'uploadBuckets' in request.session and request.session[
                        'uploadBuckets'] is not None:
                    buckets = request.session['uploadBuckets']
                create_type(object_content, name, filename, buckets,
                            dependencies)
                redirect = '/admin/xml-schemas/manage-types'

        response_dict = {'redirect': redirect}
        messages.add_message(request, messages.INFO,
                             '{} uploaded with success.'.format(object_type))
        return HttpResponse(json.dumps(response_dict),
                            content_type='application/javascript')
    else:
        response_dict = {'errorDependencies': error.replace("'", "")}
        return HttpResponse(json.dumps(response_dict),
                            content_type='application/javascript')
def insert_element_sequence(request):
    try:
        type_id = request.POST['typeID']
        client_type_name = request.POST['typeName']
        xpath = request.POST['xpath']

        xml_tree_str = request.session['newXmlTemplateCompose']

        # build the dom tree of the schema being built
        xsd_tree = etree.parse(BytesIO(xml_tree_str.encode('utf-8')))
        # get namespaces information for the schema
        namespaces = get_namespaces(BytesIO(str(xml_tree_str)))
        default_prefix = get_default_prefix(namespaces)
        target_namespace, target_namespace_prefix = get_target_namespace(namespaces, xsd_tree)

        # get the type being included
        type_object = Type.objects().get(pk=type_id)
        type_xsd_tree = etree.parse(BytesIO(type_object.content.encode('utf-8')))
        # get namespaces information for the type
        type_namespaces = get_namespaces(BytesIO(str(type_object.content)))
        type_target_namespace, type_target_namespace_prefix = get_target_namespace(type_namespaces, type_xsd_tree)

        # get the type from the included/imported file
        # If there is a complex type
        element_type = type_xsd_tree.find("{}complexType".format(LXML_SCHEMA_NAMESPACE))
        if element_type is None:
            # If there is a simple type
            element_type = type_xsd_tree.find("{}simpleType".format(LXML_SCHEMA_NAMESPACE))
        type_name = element_type.attrib["name"]

        if type_target_namespace is not None:
            ns_type_name = "{0}:{1}".format(type_target_namespace_prefix, type_name)
        else:
            if target_namespace is not None:
                ns_type_name = "{0}:{1}".format(target_namespace_prefix, type_name)
            else:
                ns_type_name = '{}'.format(type_name)
        nsmap = {type_target_namespace_prefix: type_target_namespace}
        update_nsmap = False

        # build xpath to element
        xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE)

        # get link to the type to include
        include_url = getSchemaLocation(str(type_id))

        # Schema without target namespace
        if target_namespace is None:
            # Type without target namespace
            if type_target_namespace is None:
                # add include
                xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE),
                                          attrib={'schemaLocation': include_url}))
                # add element
                xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                                            attrib={'type': type_name,
                                                    'name': client_type_name}))
            # Type with target namespace
            else:
                # add import
                xsd_tree.getroot().insert(0, etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE),
                                          attrib={'schemaLocation': include_url,
                                                  'namespace': type_target_namespace}))
                # create the element to add
                element = etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                                        attrib={'name': client_type_name,
                                                'type': ns_type_name},
                                        )
                # add the element
                xsd_tree.find(xpath).append(element)

                update_nsmap = True

        # Schema with target namespace
        else:
            # Type without target namespace
            if type_target_namespace is None:
                # add include
                xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE),
                                          attrib={'schemaLocation': include_url}))
                # add element
                xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                                            attrib={'name': client_type_name,
                                                    'type': ns_type_name}))
            # Type with target namespace
            else:
                # Same target namespace as base template
                if target_namespace == type_target_namespace:
                    # add include
                    xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE),
                                              attrib={'schemaLocation': include_url}))
                    # add element
                    xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                                                attrib={'name': client_type_name,
                                                        'type': ns_type_name}))
                # Different target namespace as base template
                else:
                    # add import
                    xsd_tree.getroot().insert(0, etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE),
                                              attrib={'schemaLocation': include_url,
                                                      'namespace': type_target_namespace}))
                    # create the element to add
                    element = etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE),
                                            attrib={'name': client_type_name,
                                                    'type': ns_type_name},
                                            )
                    # add the element
                    xsd_tree.find(xpath).append(element)

                    update_nsmap = True

        # add the id of the type if not already present
        if include_url not in request.session['includedTypesCompose']:
            request.session['includedTypesCompose'].append(include_url)

        if update_nsmap:
            root = xsd_tree.getroot()
            root_nsmap = root.nsmap

            if type_target_namespace_prefix in root_nsmap.keys() and\
                            root_nsmap[type_target_namespace_prefix] != type_target_namespace:
                raise MDCSError('The namespace prefix is already declared for a different namespace.')
            else:
                root_nsmap[type_target_namespace_prefix] = type_target_namespace
                new_root = etree.Element(root.tag, nsmap=root_nsmap)
                new_root[:] = root[:]

                # validate XML schema
                error = validate_xml_schema(new_root)

                new_xsd_str = etree.tostring(new_root)

        else:
            # validate XML schema
            error = validate_xml_schema(xsd_tree)
            new_xsd_str = etree.tostring(xsd_tree)

        if error is not None:
            raise MDCSError(error)

        # save the tree in the session
        request.session['newXmlTemplateCompose'] = new_xsd_str
    except Exception, e:
        return HttpResponseBadRequest(e.message, content_type='application/javascript')
################################################################################
def save_template(request):
    template_name = request.POST['templateName']
    content = request.session['newXmlTemplateCompose']
    
    response_dict = {}

    # Validate XML document
    try:
        xml_tree = etree.parse(BytesIO(content.encode('utf-8')))
    except Exception, e:
        response_dict['errors'] = e.message.replace("'", "")
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')

    # validate the schema
    error = validate_xml_schema(xml_tree)

    if error is not None:
        response_dict['errors'] = 'This is not a valid XML schema.' + error.replace("'","")
        return HttpResponse(json.dumps(response_dict), content_type='application/javascript')

    dependencies = []

    for uri in request.session["includedTypesCompose"]:
        try:
            url = urlparse(uri)
            id = url.query.split("=")[1]
            # add dependency if it matches a type id
            Type.objects().get(pk=id)
            dependencies.append(id)
        except: