Пример #1
0
    def encoderModel(self, ofType, getter=None, exploit=None):
        '''
        Create a encode exploit for a model.
        
        @param ofType: TypeModel
            The type model to encode.
        @param getter: callable(object) -> object|None
            The getter used to get the model from the value object.
        @param exploit: EncodeObject|None
            The encode model to use.
        @return: callable(**data)
            The exploit that provides the model encoding.
        '''
        assert isinstance(ofType, TypeModel), 'Invalid type model %s' % ofType

        typesProps = list(ofType.childTypes())
        if ofType.hasId(): typesProps.remove(ofType.childTypeId())
        typesProps.sort(key=lambda typeProp: typeProp.property)
        typesProps.sort(key=self.sortTypePropertyKey)
        if ofType.hasId(): typesProps.insert(0, ofType.childTypeId())

        exploit = exploit or EncodeObject(ofType.container.name, getter)
        assert isinstance(exploit, EncodeObject), 'Invalid encode object %s' % exploit

        for typeProp in typesProps:
            assert isinstance(typeProp, TypeModelProperty)

            self.registerProperty(exploit, typeProp, getterOnObjIfIn(typeProp.property, typeProp))

        return exploit
Пример #2
0
    def encoderModel(self, ofType, getter=None, exploit=None):
        '''
        Create a encode exploit for a model.
        
        @param ofType: TypeModel
            The type model to encode.
        @param getter: callable(object) -> object|None
            The getter used to get the model from the value object.
        @param exploit: EncodeObject|None
            The encode model to use.
        @return: callable(**data)
            The exploit that provides the model encoding.
        '''
        assert isinstance(ofType, TypeModel), 'Invalid type model %s' % ofType

        typesProps = list(ofType.propertyTypes())
        if ofType.hasId(): typesProps.remove(ofType.propertyTypeId())
        typesProps.sort(key=lambda typeProp: typeProp.property)
        typesProps.sort(key=self.sortTypePropertyKey)
        if ofType.hasId(): typesProps.insert(0, ofType.propertyTypeId())

        exploit = exploit or EncodeObject(ofType.container.name, getter)
        assert isinstance(exploit, EncodeObject), 'Invalid encode object %s' % exploit

        for typeProp in typesProps:
            assert isinstance(typeProp, TypeModelProperty)

            self.registerProperty(exploit, typeProp, getterOnObjIfIn(typeProp.property, typeProp))

        return exploit
Пример #3
0
    def encodeCriteria(self, typeCriteria, getterCriteria):
        '''
        Exploit that provides the encoding for the criteria.
        
        @param typeCriteria: TypeCriteria
            The criteria type to encode.
        @param getterCriteria: callable(object) -> object
            The getter used to get the criteria from the value object.
        @return: callable(**data)
            The exploit that provides the criteria encoding.
        '''
        assert isinstance(
            typeCriteria,
            TypeCriteria), 'Invalid criteria type %s' % typeCriteria
        assert callable(getterCriteria), 'Invalid getter %s' % getterCriteria
        criteria = typeCriteria.container
        assert isinstance(criteria, Criteria)

        if issubclass(typeCriteria.clazz, AsOrdered):
            exclude = ('ascending', 'priority')
        else:
            exclude = ()

        children, childrenMain = OrderedDict(), OrderedDict()
        for prop, typeProp in sorted(criteria.properties.items(),
                                     key=lambda item: item[0]):
            if prop in exclude: continue
            propEncode = self.encodePrimitive(
                typeProp,
                getterOnObjIfIn(prop, typeCriteria.propertyTypeFor(prop)))
            if prop in criteria.main: childrenMain[prop] = propEncode
            else: children[prop] = propEncode

        exploitPath = self.encodePath(children) if children else None
        exploitPathMain = self.encodePath(
            childrenMain) if childrenMain else None

        def exploit(value, target, path='', **data):
            assert isinstance(path, str), 'Invalid path %s' % path
            assert isinstance(target, deque), 'Invalid target %s' % target

            if value is not SAMPLE:
                value = getterCriteria(value)
                if value is None: return
            data.update(path=path, value=value)
            if exploitPathMain:
                targetMain = deque()
                exploitPathMain(target=targetMain, **data)
                if targetMain:
                    targetMainIter = iter(targetMain)
                    _name, valueMain = next(targetMainIter)
                    for _name, val in targetMainIter:
                        if valueMain != val:
                            target.extend(targetMain)
                            break
                    else:
                        target.append((path, valueMain))
            if exploitPath: exploitPath(target=target, **data)

        return exploit
