Ignore:
Timestamp:
02/04/09 10:38:41 (11 years ago)
Author:
pjkersha
Message:

Moved function condition classes into cond module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/authz/xacml/__init__.py

    r5161 r5162  
    1 """XACML Policy Decision Point module 
     1"""XACML Package 
    22 
    33NERC DataGrid Project 
     
    354354        raise NotImplementedError() 
    355355     
    356        
    357 class FunctionBase(XacmlBase): 
    358     FUNCTION_NS = "urn:oasis:names:tc:xacml:1.0:function:" 
    359      
    360     def __init__(self,  
    361                  functionName,  
    362                  functionId=None,  
    363                  paramType=None, 
    364                  paramIsBag=False, 
    365                  numParams=0,  
    366                  minParams=0, 
    367                  returnType='',  
    368                  returnsBag=False): 
    369            
    370         self.functionName = functionName 
    371         self.functionId = functionId 
    372         self.returnType = None 
    373         self.returnsBag = False 
    374      
    375         self.singleType = True; 
    376      
    377         self.paramType = paramType 
    378         self.paramIsBag = paramIsBag 
    379         self.numParams = numParams 
    380         self.minParams = minParams 
    381          
    382    
    383     def _setFunctionName(self, functionName): 
    384           if functionName not in self.__class__.supportedIdentifiers: 
    385               functionList = ', '.join(self.__class__.supportedIdentifiers) 
    386               raise TypeError("Function name [%s] is not on of the recognised " 
    387                               "types: %s" % (functionName, functionList)) 
    388           self._functionName = functionName 
    389            
    390     def _getFunctionName(self): 
    391           return getattr(self, '_functionName', None) 
    392      
    393     functionName = property(fset=_setFunctionName, 
    394                                     fget=_getFunctionName) 
    395            
    396     def checkInputs(self, inputs): 
    397         '''Checks that the given inputs are of the right types, in the right  
    398         order, and are the right number for this function to evaluate.''' 
    399         raise NotImplementedError() 
    400              
    401     def checkInputsNoBag(self, inputs): 
    402         '''Checks that the given inputs are of the right types, in the right  
    403         order, and are the right number for this function to evaluate.''' 
    404         raise NotImplementedError() 
    405   
    406     def evaluate(self, inputs, context): 
    407         '''Evaluates the Function using the given inputs.''' 
    408         raise NotImplementedError() 
    409       
    410     def evalArgs(self, params, context, args): 
    411         '''Evaluates each of the parameters, in order, filling in the argument 
    412         array with the resulting values. If any error occurs, this method 
    413         returns the error, otherwise null is returned, signalling that 
    414         evaluation was successful for all inputs, and the resulting argument 
    415         list can be used. 
    416          
    417         @param params a list of Evaluatable objects representing the parameters 
    418         to evaluate 
    419         @param context the representation of the request 
    420         @param args an array as long as the params list that will, on return,  
    421         contain the AttributeValues generated from evaluating all parameters 
    422  
    423         @return None if no errors were encountered, otherwise 
    424         an EvaluationResult representing the error 
    425         ''' 
    426         index = 0 
    427  
    428         for eval in params: 
    429             # get and evaluate the next parameter 
    430             result = eval.evaluate(context) 
    431  
    432             # If there was an error, pass it back... 
    433             if result.indeterminate(): 
    434                 return result 
    435  
    436             # ...otherwise save it and keep going 
    437             args[index] = result.getAttributeValue() 
    438             index += 1 
    439              
    440         return None 
    441  
    442 # TODO: Condition classes - minimal implementation until opportunity to fully  
    443 # implement    
    444 class Function(XacmlBase): 
    445     def __init__(self, *arg, **kw): 
    446         raise NotImplementedError() 
    447  
    448     @classmethod 
    449     def getInstance(cls, root): 
    450         raise NotImplementedError() 
    451  
    452 class BagFunction(FunctionBase): 
    453     def __init__(self, *arg, **kw): 
    454         raise NotImplementedError() 
    455  
    456 class SetFunction(FunctionBase): 
    457     def __init__(self, *arg, **kw): 
    458         raise NotImplementedError() 
    459         
    460 class ConditionBagFunction(BagFunction): 
    461     def __init__(self, *arg, **kw): 
    462         raise NotImplementedError() 
    463          
    464 class ConditionSetFunction(FunctionBase): 
    465     def __init__(self, *arg, **kw): 
    466         raise NotImplementedError() 
    467          
    468 class HigherOrderFunction(Function): 
    469     def __init__(self, *arg, **kw): 
    470         raise NotImplementedError() 
    471  
    472 # TODO: Function classes - minimal implementation until opportunity to fully  
    473 # implement                                     
    474 class LogicalFunction(FunctionBase): 
    475  
    476     def __init__(self, *arg, **kw): 
    477         raise NotImplementedError() 
    478  
    479 class NOfFunction(FunctionBase): 
    480      
    481     def __init__(self, *arg, **kw): 
    482         raise NotImplementedError() 
    483          
    484 class NotFunction(FunctionBase): 
    485      
    486     def __init__(self, *arg, **kw): 
    487         raise NotImplementedError() 
    488          
    489 class ComparisonFunction(FunctionBase): 
    490      
    491     def __init__(self, *arg, **kw): 
    492         raise NotImplementedError() 
    493  
    494 class MatchFunction(FunctionBase): 
    495     NAME_REGEXP_STRING_MATCH = \ 
    496           "urn:oasis:names:tc:xacml:1.0:function:regexp-string-match" 
    497     NAME_RFC822NAME_MATCH = \ 
    498           "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-match" 
    499     NAME_X500NAME_MATCH = \ 
    500           "urn:oasis:names:tc:xacml:1.0:function:x500Name-match"      
    501  
    502     supportedIdentifiers = (NAME_REGEXP_STRING_MATCH,  
    503                             NAME_RFC822NAME_MATCH, 
    504                             NAME_X500NAME_MATCH) 
    505      
    506     lut = { 
    507           NAME_REGEXP_STRING_MATCH: 'regexpStringMatch', 
    508           NAME_RFC822NAME_MATCH:    'rfc822NameMatch', 
    509           NAME_X500NAME_MATCH:      'x500NameMatch' 
    510     } 
    511      
    512     def __init__(self, functionName, **kw): 
    513           super(MatchFunction, self).__init__(functionName, **kw) 
    514  
    515     def regexpStringMatch(self, regex, val): 
    516           return re.match(regex, val) is not None 
    517      
    518     def rfc822NameMatch(self, *inputs): 
    519         raise NotImplementedError() 
    520      
    521     def x500NameMatch(self, *inputs): 
    522         raise NotImplementedError() 
    523      
    524     def evaluate(self, inputs, context): 
    525           matchFunction = getattr(self, MatchFunction.lut[self.functionName]) 
    526           match = matchFunction(self, *inputs) 
    527           if match: 
    528                 return EvaluationResult(status=Status.STATUS_OK) 
    529  
    530  
    531 class EqualFunction(FunctionBase): 
    532     supportedIdentifiers = ( 
    533           "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal", 
    534           "urn:oasis:names:tc:xacml:1.0:function:base64Binary-equal", 
    535           "urn:oasis:names:tc:xacml:1.0:function:boolean-equal", 
    536           "urn:oasis:names:tc:xacml:1.0:function:date-equal", 
    537           "urn:oasis:names:tc:xacml:1.0:function:dateTime-equal", 
    538           "urn:oasis:names:tc:xacml:1.0:function:dayTimeDuration-equal", 
    539           "urn:oasis:names:tc:xacml:1.0:function:double-equal", 
    540           "urn:oasis:names:tc:xacml:1.0:function:hexBinary-equal", 
    541           "urn:oasis:names:tc:xacml:1.0:function:integer-equal", 
    542           "urn:oasis:names:tc:xacml:1.0:function:rfc822Name-equal", 
    543           "urn:oasis:names:tc:xacml:1.0:function:string-equal", 
    544           "urn:oasis:names:tc:xacml:1.0:function:time-equal", 
    545           "urn:oasis:names:tc:xacml:1.0:function:x500Name-equal", 
    546           "urn:oasis:names:tc:xacml:1.0:function:yearMonthDuration-equal" 
    547     ) 
    548  
    549     (NAME_ANYURI_EQUAL, 
    550     NAME_BASE64BINARY_EQUAL, 
    551     NAME_BOOLEAN_EQUAL, 
    552     NAME_DATE_EQUAL, 
    553     NAME_DATETIME_EQUAL, 
    554     NAME_DAYTIME_DURATION_EQUAL, 
    555     NAME_DOUBLE_EQUAL, 
    556     NAME_HEXBINARY_EQUAL, 
    557     NAME_INTEGER_EQUAL, 
    558     NAME_RFC822NAME_EQUAL, 
    559     NAME_STRING_EQUAL, 
    560     NAME_TIME_EQUAL, 
    561     NAME_X500NAME_EQUAL, 
    562     NAME_YEARMONTH_DURATION_EQUAL) = supportedIdentifiers 
    563  
    564     lut = { 
    565           NAME_STRING_EQUAL: 'stringEqual' 
    566     } 
    567      
    568     typeMap = {NAME_STRING_EQUAL: basestring} 
    569      
    570     def __init__(self, functionName, **kw): 
    571           super(EqualFunction, self).__init__(functionName, **kw) 
    572  
    573     def evaluate(self, inputs, evaluationCtx): 
    574         function = EqualFunction.lut.get(self.functionName) 
    575         if function is None: 
    576             if self.functionName in supportedIdentifiers: 
    577                 raise NotImplementedError("No implementation is available for " 
    578                                           "%s" % self.functionName)             
    579             else: 
    580                 raise AttributeError('function name "%s" not recognised ' 
    581                                      'for %s' % (self.functionName, 
    582                                                  self.__class__.__name__)) 
    583                                    
    584         return getattr(self, function)(inputs, evaluationCtx) 
    585      
    586     def stringEqual(self, inputs, evaluationCtx): 
    587         result = self.evalArgs(inputs, context, argValues) 
    588         if result is not None: 
    589             return result 
    590            
    591         return EvaluationResult(argValues[0] == argValues[1]) 
    592      
    593     def getArgumentType(functionName): 
    594         datatype = EqualFunction.typeMap.get(functionName); 
    595         if datatype is None: 
    596             raise AttributeError("Not a standard function: %s" % functionName) 
    597            
    598         return datatype 
    599  
    600 class AddFunction(FunctionBase): 
    601      
    602     def __init__(self, *arg, **kw): 
    603         raise NotImplementedError() 
    604              
    605 class SubtractFunction(FunctionBase): 
    606      
    607     def __init__(self, *arg, **kw): 
    608         raise NotImplementedError() 
    609              
    610 class MultiplyFunction(FunctionBase): 
    611      
    612     def __init__(self, *arg, **kw): 
    613         raise NotImplementedError() 
    614              
    615 class DivideFunction(FunctionBase): 
    616      
    617     def __init__(self, *arg, **kw): 
    618         raise NotImplementedError() 
    619              
    620 class ModFunction(FunctionBase): 
    621      
    622     def __init__(self, *arg, **kw): 
    623         raise NotImplementedError() 
    624  
    625 class AbsFunction(FunctionBase): 
    626      
    627     def __init__(self, *arg, **kw): 
    628         raise NotImplementedError() 
    629  
    630 class RoundFunction(FunctionBase): 
    631      
    632     def __init__(self, *arg, **kw): 
    633         raise NotImplementedError() 
    634  
    635 class FloorFunction(FunctionBase): 
    636      
    637     def __init__(self, *arg, **kw): 
    638         raise NotImplementedError() 
    639  
    640 class DateMathFunction(FunctionBase): 
    641      
    642     def __init__(self, *arg, **kw): 
    643         raise NotImplementedError() 
    644  
    645 class GeneralBagFunction(BagFunction): 
    646      
    647     def __init__(self, *arg, **kw): 
    648         raise NotImplementedError() 
    649  
    650 class NumericConvertFunction(FunctionBase): 
    651      
    652     def __init__(self, *arg, **kw): 
    653         raise NotImplementedError() 
    654  
    655 class StringNormalizeFunction(FunctionBase): 
    656      
    657     def __init__(self, *arg, **kw): 
    658         raise NotImplementedError() 
    659  
    660 class GeneralSetFunction(SetFunction): 
    661      
    662     def __init__(self, *arg, **kw): 
    663         raise NotImplementedError() 
    664      
    665 class MapFunction(Function):         
    666     supportedIdentifiers = () 
    667     NAME_MAP = FunctionBase.FUNCTION_NS + "map" 
    668      
    669     def __init__(self, *arg, **kw): 
    670         raise NotImplementedError() 
    671  
    672     @classmethod 
    673     def getInstance(cls, root): 
    674         raise NotImplementedError() 
    675      
    676 class FunctionProxy(): 
    677  
    678     def getInstance(self, root): 
    679         raise NotImplementedError() 
    680  
    681 class MapFunctionProxy(FunctionProxy): 
    682  
    683     def getInstance(self, root): 
    684         return MapFunction.getInstance(root) 
    685  
    686  
    687 class UnknownIdentifierException(Exception): 
    688     pass 
    689  
    690 class FunctionTypeException(Exception): 
    691     pass 
    692  
    693 class ParsingException(Exception): 
    694     pass 
    695  
    696 class FunctionFactory(XacmlBase): 
    697     '''Factory used to create all functions. There are three kinds of factories: 
    698     general, condition, and target. These provide functions that can be used 
    699     anywhere, only in a condition's root and only in a target (respectively). 
    700      
    701     Note that all functions, except for abstract functions, are singletons, so 
    702     any instance that is added to a factory will be the same one returned 
    703     from the create methods. This is done because most functions don't have 
    704     state, so there is no need to have more than one, or to spend the time 
    705     creating multiple instances that all do the same thing.''' 
    706  
    707     defaultFactoryProxy = StandardFunctionFactory()                  
    708              
    709     @classmethod 
    710     def getTargetInstance(cls): 
    711         '''Returns the default FunctionFactory that will only provide those 
    712         functions that are usable in Target matching. 
    713          
    714         @return a FunctionFactory for target functions''' 
    715         return cls.defaultFactoryProxy.getTargetFactory() 
    716         
    717     @classmethod  
    718     def getConditionInstance(cls):  
    719         '''Returns the default FunctionFactory that provides access to all the 
    720         functions. These Functions are a superset of the Condition functions. 
    721          
    722         @return a FunctionFactory for all functions 
    723         ''' 
    724         return cls.defaultFactoryProxy.getConditionFactory() 
    725      
    726     @classmethod 
    727     def getGeneralInstance(cls):  
    728         '''Sets the default factory. Note that this is just a place holder for 
    729         now, and will be replaced with a more useful mechanism soon.''' 
    730         return cls.defaultFactoryProxy.getGeneralFactory() 
    731      
    732      
    733     def addFunction(self, function): 
    734         '''Adds the function to the factory. Most functions have no state, so 
    735         the singleton model used here is typically desirable. The factory will 
    736         not enforce the requirement that a Target or Condition matching  
    737         function must be boolean. 
    738          
    739         @param function the Function to add to the factory 
    740         ''' 
    741         raise NotImplementedError() 
    742          
    743     def addAbstractFunction(self, functionProxy, identity): 
    744         '''Adds the abstract function proxy to the factory. This is used for 
    745         those functions which have state, or change behaviour (for instance 
    746         the standard map function, which changes its return type based on 
    747         how it is used).  
    748          
    749         @param proxy the FunctionProxy to add to the factory 
    750         @param identity the function's identifier 
    751         ''' 
    752         raise NotImplementedError()         
    753      
    754     def getSupportedFunctions(self): 
    755         '''Returns the function identifiers supported by this factory. 
    756          
    757         @return a Set of Strings''' 
    758         raise NotImplementedError() 
    759  
    760     def createFunction(self, identity): 
    761         '''Tries to get an instance of the specified function. 
    762          
    763         @param identity the name of the function 
    764         '''        
    765         raise NotImplementedError() 
    766      
    767     def createAbstractFunction(self, identity, root): 
    768         '''Tries to get an instance of the specified abstract function. 
    769          
    770         @param identity the name of the function 
    771         @param root the DOM root containing info used to create the function 
    772         ''' 
    773         raise NotImplementedError() 
    774  
    775  
    776 class FunctionFactoryProxy(XacmlBase): 
    777     '''A simple proxy interface used to install new FunctionFactorys. 
    778     The three kinds of factory (Target, Condition, and General) are tied 
    779     together in this interface because implementors writing new factories 
    780     should always implement all three types and provide them together''' 
    781     def getTargetFactory(): 
    782         raise NotImplementedError() 
    783  
    784     def getConditionFactory(): 
    785         raise NotImplementedError() 
    786  
    787     def getGeneralFactory(): 
    788         raise NotImplementedError() 
    789  
    790  
    791 class BasicFunctionFactoryProxy(FunctionFactoryProxy): 
    792     '''A simple utility class that manages triples of function factories.''' 
    793      
    794     # the triple of factories 
    795     targetFactory = None 
    796     conditionFactory = None 
    797     generalFactory = None 
    798  
    799     def __init__(targetFactory, conditionFactory, generalFactory):  
    800         '''Creates a new proxy. 
    801          
    802         @param targetFactory the target factory provided by this proxy 
    803         @param conditionFactory the target condition provided by this proxy 
    804         @param generalFactory the general factory provided by this proxy 
    805         ''' 
    806         self.targetFactory = targetFactory 
    807         self.conditionFactory = conditionFactory 
    808         self.generalFactory = generalFactory 
    809      
    810     def getTargetFactory(): 
    811         return targetFactory 
    812  
    813     def getConditionFactory(): 
    814         return conditionFactory 
    815  
    816     def getGeneralFactory(): 
    817         return generalFactory 
    818      
    819  
    820 class BaseFunctionFactory(FunctionFactory): 
    821     '''This is a basic implementation of <code>FunctionFactory</code>. It 
    822     implements the insertion and retrieval methods, but it doesn't actually 
    823     setup the factory with any functions. It also assumes a certain model 
    824     with regard to the different kinds of functions (Target, Condition, and 
    825     General). For this reason, you may want to re-use this class, or you  
    826     may want to extend FunctionFactory directly, if you're writing a new 
    827     factory implementation. 
    828      
    829     Note that while this class is thread-safe on all creation methods, it 
    830     is not safe to add support for a new function while creating an instance 
    831     of a function. This follows from the assumption that most people will 
    832     initialize these factories up-front, and then start processing without 
    833     ever modifying the factories. If you need these mutual operations to 
    834     be thread-safe, then you should write a wrapper class that implements 
    835     the right synchronization. 
    836     ''' 
    837      
    838     def __init__(self,  
    839                  superset=None,  
    840                  supportedFunctions=[], 
    841                  supportedAbstractFunctions={}): 
    842         '''Sets a "superset factory". This is useful since 
    843         the different function factories (Target, Condition, and General) 
    844         have a superset relationship (Condition functions are a superset 
    845         of Target functions, etc.). Adding a function to this factory will 
    846         automatically add the same function to the superset factory. 
    847  
    848         Constructor that defines the initial functions supported by this 
    849         factory but doesn't use a superset factory. 
    850  
    851         Constructor that defines the initial functions supported by this 
    852         factory but doesn't use a superset factory. 
    853  
    854         Constructor that defines the initial functions supported by this 
    855         factory and uses a superset factory. Note that the functions 
    856         supplied here are not propagated up to the superset factory, so 
    857         you must either make sure the superset factory is correctly 
    858         initialized or use BaseFunctionFactory(FunctionFactory) 
    859         and then manually add each function. 
    860         
    861         @param supportedFunctions a Set of Functions 
    862         @param supportedAbstractFunctions a mapping from URI to 
    863                                           FunctionProxy 
    864          
    865         @param supportedFunctions a Set of Functions 
    866         @param supportedAbstractFunctions a mapping from URI to FunctionProxy 
    867          
    868         @param superset the superset factory or None''' 
    869          
    870         # the backing maps for the Function objects 
    871         self.functionMap = {} 
    872      
    873         # the superset factory chained to this factory 
    874         self.superset = superset 
    875       
    876         for function in supportedFunctions: 
    877             self.functionMap[function.functionId] = function 
    878          
    879         for id in supportedAbstractFunctions.keys(): 
    880             proxy = supportedAbstractFunctions.get(id) 
    881             self.functionMap[id] = proxy 
    882   
    883     def addFunction(self, function): 
    884         '''Adds the function to the factory. Most functions have no state, so 
    885         the singleton model used here is typically desirable. The factory will 
    886         not enforce the requirement that a Target or Condition matching  
    887         function must be boolean. 
    888          
    889         @param function the Function to add to the factory 
    890         @raise TypeError if the function's identifier is already used or if the 
    891         function is non-boolean (when this is a Target or Condition factory) 
    892         ''' 
    893         id = function.functionId 
    894  
    895         # make sure this doesn't already exist 
    896         if id in self.functionMap: 
    897             raise TypeError("function %s already exists" % id) 
    898  
    899         # add to the superset factory 
    900         if self.superset != None: 
    901             self.superset.addFunction(function) 
    902  
    903         # Add to this factory 
    904         self.functionMap[id] = function 
    905      
    906          
    907     def addAbstractFunction(self, proxy, id): 
    908         '''Adds the abstract function proxy to the factory. This is used for 
    909         those functions which have state, or change behaviour (for instance 
    910         the standard map function, which changes its return type based on 
    911         how it is used).  
    912          
    913         @param proxy: the FunctionProxy to add to the factory 
    914         @param id: the function's identifier 
    915          
    916         @raise TypeError if the function's identifier is already used''' 
    917  
    918         # make sure this doesn't already exist 
    919         if id in self.functionMap: 
    920             raise TypeError("function already exists") 
    921  
    922         # add to the superset factory 
    923         if self.superset != None: 
    924             self.superset.addAbstractFunction(proxy, id) 
    925  
    926         # finally, add to this factory 
    927         functionMap[id] = proxy 
    928      
    929  
    930     def getSupportedFunctions(self):  
    931         '''Returns the function identifiers supported by this factory. 
    932          
    933         @return a list of strings''' 
    934      
    935         functions = self.functionMap.keys() 
    936  
    937         if self.superset != None: 
    938             functions += self.superset.getSupportedFunctions() 
    939  
    940         return functions 
    941      
    942  
    943     def createFunction(self, identity): 
    944         '''Tries to get an instance of the specified function. 
    945          
    946         @param identity the name of the function 
    947          
    948         @throws UnknownIdentifierException if the name isn't known 
    949         @throws FunctionTypeException if the name is known to map to an 
    950                                       abstract function, and should therefore 
    951                                       be created through createAbstractFunction 
    952         ''' 
    953         entry = self.functionMap.get(identity) 
    954         if entry is not None: 
    955             if isinstance(entry, Function):  
    956                 return entry 
    957             else: 
    958                 # this is actually a proxy, which means the other create 
    959                 # method should have been called 
    960                 raise FunctionTypeException("function is abstract")     
    961         else: 
    962             # we couldn't find a match 
    963             raise UnknownIdentifierException("functions of type %s are not " 
    964                                              "supported by this factory" %  
    965                                              identity)         
    966      
    967      
    968     def createAbstractFunction(identity, root): 
    969         '''Tries to get an instance of the specified abstract function. 
    970          
    971         @param identity the name of the function 
    972         @param root the DOM root containing info used to create the function 
    973         @param xpathVersion the version specified in the containing policy, or 
    974                             None if no version was specified 
    975          
    976         @throws UnknownIdentifierException if the name isn't known 
    977         @throws FunctionTypeException if the name is known to map to a 
    978                                       concrete function, and should therefore 
    979                                       be created through createFunction 
    980         @throws ParsingException if the function can't be created with the 
    981                                  given inputs''' 
    982      
    983         entry = self.functionMap.get(identity) 
    984         if entry is not None: 
    985             if isinstance(entry, FunctionProxy):  
    986                 try:  
    987                     return entry.getInstance(root) 
    988                  
    989                 except Exception, e: 
    990                     raise ParsingException("Couldn't create abstract function " 
    991                                            "%s: %s" % identity, e)       
    992             else: 
    993                 # this is actually a concrete function, which means that 
    994                 # the other create method should have been called 
    995                 raise FunctionTypeException("function is concrete") 
    996              
    997         else: 
    998             raise UnknownIdentifierException("Abstract functions of type %s " 
    999                                              "are not supported by this " 
    1000                                              "factory" % identity) 
    1001  
    1002  
    1003 class StandardFunctionFactory(BaseFunctionFactory): 
    1004     '''This factory supports the standard set of functions specified in XACML 
    1005     1.0 and 1.1. It is the default factory used by the system, and imposes 
    1006     a singleton pattern insuring that there is only ever one instance of 
    1007     this class. 
    1008     <p> 
    1009     Note that because this supports only the standard functions, this 
    1010     factory does not allow the addition of any other functions. If you call 
    1011     addFunction on an instance of this class, an exception 
    1012     will be thrown. If you need a standard factory that is modifiable, 
    1013     you can either create a new BaseFunctionFactory (or some 
    1014     other implementation of FunctionFactory) populated with 
    1015     the standard functions from getStandardFunctions or 
    1016     you can use getNewFactoryProxy to get a proxy containing 
    1017     a new, modifiable set of factories.''' 
    1018  
    1019  
    1020     # the three singleton instances 
    1021     targetFactory = None 
    1022     conditionFactory = None 
    1023     generalFactory = None 
    1024  
    1025     # the three function sets/maps that we use internally 
    1026     targetFunctions = None 
    1027     conditionFunctions = None 
    1028     generalFunctions = None 
    1029  
    1030     targetAbstractFunctions = None 
    1031     conditionAbstractFunctions = None 
    1032     generalAbstractFunctions = None 
    1033  
    1034     # the set/map used by each singleton factory instance 
    1035     supportedFunctions = None 
    1036     supportedAbstractFunctions = None 
    1037  
    1038      
    1039     def __init__(self, supportedFunctions, supportedAbstractFunctions):  
    1040         '''Creates a new StandardFunctionFactory, making sure that the default 
    1041         maps are initialized correctly. Standard factories can't be modified, 
    1042         so there is no notion of supersetting since that's only used for 
    1043         correctly propagating new functions.''' 
    1044         super(StandardFunctionFactory, self).__init__(supportedFunctions,  
    1045                                                     supportedAbstractFunctions) 
    1046  
    1047         self.supportedFunctions = supportedFunctions 
    1048         self.supportedAbstractFunctions = supportedAbstractFunctions 
    1049      
    1050  
    1051      
    1052      
    1053     def _initTargetFunctions(self):  
    1054         '''Private initializer for the target functions. This is only ever 
    1055         called once.''' 
    1056         log.info("Initializing standard Target functions") 
    1057  
    1058         # Emulate a list with unique items using a dict with only the keys set 
    1059         StandardFunctionFactory.targetFunctions = {} 
    1060  
    1061         # add EqualFunction 
    1062         StandardFunctionFactory.targetFunctions.fromkeys( 
    1063                                     EqualFunction.supportedIdentifiers) 
    1064  
    1065         # add LogicalFunction 
    1066         StandardFunctionFactory.targetFunctions.fromkeys( 
    1067                                     LogicalFunction.supportedIdentifiers) 
    1068          
    1069         # add NOfFunction 
    1070         StandardFunctionFactory.targetFunctions.fromkeys( 
    1071                                     NOfFunction.supportedIdentifiers) 
    1072          
    1073         # add NotFunction 
    1074         StandardFunctionFactory.targetFunctions.fromkeys( 
    1075                                     NotFunction.supportedIdentifiers) 
    1076          
    1077         # add ComparisonFunction 
    1078         StandardFunctionFactory.targetFunctions.fromkeys( 
    1079                                     ComparisonFunction.supportedIdentifiers) 
    1080  
    1081         # add MatchFunction 
    1082         StandardFunctionFactory.targetFunctions.fromkeys( 
    1083                                     MatchFunction.supportedIdentifiers) 
    1084  
    1085         StandardFunctionFactory.targetAbstractFunctions = {} 
    1086      
    1087      
    1088     def _initConditionFunctions(self):  
    1089         '''Private initializer for the condition functions. This is only ever 
    1090         called once.''' 
    1091         log.info("Initializing standard Condition functions") 
    1092  
    1093         if StandardFunctionFactory.targetFunctions is None: 
    1094             self._initTargetFunctions() 
    1095  
    1096         StandardFunctionFactory.conditionFunctions = \ 
    1097             StandardFunctionFactory.targetFunctions.copy() 
    1098  
    1099         # add condition functions from BagFunction 
    1100         conditionFunctions.fromkeys(ConditionBagFunction.supportedIdentifiers) 
    1101          
    1102         # add condition functions from SetFunction 
    1103         conditionFunctions.fromkeys(ConditionSetFunction.supportedIdentifiers) 
    1104          
    1105         # add condition functions from HigherOrderFunction 
    1106         conditionFunctions.fromkeys(HigherOrderFunction.supportedIdentifiers) 
    1107  
    1108         StandardFunctionFactory.conditionAbstractFunctions = \ 
    1109             StandardFunctionFactory.targetAbstractFunctions.copy() 
    1110      
    1111  
    1112     def _initGeneralFunctions(self):      
    1113         '''Private initializer for the general functions. This is only ever 
    1114         called once.''' 
    1115      
    1116         log.info("Initializing standard General functions") 
    1117  
    1118         if StandardFunctionFactory.conditionFunctions is None: 
    1119             self._initConditionFunctions() 
    1120  
    1121         StandardFunctionFactory.generalFunctions = \ 
    1122             StandardFunctionFactory.conditionFunctions.copy() 
    1123  
    1124         # add AddFunction 
    1125         StandardFunctionFactory.generalFunctions.fromkeys( 
    1126             AddFunction.supportedIdentifiers) 
    1127              
    1128         # add SubtractFunction 
    1129         StandardFunctionFactory.generalFunctions.fromkeys( 
    1130             SubtractFunction.supportedIdentifiers) 
    1131              
    1132         # add MultiplyFunction 
    1133         StandardFunctionFactory.generalFunctions.fromkeys( 
    1134             MultiplyFunction.supportedIdentifiers) 
    1135              
    1136         # add DivideFunction 
    1137         StandardFunctionFactory.generalFunctions.fromkeys( 
    1138             DivideFunction.supportedIdentifiers) 
    1139              
    1140         # add ModFunction 
    1141         StandardFunctionFactory.generalFunctions.fromkeys( 
    1142             ModFunction.supportedIdentifiers) 
    1143          
    1144         # add AbsFunction 
    1145         StandardFunctionFactory.generalFunctions.fromkeys( 
    1146             AbsFunction.supportedIdentifiers) 
    1147              
    1148         # add RoundFunction 
    1149         StandardFunctionFactory.generalFunctions.fromkeys( 
    1150             RoundFunction.supportedIdentifiers) 
    1151              
    1152         # add FloorFunction 
    1153         StandardFunctionFactory.generalFunctions.fromkeys( 
    1154             FloorFunction.supportedIdentifiers) 
    1155          
    1156         # add DateMathFunction 
    1157         StandardFunctionFactory.generalFunctions.fromkeys( 
    1158             DateMathFunction.supportedIdentifiers) 
    1159              
    1160         # add general functions from BagFunction 
    1161         StandardFunctionFactory.generalFunctions.fromkeys( 
    1162             GeneralBagFunction.supportedIdentifiers) 
    1163              
    1164         # add NumericConvertFunction 
    1165         StandardFunctionFactory.generalFunctions.fromkeys( 
    1166             NumericConvertFunction.supportedIdentifiers) 
    1167              
    1168         # add StringNormalizeFunction 
    1169         StandardFunctionFactory.generalFunctions.fromkeys( 
    1170             StringNormalizeFunction.supportedIdentifiers) 
    1171          
    1172         # add general functions from SetFunction 
    1173         StandardFunctionFactory.generalFunctions.fromkeys( 
    1174             GeneralSetFunction.supportedIdentifiers) 
    1175              
    1176         StandardFunctionFactory.generalAbstractFunctions = \ 
    1177             StandardFunctionFactory.conditionAbstractFunctions.copy() 
    1178  
    1179         # Add the map function's proxy 
    1180         StandardFunctionFactory.generalAbstractFunctions[ 
    1181                                     MapFunction.NAME_MAP] = MapFunctionProxy() 
    1182      
    1183     @classmethod  
    1184     def getTargetFactory(cls):  
    1185         '''Returns a FunctionFactory that will only provide those functions  
    1186         that are usable in Target matching. This method enforces a singleton 
    1187         model, meaning that this always returns the same instance, creating 
    1188         the factory if it hasn't been requested before. This is the default 
    1189         model used by the FunctionFactory, ensuring quick 
    1190         access to this factory. 
    1191          
    1192         @return a FunctionFactory for target functions''' 
    1193         if StandardFunctionFactory.targetFactory is None:  
    1194             if StandardFunctionFactory.targetFunctions is None: 
    1195                 StandardFunctionFactory._initTargetFunctions() 
    1196                  
    1197             if StandardFunctionFactory.targetFactory is None: 
    1198                 StandardFunctionFactory.targetFactory=StandardFunctionFactory( 
    1199                             StandardFunctionFactory.targetFunctions, 
    1200                             StandardFunctionFactory.targetAbstractFunctions) 
    1201          
    1202         return StandardFunctionFactory.targetFactory 
    1203  
    1204      
    1205     @classmethod 
    1206     def getConditionFactory(cls):  
    1207         '''Returns a FuntionFactory that will only provide those functions that 
    1208         are usable in the root of the Condition. These Functions are a 
    1209         superset of the Target functions. This method enforces a singleton 
    1210         model, meaning that this always returns the same instance, creating 
    1211         the factory if it hasn't been requested before. This is the default 
    1212         model used by the FunctionFactory, ensuring quick 
    1213         access to this factory. 
    1214      
    1215         @return a FunctionFactory for condition functions 
    1216         ''' 
    1217         if StandardFunctionFactory.conditionFactory is None: 
    1218             if StandardFunctionFactory.conditionFunctions is None: 
    1219                 StandardFunctionFactory._initConditionFunctions() 
    1220                  
    1221             if StandardFunctionFactory.conditionFactory is None: 
    1222                 StandardFunctionFactory.conditionFactory = \ 
    1223                     StandardFunctionFactory( 
    1224                            StandardFunctionFactory.conditionFunctions, 
    1225                            StandardFunctionFactory.conditionAbstractFunctions)        
    1226  
    1227         return StandardFunctionFactory.conditionFactory 
    1228      
    1229  
    1230     @classmethod 
    1231     def getGeneralFactory(cls):  
    1232         '''Returns a FunctionFactory that provides access to all the functions. 
    1233         These Functions are a superset of the Condition functions. This method 
    1234         enforces a singleton model, meaning that this always returns the same 
    1235         instance, creating the factory if it hasn't been requested before. 
    1236         This is the default model used by the FunctionFactory, 
    1237         ensuring quick access to this factory. 
    1238          
    1239         @return a FunctionFactory for all functions''' 
    1240      
    1241         if StandardFunctionFactory.generalFactory is None: 
    1242             if StandardFunctionFactory.generalFunctions is None: 
    1243                 StandardFunctionFactory._initGeneralFunctions() 
    1244                  
    1245                 StandardFunctionFactory.generalFactory = \ 
    1246                     StandardFunctionFactory( 
    1247                             StandardFunctionFactory.generalFunctions, 
    1248                             StandardFunctionFactory.generalAbstractFunctions) 
    1249                  
    1250         return StandardFunctionFactory.generalFactory 
    1251  
    1252  
    1253     def getStandardFunctions(self): 
    1254         '''Returns the set of functions that this standard factory supports. 
    1255          
    1256         @return a Set of Functions''' 
    1257         return tuple(self.supportedFunctions.keys()) 
    1258          
    1259     def getStandardAbstractFunctions(self): 
    1260         '''Returns the set of abstract functions that this standard factory 
    1261         supports as a mapping of identifier to proxy. 
    1262          
    1263         @return a Map mapping URIs to FunctionProxys''' 
    1264         return tuple(self.supportedAbstractFunctions.keys()) 
    1265      
    1266      
    1267     @classmethod 
    1268     def getNewFactoryProxy(cls):  
    1269         '''A convenience method that returns a proxy containing newly created 
    1270         instances of BaseFunctionFactorys that are correctly 
    1271         supersetted and contain the standard functions and abstract functions. 
    1272         These factories allow adding support for new functions. 
    1273          
    1274         @return a new proxy containing new factories supporting the standard 
    1275         functions''' 
    1276          
    1277         general = StandardFunctionFactory.getGeneralFactory() 
    1278              
    1279         newGeneral=BaseFunctionFactory(general.getStandardFunctions(), 
    1280                                        general.getStandardAbstractFunctions()) 
    1281  
    1282         condition = StandardFunctionFactory.getConditionFactory() 
    1283          
    1284         newCondition = BaseFunctionFactory(newGeneral, 
    1285                                     condition.getStandardFunctions(), 
    1286                                     condition.getStandardAbstractFunctions()) 
    1287  
    1288         target = StandardFunctionFactory.getTargetFactory() 
    1289         newTarget = BaseFunctionFactory(newCondition, 
    1290                                     target.getStandardFunctions(), 
    1291                                     target.getStandardAbstractFunctions()) 
    1292  
    1293         return BasicFunctionFactoryProxy(newTarget, newCondition, newGeneral) 
    1294      
    1295  
    1296      
    1297      
    1298     def addFunction(self, function): 
    1299         '''Always throws an exception, since support for new functions may not  
    1300         be added to a standard factory. 
    1301          
    1302         @param function the Function to add to the factory        
    1303         @raise NotImplementedError''' 
    1304      
    1305         raise NotImplementedError("a standard factory cannot support new " 
    1306                                   "functions") 
    1307      
    1308      
    1309     def addAbstractFunction(self, proxy, identity): 
    1310         '''Always throws an exception, since support for new functions may not  
    1311         be added to a standard factory. 
    1312          
    1313         @param proxy the FunctionProxy to add to the factory 
    1314         @param identity the function's identifier 
    1315          
    1316         @raise NotImplementedError always''' 
    1317         raise NotImplementedError("a standard factory cannot support new " 
    1318                                   "functions") 
    1319  
    1320356     
    1321357class Status(XacmlBase): 
Note: See TracChangeset for help on using the changeset viewer.