Current section

Files

Jump to
bpe src bpe_gateways.erl
Raw

src/bpe_gateways.erl

-module(bpe_gateways).
-author('Oleksandr Naumov').
-include("bpe.hrl").
-include("doc.hrl").
-export([def/0,
vertices/1,
vertices/2,
getEdgesAndVertices/1,
setVertexType/3,
fixBeginEndEvents/1]).
-export([fixGateways/1, convertIfNeeded/1, action/2]).
-import(lists, [reverse/1, keyfind/3, keyreplace/4]).
def() ->
R_raw = [{r1, a, b},
{r2, b, c},
{r3, b, d},
{r4, c, e},
{r5, c, f},
{r6, d, g},
{r7, e, h},
{r8, h, j},
{r9, f, i},
{r10, i, j},
{r11, f, g},
{r12, g, j},
{r13, j, k}],
{R, N} = getEdgesAndVertices(R_raw),
P = #process{name = 'Graph', flows = R, tasks = N,
beginEvent = a, endEvent = k, events = []},
fixGateways(fixBeginEndEvents(P)).
vertices(R) -> vertices(reverse(R), []).
vertices([], N) -> N;
vertices([#sequenceFlow{id = Id, source = From,
target = To}
| Rtail],
N) ->
N1 = case keyfind(From, #task.id, N) of
false -> [#task{name = From, output = [Id]} | N];
V = #task{output = L} ->
keyreplace(From, #task.id, N, V#task{output = [Id | L]})
end,
NewN = case keyfind(To, #task.id, N1) of
false -> [#task{name = To, input = [Id]} | N1];
V1 = #task{input = L1} ->
keyreplace(To, #task.id, N1, V1#task{input = [Id | L1]})
end,
vertices(Rtail, NewN).
getEdgesAndVertices(Edges_Raw) ->
R = [#sequenceFlow{name = Id, source = From,
target = To}
|| {Id, From, To} <- Edges_Raw],
{R, vertices(R)}.
setVertexType(Id, Type, Vertices) ->
NewVertex = (keyfind(Id,
#task.id,
Vertices))#gateway{type = Type},
keyreplace(Id, #sequenceFlow.id, Vertices, NewVertex).
fixBeginEndEvents(Proc) ->
Tasks = Proc#process.tasks,
[BeginTask] = [T
|| #task{input = In} = T <- Tasks, In == []],
#task{name = BName, output = _BOut} = BeginTask,
[EndTask] = [T
|| #task{output = Out} = T <- Tasks, Out == []],
#task{name = EName, input = _EIn, output = []} =
EndTask,
BeginEvent = #beginEvent{name = BName},
EndEvent = #endEvent{name = EName},
Proc#process{tasks =
[BeginEvent, EndEvent | Tasks -- [BeginTask, EndTask]],
beginEvent = BName, endEvent = EName}.
fixGateways(#process{tasks = Tasks} = Proc) ->
Proc#process{tasks =
[convertIfNeeded(T) || T <- Tasks]}.
convertIfNeeded(#task{name = Name, input = In,
output = Out})
when length(In) > 1; length(Out) > 1 ->
#gateway{name = Name, type = parallel, input = In,
output = Out};
convertIfNeeded(Task) -> Task.
action({request, _, _}, Proc) -> {reply, Proc}.