-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubscription.py
More file actions
238 lines (178 loc) · 5.21 KB
/
Copy pathsubscription.py
File metadata and controls
238 lines (178 loc) · 5.21 KB
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
""" Attribute value types
Constaints that represent value types
"""
INT = 'INTEGER'
DOU = 'DOUBLE'
STR = 'STRING'
""" Operators
Constaints that represent operators
"""
IN = 'in'
LT = '<'
GT = '>'
LE = '<='
GE = '>='
EQ = '='
class AttributeAssignment:
def __init__(self, string):
self.rep = string
vals = string.split(',')
self.values = {}
for v in vals:
name,value = v.split('=')
valueType, valueString = value.split(':')
val = CreateType(valueType).Parse(valueString)
self.values[name] = val
def __getitem__(self, name):
return self.values[name]
def __repr__(self):
return self.rep
def has_key(self, name):
return self.values.has_key(name)
class Subscription:
""" Subcription will have the format as follows:
{[attribute value type],[attribute name],[operator],[value]}{[other constraints]}
"""
def __init__(self, data):
self.rep = data
self.attrConstraints = {}
for constraint in data.split('}{'):
constraint = constraint.strip('{}')
#Type,Name,Op,Val = constraint.split(',', 3)
#self.attrConstraints[Name] = AttributeConstraint(Type, Op, Val)
ac = AttributeConstraint(constraint)
self.attrConstraints[ac.attrName] = ac
self.count = len(self.attrConstraints)
def __repr__(self):
return self.rep
def Match(self, assignments):
""" Attribute assignments have format as follows:
[attribute name]=[attribute type]:[value],[other attribute assignment]
A AttributeAssignment object will handle this format
"""
#print self.attrConstraints
for name,constraint in self.attrConstraints.items():
print name, constraint
if not assignments.has_key(name):
return False
if not constraint.Match(assignments[name]):
return False
return True
@staticmethod
def FormatCheck(string):
""" Subscription format check
Subscriptions have the format as follows:
{[attribute value type],
[attribute name],
[operator],
[attribute value]}{other attribute constrants}
No white space is allowed
The sender of a subscription should strips all leading and trailing white spaces
"""
MIN_FIELD_NUM = 4
MAX_FIELD_NUM = 5
for c in string.split('}{'):
cons = c.split(',')
if len(cons) < MIN_FIELD_NUM or len(cons) > MAX_FIELD_NUM:
return False
for con in cons:
if len(con) == 0:
return False
return True
# operators
def CreateOperator(type):
if type == IN:
return OpIN()
if type == GT:
return OpGT()
if type == GE:
return OpGE()
if type == LT:
return OpLT()
if type == LE:
return OpLE()
if type == EQ:
return OpEQ()
class OpIN:
def Check(self, cons, val):
return val > cons[0] and val < cons[1]
def __repr__(self):
return IN
class OpEQ:
def Check(self, cons, val):
return val == cons
def __repr__(self):
return EQ
class OpGT:
def Check(self, cons, val):
return val > cons
def __repr__(self):
return GT
class OpGE:
def Check(self, cons, val):
return val >= cons
def __repr__(self):
return GE
class OpLT:
def Check(self, cons, val):
return val < cons
def __repr__(self):
return LT
class OpLE:
def Check(self, cons, val):
return val <= cons
def __repr__(self):
return LE
# Attribute value types
def CreateType(tp):
if tp == INT:
return TypeInteger()
if tp == DOU:
return TypeDouble()
if tp == STR:
return TypeString()
class TypeInteger:
def Parse(self, val):
return int(val)
def __repr__(self):
return INTEGER
class TypeDouble:
def Parse(self, val):
return float(val)
def __repr__(self):
return DOUBLE
class TypeString:
def Parse(self, val):
return val
def __repr__(self):
return STRING
class AttributeConstraint:
""" AttributeConstraint
A 4-tuple with type, name, op, value
"""
#def __init__(self, tp, op, val):
def __init__(self, *rep):
if len(rep) > 1:
tp, name, op, val = rep
self.rep = ','.join(rep)
else:
tp, name, op, val = rep[0].split(',', 3)
self.rep = rep[0]
self.attrName = name
self.optr = CreateOperator(op)
if op == IN:
vals = val.split(',')
self.value = (CreateType(tp).Parse(vals[0]), CreateType(tp).Parse(vals[1]))
else:
self.value = CreateType(tp).Parse(val)
def __repr__(self):
return self.rep
def Match(self, val):
return self.optr.Check(self.value, val)
if __name__ == '__main__':
sub = Subscription('{INTEGER,age,in,1,3}')
aa = AttributeAssignment("age=INTEGER:2")
if sub.Match(aa):
print 'correct'
print str(aa)
print str(sub)