Пример #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 curate_edit_form(request):
    try:
        if request.method == 'GET':
            if 'id' in request.GET:
                form_data_id = request.GET['id']
                try:
                    form_data = FormData.objects.get(pk=ObjectId(form_data_id))
                except:
                    raise MDCSError("The form you are looking for doesn't exist.")

                # parameters to build FormData object in db
                request.session['currentTemplateID'] = form_data.template
                request.session['curate_edit'] = True
                request.session['curate_edit_data'] = form_data.xml_data

                # parameters that will be used during curation
                request.session['curateFormData'] = str(form_data.id)

                if 'formString' in request.session:
                    del request.session['formString']
                if 'xmlDocTree' in request.session:
                    del request.session['xmlDocTree']

                context = RequestContext(request, {})
                template = loader.get_template('curate/curate_enter_data.html')

                return HttpResponse(template.render(context))
            else:
                raise MDCSError("The form ID is missing.")
    except MDCSError, e:
        template = loader.get_template('curate/errors.html')
        context = RequestContext(request, {
            'errors': e.message,
        })
        return HttpResponse(template.render(context))
Пример #3
0
def curate_from_schema(request):
    try:
        schema_name = request.GET['template']
        templates = Template.objects(title=schema_name)

        # if the schemas are all versions of the same schema
        if len(set(templates.values_list('templateVersion'))) == 1:
            template_id = TemplateVersion.objects().get(
                pk=templates[0].templateVersion).current
            request.session['currentTemplateID'] = template_id

            form_data = FormData(user=str(request.user.id),
                                 template=template_id,
                                 name=schema_name)
            form_data.save()

            request.session['curateFormData'] = str(form_data.pk)
            request.session['curate_edit'] = False

            if 'xmlDocTree' in request.session:
                del request.session['xmlDocTree']
        else:
            error_message = "The selection of template by name can't be used if the MDCS contain more than one "
            error_message += "template with the same name."

            raise MDCSError(error_message)
    except:
        raise MDCSError("The template you are looking for doesn't exist.")
Пример #4
0
def curate_edit_form(request):
    try:
        if request.method == 'GET':
            if 'id' in request.GET:
                form_data_id = request.GET['id']
                try:
                    form_data = FormData.objects.get(pk=ObjectId(form_data_id))
                except:
                    raise MDCSError(
                        "The form you are looking for doesn't exist.")
                request.session['curate_edit'] = True
                # parameters that will be used during curation
                request.session['curateFormData'] = str(form_data.id)
                request.session['currentTemplateID'] = form_data.template
                templateObject = Template.objects.get(pk=form_data.template)
                xmlDocData = templateObject.content
                XMLtree = etree.parse(BytesIO(xmlDocData.encode('utf-8')))
                request.session['xmlDocTree'] = etree.tostring(XMLtree)

                if form_data.schema_element_root is not None:
                    delete_branch_from_db(form_data.schema_element_root.pk)
                    form_data.schema_element_root = None

                if form_data.template is not None:
                    template_object = Template.objects.get(
                        pk=form_data.template)
                    xsd_doc_data = template_object.content
                else:
                    raise MDCSError("No schema attached to this file")

                if form_data.xml_data is not None:
                    xml_doc_data = form_data.xml_data
                else:
                    xml_doc_data = None

                root_element_id = generate_form(request,
                                                xsd_doc_data,
                                                xml_doc_data,
                                                config=load_config())
                root_element = SchemaElement.objects.get(pk=root_element_id)

                form_data.update(set__schema_element_root=root_element)
                form_data.reload()

                request.session['form_id'] = str(
                    form_data.schema_element_root.id)

                context = RequestContext(request, {})
                template = loader.get_template('curate/curate_enter_data.html')

                return HttpResponse(template.render(context))
            else:
                raise MDCSError("The form ID is missing.")
    except MDCSError, e:
        template = loader.get_template('curate/errors.html')
        context = RequestContext(request, {
            'errors': e.message,
        })
        return HttpResponse(template.render(context))
