Back to index

plone3  3.1.7
primaryfield.py
Go to the documentation of this file.
00001 # Copyright (c) 2002-2006, Benjamin Saller <bcsaller@ideasuite.com>, and 
00002 #                      the respective authors.
00003 # All rights reserved.
00004 #
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are
00007 # met:
00008 # 
00009 #     * Redistributions of source code must retain the above copyright
00010 #       notice, this list of conditions and the following disclaimer. 
00011 #     * Redistributions in binary form must reproduce the above
00012 #       copyright notice, this list of conditions and the following disclaimer
00013 #       in the documentation and/or other materials provided with the
00014 #       distribution. 
00015 #     * Neither the name of Archetypes nor the names of its contributors
00016 #       may be used to endorse or promote products derived from this software
00017 #       without specific prior written permission. 
00018 # 
00019 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00031 
00032 import re
00033 from types import ListType, TupleType
00034 from cStringIO import StringIO
00035 from rfc822 import Message
00036 
00037 from AccessControl import ClassSecurityInfo
00038 from Acquisition import aq_base
00039 from Globals import InitializeClass
00040 from OFS.Image import File
00041 from Products.Archetypes.Field import TextField, FileField
00042 from Products.Archetypes.interfaces.marshall import IMarshall
00043 from Products.Archetypes.interfaces.layer import ILayer
00044 from Products.Archetypes.interfaces.base import IBaseUnit
00045 from Products.Archetypes.debug import log
00046 from Products.Archetypes.utils import shasattr
00047 from Products.Archetypes.utils import mapply
00048 
00049 try:
00050     from zope.contenttype import guess_content_type
00051 except ImportError: # BBB: Zope < 2.10
00052     try:
00053         from zope.app.content_types import guess_content_type
00054     except ImportError: # BBB: Zope < 2.9
00055         from OFS.content_types import guess_content_type
00056 
00057 from base import Marshaller
00058 
00059 class PrimaryFieldMarshaller(Marshaller):
00060 
00061     security = ClassSecurityInfo()
00062     security.declareObjectPrivate()
00063     security.setDefaultAccess('deny')
00064 
00065     def demarshall(self, instance, data, file=None, **kwargs):
00066         p = instance.getPrimaryField()
00067         # XXX Hardcoding field types is bad. :(
00068         if isinstance(p, (FileField, TextField)) and file:
00069             data = file
00070         mutator = p.getMutator(instance)
00071         mutator(data, **kwargs)
00072 
00073     def marshall(self, instance, **kwargs):
00074         p = instance.getPrimaryField()
00075         if not p:
00076             raise TypeError, 'Primary Field could not be found.'
00077         data = p and instance[p.getName()] or ''
00078         content_type = length = None
00079         # Gather/Guess content type
00080         if IBaseUnit.isImplementedBy(data):
00081             content_type = data.getContentType()
00082             length = data.get_size()
00083             data   = data.getRaw()
00084         elif isinstance(data, File):
00085             content_type = data.content_type
00086             length = data.get_size()
00087             data = data.data
00088         else:
00089             log('WARNING: PrimaryFieldMarshaller(%r): '
00090                 'field %r does not return a IBaseUnit '
00091                 'instance.' % (instance, p.getName()))
00092             if hasattr(p, 'getContentType'):
00093                 content_type = p.getContentType(instance) or 'text/plain'
00094             else:
00095                 content_type = (data and guess_content_type(data)
00096                                 or 'text/plain')
00097 
00098             # DM 2004-12-01: "FileField"s represent a major field class
00099             #  that does not use "IBaseUnit" yet.
00100             #  Ensure, the used "File" objects get the correct length.
00101             if hasattr(p, 'get_size'):
00102                 length = p.get_size(instance)
00103             else:
00104                 # DM: this almost surely is stupid!
00105                 length = len(data)
00106 
00107             # ObjectField without IBaseUnit?
00108             if shasattr(data, 'data'):
00109                 data = data.data
00110             else:
00111                 data = str(data)
00112                 # DM 2004-12-01: recompute 'length' as we now know it
00113                 # definitely
00114                 length = len(data)
00115 
00116         return (content_type, length, data)
00117 
00118 InitializeClass(PrimaryFieldMarshaller)