1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
# Copyright (c) 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License 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.
import sys
import yaql
from yaql.language import exceptions
from yaql.language import utils
class Expression(object):
def __call__(self, receiver, context, engine):
pass
class Function(Expression):
def __init__(self, name, *args):
self.name = name
self.args = args
self.uses_receiver = True
def __call__(self, receiver, context, engine):
return context(self.name, engine, receiver, context)(*self.args)
def __str__(self):
return '{0}({1})'.format(self.name, ', '.join(map(str, self.args)))
class BinaryOperator(Function):
def __init__(self, op, obj1, obj2, alias):
if alias is None:
func_name = '#operator_' + op
else:
func_name = '*' + alias
self.operator = op
super(BinaryOperator, self).__init__(func_name, obj1, obj2)
self.uses_receiver = False
class UnaryOperator(Function):
def __init__(self, op, obj, alias):
if alias is None:
func_name = '#unary_operator_' + op
else:
func_name = '*' + alias
self.operator = op
super(UnaryOperator, self).__init__(func_name, obj)
self.uses_receiver = False
class IndexExpression(Function):
def __init__(self, value, *args):
super(IndexExpression, self).__init__('#indexer', value, *args)
self.uses_receiver = False
class ListExpression(Function):
def __init__(self, *args):
super(ListExpression, self).__init__('#list', *args)
self.uses_receiver = False
class MapExpression(Function):
def __init__(self, *args):
super(MapExpression, self).__init__('#map', *args)
self.uses_receiver = False
class GetContextValue(Function):
def __init__(self, path):
super(GetContextValue, self).__init__('#get_context_data', path)
self.path = path
self.uses_receiver = False
def __str__(self):
return self.path.value
class Constant(Expression):
def __init__(self, value):
self.value = value
self.uses_receiver = False
def __str__(self):
if isinstance(self.value, str):
return "'{0}'".format(self.value)
return str(self.value)
def __call__(self, receiver, context, engine):
return self.value
class KeywordConstant(Constant):
pass
class Wrap(Expression):
def __init__(self, expression):
self.expr = expression
self.uses_receiver = False
def __str__(self):
return str(self.expr)
def __call__(self, receiver, context, engine):
return self.expr(receiver, context, engine)
class MappingRuleExpression(Expression):
def __init__(self, source, destination):
self.source = source
self.destination = destination
self.uses_receiver = False
def __str__(self):
return u'{0} => {1}'.format(self.source, self.destination)
def __call__(self, receiver, context, engine):
return utils.MappingRule(
self.source(receiver, context, engine),
self.destination(receiver, context, engine))
class Statement(Function):
def __init__(self, expression, engine):
self.expression = expression
self.uses_receiver = False
self.engine = engine
super(Statement, self).__init__('#finalize', expression)
def __call__(self, receiver, context, engine):
if not context.collect_functions('#finalize'):
context = context.create_child_context()
context.register_function(lambda x: x, name='#finalize')
try:
return super(Statement, self).__call__(receiver, context, engine)
except exceptions.WrappedException as e:
raise e.wrapped.with_traceback(sys.exc_info()[2])
def evaluate(self, data=utils.NO_VALUE, context=None):
if context is None or context is utils.NO_VALUE:
context = yaql.create_context()
if data is not utils.NO_VALUE:
if self.engine.options.get('yaql.convertInputData', True):
context['$'] = utils.convert_input_data(data)
else:
context['$'] = data
return self(utils.NO_VALUE, context, self.engine)
def __str__(self):
return str(self.expression)
|