Пример #5
0
def curate_edit_data(request):
    try:
        xml_data_id = request.GET['id']
        xml_data = XMLdata.get(xml_data_id)
        xml_content = xml_data['xml_file']
        request.session['curate_edit'] = True
        request.session['currentTemplateID'] = xml_data['schema']
        # remove previously created forms when editing a new one
        previous_forms = FormData.objects(user=str(request.user.id),
                                          xml_data_id__exists=True)

        for previous_form in previous_forms:
            if previous_form.schema_element_root is not None:
                delete_branch_from_db(previous_form.schema_element_root.pk)
            previous_form.delete()

        form_data = FormData(user=str(request.user.id),
                             template=xml_data['schema'],
                             name=xml_data['title'],
                             xml_data=xml_content,
                             xml_data_id=xml_data_id)
        form_data.save()

        request.session['curateFormData'] = str(form_data.pk)

        if 'form_id' in request.session:
            del request.session['form_id']
        if 'xmlDocTree' in request.session:
            del request.session['xmlDocTree']
    except:
        raise MDCSError("The document you are looking for doesn't exist.")
def curate_edit_data(request):
    try:
        if 'useForm' in request.GET and request.GET['useForm'] == 'true':
            pass
        else:
            xml_data_id = request.GET['id']
            xml_data = XMLdata.get(xml_data_id)
            json_content = xml_data['content']
            xml_content = xmltodict.unparse(json_content)
            request.session['curate_edit_data'] = xml_content
            request.session['curate_edit'] = True
            request.session['currentTemplateID'] = xml_data['schema']
            # remove previously created forms when editing a new one
            previous_forms = FormData.objects(user=str(request.user.id), xml_data_id__exists=True)
            for previous_form in previous_forms:
                # TODO: check if need to delete all SchemaElements
                previous_form.delete()
            form_data = FormData(
                user=str(request.user.id),
                template=xml_data['schema'],
                name=xml_data['title'],
                xml_data=xml_content,
                xml_data_id=xml_data_id
            )
            form_data.save()
            request.session['curateFormData'] = str(form_data.id)

            if 'form_id' in request.session:
                del request.session['form_id']
            if 'formString' in request.session:
                del request.session['formString']
            if 'xmlDocTree' in request.session:
                del request.session['xmlDocTree']
    except:
        raise MDCSError("The document you are looking for doesn't exist.")
Пример #7
0
def get_projection(document):
    """ Get the value returned by the projection

    :param document:
    :return:
    """
    if len(document) == 1:  # If only one key, _id (by default from mongo)
        return document['_id']
    elif len(document) == 2:  # If 2 keys, get the the one that is not _id
        keys = document.keys()
        for key in keys:
            if key != '_id':
                return get_projection_value(document[key])

    raise MDCSError('Unable to get a value for the projection.')
Пример #8
0
def curate_edit_data(request):
    try:
        if 'useForm' in request.GET and request.GET['useForm'] == 'true':
            pass
        else:
            xml_data_id = request.GET['id']
            request.session['curate_edit'] = True
            # remove previously created forms when editing a new one
            previous_forms = FormData.objects(user=str(request.user.id),
                                              xml_data_id__exists=True,
                                              isNewVersionOfRecord=False)
            for previous_form in previous_forms:
                if previous_form.schema_element_root is not None:
                    delete_branch_from_db(previous_form.schema_element_root.pk)
                previous_form.delete()

            #Check if a form_data already exists for this record
            form_data = FormData.objects(xml_data_id=xml_data_id).all().first()
            if not form_data:
                xml_data = XMLdata.get(xml_data_id)
                json_content = xml_data['content']
                xml_content = XMLdata.unparse(json_content)
                form_data = FormData(user=str(request.user.id),
                                     template=xml_data['schema'],
                                     name=xml_data['title'],
                                     xml_data=xml_content,
                                     xml_data_id=xml_data_id,
                                     isNewVersionOfRecord=xml_data.get(
                                         'ispublished', False))
                form_data.save()

            request.session['currentTemplateID'] = form_data.template
            request.session['curate_edit_data'] = form_data.xml_data
            request.session['curateFormData'] = str(form_data.pk)

            if 'form_id' in request.session:
                del request.session['form_id']
            if 'xmlDocTree' in request.session:
                del request.session['xmlDocTree']
    except:
        raise MDCSError("The document you are looking for doesn't exist.")
