Beispiel #1
0
    def __call__(self):
        fti = self.context
        result = {
            # '@context': 'http://www.w3.org/ns/hydra/context.jsonld',
            'title': fti.id,
            'type': 'object',
            '$schema': 'http://json-schema.org/draft-04/hyper-schema#',
            'fieldsets': [],
            'required': [],
            'schemas': {},
            'properties': {},
        }

        for schema in iterSchemataForType(fti.id):

            schema_serializer = getMultiAdapter((schema, fti, self.request),
                                                ISchemaSerializer)
            result['schemas'][schema_serializer.name] = schema_serializer()

            fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])
            fieldset_fields = set()
            for fieldset in fieldsets:
                fields = fieldset.fields
                # Keep a list so we can figure out what doesn't belong
                # to a fieldset
                fieldset_fields.update(fields)

                # Write the fieldset and any fields it contains
                fieldset_serializer = getMultiAdapter(
                    (fieldset, schema, fti, self.request), IFieldsetSerializer)
                result['fieldsets'].append({
                    'id': fieldset_serializer.name,
                    'title': fieldset_serializer.name,
                    'fields': fieldset_serializer()
                })

            # Handle any fields that aren't part of a fieldset
            non_fieldset_fields = [
                name for name, field in sortedFields(schema)
                if name not in fieldset_fields
            ]

            for fieldName in non_fieldset_fields:
                field = schema[fieldName]
                if field.required:
                    result['required'].append(fieldName)
                serializer = getMultiAdapter(
                    (field, schema, fti, self.request), IFieldSerializer)
                result['properties'][fieldName] = serializer()

            invariants = []
            for i in schema.queryTaggedValue('invariants', []):
                invariants.append("%s.%s" % (i.__module__, i.__name__))
            result['invariants'] = invariants

        if len(result['fieldsets']) == 0:
            del result['fieldsets']
        return result
Beispiel #2
0
def serialize(model):

    handlers = {}
    schema_metadata_handlers = tuple(getUtilitiesFor(ISchemaMetadataHandler))
    field_metadata_handlers = tuple(getUtilitiesFor(IFieldMetadataHandler))

    nsmap = {'i18n': I18N_NAMESPACE}
    for name, handler in schema_metadata_handlers + field_metadata_handlers:
        namespace, prefix = handler.namespace, handler.prefix
        if namespace is not None and prefix is not None:
            nsmap[prefix] = namespace

    xml = etree.Element('model', nsmap=nsmap)
    xml.set('xmlns', XML_NAMESPACE)

    def writeField(field, parentElement):
        name_extractor = IFieldNameExtractor(field)
        fieldType = name_extractor()
        handler = handlers.get(fieldType, None)
        if handler is None:
            handler = handlers[fieldType] = queryUtility(IFieldExportImportHandler, name=fieldType)
            if handler is None:
                raise ValueError("Field type %s specified for field %s is not supported" % (fieldType, fieldName))
        fieldElement = handler.write(field, fieldName, fieldType)
        if fieldElement is not None:
            parentElement.append(fieldElement)

            for handler_name, metadata_handler in field_metadata_handlers:
                metadata_handler.write(fieldElement, schema, field)

    for schemaName, schema in model.schemata.items():

        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        fieldset_fields = set()
        for fieldset in fieldsets:
            fieldset_fields.update(fieldset.fields)

        non_fieldset_fields = [name for name, field in sortedFields(schema)
                                if name not in fieldset_fields]

        schema_element = etree.Element('schema')
        if schemaName:
            schema_element.set('name', schemaName)

        bases = [b.__identifier__ for b in schema.__bases__ if b is not Schema]
        if bases:
            schema_element.set('based-on', ' '.join(bases))

        for invariant in schema.queryTaggedValue('invariants', []):
            invariant_element = etree.Element('invariant')
            invariant_element.text = "%s.%s" % (invariant.__module__, invariant.__name__)
            schema_element.append(invariant_element)

        for fieldName in non_fieldset_fields:
            field = schema[fieldName]
            writeField(field, schema_element)

        for fieldset in fieldsets:

            fieldset_element = etree.Element('fieldset')
            fieldset_element.set('name', fieldset.__name__)
            if fieldset.label:
                fieldset_element.set('label', fieldset.label)
            if fieldset.description:
                fieldset_element.set('description', fieldset.description)

            for fieldName in fieldset.fields:
                field = schema[fieldName]
                writeField(field, fieldset_element)

            schema_element.append(fieldset_element)

        for handler_name, metadata_handler in schema_metadata_handlers:
            metadata_handler.write(schema_element, schema)

        xml.append(schema_element)

    # handle i18n
    i18n_domain = xml.get(ns('domain', prefix=I18N_NAMESPACE))
    for node in xml.xpath('//*[@i18n:translate]', namespaces=nsmap):
        domain = node.get(ns('domain', prefix=I18N_NAMESPACE), i18n_domain)
        if i18n_domain is None:
            i18n_domain = domain
        if domain == i18n_domain:
            node.attrib.pop(ns('domain', prefix=I18N_NAMESPACE))
    if i18n_domain:
        xml.set(ns('domain', prefix=I18N_NAMESPACE), i18n_domain)

    return prettyXML(xml)
