My favorites | Sign in
Project Home Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
/**
* Completes the functionality and logic of {@model Gate}s within {@model Frame}s and {@model Scope}s.
*/
#created on: 4/11/2008
package org.openiaml.model.drools.rules.gate

#list any import classes here.
import org.openiaml.model.drools.*;

import org.openiaml.model.inference.*;
import org.openiaml.model.model.*;
import org.openiaml.model.model.impl.*;
import org.openiaml.model.model.wires.*;
import org.openiaml.model.model.visual.*;
import org.openiaml.model.model.operations.*;
import org.openiaml.model.model.scopes.*;
import org.openiaml.model.model.components.*;
import org.openiaml.model.model.users.*;

#declare any global variables here
global OverridableCreateElementsHelper handler;
global DroolsInsertionQueue queue;
global DroolsHelperFunctions functions;

/**
* @inference Gate
* A {@model Gate} referencing a {@model Frame},
* with an outgoing {@model ECARule} named 'first', 'last' or 'fail',
* will create a {@model Button} named 'continue' in the referenced {@model Frame}.
*/
rule "Create 'Continue' button for Frames connected with 'first' or 'last' or 'fail' ECARule"
when
gate : Gate ( )
tf : Frame ( )
nav : ECARule ( trigger == gate, target == tf, name == "first" || name == "last" || name == "fail" )

not (Button ( eContainer == tf, name == "Continue" ))
not (ECARule ( target == gate ))

eval ( handler.veto( gate ))

then
Button button = handler.generatedButton(gate, tf);
handler.setName(button, "Continue");
queue.add(button, drools);

end

/**
* @inference Gate
* The 'continue' {@model Button} generated for a {@model Gate},
* with an outgoing {@model ECARule} named 'first', 'last' or 'fail',
* will execute the {@model Gate}
* when {@model Button#onClick clicked}.
*/
rule "Connect 'click' on 'Continue' button to resume Gate"
when
gate : Gate ( )
tf : Frame ( )
nav : ECARule ( trigger == gate, target == tf, name == "first" || name == "last" || name == "fail" )
button : Button ( eContainer == tf, name == "Continue" )

click : Event ( button.onClick == click, eContainer == button )

not (ECARule ( trigger == click, target == gate ))

eval ( handler.veto( gate ))

then
ECARule wire = handler.generatedECARule(gate, tf, click, gate);
handler.setName(wire, "resume");
queue.add(wire, drools);

end

/**
* @inference Gate
* A {@model Scope} protected by a {@model Gate} {@model Gate#name named} 'XXX',
* with an outgoing {@model ECARule} named 'first' or 'last',
* will contain a <em>flag</em> {@model Value} named 'XXX flag', in order to track the runtime status of the {@model Gate}.
*/
rule "Create '(gate) flag' property when Gate is connected by 'first' or 'last'"
when
session : Scope ( )
gate : Gate ( eContainer == session )

wire : ECARule ( trigger == gate, name == "first" || name == "last" )

not (Value ( eContainer == session, eval( name.equals(gate.getName() + " flag")) ))

eval ( handler.veto( gate ))

then
Value prop = handler.generatedValue(gate, session);
handler.setName(prop, gate.getName() + " flag");
handler.setValue(prop, ModelPackage.eINSTANCE.getValue_DefaultValue(), "false");
queue.add(prop, drools);

end

/**
* TODO can the 'Frame' restriction be relaxed to 'Scope'?
*
* @inference Gate
* A <em>flag</em> {@model Value} generated by a {@model Gate}
* with an outgoing {@model ECARule} named 'first' or 'last' is {@model Frame#onAccess accessed},
* will generate an {@model ActivityOperation} in that {@model Scope} named 'Set gate flag'.
*/
rule "Create 'set flag' operation for Frames connected with 'first' or 'last' ECARule"
when
gate : Gate ( )
tf : Frame ( )
nav : ECARule ( trigger == gate, target == tf, name == "first" || name == "last" )
button : Button ( eContainer == tf, name == "Continue" )

not (ActivityOperation ( eContainer == tf, name == "Set gate flag" ))

eval ( handler.veto( gate ))

then
ActivityOperation op = handler.generatedActivityOperation(gate, tf);
handler.setName(op, "Set gate flag");
queue.add(op, drools);

end

