cpee 1.3.129 → 1.3.130
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.
- checksums.yaml +7 -0
- data/cpee.gemspec +1 -1
- data/lib/cpee/processtransformation/bpel/Repository/booking.bpel +125 -0
- data/lib/cpee/processtransformation/bpel/Repository/booking.wsdl +72 -0
- data/lib/cpee/processtransformation/bpel/Repository/booking/airline.wsdl +71 -0
- data/lib/cpee/processtransformation/bpel/Repository/booking/hotel.wsdl +64 -0
- data/lib/cpee/processtransformation/bpel/Repository/booking/report.wsdl +71 -0
- data/lib/cpee/processtransformation/bpel/bpel2wee.rb +34 -0
- data/lib/cpee/processtransformation/bpel/bpelserver.ru +64 -0
- data/lib/cpee/processtransformation/bpel/bpelserver.xml +70 -0
- data/lib/cpee/processtransformation/bpel/lib/BPEL_Transform.rb +367 -0
- data/lib/cpee/processtransformation/bpmn2.rb +273 -0
- data/lib/cpee/processtransformation/cpee.rb +118 -0
- data/lib/cpee/processtransformation/structures.rb +426 -0
- data/server/instances/1/properties.xml +101 -69
- data/server/instances/10/properties.xml +109 -0
- data/server/instances/11/properties.xml +109 -0
- data/server/instances/2/properties.xml +44 -191
- data/server/instances/3/properties.xml +44 -70
- data/server/instances/4/properties.xml +68 -28
- data/server/instances/5/properties.xml +70 -10
- data/server/instances/6/properties.xml +55 -175
- data/server/instances/7/properties.xml +83 -0
- data/server/instances/8/properties.xml +83 -0
- data/server/instances/9/properties.xml +77 -0
- metadata +111 -111
- data/server/instances/1/notifications/d12eff1ac812661c05d7090ce7394cf9/consumer-secret +0 -1
- data/server/instances/1/notifications/d12eff1ac812661c05d7090ce7394cf9/producer-secret +0 -1
- data/server/instances/1/notifications/d12eff1ac812661c05d7090ce7394cf9/subscription.xml +0 -27
- data/server/instances/6/notifications/5c8c36c3dfcec8e36c3b25859a71778c/consumer-secret +0 -1
- data/server/instances/6/notifications/5c8c36c3dfcec8e36c3b25859a71778c/producer-secret +0 -1
- data/server/instances/6/notifications/5c8c36c3dfcec8e36c3b25859a71778c/subscription.xml +0 -27
- data/server/server.pid +0 -1
| @@ -0,0 +1,273 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This file is part of CPEE.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Apache License, Version 2.0
         | 
| 6 | 
            +
            # 
         | 
| 7 | 
            +
            # Copyright (c) 2013 Juergen Mangler
         | 
| 8 | 
            +
            # 
         | 
| 9 | 
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 10 | 
            +
            # you may not use this file except in compliance with the License.
         | 
| 11 | 
            +
            # You may obtain a copy of the License at
         | 
| 12 | 
            +
            # 
         | 
| 13 | 
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 14 | 
            +
            # 
         | 
| 15 | 
            +
            # Unless required by applicable law or agreed to in writing, software
         | 
| 16 | 
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 17 | 
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 18 | 
            +
            # See the License for the specific language governing permissions and
         | 
| 19 | 
            +
            # limitations under the License.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/structures')
         | 
| 22 | 
            +
            require 'rubygems'
         | 
| 23 | 
            +
            require 'xml/smart'
         | 
| 24 | 
            +
            require 'highline'
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            module CPEE
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              module ProcessTransformation
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                module Source
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  class BPMN2
         | 
| 33 | 
            +
                    attr_reader :dataelements, :endpoints, :start, :graph
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                     def initialize(xml) #{{{
         | 
| 36 | 
            +
                      @tree = Tree.new
         | 
| 37 | 
            +
                      @hl = HighLine.new
         | 
| 38 | 
            +
                      @start = nil
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                      doc = XML::Smart.string(xml)
         | 
| 41 | 
            +
                      doc.register_namespace 'bm',  "http://www.omg.org/spec/BPMN/20100524/MODEL" 
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      @dataelements = {}
         | 
| 44 | 
            +
                      @endpoints = {}
         | 
| 45 | 
            +
                      @graph = Graph.new
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      extract_dataelements(doc)
         | 
| 48 | 
            +
                      extract_endpoints(doc)
         | 
| 49 | 
            +
                      extract_nodelink(doc)
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      @traces = Traces.new [[@start]]
         | 
| 52 | 
            +
                    end #}}}
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    def extract_dataelements(doc)
         | 
| 55 | 
            +
                      doc.find("/bm:definitions/bm:process/bm:property[bm:dataState/@name='cpee:dataelement']").each do |ref|
         | 
| 56 | 
            +
                        if ref.attributes['itemSubjectRef']
         | 
| 57 | 
            +
                          doc.find("/bm:definitions/bm:itemDefinition[@id=\"" + ref.attributes['itemSubjectRef'] + "\"]").each do |sref|
         | 
| 58 | 
            +
                            @dataelements[ref.attributes['name']] = sref.attributes['structureRef'].to_s
         | 
| 59 | 
            +
                          end 
         | 
| 60 | 
            +
                        else
         | 
| 61 | 
            +
                          @dataelements[ref.attributes['name']] = ''
         | 
| 62 | 
            +
                        end  
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                    def extract_endpoints(doc)
         | 
| 67 | 
            +
                      doc.find("/bm:definitions/bm:process/bm:property[bm:dataState/@name='cpee:endpoint']/@itemSubjectRef").each do |ref|
         | 
| 68 | 
            +
                        doc.find("/bm:definitions/bm:itemDefinition[@id=\"" + ref.value + "\"]/@structureRef").each do |sref|
         | 