Пример #4
0
    def encodeCriteria(self, typeCriteria, getterCriteria):
        """
        Exploit that provides the encoding for the criteria.
        
        @param typeCriteria: TypeCriteria
            The criteria type to encode.
        @param getterCriteria: callable(object) -> object
            The getter used to get the criteria from the value object.
        @return: callable(**data)
            The exploit that provides the criteria encoding.
        """
        assert isinstance(typeCriteria, TypeCriteria), "Invalid criteria type %s" % typeCriteria
        assert callable(getterCriteria), "Invalid getter %s" % getterCriteria
        criteria = typeCriteria.container
        assert isinstance(criteria, Criteria)

        if issubclass(typeCriteria.clazz, AsOrdered):
            exclude = ("ascending", "priority")
        else:
            exclude = ()

        children, childrenMain = OrderedDict(), OrderedDict()
        for prop, typeProp in sorted(criteria.properties.items(), key=lambda item: item[0]):
            if prop in exclude:
                continue
            propEncode = self.encodePrimitive(typeProp, getterOnObjIfIn(prop, typeCriteria.propertyTypeFor(prop)))
            if prop in criteria.main:
                childrenMain[prop] = propEncode
            else:
                children[prop] = propEncode

        exploitPath = self.encodePath(children) if children else None
        exploitPathMain = self.encodePath(childrenMain) if childrenMain else None

        def exploit(value, target, path="", **data):
            assert isinstance(path, str), "Invalid path %s" % path
            assert isinstance(target, deque), "Invalid target %s" % target

            if value is not SAMPLE:
                value = getterCriteria(value)
                if value is None:
                    return
            data.update(path=path, value=value)
            if exploitPathMain:
                targetMain = deque()
                exploitPathMain(target=targetMain, **data)
                if targetMain:
                    targetMainIter = iter(targetMain)
                    _name, valueMain = next(targetMainIter)
                    for _name, val in targetMainIter:
                        if valueMain != val:
                            target.extend(targetMain)
                            break
                    else:
                        target.append((path, valueMain))
            if exploitPath:
                exploitPath(target=target, **data)

        return exploit
