-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WAYANG-32] Base structure for Wayang Experiments Storage functionali…
…ties
- Loading branch information
Showing
17 changed files
with
1,343 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>wayang-commons</artifactId> | ||
<groupId>org.apache.wayang</groupId> | ||
<version>0.6.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>wayang-utils</artifactId> | ||
<packaging>pom</packaging> | ||
|
||
<modules> | ||
<module>wayang-profile-db</module> | ||
</modules> | ||
|
||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>wayang-utils</artifactId> | ||
<groupId>org.apache.wayang</groupId> | ||
<version>0.6.0-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>wayang-profile-db</artifactId> | ||
|
||
<dependencies> | ||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> | ||
<dependency> | ||
<groupId>com.google.code.gson</groupId> | ||
<artifactId>gson</artifactId> | ||
</dependency> | ||
|
||
</dependencies> | ||
|
||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Base on | ||
|
||
https://github.com/sekruse/profiledb-java.git |
105 changes: 105 additions & 0 deletions
105
wayang-commons/wayang-utils/wayang-profile-db/src/main/java/profiledb/ProfileDB.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package profiledb; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
import profiledb.json.MeasurementDeserializer; | ||
import profiledb.json.MeasurementSerializer; | ||
import profiledb.model.Experiment; | ||
import profiledb.model.Measurement; | ||
import profiledb.storage.Storage; | ||
|
||
import java.io.*; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
/** | ||
* This class provides facilities to save and load {@link Experiment}s. | ||
*/ | ||
public class ProfileDB { | ||
|
||
/** | ||
* Maintains the full list of {@link Class}es for {@link Measurement}s. Which are required for deserialization. | ||
*/ | ||
private List<Class<? extends Measurement>> measurementClasses = new LinkedList<>(); | ||
|
||
/** | ||
* Controls how conducted experiments will be persisted and loaded | ||
*/ | ||
private Storage storage; | ||
|
||
/** | ||
* Maintains actions to preparate {@link Gson}. | ||
*/ | ||
private List<Consumer<GsonBuilder>> gsonPreparationSteps = new LinkedList<>(); | ||
|
||
/** | ||
* Maintains a {@link Gson} object for efficiency. It will be dropped on changes, though. | ||
*/ | ||
private Gson gson; | ||
|
||
/** | ||
* Creates a new instance. | ||
*/ | ||
public ProfileDB(Storage storage) { | ||
|
||
this.storage = storage; | ||
this.storage.setContext(this); | ||
//this.measurementClasses.add(TimeMeasurement.class); | ||
} | ||
|
||
/** | ||
* To work with storage object provided to persist or load experiments | ||
* | ||
* @return Storage object proportioned for this instance | ||
*/ | ||
public Storage getStorage() { | ||
return storage; | ||
} | ||
|
||
/** | ||
* Register a {@link Measurement} type. This is required before being able to load that type. | ||
* | ||
* @param measurementClass the {@link Measurement} {@link Class} | ||
* @return this instance | ||
*/ | ||
public ProfileDB registerMeasurementClass(Class<? extends Measurement> measurementClass) { | ||
this.measurementClasses.add(measurementClass); | ||
this.gson = null; | ||
return this; | ||
} | ||
|
||
/** | ||
* Apply any changes necessary to {@link Gson} so that it can be used for de/serialization of custom objects. | ||
* | ||
* @param preparation a preparatory step performed on a {@link GsonBuilder} | ||
* @return this instance | ||
*/ | ||
public ProfileDB withGsonPreparation(Consumer<GsonBuilder> preparation) { | ||
this.gsonPreparationSteps.add(preparation); | ||
this.gson = null; | ||
return this; | ||
} | ||
|
||
/** | ||
* Provide a {@link Gson} object. | ||
* | ||
* @return the {@link Gson} object | ||
*/ | ||
public Gson getGson() { | ||
if (this.gson == null) { | ||
MeasurementSerializer measurementSerializer = new MeasurementSerializer(); | ||
MeasurementDeserializer measurementDeserializer = new MeasurementDeserializer(); | ||
this.measurementClasses.forEach(measurementDeserializer::register); | ||
final GsonBuilder gsonBuilder = new GsonBuilder() | ||
.registerTypeAdapter(Measurement.class, measurementDeserializer) | ||
.registerTypeAdapter(Measurement.class, measurementSerializer); | ||
this.gsonPreparationSteps.forEach(step -> step.accept(gsonBuilder)); | ||
this.gson = gsonBuilder.create(); | ||
} | ||
return this.gson; | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
.../wayang-utils/wayang-profile-db/src/main/java/profiledb/json/MeasurementDeserializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package profiledb.json; | ||
|
||
import com.google.gson.JsonDeserializationContext; | ||
import com.google.gson.JsonDeserializer; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonParseException; | ||
import profiledb.model.Measurement; | ||
|
||
import java.lang.reflect.Type; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* Custom deserializer for {@link Measurement}s | ||
* Detects actual subclass of serialized instances and then delegates the deserialization to that subtype. | ||
*/ | ||
public class MeasurementDeserializer implements JsonDeserializer<Measurement> { | ||
|
||
private final Map<String, Class<? extends Measurement>> measurementTypes = new HashMap<>(); | ||
|
||
public void register(Class<? extends Measurement> measurementClass) { | ||
String typeName = Measurement.getTypeName(measurementClass); | ||
this.measurementTypes.put(typeName, measurementClass); | ||
} | ||
|
||
@Override | ||
public Measurement deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { | ||
final JsonElement typeElement = jsonElement.getAsJsonObject().get("type"); | ||
if (typeElement == null) { | ||
throw new IllegalArgumentException("Missing type in " + jsonElement); | ||
} | ||
final String typeName = typeElement.getAsString(); | ||
final Class<? extends Measurement> measurementClass = this.measurementTypes.get(typeName); | ||
if (measurementClass == null) { | ||
throw new JsonParseException("Unknown measurement type: " + typeName); | ||
} | ||
return jsonDeserializationContext.deserialize(jsonElement, measurementClass); | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
...ns/wayang-utils/wayang-profile-db/src/main/java/profiledb/json/MeasurementSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package profiledb.json; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonSerializationContext; | ||
import com.google.gson.JsonSerializer; | ||
import profiledb.model.Measurement; | ||
|
||
import java.lang.reflect.Type; | ||
|
||
/** | ||
* Custom serializer for {@link Measurement}s | ||
* Detects actual subclass of given instances, encodes this class membership, and then delegates serialization to that subtype. | ||
*/ | ||
public class MeasurementSerializer implements JsonSerializer<Measurement> { | ||
|
||
@Override | ||
public JsonElement serialize(Measurement measurement, Type type, JsonSerializationContext jsonSerializationContext) { | ||
final JsonObject jsonObject = (JsonObject) jsonSerializationContext.serialize(measurement); | ||
jsonObject.addProperty("type", measurement.getType()); | ||
return jsonObject; | ||
} | ||
} |
163 changes: 163 additions & 0 deletions
163
wayang-commons/wayang-utils/wayang-profile-db/src/main/java/profiledb/model/Experiment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package profiledb.model; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.LinkedList; | ||
import java.util.Objects; | ||
|
||
/** | ||
* An experiment comprises {@link Measurement}s from one specific {@link Subject} execution. | ||
*/ | ||
public class Experiment { | ||
|
||
/** | ||
* Identifier for this instance. | ||
*/ | ||
private String id; | ||
|
||
/** | ||
* Description for this instance. (Optional) | ||
*/ | ||
private String description; | ||
|
||
/** | ||
* When this experiment has been started. | ||
*/ | ||
private long startTime; | ||
|
||
/** | ||
* Tags to group multiple Experiment instances. (Optional) | ||
*/ | ||
private Collection<String> tags; | ||
|
||
/** | ||
* {@link Measurement}s captured for this instance. | ||
*/ | ||
private Collection<Measurement> measurements; | ||
|
||
/** | ||
* The {@link Subject} being experimented with. | ||
*/ | ||
private Subject subject; | ||
|
||
/** | ||
* For deserialization. | ||
*/ | ||
private Experiment() { | ||
} | ||
|
||
/** | ||
* Create a new instance that is starting right now. | ||
* | ||
* @param id Identifier for the new instance | ||
* @param subject the {@link Subject} | ||
* @param tags tags to group several experiments | ||
*/ | ||
public Experiment(String id, Subject subject, String... tags) { | ||
this(id, subject, System.currentTimeMillis(), tags); | ||
} | ||
|
||
/** | ||
* Create a new instance. | ||
* | ||
* @param id Identifier for the new instance | ||
* @param subject the {@link Subject} of this experiment | ||
* @param startTime start timestamp of this experiment | ||
* @param tags tags to group several experiments | ||
*/ | ||
public Experiment(String id, Subject subject, long startTime, String... tags) { | ||
this.id = id; | ||
this.subject = subject; | ||
this.startTime = startTime; | ||
this.tags = Arrays.asList(tags); | ||
this.measurements = new LinkedList<>(); | ||
} | ||
|
||
/** | ||
* Adds a description for this instance. | ||
* | ||
* @param description the description | ||
* @return this instance | ||
*/ | ||
public Experiment withDescription(String description) { | ||
this.description = description; | ||
return this; | ||
} | ||
|
||
|
||
public String getId() { | ||
return id; | ||
} | ||
|
||
public void setId(String id) { | ||
this.id = id; | ||
} | ||
|
||
public String getDescription() { | ||
return description; | ||
} | ||
|
||
public void setDescription(String description) { | ||
this.description = description; | ||
} | ||
|
||
public long getStartTime() { | ||
return startTime; | ||
} | ||
|
||
public void setStartTime(long startTime) { | ||
this.startTime = startTime; | ||
} | ||
|
||
public Collection<String> getTags() { | ||
return tags; | ||
} | ||
|
||
public void setTags(Collection<String> tags) { | ||
this.tags = tags; | ||
} | ||
|
||
public void addMeasurement(Measurement measurement) { | ||
this.measurements.add(measurement); | ||
} | ||
|
||
public Collection<Measurement> getMeasurements() { | ||
return measurements; | ||
} | ||
|
||
public Subject getSubject() { | ||
return this.subject; | ||
} | ||
|
||
public void setSubject(Subject subject) { | ||
this.subject = subject; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Experiment that = (Experiment) o; | ||
return startTime == that.startTime && | ||
Objects.equals(id, that.id) && | ||
Objects.equals(description, that.description) && | ||
Objects.equals(tags, that.tags) && | ||
Objects.equals(subject, that.subject); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id, startTime); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.format( | ||
"%s[%s, %d tags, %d measurements]", | ||
this.getClass().getSimpleName(), | ||
this.id, | ||
this.tags.size(), | ||
this.measurements.size() | ||
); | ||
} | ||
} |
Oops, something went wrong.