| 69 | 
            +
                          @endpoints[ref.value] = sref.value
         | 
| 70 | 
            +
                        end  
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                    def extract_nodelink(doc)
         | 
| 75 | 
            +
                      doc.find("/bm:definitions/bm:process/bm:*[@id and @name and not(@itemSubjectRef) and not(name()='sequenceFlow')]").each do |e|
         | 
| 76 | 
            +
                        n = Node.new(e.attributes['id'],e.qname.name.to_sym,e.attributes['name'].strip,e.find('count(bm:incoming)'),e.find('count(bm:outgoing)'))
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                        if e.attributes['scriptFormat'] != ''
         | 
| 79 | 
            +
                          n.script_type = e.attributes['scriptFormat']
         | 
| 80 | 
            +
                        end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                        e.find("bm:property[@name='cpee:endpoint']/@itemSubjectRef").each do |ep|
         | 
| 83 | 
            +
                          n.endpoints << ep.value
         | 
| 84 | 
            +
                        end
         | 
| 85 | 
            +
                        e.find("bm:property[@name='cpee:method']/@itemSubjectRef").each do |m|
         | 
| 86 | 
            +
                          n.methods << m.value
         | 
| 87 | 
            +
                        end
         | 
| 88 | 
            +
                        e.find("bm:script").each do |s|
         | 
| 89 | 
            +
                          n.script ||= ''
         | 
| 90 | 
            +
                          n.script << s.text.strip
         | 
| 91 | 
            +
                        end
         | 
| 92 | 
            +
                        e.find("bm:ioSpecification/bm:dataInput").each do |a|
         | 
| 93 | 
            +
                          name = a.attributes['name']
         | 
| 94 | 
            +
                          value = a.attributes['itemSubjectRef']
         | 
| 95 | 
            +
                          if @dataelements.keys.include?(value)
         | 
| 96 | 
            +
                            n.parameters[name] = 'data.' + value
         | 
| 97 | 
            +
                          else  
         | 
| 98 | 
            +
                            n.parameters[name] = value
         | 
| 99 | 
            +
                          end
         | 
| 100 | 
            +
                        end
         | 
| 101 | 
            +
                        e.find("bm:ioSpecification/bm:dataOutput").each do |a|
         | 
| 102 | 
            +
                          ref = a.attributes['id']
         | 
| 103 | 
            +
                          e.find("bm:dataOutputAssociation[bm:sourceRef=\"#{ref}\"]").each do |d|
         | 
| 104 | 
            +
                            n.script_var = ref
         | 
| 105 | 
            +
                            n.script_id = d.find("string(bm:targetRef)")
         | 
| 106 | 
            +
                          end
         | 
| 107 | 
            +
                        end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                        @graph.add_node n
         | 
| 110 | 
            +
                        @start = n if n.type == :startEvent && @start == nil
         | 
| 111 | 
            +
                      end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                      # extract all sequences to a links
         | 
| 114 | 
            +
                      doc.find("/bm:definitions/bm:process/bm:sequenceFlow").each do |e|
         | 
| 115 | 
            +
                        source = e.attributes['sourceRef']
         | 
| 116 | 
            +
                        target = e.attributes['targetRef']
         | 
| 117 | 
            +
                        cond = e.find('bm:conditionExpression')
         | 
| 118 | 
            +
                        @graph.add_link Link.new(source, target, cond.empty? ? nil : cond.first.text.strip)
         | 
| 119 | 
            +
                      end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                      @graph.clean_up do |node|
         | 
| 122 | 
            +
                        if node.type == :scriptTask && (x = @graph.find_script_id(node.id)).any?
         | 
| 123 | 
            +
                          x.each do |k,n|
         | 
| 124 | 
            +
                            n.script = node.script
         | 
| 125 | 
            +
                            n.script_type = node.script_type
         | 
| 126 | 
            +
                          end
         | 
| 127 | 
            +
                          true
         | 
| 128 | 
            +
                        else
         | 
| 129 | 
            +
                          false
         | 
| 130 | 
            +
                        end  
         | 
| 131 | 
            +
                      end
         | 
| 132 | 
            +
                    end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                    def build_traces #{{{
         | 
| 135 | 
            +
                      build_extraces @traces, @start
         | 
| 136 | 
            +
                      @traces
         | 
| 137 | 
            +
                    end #}}}
         | 
| 138 | 
            +
                    def build_tree(debug=false) #{{{
         | 
| 139 | 
            +
                      build_ttree @tree, @traces.dup, nil, debug
         | 
| 140 | 
            +
                      debug_print debug, 'Tree finished'
         | 
| 141 | 
            +
                      @tree
         | 
| 142 | 
            +
                    end #}}}
         | 
| 143 | 
            +
                
         | 
| 144 | 
            +
                    def build_extraces(traces, node) #{{{
         | 
| 145 | 
            +
                      dupt = traces.last.dup
         | 
| 146 | 
            +
                      @graph.next_nodes(node).each_with_index do |n,i|
         | 
| 147 | 
            +
                        traces << dupt.dup if i > 0
         | 
| 148 | 
            +
                        if traces.last.include?(n)
         | 
| 149 | 
            +
                          traces.last << n
         | 
| 150 | 
            +
                        else  
         | 
| 151 | 
            +
                          traces.last << n
         | 
| 152 | 
            +
                          build_extraces(traces,n)
         | 
| 153 | 
            +
                        end
         | 
| 154 | 
            +
                      end
         | 
| 155 | 
            +
                    end #}}}
         | 
| 156 | 
            +
                    private :build_extraces
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    def map_node(node) #{{{
         | 
| 159 | 
            +
                      case node.type
         | 
| 160 | 
            +
                        when :parallelGateway
         | 
| 161 | 
            +
                          Parallel.new(node.id,node.type)
         | 
| 162 | 
            +
                        when :exclusiveGateway
         | 
