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

#################################################
## Default value type implementation functions ##
## (Default assumes values will be strings.)   ##
#################################################

import types

#######################################################
def DefaultValueIsNotOfType__( vsv, propertyValue, propertyClass, propertyInstance = None):
    if not isinstance(propertyValue, types.StringType):
        vsv.errMsg( 'Value "%s" is not a string.' % propertyValue)
        return True
    return False

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


#######################################################
def DefaultXMLContentStringToInstanceOf__ValueType(vsv, string):
    return vsv.cPickleLoadObjectFromXMLContentString( string)



#####################################################
## Default property class implementation functions ##
#####################################################


#######################################################
def DefaultAdd__PropToOverheadDict( vsv, propertyInstance, overheadDict):
    if not isinstance( propertyInstance._value, types.StringType):
        vsv.errMsg( 'The DefaultAdd__PropToOverheadDict() function cannot be used with values other than strings.  propertyInstance._value == "%s", propertyClass = "%s", property instance = "%s"' % (
            propertyInstance._value,
            propertyInstance.propertyClass.propertyClassName,
            vsv.catKey( propertyInstance.topicMap.topicMapName, propertyInstance.propertyInstanceKey)
            ))

    if overheadDict.has_key( propertyInstance._value):
        overheadDict[ propertyInstance._value].append( propertyInstance.proxyId)
    else:
        overheadDict[ propertyInstance._value] = [ propertyInstance.proxyId]


#######################################################
def DefaultRemove__PropFromOverheadDict( vsv, propertyInstance, overheadDict):
    if not isinstance( propertyInstance._value, types.StringType):
        vsv.errMsg( 'The DefaultRemove__PropToOverheadDict() function cannot be used with values other than strings.  propertyInstance._value == "%s", propertyClass = "%s", property instance = "%s"' % (
            propertyInstance._value,
            propertyInstance.propertyClass.propertyClassName,
            vsv.catKey( propertyInstance.topicMap.topicMapName, propertyInstance.propertyInstanceKey)
            ))

    overheadDict[ propertyInstance._value].remove( propertyInstance.proxyId)
    if not len( overheadDict[ propertyInstance._value]):
        del overheadDict[ propertyInstance._value]


#######################################################
def DefaultMerge__PropertyValues( vsv, value1, value2):
    if isinstance( value1, types.StringType) and isinstance( value2, types.StringType):
        if value1 == value2:
            return value1
        else:
            return None  ## the merge failed.
    elif isinstance( value1, types.ListType) and isinstance( value2, types.ListType):
        returnValue = value1[:]
        returnValue.extend( value2)
        return returnValue
    else:
        return None ## the merge failed.

#######################################################
def DefaultValuesOf__PropertyInstancesAreSignificantlyDifferent( vsv, value1, value2):
    if isinstance( value1, types.StringType) and isinstance( value2, types.StringType):
        if value1 != value2:
            return True
        return False
    elif isinstance( value1, types.ListType) and isinstance( value2, types.ListType):
        if len( value1) != len( value2):
            return True
        for j in range( len( value1)):
            if value1[ j] != value2[ j]:
                return True
        return False
    else:
        return True  

#######################################################
def DefaultProxiesOfSubjectIdentifiedBy__Value( vsv, propertyClass, value):
    if not isinstance( value, types.StringType):
        vsv.errMsg( 'The DefaultProxiesOfSubjectIdentifiedBy__Value() function cannot be used with values other than strings.  value == "%s", propertyClass = "%s"' % (
            value,
            propertyClass.propertyClassName,
            ))

    if propertyClass.overheadDict.has_key( value):
        return propertyClass.overheadDict[ value]
    else:
        return []  ## empty list -- no match


###########
## Misc. ##
###########

## The following really isn't a default function, because if you want
## to use it, you must refer to it explicitly in the TMA configuration
## file.  It can't be a default in the usual sense, because if it
## were, all properties would be SIPs.  (The difference between an SIP
## and an OP is that SIP classes have
## MergeProxiesBecause__PropertyInstancesSpecifySameSubject()
## functions, while OPs don't.)  The below function works nicely with
## the default functions listed above; if they will work for you,
## this probably will too.

#######################################################
def DefaultMergeProxiesBecause__PropertyInstancesSpecifySameSubject( vsv, propertyClass):
    for hashablePropertyValue in propertyClass.overheadDict:
        if len( propertyClass.overheadDict[ hashablePropertyValue]) > 1:
            vsv.mergeListOfProxies( propertyClass, propertyClass.overheadDict[ hashablePropertyValue])
    