Beispiel #3
0
def serialize(model):

    handlers = {}
    schema_metadata_handlers = tuple(getUtilitiesFor(ISchemaMetadataHandler))
    field_metadata_handlers = tuple(getUtilitiesFor(IFieldMetadataHandler))

    nsmap = {'i18n': I18N_NAMESPACE}
    for name, handler in schema_metadata_handlers + field_metadata_handlers:
        namespace, prefix = handler.namespace, handler.prefix
        if namespace is not None and prefix is not None:
            nsmap[prefix] = namespace

    xml = etree.Element('model', nsmap=nsmap)
    xml.set('xmlns', XML_NAMESPACE)

    def writeField(field, parentElement):
        name_extractor = IFieldNameExtractor(field)
        fieldType = name_extractor()
        handler = handlers.get(fieldType, None)
        if handler is None:
            handler = handlers[fieldType] = queryUtility(
                IFieldExportImportHandler, name=fieldType)
            if handler is None:
                raise ValueError(
                    "Field type %s specified for field %s is not supported" %
                    (fieldType, fieldName))
        fieldElement = handler.write(field, fieldName, fieldType)
        if fieldElement is not None:
            parentElement.append(fieldElement)

            for handler_name, metadata_handler in field_metadata_handlers:
                metadata_handler.write(fieldElement, schema, field)

    for schemaName, schema in model.schemata.items():

        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        fieldset_fields = set()
        for fieldset in fieldsets:
            fieldset_fields.update(fieldset.fields)

        non_fieldset_fields = [
            name for name, field in sortedFields(schema)
            if name not in fieldset_fields
        ]

        schema_element = etree.Element('schema')
        if schemaName:
            schema_element.set('name', schemaName)

        bases = [b.__identifier__ for b in schema.__bases__ if b is not Schema]
        if bases:
            schema_element.set('based-on', ' '.join(bases))

        for invariant in schema.queryTaggedValue('invariants', []):
            invariant_element = etree.Element('invariant')
            invariant_element.text = "%s.%s" % (invariant.__module__,
                                                invariant.__name__)
            schema_element.append(invariant_element)

        for fieldName in non_fieldset_fields:
            field = schema[fieldName]
            writeField(field, schema_element)

        for fieldset in fieldsets:

            fieldset_element = etree.Element('fieldset')
            fieldset_element.set('name', fieldset.__name__)
            if fieldset.label:
                fieldset_element.set('label', fieldset.label)
            if fieldset.description:
                fieldset_element.set('description', fieldset.description)

            for fieldName in fieldset.fields:
                field = schema[fieldName]
                writeField(field, fieldset_element)

            schema_element.append(fieldset_element)

        for handler_name, metadata_handler in schema_metadata_handlers:
            metadata_handler.write(schema_element, schema)

        xml.append(schema_element)

    # handle i18n
    i18n_domain = xml.get(ns('domain', prefix=I18N_NAMESPACE))
    for node in xml.xpath('//*[@i18n:translate]', namespaces=nsmap):
        domain = node.get(ns('domain', prefix=I18N_NAMESPACE), i18n_domain)
        if i18n_domain is None:
            i18n_domain = domain
        if domain == i18n_domain:
            node.attrib.pop(ns('domain', prefix=I18N_NAMESPACE))
    if i18n_domain:
        xml.set(ns('domain', prefix=I18N_NAMESPACE), i18n_domain)

    return prettyXML(xml)
