lib/openwfe/expressions/rprocdef.rb in ruote-0.9.19 vs lib/openwfe/expressions/rprocdef.rb in ruote-0.9.20
- old
+ new
@@ -1,52 +1,75 @@
-#
#--
-# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
-# All rights reserved.
+# Copyright (c) 2007-2009, John Mettraux, jmettraux@gmail.com
#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
#
-# . Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
#
-# . Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
#
-# . Neither the name of the "OpenWFE" nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
+# Made in Japan.
#++
-#
-#
-# "made in Japan"
-#
-# John Mettraux at openwfe.org
-#
require 'openwfe/util/treechecker'
require 'openwfe/utils'
require 'openwfe/expressions/raw'
module OpenWFE
#
+ # A shorthand for writing process definitions like :
+ #
+ # Test2 = OpenWFE.process_definition :name => 'ft_11b', :revision => '2' do
+ # sequence do
+ # participant 'alpha'
+ # sleep '3d'
+ # participant 'bravo'
+ # end
+ # end
+ #
+ # This will store in the constant Test2 the process definition in its
+ # 'raw' (tree) form :
+ #
+ # ["process-definition", {"name"=>"ft_11b", "revision"=>"2"}, [
+ # ["sequence", {}, [
+ # ["participant", {}, ["alpha"]],
+ # ["sleep", {}, ["3d"]],
+ # ["participant", {}, ["bravo"]]]]]]
+ #
+ def self.process_definition (*args, &block)
+
+ pd = ProcessDefinition.new
+ pd.instance_eval(&block)
+
+ [
+ 'process-definition',
+ lambda() { |a|
+ atts = a.last.is_a?(Hash) ? a.last : {}
+ atts['name'] = a.first unless a.first.is_a?(Hash)
+ atts.inject({}) { |h, (k, v)| h[OpenWFE.symbol_to_name(k)] = v; h }
+ }.call(args),
+ #[ ProcessDefinition.new.instance_eval(&block) ]
+ pd.context.top_expressions
+ ]
+ end
+
+ #
# Extend this class to create a programmatic process definition.
#
# A short example :
#
# class MyProcessDefinition < OpenWFE::ProcessDefinition
@@ -61,11 +84,10 @@
# end
#
# li = OpenWFE::LaunchItem.new(MyProcessDefinition)
# engine.launch(li)
#
- #
class ProcessDefinition
def self.metaclass; class << self; self; end; end
attr_reader :context
@@ -76,23 +98,24 @@
@context = Context.new
end
def method_missing (m, *args, &block)
- #puts "__i_method_missing >>>#{m}<<<<"
+ #p [ :method_missing, m ]
+ return nil if m == :make
+
ProcessDefinition.make_expression(
@context,
OpenWFE::to_expression_name(m),
ProcessDefinition.pack_args(args),
&block)
end
def self.method_missing (m, *args, &block)
- @ccontext = Context.new \
- if (not @ccontext) or @ccontext.discarded?
+ @ccontext = Context.new if (not @ccontext) or @ccontext.discarded?
ProcessDefinition.make_expression(
@ccontext,
OpenWFE::to_expression_name(m),
ProcessDefinition.pack_args(args),
@@ -104,15 +127,12 @@
# process definition tree).
#
def self.make_expression (context, exp_name, params, &block)
string_child = nil
- #attributes = OpenWFE::SymbolHash.new
attributes = Hash.new
- #puts " ... params.class is #{params.class}"
-
if params.kind_of?(Hash)
params.each do |k, v|
if k == '0'
@@ -145,16 +165,15 @@
context.top_expressions << exp
end
return exp unless block
- context.push_parent_expression exp
+ context.push_parent_expression(exp)
result = block.call
- exp.last << result \
- if result and result.kind_of?(String)
+ exp.last << result if result and result.is_a?(String)
context.pop_parent_expression
exp
end
@@ -178,10 +197,11 @@
elsif instance
instance.make
instance.context
+
else
pdef = self.new
pdef.make
pdef.context
@@ -191,12 +211,12 @@
name, revision =
extract_name_and_revision(self.metaclass.to_s[8..-2])
top_expression = [
- "process-definition",
- { "name" => name, "revision" => revision },
+ 'process-definition',
+ { 'name' => name, 'revision' => revision },
context.top_expressions
]
top_expression
end
@@ -225,53 +245,35 @@
#TreeChecker.check code
#
# checks for 'illicit' ruby code before the eval
# (now done in the DefParser)
- code, is_wrapped = wrap_code code
+ o = eval(code, binding())
- o = eval code, binding()
+ klass = extract_class(code)
+ #
+ # grab the first process definition class found
+ # in the given code
- o = extract_class(code) \
- if (o == nil) or o.is_a?(Array)
- #if (o == nil) or o.is_a?(SimpleExpRepresentation)
- #
- # grab the first process definition class found
- # in the given code
+ return o unless klass
- result = o.do_make
-
- return result.last.first if is_wrapped
-
- result
+ klass.do_make
end
protected
ClassNameRex = Regexp.compile(
" *class *([a-zA-Z0-9]*) *< .*ProcessDefinition")
- ProcessDefinitionRex = Regexp.compile(
- "^class *[a-zA-Z0-9]* *< .*ProcessDefinition")
+ #ProcessDefinitionRex = Regexp.compile(
+ # "^class *[a-zA-Z0-9]* *< .*ProcessDefinition")
ProcessNameAndDefRex = Regexp.compile(
"([^0-9_]*)_*([0-9].*)$")
ProcessNameRex = Regexp.compile(
"(.*$)")
EndsInDefinitionRex = Regexp.compile(
".*Definition$")
- def self.wrap_code (code)
-
- return [ code, false ] if ProcessDefinitionRex.match(code)
-
- s = "class NoName0 < ProcessDefinition"
- s << "\n"
- s << code
- s << "\nend"
-
- [ s, true ]
- end
-
def self.pack_args (args)
return args[0] if args.length == 1
a = {}
@@ -285,11 +287,11 @@
a
end
def self.extract_name_and_revision (s)
- i = s.rindex("::")
+ i = s.rindex('::')
s = s[i+2..-1] if i
m = ProcessNameAndDefRex.match s
return [ as_name(m[1]), as_revision(m[2]) ] if m
@@ -305,11 +307,11 @@
s
end
def self.as_revision (s)
- s.gsub("_", ".")
+ s.gsub('_', '.')
end
class Context
attr_accessor :parent_expression, :top_expressions
@@ -354,15 +356,16 @@
# This method returns the top expression among the
# top expressions...
#
def top_expression
- return nil if @top_expressions.size > 1
-
exp = @top_expressions.first
- return exp if exp.first == "process-definition"
- nil
+ return nil unless exp
+
+ exp_name = OpenWFE::to_underscore(exp[0])
+
+ DefineExpression.expression_names.include?(exp_name) ? exp : nil
end
end
end
end