fabulator 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.txt +20 -0
  2. data/Rakefile +1 -0
  3. data/VERSION +1 -1
  4. data/features/step_definitions/expression_steps.rb +1 -1
  5. data/features/step_definitions/xml_steps.rb +2 -1
  6. data/features/support/env.rb +1 -0
  7. data/lib/fabulator.rb +13 -5
  8. data/lib/fabulator/action.rb +86 -19
  9. data/lib/fabulator/core/actions.rb +21 -6
  10. data/lib/fabulator/core/actions/choose.rb +16 -35
  11. data/lib/fabulator/core/actions/for_each.rb +20 -30
  12. data/lib/fabulator/core/actions/variables.rb +6 -8
  13. data/lib/fabulator/core/constraint.rb +2 -2
  14. data/lib/fabulator/core/filter.rb +0 -13
  15. data/lib/fabulator/core/group.rb +21 -25
  16. data/lib/fabulator/core/parameter.rb +5 -17
  17. data/lib/fabulator/core/state.rb +4 -44
  18. data/lib/fabulator/core/state_machine.rb +10 -38
  19. data/lib/fabulator/core/transition.rb +6 -39
  20. data/lib/fabulator/expr/axis.rb +2 -2
  21. data/lib/fabulator/expr/bin_expr.rb +3 -3
  22. data/lib/fabulator/expr/context.rb +37 -6
  23. data/lib/fabulator/expr/function.rb +9 -3
  24. data/lib/fabulator/expr/literal.rb +1 -1
  25. data/lib/fabulator/expr/node.rb +1 -1
  26. data/lib/fabulator/expr/node_logic.rb +1 -1
  27. data/lib/fabulator/expr/parser.rb +1 -1
  28. data/lib/fabulator/expr/predicates.rb +1 -1
  29. data/lib/fabulator/expr/statement_list.rb +4 -0
  30. data/lib/fabulator/expr/union_expr.rb +1 -1
  31. data/lib/fabulator/lib.rb +69 -0
  32. data/lib/fabulator/lib/action.rb +13 -0
  33. data/lib/fabulator/lib/attribute.rb +9 -0
  34. data/lib/fabulator/lib/lib.rb +47 -0
  35. data/lib/fabulator/lib/structural.rb +13 -0
  36. data/lib/fabulator/structural.rb +92 -0
  37. data/lib/fabulator/{action_lib.rb → tag_lib.rb} +89 -51
  38. data/lib/fabulator/template/standard_tags.rb +4 -3
  39. data/xsm_expression_parser.racc +1 -1
  40. metadata +27 -8
  41. data/TODO +0 -7
  42. data/features/xsm-inheritance.feature +0 -46
@@ -20,7 +20,7 @@ module Fabulator
20
20
 
21
21
  def run(context, autovivify = false)
22
22
  @context.with(context) do |ctx|
23
- ctx.set_value(@path, @select.nil? ? @actions : @select )
23
+ ctx.set_value(self.path, @select.nil? ? @actions : @select )
24
24
  end
25
25
  end
26
26
  end
@@ -32,18 +32,16 @@ module Fabulator
32
32
  has_actions
33
33
 
34
34
  def run(context, autovivify = false)
35
- return [] if @name.nil?
35
+ return [] if self.name.nil?
36
36
  res = [ ]
37
37
  @context.with(context) do |ctx|
38
38
  if @select
39
- res = @select.run(ctx, autovivify)
40
- elsif !@actions.empty?
41
- @actions.each do |a|
42
- res = a.run(ctx, autovivify)
43
- end
39
+ res = self.select(ctx)
40
+ else
41
+ res = self.run_actions(ctx)
44
42
  end
45
43
  end
46
- context.set_var(@name, res)
44
+ context.set_var(self.name, res)
47
45
  res
48
46
  end
49
47
  end
@@ -9,6 +9,7 @@ module Fabulator
9
9
 
10
10
  def compile_xml(xml, ctx)
11
11
  super
12
+
12
13
  @constraints = [ ]
13
14
  @values = [ ]
14
15
  @params = [ ]
@@ -28,7 +29,7 @@ module Fabulator
28
29
  e_ctx = @context.merge(e)
29
30
  case e.name
30
31
  when 'param':
