| GONE | = | "gone" | ||
| GONE_PARENT_ID | = | FlowExpressionId.new | This special flow expression id is used by the forget() method (which is used by the forget expression and the concurrence synchronization expressions) | |
| SPLIT_MAP | = | { "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" => UuidWfidGenerator, "[0-9]{8}-[a-z]*" => KotobaWfidGenerator | "module methods" | |
| VAR_PAUSED | = | '/__paused__' | When this variable is set to true (at the process root), it means the process is paused. | |
| KEYWORDS | = | [ :if, :do, :redo, :undo, :print, :sleep, :loop, :break, :when |
OpenWFE process definitions do use some Ruby
keywords… The workaround is to put an underscore just before the name
to ‘escape’ it.
‘undo’ isn‘t reserved by Ruby, but lets keep it in line with ‘do’ and ‘redo’ that are. |
|
| NAME | = | 'name' | ||
| STORE | = | 'store' | ||
| STORES | = | 'stores' | ||
| WORKITEM_COUNT | = | 'workitem-count' | ||
| PERMISSIONS | = | 'permissions' | ||
| HEADER | = | 'header' | ||
| HEADERS | = | 'headers' | ||
| A_LAST_MODIFIED | = | 'last-modified' | ||
| A_LOCKED | = | 'locked' | ||
| FLOW_EXPRESSION_ID | = | 'flow-expression-id' | ||
| ATTRIBUTES | = | 'attributes' | ||
| OWFE_VERSION | = | 'owfe-version' | ||
| ENGINE_ID | = | 'engine-id' | ||
| INITIAL_ENGINE_ID | = | 'initial-engine-id' | ||
| WORKFLOW_DEFINITION_URL | = | 'workflow-definition-url' | ||
| WORKFLOW_DEFINITION_NAME | = | 'workflow-definition-name' | ||
| WORKFLOW_DEFINITION_REVISION | = | 'workflow-definition-revision' | ||
| WORKFLOW_INSTANCE_ID | = | 'workflow-instance-id' | ||
| EXPRESSION_NAME | = | 'expression-name' | ||
| EXPRESSION_ID | = | 'expression-id' | ||
| E_STRING | = | 'string' | ||
| E_INTEGER | = | 'integer' | ||
| E_BOOLEAN | = | 'boolean' | ||
| E_LONG | = | 'long' | ||
| E_DOUBLE | = | 'double' | ||
| E_RAW_XML | = | 'raw-xml' | ||
| E_XML_DOCUMENT | = | 'xml-document' | ||
| E_BASE64 | = | 'base64' | ||
| E_LIST | = | 'list' | ||
| E_MAP | = | 'map' | ||
| E_SMAP | = | 'smap' | ||
| M_ENTRY | = | 'entry' | ||
| M_KEY | = | 'key' | ||
| M_VALUE | = | 'value' | ||
| MAP_TYPE | = | '___map_type' | ||
| FLOW_EXPRESSION_IDS | = | 'flow-expression-ids' | ||
| LAUNCHITEM | = | 'launchitem' | ||
| ENGINEID | = | "engineid" | ||
| OK | = | "ok" | ||
| A_FLOW_ID | = | "flow-id" | ||
| IN_FLOW_WORKITEM | = | 'workitem' | ||
| A_DISPATCH_TIME | = | 'dispatch-time' | ||
| A_PARTICIPANT_NAME | = | 'participant-name' | ||
| E_LAST_EXPRESSION_ID | = | 'last-expression-id' | ||
| LAUNCHABLES | = | 'launchables' | ||
| LAUNCHABLE | = | 'launchable' | ||
| URL | = | 'url' | ||
| TARGETSTORE | = | 'targetstore' | ||
| EXPRESSIONS | = | 'expressions' | ||
| EXPRESSION | = | 'expression' | ||
| APPLY_TIME | = | 'apply-time' | ||
| STATE | = | 'state' | ||
| STATE_SINCE | = | 'state-since' | ||
| HISTORY | = | 'history' | ||
| HISTORY_ITEM | = | 'history-item' | ||
| A_AUTHOR | = | 'author' | ||
| A_DATE | = | 'date' | ||
| A_HOST | = | 'host' | ||
| S_LOGGER | = | :logger | service names | |
| S_ENGINE | = | 'engine' | ||
| S_EXPRESSION_MAP | = | 'expressionMap' | ||
| S_WFID_GENERATOR | = | 'wfidGenerator' | ||
| S_EXPRESSION_POOL | = | 'expressionPool' | ||
| S_EXPRESSION_STORAGE | = | 'expressionStorage' | ||
| S_PARTICIPANT_MAP | = | 'participantMap' | ||
| S_SCHEDULER | = | 'scheduler' | ||
| S_ERROR_JOURNAL | = | 'errorJournal' | ||
| EN_ENVIRONMENT | = | 'environment' | some special expression names | |
| DEFAULT_WORK_DIRECTORY | = | 'work' | some file storage default values | |
| DSUB_SAFETY_LEVEL | = | 4 | ||
| OPENWFERU_VERSION | = | '0.9.18' | ||
| FIELD_RESULT | = | "__result__" | The convention for the result of some expressions is to store their result in a workitem field named "result". |
Some code for writing thinks like :
if async
OpenWFE::call_in_thread "launch()", self do
raw_expression.apply(wi)
end
else
raw_expression.apply(wi)
end
Returns the new thread instance.
# File lib/openwfe/utils.rb, line 291
291: def OpenWFE.call_in_thread (caller_name, caller_object=nil, &block)
292:
293: return unless block
294:
295: Thread.new do
296:
297: #set_current_thread_name "call_in_thread() for '#{caller_name}'"
298: set_current_thread_name caller_name
299:
300: begin
301: #$SAFE = safe_level
302: #
303: # (note)
304: # doesn't work : the block inherits the safety level
305: # of its surroundings, it's a closure, ne ?
306:
307: block.call
308:
309: rescue Exception => e
310: msg = "#{caller_name} caught an exception\n" + exception_to_s(e)
311: if caller_object and caller_object.respond_to? :lwarn
312: caller_object.lwarn { msg }
313: else
314: puts msg
315: end
316: end
317: end
318: # returns the thread
319: end
Pretty printing a caller() array
# File lib/openwfe/utils.rb, line 256
256: def OpenWFE.caller_to_s (start_index, max_lines=nil)
257: s = ""
258: caller(start_index + 1).each_with_index do |line, index|
259: break if max_lines and index >= max_lines
260: s << " #{line}\n"
261: end
262: s
263: end
"my//path" -> "my/path"
# File lib/openwfe/utils.rb, line 381
381: def OpenWFE.clean_path (s)
382: s.gsub(/\/+/, "/")
383: end
see wiki.rubygarden.org/Ruby/page/show/Make_A_Deep_Copy_Of_An_Object
It‘s not perfect (that‘s why fulldup() uses it only in certain cases).
For example :
TypeError: singleton can't be dumped
./lib/openwfe/utils.rb:74:in `dump'
./lib/openwfe/utils.rb:74:in `deep_clone'
# File lib/openwfe/utils.rb, line 72
72: def OpenWFE.deep_clone (object)
73:
74: Marshal::load(Marshal.dump(object))
75: end
Dispatches a workitem over TCP, the workitem will be encoded with XML The default encode_method is
# File lib/openwfe/orest/osocket.rb, line 93
93: def OpenWFE.dispatch_workitem (host, port, workitem)
94:
95: #sXml = OpenWFE.xml_encode(workitem)
96: sXml = OpenWFE::XmlCodec::encode workitem
97:
98: socket = TCPSocket.new(host, port)
99: socket.puts "xmlCoder #{sXml.length}"
100: socket.puts
101: socket.puts sXml
102: socket.puts
103: socket.close_write
104:
105: reply = socket.gets
106:
107: #reply = reply + socket.gets
108: #
109: # a bit ridiculous, but it works
110: # socket.close_write fixed it
111:
112: socket.close
113:
114: #puts "dispatch() reply is >#{reply}<"
115: end
Performs ‘dollar substitution’ on a piece of text with as input a flow expression and a workitem (fields and variables).
# File lib/openwfe/util/dollar.rb, line 62
62: def OpenWFE.dosub (text, flow_expression, workitem)
63:
64: #
65: # patch by Nick Petrella (2008/03/20)
66: #
67:
68: if text.is_a?(String)
69:
70: Rufus::dsub(text, FlowDict.new(flow_expression, workitem))
71:
72: elsif text.is_a?(Array)
73:
74: text.collect { |e| dosub(e, flow_expression, workitem) }
75:
76: elsif text.is_a?(Hash)
77:
78: text.inject({}) do |r, (k, v)|
79:
80: r[dosub(k, flow_express, workitem)] =
81: dosub(v, flow_expression, workitem)
82: r
83: end
84:
85: else
86:
87: text
88: end
89: end
Returns true if the given string ends with the ‘_end’ string.
# File lib/openwfe/utils.rb, line 237
237: def OpenWFE.ends_with (string, _end)
238: return false unless string
239: return false if string.length < _end.length
240: string[-_end.length..-1] == _end
241: end
Returns a version of s that is usable as or within a filename (removes for examples things like ’/’ or ’\’…)
# File lib/openwfe/utils.rb, line 364
364: def OpenWFE.ensure_for_filename (s)
365:
366: s = s.gsub(" ", "_")
367: s = s.gsub("/", "_")
368: s = s.gsub(":", "_")
369: s = s.gsub(";", "_")
370: s = s.gsub("\*", "_")
371: s = s.gsub("\\", "_")
372: s = s.gsub("\+", "_")
373: s = s.gsub("\?", "_")
374:
375: s
376: end
Attempts at displaying a nice stack trace
# File lib/openwfe/utils.rb, line 246
246: def OpenWFE.exception_to_s (exception)
247: s = "exception : "
248: s << "#{exception}\n"
249: s << exception.backtrace.join("\n")
250: s
251: end
Returns the first subelt of xmlElt that matches the given xpath. If xpath is null, the first elt will be returned.
# File lib/openwfe/utils.rb, line 51
51: def OpenWFE.first_element (xmlElt, elementName=nil)
52:
53: return nil if not xmlElt
54:
55: return xmlElt.elements[1] if not elementName
56:
57: xmlElt.elements.detect { |elt| elt.name == elementName }
58: end
an automatic dup implementation attempt
# File lib/openwfe/utils.rb, line 80
80: def OpenWFE.fulldup (object)
81:
82: return nil if object == nil
83:
84: return object.fulldup if object.respond_to?("fulldup")
85: # trusting client objects providing a fulldup() implementation
86: # Tomaso Tosolini 2007.12.11
87:
88: return object if object.kind_of?(Float)
89: return object if object.kind_of?(Fixnum)
90: return object if object.kind_of?(TrueClass)
91: return object if object.kind_of?(FalseClass)
92: return object if object.kind_of?(Symbol)
93:
94: return object.dup if object.kind_of?(String)
95:
96: #return deep_clone(object) if object.kind_of? REXML::Document
97:
98: #return REXML::Document.new(object.to_s) # if object.kind_of? REXML::Document
99:
100: if object.kind_of?(REXML::Element)
101: d = REXML::Document.new object.to_s
102: return d if object.kind_of?(REXML::Document)
103: return d.root
104: end
105:
106: return Rational(object.denominator, object.numerator) \
107: if object.kind_of?(Rational)
108:
109: o = nil
110:
111: begin
112: o = object.class.new
113: rescue ArgumentError => ae
114: return deep_clone(object)
115: end
116:
117: #
118: # some kind of collection ?
119:
120: if object.kind_of?(Array)
121: object.each do |i|
122: o << fulldup(i)
123: end
124: elsif object.kind_of?(Hash)
125: object.each do |k, v|
126: o[fulldup(k)] = fulldup(v)
127: end
128: end
129:
130: #
131: # duplicate the attributes of the object
132:
133: object.instance_variables.each do |v|
134:
135: #puts "v is #{v}"
136:
137: value = object.instance_variable_get(v)
138:
139: #puts "value is '#{value}'"
140:
141: value = fulldup(value)
142:
143: begin
144: o.instance_variable_set(v, value)
145: rescue
146: # ignore, must be readonly
147: end
148: end
149:
150: o
151: end
# File lib/openwfe/workitem.rb, line 481
481: def OpenWFE.get_class (h)
482:
483: cl = h[:type]
484: return nil if cl.index(";")
485: return nil if cl.index(" ")
486: eval(cl)
487: end
Returns a list of lines matching the pattern in the given file.
This is also possible :
OpenWFE::grep "^..) ", "path/to/file.txt" do |line|
puts " - '#{line.downcase}'"
end
TODO : find a ruby library and use it instead of that code
# File lib/openwfe/utils.rb, line 441
441: def OpenWFE.grep (pattern, filepath, &block)
442:
443: result = []
444: r = Regexp.new pattern
445:
446: File.open filepath do |file|
447: file.readlines.each do |l|
448: if r.match l
449: if block
450: block.call l
451: else
452: result << l
453: end
454: end
455: end
456: end
457: result unless block
458: end
This method is used within the InFlowWorkItem and the CsvTable classes.
# File lib/openwfe/utils.rb, line 410
410: def OpenWFE.has_attribute? (container, key)
411:
412: key, last_key = pop_last_key(key)
413:
414: container = lookup_attribute(container, key) if key
415:
416: if container.respond_to?(:has_key?)
417:
418: (container.has_key?(last_key) or container.has_key?(last_key.to_s))
419:
420: elsif container.is_a?(Array) and last_key.is_a?(Fixnum)
421:
422: (last_key < container.length)
423:
424: else
425:
426: false
427: end
428: end
This method is used within the InFlowWorkItem and the CsvTable classes.
# File lib/openwfe/utils.rb, line 388
388: def OpenWFE.lookup_attribute (container, key)
389:
390: key, rest = pop_key(key)
391:
392: #value = nil
393: #begin
394: # value = container[key]
395: #rescue Exception => e
396: #end
397:
398: value = flex_lookup(container, key)
399:
400: return value unless rest
401:
402: return nil unless value
403:
404: lookup_attribute(value, rest)
405: end
# File lib/openwfe/utils.rb, line 169
169: def OpenWFE.name_to_symbol (name)
170:
171: return name if name.is_a?(Symbol)
172: to_underscore(name).intern
173: end
Returns a URI instance if the given ref is a http, https, file or ftp URI. Returns nil else. The sister method parse_uri() is OK with things like mailto:, gopher:, …
# File lib/openwfe/utils.rb, line 205
205: def OpenWFE.parse_known_uri (ref)
206:
207: uri = OpenWFE::parse_uri(ref.to_s)
208:
209: return nil unless uri
210:
211: return uri if uri.scheme == "file"
212: return uri if uri.scheme == "http"
213: return uri if uri.scheme == "https"
214: return uri if uri.scheme == "ftp"
215: # what else ...
216:
217: nil
218: end
Returns an URI if the string is one, else returns nil. No exception is thrown by this method.
# File lib/openwfe/utils.rb, line 188
188: def OpenWFE.parse_uri (string)
189:
190: return nil if string.split("\n").size > 1
191:
192: begin
193: return URI::parse(string)
194: rescue Exception => e
195: end
196:
197: nil
198: end
Renders a nice, terminal oriented, representation of an Engine.get_process_status() result.
You usually directly benefit from this when doing
puts engine.get_process_status.to_s
# File lib/openwfe/engine/status_methods.rb, line 241
241: def OpenWFE.pretty_print_process_status (ps)
242:
243: # TODO : include launch_time and why is process_id so long ?
244:
245: s = ""
246: s << "process_id | name | rev | brn | err | paused? \n"
247: s << "--------------------+-------------------+---------+-----+-----+---------\n"
248:
249: ps.keys.sort.each do |wfid|
250:
251: status = ps[wfid]
252: fexp = status.expressions.first
253: ffei = fexp.fei
254:
255: s << "%-19s" % wfid[0, 19]
256: s << " | "
257: s << "%-17s" % ffei.workflow_definition_name[0, 17]
258: s << " | "
259: s << "%-7s" % ffei.workflow_definition_revision[0, 7]
260: s << " | "
261: s << "%3s" % status.expressions.size.to_s[0, 3]
262: s << " | "
263: s << "%3s" % status.errors.size.to_s[0, 3]
264: s << " | "
265: s << "%5s" % status.paused?.to_s
266: s << "\n"
267: end
268: s
269: end
This method is used within the InFlowWorkItem and the CsvTable classes.
# File lib/openwfe/utils.rb, line 463
463: def OpenWFE.set_attribute (container, key, value)
464:
465: i = key.rindex(".")
466:
467: if not i
468: container[key] = value
469: return
470: end
471:
472: container = lookup_attribute(container, key[0..i-1])
473: container[key[i+1..-1]] = value
474: end
Sets the name of the current thread (the attribute :name if it is a ruby thread, the java thread name if we‘re in JRuby)
# File lib/openwfe/utils.rb, line 269
269: def OpenWFE.set_current_thread_name (name)
270: if defined?(JRUBY_VERSION)
271: require 'java'
272: java.lang.Thread.current_thread.name = "#{name} (Ruby Thread)"
273: else
274: Thread.current[:name] = name
275: end
276: end
This method should be able to split any wfid whose scheme is implemented here.
# File lib/openwfe/expool/wfidgen.rb, line 376
376: def OpenWFE.split_wfid (wfid)
377:
378: SPLIT_MAP.each do |regex, clazz|
379: return clazz.split_wfid(wfid) if wfid.match(regex)
380: end
381: #
382: # else
383: #
384: DefaultWfidGenerator.split_wfid(wfid)
385: end
Returns true if the given string starts with the ‘start’ string.
# File lib/openwfe/utils.rb, line 223
223: def OpenWFE.starts_with (string, start)
224: #
225: # my favourite way of doing that would be by adding this
226: # method to the String class, but that could be intrusive
227: # (as OpenWFE is meant at first as an embeddable workflow engine).
228: #
229: return false unless string
230: return false if string.length < start.length
231: string[0, start.length] == start
232: end
Turns all the spaces in string into underscores. Returns the new String.
# File lib/openwfe/utils.rb, line 179
179: def OpenWFE.stu (s)
180:
181: s.gsub("\s", "_")
182: end
# File lib/openwfe/utils.rb, line 164
164: def OpenWFE.symbol_to_name (symbol)
165:
166: to_dash(symbol.to_s)
167: end
# File lib/openwfe/utils.rb, line 159
159: def OpenWFE.to_dash (string)
160:
161: string.gsub("_", "-")
162: end
# File lib/openwfe/utils.rb, line 154
154: def OpenWFE.to_underscore (string)
155:
156: string.gsub("-", "_")
157: end
Binds the SIGINT signal so that a console is opened with the bindings specified in ‘args’.
# File lib/openwfe/util/irb.rb, line 57
57: def OpenWFE.trap_int_irb (*args)
58: trap 'INT' do
59: OpenWFE.start_irb_session(*args)
60: #OpenWFE.trap_int_irb(*args) if $openwfe_irb
61: OpenWFE.trap_int_irb(*args)
62: end
63: end
This method is used within the InFlowWorkItem and the CsvTable classes.
# File lib/openwfe/utils.rb, line 479
479: def OpenWFE.unset_attribute (container, key)
480:
481: i = key.rindex(".")
482:
483: if not i
484: container.delete key
485: return
486: end
487:
488: container = lookup_attribute container, key[0..i-1]
489:
490: if container.is_a?(Array)
491:
492: container.delete_at key[i+1..-1].to_i
493: else
494:
495: container.delete key[i+1..-1]
496: end
497: end
Turns a hash into its corresponding workitem (InFlowWorkItem, CancelItem, LaunchItem).
# File lib/openwfe/workitem.rb, line 474
474: def OpenWFE.workitem_from_h (h)
475:
476: #wi_class = eval(h[:type])
477: wi_class = get_class(h)
478: wi_class.from_h(h)
479: end
An alias for OpenWFE::xmldoc_to_string()
# File lib/openwfe/orest/xmlcodec.rb, line 649
649: def OpenWFE.xml_to_s (xml, decl=true)
650:
651: OpenWFE::xmldoc_to_string(xml, decl)
652: end