| 163 | 
            +
                          Conditional.new(node.id,:exclusive,node.type)
         | 
| 164 | 
            +
                        when :eventBasedGateway
         | 
| 165 | 
            +
                          Parallel.new(node.id,node.type,1)
         | 
| 166 | 
            +
                        when :inclusiveGateway
         | 
| 167 | 
            +
                          Conditional.new(node.id,:inclusive,node.type)
         | 
| 168 | 
            +
                        when :endEvent, :startEvent, nil
         | 
| 169 | 
            +
                          nil
         | 
| 170 | 
            +
                        else
         | 
| 171 | 
            +
                          node
         | 
| 172 | 
            +
                      end
         | 
| 173 | 
            +
                    end #}}}
         | 
| 174 | 
            +
                    private :map_node
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                    def build_ttree(branch,traces,enode=nil,debug=false)
         | 
| 177 | 
            +
                      while not traces.finished?
         | 
| 178 | 
            +
                        ### if traces exist more than once, make it so they exist only once
         | 
| 179 | 
            +
                        ### if somebody creates a modell with an inclusive/exclusive that
         | 
| 180 | 
            +
                        ### has identical branches with different conditions, we are fucked
         | 
| 181 | 
            +
                        ### but how are the odds? right? right?
         | 
| 182 | 
            +
                        traces.uniq!
         | 
| 183 | 
            +
                        debug_print debug, traces
         | 
| 184 | 
            +
                        if node = traces.same_first
         | 
| 185 | 
            +
                          if branch.condition?
         | 
| 186 | 
            +
                            li = @graph.link(branch.id,traces.first_node.id)
         | 
| 187 | 
            +
                            unless li.nil?
         | 
| 188 | 
            +
                              branch.condition << li.condition 
         | 
| 189 | 
            +
                              branch.condition_type = "text/javascript"
         | 
| 190 | 
            +
                            end  
         | 
| 191 | 
            +
                          end
         | 
| 192 | 
            +
                          if node == enode
         | 
| 193 | 
            +
                            traces.shift_all
         | 
| 194 | 
            +
                          elsif node.incoming <= 1
         | 
| 195 | 
            +
                            traces.shift_all
         | 
| 196 | 
            +
                            n = map_node(node)
         | 
| 197 | 
            +
                            if !(n.nil? || (n.container? && (node.outgoing <=1 || traces.finished?)))
         | 
| 198 | 
            +
                              (branch << n).compact!
         | 
| 199 | 
            +
                            end
         | 
| 200 | 
            +
                          else
         | 
| 201 | 
            +
                            loops = traces.loops
         | 
| 202 | 
            +
                            if node.type == :exclusiveGateway
         | 
| 203 | 
            +
                              ### as the first is a decision node, just remove and continue
         | 
| 204 | 
            +
                              if node.incoming == 2
         | 
| 205 | 
            +
                                node.incoming = 1
         | 
| 206 | 
            +
                                branch << Loop.new(node.id)
         | 
| 207 | 
            +
                                ### remove the gateway itself, as for a single loop it is no longer used.
         | 
| 208 | 
            +
                                ### the condition will the loop condition
         | 
| 209 | 
            +
                                traces.shift_all
         | 
| 210 | 
            +
                                loops.remove_empty
         | 
| 211 | 
            +
                                build_ttree branch.last, loops, nil, debug
         | 
| 212 | 
            +
                              else  
         | 
| 213 | 
            +
                                ### dont remove it, treat it as a normal conditional
         | 
| 214 | 
            +
                                ### an infinite loop that can only be left by break is created
         | 
| 215 | 
            +
                                node.incoming = 1
         | 
| 216 | 
            +
                                branch << InfiniteLoop.new(node.id)
         | 
| 217 | 
            +
                                ### add the blank conditional to get a break
         | 
| 218 | 
            +
                                len = loops.length
         | 
| 219 | 
            +
                                loops.add_breaks
         | 
| 220 | 
            +
                                build_ttree branch.last, loops, nil, debug
         | 
| 221 | 
            +
                                ### set outgoing to number of loops (without the break) so that it can be ignored (should be 1 all the time)
         | 
| 222 | 
            +
                                node.outgoing -= len
         | 
| 223 | 
            +
                              end   
         | 
| 224 | 
            +
                            else
         | 
| 225 | 
            +
                              node.incoming -= loops.length
         | 
| 226 | 
            +
                              ### throw away the loop traces, remove loop traces from front of all other traces
         | 
| 227 | 
            +
                              traces.segment_by_loops loops
         | 
| 228 | 
            +
                              build_ttree branch, loops, nil, debug
         | 
| 229 | 
            +
                            end
         | 
| 230 | 
            +
                            traces.remove(loops)
         | 
| 231 | 
            +
                            traces.remove_empty
         | 
| 232 | 
            +
                          end
         | 
| 233 | 
            +
                        else
         | 
| 234 | 
            +
                          endnode = traces.find_endnode || enode
         | 
| 235 | 
            +
                          tracesgroup, endnode = traces.segment_by endnode
         | 
| 236 | 
            +
                          tracesgroup.each do |trcs|
         | 
| 237 | 
            +
                            if trcs.finished?
         | 
| 238 | 
            +
                              build_ttree branch.last.new_branch, Traces.new([[Break.new(1)]]), endnode, debug
         | 
| 239 | 
            +
                            else  
         | 
| 240 | 
            +
                              build_ttree branch.last.new_branch, trcs, endnode, debug
         | 
| 241 | 
            +
                            end  
         | 
| 242 | 
            +
                            endnode.incoming -= 1 unless endnode.nil?
         | 
| 243 | 
            +
                          end
         | 
| 244 | 
            +
                          ### all before is reduced to one incoming arrow
         | 
| 245 | 
            +
                          ### if now there is still more than one incoming we have a loop situation
         | 
