fabulator 0.0.6 → 0.0.7
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.
- data/History.txt +20 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/features/step_definitions/expression_steps.rb +1 -1
- data/features/step_definitions/xml_steps.rb +2 -1
- data/features/support/env.rb +1 -0
- data/lib/fabulator.rb +13 -5
- data/lib/fabulator/action.rb +86 -19
- data/lib/fabulator/core/actions.rb +21 -6
- data/lib/fabulator/core/actions/choose.rb +16 -35
- data/lib/fabulator/core/actions/for_each.rb +20 -30
- data/lib/fabulator/core/actions/variables.rb +6 -8
- data/lib/fabulator/core/constraint.rb +2 -2
- data/lib/fabulator/core/filter.rb +0 -13
- data/lib/fabulator/core/group.rb +21 -25
- data/lib/fabulator/core/parameter.rb +5 -17
- data/lib/fabulator/core/state.rb +4 -44
- data/lib/fabulator/core/state_machine.rb +10 -38
- data/lib/fabulator/core/transition.rb +6 -39
- data/lib/fabulator/expr/axis.rb +2 -2
- data/lib/fabulator/expr/bin_expr.rb +3 -3
- data/lib/fabulator/expr/context.rb +37 -6
- data/lib/fabulator/expr/function.rb +9 -3
- data/lib/fabulator/expr/literal.rb +1 -1
- data/lib/fabulator/expr/node.rb +1 -1
- data/lib/fabulator/expr/node_logic.rb +1 -1
- data/lib/fabulator/expr/parser.rb +1 -1
- data/lib/fabulator/expr/predicates.rb +1 -1
- data/lib/fabulator/expr/statement_list.rb +4 -0
- data/lib/fabulator/expr/union_expr.rb +1 -1
- data/lib/fabulator/lib.rb +69 -0
- data/lib/fabulator/lib/action.rb +13 -0
- data/lib/fabulator/lib/attribute.rb +9 -0
- data/lib/fabulator/lib/lib.rb +47 -0
- data/lib/fabulator/lib/structural.rb +13 -0
- data/lib/fabulator/structural.rb +92 -0
- data/lib/fabulator/{action_lib.rb → tag_lib.rb} +89 -51
- data/lib/fabulator/template/standard_tags.rb +4 -3
- data/xsm_expression_parser.racc +1 -1
- metadata +27 -8
- data/TODO +0 -7
- 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(
|
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
|
35
|
+
return [] if self.name.nil?
|
36
36
|
res = [ ]
|
37
37
|
@context.with(context) do |ctx|
|
38
38
|
if @select
|
39
|
-
res =
|
40
|
-
|
41
|
-
|
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(
|
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')
|
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|
|
data/lib/fabulator/core/group.rb
CHANGED
@@ -1,41 +1,37 @@
|
|
1
1
|
module Fabulator
|
2
2
|
module Core
|
3
|
-
class Group < Fabulator::
|
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
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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::
|
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)
|
data/lib/fabulator/core/state.rb
CHANGED
@@ -1,54 +1,13 @@
|
|
1
1
|
module Fabulator
|
2
2
|
module Core
|
3
|
-
class State < Fabulator::
|
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
|
-
|
17
|
-
super
|
8
|
+
attribute :name, :static => true
|
18
9
|
|
19
|
-
|
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
|
26
|
-
|
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
|
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::
|
3
|
+
class Transition < Fabulator::Structural
|
4
4
|
attr_accessor :state, :validations, :tags
|
5
5
|
|
6
|
-
namespace
|
7
|
-
attribute :view, :as => :lstate, :static => true
|
8
|
-
attribute :tag, :as => :ltags, :static => true, :default => ''
|
6
|
+
namespace FAB_NS
|
9
7
|
|
10
|
-
|
11
|
-
|
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
|
-
|
22
|
-
|
23
|
-
if !inheriting
|
24
|
-
@state = @lstate
|
25
|
-
@tags = @ltags
|
26
|
-
end
|
11
|
+
contains :params, :as => :params
|
27
12
|
|
28
|
-
|
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
|
data/lib/fabulator/expr/axis.rb
CHANGED
@@ -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::
|
27
|
-
context.root.roots[@root] = Fabulator::
|
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::
|
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::
|
27
|
-
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
|
-
|
322
|
-
|
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::
|
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::
|
359
|
-
Fabulator::
|
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::
|
415
|
+
handler = Fabulator::TagLib.namespaces[ns]
|
385
416
|
return [] if handler.nil?
|
386
417
|
handler.run_filter(self, name)
|
387
418
|
end
|