%load_ext cypher

"""
Explanation: Introduction
Software architects have to make sure that the communicated software architecture blueprints exist in the real world. For this, manual inspections as well as automated measurements are needed to avoid surprises.
In this notebook, I want to show how software architects can define and check for architectural governance rules for Java applications using jQAssistant and Neo4j.
Idea
This notebook shows an approach to check for architectural rules using the structural code analyzer jQAssistant in combination with the graph database Neo4j. jQAssistant scans several artifacts (Java Bytecode, Git history, Maven Dependencies, and so on) and stores the structural information into the Neo4j database. 
<img src="../demos/resources/fitness_functions_with_jqassistant.png" style="width:80%;"/>
<div align=center><small>Figure 1: Overview of the analysis pipeline</small></div>

Setup
If you want to execute the notebook, you also need to build the example project and run a Neo4j instance in the background. You can find the instructions here.
Load extension for querying the Neo4j graph database via Cypher.
End of explanation
"""


%%cypher
MATCH
  (t:Type)-[:ANNOTATED_BY]->()-[:OF_TYPE]->(a:Type)
WHERE
  a.fqn="javax.persistence.Entity"
SET
  t:Entity
RETURN
  t.fqn AS Entity

"""
Explanation: Define Concerns
In the application at hand (a fork of the Spring PetClinic project), there are Java classes called Entitys, that represent the database table. Each of these classes is marked by a special interface @Entity. We can find these classes by querying the graph database and create a higher level concern (or concept) to make further searches easier.
The following query defines Entitys and returns all found Entitys in the scanned codebase.
End of explanation
"""


%%cypher
MATCH (e:Entity)<-[:CONTAINS]-(p:Package)
WHERE p.name = "model"
RETURN e.fqn as Entity, p.name as Package

"""
Explanation: Rule Definition
Because we want to enable developers to quickly identify Entities in the application, we use the Java package names to define were all the Entities are placed. Thus, Entities must be placed in a package named model.
The following query lists all existing Entities in the scanned codebase:
End of explanation
"""


%%cypher
MATCH (e:Entity)<-[:CONTAINS]-(p:Package)
WHERE p.name <> "model"
RETURN e.fqn as MisplacedEntity, p.name as WrongPackage

"""
Explanation: Rule Violations
The following query lists all Enties that doesn't comply to the rule above:
End of explanation
"""