| 246 | 
            +
                          ### where the end of a branching statement is also the starting/endpoint 
         | 
| 247 | 
            +
                          ### of a loop
         | 
| 248 | 
            +
                          endnode.incoming += 1 unless endnode.nil?
         | 
| 249 | 
            +
                        end
         | 
| 250 | 
            +
                      end
         | 
| 251 | 
            +
                    end
         | 
| 252 | 
            +
                    private :build_ttree
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                    def debug_print(debug,traces) #{{{
         | 
| 255 | 
            +
                      if debug
         | 
| 256 | 
            +
                        puts '-' * @hl.output_cols, @tree.to_s
         | 
| 257 | 
            +
                        puts traces.to_s
         | 
| 258 | 
            +
                        @hl.ask('Continue ... '){ |q| q.echo = false }
         | 
| 259 | 
            +
                      end  
         | 
| 260 | 
            +
                    end #}}}
         | 
| 261 | 
            +
                    private :debug_print
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                    def generate_model(formater) #{{{
         | 
| 264 | 
            +
                      formater.new(@tree).generate
         | 
| 265 | 
            +
                    end #}}}
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                  end  
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
              end
         | 
| 272 | 
            +
             | 
| 273 | 
            +
            end
         | 
| @@ -0,0 +1,118 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This file is part of CPEE.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Apache License, Version 2.0
         | 
| 6 | 
            +
            # 
         | 
| 7 | 
            +
            # Copyright (c) 2013 Juergen Mangler
         | 
| 8 | 
            +
            # 
         | 
| 9 | 
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 10 | 
            +
            # you may not use this file except in compliance with the License.
         | 
| 11 | 
            +
            # You may obtain a copy of the License at
         | 
| 12 | 
            +
            # 
         | 
| 13 | 
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 14 | 
            +
            # 
         | 
| 15 | 
            +
            # Unless required by applicable law or agreed to in writing, software
         | 
| 16 | 
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 17 | 
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 18 | 
            +
            # See the License for the specific language governing permissions and
         | 
| 19 | 
            +
            # limitations under the License.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            module CPEE
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              module ProcessTransformation
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                module Target
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  class CPEE
         | 
| 28 | 
            +
                    def initialize(tree)
         | 
| 29 | 
            +
                      @tree = tree
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                    def generate
         | 
| 32 | 
            +
                      res = XML::Smart.string("<description xmlns='http://cpee.org/ns/description/1.0'/>")
         | 
| 33 | 
            +
                      res.register_namespace 'd', 'http://cpee.org/ns/description/1.0'
         | 
| 34 | 
            +
                      generate_for_list(@tree,res.root)
         | 
| 35 | 
            +
                      res
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    def generate_for_list(list,res)
         | 
| 39 | 
            +
                      list.each do |e|
         | 
| 40 | 
            +
                        nam = e.class.name.gsub(/\w+:+/,'')
         | 
| 41 | 
            +
                      send("print_#{nam}".to_sym,e,res)
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                    private :generate_for_list
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    def print_Break(node,res)
         | 
| 47 | 
            +
                      res.add('break')
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    def print_InfiniteLoop(node,res)
         | 
| 51 | 
            +
                      s1 = res.add('loop', 'pre_test' => 'true')
         | 
| 52 | 
            +
                      generate_for_list(node,s1)
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                    def print_Loop(node,res)
         | 
| 55 | 
            +
                      s1 = res.add('loop', 'pre_test' => node.condition.join(' && '))
         | 
| 56 | 
            +
                      s1.attributes['language'] = node.condition_type unless node.condition_type.nil?
         | 
| 57 | 
            +
                      generate_for_list(node,s1)
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    def print_Node(node,res)
         | 
| 61 | 
            +
                      if node.endpoints.empty? && !node.script.nil? && node.script.strip != ''
         | 
| 62 | 
            +
                        n = res.add('d:manipulate', 'id' => "a#{node.niceid}")
         | 
| 63 | 
            +
                        n.text = node.script
         | 
| 64 | 
            +
                        n.attributes['output'] = node.script_var unless node.script_var.nil?
         | 
| 65 | 
            +
                        n.attributes['language'] = node.script_type unless node.script_type.nil?
         | 
| 66 | 
            +
                      else  
         | 
| 67 | 
            +
                        n   = res.add('d:call', 'id' => "a#{node.niceid}", 'endpoint' => node.endpoints.join(','))
         | 
| 68 | 
            +
                        p   = n.add('d:parameters')
         | 
| 69 | 
            +
                              p.add('d:label',node.label)
         | 
| 70 | 
            +
                              p.add('d:method',node.methods.join(','))
         | 
| 71 | 
            +
                              p.add('d:type',node.type)
         | 
| 72 | 
            +
                              p.add('d:mid',node.id)
         | 
| 73 | 
            +
                        par = p.add('d:parameters')
         | 
| 74 | 
            +
                        node.parameters.each do |k,v|
         | 
| 75 | 
            +
                          par.add(k,v)
         | 
| 76 | 
            +
                        end
         | 
| 77 | 
            +
                        if !node.script.nil? && node.script.strip != ''
         | 
| 78 | 
            +
                          x = n.add('manipulate',node.script)
         | 
| 79 | 
            +
                          x.attributes['output'] = node.script_var unless node.script_var.nil?
         | 
| 80 | 
            +
                          x.attributes['language'] = node.script_type unless node.script_type.nil?
         | 
| 81 | 
            +
                        end
         | 
| 82 | 
            +
                      end
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                    private :print_Node
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    def print_Parallel(node,res)
         | 
| 87 | 
            +
                      s1 = res.add('parallel','wait' => node.wait)
         | 
| 88 | 
            +
                      node.sub.each do |branch|
         | 
| 89 | 
            +
                        s2 = s1.add('parallel_branch')
         | 
