示例#1
0
    def test_import_field_ref(self):
        xml = """\
<registry>
    <record name="test.registry.field.override">
        <field ref="test.registry.field" />
        <value>Another value</value>
    </record>
</registry>
"""
        context = DummyImportContext(self.site, purge=False)
        context._files = {'registry.xml': xml}

        self.registry.records['test.registry.field'] = Record(
                field.TextLine(title=u"Simple record", default=u"N/A"),
                value=u"Sample value")

        importRegistry(context)

        self.assertEqual(2, len(self.registry.records))
        self.assertTrue(
            IFieldRef.providedBy(
                self.registry.records['test.registry.field.override'].field)
            )
        self.assertEqual(
            u"Simple record",
            self.registry.records['test.registry.field.override'].field.title
        )
        self.assertEqual(
            u"value",
            self.registry.records['test.registry.field.override'].field.__name__  # noqa
        )
        self.assertEqual(
            u"Another value",
            self.registry['test.registry.field.override']
        )
示例#2
0
文件: handler.py 项目: CGTIC/Plone_SP
    def exportRecord(self, record):

        node = etree.Element('record')
        node.attrib['name'] = record.__name__

        if IInterfaceAwareRecord.providedBy(record):
            node.attrib['interface'] = record.interfaceName
            node.attrib['field'] = record.fieldName

        # write field

        field = record.field
        if IFieldRef.providedBy(field):
            field_element = etree.Element('field')
            field_element.attrib['ref'] = field.recordName
            node.append(field_element)
        else:
            field_type = IFieldNameExtractor(record.field)()
            handler = queryUtility(IFieldExportImportHandler, name=field_type)
            if handler is None:
                self.logger.warning("Field type %s specified for record %s \
                    cannot be exported" % (field_type, record.__name__))
            else:
                field_element = handler.write(record.field, None, field_type, elementName='field')
                node.append(field_element)

        # write value

        value_element = valueToElement(record.field, record.value, name='value', force=True)
        node.append(value_element)

        return node
示例#3
0
    def test_fieldref_interfaces(self):
        from plone.registry import field, FieldRef
        from plone.registry.interfaces import IFieldRef
        from zope.schema.interfaces import ICollection

        listField = field.List(value_type=field.ASCIILine())
        ref = FieldRef('some.record', listField)

        self.assertTrue(ICollection.providedBy(ref))
        self.assertTrue(IFieldRef.providedBy(ref))
示例#4
0
    def test_fieldref_interfaces(self):
        from plone.registry import field, FieldRef
        from plone.registry.interfaces import IFieldRef
        from zope.schema.interfaces import ICollection

        listField = field.List(value_type=field.ASCIILine())
        ref = FieldRef('some.record', listField)

        self.assertTrue(ICollection.providedBy(ref))
        self.assertTrue(IFieldRef.providedBy(ref))
示例#5
0
 def _setField(self, name, field):
     if not IPersistentField.providedBy(field):
         raise ValueError("The record's field must be an IPersistentField.")
     if IFieldRef.providedBy(field):
         if field.recordName not in self._fields:
             raise ValueError("Field reference points to non-existent record")
         self._fields[name] = field.recordName # a pointer, of sorts
     else:
         field.__name__ = 'value'
         self._fields[name] = field
示例#6
0
 def _setField(self, name, field):
     if not IPersistentField.providedBy(field):
         raise ValueError("The record's field must be an IPersistentField.")
     if IFieldRef.providedBy(field):
         if field.recordName not in self._fields:
             raise ValueError("Field reference points to non-existent record")
         self._fields[name] = field.recordName # a pointer, of sorts
     else:
         field.__name__ = 'value'
         self._fields[name] = field
示例#7
0
    def exportRecord(self, record):

        node = etree.Element('record')
        node.attrib['name'] = record.__name__

        if IInterfaceAwareRecord.providedBy(record):
            node.attrib['interface'] = record.interfaceName
            node.attrib['field'] = record.fieldName

        # write field

        field = record.field
        if IFieldRef.providedBy(field):
            field_element = etree.Element('field')
            field_element.attrib['ref'] = field.recordName
            node.append(field_element)
        else:
            field_type = IFieldNameExtractor(record.field)()
            handler = queryUtility(IFieldExportImportHandler, name=field_type)
            if handler is None:
                self.logger.warning(
                    'Field type {0} specified for record {1} '
                    'cannot be exported'.format(field_type, record.__name__)
                )
            else:
                field_element = handler.write(
                    record.field,
                    None,
                    field_type,
                    elementName='field'
                )
                node.append(field_element)

        # write value
        value_element = valueToElement(
            record.field,
            record.value,
            name='value',
            force=True
        )
        node.append(value_element)

        return node