31
- pname = e_ctx.attribute(FAB_NS, 'name') # (e.get_attribute_ns(FAB_NS, 'name').value rescue nil)
32
+ pname = e_ctx.attribute(FAB_NS, 'name')
32
33
  if !pname.nil?
33
34
  v = e_ctx.attribute(FAB_NS, 'value', { :default => e_ctx.get_select })
34
35
  @params[pname] = v unless v.nil?
@@ -44,7 +45,6 @@ module Fabulator
44
45
  end
45
46
  end
46
47
  end
47
- self
48
48
  end
49
49
 
50
50
  def error_message(context)
@@ -4,19 +4,6 @@ module Fabulator
4
4
  namespace Fabulator::FAB_NS
5
5
  attribute :name, :static => true
6
6
 
7
- # def compile_xml(xml, context)
8
- # @context = context.merge(xml)
9
- # filter_type = @context.attribute(FAB_NS, 'name', {:static => true}).split(/:/, 2)
10
- # if filter_type.size == 2
11
- # @ns = @context.get_ns(filter_type[0])
12
- # @name = filter_type[1]
13
- # else
14
- # @ns = FAB_NS
15
- # @name = filter_type[0]
16
- # end
17
- # self
18
- # end
19
-
20
7
  def run(context)
21
8
  filtered = [ ]
22
9
  @context.with(context) do |ctx|
@@ -1,41 +1,37 @@
1
1
  module Fabulator
2
2
  module Core
3
- class Group < Fabulator::Action
3
+ class Group < Fabulator::Structural
4
4
  attr_accessor :name, :params, :tags, :required_params
5
5
 
6
6
  namespace Fabulator::FAB_NS
7
7
 
8
+ contains 'group', :as => :groups
9
+ contains 'param', :as => :params
10
+ contains 'constraint', :as => :constraints
11
+ contains 'filter', :as => :filters
12
+
8
13
  has_select
9
14
 
10
- def initialize
11
- @params = [ ]
12
- @constraints = [ ]
13
- @filters = [ ]
14
- @required_params = [ ]
15
- @tags = [ ]
16
- end
15
+ attribute :select, :as => :name, :static => true
17
16
 
18
17
  def compile_xml(xml, context)
19
18
  super
20
- xml.each_element do |e|
21
- next unless e.namespaces.namespace.href == FAB_NS
22
19
 
23
- case e.name
24
- when 'param':
25
- v = Parameter.new.compile_xml(e,@context)
26
- @params << v
27
- @required_params = @required_params + v.names if v.required?
28
- when 'group':
29
- v = Group.new.compile_xml(e,@context)
30
- @params << v
31
- @required_params = @required_params + v.required_params.collect{ |n| (@name + '/' + n).gsub(/\/+/, '/') }
32
- when 'constraint':
33
- @constraints << Constraint.new.compile_xml(e,@context)
34
- when 'filter':
35
- @filters << Filter.new.compile_xml(e,@context)
36
- end
20
+ @required_params = [ ]
21
+
22
+ @params.each do |p|
23
+ @required_params += p.names if p.required?
37
24
  end
