dteventhandlers.py :  » Web-Server » Porcupine-Web-Application-Server » porcupine-0.6-src » porcupine » core » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Server » Porcupine Web Application Server 
Porcupine Web Application Server » porcupine 0.6 src » porcupine » core » dteventhandlers.py
#===============================================================================
#    Copyright 2005-2009, Tassos Koutsovassilis
#
#    This file is part of Porcupine.
#    Porcupine is free software; you can redistribute it and/or modify
#    it under the terms of the GNU Lesser General Public License as published by
#    the Free Software Foundation; either version 2.1 of the License, or
#    (at your option) any later version.
#    Porcupine is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.
#    You should have received a copy of the GNU Lesser General Public License
#    along with Porcupine; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#===============================================================================
"Porcupine server built-in datatypes event handlers"
import os

from porcupine import db
from porcupine import exceptions
from porcupine.utils import misc

class DatatypeEventHandler(object):
    @staticmethod
    def on_create(item, attr):
        pass

    @staticmethod
    def on_update(item, new_attr, old_attr):
        pass
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        pass
    
    @staticmethod
    def on_undelete(item, attr):
        pass

class CompositionEventHandler(DatatypeEventHandler):
    "Composition datatype event handler"
    
    @staticmethod
    def on_create(item, attr):
        CompositionEventHandler.on_update(item, attr, None)
    
    @staticmethod
    def on_update(item, new_attr, old_attr):
        from porcupine.systemObjects import Composite
        # load objects
        dctObjects = {}
        for i, obj in enumerate(new_attr.value):
            if isinstance(obj, Composite):
                obj._containerid = item._id
            elif isinstance(obj, str):
                obj = db._db.get_item(obj)
                new_attr.value[i] = obj
            else:
                raise exceptions.ContainmentError, \
                    'Invalid object type "%s" in composition.' % \
                    obj.__class__.__name__
            dctObjects[obj._id] = obj
        
        # check containment
        composite_type = misc.get_rto_by_name(new_attr.compositeClass)
        
        if [obj for obj in dctObjects.values()
                if not isinstance(obj, composite_type)]:
            raise exceptions.ContainmentError, \
                'Invalid content class "%s" in composition.' % \
                obj.get_contentclass()
        
        # get previous value
        if old_attr != None:
            old_ids = set(old_attr.value)
        else:
            old_ids = set()
        
        new_ids = set([obj._id for obj in new_attr.value])
        
        # calculate added composites
        lstAdded = list(new_ids - old_ids)
        for obj_id in lstAdded:
            db._db.handle_update(dctObjects[obj_id], None)
            db._db.put_item(dctObjects[obj_id])
        
        # calculate constant composites
        lstConstant = list(new_ids & old_ids)
        for obj_id in lstConstant:
            db._db.handle_update(dctObjects[obj_id], db._db.get_item(obj_id))
            db._db.put_item(dctObjects[obj_id])
        
        # calculate removed composites
        lstRemoved = list(old_ids - new_ids)
        [CompositionEventHandler._removeComposite(db._db.get_item(id))
         for id in lstRemoved]
        
        new_attr.value = list(new_ids)
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        if bPermanent:
            [CompositionEventHandler._removeComposite(db._db.get_item(id))
             for id in attr.value]
        else:
            for sID in attr.value:
                composite = db._db.get_item(sID)
                db._db.handle_delete(composite, False)
                composite._isDeleted = 1
                db._db.put_item(composite)
    
    @staticmethod
    def _removeComposite(composite):
        db._db.handle_delete(composite, True)
        db._db.delete_item(composite)