Пример #9
0
def curate_edit_data(request):
    try:
        xml_data_id = request.GET['id']
        xml_data = XMLdata.get(xml_data_id)
        json_content = xml_data['content']
        xml_content = xmltodict.unparse(json_content)
        request.session['curate_edit_data'] = xml_content
        request.session['curate_edit'] = True
        request.session['currentTemplateID'] = xml_data['schema']
        # remove previously created forms when editing a new one
        previous_forms = FormData.objects(user=str(request.user.id), xml_data_id__exists=True)
        for previous_form in previous_forms:
            # cascade delete references
            for form_element_id in previous_form.elements.values():
                try:
                    form_element = FormElement.objects().get(pk=form_element_id)
                    if form_element.xml_element is not None:
                        try:
                            xml_element = XMLElement.objects().get(pk=str(form_element.xml_element.id))
                            xml_element.delete()
                        except:
                            # raise an exception when element not found
                            pass
                    form_element.delete()
                except:
                    # raise an exception when element not found
                    pass
            previous_form.delete()
        form_data = FormData(user=str(request.user.id), template=xml_data['schema'], name=xml_data['title'], xml_data=xml_content, xml_data_id=xml_data_id).save()
        request.session['curateFormData'] = str(form_data.id)
        if 'formString' in request.session:
            del request.session['formString']
        if 'xmlDocTree' in request.session:
            del request.session['xmlDocTree']
    except:
        raise MDCSError("The document you are looking for doesn't exist.")
Пример #10
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')
Пример #11
0
def start_curate(request):
    if 'currentTemplateID' not in request.session and 'template' not in request.GET:
        return redirect('/curate/select-template')
    else:
        if request.method == 'POST':
            # parameters to build FormData object in db
            user = request.user.id
            template_id = request.session['currentTemplateID']

            form_data = None

            selected_option = request.POST['curate_form']
            if selected_option == "new":
                request.session['curate_edit'] = False
                new_form = NewForm(request.POST)
                try:
                    form_data = FormData(user=str(user),
                                         template=template_id,
                                         name=new_form.data['document_name'])
                    form_data.save()
                except:
                    return HttpResponseBadRequest(
                        'Unable to create the form. A form with the same name may already exist.'
                    )
            elif selected_option == "open":
                request.session['curate_edit'] = True
                open_form = OpenForm(request.POST)
                form_data = FormData.objects.get(
                    pk=ObjectId(open_form.data['forms']))
            elif selected_option == "upload":
                request.session['curate_edit'] = True
                upload_form = UploadForm(request.POST, request.FILES)
                xml_file = request.FILES['file']
                # put the cursor at the beginning of the file
                xml_file.seek(0)
                # read the content of the file
                xml_data = xml_file.read()
                # check XML data or not?
                try:
                    etree.fromstring(xml_data)
                except XMLSyntaxError:
                    return HttpResponseBadRequest(
                        'Uploaded File is not well formed XML.')
                try:
                    form_data = FormData(user=str(user),
                                         template=template_id,
                                         name=xml_file.name,
                                         xml_data=xml_data).save()
                except:
                    return HttpResponseBadRequest(
                        'Unable to create the form. A form with the same name may already exist.'
                    )

            # parameters that will be used during curation
            request.session['curateFormData'] = str(form_data.id)

            return HttpResponse('ok')
        else:
            try:
                ajaxCall = False
                context_params = dict()
                if 'template' in request.GET:
                    schema_name = request.GET['template']
                    context_params['template_name'] = schema_name
                    try:
                        templates = Template.objects(title=schema_name)
                    except:
                        raise MDCSError(
                            "The template you are looking for doesn't exist.")

                    # if the schemas are all versions of the same schema
                    if len(set(templates.values_list('templateVersion'))) == 1:
                        template_id = TemplateVersion.objects().get(
                            pk=templates[0].templateVersion).current
                        request.session['currentTemplateID'] = template_id
                    else:
                        raise MDCSError(
                            "The selection of template by name can't be used if the MDCS contain more than "
                            "one template with the same name.")

                    template = loader.get_template(
                        'curate/curate_full_start.html')

                    if 'xmlDocTree' in request.session:
                        del request.session['xmlDocTree']

                else:
                    ajaxCall = True
                    template = loader.get_template('curate/curate_start.html')

                open_form = OpenForm(forms=FormData.objects(
                    user=str(request.user.id),
                    template=request.session['currentTemplateID'],
                    xml_data_id__exists=False))
                new_form = NewForm()
                upload_form = UploadForm()

                context_params['new_form'] = new_form
                context_params['open_form'] = open_form
                context_params['upload_form'] = upload_form

                context = RequestContext(
                    request,
                    context_params)  # , 'options_form': options_form})

                if ajaxCall:
                    return HttpResponse(json.dumps(
                        {'template': template.render(context)}),
                                        content_type='application/javascript')
                else:
                    return HttpResponse(template.render(context))

            except MDCSError, e:
                template = loader.get_template('curate/errors.html')
                context = RequestContext(request, {
                    'errors': e.message,
                })
                return HttpResponse(template.render(context))