/**
* TODO can the 'Frame' restriction be relaxed to 'Scope'?
*
* @inference Gate
* When a {@model Frame} protected by a {@model Gate}
* with an outgoing {@model ECARule} named 'first' or 'last' is {@model Frame#onAccess accessed},
* the 'Set gate flag' {@model Operation} will be {@model ECARule executed}.
*/
rule "Connect 'access' event with 'set flag' operation"
when
gate : Gate ( )
tf : Frame ( )
nav : ECARule ( trigger == gate, target == tf, name == "first" || name == "last" )
button : Button ( eContainer == tf, name == "Continue" )
op : Operation ( eContainer == tf, name == "Set gate flag" )
access : Event ( eContainer == tf, tf.onAccess == access )

not ( ECARule ( trigger == access, target == op ))

eval ( handler.veto( gate ))

then
ECARule run = handler.generatedECARule(gate, tf, access, op);
handler.setName(run, "run");
queue.add(run, drools);

end

/**
* TODO can the 'Frame' restriction be relaxed to 'Scope'?
*
* @inference Gate,ActivityOperation
* The {@model ActivityOperation} 'Set gate flag' generated for a {@model Gate} protecting a {@model Frame},
* with an outgoing {@model ECARule} named 'first' or 'last',
* will be completed with the {@model ActivityNode contents necessary} to set the <em>flag</em> {@model Value}.
*/
rule "Create contents of 'set flag' operation"
when
session : Scope ( )
gate : Gate ( eContainer == session )
tf : Frame ( )
nav : ECARule ( trigger == gate, target == tf, name == "first" || name == "last" )
button : Button ( eContainer == tf, name == "Continue" )
property : Value ( eContainer == session, eval( name.equals(gate.getName() + " flag")) )

op : ActivityOperation ( eContainer == tf, name == "Set gate flag" )

not (StartNode ( eContainer == op ))

eval ( handler.veto( gate ))

then
StartNode start = handler.generatedStartNode(gate, op);
FinishNode finish = handler.generatedFinishNode(gate, op);
SetNode set = handler.generatedSetNode(gate, op);

Value value = handler.generatedValue(gate, op);
handler.setReadOnly(value, true);
handler.setName(value, "true");
handler.setDefaultValue(value, "true");

queue.add(start, drools);
queue.add(finish, drools);
queue.add(set, drools);

ExternalValue ev_property = handler.generatedExternalValue(gate, op);
handler.setValue(ev_property, property);
queue.add(ev_property, drools);

ExternalValue ev_value = handler.generatedExternalValue(gate, op);
handler.setValue(ev_value, value);
queue.add(ev_value, drools);

ExecutionEdge e1 = handler.generatedExecutionEdge(gate, op, start, set);
ExecutionEdge e2 = handler.generatedExecutionEdge(gate, op, set, finish);
DataFlowEdge d1 = handler.generatedDataFlowEdge(gate, op, ev_value, set);
DataFlowEdge d2 = handler.generatedDataFlowEdge(gate, op, set, ev_property);

queue.add(e1, drools);
queue.add(e2, drools);
queue.add(d1, drools);
queue.add(d2, drools);

end

/**
* @inference Gate,Scope
* A {@model Scope} protected by a {@model Gate} named 'XXX',
* with an outgoing {@model ECARule} named 'first' or 'last',
* will contain an {@model ActivityPredicate}
* named 'check XXX' to check that the {@model Gate} has been satisfied.
*/
rule "Create condition 'check (gate)'"
when
session : Scope ( )
gate : Gate ( eContainer == session )
wire : ECARule ( trigger == gate, name == "first" || name == "last" )

type : EXSDDataType( definition != null,
definition.name == "boolean" )

not ( Function ( eContainer == session, eval( name.equals("check " + gate.getName())) ))

eval ( handler.veto( gate ))

then
ActivityPredicate cond = handler.generatedActivityPredicate(gate, session);
handler.setName(cond, "check " + gate.getName());
handler.setType(cond, type);
queue.add(cond, drools);

end

/**
* @inference Gate,Scope
* The 'check XXX' {@model Function} for a {@model Gate},
* with an outgoing {@model ECARule} named 'first' or 'last',
* will be provided as a
* runtime {@model SimpleCondition} check to that {@model Gate}.
*/
rule "Connect condition 'check (gate)' with gate"
when
session : Scope ( )
gate : Gate ( eContainer == session )
wire : ECARule ( trigger == gate, name == "first" || name == "last" )

cond : Function ( eContainer == session, eval( name.equals("check " + gate.getName())) )

not ( SimpleCondition ( function == cond, conditioned == gate ))

eval ( handler.veto( gate ))

then
SimpleCondition cw = handler.generatedSimpleCondition(gate, session, cond, gate);
handler.setName(cw, "condition");
queue.add(cw, drools);

end

