#####################################################################
#####################################################################
## Versavant Topic Map Application Bus / Subject Addressing Engine ##
## Copyright 2005 Steven R. Newcomb                                ##
##                                                                 ##
## This software is licensed under the Apache License, Version 2.0 ##
## (the "License"); you may not use this file except in compliance ##
## with the License.  Copies of the License are available at       ##
##        http://www.apache.org/licenses/LICENSE-2.0               ##
##                                                                 ##
## Unless required by applicable law or agreed to in writing,      ##
## software distributed under the License is distributed on an "AS ##
## IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either ##
## express or implied.  See the License for the specific language  ##
## governing permissions and limitations under the License.        ##
##                                                                 ##
## Copies of the source code and the license are available at      ##
##        http://www.versavant.org                                 ##
#####################################################################
#####################################################################

####################################
cvsRevision = "$Revision: 1.1 $"##
####################################


import types, traceback

#################################################
## implementation of                           ##
## stringListAndProxyIdList                    ##
#################################################

#######################################################
def ValueIsNotOfType_stringListAndProxyIdList_( vsv, propertyValue, propertyClass, propertyInstance = None):
    if not isinstance( propertyValue, types.ListType):
        if propertyInstance:
            vsv.errMsg( 'Value "%s" of property "%s" is not a list.' % ( propertyValue, propertyInstance.propertyInstanceKey))
        else:
            vsv.errMsg( 'Value "%s" of proposed "%s" property is not a list.' % ( propertyValue, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
        return True

    if len( propertyValue) != 2:
        if propertyInstance:
            vsv.errMsg( 'Value "%s" of property "%s" is a list, but it does not have two members.' % ( propertyValue, propertyInstance.propertyInstanceKey))
        else:
            vsv.errMsg( 'Value "%s" of proposed "%s" property is a list, but it does not have two members.' % ( propertyValue, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
        return True
        
    stringList = propertyValue[ 0]
    proxyIdList = propertyValue[ 1]

    if not isinstance( stringList, types.ListType):
        if propertyInstance:
            vsv.errMsg( 'First item in the list that is the value of property "%s" is not a list.' % ( propertyInstance.propertyInstanceKey))
        else:
            vsv.errMsg( 'First item in the list that is the value of proposed "%s" property is not a list.' % ( vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
        return True

    if not isinstance( proxyIdList, types.ListType):
        if propertyInstance:
            vsv.errMsg( 'Second item in the list that is the value of property "%s" is not a list.' % ( propertyInstance.propertyInstanceKey))
        else:
            vsv.errMsg( 'Second item in the list that is the value of proposed "%s" property is not a list.' % ( vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
        return True

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet; assume it's OK for now.
    
    for string in stringList:
        if not isinstance( string, types.StringType):
            if propertyInstance:
                vsv.errMsg( 'An item ("%s") in the list that is the first item in the list that is the value of property "%s" is not a string.' % ( string, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'An item ("%s") in the list that is the first item in the list that is the value of proposed "%s" property is not a list.' % ( string, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
            return True
            
    for proxyId in proxyIdList:
        if not isinstance( proxyId, types.StringType):
            if propertyInstance:
                vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of property "%s" is not a proxyId, because it is not a string.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of proposed "%s" property is not a proxyId, because it is not a string.' % ( proxyId, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
            return True

        proxy = vsv.isProxyId( proxyId, propertyClass.topicMap)
        if not proxy:

            if proxyId not in vsv.currentTopicMapHoldingDict[ 'IoMapsDict'][ 'TMAs'][ propertyInstance.TMAName][ propertyClassName]:
                   ## We're probably in the process of importing a topic map, and these are
                   ## references to proxies that don't exist yet because they haven't been imported
                   ## yet.  The above check is supposed to calm our fears that this proxy reference
                   ## is invalid, giving us reason to believe that it will soon be valid, even
                   ## though it's not quite valid yet.
                if propertyInstance:

                    vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of property "%s" is not a proxyId.' % ( proxyId, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of proposed "%s" property is not a proxyId.' % ( proxyId, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
                return True

        else:  ## proxy is real and known
            if proxy.forwardTo:
                if propertyInstance:

                    vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of property "%s" is not a proxyId of a living proxy.' % ( proxyId, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'An item ("%s") in the list that is the second item in the list that is the value of proposed "%s" property is not a proxyId of a living proxy.' % ( proxyId, vsv.catKey( propertyClass.topicMap.topicMapName, propertyClass.propertyClassName)))
                return True

    return False

#######################################################
def InstanceOf_stringListAndProxyIdList_ValueTypeToXMLContentString( vsv, propertyInstance):
    return vsv.cPickleDumpObjectAsXMLContentString( propertyInstance._value)

#######################################################
def XMLContentStringToInstanceOf_stringListAndProxyIdList_ValueType( vsv, string, propertyClass):
    ## Import a list of proxy references, adjusting them as necessary to
    ## the new proxyIds of the imported proxies to which they refer.

    oldPropertyValue = vsv.cPickleLoadObjectFromXMLContentString( string)

    oldStringList  = oldPropertyValue[ 0]
    oldProxyIdList = oldPropertyValue[ 1]

    mem2xmlProxyIdDict = vsv.currentTopicMapHoldingDict[ 'IoMapsDict'][ 'ProxyIds.mem2xml']
        ## This dictionary allows us to look up the in-xml element id of a
        ## proxy, given the proxy's proxyId as it was in the topic map
        ## from which the proxy was exported as xml.

    firstImportedProxyId = vsv.firstImportedProxyId
        ## This is an integer which, if we were to convert it into a
        ## string of decimal digits with 2 prepended zero characters,
        ## would be the proxyId of the first (the first, that is, not
        ## counting the proxies created in order to register the TMAs
        ## of the xml topic map being imported) in-memory proxy to be
        ## imported into the being-imported-into topic map from the
        ## xml topic map that we're importing.

    propertyClassName = propertyClass.propertyClassName
    TMAName = propertyClass.TMA.TMAName

    newProxyIdList = []

    for oldProxyId in oldProxyIdList:
        xmlProxyNum = mem2xmlProxyIdDict[ int( oldProxyId)]
        newProxyNum = (xmlProxyNum + firstImportedProxyId) - 1
        newProxyId = '00%s' % ( newProxyNum)
        newProxyIdList.append( newProxyId)

        appDict = vsv.currentTopicMapHoldingDict[ 'IoMapsDict'][ 'TMAs'][ TMAName]
        if not appDict.has_key( propertyClassName):
            appDict[ propertyClassName] = [ newProxyId]
        else:
            if newProxyId not in appDict[ propertyClassName]:
                appDict[ propertyClassName].append( newProxyId)
    ## vsv.IoMapsDict[ args[ 'TMAName']][ propertyClassName] will be consulted by
    ## the ValueIsNotOfType__() function in order to avoid a logical logjam over this.
    ## The logical logjam is that we're referring to proxies that haven't been imported
    ## yet, and the ValueIsNotOfType__() function checks to see that the proxy references are valid.
    ## This gives the ValueIsNotOfType__() function something to fall back on, as it checks.
    ## See that function, above, for more.

    return [ oldStringList, newProxyIdList]


