openwferu 0.9.0

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.
Files changed (55) hide show
  1. data/README +47 -0
  2. data/lib/codec.rb +571 -0
  3. data/lib/controlclient.rb +115 -0
  4. data/lib/definitions.rb +112 -0
  5. data/lib/exception.rb +60 -0
  6. data/lib/flowexpressionid.rb +137 -0
  7. data/lib/openwferu.rb +43 -0
  8. data/lib/osocket.rb +138 -0
  9. data/lib/otime.rb +171 -0
  10. data/lib/restclient.rb +155 -0
  11. data/lib/ru/contextual.rb +63 -0
  12. data/lib/ru/dollar.rb +163 -0
  13. data/lib/ru/engine.rb +130 -0
  14. data/lib/ru/environment.rb +140 -0
  15. data/lib/ru/expressionmap.rb +120 -0
  16. data/lib/ru/expressionpool.rb +339 -0
  17. data/lib/ru/expressionstorage.rb +97 -0
  18. data/lib/ru/fe_base.rb +105 -0
  19. data/lib/ru/fe_concurrence.rb +122 -0
  20. data/lib/ru/fe_define.rb +101 -0
  21. data/lib/ru/fe_misc.rb +96 -0
  22. data/lib/ru/fe_participant.rb +75 -0
  23. data/lib/ru/fe_raw.rb +173 -0
  24. data/lib/ru/fe_subprocess.rb +84 -0
  25. data/lib/ru/fe_time.rb +135 -0
  26. data/lib/ru/fe_utils.rb +123 -0
  27. data/lib/ru/fe_value.rb +225 -0
  28. data/lib/ru/flowexpression.rb +250 -0
  29. data/lib/ru/logging.rb +85 -0
  30. data/lib/ru/participant.rb +67 -0
  31. data/lib/ru/participantmap.rb +93 -0
  32. data/lib/ru/participants.rb +74 -0
  33. data/lib/ru/rudefinitions.rb +70 -0
  34. data/lib/ru/ruutils.rb +68 -0
  35. data/lib/ru/scheduler.rb +478 -0
  36. data/lib/ru/schedulers.rb +63 -0
  37. data/lib/ru/service.rb +64 -0
  38. data/lib/test.rb +220 -0
  39. data/lib/utils.rb +94 -0
  40. data/lib/workitem.rb +250 -0
  41. data/lib/worklistclient.rb +276 -0
  42. data/test/dollartest.rb +79 -0
  43. data/test/feitest.rb +130 -0
  44. data/test/flowtestbase.rb +86 -0
  45. data/test/ft_0.rb +161 -0
  46. data/test/ft_1_unset.rb +152 -0
  47. data/test/ft_2_concurrence.rb +34 -0
  48. data/test/ft_3_equals.rb +84 -0
  49. data/test/ft_4_misc.rb +128 -0
  50. data/test/ft_5_time.rb +56 -0
  51. data/test/misctest.rb +46 -0
  52. data/test/runtest.rb +21 -0
  53. data/test/rutest_utils.rb +15 -0
  54. data/test/timetest.rb +111 -0
  55. metadata +100 -0
