Mercurial > paraspace
annotate paraspace/structpath.py @ 32:9bac21d401fe
Make get_parent() as a method of structpath.context
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 15 Jun 2011 02:03:38 +0800 |
parents | aed662c820d8 |
children | fe1ebf0c3d40 |
rev | line source |
---|---|
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
1 ## |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
2 # Implement a xpath liked query language. |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
3 # |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
4 class context(object): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
5 all_classes = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
6 class_instances = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
7 root = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
8 objs = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
9 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
10 def __init__(self, objs, ctx=None): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
11 if ctx: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
12 self.all_classes = ctx.all_classes |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
13 self.class_instances = ctx.class_instances |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
14 self.root = ctx.root |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
15 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
16 self.objs = objs |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
17 pass |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
18 |
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
19 def get_parent(self, obj): |
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
20 raise NotImplementedError, 'get_parent() is not implemented' |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
21 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
22 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
23 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
24 def _path_split(path): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
25 parts = [p.strip() |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
26 for p in path.split('/')] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
27 return parts |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
28 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
29 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
30 def _is_abs(path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
31 if len(path_parts) == 0: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
32 return False |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
33 return path_parts[0] == '' |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
34 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
35 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
36 def _rel_of_abs(path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
37 return path_parts[1:] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
38 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
39 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
40 def _is_class(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
41 return part.startswith('.') |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
42 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
43 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
44 def _class_name(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
45 return part[1:] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
46 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
47 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
48 def _is_parent_name(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
49 return part == '..' |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
50 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
51 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
52 def _obj_attr(obj, attrname): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
53 if isinstance(obj, list): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
54 idx = int(attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
55 return obj[idx] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
56 elif isinstance(obj, dict): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
57 key = eval(attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
58 return obj[key] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
59 return getattr(obj, attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
60 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
61 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
62 def _handle_path_part_obj(ctx, part, obj): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
63 if _is_parent_name(part): |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
64 new_objs = [ctx.get_parent(obj)] |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
65 elif _is_class(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
66 class_name = _class_name(part) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
67 new_objs = ctx.class_instances[class_name] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
68 else: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
69 new_objs = [_obj_attr(obj, part)] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
70 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
71 return new_objs |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
72 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
73 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
74 def _handle_path_part(ctx, part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
75 from itertools import chain |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
76 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
77 if not ctx.objs: |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
78 ctx = ctx.__class__([ctx.root], ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
79 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
80 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
81 objss = [_handle_path_part_obj(ctx, part, obj) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
82 for obj in ctx.objs] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
83 objs = [o for o in chain(*objss)] |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
84 new_ctx = ctx.__class__(objs, ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
85 return new_ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
86 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
87 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
88 def _handle_path_parts(ctx, path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
89 if _is_abs(path_parts): |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
90 ctx = ctx.__class__([ctx.root], ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
91 path_parts = _rel_of_abs(path_parts) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
92 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
93 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
94 if len(path_parts) == 1 and path_parts[0] == '': |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
95 return ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
96 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
97 for path_part in path_parts: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
98 ctx = _handle_path_part(ctx, path_part) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
99 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
100 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
101 return ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
102 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
103 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
104 def find_objs_path(ctx, path): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
105 path_parts = _path_split(path) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
106 rctx = _handle_path_parts(ctx, path_parts) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
107 return rctx.objs |