38
- self
25
+
26
+ @name = '' if @name.nil?
27
+ @name.gsub!(/^\//, '')
28
+
29
+ @groups.each do |g|
30
+ @required_params += g.required_params.collect{ |n| (@name + '/' + n).gsub(/\/+/, '/') }
31
+ end
32
+
33
+ @params += @groups
34
+ @groups = nil
39
35
  end
40
36
 
41
37
  def apply_filters(context)
@@ -1,6 +1,6 @@
1
1
  module Fabulator
2
2
  module Core
3
- class Parameter < Fabulator::Action
3
+ class Parameter < Fabulator::Structural
4
4
  attr_accessor :name
5
5
 
6
6
  namespace Fabulator::FAB_NS
@@ -8,6 +8,10 @@ module Fabulator
8
8
  attribute :name, :eval => false, :static => true
9
9
  attribute :required, :static => true, :default => 'false'
10
10
 
11
+ contains :constraint
12
+ contains :filter
13
+ contains :value, :as => :constraints
14
+
11
15
  def required?
12
16
  @required
13
17
  end
@@ -23,9 +27,6 @@ module Fabulator
23
27
  def compile_xml(xml, context)
24
28
  super
25
29
 
26
- @constraints = [ ]
27
- @filters = [ ]
28
-
29
30
  case @required.downcase
30
31
  when 'yes':
31
32
  @required = true
@@ -36,19 +37,6 @@ module Fabulator
36
37
  when 'false':
37
38
  @required = false
38
39
  end
39
-
40
- xml.each_element do |e|
41
- next unless e.namespaces.namespace.href == FAB_NS
42
- case e.name
43
- when 'constraint':
44
- @constraints << Constraint.new.compile_xml(e, @context)
45
- when 'filter':
46
- @filters << Filter.new.compile_xml(e, @context)
47
- when 'value':
48
- @constraints << Constraint.new.compile_xml(e, @context)
49
- end
50
- end
51
- self
52
40
  end
53
41
 
54
42
  def get_context(context)
@@ -1,54 +1,13 @@
1
1
  module Fabulator
2
2
  module Core
3
- class State < Fabulator::Action
3
+ class State < Fabulator::Structural
4
4
  attr_accessor :name, :transitions
5
5
 
6
- def initialize
7
- @transitions = []
8
- @pre_actions = nil
9
- @post_actions = nil
10
- end
11
-
12
6
  namespace Fabulator::FAB_NS
13
- attribute :name, :static => true
14
-
15
7
 
16
- def compile_xml(xml, ctx)
17
- super
8
+ attribute :name, :static => true
18
9
 
19
- inheriting = !@transitions.empty?
20
- xml.each_element do |e|
21
- next unless e.namespaces.namespace.href == FAB_NS
22
- case e.name
23
- when 'goes-to':
24
- if inheriting
25
- target = e.attributes.get_attribute_ns(FAB_NS, 'view').value
26
- tags = (e.attributes.get_attribute_ns(FAB_NS, 'tag').value rescue '').split(/\s+/)
27
- old = @transitions.collect{ |t| t.state == target && (tags.empty? || !(tags & t.tags).empty?)}
28
- if old.empty?
29
- @transitions << Transition.new.compile_xml(e,@context)
30
- else
31
- old.each do |t|
32
- t.compile_xml(e,@context)
33
- end
34
- end
35
- else
36
- @transitions << Transition.new.compile_xml(e, @context)
37
- end
38
- when 'before':
39
- ActionLib.with_super(@pre_actions) do
40
- t = @context.compile_actions(e)
41
- @pre_actions = t if @pre_actions.nil? || !t.is_noop?
42
- end
43
- when 'after':
44
- ActionLib.with_super(@post_actions) do
45
- t = @context.compile_actions(e)
46
- @post_actions = t if @post_actions.nil? || !t.is_noop?
47
- end
48
- end
49
- end
50
- self
51
- end
10
+ contains 'goes-to', :as => :transitions
52
11
 
53
12
  def states
54
13
  @transitions.map { |t| t.state }.uniq
@@ -56,6 +15,7 @@ module Fabulator
56
15
 
57
16
  def select_transition(context,params)
58
17
  # we need hypthetical variables here :-/
18
+ return nil if @context.nil?
59
19
  best_match = nil
60
20
  @context.with(context) do |ctx|
61
21
  best_match = nil
@@ -2,63 +2,35 @@ require 'yaml'
2
2
  require 'xml/libxml'
3
3
 
4
4
  module Fabulator
5
- FAB_NS='http://dh.tamu.edu/ns/fabulator/1.0#'
6
- RDFS_NS = 'http://www.w3.org/2000/01/rdf-schema#'
7
- RDF_NS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
8
- RDFA_NS = 'http://dh.tamu.edu/ns/fabulator/rdf/1.0#'
9
-
10
5
  class StateChangeException < Exception
11
6
  end
12
7
 
13
8
  module Core
14
9
 
15
- class StateMachine
10
+ class StateMachine < Structural
16
11
  attr_accessor :states, :missing_params, :errors, :namespaces, :updated_at
17
12
  attr_accessor :state
18
13
 
14
+ namespace FAB_NS
15
+
16
+ contains :view, :as => :states, :storage => :hash
17
+
18
+ has_actions
19
+
19
20
  def initialize
20
21
  @states = { }
21
22
  @context = Fabulator::Expr::Context.new
22
23
  @state = 'start'
23
24
  end
24
25
 
25
- def compile_xml(xml, context = nil, callbacks = { })
26
- # /statemachine/states
27
- XML.default_line_numbers = true
28
- if xml.is_a?(String)
29
- xml = LibXML::XML::Document.string xml
30
- end
31
-
32
- if context.nil?
33
- @context = @context.merge(xml.root)
34
- else
35
- @context = context.merge(xml.root)
36
- end
37
-
38
- ActionLib.with_super(@actions) do
39
- p_actions = @context.compile_actions(xml.root)
40
- @actions = p_actions if @actions.nil? || !p_actions.is_noop?
41
- end
42
-
43
- xml.root.each_element do |child|
44
- next unless child.namespaces.namespace.href == FAB_NS
45
- case child.name
46
- when 'view':
47
- nom = (child.attributes.get_attribute_ns(FAB_NS, 'name').value rescue nil)
48
- if !@states[nom].nil?
49
- @states[nom].compile_xml(child, @context)
50
- else
51
- @states[nom] = State.new.compile_xml(child, @context)
52
- end
53
- end
54
- end
26
+ def compile_xml(xml, context = nil)
27
+ super
55
28
 
56
29
  if @states.empty?
57
30
  s = State.new
58
31
  s.name = 'start'
59
- @states['start'] = s
32
+ @states = { 'start' => s }
60
33
  end
61
- self
62
34
  end
63
35
 
64
36
  def clone
@@ -1,49 +1,16 @@
1
1
  module Fabulator
2
2
  module Core
3
- class Transition < Fabulator::Action
3
+ class Transition < Fabulator::Structural
4
4
  attr_accessor :state, :validations, :tags
5
5
 
6
- namespace Fabulator::FAB_NS
7
- attribute :view, :as => :lstate, :static => true
8
- attribute :tag, :as => :ltags, :static => true, :default => ''
6
+ namespace FAB_NS
9
7
 
10
- def initialize
11
- @state = nil
12
- @tags = nil
13
- @groups = { }
14
- @params = [ ]
15
- @actions = nil
16
- end
17
-
18
- def compile_xml(xml, ctx)
19
- super
8
+ attribute :view, :as => :state, :static => true
9
+ #attribute :tag, :as => :ltags, :static => true, :default => ''
20
10
 
21
- inheriting = !@state.nil?
22
-
23
- if !inheriting
24
- @state = @lstate
25
- @tags = @ltags
26
- end
11
+ contains :params, :as => :params
27
12
 
28
- # TODO: figure out some way to reference inherited actions
29
- # figure out 'super' vs. 'inner' -- only supporting 'super'
30
- # for now
31
- ActionLib.with_super(@actions) do
32
- t = @context.compile_actions(xml)
33
- @actions = t if @actions.nil? || !t.is_noop?
34
- end
35
- parser = Fabulator::Expr::Parser.new
36
-
37
- xml.each_element do |e|
38
- next unless e.namespaces.namespace.href == FAB_NS
39
- case e.name
40
- # TODO: handle parameters when inheriting
41
- when 'params':
42
- @params << Group.new.compile_xml(e, @context)
43
- end
44
- end
45
- self
46
- end
13
+ has_actions
47
14
 
48
15
  def param_names
49
16
  (@params.collect{|w| w.param_names}.flatten).uniq
@@ -23,8 +23,8 @@ module Fabulator
23
23
  if @root.nil? || @root == ''
24
24
  return @axis.run(context, autovivify)
25
25
  else
26
- if context.root.roots[@root].nil? && !Fabulator::ActionLib.axes[@root].nil?
27
- context.root.roots[@root] = Fabulator::ActionLib.axes[@root].call(context)
26
+ if context.root.roots[@root].nil? && !Fabulator::TagLib.axes[@root].nil?
27
+ context.root.roots[@root] = Fabulator::TagLib.axes[@root].call(context)
28
28
  end
29
29
  return context.root.roots[@root].nil? ? [ ] :
30
30
  @axis.nil? ? [ context.root.roots[@root] ] :
@@ -9,7 +9,7 @@ module Fabulator
9
9
  def expr_type(context)
10
10
  lt = @left.expr_type(context)
11
11
  rt = @right.expr_type(context)
12
- Fabulator::ActionLib.unify_types([ lt, rt ])
12
+ Fabulator::TagLib.unify_types([ lt, rt ])
13
13
  end
14
14
 
15
15
  def run(context, autovivify = false)
@@ -23,8 +23,8 @@ module Fabulator
23
23
 
24
24
  l.each do |i|
25
25
  r.each do |j|
26
- ut = Fabulator::ActionLib.unify_types([ i.vtype, j.vtype ])
27
- op = ActionLib.find_op(ut, self.op)
26
+ ut = Fabulator::TagLib.unify_types([ i.vtype, j.vtype ])
27
+ op = TagLib.find_op(ut, self.op)
28
28
  if(op && op[:proc])
29
29
  calc = op[:proc].call(i.to(ut), j.to(ut))
30
30
  else
@@ -318,8 +318,13 @@ module Fabulator
318
318
  end
319
319
  end
320
320
  d.each do |i|
321
- c = root_context.create_child(node_name)
322
- self.with_root(c).merge_data(i)
321
+ next if i.nil?
322
+ if i.is_a?(Array) || i.is_a?(Hash)
323
+ c = root_context.create_child(node_name)
324
+ self.with_root(c).merge_data(i)
325
+ else
326
+ root_context.create_child(node_name, i)
327
+ end
323
328
  end
324
329
  elsif d.is_a?(Hash)
325
330
  d.each_pair do |k,v|
@@ -338,10 +343,12 @@ module Fabulator
338
343
 
339
344
  def compile_actions(xml)
340
345
  actions = Fabulator::Expr::StatementList.new
346
+ return actions if xml.nil?
347
+
341
348
  local_ctx = self.merge(xml)
342
349
  xml.each_element do |e|
343
350
  ns = e.namespaces.namespace.href
344
- next unless Fabulator::ActionLib.namespaces.include?(ns)
351
+ next unless Fabulator::TagLib.namespaces.include?(ns)
345
352
  if ns == FAB_NS && e.name == 'ensure'
346
353
  actions.add_ensure(local_ctx.compile_actions(e))
347
354
  elsif ns == FAB_NS && e.name == 'catch'
@@ -355,8 +362,32 @@ module Fabulator
355
362
 
356
363
  def compile_action(e)
357
364
  ns = e.namespaces.namespace.href
358
- return unless Fabulator::ActionLib.namespaces.include?(ns)
359
- Fabulator::ActionLib.namespaces[ns].compile_action(e, self)
365
+ return unless Fabulator::TagLib.namespaces.include?(ns)
366
+ Fabulator::TagLib.namespaces[ns].compile_action(e, self)
367
+ end
368
+
369
+ def compile_structurals(xml)
370
+ #local_ctx = self.merge(xml)
371
+ structs = { }
372
+ our_ns = xml.namespaces.namespace.href
373
+ our_nom = xml.name
374
+ xml.each_element do |e|
375
+ ns = e.namespaces.namespace.href
376
+ nom = e.name.to_sym
377
+ allowed = (Fabulator::TagLib.namespaces[our_ns].structural_class(our_nom).accepts_structural?(ns, nom) rescue false)
378
+ next unless allowed
379
+ structs[ns] ||= { }
380
+ structs[ns][nom] ||= [ ]
381
+ structs[ns][nom] << self.compile_structural(e)
382
+ structs[ns][nom] -= [ nil ]
383
+ end
384
+ return structs
385
+ end
386
+
387
+ def compile_structural(e)
388
+ ns = e.namespaces.namespace.href
389
+ return unless Fabulator::TagLib.namespaces.include?(ns)
390
+ Fabulator::TagLib.namespaces[ns].compile_structural(e, self)
360
391
  end
361
392
 
362
393
  def in_context(&block)
@@ -381,7 +412,7 @@ module Fabulator
381
412
  end
382
413
 
383
414
  def run_filter(ns, name)
384
- handler = Fabulator::ActionLib.namespaces[ns]
415
+ handler = Fabulator::TagLib.namespaces[ns]
385
416
  return [] if handler.nil?
386
417
  handler.run_filter(self, name)
387
418
  end