lib/openwfe/expool/parser.rb in ruote-0.9.18 vs lib/openwfe/expool/parser.rb in ruote-0.9.19

- old
+ new

@@ -35,208 +35,244 @@ # "made in Japan" # # John Mettraux at openwfe.org # -require 'rexml/document' +require 'openwfe/rexml' +require 'openwfe/service' +require 'openwfe/contextual' +require 'openwfe/util/treechecker' require 'openwfe/expressions/rprocdef' module OpenWFE + # + # A process definition parser. + # + # Currently supports XML, Ruby process pdefinitions, YAML and JSON. + # + class DefParser < Service + include OwfeServiceLocator + # - # A process definition parser. + # a static version of the parse method, + # by default checks the tree if it's Ruby code that is passed. # - # Currently supports XML, Ruby process pdefinitions, YAML and JSON. + def self.parse (pdef, use_ruby_treechecker=true) + + # + # preparing a small ad-hoc env (app context) for this parsing + + ac = { :use_ruby_treechecker => use_ruby_treechecker } + + ac[:s_tree_checker] = TreeChecker.new(:s_tree_checker, ac) + ac[:s_def_parser] = DefParser.new(:s_def_parser, ac) + + ac[:s_def_parser].parse(pdef) + end + # - module DefParser + # the classical initialize() of Ruote services + # + def initialize (service_name, application_context) + super + end - # - # in : a process pdefinition - # out : a tree [ name, attributes, children ] - # - def self.parse (pdef) + # + # in : a process pdefinition + # out : a tree [ name, attributes, children ] + # + def parse (pdef) - return pdef \ - if pdef.is_a?(Array) + return pdef \ + if pdef.is_a?(Array) - return parse_string(pdef) \ - if pdef.is_a?(String) + return parse_string(pdef) \ + if pdef.is_a?(String) - return pdef.do_make \ - if pdef.is_a?(ProcessDefinition) or pdef.is_a?(Class) + return pdef.do_make \ + if pdef.is_a?(ProcessDefinition) or pdef.is_a?(Class) - return pdef.to_a \ - if pdef.is_a?(SimpleExpRepresentation) - # for legacy stuff + return pdef.to_a \ + if pdef.is_a?(SimpleExpRepresentation) + # for legacy stuff - raise "cannot handle pdefinition of class #{pdef.class.name}" - end + raise "cannot handle pdefinition of class #{pdef.class.name}" + end - def self.parse_string (pdef) + def parse_string (pdef) - pdef = pdef.strip + pdef = pdef.strip - return parse_xml(pdef) \ - if pdef[0, 1] == "<" + return parse_xml(pdef) \ + if pdef[0, 1] == '<' - return YAML.load(s) \ - if pdef.match /^--- ./ + return YAML.load(s) \ + if pdef.match(/^--- ./) - # - # else it's some ruby code to eval + # + # else it's some ruby code to eval - ProcessDefinition.eval_ruby_process_definition pdef - end + get_tree_checker.check pdef - # - # The process definition is expressed as XML, turn that into - # an expression tree. - # - def self.parse_xml (xml) + # green for eval... - xml = REXML::Document.new(xml) \ - if xml.is_a?(String) + ProcessDefinition.eval_ruby_process_definition pdef + end - xml = xml.root \ - if xml.is_a?(REXML::Document) + # + # The process definition is expressed as XML, turn that into + # an expression tree. + # + def parse_xml (xml) - if xml.is_a?(REXML::Text) + xml = REXML::Document.new(xml) \ + if xml.is_a?(String) - s = xml.to_s.strip + xml = xml.root \ + if xml.is_a?(REXML::Document) - return s if s.length > 0 + if xml.is_a?(REXML::Text) - return nil - end + s = xml.to_s.strip - return nil if xml.is_a?(REXML::Comment) + return s if s.length > 0 - # xml element thus... + return nil + end - name = xml.name + return nil if xml.is_a?(REXML::Comment) - attributes = xml.attributes.inject({}) do |r, (k, v)| - r[k] = v - r - end + # then it's a REXML::Element - rep = [ name, attributes, [] ] + rep = [ + xml.name, + xml.attributes.inject({}) { |r, (k, v)| r[k] = v; r }, + [] ] - xml.children.each do |c| + xml.children.each do |c| - r = parse_xml c + r = parse_xml c - rep.last << r if r - end + rep.last << r if r + end - rep - end + rep end + end + # + # A set of methods for manipulating / querying a process expression tree + # + module ExpressionTree + # - # A set of methods for manipulating / querying a process expression tree + # Extracts the description out of a process definition tree. # - module ExpressionTree + # TODO #14964 : add language support here + # + def self.get_description (tree) - # - # Extracts the description out of a process definition tree. - # - # TODO #14964 : add language support here - # - def self.get_description (tree) + #return tree.last.first.to_s if tree.first == 'description' + #tree.last.each do |child| + # d = get_description(child) + # return d if d + #end + #nil - #return tree.last.first.to_s if tree.first == 'description' - #tree.last.each do |child| - # d = get_description(child) - # return d if d - #end - #nil + tree.last.each do |child| + next unless child.is_a?(Array) + return child.last.first if child.first == 'description' + end - tree.last.each do |child| - next unless child.is_a?(Array) - return child.last.first if child.first == 'description' - end + nil + end - nil - end + # + # Returns a string containing the ruby code that generated this + # raw representation tree. + # + def self.to_code_s (tree, indentation = 0) - # - # Returns a string containing the ruby code that generated this - # raw representation tree. - # - def self.to_code_s (tree, indentation = 0) + s = "" + tab = " " + ind = tab * indentation - s = "" - tab = " " - ind = tab * indentation + s << ind + s << OpenWFE::make_safe(tree.first) - s << ind - s << OpenWFE::make_safe(tree.first) + sa = "" + tree[1].each do |k, v| + #v = "'#{v}'" if v.is_a?(String) + #v = ":#{v}" if v.is_a?(Symbol) + v = v.inspect + sa << ", :#{OpenWFE::to_underscore(k)} => #{v}" + end + s << sa[1..-1] if sa.length > 0 - sa = "" - tree[1].each do |k, v| - sa << ", :#{OpenWFE::to_underscore(k)} => '#{v}'" + if tree.last.length > 0 + if tree.last.size == 1 and tree.last.first.class == String + # maybe could work for things that are not string either... + s << " '#{tree.last.first}'" + else + s << " do\n" + tree.last.each do |child| + #if child.respond_to?(:to_code_s) + if child.is_a?(Array) and child.size == 3 # and ... + s << to_code_s(child, indentation + 1) + else + s << ind + s << tab + s << "'#{child.to_s}'" # inspect instead of to_s ? end - s << sa[1..-1] if sa.length > 0 - - if tree.last.length > 0 - s << " do\n" - tree.last.each do |child| - #if child.respond_to?(:to_code_s) - if child.is_a?(Array) and child.size == 3 # and ... - s << to_code_s(child, indentation + 1) - else - s << ind - s << tab - s << "'#{child.to_s}'" - end - s << "\n" - end - s << ind - s << "end" - end - - s + s << "\n" + end + s << ind + s << "end" end + end - # - # Turns the expression tree into an XML process definition - # - def self.to_xml (tree) + s + end - elt = REXML::Element.new tree.first.to_s + # + # Turns the expression tree into an XML process definition + # + def self.to_xml (tree) - tree[1].each do |k, v| + elt = REXML::Element.new tree.first.to_s - elt.attributes[k] = v - end + tree[1].each do |k, v| - tree.last.each do |child| + elt.attributes[k] = v + end - #if child.kind_of?(SimpleExpRepresentation) - if child.is_a?(Array) and child.size == 3 + tree.last.each do |child| - elt << to_xml(child) - else + #if child.kind_of?(SimpleExpRepresentation) + if child.is_a?(Array) and child.size == 3 - elt << REXML::Text.new(child.to_s) - end - end + elt << to_xml(child) + else - elt + elt << REXML::Text.new(child.to_s) end + end - # - # Returns an XML string - # - def self.to_s (tree, indent=-1) + elt + end - d = REXML::Document.new - d << to_xml(tree) - s = "" - d.write s, indent - s - end + # + # Returns an XML string + # + def self.to_s (tree, indent=-1) + + d = REXML::Document.new + d << to_xml(tree) + s = "" + d.write s, indent + s end + end end