| 90 | 
            +
                        generate_for_list(branch,s2)
         | 
| 91 | 
            +
                      end
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                    private :print_Parallel
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                    def print_Conditional(node,res)
         | 
| 96 | 
            +
                      s1 = res.add('d:choose', 'mode' => node.mode)
         | 
| 97 | 
            +
                      node.sub.each do |branch|
         | 
| 98 | 
            +
                        s2 = if branch.condition.any?
         | 
| 99 | 
            +
                          a = s1.add('d:alternative','condition' => branch.condition.join(' or '))
         | 
| 100 | 
            +
                          a.attributes['language'] = branch.condition_type unless branch.condition_type.nil?
         | 
| 101 | 
            +
                          a
         | 
| 102 | 
            +
                        else
         | 
| 103 | 
            +
                          s1.add('d:otherwise')
         | 
| 104 | 
            +
                        end  
         | 
| 105 | 
            +
                        generate_for_list(branch,s2)
         | 
| 106 | 
            +
                      end
         | 
| 107 | 
            +
                      if (x = s1.find('d:otherwise')).any?
         | 
| 108 | 
            +
                        s1.add x
         | 
| 109 | 
            +
                      end
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
                    private :print_Conditional
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
              end  
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            end
         | 
| @@ -0,0 +1,426 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # This file is part of CPEE.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Apache License, Version 2.0
         | 
| 6 | 
            +
            # 
         | 
| 7 | 
            +
            # Copyright (c) 2013 Juergen Mangler
         | 
| 8 | 
            +
            # 
         | 
| 9 | 
            +
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| 10 | 
            +
            # you may not use this file except in compliance with the License.
         | 
| 11 | 
            +
            # You may obtain a copy of the License at
         | 
| 12 | 
            +
            # 
         | 
| 13 | 
            +
            #     http://www.apache.org/licenses/LICENSE-2.0
         | 
| 14 | 
            +
            # 
         | 
| 15 | 
            +
            # Unless required by applicable law or agreed to in writing, software
         | 
| 16 | 
            +
            # distributed under the License is distributed on an "AS IS" BASIS,
         | 
| 17 | 
            +
            # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         | 
| 18 | 
            +
            # See the License for the specific language governing permissions and
         | 
| 19 | 
            +
            # limitations under the License.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            module CPEE
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              module ProcessTransformation
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                class Link #{{{
         | 
| 26 | 
            +
                  attr_accessor :from, :to
         | 
| 27 | 
            +
                  attr_reader :condition
         | 
| 28 | 
            +
                  def initialize(from,to,cond=nil)
         | 
| 29 | 
            +
                    @from  = from
         | 
| 30 | 
            +
                    @to = to
         | 
| 31 | 
            +
                    @condition = cond
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end #}}}
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                module Container
         | 
| 36 | 
            +
                  def container?
         | 
| 37 | 
            +
                    @container || false
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                class Node #{{{ 
         | 
| 42 | 
            +
                  include Container
         | 
| 43 | 
            +
                  @@niceid = -1
         | 
| 44 | 
            +
                  attr_reader :id, :label, :niceid
         | 
| 45 | 
            +
                  attr_reader :endpoints, :methods, :parameters
         | 
| 46 | 
            +
                  attr_accessor :script, :script_id, :script_var, :script_type, :incoming, :outgoing, :type
         | 
| 47 | 
            +
                  def initialize(id,type,label,incoming,outgoing)
         | 
| 48 | 
            +
                    @id = id
         | 
| 49 | 
            +
                    @niceid = (@@niceid += 1)
         | 
| 50 | 
            +
                    @type = type
         | 
| 51 | 
            +
                    @label = label
         | 
| 52 | 
            +
                    @endpoints = []
         | 
| 53 | 
            +
                    @methods = []
         | 
| 54 | 
            +
                    @script = nil
         | 
| 55 | 
            +
                    @script_type = nil
         | 
| 56 | 
            +
                    @script_id = nil
         | 
| 57 | 
            +
                    @script_var = 'result'
         | 
| 58 | 
            +
                    @parameters = {}
         | 
| 59 | 
            +
                    @incoming = incoming
         | 
| 60 | 
            +
                    @outgoing = outgoing
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end # }}} 
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                module Struct #{{{
         | 
| 65 | 
            +
                  def each(&a)
         | 
| 66 | 
            +
                    @sub.each{|s| a.call(s)}
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  def length
         | 
| 69 | 
            +
                    @sub.length
         | 
| 70 | 
            +
                  end  
         | 
| 71 | 
            +
                end #}}}
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                class Break < Node
         | 
| 74 | 
            +
                  def initialize(incoming)
         | 
| 75 | 
            +
                    super '-1', :break, 'BREAK', incoming, []
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                class Alternative < Array #{{{
         | 
| 80 | 
            +
                  include Container
         | 
| 81 | 
            +
                  attr_accessor :condition, :condition_type
         | 
| 82 | 
            +
                  attr_reader :id
         | 
| 83 | 
            +
                  def condition?; true; end
         | 
| 84 | 
            +
                  def initialize(id)
         | 
| 85 | 
            +
                    @container = true
         | 
| 86 | 
            +
                    @id = id
         | 
| 87 | 
            +
                    @condition = []
         | 
| 88 | 
            +
                    @condition_type = nil
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
                end #}}}
         | 
| 91 | 
            +
                class Branch < Array #{{{
         | 
| 92 | 
            +
                  include Container
         | 
| 93 | 
            +
                  attr_reader :id
         | 
| 94 | 
            +
                  def condition?; false; end
         | 
| 95 | 
            +
                  def initialize(id)
         | 
| 96 | 
            +
                    @container = true
         | 
| 97 | 
            +
                    @id = id
         | 
| 98 | 
            +
                  end
         | 
| 99 | 
            +
                end #}}}
         | 
| 100 | 
            +
                class InfiniteLoop < Array #{{{
         | 
