fabulator 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|