示例#8
0
    def importRecord(self, node):
        name = node.get('name', '')
        if node.get('delete') is not None:
            self.logger.warning(
                u"The 'delete' attribute of <record /> nodes is deprecated, "
                u"it should be replaced with 'remove'."
            )
        remove = node.get('remove', node.get('delete', 'false'))
        interfaceName = node.get('interface', None)
        fieldName = node.get('field', None)

        if not name and (interfaceName and fieldName):
            prefix = node.get('prefix', None)
            if prefix is None:
                prefix = interfaceName

            name = "%s.%s" % (prefix, fieldName)

        if not name:
            raise NameError("No name given for <record /> node!")

        # Unicode is not supported
        name = str(name)
        __traceback_info__ = 'record name: {0}'.format(name)

        # Handle deletion and quit
        if remove.lower() == 'true':
            if name in self.context.records:
                del self.context.records[name]
                self.logger.info("Removed record %s." % name)
            else:
                self.logger.warning(
                    "Record {0} was marked for deletion, but was not "
                    "found.".format(name)
                )
            return

        # See if we have an existing record
        existing_record = self.context.records.get(name, None)

        interface = None
        field = None
        value = _marker
        value_purge = True

        # If we are given an interface and field name, try to resolve them
        if interfaceName and fieldName:
            try:
                interface = resolve(interfaceName)
                field = IPersistentField(interface[fieldName])
            except ImportError:
                self.logger.warning(
                    'Failed to import interface {0} for '
                    'record {1}'.format(interfaceName, name)
                )
                interface = None
                field = None
            except KeyError:
                self.logger.warning(
                    'Interface {0} specified for record %s has '
                    'no field {1}.'.format(interfaceName, name, fieldName)
                )
                interface = None
                field = None
            except TypeError:
                self.logger.warning(
                    "Field {0} in interface {1} specified for record {2} "
                    "cannot be used as a persistent field.".format(
                        fieldName,
                        interfaceName,
                        name
                    )
                )
                interface = None
                field = None

        # Find field and value nodes

        field_node = None
        value_node = None

        for child in node:
            if not isinstance(child.tag, str):
                continue
            elif child.tag.lower() == 'field':
                field_node = child
            elif child.tag.lower() == 'value':
                value_node = child

        # Let field not potentially override interface[fieldName]
        if field_node is not None:
            field_ref = field_node.attrib.get('ref', None)
            if field_ref is not None:
                # We have a field reference
                if field_ref not in self.context:
                    raise KeyError(
                        u'Record {0} references field for record {1}, '
                        u'which does not exist'.format(name, field_ref)
                    )
                ref_record = self.context.records[field_ref]
                field = FieldRef(field_ref, ref_record.field)
            else:
                # We have a standard field
                field_type = field_node.attrib.get('type', None)
                field_type_handler = queryUtility(
                    IFieldExportImportHandler,
                    name=field_type
                )
                if field_type_handler is None:
                    raise TypeError(
                        "Field of type {0} used for record {1} is not "
                        "supported.".format(field_type, name)
                    )
                else:
                    field = field_type_handler.read(field_node)
                    if not IPersistentField.providedBy(field):
                        raise TypeError(
                            "Only persistent fields may be imported. {0} used "
                            "for record {1} is invalid.".format(
                                field_type,
                                name
                            )
                        )

        if field is not None and not IFieldRef.providedBy(field):
            # Set interface name and fieldName, if applicable
            field.interfaceName = interfaceName
            field.fieldName = fieldName

        # Fall back to existing record if neither a field node nor the
        # interface yielded a field

        change_field = True

        if field is None and existing_record is not None:
            change_field = False
            field = existing_record.field

        if field is None:
            raise ValueError(
                "Cannot find a field for the record {0}. Add a <field /> "
                "element or reference an interface and field name.".format(
                    name
                )
            )

        # Extract the value

        if value_node is not None:
            value_purge = value_node.attrib.get('purge', '').lower() != 'false'
            value = elementToValue(field, value_node, default=_marker)

        # Now either construct or update the record

        if value is _marker:
            value = field.default
            value_purge = True

        if existing_record is not None:
            if change_field:
                existing_record.field = field
            existing_value = existing_record.value
            if change_field or value != existing_value:

                if not value_purge and type(value) == type(existing_value):
                    if isinstance(value, list):
                        value = (
                            existing_value +
                            [v for v in value if v not in existing_value]
                        )
                    elif isinstance(value, tuple):
                        value = (
                            existing_value +
                            tuple(
                                [v for v in value if v not in existing_value]
                            )
                        )
                    elif isinstance(value, (set, frozenset, )):
                        value = existing_value.union(value)
                    elif isinstance(value, dict):
                        for key, value in value.items():
                            # check if value is list, if so, let's add
                            # instead of overridding
                            if (
                                type(value) == list and
                                key in existing_value and
                                not shouldPurgeList(value_node, key)
                            ):
                                existing = existing_value[key]
                                for item in existing:
                                    # here, we'll remove existing items
                                    # point is that we don't want
                                    # duplicates and don't want to reorder
                                    if item in value:
                                        value.remove(item)
                                existing.extend(value)
                                value = existing
                            existing_value[key] = value
                        value = existing_value

                existing_record.value = value
        else:
            self.context.records[name] = Record(field, value)