Beispiel #4
0
def serialize(model):

    handlers = {}
    schema_metadata_handlers = tuple(getUtilitiesFor(ISchemaMetadataHandler))
    field_metadata_handlers = tuple(getUtilitiesFor(IFieldMetadataHandler))

    xml = ElementTree.Element('model')
    xml.set('xmlns', XML_NAMESPACE)

    # Let utilities indicate which namespace they prefer.

    # XXX: This is manipulating a global - it's probably safe, though,
    # since we only add new items, and only add them if they don't conflict

    used_prefixes = set(ElementTree._namespace_map.values())
    for name, handler in schema_metadata_handlers + field_metadata_handlers:
        namespace, prefix = handler.namespace, handler.prefix
        if namespace is not None and prefix is not None \
                and prefix not in used_prefixes and namespace not in ElementTree._namespace_map:
            used_prefixes.add(prefix)
            ElementTree._namespace_map[namespace] = prefix

    def writeField(field, parentElement):
        name_extractor = IFieldNameExtractor(field)
        fieldType = name_extractor()
        handler = handlers.get(fieldType, None)
        if handler is None:
            handler = handlers[fieldType] = queryUtility(
                IFieldExportImportHandler, name=fieldType)
            if handler is None:
                raise ValueError(
                    "Field type %s specified for field %s is not supported" %
                    (fieldType, fieldName))
        fieldElement = handler.write(field, fieldName, fieldType)
        if fieldElement is not None:
            parentElement.append(fieldElement)

            for handler_name, metadata_handler in field_metadata_handlers:
                metadata_handler.write(fieldElement, schema, field)

    for schemaName, schema in model.schemata.items():

        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        fieldset_fields = set()
        for fieldset in fieldsets:
            fieldset_fields.update(fieldset.fields)

        non_fieldset_fields = [
            name for name, field in sortedFields(schema)
            if name not in fieldset_fields
        ]

        schema_element = ElementTree.Element('schema')
        if schemaName:
            schema_element.set('name', schemaName)

        bases = [b.__identifier__ for b in schema.__bases__]
        if bases:
            schema_element.set('based-on', ' '.join(bases))

        for fieldName in non_fieldset_fields:
            field = schema[fieldName]
            writeField(field, schema_element)

        for fieldset in fieldsets:

            fieldset_element = ElementTree.Element('fieldset')
            fieldset_element.set('name', fieldset.__name__)
            if fieldset.label:
                fieldset_element.set('label', fieldset.label)
            if fieldset.description:
                fieldset_element.set('description', fieldset.description)

            for fieldName in fieldset.fields:
                field = schema[fieldName]
                writeField(field, fieldset_element)

            schema_element.append(fieldset_element)

        for handler_name, metadata_handler in schema_metadata_handlers:
            metadata_handler.write(schema_element, schema)

        xml.append(schema_element)

    return prettyXML(xml)
Beispiel #5
0
 def field_ids(self):
     return [n for n, s in sortedFields(self.schema)]
def serialize(model):

    handlers = {}
    schema_metadata_handlers = tuple(getUtilitiesFor(ISchemaMetadataHandler))
    field_metadata_handlers = tuple(getUtilitiesFor(IFieldMetadataHandler))

    xml = ElementTree.Element('model')
    xml.set('xmlns', XML_NAMESPACE)

    # Let utilities indicate which namespace they prefer.

    # XXX: This is manipulating a global - it's probably safe, though,
    # since we only add new items, and only add them if they don't conflict

    used_prefixes = set(ElementTree._namespace_map.values())
    for name, handler in schema_metadata_handlers + field_metadata_handlers:
        namespace, prefix = handler.namespace, handler.prefix
        if namespace is not None and prefix is not None \
                and prefix not in used_prefixes and namespace not in ElementTree._namespace_map:
            used_prefixes.add(prefix)
            ElementTree._namespace_map[namespace] = prefix

    def writeField(field, parentElement):
        name_extractor = IFieldNameExtractor(field)
        fieldType = name_extractor()
        handler = handlers.get(fieldType, None)
        if handler is None:
            handler = handlers[fieldType] = queryUtility(IFieldExportImportHandler, name=fieldType)
            if handler is None:
                raise ValueError("Field type %s specified for field %s is not supported" % (fieldType, fieldName))
        fieldElement = handler.write(field, fieldName, fieldType)
        if fieldElement is not None:
            parentElement.append(fieldElement)

            for handler_name, metadata_handler in field_metadata_handlers:
                metadata_handler.write(fieldElement, schema, field)

    for schemaName, schema in model.schemata.items():

        fieldsets = schema.queryTaggedValue(FIELDSETS_KEY, [])

        fieldset_fields = set()
        for fieldset in fieldsets:
            fieldset_fields.update(fieldset.fields)

        non_fieldset_fields = [name for name, field in sortedFields(schema)
                                if name not in fieldset_fields]

        schema_element = ElementTree.Element('schema')
        if schemaName:
            schema_element.set('name', schemaName)

        bases = [b.__identifier__ for b in schema.__bases__]
        if bases:
            schema_element.set('based-on', ' '.join(bases))

        for fieldName in non_fieldset_fields:
            field = schema[fieldName]
            writeField(field, schema_element)

        for fieldset in fieldsets:

            fieldset_element = ElementTree.Element('fieldset')
            fieldset_element.set('name', fieldset.__name__)
            if fieldset.label:
                fieldset_element.set('label', fieldset.label)
            if fieldset.description:
                fieldset_element.set('description', fieldset.description)

            for fieldName in fieldset.fields:
                field = schema[fieldName]
                writeField(field, fieldset_element)

            schema_element.append(fieldset_element)

        for handler_name, metadata_handler in schema_metadata_handlers:
            metadata_handler.write(schema_element, schema)

        xml.append(schema_element)

    return prettyXML(xml)
Beispiel #7
0
 def field_ids(self):
     return [n for n, s in sortedFields(self.schema)]