diff --git a/composer/schema/configure.zcml b/composer/schema/configure.zcml index 4ad9e4c..4b5b04e 100644 --- a/composer/schema/configure.zcml +++ b/composer/schema/configure.zcml @@ -10,4 +10,6 @@ + + diff --git a/composer/schema/field.py b/composer/schema/field.py index be1dc56..4c07eff 100644 --- a/composer/schema/field.py +++ b/composer/schema/field.py @@ -23,9 +23,10 @@ $Id$ """ from zope.interface import implements +from zope.component import adapts from cybertools.composer.base import Component -from cybertools.composer.schema.interfaces import IField, IFieldState +from cybertools.composer.schema.interfaces import IField, IFieldInstance from cybertools.composer.schema.schema import formErrors from cybertools.util.format import toStr, toUnicode @@ -53,6 +54,19 @@ class Field(Component): def getTitleValue(self): return self.title or self.name + +class FieldInstance(object): + + implements(IFieldInstance) + adapts(IField) + + def __init__(self, context): + self.context = context + self.name = self.__name__ = context.name + self.errors = [] + self.severity = 0 + self.change = None + def marshall(self, value): return value #return toStr(value) @@ -64,23 +78,11 @@ class Field(Component): def unmarshall(self, strValue): return toUnicode(strValue) or u'' - def validateValue(self, value): + def validate(self, value): errors = [] severity = 0 - if not value and self.required: + if not value and self.context.required: error = formErrors['required_missing'] - errors.append(error) - severity = error.severity - return FieldState(self.name, errors, severity) - - -class FieldState(object): - - implements(IFieldState) - - def __init__(self, name, errors=[], severity=0, change=None): - self.name = self.__name__ = name - self.errors = errors - self.severity = severity - self.change = change + self.errors.append(error) + self.severity = error.severity diff --git a/composer/schema/instance.py b/composer/schema/instance.py index 0079b26..c6b876c 100644 --- a/composer/schema/instance.py +++ b/composer/schema/instance.py @@ -28,7 +28,7 @@ from zope.interface import implements from cybertools.composer.instance import Instance from cybertools.composer.interfaces import IInstance -from cybertools.composer.schema.interfaces import IClient +from cybertools.composer.schema.interfaces import IClient, IFieldInstance from cybertools.composer.schema.schema import FormState @@ -75,9 +75,10 @@ class ClientInstance(object): values = attrs.setdefault(self.aspect, {}) if template is not None: for f in template.fields: + fi = IFieldInstance(f) name = f.name value = values.get(name, u'') - value = mode == 'view' and f.display(value) or f.marshall(value) + value = mode == 'view' and fi.display(value) or fi.marshall(value) result[name] = value result['__name__'] = self.context.__name__ return result @@ -103,23 +104,25 @@ class ClientInstanceEditor(ClientInstance): setattr(self.context, self.attrsName, attrs) values = attrs.setdefault(self.aspect, OOBTree()) for f in template.fields: + #fi = IFieldInstance(f) name = f.name - fieldState = formState.fieldStates[name] - value = f.unmarshall(data.get(name)) + fi = formState.fieldInstances[name] + value = fi.unmarshall(data.get(name)) if name in data: oldValue = values.get(name) if value != oldValue: values[name] = value - fieldState.change = (oldValue, value) + fi.change = (oldValue, value) formState.changed = True return formState def validate(self, data): formState = FormState() for f in self.template.fields: - value = f.unmarshall(data.get(f.name)) - fieldState = f.validateValue(value) - formState.fieldStates.append(fieldState) - formState.severity = max(formState.severity, fieldState.severity) + fi = IFieldInstance(f) + value = fi.unmarshall(data.get(f.name)) + fi.validate(value) + formState.fieldInstances.append(fi) + formState.severity = max(formState.severity, fi.severity) return formState diff --git a/composer/schema/interfaces.py b/composer/schema/interfaces.py index d709de6..e8a58c2 100644 --- a/composer/schema/interfaces.py +++ b/composer/schema/interfaces.py @@ -99,32 +99,12 @@ class IField(IComponent): '(only for type textarea)'), default=3, required=False,) - # validator = schema.Text(), - # marshaller = schema.Text(), - - def marshallValue(value): - """ Return a string (possibly unicode) representation of the - value given that may be used for editing. - """ - - def displayValue(value): - """ Return a string (possibly unicode) representation of the - value given that may be used for presentation. - """ - - def unmarshallValue(strValue): - """ Return the internal (real) value corresponding to the string - value given. - """ - - def validateValue(value): - """ Check if the value given is valid. Return an object implementing - IFieldState. - """ -class IFieldState(Interface): - """ Represents the state of a field used for editing. +class IFieldInstance(Interface): + """ An adapter for checking and converting data values coming + from or being displayed on an external system (like a browser form). + It also keeps information on the processing state. """ name = Attribute('Field name.') @@ -133,15 +113,35 @@ class IFieldState(Interface): severity = Attribute("An integer giving a state or error " "code, 0 meaning 'OK'.") + def marshall(value): + """ Return a string (possibly unicode) representation of the + value given that may be used for editing. + """ + + def display(value): + """ Return a string (possibly unicode) representation of the + value given that may be used for presentation. + """ + + def unmarshall(strValue): + """ Return the internal (real) value corresponding to the string + value given. + """ + + def validate(value): + """ Check if the value given is valid. Return an object implementing + IFieldState. + """ + class IFormState(Interface): """ Represents the state of all fields when editing. """ fieldStates = Attribute('A mapping ``{fieldName: fieldState, ...}``.') - changed = Attribute('True if one of the fields has been changed or False.') + changed = Attribute('True if one of the fields has been changed') severity = Attribute("An integer giving an overall state or error " - "code, typically the maximum of the field states' " + "code, typically the maximum of the field instances' " "severities.") diff --git a/composer/schema/schema.py b/composer/schema/schema.py index 216492e..c75230b 100644 --- a/composer/schema/schema.py +++ b/composer/schema/schema.py @@ -64,8 +64,8 @@ class FormState(object): implements(IFormState) - def __init__(self, fieldStates=[], changed=False, severity=0): - self.fieldStates = Jeep(fieldStates) + def __init__(self, fieldInstances=[], changed=False, severity=0): + self.fieldInstances = Jeep(fieldInstances) self.changed = changed self.severity = severity