From d78e6448070cc3421ce41cac3561e97b8266d985 Mon Sep 17 00:00:00 2001 From: Tamino Dauth Date: Tue, 9 Apr 2019 17:32:33 +0200 Subject: [PATCH] Allow construction of identifiers by hash code only #19 Required by the OGM converters. --- README.md | 4 +++- build.sbt | 15 +++++++-------- .../guistatemachine/api/ActionIdentifier.scala | 9 +++++++-- .../guistatemachine/api/HashIdentifier.scala | 12 ++++++++---- .../guistatemachine/api/SutStateIdentifier.scala | 9 +++++++-- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3af4fe4..a1d66eb 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ This backend uses the GraphDB [Neo4J](https://neo4j.com/) (community edition) wi It uses [Neo4J-OGM](https://neo4j.com/docs/ogm-manual/current/) to map our types to the graph database. Each state machine is represented by a separate graph database stored in a separate directory. -The nodes all have the property "sutState" which contains the corresponding SUT state serialized as XML. The relationship types correspond to actions. Each relation has the property "counter" which contains the execution counter of the action. + +Visualization: +Desktop application: diff --git a/build.sbt b/build.sbt index d7c138d..a22c21b 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ name := "gui-state-machine-api" organization := "de.retest" -scalaVersion := "2.12.8" +scalaVersion := "2.11.8" /* * retest-sut-api provides a package and an object with the name a etc. @@ -20,16 +20,15 @@ resolvers += "nexus-retest-maven-all" at "https://nexus.retest.org/repository/al resolvers += "sonatype-snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/" +// Dependencies for a graph database: +libraryDependencies += "org.neo4j" % "neo4j" % "3.5.4" +libraryDependencies += "org.neo4j" % "neo4j-ogm-core" % "3.1.8" +libraryDependencies += "org.neo4j" % "neo4j-ogm-embedded-driver" % "3.1.8" + // Dependencies to represent states and actions: libraryDependencies += "de.retest" % "surili-commons" % "0.1.0-SNAPSHOT" withSources () withJavadoc () changing () libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.0" -// Dependencies for a graph database: -libraryDependencies += "org.neo4j" % "neo4j" % "3.0.1" -libraryDependencies += "org.neo4j" % "neo4j-ogm-core" % "3.1.7" -libraryDependencies += "org.neo4j" % "neo4j-ogm-embedded-driver" % "3.1.7" -libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.1.1" - // Dependencies to write GML files for yEd: libraryDependencies += "com.github.systemdir.gml" % "GMLWriterForYed" % "2.1.0" libraryDependencies += "org.jgrapht" % "jgrapht-core" % "1.0.1" @@ -57,5 +56,5 @@ sys.env.get("TRAVIS_NEXUS_PW") match { case Some(password) => credentials += Credentials("ReTest Nexus", "nexus.retest.org", "retest", password) case _ => - throw new IllegalStateException("PASSWORD is missing!") + throw new IllegalStateException("TRAVIS_NEXUS_PW is not defined as environment variable!") } diff --git a/src/main/scala/de/retest/guistatemachine/api/ActionIdentifier.scala b/src/main/scala/de/retest/guistatemachine/api/ActionIdentifier.scala index a5b16a3..626ef03 100644 --- a/src/main/scala/de/retest/guistatemachine/api/ActionIdentifier.scala +++ b/src/main/scala/de/retest/guistatemachine/api/ActionIdentifier.scala @@ -2,7 +2,12 @@ package de.retest.guistatemachine.api import de.retest.surili.commons.actions.Action -class ActionIdentifier(action: Action) extends HashIdentifier(action) { - val msg = s"ActionIdentifier[action=${action.toString}, hash=$hash]" +class ActionIdentifier(hash: String) extends HashIdentifier(hash) { + var msg = s"ActionIdentifier[action=Unknown, hash=$hash]" + + def this(action: Action) = { + this(HashIdentifier.sha256Hash(action)) + msg = s"ActionIdentifier[action=${action.toString}, hash=$hash]" + } override def toString: String = msg } diff --git a/src/main/scala/de/retest/guistatemachine/api/HashIdentifier.scala b/src/main/scala/de/retest/guistatemachine/api/HashIdentifier.scala index 42ed148..721709f 100644 --- a/src/main/scala/de/retest/guistatemachine/api/HashIdentifier.scala +++ b/src/main/scala/de/retest/guistatemachine/api/HashIdentifier.scala @@ -6,12 +6,14 @@ import java.io.{ByteArrayOutputStream, ObjectOutputStream, Serializable} * Storing the whole states and actions as XML takes too much space. Therefore, we only store a hash value. The hash * should have no collisions to uniquely identify states and actions. Since we use SHA-256 the probability is very low * that any collisions will occur. - * - * @param serializable The serializable from which a SHA-256 is generated. */ @SerialVersionUID(1L) -class HashIdentifier(serializable: Serializable) extends scala.Serializable { - val hash: String = HashIdentifier.sha256Hash(HashIdentifier.serializableToString(serializable)) +class HashIdentifier(val hash: String) extends scala.Serializable { + + /** + * @param serializable The serializable from which a SHA-256 is generated. + */ + def this(serializable: Serializable) = this(HashIdentifier.sha256Hash(serializable)) override def equals(obj: Any): Boolean = if (!obj.isInstanceOf[HashIdentifier]) { @@ -31,6 +33,8 @@ object HashIdentifier { def sha256Hash(text: String): String = String.format("%064x", new java.math.BigInteger(1, java.security.MessageDigest.getInstance("SHA-256").digest(text.getBytes("UTF-8")))) + def sha256Hash(serializable: Serializable): String = sha256Hash(serializableToString(serializable)) + def serializableToString(serializable: Serializable): String = { val byteArrayOutputStream = new ByteArrayOutputStream() val oos = new ObjectOutputStream(byteArrayOutputStream) diff --git a/src/main/scala/de/retest/guistatemachine/api/SutStateIdentifier.scala b/src/main/scala/de/retest/guistatemachine/api/SutStateIdentifier.scala index 9f66280..fe5e180 100644 --- a/src/main/scala/de/retest/guistatemachine/api/SutStateIdentifier.scala +++ b/src/main/scala/de/retest/guistatemachine/api/SutStateIdentifier.scala @@ -2,7 +2,12 @@ package de.retest.guistatemachine.api import de.retest.recheck.ui.descriptors.SutState -class SutStateIdentifier(sutState: SutState) extends HashIdentifier(sutState) { - val msg = s"SutStateIdentifier[sutState=${sutState.toString}, hash=$hash]" +class SutStateIdentifier(hash: String) extends HashIdentifier(hash) { + var msg = s"SutStateIdentifier[sutState=Unknown, hash=$hash]" + + def this(sutState: SutState) { + this(HashIdentifier.sha256Hash(sutState)) + msg = s"SutStateIdentifier[sutState=${sutState.toString}, hash=$hash]" + } override def toString: String = msg }