#####################################################################
#####################################################################
## 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.4 $" ##
####################################


#############################################
## "proxyIdList" value type implementation ##
#############################################

## This value type is useful for storing LISTS references to proxies.
## Values are lists of proxyIds, i.e., proxy.proxyId values, which are
## always strings of decimal digits that begin with two zeroes.

## NOTE: Use the "proxyIdSet" functions for *sets* of proxyId references.

## NOTE: When you create other value types that contain proxy references,
## you should use this implementation as a guide.  It's tricky to
## manage proxy references, not only because they die when merged, but
## also because they can't possibly retain their original IDs when
## they are imported.

## NOTE: During importation of instances of this value type from XML,
## some recordkeeping is done in vsv.currentTopicMapHoldingDict[
## 'IoMapsDict'][ (TMA name)][ propertyClassName].

import types, traceback

#######################################################
def ValueIsNotOfType_proxyIdList_(vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    if not isinstance( propertyValue, types.ListType):
        traceback.print_stack()
        vsv.errMsg( 'Value "%s" is not a list.' % ( propertyValue))
###
        vsv.inspect( proxyId = propertyInstance.proxyId)
###
        return True

    if propertyInstance:
        topicMap = propertyInstance.topicMap
        propertyClassName = propertyInstance.propertyClass.propertyClassName
    else:
        topicMap = None
        propertyClassName = args[ 'propertyClassName']

    for proxyId in propertyValue:
        if not isinstance(proxyId, types.StringType):
            vsv.errMsg( 'An item ("%s") in the list is not a string.' % ( proxyId))
            return True
        if not vsv.proxyIdStrValidatorRE.match( proxyId):
            vsv.errMsg( 'An item ("%s") in the list is not a proxy identifier string.' % ( proxyId))
            return True
        proxy = None
        if topicMap:
            if topicMap.proxies.has_key( proxyId):
                proxy = topicMap.proxies[ proxyId]
        else:
            for topicMapName in vsv.topicMaps:
                if vsv.topicMaps[ topicMapName].proxies.has_key( proxyId):
                    proxy = vsv.topicMaps[ topicMapName].proxies[ proxyId]

        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:
                    errString = 'An item ("%s") in the list is not the ID of any proxy in topic map "%s".' % ( proxyId, propertyInstance.topicMap.topicMapName)
                else:
                    errString = 'An item ("%s") in the list is not the ID of any proxy in any open topic map.' % ( proxyId)
                vsv.errMsg( errString)
                return True

    return False  ## all's well, presumably.                    

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

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

    oldProxyIdList = vsv.cPickleLoadObjectFromXMLContentString( string)

    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 = int( args[ '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 = args[ 'propertyClassName']

    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'][ args[ '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 newProxyIdList

