Adds examples for using the the low level VAB providers
Change-Id: If929e78498c7e046fe1be8855fb484b45d3680bf
Signed-off-by: Daniel Espen <daniel.espen@iese.fraunhofer.de>
diff --git a/examples/basys.examples/.gitignore b/examples/basys.examples/.gitignore
index 159bc9d..02eeb17 100644
--- a/examples/basys.examples/.gitignore
+++ b/examples/basys.examples/.gitignore
@@ -1,7 +1,7 @@
.classpath
.project
-
+regressiontest/
target/
pom.xml.tag
pom.xml.releaseBackup
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
new file mode 100644
index 0000000..db1b74a
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/FileSystemProviderClass.java
@@ -0,0 +1,64 @@
+package org.eclipse.basyx.examples.snippets.vab.provider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+
+import org.eclipse.basyx.aas.backend.http.tools.GSONTools;
+import org.eclipse.basyx.aas.backend.http.tools.factory.DefaultTypeFactory;
+import org.eclipse.basyx.vab.core.IModelProvider;
+import org.eclipse.basyx.vab.provider.filesystem.FileSystemProvider;
+import org.eclipse.basyx.vab.provider.filesystem.filesystem.FileSystem;
+import org.eclipse.basyx.vab.provider.filesystem.filesystem.impl.GenericFileSystem;
+import org.junit.Test;
+
+/**
+ * Code snippet showing the use of the VABFileSystemProvider. It can be used as a basic low level model provider for
+ * arbitrary models based on HashMaps and a FileSystem. The provider encapsulates the actual data and implements the
+ * abstract interface IModelProvider so that the contained model can be accessed via the five VAB primitives create,
+ * retrieve, update, delete and invoke. The implementation abstracts the underlying file system, so it is possible to
+ * provide different implementations.
+ *
+ * @author espen
+ *
+ */
+public class FileSystemProviderClass {
+ private final GSONTools gsonTools = new GSONTools(new DefaultTypeFactory());
+
+ /**
+ * Snippet showing the programmatic approach for creating arbitrary local, static models using the FileSystem
+ * provider
+ */
+ @Test
+ public void snippet() throws Exception {
+ // Create a HashMap as the root for the data structure
+ HashMap<String, Object> rootElement = new HashMap<>();
+
+ // Additional properties can be directly added to the HashMap at this point
+ rootElement.put("myInteger", 3);
+
+ // Create a generic file system and specify the storage location
+ // This exemplary file system is based on local files, but implementations are possible here
+ FileSystem fs = new GenericFileSystem();
+ String basePath = "regressiontest/HMDR/Test";
+
+ // The provider then encapsulates the data and realizes the abstract IModelProvider interface
+ // When initializing the provider, it is possible to optionally clear the provided directory
+ IModelProvider provider = new FileSystemProvider(fs, basePath, rootElement, true);
+
+ // The interface is equal to the interface used in e.g. the HashMapProvider
+ int previouslyCreated = (Integer) provider.getModelPropertyValue("/myInteger");
+ assertEquals(3, previouslyCreated);
+
+ // When creating elements, the internal directory and file structure represent the changes
+ provider.createValue("/name", "Max Mustermann");
+
+ // Properties are serialized and stored in the file that corresponds to their path
+ String expected = "Max Mustermann";
+ String byProvider = (String) provider.getModelPropertyValue("/name");
+ String byFileSystem = fs.readFile(basePath + "/name");
+ String byFSDeserialized = (String) gsonTools.deserialize(byFileSystem);
+ assertEquals(expected, byProvider);
+ assertEquals(expected, byFSDeserialized);
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABHashMapProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABHashMapProviderClass.java
new file mode 100644
index 0000000..91e1014
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABHashMapProviderClass.java
@@ -0,0 +1,69 @@
+package org.eclipse.basyx.examples.snippets.vab.provider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.function.Function;
+
+import org.eclipse.basyx.vab.core.IModelProvider;
+import org.eclipse.basyx.vab.provider.hashmap.VABHashmapProvider;
+import org.junit.Test;
+
+/**
+ * Code snippet showing the use of the VABHashMapProvider. It can be used as a basic low level model provider for
+ * arbitrary models based on HashMaps. The provider encapsulates the actual data and implements the abstract interface
+ * IModelProvider so that the contained model can be accessed via the five VAB primitives create, retrieve, update,
+ * delete and invoke.
+ *
+ * @author espen
+ *
+ */
+public class VABHashMapProviderClass {
+
+ /**
+ * Snippet showing the programmatic approach for creating arbitrary local, static models using HashMaps
+ */
+ @Test
+ public void snippet() throws Exception {
+ // Create a HashMap as the root for the data structure
+ HashMap<String, Object> rootElement = new HashMap<>();
+
+ // Add a simple string element
+ rootElement.put("name", "myElement");
+
+ // Create a function and then add it as another element to the root
+ Function<Object[], Object> myFunction = (param) -> {
+ return (int) param[0] + (int) param[1];
+ };
+ rootElement.put("operation", myFunction);
+
+ // Hierarchical structures are possible by nesting multiple HashMaps
+ // => Create a new HashMap with two elements and add it as a child to the root Map
+ HashMap<String, Object> childMap = new HashMap<>();
+ childMap.put("type", "boolean");
+ childMap.put("value", true);
+ rootElement.put("data", childMap);
+
+ // The provider then encapsulates the data and realizes the abstract IModelProvider interface
+ IModelProvider provider = new VABHashmapProvider(rootElement);
+
+ // Child elements can now be accessed with a path that is mapped to actual data structure
+ assertEquals("myElement", provider.getModelPropertyValue("/name"));
+ assertEquals("boolean", provider.getModelPropertyValue("/data/type"));
+ assertEquals(true, provider.getModelPropertyValue("/data/value"));
+
+ // Future modifications are now applied using the IModelProvider interface.
+ provider.setModelPropertyValue("/name", "yourElement");
+ assertEquals("yourElement", provider.getModelPropertyValue("/name"));
+
+ // The creation of nested elements within an existing provider is also possible
+ // HashMaps and Collections are supported for this purpose
+ HashMap<String, Object> description = new HashMap<>();
+ description.put("DE", "Dies ist ein generisches Element für den VAB");
+ description.put("EN", "This is a generic VAB element");
+ provider.createValue("/description", description);
+
+ // The path is again mapped to the HashMap structure
+ assertEquals("This is a generic VAB element", provider.getModelPropertyValue("/description/EN"));
+ }
+}
diff --git a/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
new file mode 100644
index 0000000..6f057f9
--- /dev/null
+++ b/examples/basys.examples/src/test/java/org/eclipse/basyx/examples/snippets/vab/provider/VABLambdaProviderClass.java
@@ -0,0 +1,66 @@
+package org.eclipse.basyx.examples.snippets.vab.provider;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.basyx.vab.core.IModelProvider;
+import org.eclipse.basyx.vab.provider.lambda.VABLambdaProvider;
+import org.eclipse.basyx.vab.provider.lambda.VABLambdaProviderHelper;
+import org.junit.Test;
+
+/**
+ * Code snippet showing the use of the VABLambdaProvider. It can be used as a basic low level model provider for
+ * arbitrary models based on HashMaps. The provider encapsulates the actual data and implements the abstract interface
+ * IModelProvider so that the contained model can be accessed via the five VAB primitives create, retrieve, update,
+ * delete and invoke. In addition to the VABHashMapProvider, the VABLambdaProvider can proxy calls to properties and
+ * operations to user-defined functions to enable dynamic properties.
+ *
+ * @author espen
+ *
+ */
+public class VABLambdaProviderClass {
+ private String dynamicString = "myDynamicString";
+
+ /**
+ * Snippet showing the programmatic approach for creating arbitrary local, static models using HashMaps
+ */
+ @Test
+ public void snippet() throws Exception {
+ // Create a HashMap as the root for the data structure
+ HashMap<String, Object> rootElement = new HashMap<>();
+
+ // Create and add a dynamic string property by providing the necessary get and set operations.
+ Map<String, Object> dynamicPropertyVal = VABLambdaProviderHelper.createSimple(() -> {
+ // A user defined get-operation is provided here
+ return dynamicString;
+ }, (Object newValue) -> {
+ // A user defined set-operation is provided here
+ if (newValue instanceof String) {
+ dynamicString = ((String) newValue);
+ }
+ });
+ rootElement.put("dynamic", dynamicPropertyVal);
+
+ // Since the VABLambdaProvider is also a HashMapProvider, static properties can be added as well
+ rootElement.put("static", "myStaticString");
+
+ // The provider encapsulates the data and realizes the abstract IModelProvider interface
+ IModelProvider provider = new VABLambdaProvider(rootElement);
+
+ // Static and dynamic properties are resolved to their primitive object value
+ assertEquals("myStaticString", provider.getModelPropertyValue("/static"));
+ assertEquals("myDynamicString", provider.getModelPropertyValue("/dynamic"));
+
+ // Now each time the dynamic property is read, it resolves its value through the given get operation
+ // - modify the source of the dynamic property
+ dynamicString = "newValue";
+ // - resolve the property
+ assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+
+ // The custom setter of the dynamic property in this example only allows string types...
+ provider.setModelPropertyValue("/dynamic", true);
+ assertEquals("newValue", provider.getModelPropertyValue("/dynamic"));
+ }
+}