gf-treevisitor 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ require 'pathname'
2
+
3
+ class DirProcessor
4
+
5
+ def initialize( dirname, &action )
6
+ @dirname = dirname
7
+ @processors = {}
8
+ @default_processor = action
9
+ end
10
+
11
+ def add_processor( re, &action )
12
+ @processors[ re ] = action
13
+ end
14
+
15
+ def run()
16
+ old_dirname = Dir.pwd
17
+ Dir.chdir( @dirname )
18
+ Dir["**/*"].each { |f|
19
+ pn = Pathname.new( f ).expand_path
20
+ # puts "#{self.class.name}#loadfromdir #{f}"
21
+ next if pn.directory?
22
+ process_file( pn )
23
+ }
24
+ Dir.chdir( old_dirname )
25
+ self
26
+ end
27
+
28
+ private
29
+
30
+ def process_file( pn )
31
+ # puts "file: #{f}"
32
+ pair = @processors.find { |re,action| re =~ pn.to_s }
33
+ unless pair.nil?
34
+ pair[1].call( pn )
35
+ else
36
+ @default_processor.call( pn ) if @default_processor
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,99 @@
1
+ class DirTreeWalker
2
+
3
+ def initialize( dirname )
4
+ @dirname = dirname
5
+ unless File.directory?( dirname )
6
+ raise "#{dirname} is not a directory!"
7
+ end
8
+
9
+ @visitor = nil
10
+ @ignore_dir_patterns = []
11
+ @inspect_file_patterns = []
12
+ @ignore_file_patterns = []
13
+ end
14
+
15
+ def add_ignore_dir( pattern )
16
+ @ignore_dir_patterns << pattern
17
+ end
18
+
19
+ def add_ignore_file( pattern )
20
+ @ignore_file_patterns << pattern
21
+ end
22
+
23
+ #
24
+ # quali file bisogna prendere in considerazione
25
+ # inspect opposto di ignore :-)
26
+ #
27
+ def add_inspect_file( pattern )
28
+ @inspect_file_patterns << pattern
29
+ end
30
+
31
+ def ignore_dir?( dirname )
32
+ basename = File.basename( dirname )
33
+ @ignore_dir_patterns.find{ |pattern|
34
+ basename == pattern
35
+ }
36
+ end
37
+
38
+ def ignore_file?( filename )
39
+ basename = File.basename( filename )
40
+ @ignore_file_patterns.find{ |pattern|
41
+ if pattern.kind_of? Regexp
42
+ pattern =~ basename
43
+ else
44
+ pattern == basename
45
+ end
46
+ }
47
+ end
48
+
49
+ def inspect_file?( filename )
50
+ return true if @inspect_file_patterns.empty?
51
+ basename = File.basename( filename )
52
+ @inspect_file_patterns.find{ |pattern|
53
+ if pattern.kind_of? Regexp
54
+ pattern =~ basename
55
+ else
56
+ pattern == basename
57
+ end
58
+ }
59
+ end
60
+
61
+ def run( treeNodeVisitor )
62
+ @visitor = treeNodeVisitor
63
+ process_directory( File.expand_path( @dirname ) )
64
+ end
65
+
66
+ private
67
+
68
+ #
69
+ # recurse on other directories
70
+ #
71
+ # def process_directory( parentNode, dirname )
72
+ def process_directory( dirname )
73
+ return if ignore_dir?( dirname )
74
+
75
+ @visitor.enter_treeNode( dirname )
76
+
77
+ Dir.entries( dirname ).each { |basename|
78
+ next if basename == "." or basename == ".."
79
+ pathname = File.join( dirname, basename )
80
+
81
+ if File.directory?( pathname )
82
+
83
+ # directory
84
+ if ! ignore_dir?( basename )
85
+ process_directory( pathname )
86
+ end
87
+
88
+ else
89
+
90
+ # file
91
+ if inspect_file?( basename ) && ! ignore_file?( basename )
92
+ @visitor.visit_leafNode( pathname )
93
+ end
94
+
95
+ end
96
+ }
97
+ @visitor.exit_treeNode( dirname )
98
+ end
99
+ end
@@ -0,0 +1,27 @@
1
+ # common
2
+ require "treevisitor/abs_node"
3
+
4
+ #
5
+ # Deriva da AbsNode
6
+ #
7
+ # definisce un metodo to_str
8
+ #
9
+ #
10
+ class LeafNode < AbsNode
11
+
12
+ def initialize( name, parent = nil )
13
+ super( name )
14
+ if parent
15
+ parent.add_leaf( self )
16
+ end
17
+ end
18
+
19
+ def accept( visitor )
20
+ visitor.visit_leafNode( self )
21
+ end
22
+
23
+ def to_str
24
+ name.to_str
25
+ end
26
+
27
+ end
@@ -0,0 +1,134 @@
1
+ # common
2
+ require 'treevisitor/leaf_node'
3
+
4
+ #
5
+ # Un treeNode e' come un AbsNode
6
+ # in piu' ha la possibilita' di contenere
7
+ # altri treeNode e LeafNode
8
+ #
9
+ # TreeNode @childs -1---n-> TreeNode
10
+ # @leaves -1---n-> LeafNode
11
+ #
12
+ class TreeNode < AbsNode
13
+
14
+ attr_reader :leaves
15
+ attr_reader :childs
16
+
17
+ def initialize( name, parent = nil )
18
+ @leaves = []
19
+ @childs = []
20
+ super( name )
21
+ if parent
22
+ parent.add_child( self )
23
+ end
24
+ end
25
+
26
+ def root?
27
+ @parent.nil?
28
+ end
29
+
30
+ #
31
+ # invalidate cached info
32
+ #
33
+ def invalidate
34
+ super
35
+ @childs.each{ |c| c.invalidate }
36
+ @leaves.each{ |l| l.invalidate }
37
+ end
38
+
39
+ def nr_nodes
40
+ nr = @leaves.length + @childs.length
41
+ @childs.inject( nr ) { |nr,c| nr + c.nr_nodes }
42
+ end
43
+
44
+ def nr_leaves
45
+ @leaves.length + @childs.inject(0) { |sum, child| sum + child.nr_leaves }
46
+ end
47
+
48
+ def nr_childs
49
+ @childs.length + @childs.inject(0) { |sum, child| sum + child.nr_childs }
50
+ end
51
+
52
+ def add_leaf( leaf )
53
+ return if leaf.parent == self
54
+ if not leaf.parent.nil?
55
+ leaf.remove_from_parent()
56
+ end
57
+ leaf.parent = self
58
+ if @leaves.length > 0
59
+ @leaves.last.next = leaf
60
+ leaf.prev = @leaves.last
61
+ leaf.next = nil
62
+ end
63
+ leaf.invalidate
64
+ @leaves << leaf
65
+ end
66
+
67
+ def add_child( treeNode )
68
+ return if treeNode.parent == self
69
+ if not treeNode.parent.nil?
70
+ treeNode.remove_from_parent()
71
+ end
72
+ treeNode.invalidate
73
+ treeNode.parent = self
74
+ @childs << treeNode
75
+ end
76
+
77
+ def find( name )
78
+ if self.name == name
79
+ return self
80
+ end
81
+
82
+ leaf = @leaves.find { |l| l.name == name }
83
+ if leaf
84
+ return leaf
85
+ end
86
+
87
+ @childs.each {|c|
88
+ node = c.find(name)
89
+ return node if node
90
+ }
91
+ nil
92
+ end
93
+
94
+ def accept( visitor )
95
+ visitor.enter_treeNode( self )
96
+ @leaves.each{ |l|
97
+ l.accept( visitor )
98
+ }
99
+ @childs.each { |tn|
100
+ tn.accept( visitor )
101
+ }
102
+ visitor.exit_treeNode( self )
103
+ end
104
+
105
+ def to_str( depth = 0 )
106
+ str = ""
107
+ (0...depth).step {
108
+ str << " |-"
109
+ }
110
+
111
+ str << @name
112
+ str << "\n"
113
+
114
+ if ! @leaves.empty?
115
+ @leaves.each{ |l|
116
+ (0...depth-1).step {
117
+ str << " |-"
118
+ }
119
+ if @childs.empty?
120
+ str << " | "
121
+ else
122
+ str << " | | "
123
+ end
124
+ str << l.to_str
125
+ str << "\n"
126
+ }
127
+ end
128
+
129
+ @childs.each { |tn|
130
+ str << tn.to_str( depth + 1 )
131
+ }
132
+ str
133
+ end
134
+ end
@@ -0,0 +1,251 @@
1
+ # rubygems
2
+ require 'rubygems'
3
+ require 'abstract'
4
+
5
+ #
6
+ # Classe astratta per visitare un TreeNode
7
+ #
8
+ class TreeNodeVisitor
9
+
10
+ def enter_treeNode( treeNode )
11
+ not_implemented
12
+ end
13
+
14
+ def exit_treeNode( treeNode )
15
+ not_implemented
16
+ end
17
+
18
+ def visit_leafNode( leafNode )
19
+ not_implemented
20
+ end
21
+
22
+ end
23
+
24
+ #
25
+ # Utilizzo della classa astratta DirTreeProcessor
26
+ # per chimare un blocco su tutti i TreeNode
27
+ #
28
+ class BlockTreeNodeVisitor
29
+
30
+ def initialize( &action )
31
+ @block = action
32
+ end
33
+
34
+ def enter_treeNode( treeNode )
35
+ @block.call( treeNode )
36
+ end
37
+
38
+ def exit_treeNode( treeNode )
39
+ end
40
+
41
+ def visit_leafNode( leafNode )
42
+ @block.call( leafNode )
43
+ end
44
+
45
+ end
46
+
47
+ #
48
+ # Utilizzo della classa astratta DirTreeProcessor
49
+ # per stampare i nodi di un TreeNode
50
+ #
51
+ class FlatPrintTreeNodeVisitor < TreeNodeVisitor
52
+
53
+ def enter_treeNode( treeNode )
54
+ puts treeNode.name
55
+ end
56
+
57
+ def exit_treeNode( treeNode )
58
+ end
59
+
60
+ def visit_leafNode( leafNode )
61
+ puts leafNode.name
62
+ end
63
+
64
+ end
65
+
66
+
67
+ class PrintTreeNodeVisitor < TreeNodeVisitor
68
+
69
+ def initialize( *args )
70
+ super( *args )
71
+ @depth = 0
72
+ end
73
+
74
+ def visit_leafNode( leafNode )
75
+ str = ""
76
+ (0...@depth-1).step {
77
+ str << " |-"
78
+ }
79
+ str << " | "
80
+ puts str + leafNode.name.to_s
81
+ end
82
+
83
+ def enter_treeNode( treeNode )
84
+
85
+ str = ""
86
+ (0...@depth).step {
87
+ str << " |-"
88
+ }
89
+
90
+ if @depth == 0
91
+ puts str + treeNode.name.to_s
92
+ else
93
+ puts str + treeNode.name.to_s
94
+ end
95
+ @depth += 1
96
+ end
97
+
98
+ def exit_treeNode( treeNode )
99
+ @depth -= 1
100
+ end
101
+ end
102
+
103
+
104
+ #
105
+ #
106
+ #
107
+ class DepthTreeNodeVisitor < TreeNodeVisitor
108
+
109
+ attr_reader :depth
110
+
111
+ def initialize
112
+ super
113
+ @depth = 0
114
+ end
115
+
116
+ def enter_treeNode( treeNode )
117
+ @depth += 1
118
+ end
119
+
120
+ def exit_treeNode( treeNode )
121
+ @depth -= 1
122
+ end
123
+
124
+ def visit_leafNode( leafNode )
125
+ end
126
+
127
+ end
128
+
129
+ #
130
+ # Esempio
131
+ # Clona un TreeNode
132
+ #
133
+ class CloneTreeNodeVisitor < TreeNodeVisitor
134
+
135
+ attr_reader :clonedRoot
136
+
137
+ def initialize
138
+ super
139
+ @clonedRoot = nil
140
+ @stack = []
141
+ end
142
+
143
+ def enter_treeNode( treeNode )
144
+ if @stack.empty?
145
+ clonedTreeNode = TreeNode.new( treeNode.name )
146
+ @clonedRoot = clonedTreeNode
147
+ else
148
+ clonedTreeNode = TreeNode.new( treeNode.name, @stack.last )
149
+ end
150
+ @stack.push( clonedTreeNode )
151
+ end
152
+
153
+ def exit_treeNode( treeNode )
154
+ @stack.pop
155
+ end
156
+
157
+ def visit_leafNode( leafNode )
158
+ clonedLeafNode = LeafNode.new( leafNode.name, @stack.last )
159
+ end
160
+
161
+ end
162
+
163
+ #
164
+ # CallbackTreeNodeVisitor
165
+ #
166
+ class CallbackTreeNodeVisitor < TreeNodeVisitor
167
+
168
+ def initialize( root = nil )
169
+ super()
170
+ @stack = []
171
+ @root = root
172
+ @stack.push( root ) if root
173
+ @action_enterTreeNode = nil
174
+ @action_visitLeafNode = nil
175
+ end
176
+
177
+ def onEnterTreeNode( &action )
178
+ @action_enterTreeNode = action
179
+ end
180
+
181
+ def onVisitLeafNode( &action )
182
+ @action_visitLeafNode = action
183
+ end
184
+
185
+ def enter_treeNode( treeNode )
186
+ parentNode = if @stack.empty?
187
+ nil
188
+ else
189
+ @stack.last
190
+ end
191
+ @root = treeNode if @stack.empty?
192
+ @stack.push( treeNode )
193
+ @action_enterTreeNode.call( treeNode ) if @action_enterTreeNode
194
+ end
195
+
196
+ def exit_treeNode( treeNode )
197
+ @stack.pop
198
+ end
199
+
200
+ def visit_leafNode( leafNode )
201
+ parentNode = @stack.last
202
+ @action_visitLeafNode.call( leafNode ) if @action_visitLeafNode
203
+ end
204
+
205
+ end
206
+
207
+
208
+ #
209
+ # CallbackTreeNodeVisitor
210
+ #
211
+ class CallbackTreeNodeVisitor2 < TreeNodeVisitor
212
+
213
+ attr_reader :root
214
+
215
+ def initialize( root = nil )
216
+ super()
217
+ @stack = []
218
+ @root = root
219
+ @stack.push( root ) if root
220
+ end
221
+
222
+ def onEnterTreeNode( &action )
223
+ @action_enterTreeNode = action
224
+ end
225
+
226
+ def onVisitLeafNode( &action )
227
+ @action_visitLeafNode = action
228
+ end
229
+
230
+ def enter_treeNode( treeNode )
231
+ newParentNode = if @stack.empty?
232
+ nil
233
+ else
234
+ @stack.last
235
+ end
236
+ newTreeNode = @action_enterTreeNode.call( treeNode, newParentNode )
237
+ @root = newTreeNode if @stack.empty?
238
+ @stack.push( newTreeNode )
239
+ end
240
+
241
+ def exit_treeNode( treeNode )
242
+ @stack.pop
243
+ end
244
+
245
+ def visit_leafNode( leafNode )
246
+ newParentNode = @stack.last
247
+ @action_visitLeafNode.call( leafNode, newParentNode )
248
+ end
249
+
250
+ end
251
+