Back to index

plone3  3.1.7
IModifier.py
Go to the documentation of this file.
00001 #########################################################################
00002 # Copyright (c) 2004, 2005 Alberto Berti, Gregoire Weber,
00003 # Reflab(Vincenzo Di Somma, Francesco Ciriaci, Riccardo Lemmi),
00004 # Duncan Booth.
00005 #
00006 # All Rights Reserved.
00007 #
00008 # This file is part of CMFEditions.
00009 #
00010 # CMFEditions is free software; you can redistribute it and/or modify
00011 # it under the terms of the GNU General Public License as published by
00012 # the Free Software Foundation; either version 2 of the License, or
00013 # (at your option) any later version.
00014 #
00015 # CMFEditions is distributed in the hope that it will be useful,
00016 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 # GNU General Public License for more details.
00019 #
00020 # You should have received a copy of the GNU General Public License
00021 # along with CMFEditions; if not, write to the Free Software
00022 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00023 #########################################################################
00024 """Intercepts/modifies saving/retrieving of versions to/from the repository.
00025 
00026 $Id: IModifier.py,v 1.7 2005/06/24 11:42:01 gregweb Exp $
00027 """
00028 
00029 from Interface import Interface
00030 
00031 class IAttributeModifier(Interface):
00032     """The simplest possible modifier, it indicates, which attributes
00033        shouldn't be copied by the archivist, but be passed to the the storage
00034        by reference.
00035 
00036     """
00037 
00038     def getReferencedAttributes(obj):
00039         """Returns attributes which should be passe dto the storage by reference.
00040         
00041         Returns a dict of the format ``name:attribute``. 
00042         """
00043 
00044     def reattachReferencedAttributes(obj, attrs_dict):
00045         """Giving an obj and and an attribute dict composed by
00046            attribute names and values, reattach them to the obj.
00047         """
00048 
00049 class ICloneModifier(Interface):
00050     """Modifies an object on save to or retrieval from a repository storage.
00051 
00052     A modifier knows how to manipulate an object being under version control
00053     on save to and on retrieval from the repositories storage.
00054 
00055     """
00056 
00057     def getOnCloneModifiers(obj):
00058         """Returns modifier callbacks being called during clone.
00059 
00060         Use this to manipulate objects during cloning to avoid excessive
00061         recursing of the clone operator eating much CPU and RAM.
00062 
00063         Returns a tuple consisting of a pickle peristent_id callback,
00064         a pickle persistent_load callback, two lists of 'IAttributeAdapter'
00065         objects adapting to a referenced object (inside references and
00066         outside references) and a name. The name may be an empty string.
00067 
00068         Returns just 'None' if no modifier callbacks have to be called.
00069 
00070         XXX Argh, this description is shit!
00071         """
00072 
00073 
00074 
00075 class ISaveRetrieveModifier(Interface):
00076     """Modifies an object on save to or retrieval from a repository storage.
00077 
00078     A modifier knows how to manipulate an object being under version control
00079     on save to and on retrieval from the repositories storage.
00080 
00081     """
00082 
00083     def beforeSaveModifier(obj, obj_clone):
00084         """Modifies the object before being saved to the repos storage.
00085 
00086         Preprocesses the objects clone before it gets saved to
00087         the repositories storage. The copy is an unwrapped deep copy
00088         of the original object ('obj').
00089 
00090         Usually this hook is used to do one or more of the following
00091         tasks:
00092 
00093             - manipulate data before it get versioned
00094             - remove data that should not be versioned (or aren't
00095               versionable at all) and wasn't removed already by the
00096               'getOnCloneModifiers'.
00097 
00098         Returns a dict with metadata to be added to the sys_metadata dict
00099         and two lists of 'IAttributeAdapter' objects adapting to a
00100         'IVersionAwareReference' objects (inside references and outside
00101         references).
00102 
00103         XXX Argh, this description is shit!
00104         """
00105 
00106     def afterRetrieveModifier(obj, repo_clone, preserve=()):
00107         """Modifies the object after being retrieved from the repos storage.
00108 
00109         Postprocesses the copy of an objects version after it has been
00110         retrieved from the repositories storage. The repository copy is a
00111         reference to an unwrapped deep copy of a version previously
00112         saved to the repositories storage.
00113 
00114         Usually this hook is used to do one or more of the following
00115         tasks:
00116 
00117             - readd data that was removed by the 'beforeSaveHook'
00118             - manipulate data before it get restored
00119             - return data that gets overwritte in this process
00120 
00121         It does kind of the inverse of the method ``beforeSaveModifier``.
00122 
00123         'obj' may be None. This signifies there is no working copy object.
00124 
00125         Returns:
00126         
00127         - a list of references to be deleted on revert (providing
00128           ``IReferenceAdapter``) 
00129         - a list of attribute names beeing in charge of holding reference
00130           information (e.g. an ObjectManager with ``doc1`` and ``doc2`` 
00131           as childrens: ['_objects', 'doc1', 'doc2'])
00132         - a dictionary of the data having been preserved from beeing 
00133           overwritten.
00134         """
00135 
00136 class IReferenceAdapter(Interface):
00137     """Adapts to a references.
00138     
00139     Currently used to be able to remove a reference without having to
00140     know how.
00141     """
00142     
00143     def remove():
00144         """Removes the refrence adapted to.
00145         """
00146 
00147 
00148 class IModifierRegistrySet(Interface):
00149     """Registring and editing a modifier registry.
00150     """
00151 
00152     def register(id, modifier, pos=-1):
00153         """Registers a before save and after retrieve modifier.
00154 
00155         If no 'pos' argument is passed the modifier gets added at the
00156         end of the registry.
00157         """
00158 
00159     def unregister(id):
00160         """Unregisters a before save and after retrieve modifier.
00161 
00162         Unregistering can be done by passing the method the id or
00163         the position.
00164         """
00165 
00166     def edit(id, enabled=None, condition=None):
00167         """Edits a before save and after retrieve modifier.
00168         
00169         None values leave the respective parameter unchanged.
00170         
00171         The respective modifier only gets called if it is enabled and
00172         the 'condition' evaluates to a True value.
00173         """
00174     
00175     
00176 class IModifierRegistryQuery(Interface):
00177     """Querying a modifier registry.
00178     """
00179 
00180     def get(id):
00181         """Returns the conditional modifier with the given id.
00182            
00183         Returns a 'IConditionalModifier' object.
00184         
00185         Raises an exception if the item doesn't exist.
00186         """
00187     
00188     def query(id, default=None):
00189         """Returns the condition and the modifier with the given id.
00190            
00191         Returns the default value if the item does not exist..
00192         """
00193     
00194     
00195 class IConditionalModifier(Interface):
00196     """A modifier with a condition.
00197     
00198     The modifiers get only called if it is enabled and if a possibly 
00199     existing implicit condition evaluates to a true value.
00200     """
00201     
00202     def __init__(id, modifier, title=''):
00203         """Initialize with a modifier.
00204         
00205         The conditional modifier is disabled by default.
00206         """
00207         
00208     def edit(enabled=None):
00209         """Modifies an existing conditional modifier.
00210         
00211         None values leave the respective parameter unchanged.
00212         """
00213         
00214     def isApplicable(obj, portal=None):
00215         """Returns True if the modifier is applicable.
00216         
00217         A modifier is applicable if it is enabled and if an additional
00218         condition evaluates to a true value.
00219         """
00220         
00221     def isEnabled():
00222         """Returns the enable status.
00223         """
00224         
00225     def getModifier():
00226         """Returns the modifier.
00227         """
00228     
00229     
00230 class IConditionalTalesModifier(IConditionalModifier):
00231     """A modifier with a condition.
00232     
00233     The modifiers get only called if it is enabled and if the TALES
00234     condition evaluates to a true value.
00235     """
00236     
00237     def edit(enabled=None, condition=None):
00238         """Modifies an existing conditional TALES modifier.
00239         
00240         'condition' is a TALES expression.
00241         
00242         None values leave the respective parameter unchanged.
00243         """
00244         
00245     def getTalesCondition():
00246         """Returns the TALES expression.
00247         """
00248     
00249     
00250 # not yet implemented stuff, subject to change
00251 class IBulkEditableModifierRegistry(Interface):
00252     """A extension of a modifier registry that allows bulk editing.
00253     
00254     Used for management screens.
00255     """
00256     
00257     def listModifiers():
00258         """Returns the subscribers in string format for use in forms.
00259         
00260         Returns a list of dictionaries with the following keys:
00261         
00262             id -- the id of the subscriber
00263             pos -- the position of the subscriber in the hsitory
00264             before_save -- a string representation of the "before save 
00265                            subscriber"
00266             after_retrieve -- a string representation of the "after
00267                               retrieve subscriber"
00268             on_clone -- a string representation of the "on clone" 
00269                         modifier.
00270             editable -- A flag signalizing if the subscribers are 
00271                         editable
00272         """
00273     
00274     def setModifiers(ids, pos, before_save, after_retrieve, on_clone):
00275         """Replaces all the subscribers passed
00276         
00277         Use this to set all subscribers at once from a form.
00278         """
00279 
00280 class ModifierException(Exception):
00281     """A base class for exceptions thrown by modifiers which wish to abort
00282     a save operation"""
00283     pass
00284 
00285 class FileTooLargeToVersionError(ModifierException):
00286     """A simple exception indicating that an object contained a file
00287     object that was too large to support versioning, and that versioning
00288     will be aborted as a result"""
00289     pass