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
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
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
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
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
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