Пример #5
0
    def encodeInvoker(self, invoker):
        '''
        Create an encode exploit for the invoker.
        
        @param invoker: Invoker
            The invoker to create a parameters encoder for.
        @return: callable(**data)
            The exploit that provides the invoker encoding.
        '''
        assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker

        children, ordered = OrderedDict(), OrderedDict()
        for inp in invoker.inputs:
            assert isinstance(inp, Input)
            typeInp = inp.type
            assert isinstance(typeInp, Type)

            if typeInp.isPrimitive:
                children[inp.name] = self.encodePrimitive(typeInp, getterOnDict(inp.name))

            elif isinstance(typeInp, TypeQuery):
                assert isinstance(typeInp, TypeQuery)

                childrenQuery, orderedQuery, getterQuery = OrderedDict(), OrderedDict(), getterOnDict(inp.name)
                for nameEntry, classCriteria in typeInp.query.criterias.items():

                    getter = getterChain(getterQuery, getterOnObjIfIn(nameEntry, typeInp.childTypeFor(nameEntry)))
                    childrenQuery[nameEntry] = self.encodeCriteria(typeFor(classCriteria), getter)

                    if issubclass(classCriteria, AsOrdered):
                        orderedQuery[nameEntry] = self.encodeGetOrder(typeInp.childTypeFor(nameEntry), getterQuery)

                isUpdated = False
                if invoker.output.isOf(typeInp.owner):
                    # If the query is a main query and also there is no name conflict then add the query children to
                    # the main children
                    if set(childrenQuery.keys()).isdisjoint(children.keys()) and set(orderedQuery).isdisjoint(ordered):
                        isUpdated = True
                        children.update(childrenQuery)
                        ordered.update(orderedQuery)

                if not isUpdated:
                    children[inp.name] = self.encodePath(childrenQuery)
                    ordered[inp.name] = self.encodePath(orderedQuery)

        exploitOrder = None
        if ordered:
            if self.nameOrderAsc in children: log.error('Name conflict for \'%s\' in %s', self.nameOrderAsc, invoker)
            elif self.nameOrderDesc in children: log.error('Name conflict for \'%s\' in %s', self.nameOrderDesc, invoker)
            else: exploitOrder = self.encodeOrder(self.encodePath(ordered))
        exploitPath = self.encodePath(children)
        def exploit(**data):
            target = deque()
            data.update(target=target)
            exploitPath(**data)
            if exploitOrder: exploitOrder(**data)
            return target

        return exploit
Пример #6
0
    def encodeInvoker(self, invoker):
        '''
        Create an encode exploit for the invoker.
        
        @param invoker: Invoker
            The invoker to create a parameters encoder for.
        @return: callable(**data)
            The exploit that provides the invoker encoding.
        '''
        assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker

        children, ordered = OrderedDict(), OrderedDict()
        for inp in invoker.inputs:
            assert isinstance(inp, Input)
            typeInp = inp.type
            assert isinstance(typeInp, Type)

            if typeInp.isPrimitive:
                children[inp.name] = self.encodePrimitive(
                    typeInp, getterOnDict(inp.name))

            elif isinstance(typeInp, TypeQuery):
                assert isinstance(typeInp, TypeQuery)

                childrenQuery, orderedQuery, getterQuery = OrderedDict(
                ), OrderedDict(), getterOnDict(inp.name)
                for nameEntry, classCriteria in typeInp.query.criterias.items(
                ):

                    getter = getterChain(
                        getterQuery,
                        getterOnObjIfIn(
                            nameEntry,
                            typeInp.criteriaEntryTypeFor(nameEntry)))
                    childrenQuery[nameEntry] = self.encodeCriteria(
                        typeFor(classCriteria), getter)

                    if issubclass(classCriteria, AsOrdered):
                        orderedQuery[nameEntry] = self.encodeGetOrder(
                            typeInp.criteriaEntryTypeFor(nameEntry),
                            getterQuery)

                isUpdated = False
                if invoker.output.isOf(typeInp.owner):
                    # If the query is a main query and also there is no name conflict then add the query children to
                    # the main children
                    if set(childrenQuery.keys()).isdisjoint(children.keys(
                    )) and set(orderedQuery).isdisjoint(ordered):
                        isUpdated = True
                        children.update(childrenQuery)
                        ordered.update(orderedQuery)

                if not isUpdated:
                    children[inp.name] = self.encodePath(childrenQuery)
                    ordered[inp.name] = self.encodePath(orderedQuery)

        exploitOrder = None
        if ordered:
            if self.nameOrderAsc in children:
                log.error('Name conflict for \'%s\' in %s', self.nameOrderAsc,
                          invoker)
            elif self.nameOrderDesc in children:
                log.error('Name conflict for \'%s\' in %s', self.nameOrderDesc,
                          invoker)
            else:
                exploitOrder = self.encodeOrder(self.encodePath(ordered))
        exploitPath = self.encodePath(children)

        def exploit(**data):
            target = deque()
            data.update(target=target)
            exploitPath(**data)
            if exploitOrder: exploitOrder(**data)
            return target

        return exploit