/**
* @inference Gate,Scope,ActivityPredicate
* The 'check XXX' {@model ActivityPredicate} for a {@model Gate},
* with an outgoing {@model ECARule} named 'first' or 'last',
* will be completed with the {@model ActivityNode contents necessary} to evaluate the <em>flag</em> {@model Value}.
*/
rule "Create contents of 'check (gate)' condition"
when
session : Scope ( )
gate : Gate ( eContainer == session )
wire : ECARule ( trigger == gate, name == "first" || name == "last" )
property : Value ( eContainer == session, eval( name.equals(gate.getName() + " flag")) )

cond : ActivityPredicate ( eContainer == session, eval( name.equals("check " + gate.getName())) )
cw : SimpleCondition ( function == cond, conditioned == gate )

not ( StartNode ( eContainer == cond ))

eval ( handler.veto( gate ))

then
StartNode start = handler.generatedStartNode(gate, cond);
FinishNode finish = handler.generatedFinishNode(gate, cond);
CancelNode cancel = handler.generatedCancelNode(gate, cond);
DecisionNode cmp = handler.generatedDecisionNode(gate, cond);
handler.setName(cmp, "true?");

queue.add(start, drools);
queue.add(finish, drools);
queue.add(cancel, drools);
queue.add(cmp, drools);

ExecutionEdge e1 = handler.generatedExecutionEdge(gate, cond, start, cmp);
ExecutionEdge e2 = handler.generatedExecutionEdge(gate, cond, cmp, finish);
handler.setName(e2, "y");
ExecutionEdge e3 = handler.generatedExecutionEdge(gate, cond, cmp, cancel);
handler.setName(e3, "n");

ExternalValue ev_property = handler.generatedExternalValue(gate, cond);
handler.setValue(ev_property, property);
queue.add(ev_property, drools);

DataFlowEdge d1 = handler.generatedDataFlowEdge(gate, cond, ev_property, cmp);

queue.add(e1, drools);
queue.add(e2, drools);
queue.add(e3, drools);
queue.add(d1, drools);

end

/**
* TODO Should the Provides page be placed into a separate Session if the protected
* Scope by the Gate is also a Session? The current implementation requires that if the
* data entered is to be unique, the protected Session will also have to be contained
* within a Session itself, otherwise the generated Provides Frame will allow access
* to the private data explicitly.
*
* @inference Gate,RequiresEdge
* A {@model Gate} protecting a {@model Scope} as an {@model Scope#entryGate entry gate}
* with an incoming {@model RequiresEdge} from an <em>expected input value</em> (represented as a {@model Label})
* -- known as an <em>input entry</em> {@model Gate} --
* will create an <em>input</em> {@model Frame} to allow the user to enter in these expected values.
*/
rule "If an EntryGate requires a Label value, then a Page should be created outside the Scope to enter it"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

not ( provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) ) )

eval ( handler.veto( gate ))

then
Frame provide = handler.generatedFrame(gate, container);
handler.setName(provide, functions.getEntryGateFrameNameForProvides(label));
queue.add(provide, drools);

end

/**
* @inference Gate,RequiresEdge
* An <em>input entry</em> {@model Gate} will create an outgoing {@model ECARule navigation rule}
* from the {@model Gate} named 'fail' to the <em>input</em> {@model Frame}.
*/
rule "For EntryGates that require Label values, connect a NavigateWire to the provides Frame"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) )

# allow other ECARules to override this one
not ( ECARule ( trigger == gate ))

eval ( handler.veto( gate ))

then
ECARule nav = handler.generatedECARule(gate, gate, gate, provide);
handler.setName(nav, "fail");
queue.add(nav, drools);

end

/**
* @inference Gate,RequiresEdge
* An <em>input</em> {@model Frame} generated by an <em>input entry</em> {@model Gate}
* will contain an {@model InputTextField} for every {@model Label} {@model RequiresEdge required}
* by that {@model Gate}.
*/
rule "Create TextFields for all Labels required by an EntryGate"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) )

not ( VisibleThing ( eContainer == provide, name == label.name ) )

eval ( handler.veto( gate ))

then
InputTextField text = handler.generatedInputTextField(gate, provide);
handler.setName(text, label.getName());
handler.setType(text, label.getType());
queue.add(text, drools);

end

/**
* @inference Gate
* An <em>input entry</em> {@model Gate} will check that every {@model Label} is set,
* through the 'fieldValue is set' {@model Function} of each {@model Label}.
*/
rule "If an EntryGate requires a Label value, then the 'is set?' Function in the Label is used as the Gate Condition"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

