Skip to content
This repository has been archived by the owner on Mar 12, 2020. It is now read-only.

Commit

Permalink
Revise ID properties #19
Browse files Browse the repository at this point in the history
  • Loading branch information
tdauth committed Apr 10, 2019
1 parent 75baf13 commit d973b6e
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ object Example extends App {
private val action0 = new NavigateToAction("http://google.com")

val stateMachine = GuiStateMachineApi.neo4j.createStateMachine("tmp")
//stateMachine.clear()
stateMachine.clear()
val startState = new SutState(Arrays.asList(rootElementA, rootElementB, rootElementC))
val endState = new SutState(Arrays.asList(rootElementA))

stateMachine.getState(startState)
stateMachine.getState(endState)

// TODO #19 The states do not exist after this although saved. Concurrent transactions?

println(s"All states ${stateMachine.getAllStates.size}")

stateMachine.executeAction(startState, action0, endState)

println(s"All states ${stateMachine.getAllStates.size}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package de.retest.guistatemachine.api.neo4j
import org.neo4j.ogm.annotation.{EndNode, Index, RelationshipEntity, StartNode}
import org.neo4j.ogm.annotation._

@RelationshipEntity(`type` = "ACTIONS")
class ActionTransitionEntity(s: SutStateEntity, e: SutStateEntity, a: String) extends Entity {
class ActionTransitionEntity(s: SutStateEntity, e: SutStateEntity, a: String) {

def this() = this(null, null, null)

@Id
@GeneratedValue
var id: java.lang.Long = 0L

@Index
@StartNode val start: SutStateEntity = s
@StartNode var start: SutStateEntity = s

@Index
@EndNode val end: SutStateEntity = e
@EndNode var end: SutStateEntity = e

@Index
val action: String = a
var action: String = a

/// The number of times this action has been executed.
var counter: Int = 1
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package de.retest.guistatemachine.api.neo4j

import com.typesafe.scalalogging.Logger
import de.retest.guistatemachine.api.{GuiStateMachine, State, SutStateIdentifier}
import org.neo4j.ogm.cypher.{ComparisonOperator, Filter}

import scala.collection.immutable.HashMap

class GuiStateMachineNeo4J(var uri: String) extends GuiStateMachine {
private val logger = Logger[GuiStateMachineNeo4J]
implicit val session = Neo4jSessionFactory.getSessionFactory(uri).openSession() // TODO #19 Close the session at some point?

override def getState(sutStateIdentifier: SutStateIdentifier): State = {
Neo4jSessionFactory.transaction {
val result = Neo4jSessionFactory.transaction {
getNodeBySutStateIdentifier(sutStateIdentifier) match {
case None =>
// Create a new node for the SUT state in the graph database.
val sutStateEntity = new SutStateEntity(sutStateIdentifier)
session.save(sutStateEntity)
true

// Do nothing if the node for the SUT state does already exist.
case _ =>
case Some(_) => false
}
}

if (result) {
logger.info("Created new state with hash {}", sutStateIdentifier.hash)
}

StateNeo4J(sutStateIdentifier, this)
}

Expand All @@ -32,7 +39,7 @@ class GuiStateMachineNeo4J(var uri: String) extends GuiStateMachine {

while (iterator.hasNext) {
val node = iterator.next()
val sutState = new SutStateIdentifier(node.id)
val sutState = new SutStateIdentifier(node.hash)
result = result + (sutState -> StateNeo4J(sutState, this))
}
result
Expand All @@ -47,7 +54,7 @@ class GuiStateMachineNeo4J(var uri: String) extends GuiStateMachine {
}

private[neo4j] def getNodeBySutStateIdentifier(sutStateIdentifier: SutStateIdentifier): Option[SutStateEntity] = {
val filter = new Filter("id", ComparisonOperator.EQUALS, sutStateIdentifier.hash)
val filter = new Filter("hash", ComparisonOperator.EQUALS, sutStateIdentifier.hash)
val first = session.loadAll(classOf[SutStateEntity], filter).stream().findFirst()
if (first.isPresent) {
Some(first.get())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ case class StateNeo4J(sutStateIdentifier: SutStateIdentifier, guiStateMachine: G
while (iterator.hasNext) {
val relationship = iterator.next()
val action = new ActionIdentifier(relationship.action)
val targetSutState = new SutStateIdentifier(relationship.end.id)
val targetSutState = new SutStateIdentifier(relationship.end.hash)
val counter = relationship.counter
val actionTransitions = if (result.contains(action)) {
val existing = result(action)
Expand All @@ -39,7 +39,7 @@ case class StateNeo4J(sutStateIdentifier: SutStateIdentifier, guiStateMachine: G
while (iterator.hasNext) {
val relationship = iterator.next()
val action = new ActionIdentifier(relationship.action)
val sourceSutState = new SutStateIdentifier(relationship.start.id)
val sourceSutState = new SutStateIdentifier(relationship.start.hash)
val counter = relationship.counter
val actionTransitions = if (result.contains(action)) {
val existing = result(action)
Expand All @@ -52,33 +52,39 @@ case class StateNeo4J(sutStateIdentifier: SutStateIdentifier, guiStateMachine: G
result
}

// TODO #19 Can we somehow add the transition to the incoming and outgoing relations?
private[api] override def addTransition(a: ActionIdentifier, to: State): Int = Neo4jSessionFactory.transaction {
/*
TODO #19 Filter for start and end states.
val filterStart = new Filter("start", ComparisonOperator.EQUALS, sutStateIdentifier.hash)
val filterEnd = new Filter("end", ComparisonOperator.EQUALS, targetSutStateIdentifier.hash)
filterStart.and(filterAction).and(filterEnd)
*/

val filterAction = new Filter("action", ComparisonOperator.EQUALS, a.hash)
val targetSutStateIdentifier = to.asInstanceOf[StateNeo4J].sutStateIdentifier

import scala.collection.JavaConversions._
val transitions = session.loadAll(classOf[ActionTransitionEntity], filterAction).toSeq

val matchingTransitions = transitions.filter(actionTransitionEntity =>
actionTransitionEntity.start.id == sutStateIdentifier.hash && actionTransitionEntity.end.id == targetSutStateIdentifier.hash)
actionTransitionEntity.start.hash == sutStateIdentifier.hash && actionTransitionEntity.end.hash == targetSutStateIdentifier.hash)
if (matchingTransitions.nonEmpty) {
val first: ActionTransitionEntity = matchingTransitions.head
first.counter = first.counter + 1
session.save(first)
first.counter
} else {
val sourceState = guiStateMachine.getNodeBySutStateIdentifier(sutStateIdentifier).get
val targetState = guiStateMachine.getNodeBySutStateIdentifier(targetSutStateIdentifier).get
val transition = new ActionTransitionEntity(sourceState, targetState, a.hash)
session.save(transition)
1
guiStateMachine.getNodeBySutStateIdentifier(sutStateIdentifier) match {
case Some(sourceState) =>
guiStateMachine.getNodeBySutStateIdentifier(targetSutStateIdentifier) match {
case Some(targetState) =>
val transition = new ActionTransitionEntity(sourceState, targetState, a.hash)
session.save(transition)
1
case None => throw new RuntimeException(s"Missing target state $targetSutStateIdentifier.")
}
case None => throw new RuntimeException(s"Missing source state $sutStateIdentifier.")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
package de.retest.guistatemachine.api.neo4j

import de.retest.guistatemachine.api.SutStateIdentifier
import org.neo4j.ogm.annotation.{Relationship, _}

import scala.collection.mutable
import org.neo4j.ogm.annotation._

@NodeEntity
class SutStateEntity(
@Id
//@Index(unique = true)
val id: java.lang.String) {
@Index(unique = true)
@Property
var hash: java.lang.String) {

def this(sutStateIdentifier: SutStateIdentifier) = this(sutStateIdentifier.hash)
def this() = this("")

@Relationship(`type` = "ACTIONS", direction = Relationship.INCOMING) val incomingActionTransitions = mutable.HashSet[ActionTransitionEntity]()
@Relationship(`type` = "ACTIONS", direction = Relationship.OUTGOING) val outgoingActionTransitions = mutable.HashSet[ActionTransitionEntity]()
@Id
@GeneratedValue
var id: java.lang.Long = 0L

@Relationship(`type` = "ACTIONS", direction = Relationship.UNDIRECTED) var actionTransitions = new java.util.LinkedList[ActionTransitionEntity]()

// TODO #19 Which container types?
/*
@Relationship(`type` = "ACTIONS", direction = Relationship.INCOMING) var incomingActionTransitions = new java.util.LinkedList[ActionTransitionEntity]()
@Relationship(`type` = "ACTIONS", direction = Relationship.OUTGOING) var outgoingActionTransitions = new java.util.LinkedList[ActionTransitionEntity]()
*/
}

0 comments on commit d973b6e

Please sign in to comment.