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))
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.")
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))
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.")
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.')
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.")
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.")
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')
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))
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