gf-treevisitor 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+