Пример #12
0
    def render_element(self, element):
        """

        :param element:
        :return:
        """
        xml_string = ''
        children = {}
        child_keys = []
        children_number = 0

        for child in element.children:
            if child.tag == 'elem-iter':
                children[child.pk] = child.children
                child_keys.append(child.pk)

                if len(child.children) > 0:
                    children_number += 1
            else:
                message = 'render_element (iteration): ' + child.tag + ' not handled'
                self.warnings.append(message)

        element_name = element.options['name']

        for child_key in child_keys:
            for child in children[child_key]:
                content = ['', '', '']

                # add XML Schema instance prefix if root
                if self.isRoot:
                    xsi = ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
                    content[0] += xsi
                    self.isRoot = False

                if child.tag == 'complex_type':
                    tmp_content = self.render_complex_type(child)
                    content[0] += tmp_content[0]
                    content[1] += tmp_content[1]
                    content[2] += tmp_content[2]
                elif child.tag == 'input':
                    tmp_content = child.value if child.value is not None else ''
                    content[1] += tmp_content
                elif child.tag == 'simple_type':
                    tmp_content = self.render_simple_type(child)
                    content[0] += tmp_content[0]
                    content[1] += tmp_content[1]
                    content[2] += tmp_content[2]
                elif child.tag == 'module':
                    tmp_content = self.render_module(child)

                    if child.options['multiple']:
                        content[2] += tmp_content[1]
                    else:
                        content[1] += tmp_content[1]
                else:
                    message = 'render_element: ' + child.tag + ' not handled'
                    self.warnings.append(message)

                # namespaces
                parent = get_parent_element(element)
                if parent is not None:
                    if 'xmlns' in element.options and element.options[
                            'xmlns'] is not None:
                        if 'xmlns' in parent.options and element.options[
                                'xmlns'] != parent.options['xmlns']:
                            xmlns = ' xmlns="{}"'.format(
                                element.options['xmlns'])
                            content[0] += xmlns
                else:
                    if 'xmlns' in element.options and element.options[
                            'xmlns'] is not None:
                        xmlns = ' xmlns="{}"'.format(element.options['xmlns'])
                        content[0] += xmlns

                # content[2] has the value returned by a module (the entire tag, when multiple is True)
                if content[2] != '':
                    if content[0] != '' or content[1] != '':
                        raise MDCSError(
                            'ERROR: More values than expected were returned (Module multiple).'
                        )
                    xml_string += content[2]
                else:
                    xml_string += self._render_xml(element_name, content[0],
                                                   content[1])

        return xml_string