data/README ADDED
@@ -0,0 +1,47 @@
1
+ = OpenWFEru, Standard Library Documentation
2
+
3
+ == Prerequisites
4
+ Ruby 1.8.0 or later
5
+
6
+ == Supported platforms
7
+ TODO
8
+
9
+ == Installation
10
+ TODO
11
+
12
+ == Overview
13
+ OpenWFEru is a Ruby port of the OpenWFE workflow engine
14
+ (http://www.openwfe.org). It is a complete rewrite in Ruby
15
+ so does not need to use the Java-based engine from OpenWFE.
16
+
17
+ OpenWFEru was initially implemented in San Joaquin de Flores, Costa Rica.
18
+
19
+ One project goal for OpenWFEru is compatibility with its
20
+ Java based cousin so workflows defined for the Java engine
21
+ should work with the Ruby implementation. There are
22
+ some incompatibilities between each implementatio.
23
+
24
+ TODO: Document implementation differences
25
+
26
+ == Example
27
+
28
+ These are mostly stolen from the unit tests
29
+
30
+ Creating an workflow engine instance
31
+
32
+ require 'openwferu'
33
+
34
+ engine = OpenWFEru::Engine.new()
35
+ engine.register_participant('test-.*',
36
+ OpenWFEru::PrintParticipant.new())
37
+
38
+ == Documentation
39
+
40
+ The main project site lives at rubyforge at:
41
+ http://rubyforge.org/projects/openwferu
42
+
43
+ In the meantime the old site hosted at openwfe.org is at:
44
+ http://www.openwfe.org/openwfe-ruby.html
45
+
46
+ If you're interested in helping : john at openwfe dot org
47
+
data/lib/codec.rb ADDED
@@ -0,0 +1,571 @@
1
+ #
2
+ # Copyright (c) 2005-2006, John Mettraux, OpenWFE.org
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # . Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ #
11
+ # . Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # . Neither the name of the "OpenWFE" nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without
17
+ # specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # $Id: codec.rb 2865 2006-06-23 14:54:07Z jmettraux $
32
+ #
33
+
34
+ #
35
+ # "hecho en Costa Rica"
36
+ #
37
+
38
+ #require 'base64'
39
+ require 'rexml/document'
40
+
41
+ require 'definitions'
42
+ require 'utils'
43
+ require 'workitem'
44
+
45
+
46
+ module OpenWFE
47
+
48
+ #
49
+ # Takes as input some XML element and returns is decoded (as an instance)
50
+ #
51
+ def OpenWFE.decode (xmlElt)
52
+
53
+ return nil if not xmlElt
54
+
55
+ #puts "decode() xmlElt.name is >#{xmlElt.name}<"
56
+
57
+ return decodeList(xmlElt) if xmlElt.name == STORES
58
+ return decodeStore(xmlElt) if xmlElt.name == STORE
59
+ return decodeList(xmlElt) if xmlElt.name == HEADERS
60
+ return decodeHeader(xmlElt) if xmlElt.name == HEADER
61
+
62
+ return decodeLaunchOk(xmlElt) if xmlElt.name == OK
63
+
64
+ return decodeList(xmlElt) if xmlElt.name == HISTORY
65
+ return decodeHistoryItem(xmlElt) if xmlElt.name == HISTORY_ITEM
66
+
67
+ return decodeList(xmlElt) \
68
+ if xmlElt.name == FLOW_EXPRESSION_IDS
69
+ return decodeFlowExpressionId(xmlElt) \
70
+ if xmlElt.name == FLOW_EXPRESSION_ID
71
+
72
+ return decodeInFlowWorkItem(xmlElt) \
73
+ if xmlElt.name == IN_FLOW_WORKITEM
74
+
75
+ return decodeList(xmlElt) if xmlElt.name == LAUNCHABLES
76
+ return decodeLaunchable(xmlElt) if xmlElt.name == LAUNCHABLE
77
+
78
+ return decodeList(xmlElt) if xmlElt.name == EXPRESSIONS
79
+ return decodeExpression(xmlElt) if xmlElt.name == EXPRESSION
80
+
81
+ return decodeAttribute(xmlElt.elements[1]) if xmlElt.name == ATTRIBUTES
82
+
83
+ #
84
+ # default
85
+
86
+ return decodeAttribute(xmlElt)
87
+
88
+ #raise \
89
+ # ArgumentException, \
90
+ # "Cannot decode : '"+xmlElt.name+"' "+xmlElt.to_s()
91
+ end
92
+
93
+ #
94
+ # Takes some OpenWFE Ruby instance and returns it as XML
95
+ #
96
+ def OpenWFE.encode (owfeData)
97
+
98
+ #puts "encode() #{owfeData.inspect}"
99
+
100
+ return encodeLaunchItem(owfeData) \
101
+ if owfeData.kind_of?(LaunchItem)
102
+
103
+ return encodeFlowExpressionId(owfeData) \
104
+ if owfeData.kind_of?(FlowExpressionId)
105
+
106
+ return encodeInFlowWorkItem(owfeData) \
107
+ if owfeData.kind_of?(InFlowWorkItem)
108
+
109
+ raise \
110
+ ArgumentException, \
111
+ "Cannot encode : "+owfeData.inspect()
112
+ end
113
+
114
+ private
115
+
116
+
117
+ #
118
+ # DECODE
119
+ #
120
+
121
+ def OpenWFE.decodeList (xmlElt)
122
+
123
+ l = []
124
+
125
+ xmlElt.elements.each do |elt|
126
+ #puts " ... #{elt.inspect()}"
127
+ l.push(decode(elt))
128
+ end
129
+
130
+ return l
131
+ end
132
+
133
+
134
+ def OpenWFE.decodeLaunchable (xmlElt)
135
+
136
+ launchable = Launchable.new()
137
+
138
+ launchable.url = xmlElt.attributes[URL]
139
+ launchable.engineId = xmlElt.attributes[ENGINE_ID]
140
+
141
+ return launchable
142
+ end
143
+
144
+
145
+ def OpenWFE.decodeExpression (xmlElt)
146
+
147
+ exp = Expression.new()
148
+
149
+ #exp.id = decode(firstElement(xmlElt, "//"+FLOW_EXPRESSION_ID))
150
+ exp.id = decode(firstElement(xmlElt))
151
+
152
+ exp.applyTime = xmlElt.attributes[APPLY_TIME]
153
+ exp.state = xmlElt.attributes[STATE]
154
+ exp.stateSince = xmlElt.attributes[STATE_SINCE]
155
+
156
+ return exp
157
+ end
158
+
159
+
160
+ def OpenWFE.decodeStore (xmlElt)
161
+
162
+ store = Store.new()
163
+
164
+ store.name = xmlElt.attributes[NAME]
165
+ store.workitemCount = xmlElt.attributes[WORKITEM_COUNT]
166
+ store.workitemCount = Integer(store.workitemCount)
167
+ store.permissions = xmlElt.attributes[PERMISSIONS]
168
+
169
+ return store
170
+ end
171
+
172
+
173
+ def OpenWFE.decodeHeader (xmlElt)
174
+
175
+ header = Header.new()
176
+
177
+ header.lastModified = xmlElt.attributes[A_LAST_MODIFIED]
178
+ header.locked = parseBoolean(xmlElt.attributes[A_LOCKED])
179
+ header.flowExpressionId = decode(firstElement(xmlElt, FLOW_EXPRESSION_ID))
180
+ header.attributes = decode(firstElement(xmlElt, ATTRIBUTES))
181
+
182
+ return header
183
+ end
184
+
185
+
186
+ def OpenWFE.decodeFlowExpressionId (xmlElt)
187
+
188
+ fei = FlowExpressionId.new()
189
+
190
+ fei.owfeVersion = xmlElt.attributes[OWFE_VERSION]
191
+ fei.engineId = xmlElt.attributes[ENGINE_ID]
192
+ fei.initialEngineId = xmlElt.attributes[INITIAL_ENGINE_ID]
193
+
194
+ fei.workflowDefinitionUrl = xmlElt.attributes[WORKFLOW_DEFINITION_URL]
195
+ fei.workflowDefinitionName = xmlElt.attributes[WORKFLOW_DEFINITION_NAME]
196
+ fei.workflowDefinitionRevision = xmlElt.attributes[WORKFLOW_DEFINITION_REVISION]
197
+
198
+ fei.workflowInstanceId = xmlElt.attributes[WORKFLOW_INSTANCE_ID]
199
+
200
+ fei.expressionName = xmlElt.attributes[EXPRESSION_NAME]
201
+ fei.expressionId = xmlElt.attributes[EXPRESSION_ID]
202
+
203
+ #puts " ... fei.expressionName is >#{fei.expressionName}<"
204
+ #puts " ... fei.wfid is >#{fei.workflowInstanceId}<"
205
+
206
+ return fei
207
+ end
208
+
209
+
210
+ def OpenWFE.decodeAttribute (xmlElt)
211
+
212
+ #puts "decodeAttribute() '#{xmlElt.name}' --> '#{xmlElt.text}'"
213
+
214
+ #
215
+ # atomic types
216
+
217
+ return xmlElt.text if xmlElt.name == E_STRING
218
+ return Integer(xmlElt.text) if xmlElt.name == E_INTEGER
219
+ return Integer(xmlElt.text) if xmlElt.name == E_LONG
220
+ return Float(xmlElt.text) if xmlElt.name == E_DOUBLE
221
+ return parseBoolean(xmlElt.text) if xmlElt.name == E_BOOLEAN
222
+
223
+ return xmlElt if xmlElt.name == E_XML
224
+
225
+ return Base64Attribute.new(xmlElt.txt) if xmlElt.name == E_BASE64
226
+
227
+ #
228
+ # composite types
229
+
230
+ return decodeList(xmlElt) if xmlElt.name == E_LIST
231
+
232
+ if xmlElt.name == E_SMAP or xmlElt.name == E_MAP
233
+
234
+ map = {}
235
+ map[MAP_TYPE] = xmlElt.name
236
+
237
+ #xmlElt.elements.each("//"+M_ENTRY) do |e|
238
+ xmlElt.elements.each(M_ENTRY) do |e|
239
+ #puts "decodeAttribute() >#{e}<"
240
+ decodeEntry(e, map)
241
+ end
242
+
243
+ return map
244
+ end
245
+
246
+ #puts docToString(xmlElt.document())
247
+
248
+ raise \
249
+ ArgumentError, \
250
+ "Cannot decode <#{xmlElt.name}/> in \n"+\
251
+ docToString(xmlElt.document())
252
+ end
253
+
254
+ def OpenWFE.decodeEntry (xmlElt, map)
255
+
256
+ key = xmlElt.elements[1]
257
+ val = xmlElt.elements[2]
258
+
259
+ #
260
+ # this parse method supports the old style and the [new] light
261
+ # style/schema
262
+ #
263
+
264
+ key = key.elements[1] if key.name == M_KEY
265
+ val = val.elements[1] if val.name == M_VALUE
266
+
267
+ key = decode(key)
268
+ val = decode(val)
269
+
270
+ #puts "decodeEntry() k >#{key}< v >#{val}<"
271
+ #puts "decodeEntry() subject '#{val}'" if key == '__subject__'
272
+
273
+ map[key] = val
274
+ end
275
+
276
+ def OpenWFE.parseBoolean (string)
277
+
278
+ return string.strip.downcase == 'true'
279
+ end
280
+
281
+ def OpenWFE.decodeHistoryItem (xmlElt)
282
+
283
+ hi = HistoryItem.new
284
+
285
+ hi.author = xmlElt.attributes[A_AUTHOR]
286
+ hi.date = xmlElt.attributes[A_DATE]
287
+ hi.host = xmlElt.attributes[A_HOST]
288
+ hi.text = xmlElt.text
289
+
290
+ hi.wfdName = xmlElt.attributes[WORKFLOW_DEFINITION_NAME]
291
+ hi.wfdRevision = xmlElt.attributes[WORKFLOW_DEFINITION_REVISION]
292
+ hi.wfInstanceId = xmlElt.attributes[WORKFLOW_INSTANCE_ID]
293
+ hi.expressionId = xmlElt.attributes[EXPRESSION_ID]
294
+
295
+ return hi
296
+ end
297
+
298
+
299
+ def OpenWFE.decodeLaunchOk (xmlElt)
300
+
301
+ sFei = xmlElt.attributes[A_FLOW_ID]
302
+
303
+ return true if not sFei
304
+
305
+ return FlowExpressionId.strToFei(sFei)
306
+ end
307
+
308
+
309
+ def OpenWFE.decodeInFlowWorkItem (xmlElt)
310
+
311
+ wi = InFlowWorkItem.new()
312
+
313
+ wi.lastModified = xmlElt.attributes[A_LAST_MODIFIED]
314
+ wi.attributes = decode(firstElement(xmlElt, ATTRIBUTES))
315
+
316
+ wi.participantName = xmlElt.attributes[A_PARTICIPANT_NAME]
317
+ wi.flowExpressionId = decode(firstElement(firstElement(xmlElt, E_LAST_EXPRESSION_ID), FLOW_EXPRESSION_ID))
318
+
319
+ wi.dispatchTime = xmlElt.attributes[A_DISPATCH_TIME]
320
+
321
+ # TODO : decode filter
322
+
323
+ wi.history = decode(firstElement(xmlElt, HISTORY))
324
+
325
+ return wi
326
+ end
327
+
328
+
329
+ #
330
+ # ENCODE
331
+ #
332
+
333
+ def OpenWFE.docToString (xml, decl=true)
334
+
335
+ s = ""
336
+
337
+ if decl and xml[0].kind_of? REXML::XMLDecl
338
+ xml << REXML::XMLDecl.new()
339
+ end
340
+
341
+ xml.write(s, 0)
342
+ return s
343
+ end
344
+
345
+
346
+ def OpenWFE.encodeItem (item, elt)
347
+
348
+ elt.attributes[A_LAST_MODIFIED] = item.lastModified
349
+
350
+ eAttributes = REXML::Element.new(ATTRIBUTES)
351
+
352
+ eAttributes << encodeAttribute(item.attributes)
353
+
354
+ elt << eAttributes
355
+ end
356
+
357
+
358
+ def OpenWFE.encodeLaunchItem (launchitem)
359
+
360
+ doc = REXML::Document.new()
361
+
362
+ root = REXML::Element.new(E_LAUNCHITEM)
363
+
364
+ encodeItem(launchitem, root)
365
+
366
+ root.attributes[WORKFLOW_DEFINITION_URL] = \
367
+ launchitem.workflowDefinitionUrl
368
+
369
+ # TODO :
370
+ #
371
+ # - encode descriptionMap
372
+ #
373
+ # - replyTo is not necessary
374
+
375
+ #doc.root = root
376
+ doc << root
377
+
378
+ return docToString(doc)
379
+ end
380
+
381
+
382
+ def OpenWFE.encodeInFlowItem (item, elt)
383
+
384
+ encodeItem(item, elt)
385
+
386
+ elt.attributes[A_PARTICIPANT_NAME] = item.participantName
387
+
388
+ eLastExpressionId = REXML::Element.new(E_LAST_EXPRESSION_ID)
389
+
390
+ eLastExpressionId << encodeFlowExpressionId(item.lastExpressionId)
391
+
392
+ elt << eLastExpressionId
393
+ end
394
+
395
+
396
+ def OpenWFE.encodeInFlowWorkItem (item)
397
+
398
+ doc = REXML::Document.new()
399
+
400
+ root = REXML::Element.new(IN_FLOW_WORKITEM)
401
+
402
+ encodeInFlowItem(item, root)
403
+
404
+ root.attributes[A_DISPATCH_TIME] = item.dispatchTime
405
+
406
+ # add filter ? no
407
+
408
+ encodeHistory(item, root)
409
+
410
+ doc << root
411
+
412
+ s = docToString(doc)
413
+ #puts "encoded :\n#{s}"
414
+ return s
415
+ end
416
+
417
+
418
+ def OpenWFE.encodeHistory (item, elt)
419
+
420
+ eHistory = REXML::Element.new(HISTORY)
421
+
422
+ item.history.each do |hi|
423
+
424
+ ehi = REXML::Element.new(HISTORY_ITEM)
425
+
426
+ ehi.attributes[A_AUTHOR] = hi.author
427
+ ehi.attributes[A_DATE] = hi.date
428
+ ehi.attributes[A_HOST] = hi.host
429
+
430
+ ehi.attributes[WORKFLOW_DEFINITION_NAME] = hi.wfdName
431
+ ehi.attributes[WORKFLOW_DEFINITION_REVISION] = hi.wfdRevision
432
+ ehi.attributes[WORKFLOW_INSTANCE_ID] = hi.wfInstanceId
433
+ ehi.attributes[EXPRESSION_ID] = hi.expressionId
434
+
435
+ eHistory << ehi
436
+ end
437
+
438
+ elt << eHistory
439
+ end
440
+
441
+
442
+ def OpenWFE.encodeAttribute (att)
443
+
444
+ #puts "encodeAttribute() att.class is #{att.class}"
445
+
446
+ return encodeAtomicAttribute(E_STRING, att) \
447
+ if att.kind_of? String
448
+ return encodeAtomicAttribute(E_INTEGER, att) \
449
+ if att.kind_of? Fixnum
450
+ return encodeAtomicAttribute(E_DOUBLE, att) \
451
+ if att.kind_of? Float
452
+
453
+ return encodeXmlAttribute(att) \
454
+ if att.kind_of? REXML::Element
455
+
456
+ return encodeAtomicAttribute(E_BOOLEAN, true) \
457
+ if att.kind_of? TrueClass
458
+ return encodeAtomicAttribute(E_BOOLEAN, false) \
459
+ if att.kind_of? FalseClass
460
+
461
+ return encodeBase64Attribute(att) \
462
+ if att.kind_of? Base64Attribute
463
+
464
+ #
465
+ # missing : BASE64...
466
+
467
+ return encodeMapAttribute(att) if att.kind_of? Hash
468
+ return encodeListAttribute(att) if att.kind_of? Array
469
+
470
+ #
471
+ # default
472
+
473
+ return encodeAtomicAttribute(E_STRING, att)
474
+
475
+ #raise \
476
+ # ArgumentException, \
477
+ # "Cannot encode attribute of class '#{att.class}'"
478
+ end
479
+
480
+
481
+ def OpenWFE.encodeXmlAttribute (elt)
482
+
483
+ return elt if elt.name == E_XML
484
+
485
+ #
486
+ # else, wrap within <raw-xml>...</raw-xml>
487
+
488
+ e = REXML::Element.new(E_XML)
489
+ e << elt
490
+
491
+ return e
492
+ end
493
+
494
+
495
+ def OpenWFE.encodeBase64Attribute (att)
496
+
497
+ e = REXML::Element.new(E_BASE64)
498
+ e.text = att.content
499
+
500
+ return e
501
+ end
502
+
503
+
504
+ def OpenWFE.encodeAtomicAttribute (name, value)
505
+
506
+ elt = REXML::Element.new(name)
507
+ #elt << REXML::Text.new(value.to_s())
508
+ elt.add_text(value.to_s())
509
+
510
+ return elt
511
+ end
512
+
513
+
514
+ def OpenWFE.encodeListAttribute (list)
515
+
516
+ elt = REXML::Element.new(E_LIST)
517
+
518
+ list.each do |e|
519
+ elt << encodeAttribute(e)
520
+ end
521
+
522
+ return elt
523
+ end
524
+
525
+
526
+ def OpenWFE.encodeMapAttribute (hash)
527
+
528
+ name = hash[MAP_TYPE]
529
+ name = 'map' if name == nil
530
+
531
+ elt = REXML::Element.new(name)
532
+
533
+ hash.each_key do |key|
534
+
535
+ next if key == MAP_TYPE
536
+
537
+ eEntry = REXML::Element.new(M_ENTRY)
538
+
539
+ val = hash[key]
540
+
541
+ eEntry << encodeAttribute(key)
542
+ eEntry << encodeAttribute(val)
543
+
544
+ elt << eEntry
545
+ end
546
+
547
+ return elt
548
+ end
549
+
550
+
551
+ def OpenWFE.encodeFlowExpressionId (fei)
552
+
553
+ elt = REXML::Element.new(FLOW_EXPRESSION_ID)
554
+
555
+ elt.attributes[OWFE_VERSION] = fei.owfeVersion
556
+ elt.attributes[ENGINE_ID] = fei.engineId
557
+ elt.attributes[INITIAL_ENGINE_ID] = fei.initialEngineId
558
+
559
+ elt.attributes[WORKFLOW_DEFINITION_URL] = fei.workflowDefinitionUrl
560
+ elt.attributes[WORKFLOW_DEFINITION_NAME] = fei.workflowDefinitionName
561
+ elt.attributes[WORKFLOW_DEFINITION_REVISION] = fei.workflowDefinitionRevision
562
+ elt.attributes[WORKFLOW_INSTANCE_ID] = fei.workflowInstanceId
563
+
564
+ elt.attributes[EXPRESSION_NAME] = fei.expressionName
565
+ elt.attributes[EXPRESSION_ID] = fei.expressionId
566
+
567
+ return elt
568
+ end
569
+
570
+ end
571
+