| 101 | 
            +
                  include Container
         | 
| 102 | 
            +
                  def condition?; false; end
         | 
| 103 | 
            +
                  attr_accessor :id, :type
         | 
| 104 | 
            +
                  def initialize(id)
         | 
| 105 | 
            +
                    @container = true
         | 
| 106 | 
            +
                    @id = id
         | 
| 107 | 
            +
                    @type = :loop
         | 
| 108 | 
            +
                  end  
         | 
| 109 | 
            +
                end #}}}
         | 
| 110 | 
            +
                class Loop < Array #{{{
         | 
| 111 | 
            +
                  include Container
         | 
| 112 | 
            +
                  attr_accessor :id, :type, :condition, :condition_type
         | 
| 113 | 
            +
                  def condition?; true; end
         | 
| 114 | 
            +
                  def initialize(id)
         | 
| 115 | 
            +
                    @container = true
         | 
| 116 | 
            +
                    @id = id
         | 
| 117 | 
            +
                    @type = :loop
         | 
| 118 | 
            +
                    @condition = []
         | 
| 119 | 
            +
                    @condition_type = nil
         | 
| 120 | 
            +
                  end  
         | 
| 121 | 
            +
                end #}}}
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                class Parallel #{{{
         | 
| 124 | 
            +
                  include Container
         | 
| 125 | 
            +
                  include Struct
         | 
| 126 | 
            +
                  include Enumerable
         | 
| 127 | 
            +
                  attr_reader :id, :sub
         | 
| 128 | 
            +
                  attr_accessor :type, :wait
         | 
| 129 | 
            +
                  def initialize(id,type,wait='-1')
         | 
| 130 | 
            +
                    @container = true
         | 
| 131 | 
            +
                    @id = id
         | 
| 132 | 
            +
                    @type = type
         | 
| 133 | 
            +
                    @sub = []
         | 
| 134 | 
            +
                    @wait = wait
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
                  def new_branch
         | 
| 137 | 
            +
                    (@sub << Branch.new(@id)).last
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                end #}}} 
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                class Conditional #{{{
         | 
| 142 | 
            +
                  include Container
         | 
| 143 | 
            +
                  include Struct
         | 
| 144 | 
            +
                  include Enumerable
         | 
| 145 | 
            +
                  attr_reader :container
         | 
| 146 | 
            +
                  attr_reader :id, :sub, :mode
         | 
| 147 | 
            +
                  attr_accessor :type
         | 
| 148 | 
            +
                  def initialize(id,mode,type)
         | 
| 149 | 
            +
                    @container = true
         | 
| 150 | 
            +
                    @id = id
         | 
| 151 | 
            +
                    @sub = []
         | 
| 152 | 
            +
                    @mode = mode
         | 
| 153 | 
            +
                    @type = type
         | 
| 154 | 
            +
                  end  
         | 
| 155 | 
            +
                  def new_branch
         | 
| 156 | 
            +
                    (@sub << Alternative.new(@id)).last
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
                end #}}}
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                class Graph #{{{
         | 
| 161 | 
            +
                  attr_reader :flow, :nodes
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  def initialize
         | 
| 164 | 
            +
                    @nodes = {}
         | 
| 165 | 
            +
                    @links = []
         | 
| 166 | 
            +
                  end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                  def clean_up(&bl)
         | 
| 169 | 
            +
                    selnodes = []
         | 
| 170 | 
            +
                    @nodes.each do |k,n|
         | 
| 171 | 
            +
                      ret = bl.call(n)
         | 
| 172 | 
            +
                      selnodes << n if ret
         | 
| 173 | 
            +
                    end
         | 
| 174 | 
            +
                    selnodes.each do |n|
         | 
| 175 | 
            +
                      if n.incoming > 1 || n.outgoing > 1
         | 
| 176 | 
            +
                        raise "#{n.inspect} - not a simple node to remove"
         | 
| 177 | 
            +
                      end  
         | 
| 178 | 
            +
                      to,from = nil
         | 
| 179 | 
            +
                      @links.each do |f|
         | 
| 180 | 
            +
                        to = f if f.to == n.id
         | 
| 181 | 
            +
                        from = f if f.from == n.id
         | 
| 182 | 
            +
                      end
         | 
| 183 | 
            +
                      if to && from
         | 
| 184 | 
            +
                        to.to = from.to
         | 
| 185 | 
            +
                        @links.delete(from)
         | 
| 186 | 
            +
                        @nodes.delete(n.id)
         | 
| 187 | 
            +
                      else
         | 
| 188 | 
            +
                        raise "#{n.inspect} - could not remove flow"
         | 
| 189 | 
            +
                      end  
         | 
| 190 | 
            +
                    end
         | 
| 191 | 
            +
                  end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                  def find_script_id(s)
         | 
| 194 | 
            +
                    @nodes.find_all{|k,n| n.script_id == s}
         | 
| 195 | 
            +
                  end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                  def add_node(n)
         | 
| 198 | 
            +
                    @nodes[n.id] = n
         | 
| 199 | 
            +
                  end  
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                  def link(f,t)
         | 
| 202 | 
            +
                    @links.find{ |x| x.from == f && x.to == t }
         | 
| 203 | 
            +
                  end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                  def add_link(l)
         | 
| 206 | 
            +
                    @links << l
         | 
| 207 | 
            +
                  end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                  def next_nodes(from)
         | 
| 210 | 
            +
                    links = @links.find_all { |x| x.from == from.id }
         | 
| 211 | 
            +
                    links.map{|x| @nodes[x.to] }
         | 
| 212 | 
            +
                  end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                  def next_node(from)
         | 
| 215 | 
            +
                    if (nodes = next_nodes(from)).length == 1
         | 
| 216 | 
            +
                      nodes.first
         | 
| 217 | 
            +
                    else
         | 
