Back to index

plone3  3.1.7
dcns.py
Go to the documentation of this file.
00001 ##################################################################
00002 # Marshall: A framework for pluggable marshalling policies
00003 # Copyright (C) 2004 EnfoldSystems, LLC
00004 # Copyright (C) 2004 ObjectRealms, LLC
00005 #
00006 # This program is free software; you can redistribute it and/or modify
00007 # it under the terms of the GNU General Public License as published by
00008 # the Free Software Foundation; either version 2 of the License, or
00009 # (at your option) any later version.
00010 #
00011 # This program is distributed in the hope that it will be useful,
00012 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 # GNU General Public License for more details.
00015 #
00016 # You should have received a copy of the GNU General Public License
00017 # along with this program; if not, write to the Free Software
00018 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ##################################################################
00020 
00021 """
00022 $Id: $
00023 """
00024 
00025 from Products.CMFCore.utils import getToolByName
00026 from Products.Marshall.handlers.atxml import XmlNamespace
00027 from Products.Marshall.handlers.atxml import SchemaAttribute
00028 
00029 RNGSchemaFragment = '''
00030   <define name="DublinCore"
00031           xmlns:dc="http://purl.org/dc/elements/1.1/"
00032           datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
00033           xmlns="http://relaxng.org/ns/structure/1.0">
00034     <choice>
00035       <zeroOrMore>
00036         <element name="dc:title"><text /></element>
00037       </zeroOrMore>
00038       <zeroOrMore>
00039         <element name="dc:description"><text /></element>
00040       </zeroOrMore>
00041       <zeroOrMore>
00042         <element name="dc:subject"><text /></element>
00043       </zeroOrMore>
00044       <zeroOrMore>
00045         <element name="dc:contributor"><data type="NMTOKEN" /></element>
00046       </zeroOrMore>
00047       <oneOrMore>
00048         <element name="dc:creator"><data type="NMTOKEN" /></element>
00049       </oneOrMore>
00050       <zeroOrMore>
00051         <element name="dc:language"><data type="language" /></element>
00052       </zeroOrMore>
00053       <zeroOrMore>
00054         <element name="dc:rights"><text /></element>
00055       </zeroOrMore>
00056     </choice>
00057   </define>
00058 '''
00059 
00060 class DCAttribute(SchemaAttribute):
00061 
00062     def __init__(self,
00063                  name,
00064                  accessor,
00065                  mutator,
00066                  many=False,
00067                  process=()):
00068 
00069         super(DCAttribute, self).__init__(name)
00070 
00071         self.accessor = accessor
00072         self.mutator = mutator
00073         self.many = many
00074         self.process = process
00075 
00076     def get(self, instance):
00077         accessor = getattr( instance, self.accessor)
00078         value = accessor()
00079 
00080         if not value:
00081             return None
00082         elif not isinstance( value, (list, tuple) ):
00083             values = [value]
00084         elif self.many:
00085             values = value
00086         else:
00087             raise AssertionError("Many values on single value attr")
00088         
00089         return filter(None, values)
00090 
00091     def deserialize(self, instance, ns_data):
00092         
00093         value = ns_data.get( self.name )
00094 
00095         if not self.mutator or not value:
00096             return
00097         
00098         if self.process:
00099             for p in self.process:
00100                 value = p( value )
00101 
00102         mutator = getattr( instance, self.mutator )
00103         mutator( value )
00104 
00105     def serialize(self, dom, parent_node, instance):
00106         values = self.get( instance )
00107         if not values:
00108             return False
00109             
00110         for value in values:
00111             elname = "%s:%s"%(self.namespace.prefix, self.name)
00112             node = dom.createElementNS( DublinCore.xmlns, elname)
00113             value_node = dom.createTextNode( str( value ) )
00114             node.appendChild( value_node )
00115             node.normalize()
00116             parent_node.appendChild( node )
00117         return True
00118 
00119     def processXmlValue(self, context, value):
00120         value = value and value.strip()
00121         if not value:
00122             return
00123         data = context.getDataFor( self.namespace.xmlns )
00124         
00125         if self.many:
00126             data.setdefault(self.name, []).append( value )
00127         else:
00128             data[self.name]=value
00129             
00130 class normalizer(object):
00131     """ utility function ns """
00132 
00133     def space( text ):
00134         return '\n'.join([s.strip() for s in text.splitlines()])
00135     space = staticmethod(space)
00136 
00137     def newline( text ):
00138         return ' '.join([s.strip() for s in text.splitlines()])
00139     newline = staticmethod(newline)
00140 
00141 
00142 class DublinCore(XmlNamespace):
00143 
00144     xmlns = 'http://purl.org/dc/elements/1.1/'
00145     prefix = 'dc'
00146 
00147     uses_at_fields = True
00148     
00149     attributes = (
00150         DCAttribute('title', 'Title', 'setTitle',
00151                     process=(normalizer.space, normalizer.newline)),
00152         
00153         DCAttribute('description', 'Description', 'setDescription',
00154                     process=(normalizer.space,)),
00155 
00156         DCAttribute('subject', 'Subject', 'setSubject', many=True),                
00157         DCAttribute('contributor', 'Contributors', 'setContributors',
00158                     many=True),
00159         # this attr diverges from cmfdefault.dublincore
00160         DCAttribute('creator', 'Creators', 'setCreators', many=True),
00161         DCAttribute('rights', 'Rights', 'setRights'),
00162         DCAttribute('language', 'Language', 'setLanguage')
00163         )
00164     
00165 
00166     def getATFields(self):
00167         return ('title',
00168                 'description',
00169                 'contributors',
00170                 'subject',
00171                 'creators',
00172                 'rights',
00173                 'language')
00174 
00175     def getSchemaInfo(self):
00176         return [ ("DublinCore", "zeroOrMore", RNGSchemaFragment) ]