def i18n_persistent_field_adapter(context): """Special handling for I18NField fields.""" if IPersistentField.providedBy(context): return context ignored = list(DisallowedProperty.uses + StubbornProperty.uses) constrained = list(InterfaceConstrainedProperty.uses) instance = I18NFieldPersistent.__new__(I18NFieldPersistent) context_dict = dict([ (k, v) for k, v in context.__dict__.items() if k not in ignored ]) for k, iface in constrained: v = context_dict.get(k, None) if v is not None and v != context.missing_value: v = iface(v, None) if v is None: __traceback_info__ = TRACE.format(k, iface.__identifier__) return None context_dict[k] = v instance.__dict__.update(context_dict) return instance
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
def __init__(self, field, value=_marker, _validate=True): if _validate and not IPersistentField.providedBy(field): raise ValueError("Field is not persistent") if value is _marker: value = field.default else: if _validate: if value != field.missing_value: bound_field = field.bind(self) bound_field.validate(value) # Bypass event notification and setting on the parent self._field = field self._value = value if field.interfaceName: alsoProvides(self, IInterfaceAwareRecord)
def persistentFieldAdapter(context): """Turn a non-persistent field into a persistent one """ if IPersistentField.providedBy(context): return context # See if we have an equivalently-named field class_name = context.__class__.__name__ persistent_class = getattr(plone.registry.field, class_name, None) if persistent_class is None: return None if not issubclass(persistent_class, context.__class__): __traceback_info__ = "Can only clone a field of an equivalent type." return None ignored = list(DisallowedProperty.uses + StubbornProperty.uses) constrained = list(InterfaceConstrainedProperty.uses) instance = persistent_class.__new__(persistent_class) context_dict = dict([(k, v) for k, v in context.__dict__.items() if k not in ignored]) for key, iface in constrained: value = context_dict.get(key, None) if value is None or value == context.missing_value: continue value = iface(value, None) if value is None: __traceback_info__ = ("The property `{0}` cannot be adapted to " "`{1}`.".format( key, iface.__identifier__, )) return None context_dict[key] = value instance.__dict__.update(context_dict) return instance
def persistentFieldAdapter(context): """Turn a non-persistent field into a persistent one """ if IPersistentField.providedBy(context): return context # See if we have an equivalently-named field class_name = context.__class__.__name__ persistent_class = getattr(plone.registry.field, class_name, None) if persistent_class is None: return None if not issubclass(persistent_class, context.__class__): __traceback_info__ = "Can only clone a field of an equivalent type." return None ignored = list(DisallowedProperty.uses + StubbornProperty.uses) constrained = list(InterfaceConstrainedProperty.uses) instance = persistent_class.__new__(persistent_class) context_dict = dict( [(k, v) for k, v in context.__dict__.items() if k not in ignored] ) for key, iface in constrained: value = context_dict.get(key, None) if value is None or value == context.missing_value: continue value = iface(value, None) if value is None: __traceback_info__ = ( "The property `{0}` cannot be adapted to " "`{1}`.".format(key, iface.__identifier__,) ) return None context_dict[key] = value instance.__dict__.update(context_dict) return instance
def i18n_persistent_field_adapter(context): """Special handling for I18NField fields.""" if IPersistentField.providedBy(context): return context ignored = list(DisallowedProperty.uses + StubbornProperty.uses) constrained = list(InterfaceConstrainedProperty.uses) instance = I18NFieldPersistent.__new__(I18NFieldPersistent) context_dict = dict([(k, v) for k, v in context.__dict__.items() if k not in ignored]) for k, iface in constrained: v = context_dict.get(k, None) if v is not None and v != context.missing_value: v = iface(v, None) if v is None: __traceback_info__ = TRACE.format(k, iface.__identifier__) return None context_dict[k] = v instance.__dict__.update(context_dict) return instance
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)
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)
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)