| 218 | 
            +
                      raise "#{from.inspect} - multiple outgoing connections"
         | 
| 219 | 
            +
                    end  
         | 
| 220 | 
            +
                  end
         | 
| 221 | 
            +
                end #}}}
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                  class Tree < Array #{{{
         | 
| 224 | 
            +
                    def condition?; false; end
         | 
| 225 | 
            +
             | 
| 226 | 
            +
                    def to_s
         | 
| 227 | 
            +
                      "TREE:\n" << print_tree(self)
         | 
| 228 | 
            +
                    end
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                    def print_tree(ele,indent='  ')
         | 
| 231 | 
            +
                      ret = ''
         | 
| 232 | 
            +
                      ele.each_with_index do |e,i|
         | 
| 233 | 
            +
                        last  = (i == ele.length - 1)
         | 
| 234 | 
            +
                        pchar = last ? '└' : '├'
         | 
| 235 | 
            +
                        if e.container?
         | 
| 236 | 
            +
                          ret << indent + pchar + ' ' + e.class.to_s.gsub(/[^:]*::/,'') + "\n"
         | 
| 237 | 
            +
                          ret << print_tree(e,indent + (last ? '  ' : '│ '))
         | 
| 238 | 
            +
                        elsif e.is_a?(Break) && 
         | 
| 239 | 
            +
                          ret << indent + pchar + ' ' + e.class.to_s.gsub(/[^:]*::/,'') + "\n"
         | 
| 240 | 
            +
                        else
         | 
| 241 | 
            +
                          ret << indent + pchar + ' ' + e.niceid.to_s + "\n"
         | 
| 242 | 
            +
                        end
         | 
| 243 | 
            +
                      end
         | 
| 244 | 
            +
                      ret
         | 
| 245 | 
            +
                    end
         | 
| 246 | 
            +
                    private :print_tree
         | 
| 247 | 
            +
                  end #}}}
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                  class Traces < Array #{{{
         | 
| 250 | 
            +
                    def initialize_copy(other)
         | 
| 251 | 
            +
                     super
         | 
| 252 | 
            +
                     self.map!{ |t| t.dup }
         | 
| 253 | 
            +
                    end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                    def remove(trcs)
         | 
| 256 | 
            +
                      trcs.each do |t|
         | 
| 257 | 
            +
                        self.delete(t)
         | 
| 258 | 
            +
                      end  
         | 
| 259 | 
            +
                    end
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                    def remove_empty
         | 
| 262 | 
            +
                      self.delete_if{|t| t.empty? }
         | 
| 263 | 
            +
                    end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                    def first_node
         | 
| 266 | 
            +
                      self.first.first
         | 
| 267 | 
            +
                    end
         | 
| 268 | 
            +
                    def second_nodes
         | 
| 269 | 
            +
                      self.map { |t| t[1] }
         | 
| 270 | 
            +
                    end
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                    def shortest
         | 
| 273 | 
            +
                      self.min_by{|e|e.length}
         | 
| 274 | 
            +
                    end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
                    def to_s
         | 
| 277 | 
            +
                      "TRACES: " + self.collect { |t| t.empty? ? '∅' : t.collect{|n| "%2d" % n.niceid }.join('→ ') }.join("\n        ")
         | 
| 278 | 
            +
                    end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    def shift_all
         | 
| 281 | 
            +
                      self.each{ |tr| tr.shift }
         | 
| 282 | 
            +
                    end  
         | 
| 283 | 
            +
             | 
| 284 | 
            +
                    def finished?
         | 
| 285 | 
            +
                      self.reduce(0){|sum,t| sum += t.length} == 0
         | 
| 286 | 
            +
                    end
         | 
| 287 | 
            +
             | 
| 288 | 
            +
                    def same_first
         | 
| 289 | 
            +
                      (n = self.map{|t| t.first }.uniq).length == 1 ? n.first : nil
         | 
| 290 | 
            +
                    end
         | 
| 291 | 
            +
             | 
| 292 | 
            +
                    def include_in_all?(e)
         | 
| 293 | 
            +
                      num = 0
         | 
| 294 | 
            +
                      self.each{|n| num += 1 if n.include?(e)} 
         | 
| 295 | 
            +
                      num == self.length
         | 
| 296 | 
            +
                    end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                    def add_breaks
         | 
| 299 | 
            +
                      trueloops = self.find_all{ |t| t.last == t.first }.length
         | 
| 300 | 
            +
                      if trueloops == self.length
         | 
| 301 | 
            +
                        self << [self.first_node] ### the blank conditional so that we get a break
         | 
| 302 | 
            +
                      else
         | 
| 303 | 
            +
                        self.each do |t|
         | 
| 304 | 
            +
                          t << Break.new(1) unless t.last == t.first ### an explicit break
         | 
| 305 | 
            +
                        end
         | 
| 306 | 
            +
                      end  
         | 
| 307 | 
            +
                    end
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                    def loops
         | 
| 310 | 
            +
                      lo = Traces.new self.find_all{ |t| t.first == t.last }
         | 
| 311 | 
            +
                      self.each do |t|
         | 
| 312 | 
            +
                        lo << t if lo.second_nodes.include?(t[1])
         | 
| 313 | 
            +
                      end
         | 
| 314 | 
            +
                      lo.uniq
         | 
| 315 | 
            +
                    end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                    def eliminate(loops)
         | 
| 318 | 
            +
                      ### find nested loops
         | 
| 319 | 
            +
                      self.each_with_index do |t,i|
         | 
| 320 | 
            +
                        maxcut = 0
         | 
| 321 | 
            +
                        ### find out which common parts the traces share with theloops
         | 
| 322 | 
            +
                        loops.each do |l|
         | 
| 323 | 
            +
                          maxcut.upto(l.length) do |i|
         | 
| 324 | 
            +
                            maxcut = i if t[0...i] == l[0...i]
         | 
