Back to index

plone3  3.1.7
meta.py
Go to the documentation of this file.
00001 from wicked.fieldevent import render, store
00002 from zope.interface import Interface, implementer
00003 from zope.interface import noLongerProvides, alsoProvides
00004 from zope.component import adapter
00005 from zope.component.interface import provideInterface
00006 from wicked.fieldevent.interfaces import IFieldValue
00007 from wicked.fieldevent.interfaces import IFieldValueSetter
00008 import itertools
00009 import zope.component.zcml
00010 from zope.configuration import fields
00011 import zope.interface
00012 import zope.schema
00013 import wicked.fieldevent
00014 from zope.component import provideAdapter, provideHandler
00015 from zope.component import provideSubscriptionAdapter
00016 
00017 
00018 class NewLineTokens(fields.Tokens):
00019     """ token field that splits on newline not space """
00020     
00021     def fromUnicode(self, u):
00022         u = u.strip()
00023         if u:
00024             vt = self.value_type.bind(self.context)
00025             values = []
00026             for s in u.split('\\n'):
00027                 try:
00028                     v = vt.fromUnicode(s)
00029                 except zope.schema.ValidationError, v:
00030                     raise fields.InvalidToken("%s in %s" % (v, u))
00031                 else:
00032                     values.append(v)
00033         else:
00034             values = []
00035 
00036         self.validate(values)
00037         return values
00038 
00039 
00040 class IATFieldDecoratorDirective(Interface):
00041     fieldclass = fields.GlobalObject(
00042         title=u"Field Class",
00043         required=True
00044         )
00045 
00046 class IATSchemaFieldsImplementDirective(Interface):
00047     atclass = fields.GlobalObject(
00048         title=u"Archetypes Schema Object",
00049         required=True
00050         )
00051 
00052     implements = fields.GlobalObject(
00053         title=u"Archetypes Schema Object",
00054         required=True
00055         )
00056 
00057     fields = NewLineTokens(
00058         title=u"Names of fields to be marked",
00059         description=u"""
00060         Each field enumerated here will now directly provide the
00061         interfaces in implements.
00062         """,
00063         required=True,
00064         value_type=zope.schema.TextLine(missing_value=str()))
00065     
00066 
00067 def decorate_at_field(_context=None, fieldclass=None, zcml=True):
00068     if not fieldclass in _fieldclass_monkies:
00069 
00070         # register adapters to call original methods
00071 
00072         _get=fieldclass.get
00073         _set=fieldclass.set    
00074         
00075         @implementer(IFieldValue)
00076         @adapter(fieldclass, wicked.fieldevent.IFieldRenderEvent)
00077         def field_value(field, event):
00078             return _get(field, event.instance, **event.kwargs)
00079 
00080         @implementer(IFieldValueSetter)
00081         @adapter(fieldclass, wicked.fieldevent.IFieldStorageEvent)
00082         def field_value_set(field, event):
00083             _set(field, event.instance, event.value, **event.kwargs)
00084 
00085         if zcml:
00086             # do proper zopeish config
00087             zope.component.zcml.adapter(_context, (field_value,))
00088             zope.component.zcml.subscriber(_context,
00089                                            factory=field_value_set,
00090                                            provides=IFieldValueSetter)
00091             _context.action(
00092                 discriminator = (fieldclass, monkey_getset),
00093                 callable = monkey_getset,
00094                 args = (fieldclass,)
00095                 )
00096         else:
00097             # hook it up no delay
00098             monkey_getset(fieldclass)
00099             provideAdapter(field_value)
00100             provideSubscriptionAdapter(field_value_set)
00101 
00102 
00103 _fieldclass_monkies=[]
00104 def monkey_getset(fieldclass):
00105     global _fieldclass_monkies
00106     _get=fieldclass.get
00107     _set=fieldclass.set    
00108     fieldclass.set = store
00109     fieldclass.get = render
00110     fieldclass.__original_get=_get
00111     fieldclass.__original_set=_set
00112     _fieldclass_monkies.append(fieldclass)
00113 
00114 
00115 def schemafields_implement(_context=None, atclass=None, implements=None, fields=[], zcml=True):
00116     if zcml:
00117         _context.action(
00118             discriminator = None,
00119             callable = provideInterface,
00120             args = ('', implements)
00121             )
00122     schemafields_provide(implements, atclass.schema, fields)        
00123 
00124 
00125 _schemafields_marked=[]
00126 def schemafields_provide(implements, schema, fieldnames, cleanup=False):
00127     action = noLongerProvides
00128     if not cleanup:
00129         global _schemafields_marked
00130         if (implements, schema, fieldnames) in _schemafields_marked:
00131             return
00132         _schemafields_marked.append((implements, schema, fieldnames))
00133         action = alsoProvides
00134 
00135     for name in fieldnames:
00136         field=schema[name]
00137         try:
00138             action(field, implements)
00139         except ValueError:
00140             pass
00141 
00142 
00143 def cleanup_schemafields_provide():
00144     global _schemafields_marked
00145     for implements, schema, fieldnames in _schemafields_marked:
00146         schemafields_provide(implements, schema, fieldnames, cleanup=True)
00147     _schemafields_marked=[]
00148 
00149 
00150 def cleanup_decorate_at_field():
00151     # unmonkey!
00152     global _fieldclass_monkies 
00153     for class_ in _fieldclass_monkies:
00154         class_.get = class_.__original_get
00155         class_.set = class_.__original_set
00156     _fieldclass_monkies = []
00157 
00158 
00159 def cleanUp():
00160     cleanup_decorate_at_field()
00161     cleanup_schemafields_provide()    
00162 
00163 
00164 from zope.testing.cleanup import addCleanUp
00165 addCleanUp(cleanUp)
00166 del addCleanUp
00167 
00168 
00169 def test_suite():
00170     import unittest
00171     from zope.testing import doctest
00172     from zope.testing.cleanup import cleanUp
00173 
00174     def setUp(tc):
00175         # clean slate!
00176         cleanUp()
00177         provideHandler(wicked.fieldevent.notifyFieldEvent)
00178 
00179     def tearDown(tc):
00180         cleanUp()
00181 
00182     globs=globals()
00183     globs.update(locals())
00184     
00185     optflags = doctest.REPORT_ONLY_FIRST_FAILURE | doctest.ELLIPSIS
00186     meta = doctest.DocFileTest("meta.txt",
00187                              package="wicked.fieldevent",
00188                              globs=globs,
00189                              setUp=setUp,
00190                              tearDown=tearDown,
00191                              optionflags=optflags)
00192     
00193     return unittest.TestSuite((meta,))