#!/usr/bin/env python
# -*- 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 Cards Server"""

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


import copy
import sys

glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)

import glasnost

from glasnost.common.CardsCommon import *
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools

from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
        AdminServerMixin, ObjectsServer
from glasnost.server.tools import *

from glasnost.proxy.CacheProxy import invalidateValue
from glasnost.proxy.DispatcherProxy import getApplicationId
from glasnost.proxy.tools import getProxy


applicationName = 'CardsServer'
applicationRole = 'cards'
dispatcher = None


class AdminCards(AdminServerMixin, AdminCardsCommon):
    pass
register(AdminCards)


class Card(ObjectServerMixin, CardCommon):
    def checkModifyIsPossible(self, changes, givenSlotNames = None):
        # The slot 'properties' and 'prototypeIds' are needed to compute the
        # slotNames list.
        clone = copy.copy(self)
        for slotName in ['properties', 'prototypeIds']:
            if givenSlotNames and not slotName in givenSlotNames:
                continue
            cloneSlot = clone.getSlot(slotName)
            changesSlot = changes.getSlot(slotName)
            cloneSlot.setValue(changesSlot.getValue())
        ObjectServerMixin.checkModifyIsPossible(
                clone, changes, givenSlotNames = givenSlotNames)

    def initPartial(self, partial, givenSlotNames = None):
        if givenSlotNames and not 'prototypeIds' in givenSlotNames:
            partial.prototypeIds = self.prototypeIds
        if givenSlotNames and not 'properties' in givenSlotNames:
            partial.properties = self.properties

    def getCard(self, cardId):
        if commonTools.extractDispatcherId(cardId) == context.getVar(
                'dispatcherId'):
            return self.getServer().getInternalCard(cardId)
        else:
            return getProxy(cardId).getObject(cardId)

    def getModifySlotNames(self, parentSlot = None):
        names = CardCommon.getModifySlotNames(self, parentSlot = parentSlot)
        names = names[:]
        if 'properties' in names:
            # The slot 'properties' is already mofified by the method
            # modify.
            names.remove('properties')
        if 'prototypeIds' in names:
            # The slot 'prototypeIds' is already mofified by the method
            # modify.
            names.remove('prototypeIds')
        return names

    def modify(self, changes, givenSlotNames = None):
        # The slot 'properties' and 'prototypeIds' must be modified first,
        # because they are needed to compute the slotNames list.
        for slotName in ['properties', 'prototypeIds']:
            slot = self.getSlot(slotName)
            kind = slot.getKind()
            if kind.isAutomaticallyModified:
                kind.setAutomaticalValue(slot)
                continue
            if not kind.isImportable():
                continue
            if givenSlotNames and not slotName in givenSlotNames:
                continue
            changesSlot = changes.getSlot(slotName)
            slot.setValue(changesSlot.getValue())
        ObjectServerMixin.modify(
                self, changes, givenSlotNames = givenSlotNames)
register(Card)


class CardsServer(CardsCommonMixin, ObjectsServer):
    def getImplementationIds(self, prototypeId):
        if not self.canGetObjects():
            raise faults.UserAccessDenied()
        virtualServerId = context.getVar('applicationId')
        virtualServer = self.getVirtualServer(virtualServerId)
        result = []
        for objectId, objectCore in virtualServer.objects.items():
            if objectCore.prototypeIds is not None \
                   and prototypeId in objectCore.prototypeIds \
                   and (self.canGetObject(objectId)
                        or objectCore.canBeGottenByClient()):
                result.append(objectId)
        return result

    def getInternalCard(self, cardId):
        virtualServerId = self.computeVirtualServerId(cardId)
        virtualServer = self.getVirtualServer(virtualServerId)
        card = virtualServer.loadObjectCore(cardId)
        return card

    def registerPublicMethods(self):
        ObjectsServer.registerPublicMethods(self)
        self.registerPublicMethod('getImplementationIds')


cardsServer = CardsServer()


if __name__ == "__main__":
    cardsServer.launch(applicationName, applicationRole)