class RelatorNEventHandler(DatatypeEventHandler):
    "RelatorN datatype event handler"
    
    @staticmethod
    def on_create(item, attr):
        RelatorNEventHandler.on_update(item, attr, None)
    
    @staticmethod
    def on_update(item, new_attr, old_attr):
        # remove duplicates
        new_attr.value = list(set(new_attr.value))
        
        # get previous value
        if old_attr:
            prvValue = set(old_attr.value)
            noAccessList = RelatorNEventHandler._get_no_access_ids(old_attr)
        else:
            prvValue = set()
            noAccessList = []
        
        # get current value
        currentValue = set(new_attr.value + noAccessList)
        
        if currentValue != prvValue:
            # calculate added references
            ids_added = list(currentValue - prvValue)
            if ids_added:
                RelatorNEventHandler._add_references(new_attr, ids_added,
                                                     item._id)
            # calculate removed references
            ids_removed = list(prvValue - currentValue)
            if ids_removed:
                RelatorNEventHandler._remove_references(new_attr, ids_removed,
                                                        item._id)
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        if not item._isDeleted:
            if attr.value and attr.respectsReferences:
                raise exceptions.ReferentialIntegrityError, (
                    'Cannot delete object "%s" ' % item.displayName.value +
                    'because it is being referenced by other objects.')
            if attr.cascadeDelete:
                [db._db.get_item(id)._recycle()
                 for id in attr.value]
        if bPermanent:
            if attr.cascadeDelete:
                [db._db.get_item(id)._delete()
                 for id in attr.value]
            else:
                # remove all references
                RelatorNEventHandler._remove_references(attr, attr.value,
                                                        item._id)
    
    @staticmethod
    def on_undelete(item, attr):
        if attr.cascadeDelete:
            [db._db.get_item(id)._undelete()
             for id in attr.value]
    
    @staticmethod
    def _add_references(attr, ids, oid):
        from porcupine.datatypes import Relator1,RelatorN
        for id in ids:
            ref_item = db._db.get_item(id)
            if ref_item != None and isinstance(ref_item,
                                               tuple([misc.get_rto_by_name(cc)
                                                      for cc in attr.relCc])):
                ref_attr = getattr(ref_item, attr.relAttr)
                if isinstance(ref_attr, RelatorN):
                    ref_attr.value.append(oid)
                elif isinstance(ref_attr, Relator1):
                    ref_attr.value = oid
                ref_attr.validate()
                db._db.put_item(ref_item)
            else:
                attr.value.remove(id)
    
    @staticmethod
    def _remove_references(attr, ids, oid):
        # remove references
        from porcupine.datatypes import Relator1,RelatorN
        for id in ids:
            ref_item = db._db.get_item(id)
            ref_attr = getattr(ref_item, attr.relAttr)
            if isinstance(ref_attr, RelatorN):
                try:
                    ref_attr.value.remove(oid)
                except ValueError:
                    pass
            elif isinstance(ref_attr, Relator1):
                ref_attr.value = ''
            ref_attr.validate()
            db._db.put_item(ref_item)
    
    @staticmethod
    def _get_no_access_ids(attr):
        ids = [id for id in attr.value
               if db.get_item(id) == None]
        return ids
    
class Relator1EventHandler(DatatypeEventHandler):
    "Relator1 datatype event handler"

    @staticmethod
    def on_create(item, attr):
        Relator1EventHandler.on_update(item, attr, None)
 
    @staticmethod
    def on_update(item, new_attr, old_attr):
        # get previous value
        if old_attr:
            prvValue = old_attr.value
        else:
            prvValue = ''
        
        if new_attr.value != prvValue:
            if new_attr.value:
                Relator1EventHandler._add_reference(new_attr, item._id)
            if old_attr and prvValue:
                # remove old reference
                Relator1EventHandler._remove_reference(old_attr, item._id)
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        if not item._isDeleted:
            if attr.value and attr.respectsReferences:
                raise exceptions.ReferentialIntegrityError, (
                    'Cannot delete object "%s" ' % item.displayName.value +
                    'because it is referenced by other objects.')
            if attr.cascadeDelete:
                db._db.get_item(attr.value)._recycle()
        if bPermanent and attr.value:
            if attr.cascadeDelete:
                db._db.get_item(attr.value)._delete()
            else:
                # remove reference
                Relator1EventHandler._remove_reference(attr, item._id)
    
    @staticmethod
    def on_undelete(item, attr):
        if attr.cascadeDelete:
            db._db.get_item(attr.value)._undelete()
    
    @staticmethod
    def _add_reference(attr, oid):
        from porcupine.datatypes import Relator1,RelatorN
        ref_item = db._db.get_item(attr.value)
        if ref_item != None and isinstance(ref_item,
                                           tuple([misc.get_rto_by_name(cc)
                                                  for cc in attr.relCc])):
            ref_attr = getattr(ref_item, attr.relAttr)
            if isinstance(ref_attr, RelatorN):
                ref_attr.value.append(oid)
            elif isinstance(ref_attr, Relator1):
                ref_attr.value = oid
            ref_attr.validate()
            db._db.put_item(ref_item)
        else:
            attr.value = None
    
    @staticmethod
    def _remove_reference(attr, oid):
        from porcupine.datatypes import Relator1,RelatorN
        ref_item = db._db.get_item(attr.value)
        ref_attr = getattr(ref_item, attr.relAttr)
        if isinstance(ref_attr, RelatorN):
            try:
                ref_attr.value.remove(oid)
            except ValueError:
                pass
        elif isinstance(ref_attr, Relator1):
            ref_attr.value = None
        ref_attr.validate()
        db._db.put_item(ref_item)

class ExternalAttributeEventHandler(DatatypeEventHandler):
    "External attribute event handler"

    @staticmethod
    def on_create(item, attr):
        ExternalAttributeEventHandler.on_update(item, attr, None)
    
    @staticmethod
    def on_update(item, new_attr, old_attr):
        if new_attr.is_dirty:
            db._db.put_external(new_attr._id, new_attr.value)
        new_attr._reset()
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        if bPermanent:
            db._db.delete_external(attr._id)

class ExternalFileEventHandler(DatatypeEventHandler):
    "External file event handler"
    
    @staticmethod
    def on_delete(item, attr, bPermanent):
        if bPermanent and attr.removeFileOnDeletion:
            try:
                os.remove(attr.value)
            except OSError:
                pass
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.