# -*- coding: iso-8859-15 -*-


# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
#     Romain Chantereau <rchantereau@entrouvert.com>
#     Nicolas Clapiès <nclapies@easter-eggs.org>
#     Pierre-Antoine Dejace <padejace@entrouvert.be>
#     Thierry Dulieu <tdulieu@easter-eggs.com>
#     Florent Monnier <monnier@codelutin.com>
#     Cédric Musso <cmusso@easter-eggs.org>
#     Frédéric Péters <fpeters@entrouvert.be>
#     Benjamin Poussin <poussin@codelutin.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#     Sébastien Régnier <regnier@codelutin.com>
#     Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
#     Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
#     Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
#     Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
#     Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


__doc__ = """Glasnost Objects Common Models"""

__version__ = '$Revision$'[11:-2]


import types

import kinds # Do not remove!
import faults
import system
import things
from tools import *


register = things.register


class ObjectCommon(things.BaseThing):
    id = None
    id_kindName = 'Id'

    language = None
    language_kindName = 'LanguageChoice'

    serverRole = None
    serverRole_kind_importExport = 'private'
    serverRole_kindName = 'ServerRole'

    thingCategory = 'object'

    version = 0
    version_kind_isRequired = 1
    version_kindName = 'Integer'

    def canCache(self):
        if hasattr(self, 'readersSet_kind') \
               and self.readersSet_kind is not None:
            import glasnost.proxy.GroupsProxy as proxyGroups
            try:
                proxyGroups.getSetContainedIds(
                        self.readersSet, serverRoles = ['identities'],
                        raiseWhenUncountable = 1)
            except faults.UncountableGroup:
                # Even non identified users can read the object. We can cache
                # it.
                return 1
        return 0

    def getId(self):
        return self.id

    def getLabel(self):
        raise NotImplementedError

    def getLabelLanguage(self):
        return self.getLanguage()

    def getLanguage(self):
        return self.language

    def getOrderedLayoutSlotNames(self, parentSlot = None):
        slotNames = things.BaseThing.getOrderedLayoutSlotNames(
            self, parentSlot = parentSlot)
        slotNames += ['id', 'version', 'language']
        return slotNames

    def getThingName(cls):
        if type(cls) == types.InstanceType:
            cls = cls.__class__
        if cls.thingName:
            thingName = cls.thingName
        else:
            thingName = cls.__name__
        return '%s.%s' % (cls.serverRole, thingName)


class AdminWithoutWritersCommon(ObjectCommon):
    adminsSet = [system.generalPublicId]
    adminsSet_kind_balloonHelp = N_(
            'Select a global [administrator->setting-permissions] '\
            '(a [people>people-and-groups] or [group->people-and-groups] object) '\
            'for these [objects->objects]. '\
            'Click on "Add" to add another one. '\
            'Select "None" to remove one.')
    adminsSet_kindName = 'UsersSet'

    language_kindName = None

    def getLanguage(self):
        virtualHost = context.getVar('virtualHost')
        if virtualHost is not None:
            return virtualHost.getLanguage()
        return 'en'

    def getOrderedLayoutSlotNames(self, parentSlot = None):
        slotNames = ObjectCommon.getOrderedLayoutSlotNames(
                self, parentSlot = parentSlot)
        slotNames += ['adminsSet']
        return slotNames

    def newDefaultObject(self):
        raise NotImplementedError


class AdminCommon(AdminWithoutWritersCommon):
    writersSet = None
    writersSet_kind_balloonHelp = N_(
            'Select the people and groups who are allowed '\
            'to [create->setting-permissions] these objects.')
    writersSet_kind_minCount = 0
    writersSet_kindName = 'WritersSet'

    readersSet = [system.generalPublicId]
    readersSet_kind_balloonHelp = N_(
            'Select the people and groups who are allowed '\
            '[read->setting-permissions] access to all these objects.')
    readersSet_kindName = 'ReadersSet'

    def getOrderedLayoutSlotNames(self, parentSlot = None):
        slotNames = AdminWithoutWritersCommon.getOrderedLayoutSlotNames(
                self, parentSlot = parentSlot)
        slotNames += ['writersSet', 'readersSet']
        return slotNames


class ObjectsCommonMixin:
    
    """Abstract class designed to be inherited with a specialized class.

    The product of a multiple inheritance is a fonctionnal Object.
    All attributes can or must be overriden or extended, in fact, this class
    define their default values.

    Attributes:
    ===========

    *adminClassName*:
        The class name string used for administrative purposes.
        **Must be overriden**.
        
    *newObjectNameCapitalized*:
        The illustrating string explaining what do a new object creation.
        The objects are the objects handled by the subclass (not the class
        itself).
        
    *objectClassName*:
        The handled object class name string.
        **Must be overriden**.
    
    *objectName*:
        The 'gettextized' handled object class name string.
    
    *objectNameCapitalized*:
        The capitalized 'gettextized' handled object class name string.
    
    *objectsName*:
        The 'gettextized' functionnal class name string (Usually the class name
        without the type (proxy or server, etc...)).
        
    *objectsNameCapitalized*:
        The capitalized 'gettextized'  class name string (Usually the class name
        without the type (proxy or server, etc...)).
    
    *serverRole*:
        The class server role string.

    *useObjectIds*:
        A boolean indicating whether the objects have an ID.

    """

    adminClassName = None # To override.
    newObjectNameCapitalized = N_('New Object')
    objectClassName = None # To override.
    objectName = N_('object')
    objectNameCapitalized = N_('Object')
    objectsName = N_('objects')
    objectsNameCapitalized = N_('Objects')
    serverRole = None
    useObjectIds = 1

    def getTranslatedObjectName(self):
        return _(self.objectName)

    def getTranslatedObjectNameCapitalized(self):
        return _(self.objectNameCapitalized)

    def getTranslatedObjectsName(self):
        return _(self.objectsName)

    def getTranslatedObjectsNameCapitalized(self):
        return _(self.objectsNameCapitalized)

    def getTranslatedNewObjectNameCapitalized(self):
        return _(self.newObjectNameCapitalized)

