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

#######################################################################
## This property class assumes a value type of lists whose items are ##
## strings.  However, they are treated as a set, not a list; their   ##
## order is not significant and redundant items will be ignored.     ##
## The value type implementation found in                            ##
## versavant/Lib/VTstringSet.py can be used.                         ##
##                                                                   ##
## * Subject sameness is having all the same items in both values.   ##
##                                                                   ##
## * If you desire any two values to be regarded as having the same  ##
##   subject if they have one or more items in common, use the       ##
##   variant functions with "anyMatch" in their names.               ##
#######################################################################

#######################################################
## Subject sameness is sameness of the whole sets:
def Add_stringSet_PropToOverheadDict( vsv, propertyInstance, overheadDict):
    hashableValue = propertyInstance.hashablePropertyValue = frozenset( propertyInstance._value)
    if overheadDict.has_key( hashableValue):
        overheadDict[ hashableValue].append( propertyInstance.proxyId)
    else:
        overheadDict[ hashableValue] = [ propertyInstance.proxyId]

#######################################################
## Subject sameness is sameness of any item in the sets (intersection of sets is non-empty):
def Add_stringSet_anyMatch_PropToOverheadDict( vsv, propertyInstance, overheadDict):
    value = propertyInstance._value
    for item in value:
        if overheadDict.has_key( item):
            overheadDict[ item].append( propertyInstance.proxyId)
        else:
            overheadDict[ item] = [ propertyInstance.proxyId]


#######################################################
def Remove_stringSet_PropFromOverheadDict( vsv, propertyInstance, overheadDict):
## Subject sameness is sameness of the whole sets:
    hashableValue = propertyInstance.hashablePropertyValue
    overheadDict[ hashableValue].remove( propertyInstance.proxyId)
    if not len( overheadDict[ hashableValue]):
        del overheadDict[ hashableValue]

#######################################################
def Remove_stringSet_anyMatch_PropFromOverheadDict( vsv, propertyInstance, overheadDict):
## Subject sameness is sameness of any item in the sets (intersection of sets is non-empty):
    value = propertyInstance._value
    for item in value:
        overheadDict[ item].remove( propertyInstance.proxyId)
        if not len( overheadDict[ item]):
            del overheadDict[ item]


#######################################################
## This works either way.
def Merge_stringSet_PropertyValues( vsv, value1, value2):
    newList = []
    for stringItem in value1:
        if stringItem not in newList:
            newList.append( stringItem)
    for stringItem in value2:
        if stringItem not in newList:
            newList.append( stringItem)
    return newList

#######################################################
## This works either way.
def ValuesOf_stringSet_PropertyInstancesAreSignificantlyDifferent( vsv, value1, value2):
    if frozenset( value1) == frozenset( value2):
        return False
    else:
        return True  

#######################################################
def ProxiesOfSubjectIdentifiedBy_stringSet_Value( vsv, propertyClass, value):
## Subject sameness is sameness of the whole set:
    fset = frozenset( value)
    if propertyClass.overheadDict.has_key( fset):
        return propertyClass.overheadDict[ fset]
    else:
        return []  ## empty list -- no match

#######################################################
def ProxiesOfSubjectIdentifiedBy_stringSet_anyMatch_Value( vsv, propertyClass, value):
## Subject sameness is sameness of any item in the sets (intersection of sets is non-empty):
    proxyIdList = []
    for item in value:
        if propertyClass.overheadDict.has_key( item):
            for proxyId in propertyClass.overheadDict[ item]:
                if proxyId not in proxyIdList:
                    proxyIdList.append( proxyId)
    return proxyIdList

#######################################################
def MergeProxiesBecause_stringSet_PropertyInstancesSpecifySameSubject( vsv, propertyClass):
## Subject sameness is sameness of the whole set:
    ## Declare this one if and only if your property class is for SIPs
    ## (subject identity properties).
    for hashablePropertyValue in propertyClass.overheadDict:
        if len( propertyClass.overheadDict[ hashablePropertyValue]) > 1:
            vsv.mergeListOfProxies( propertyClass, propertyClass.overheadDict[ hashablePropertyValue])
    
#######################################################
def MergeProxiesBecause_stringSet_anyMatch_PropertyInstancesSpecifySameSubject( vsv, propertyClass):
## Subject sameness is sameness of any item in the sets (intersection of sets is non-empty):
    ## Declare this one if and only if your property class is for SIPs
    ## (subject identity properties).
    while True:
        foundThingsToMerge = False
        itemList = propertyClass.overheadDict.keys()  ## stabilize what we're doing
        for item in itemList:
            if len( propertyClass.overheadDict[ item]) > 1:
                vsv.mergeListOfProxies( propertyClass, propertyClass.overheadDict[ item])
                foundThingsToMerge = True
        if not foundThingsToMerge: break