cond : Function ( eContainer == label, name == "fieldValue is set" )

not ( SimpleCondition ( function == cond, conditioned == gate ))

eval ( handler.veto( gate ))

then
SimpleCondition edge = handler.generatedSimpleCondition(gate, gate, cond, gate);
queue.add(edge, drools);

end

/**
* @inference Gate,ECARule
* An <em>input entry</em> {@model Gate} will {@model ECARule update} the value of each <em>input</em> {@model Label}
* from the value of each similarly named {@model VisibleThing} in the <em>input</em> {@model Frame}
* when the protected {@model Scope} is {@model Scope#onAccess accessed}.
*/
rule "If an EntryGate requires a Label, get the containing Scope to update the Label from the expected external source"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) )

field : VisibleThing ( eContainer == provide, name == label.name )
value : Value ( field.fieldValue == value )

# Scope.onAccess
onAccess : Event ( session.onAccess == onAccess )

# Label.update()
op : Operation ( eContainer == label, name == "update" )

not ( ECARule ( trigger == onAccess, target == op ))

eval ( handler.veto( gate ))

then
ECARule run = handler.generatedECARule(gate, gate, onAccess, op);
handler.setName(run, "run");
queue.add(run, drools);

# connect with Parameter
Parameter param = handler.generatedParameter(gate, gate, value, run);
queue.add(param, drools);

end

/**
* @inference Gate
* An <em>input entry</em> {@model Gate} will only update the value of each <em>input</em> {@model Label}
* from {@model VisibleThing}s in the <em>input</em> {@model Frame} if the source elements {@model Function are set}.
*/
rule "If an EntryGate requires a Label, the Label is only updated externally if the given value has been set"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) )

field : VisibleThing ( eContainer == provide, name == label.name )

# Scope.onAccess
onAccess : Event ( session.onAccess == onAccess )

# Label.update()
op : Operation ( eContainer == label, name == "update" )

# Scope.onAccess --> Label.update()
run : ECARule ( trigger == onAccess, target == op )

# Text.isSet?
condition : Function ( eContainer == field, name == "fieldValue is set" )

not ( SimpleCondition ( function == condition, conditioned == run ))

eval ( handler.veto( gate ))

then
SimpleCondition edge = handler.generatedSimpleCondition(gate, gate, condition, run);
queue.add(edge, drools);

end

/**
* @inference Gate,SimpleCondition
* An <em>input entry</em> {@model Gate} will {@model SimpleCondition only} update the value of each <em>input</em> {@model Label}
* from {@model VisibleThing}s in the <em>input</em> {@model Frame} if the source elements {@model Function can be cast}.
*/
rule "If an EntryGate requires a Label, the Label is only updated externally if the given value can be cast to the target type"
when
container : Scope ( )

session : Scope ( eContainer == container )
gate : Gate ( session.entryGate == gate )

label : Label ( )
requires : RequiresEdge ( from == gate, to == label )

provide : Frame ( eContainer == container, name != null,
eval ( functions.getEntryGateFrameNameForProvides(label).equals(provide.getName()) ) )

field : VisibleThing ( eContainer == provide, name == label.name )
value : Value ( field.fieldValue == value )

# Scope.onAccess
onAccess : Event ( session.onAccess == onAccess )

# Label.update()
op : Operation ( eContainer == label, name == "update" )

# Scope.onAccess --> Label.update()
run : ECARule ( trigger == onAccess, target == op )

# Label.can cast?
condition : Function ( eContainer == label, name == "can cast?" )

not ( SimpleCondition ( function == condition, conditioned == run ))

eval ( handler.veto( gate ))

then
SimpleCondition edge = handler.generatedSimpleCondition(gate, gate, condition, run);
queue.add(edge, drools);

# connect with fieldValue
Parameter param = handler.generatedParameter(gate, gate, value, edge);
queue.add(param, drools);

end

Change log

r3161 by soundasleep on Apr 2, 2012   Diff
removing instances where model element
links are in italics, to fix whitespace
errors in latex output
Go to: 
Project members, sign in to write a code review

Older revisions

r3147 by soundasleep on Oct 6, 2011   Diff
cleaning up Drools rule package
documentation
r3101 by soundasleep on Sep 21, 2011   Diff
 issue 277 : updating inference rules
and codegen templates
r3095 by soundasleep on Sep 18, 2011   Diff
fixing failing tests where a Session
cannot contain a Label
manually moving the required OpenID
label into a separate Frame
All revisions of this file

File info

Size: 19750 bytes, 570 lines
Powered by Google Project Hosting