| 325 | 
            +
                          end
         | 
| 326 | 
            +
                        end
         | 
| 327 | 
            +
                        ### in case of nested loop (common part occurs at end of loop), include the whole
         | 
| 328 | 
            +
                        0.upto (maxcut-1) do |j|
         | 
| 329 | 
            +
                          if self[i][j] == self[i].last
         | 
| 330 | 
            +
                            loops << self[i].shift(self[i].length)
         | 
| 331 | 
            +
                          end
         | 
| 332 | 
            +
                        end  
         | 
| 333 | 
            +
                      end
         | 
| 334 | 
            +
                      loops.uniq!
         | 
| 335 | 
            +
                      loops.remove_empty
         | 
| 336 | 
            +
                      self.remove_empty
         | 
| 337 | 
            +
             | 
| 338 | 
            +
                      ### cut from non-nested loops
         | 
| 339 | 
            +
                      self.each_with_index do |t,i|
         | 
| 340 | 
            +
                        maxcut = 0
         | 
| 341 | 
            +
                        ### find out which common parts the traces share with theloops
         | 
| 342 | 
            +
                        loops.each do |l|
         | 
| 343 | 
            +
                          maxcut.upto(l.length) do |i|
         | 
| 344 | 
            +
                            maxcut = i if t[0...i] == l[0...i]
         | 
| 345 | 
            +
                          end
         | 
| 346 | 
            +
                        end
         | 
| 347 | 
            +
                        loops << self[i].shift(maxcut)
         | 
| 348 | 
            +
                      end
         | 
| 349 | 
            +
                    end
         | 
| 350 | 
            +
             | 
| 351 | 
            +
                    def extend
         | 
| 352 | 
            +
                      # find largest common
         | 
| 353 | 
            +
                      max = nil
         | 
| 354 | 
            +
                      sh = self.shortest
         | 
| 355 | 
            +
                      sh = sh[0..-2] if sh.first == sh.last
         | 
| 356 | 
            +
                      sh.each do |e,i|
         | 
| 357 | 
            +
                        if self.include_in_all?(e)
         | 
| 358 | 
            +
                          max = e
         | 
| 359 | 
            +
                        else  
         | 
| 360 | 
            +
                          break
         | 
| 361 | 
            +
                        end
         | 
| 362 | 
            +
                      end
         | 
| 363 | 
            +
             | 
| 364 | 
            +
                      # if last is the largest common do nothing
         | 
| 365 | 
            +
                      # else append from last to largest common
         | 
| 366 | 
            +
                      self.each do |t|
         | 
| 367 | 
            +
                        unless t.last == max
         | 
| 368 | 
            +
                          last = t.last
         | 
| 369 | 
            +
                          t.last.incoming = 1
         | 
| 370 | 
            +
                          if t.index(last) && t.index(max)
         | 
| 371 | 
            +
                            (t.index(last) + 1).upto(t.index(max)) do |i|
         | 
| 372 | 
            +
                              t << t[i]
         | 
| 373 | 
            +
                            end 
         | 
| 374 | 
            +
                          end
         | 
| 375 | 
            +
                        end  
         | 
| 376 | 
            +
                      end
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                      max.incoming = self.length
         | 
| 379 | 
            +
                      max
         | 
| 380 | 
            +
                    end
         | 
| 381 | 
            +
             | 
| 382 | 
            +
                    def segment_by_loops(loops)
         | 
| 383 | 
            +
                      # supress loops
         | 
| 384 | 
            +
                      self.delete_if { |t| loops.include?(t) }
         | 
| 385 | 
            +
                      self.eliminate(loops)
         | 
| 386 | 
            +
                      loops.extend
         | 
| 387 | 
            +
                    end  
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                    def find_endnode
         | 
| 390 | 
            +
                      # supress loops
         | 
| 391 | 
            +
                      trcs = self.dup
         | 
| 392 | 
            +
                      trcs.delete_if { |t| t.uniq.length < t.length }
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                      # find common node (except loops)
         | 
| 395 | 
            +
                      enode = nil
         | 
| 396 | 
            +
                      trcs.first.each do |n|
         | 
| 397 | 
            +
                        if trcs.include_in_all?(n)
         | 
| 398 | 
            +
                          enode = n
         | 
| 399 | 
            +
                          break
         | 
| 400 | 
            +
                        end  
         | 
| 401 | 
            +
                      end
         | 
| 402 | 
            +
                      enode
         | 
| 403 | 
            +
                    end  
         | 
| 404 | 
            +
             | 
| 405 | 
            +
                    def segment_by(endnode)
         | 
| 406 | 
            +
                      # cut shit until common node, return the shit you cut away
         | 
| 407 | 
            +
                      tracesgroup = self.group_by{|t| t.first}.map do |k,trace|
         | 
| 408 | 
            +
                        coltrace = trace.map do |t|
         | 
| 409 | 
            +
                          # slice upto common node, collect the sliced away part
         | 
| 410 | 
            +
                          len = t.index(endnode)
         | 
| 411 | 
            +
                          if len
         | 
| 412 | 
            +
                            cut = t.slice!(0...len)
         | 
| 413 | 
            +
                            cut << t.first
         | 
| 414 | 
            +
                          else # if endnode is nil, then return the whole
         | 
| 415 | 
            +
                            t
         | 
| 416 | 
            +
                          end
         | 
| 417 | 
            +
                        end.uniq
         | 
| 418 | 
            +
                        Traces.new(coltrace)
         | 
| 419 | 
            +
                      end
         | 
| 420 | 
            +
                      [tracesgroup,endnode]
         | 
| 421 | 
            +
                    end
         | 
| 422 | 
            +
                  end #}}}
         | 
| 423 | 
            +
             | 
| 424 | 
            +
              end
         | 
| 425 | 
            +
             | 
| 426 | 
            +
            end
         |