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
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)
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)
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)
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)