# -*- coding: utf8 -*-
'''
The BioCASE PyWrapper class, a XML/CGI interface to heterogeneous databases

$RCSfile: pywrapper.py,v $
$Revision: 911 $
$Author: markus $
$Date: 2008-04-30 23:52:39 +0200 (Mi, 30. Apr 2008) $
****************************************

+++  BioCASE    
+++  PyWrapper
+++  XML/CGI database interface

This is the main class of the pywrapper for BioCASE.
It implements the BioCASE protocol for query and response, based on DiGIR.
'''

# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is biocase.wrapper.
#
# The Initial Developer of the Original Code is
# M.Döring, Botanic Garden and Botanical Museum Berlin-Dahlem.
# Portions created by the Initial Developer are Copyright (C) 2003
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****


# import error messages
from biocase.wrapper.errorclasses import *
from biocase.wrapper.psf import ProviderSetup
from biocase.datasources import Datasource
from biocase.wrapper.diagnostics import DiagnosticsHandler
import os, sys, types


import biocase.configuration
cfg = biocase.configuration.Cfg()

import logging
log = logging.getLogger("pywrapper")
rootLogger = logging.getLogger()


# *********************************************
# ***  M A I N   Class
# *********************************************


# ----------------------------------------------------------------------------
class pywrapper:
    def __init__(self, protocol, dsa):
        '''Create a pywrapper instance based on the passed protocol.'''
        self.dsaObj       = None
        self.protocolObj  = None
        self.resultET     = None
        self.resultStatus = None
        #
        self.diagnosticsHandler=DiagnosticsHandler()
        rootLogger.addHandler(self.diagnosticsHandler)
        #
        self._readDatasource(dsa) # sets dsaObj
        self._setProtocol(protocol) # sets protocolObj

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def _setProtocol(self, protocol):
        '''Define the protocol to be used for responding to a request.
        Setting protocol to "None" uses no protocol at all.'''
        if protocol.lower()   == "biocase":
            # biocase 
            from biocase.wrapper.protocol.BioCASe.biocase_protocol import ProtocolClass
            self.protocolObj = ProtocolClass(dsaObj=self.dsaObj, diagnosticsHandler=self.diagnosticsHandler)
        elif protocol.lower() == "species2000":
            # species2000 
            from biocase.wrapper.protocol.species2000.sp2k_protocol import ProtocolClass
            self.protocolObj = ProtocolClass(dsaObj=self.dsaObj, diagnosticsHandler=self.diagnosticsHandler)
        else:
            raise UnknownProtocolError(protocol)
        
    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def _readDatasource(self, dsa):
        '''Reads the PSF file and creates a PSF object.'''
        # read provider-setup configuration file (psf)
        log.info("Datasource wrapper %s requested"%dsa)
        self.dsaObj = Datasource(dsa)
        # set debug level from PSF
        rootLogger.setLevel(self.psfObj.loglevel)

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def parseRequest(self, argHash=None, **args):
        '''Inits a request and processes it.
        If no parameter hash is passed to this method, 
        it tries to get parameters via the protocol objects from the CGI environment.'''
        if type(argHash) == types.DictType:
            args=argHash
        self.protocolObj.parseRequest(args)

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def doResponse(self, stream=sys.stdout, encoding='UTF-8', httpHeader=1):
        '''Returns a XML response string. 
        A true httpHeader parameter will include an XML http header.'''
        self.protocolObj.doResponse(stream, encoding, httpHeader)

    # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def getPsfObj(self):
        return self.dsaObj.getPSFObj()
    psfObj = property(getPsfObj)





##############################
if __name__ ==  "__main__":
    # start logging
    import biocase.initlogs
    dsa='pontoflex_maximus'
    biocase.initlogs.initWrapperLogging(dsa)
    pywObj = pywrapper('biocase', dsa)
    pywObj.parseRequest({'start':2, 'limit':5, 'request_type':'scan', 'concept_to_scan':'ABC'})
    pywObj.doResponse()