示例#9
0
    def importRecord(self, node):
        name = node.get('name', '')
        if node.get('delete') is not None:
            self.logger.warning(u"The 'delete' attribute of <record /> nodes "
                                u"is deprecated, it should be replaced with "
                                u"'remove'.")
        remove = node.get('remove', node.get('delete', 'false'))

        interfaceName = node.get('interface', None)
        fieldName = node.get('field', None)

        if not name and (interfaceName and fieldName):
            prefix = node.get('prefix', None)
            if prefix is None:
                prefix = interfaceName

            name = "%s.%s" % (prefix, fieldName)

        if not name:
            raise NameError("No name given for <record /> node!")

        # Unicode is not supported
        name = str(name)

        # Handle deletion and quit
        if remove.lower() == 'true':
            if name in self.context.records:
                del self.context.records[name]
                self.logger.info("Removed record %s." % name)
            else:
                self.logger.warning(
                    "Record %s was marked for deletion, but was not found." %
                    name)
            return

        # See if we have an existing record
        existing_record = self.context.records.get(name, None)

        interface = None
        field = None
        value = _marker
        value_purge = True

        # If we are given an interface and field name, try to resolve them
        if interfaceName and fieldName:
            try:
                interface = resolve(interfaceName)
                field = IPersistentField(interface[fieldName])
            except ImportError:
                self.logger.warning("Failed to import interface %s for \
                    record %s" % (interfaceName, name))
                interface = None
                field = None
            except KeyError:
                self.logger.warning("Interface %s specified for record %s has \
                    no field %s." % (interfaceName, name, fieldName))
                interface = None
                field = None
            except TypeError:
                self.logger.warning("Field %s in interface %s specified for \
                    record %s cannot be used as a persistent field." %
                                    (fieldName, interfaceName, name))
                interface = None
                field = None

        # Find field and value nodes

        field_node = None
        value_node = None

        for child in node:
            if not isinstance(child.tag, str):
                continue
            elif child.tag.lower() == 'field':
                field_node = child
            elif child.tag.lower() == 'value':
                value_node = child

        # Let field not potentially override interface[fieldName]
        if field_node is not None:
            field_ref = field_node.attrib.get('ref', None)
            if field_ref is not None:
                # We have a field reference
                if field_ref not in self.context:
                    raise KeyError(
                        u"Record %s references field for record %s, \
                        which does not exist" % (name, field_ref))
                ref_record = self.context.records[field_ref]
                field = FieldRef(field_ref, ref_record.field)
            else:
                # We have a standard field
                field_type = field_node.attrib.get('type', None)
                field_type_handler = queryUtility(IFieldExportImportHandler,
                                                  name=field_type)
                if field_type_handler is None:
                    raise TypeError(
                        "Field of type %s used for record %s is not supported."
                        % (field_type, name))
                else:
                    field = field_type_handler.read(field_node)
                    if not IPersistentField.providedBy(field):
                        raise TypeError(
                            "Only persistent fields may be imported. \
                            %s used for record %s is invalid." %
                            (field_type, name))

        if field is not None and not IFieldRef.providedBy(field):

            # Set interface name and fieldName, if applicable
            field.interfaceName = interfaceName
            field.fieldName = fieldName

        # Fall back to existing record if neither a field node nor the
        # interface yielded a field

        change_field = True

        if field is None and existing_record is not None:
            change_field = False
            field = existing_record.field

        if field is None:
            raise ValueError("Cannot find a field for the record %s. Add a \
                <field /> element or reference an interface and field name." %
                             name)

        # Extract the value

        if value_node is not None:
            value_purge = value_node.attrib.get('purge', '').lower() != 'false'
            value = elementToValue(field, value_node, default=_marker)

        # Now either construct or update the record

        if value is _marker:
            value = field.default
            value_purge = True

        if existing_record is not None:
            if change_field:
                existing_record.field = field
            existing_value = existing_record.value
            if change_field or value != existing_value:

                if not value_purge and type(value) == type(existing_value):
                    if isinstance(value, list):
                        value = existing_value + [
                            v for v in value if v not in existing_value
                        ]
                    elif isinstance(value, tuple):
                        value = existing_value + tuple(
                            [v for v in value if v not in existing_value])
                    elif isinstance(value, (
                            set,
                            frozenset,
                    )):
                        value = existing_value.union(value)
                    elif isinstance(value, dict):
                        for key, value in value.items():
                            # check if value is list, if so, let's add
                            # instead of overridding
                            if type(value) == list:
                                if key in existing_value and \
                                        not shouldPurgeList(value_node, key):
                                    existing = existing_value[key]
                                    for item in existing:
                                        # here, we'll remove existing items
                                        # point is that we don't want duplicates
                                        # and don't want to reorder
                                        if item in value:
                                            value.remove(item)
                                    existing.extend(value)
                                    value = existing
                            existing_value[key] = value

                        value = existing_value

                existing_record.value = value
        else:
            self.context.records[name] = Record(field, value)
