@@ -48,6 +48,7 @@ import org.neo4j.graphdb.Label
4848import org.neo4j.graphdb.Direction
4949import org.neo4j.graphdb.traversal.Uniqueness
5050import org.svis.xtext.famix.FAMIXElement
51+ import org.neo4j.graphdb.Relationship
5152
5253class Famix2Famix extends WorkflowComponentWithConfig {
5354 var GraphDatabaseService graph
@@ -73,90 +74,111 @@ class Famix2Famix extends WorkflowComponentWithConfig {
7374 famixRoot. document = famixDocument
7475 graph = Database :: getInstance(" ../databases/graph.db" )
7576 dbConnector = new DBConnector (graph)
76-
77+
7778 // Create Namespaces
7879 val packageLabel = Label . label(" Package" )
7980 val classLabel = Label . label(" Class" )
8081 val namespaces = newHashMap
8182 val classes = newHashMap
83+ val methods = newHashMap
84+ val attributes = newHashMap
8285 val famixEvaluator = new FamixEvaluator ()
8386 var tx = graph. beginTx
8487 try {
8588 // get roots packages
8689 val result = graph. execute(" MATCH (n:Package) WHERE NOT (n)<-[:CONTAINS]-(:Package)RETURN n" )
87- result. forEach[ row|
90+ result. forEach [ row |
8891 val rootnode = row. get(" n" ) as Node
8992 // traverse though complete graph
90- graph. traversalDescription
91- . breadthFirst
92- . relationships( Rels . CONTAINS , Direction . OUTGOING )
93- . relationships(Rels . DECLARES , Direction . OUTGOING ) // filters relevant relationships
94- . uniqueness(Uniqueness . NONE )
95- . evaluator(famixEvaluator) // filters relevant nodes
96- . traverse(rootnode)
97- . forEach[path|
98- // this loop is executed for every path
99- // for every end node an own path exists
100- // therefore we are just interested in the end node, the other nodes have already been handled
101- val node = path. endNode
102- var Node parent
103- if (path. length != 0 ) {
104- parent = path. nodes. get(path. length- 1 )
105- }
106- else {
107- parent = null
108- }
109- var type = " "
110- for (label : node. labels) {
111- if (label. name == " Package" ) {
112- type = " Package"
113- } else if (label. name == " Class" ) {
114- type = " Class"
115- } else if (label. name == " Method" ) {
116- type = " Method"
117- } else if (label. name == " Field" ) {
118- type = " Field"
93+ graph. traversalDescription. breadthFirst. relationships(Rels . CONTAINS , Direction . OUTGOING ).
94+ relationships(Rels . DECLARES , Direction . OUTGOING ) // filters relevant relationships
95+ . uniqueness(Uniqueness . NONE ). evaluator(famixEvaluator) // filters relevant nodes
96+ . traverse(rootnode). forEach [ path |
97+ // this loop is executed for every path
98+ // for every end node an own path exists
99+ // therefore we are just interested in the end node, the other nodes have already been handled
100+ val node = path. endNode
101+ var Node parent
102+ if (path. length != 0 ) {
103+ parent = path. nodes. get(path. length - 1 )
104+ } else {
105+ parent = null
119106 }
120- }
121- switch (type) {
122- case " Package" : {
123- var FAMIXNamespace parentNamespace = null
124- if (parent !== null ) {
125- parentNamespace = namespaces. get(parent. id)
107+ var type = " "
108+ for (label : node. labels) {
109+ if (label. name == " Package" ) {
110+ type = " Package"
111+ } else if (label. name == " Class" ) {
112+ type = " Class"
113+ } else if (label. name == " Method" ) {
114+ type = " Method"
115+ } else if (label. name == " Field" ) {
116+ type = " Field"
126117 }
127- val namespace = createNamespace(node, parentNamespace)
128- namespaces. put(node. id, namespace)
129- famixDocument. elements + = namespace
130118 }
131- case " Class" : {
132- var FAMIXElement container
133- if (parent. hasLabel(packageLabel)) {
134- container = namespaces. get(parent. id) as FAMIXNamespace
119+ switch (type) {
120+ case " Package" : {
121+ var FAMIXNamespace parentNamespace = null
122+ if (parent !== null ) {
123+ parentNamespace = namespaces. get(parent. id)
124+ }
125+ val namespace = createNamespace(node, parentNamespace)
126+ namespaces. put(node. id, namespace)
127+ famixDocument. elements + = namespace
135128 }
136-
137- if (parent. hasLabel(classLabel)) {
138- container = classes. get(parent. id) as FAMIXClass
129+ case " Class" : {
130+ var FAMIXElement container
131+ if (parent. hasLabel(packageLabel)) {
132+ container = namespaces. get(parent. id) as FAMIXNamespace
133+ }
134+
135+ if (parent. hasLabel(classLabel)) {
136+ container = classes. get(parent. id) as FAMIXClass
137+ }
138+ val class = createClass(node, container)
139+ classes. put(node. id, class)
140+ famixDocument. elements + = class
141+ }
142+ case " Method" : {
143+ val parentClass = classes. get(parent. id)
144+ val fileAnchor = famixFactory. createFAMIXFileAnchor
145+ fileAnchor. filename = parent. getProperty(" sourceFileName" ) as String
146+ val method = createMethod(node, parentClass, fileAnchor)
147+ methods. put(node. id, method)
148+ famixDocument. elements + = method
149+ }
150+ case " Field" : {
151+ val parentClass = classes. get(parent. id)
152+ val fileAnchor = famixFactory. createFAMIXFileAnchor
153+ fileAnchor. filename = parent. getProperty(" sourceFileName" ) as String
154+ val attribute = createAttribute(node, parentClass, fileAnchor)
155+ attributes. put(node. id, attribute)
156+ famixDocument. elements + = attribute
139157 }
140- val class = createClass(node, container)
141- classes. put(node. id, class)
142- famixDocument. elements + = class
143- }
144- case " Method" : {
145- val parentClass = classes. get(parent. id)
146- val fileAnchor = famixFactory. createFAMIXFileAnchor
147- fileAnchor. filename = parent. getProperty(" sourceFileName" ) as String
148- val method = createMethod(node, parentClass, fileAnchor)
149- famixDocument. elements + = method
150- }
151- case " Field" : {
152- val parentClass = classes. get(parent. id)
153- val fileAnchor = famixFactory. createFAMIXFileAnchor
154- fileAnchor. filename = parent. getProperty(" sourceFileName" ) as String
155- val attribute = createAttribute(node, parentClass, fileAnchor)
156- famixDocument. elements+ = attribute
157158 }
158- }
159- ]
159+ ]
160+ ]
161+ graph. execute(" MATCH p=()-[r:INVOKES]->() RETURN r" ). forEach [ row |
162+ val rel = row. get(" r" ) as Relationship
163+ val invocation = famixFactory. createFAMIXInvocation
164+ val senderRef = famixFactory. createIntegerReference
165+ val receiverRef = famixFactory. createIntegerReference
166+ senderRef. ref = methods. get(rel. startNode. id)
167+ receiverRef. ref = methods. get(rel. endNode. id)
168+ invocation. sender = senderRef
169+ invocation. candidates = receiverRef
170+ famixDocument. elements + = invocation
171+ ]
172+ graph. execute(" MATCH p=()-[r:READS|WRITES]->() RETURN r" ). forEach [ row |
173+ val rel = row. get(" r" ) as Relationship
174+ val access = famixFactory. createFAMIXAccess
175+ val attributeRef = famixFactory. createIntegerReference
176+ val accessorRef = famixFactory. createIntegerReference
177+ attributeRef. ref = attributes. get(rel. endNode. id)
178+ accessorRef. ref = methods. get(rel. startNode. id)
179+ access. variable = attributeRef
180+ access. accessor = accessorRef
181+ famixDocument. elements + = access
160182 ]
161183 println(" finish" )
162184 tx. success
@@ -165,6 +187,7 @@ class Famix2Famix extends WorkflowComponentWithConfig {
165187 } finally {
166188 tx. close
167189 }
190+
168191 ctx. set(" famix" , famixRoot)
169192 val resource = new ResourceImpl ()
170193 resource. contents + = famixRoot
@@ -195,7 +218,6 @@ class Famix2Famix extends WorkflowComponentWithConfig {
195218 }
196219 }
197220
198-
199221 def private run (Root famixRoot ) {
200222 val famixDocument = famixRoot. document
201223 famixDocument. elements. removeAll(Collections :: singleton(null ))
@@ -660,39 +682,38 @@ class Famix2Famix extends WorkflowComponentWithConfig {
660682 enumValues. removeAll(duplicateEnumValues)
661683 structures. removeAll(duplicateAnnotationTypes)
662684 }
663-
685+
664686 def createNamespace (Node node , FAMIXNamespace parent ) {
665687 val namespace = famixFactory. createFAMIXNamespace
666688 val id = node. id. toString
667689 namespace. name = id
668690 namespace. id = id
669691 namespace. value = node. getProperty(" name" ) as String
670692 namespace. fqn = node. getProperty(" fqn" ) as String
671- if (parent !== null ) {
693+ if (parent !== null ) {
672694 var ref = famixFactory. createIntegerReference
673695 ref. ref = parent
674696 namespace. parentScope = ref
675697 }
676698 return namespace
677699 }
678-
700+
679701 def createClass (Node node , FAMIXElement parent ) {
680702 val class = famixFactory. createFAMIXClass
681703 class. name = node. id. toString
682- if (node. hasProperty(" name" )) {
704+ if (node. hasProperty(" name" )) {
683705 class. value = node. getProperty(" name" ) as String
684- }
685- if (node. hasProperty(" fqn" )) {
706+ }
707+ if (node. hasProperty(" fqn" )) {
686708 class. fqn = node. getProperty(" fqn" ) as String
687709 }
688- if (node. hasProperty(" md5" )) {
710+ if (node. hasProperty(" md5" )) {
689711 class. id = node. getProperty(" md5" ) as String
690712 }
691713 var ref = famixFactory. createIntegerReference
692- if (parent instanceof FAMIXNamespace ) {
714+ if (parent instanceof FAMIXNamespace ) {
693715 ref. ref = parent as FAMIXNamespace
694- }
695- else {
716+ } else {
696717 ref. ref = parent as FAMIXClass
697718 }
698719 class. container = ref
@@ -706,33 +727,34 @@ class Famix2Famix extends WorkflowComponentWithConfig {
706727 fileAnchor. element = classRef
707728 return class
708729 }
709-
730+
710731 def createMethod (Node node , FAMIXClass parent , FAMIXFileAnchor fileAnchor ) {
711732 val method = famixFactory. createFAMIXMethod
712733 method. name = node. id. toString
713- if (node. hasProperty(" name" )) {
734+ if (node. hasProperty(" name" )) {
714735 method. value = node. getProperty(" name" ) as String
715- }
716- if (node. hasProperty(" cyclomaticComplexity" )) {
736+ }
737+ if (node. hasProperty(" cyclomaticComplexity" )) {
717738 val cyclomaticComplexity = node. getProperty(" cyclomaticComplexity" ) as Long
718739 method. cyclomaticComplexity = cyclomaticComplexity. intValue
719740 }
720- if (node. hasProperty(" effectiveLineCount" )) {
741+ if (node. hasProperty(" effectiveLineCount" )) {
721742 val numberOfStatements = node. getProperty(" effectiveLineCount" ) as Long
722743 method. numberOfStatements = numberOfStatements. intValue
723744 }
724745 method. signature = node. getProperty(" signature" ) as String
746+ method. fqn = parent. fqn + " ." + method. value + " ()"
725747 var ref = famixFactory. createIntegerReference
726748 ref. ref = parent
727749 method. parentType = ref
728- if (node. hasProperty(" firstLineNumber" )) {
750+ if (node. hasProperty(" firstLineNumber" )) {
729751 val firstLineNumber = node. getProperty(" firstLineNumber" ) as Long
730752 fileAnchor. startline = firstLineNumber. intValue
731753 }
732- if (node. hasProperty(" lastLineNumber" )) {
754+ if (node. hasProperty(" lastLineNumber" )) {
733755 val lastLineNumber = node. getProperty(" lastLineNumber" ) as Long
734756 fileAnchor. endline = lastLineNumber. intValue
735- }
757+ }
736758 var anchorRef = famixFactory. createIntegerReference
737759 anchorRef. ref = method
738760 var methodRef = famixFactory. createIntegerReference
@@ -741,15 +763,15 @@ class Famix2Famix extends WorkflowComponentWithConfig {
741763 method. sourceAnchor = anchorRef
742764 return method
743765 }
744-
766+
745767 def createAttribute (Node node , FAMIXClass parent , FAMIXFileAnchor fileAnchor ) {
746768 val attribute = famixFactory. createFAMIXAttribute
747769 attribute. name = node. id. toString
748- if (node. hasProperty(" name" )) {
770+ if (node. hasProperty(" name" )) {
749771 attribute. value = node. getProperty(" name" ) as String
750772 }
751- if (node. hasProperty(" visibility" )) {
752- attribute. modifiers+ = node. getProperty(" visibility" ) as String
773+ if (node. hasProperty(" visibility" )) {
774+ attribute. modifiers + = node. getProperty(" visibility" ) as String
753775 }
754776 var ref = famixFactory. createIntegerReference
755777 ref. ref = parent
0 commit comments