示例#10
0
    def importRecord(self, node):
        
        name = node.get('name', '')
        delete = node.get('delete', 'false')
        
        interfaceName = node.get('interface', None)
        fieldName = node.get('field', None)

        if not name and (interfaceName and fieldName):
            prefix = node.get('prefix', None)
            if prefix is None:
                prefix = interfaceName
            
            name = "%s.%s" % (prefix, fieldName,)
        
        if not name:
            raise NameError("No name given for <record /> node!")
        
        # Unicode is not supported
        name = str(name)
        
        # Handle deletion and quit
        if delete.lower() == 'true':
            if name in self.context.records:
                del self.context.records[name]
                self.logger.info("Deleted record %s." % name)
            else:
                self.logger.warning("Record %s was marked for deletion, but was not found." % name)
            return
        
        # See if we have an existing record
        existing_record = self.context.records.get(name, None)
        
        interface = None
        field = None
        value = _marker
        value_purge = True
        
        # If we are given an interface and field name, try to resolve them
        if interfaceName and fieldName:
            try:
                interface = resolve(interfaceName)
                field = IPersistentField(interface[fieldName])
            except ImportError:
                self.logger.warning("Failed to import interface %s for record %s" % (interfaceName, name))
                interface = None
                field = None
            except KeyError:
                self.logger.warning("Interface %s specified for record %s has no field %s." % (interfaceName, name, fieldName,))
                interface = None
                field = None
            except TypeError:
                self.logger.warning("Field %s in interface %s specified for record %s cannot be used as a persistent field." % (fieldName, interfaceName, name,))            
                interface = None
                field = None
        
        # Find field and value nodes
        
        field_node = None
        value_node = None
         
        for child in node:
            if child.tag.lower() == 'field':
                field_node = child
            elif child.tag.lower() == 'value':
                value_node = child
        
        # Let field not potentially override interface[fieldName]
        if field_node is not None:
            field_ref = field_node.attrib.get('ref', None)
            if field_ref is not None:
                # We have a field reference
                if field_ref not in self.context:
                    raise KeyError(u"Record %s references field for record %s, which does not exist" % (name, field_ref,))
                ref_record = self.context.records[field_ref]
                field = FieldRef(field_ref, ref_record.field)
            else:
                # We have a standard field
                field_type = field_node.attrib.get('type', None)
                field_type_handler = queryUtility(IFieldExportImportHandler, name=field_type)
                if field_type_handler is None:
                    raise TypeError("Field of type %s used for record %s is not supported." % (field_type, name,))
                else:
                    field = field_type_handler.read(field_node)
                    if not IPersistentField.providedBy(field):
                        raise TypeError("Only persistent fields may be imported. %s used for record %s is invalid." % (field_type, name,))
        
        if field is not None and not IFieldRef.providedBy(field):
            
            # Set interface name and fieldName, if applicable
            field.interfaceName = interfaceName
            field.fieldName = fieldName
        
        # Fall back to existing record if neither a field node nor the
        # interface yielded a field
        
        change_field = True
        
        if field is None and existing_record is not None:
            change_field = False
            field = existing_record.field
        
        if field is None:
            raise ValueError("Cannot find a field for the record %s. Add a <field /> element or reference an interface and field name." % name)
        
        # Extract the value

        if value_node is not None:
            value_purge = value_node.attrib.get('purge', '').lower() != 'false'
            value = elementToValue(field, value_node, default=_marker)

        # Now either construct or update the record
        
        if value is _marker:
            value = field.default
            value_purge = True
        
        if existing_record is not None:
            if change_field:
                existing_record.field = field
            existing_value = existing_record.value
            if change_field or value != existing_value:
                
                if not value_purge and type(value) == type(existing_value):
                    if isinstance(value, list):
                        value = existing_value + [v for v in value if v not in existing_value]
                    elif isinstance(value, tuple):
                        value = existing_value + tuple([v for v in value if v not in existing_value])
                    elif isinstance(value, (set, frozenset,)):
                        value = existing_value.union(value)
                    elif isinstance(value, dict):
                        existing_value.update(value)
                        value = existing_value
                
                existing_record.value = value
        else:
            self.context.records[name] = Record(field, value)