You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/12/17 17:27:55 UTC
[plc4x] 01/01: Introduced Complex Types
This is an automated email from the ASF dual-hosted git repository.
jfeinauer pushed a commit to branch feature/complex-types
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 271f9679bdaf06103a668648ae421435eb458b5c
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Tue Dec 17 18:26:56 2019 +0100
Introduced Complex Types
---
.../org/apache/plc4x/java/PlcDriverManager.java | 10 +-
.../java/org/apache/plc4x/java/api/Changed.java | 7 ++
.../org/apache/plc4x/java/api/PlcConnection.java | 1 +
.../PlcIncompatibleDatatypeException.java | 3 +
.../apache/plc4x/java/api/value/PlcBoolean.java | 44 ++++++++
.../apache/plc4x/java/api/value/PlcInteger.java | 47 ++++++++
.../org/apache/plc4x/java/api/value/PlcList.java | 37 +++++++
.../plc4x/java/api/value/PlcSimpleValue.java | 27 +++++
.../org/apache/plc4x/java/api/value/PlcString.java | 40 +++++++
.../org/apache/plc4x/java/api/value/PlcStruct.java | 37 +++++++
.../org/apache/plc4x/java/api/value/PlcValue.java | 83 +++++++++++++++
.../plc4x/java/api/value/PlcValueAdapter.java | 118 +++++++++++++++++++++
.../org/apache/plc4x/java/api/value/PlcValues.java | 45 ++++++++
.../apache/plc4x/java/api/types/PlcValueTest.java | 34 ++++++
14 files changed, 532 insertions(+), 1 deletion(-)
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/PlcDriverManager.java b/plc4j/api/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
index fb6b09a..95200ec 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/PlcDriverManager.java
@@ -18,6 +18,7 @@ under the License.
*/
package org.apache.plc4x.java;
+import org.apache.plc4x.java.api.Changed;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.authentication.PlcAuthentication;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
@@ -89,7 +90,14 @@ public class PlcDriverManager {
return connection;
}
- private PlcDriver getDriver(String url) throws PlcConnectionException {
+ /**
+ * Returns suitble driver for protocol or throws an Exception.
+ * @param url Uri to use
+ * @return Driver instance for the given protocol
+ * @throws PlcConnectionException If no Suitable Driver can be found
+ */
+ @Changed
+ public PlcDriver getDriver(String url) throws PlcConnectionException {
try {
URI connectionUri = new URI(url);
String protocol = connectionUri.getScheme();
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/Changed.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/Changed.java
new file mode 100644
index 0000000..98391b2
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/Changed.java
@@ -0,0 +1,7 @@
+package org.apache.plc4x.java.api;
+
+/**
+ * Indicates that this is a recent API Change.
+ */
+public @interface Changed {
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
index 3838594..5725529 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
@@ -62,6 +62,7 @@ public interface PlcConnection extends AutoCloseable {
*
* @throws PlcRuntimeException If the string cannot be parsed
*/
+ @Deprecated
default PlcField prepareField(String fieldQuery) throws PlcInvalidFieldException {
throw new PlcRuntimeException("Parse method is not implemented for this connection / driver");
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcIncompatibleDatatypeException.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcIncompatibleDatatypeException.java
index cb779df..4aeac24 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcIncompatibleDatatypeException.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcIncompatibleDatatypeException.java
@@ -25,4 +25,7 @@ public class PlcIncompatibleDatatypeException extends PlcRuntimeException {
super("Incompatible Datatype " + datatype.getName() + " at index " + index);
}
+ public PlcIncompatibleDatatypeException(String message) {
+ super(message);
+ }
}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcBoolean.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcBoolean.java
new file mode 100644
index 0000000..1c0cc0c
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcBoolean.java
@@ -0,0 +1,44 @@
+package org.apache.plc4x.java.api.value;
+
+public class PlcBoolean extends PlcSimpleValue<Boolean> {
+
+ public PlcBoolean(Boolean value) {
+ super(value, true);
+ }
+
+ public PlcBoolean(boolean bool) {
+ super(bool, false);
+ }
+
+ @Override public boolean isBoolean() {
+ return true;
+ }
+
+ @Override public boolean getBoolean() {
+ return value;
+ }
+
+ @Override public double getDouble() {
+ return value ? 1.0 : 0.0;
+ }
+
+ @Override public float getFloat() {
+ return value ? 1.0f : 0.0f;
+ }
+
+ @Override public long getLong() {
+ return value ? 1 : 0;
+ }
+
+ @Override public int getInteger() {
+ return value ? 1 : 0;
+ }
+
+ @Override public String getString() {
+ return value ? "true" : "false";
+ }
+
+ @Override public String toString() {
+ return Boolean.toString(value);
+ }
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcInteger.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcInteger.java
new file mode 100644
index 0000000..8b7e03c
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcInteger.java
@@ -0,0 +1,47 @@
+package org.apache.plc4x.java.api.value;
+
+import org.apache.plc4x.java.api.value.PlcSimpleValue;
+
+public class PlcInteger extends PlcSimpleValue<Integer> {
+
+ public PlcInteger(Integer value) {
+ super(value, true);
+ }
+
+ public PlcInteger(int value) {
+ super(value, false);
+ }
+
+ @Override public boolean isString() {
+ return true;
+ }
+
+ @Override public String getString() {
+ return value.toString();
+ }
+
+ @Override public boolean getBoolean() {
+ // We like C
+ return !(value == 0);
+ }
+
+ @Override public double getDouble() {
+ return (double)value;
+ }
+
+ @Override public float getFloat() {
+ return (float)value;
+ }
+
+ @Override public long getLong() {
+ return value;
+ }
+
+ @Override public int getInteger() {
+ return value;
+ }
+
+ @Override public String toString() {
+ return String.valueOf(value);
+ }
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcList.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcList.java
new file mode 100644
index 0000000..e307d61
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcList.java
@@ -0,0 +1,37 @@
+package org.apache.plc4x.java.api.value;
+
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.apache.plc4x.java.api.value.PlcValueAdapter;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PlcList extends PlcValueAdapter {
+
+ private final List<PlcValue> listItems;
+
+ public PlcList(List<PlcValue> listItems) {
+ this.listItems = Collections.unmodifiableList(listItems);
+ }
+
+ @Override public boolean isList() {
+ return true;
+ }
+
+ @Override public int length() {
+ return listItems.size();
+ }
+
+ @Override public PlcValue getIndex(int i) {
+ return listItems.get(i);
+ }
+
+ @Override public List<? extends PlcValue> getList() {
+ return listItems;
+ }
+
+ @Override public String toString() {
+ return "[" + listItems.stream().map(PlcValue::toString).collect(Collectors.joining(",")) + "]";
+ }
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcSimpleValue.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcSimpleValue.java
new file mode 100644
index 0000000..37e4ef7
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcSimpleValue.java
@@ -0,0 +1,27 @@
+package org.apache.plc4x.java.api.value;
+
+import org.apache.plc4x.java.api.value.PlcValueAdapter;
+
+public abstract class PlcSimpleValue<T> extends PlcValueAdapter {
+
+ protected final T value;
+ protected final boolean isNullable;
+
+ public PlcSimpleValue(T value, boolean isNullable) {
+ this.value = value;
+ this.isNullable = isNullable;
+ }
+
+ @Override public boolean isSimple() {
+ return true;
+ }
+
+ @Override public boolean isNullable() {
+ return isNullable;
+ }
+
+ @Override public boolean isNull() {
+ return isNullable && value == null;
+ }
+
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcString.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcString.java
new file mode 100644
index 0000000..ea12bb4
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcString.java
@@ -0,0 +1,40 @@
+package org.apache.plc4x.java.api.value;
+
+public class PlcString extends PlcSimpleValue<String> {
+
+ public PlcString(String value) {
+ super(value, true);
+ }
+
+ @Override public boolean isString() {
+ return true;
+ }
+
+ @Override public String getString() {
+ return value;
+ }
+
+ @Override public boolean getBoolean() {
+ return Boolean.parseBoolean(value);
+ }
+
+ @Override public double getDouble() {
+ return Double.parseDouble(value);
+ }
+
+ @Override public float getFloat() {
+ return Float.parseFloat(value);
+ }
+
+ @Override public long getLong() {
+ return Long.parseLong(value);
+ }
+
+ @Override public int getInteger() {
+ return Integer.parseInt(value);
+ }
+
+ @Override public String toString() {
+ return "\"" + value + "\"";
+ }
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcStruct.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcStruct.java
new file mode 100644
index 0000000..72df9b0
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcStruct.java
@@ -0,0 +1,37 @@
+package org.apache.plc4x.java.api.value;
+
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.apache.plc4x.java.api.value.PlcValueAdapter;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class PlcStruct extends PlcValueAdapter {
+
+ private final Map<String, PlcValue> map;
+
+ public PlcStruct(Map<String, PlcValue> map) {
+ this.map = Collections.unmodifiableMap(map);
+ }
+
+ @Override public boolean isStruct() {
+ return true;
+ }
+
+ @Override public boolean hasKey(String key) {
+ return map.containsKey(key);
+ }
+
+ @Override public PlcValue getValue(String key) {
+ return map.get(key);
+ }
+
+ @Override public Map<String, ? extends PlcValue> getStruct() {
+ return map;
+ }
+
+ @Override public String toString() {
+ return "{" + map.entrySet().stream().map(entry -> String.format("\"%s\": %s", entry.getKey(), entry.getValue())).collect(Collectors.joining(",")) + "}";
+ }
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValue.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValue.java
new file mode 100644
index 0000000..7b5cedf
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValue.java
@@ -0,0 +1,83 @@
+package org.apache.plc4x.java.api.value;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base Type of all Types.
+ */
+public interface PlcValue {
+
+ // Simple Types
+
+ boolean isSimple();
+
+ boolean isNullable();
+
+ boolean isNull();
+
+ // Generic (\o/ Sebastian)
+
+ boolean is(Class<?> clazz);
+
+ boolean isConvertibleTo(Class<?> clazz);
+
+ <T> T get(Class<T> clazz);
+
+ // Boolean
+
+ boolean isBoolean();
+
+ boolean getBoolean();
+
+ // Integer
+
+ boolean isLong();
+
+ long getLong();
+
+ boolean isInteger();
+
+ int getInteger();
+
+ // Floating Point
+
+ boolean isDouble();
+
+ double getDouble();
+
+ boolean isFloat();
+
+ float getFloat();
+
+ // String
+
+ boolean isString();
+
+ String getString();
+
+ // Raw Access
+
+ byte[] getRaw();
+
+ // List Methods
+
+ boolean isList();
+
+ int length();
+
+ PlcValue getIndex(int i);
+
+ List<? extends PlcValue> getList();
+
+ // Struct Methods
+
+ boolean isStruct();
+
+ boolean hasKey(String key);
+
+ PlcValue getValue(String key);
+
+ Map<String, ? extends PlcValue> getStruct();
+
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueAdapter.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueAdapter.java
new file mode 100644
index 0000000..d8d9032
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValueAdapter.java
@@ -0,0 +1,118 @@
+package org.apache.plc4x.java.api.value;
+
+import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException;
+
+import java.util.List;
+import java.util.Map;
+
+public class PlcValueAdapter implements PlcValue {
+
+ @Override public boolean isSimple() {
+ return false;
+ }
+
+ @Override public boolean isNullable() {
+ return false;
+ }
+
+ @Override public boolean isNull() {
+ return false;
+ }
+
+ @Override public boolean is(Class<?> clazz) {
+ return false;
+ }
+
+ @Override public boolean isConvertibleTo(Class<?> clazz) {
+ return false;
+ }
+
+ @Override public <T> T get(Class<T> clazz) {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isBoolean() {
+ return false;
+ }
+
+ @Override public boolean getBoolean() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isDouble() {
+ return false;
+ }
+
+ @Override public double getDouble() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isFloat() {
+ return false;
+ }
+
+ @Override public float getFloat() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isLong() {
+ return false;
+ }
+
+ @Override public long getLong() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isInteger() {
+ return false;
+ }
+
+ @Override public int getInteger() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isString() {
+ return false;
+ }
+
+ @Override public String getString() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public byte[] getRaw() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isList() {
+ return false;
+ }
+
+ @Override public int length() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public PlcValue getIndex(int i) {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public List<? extends PlcValue> getList() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public boolean isStruct() {
+ return false;
+ }
+
+ @Override public boolean hasKey(String key) {
+ return false;
+ }
+
+ @Override public PlcValue getValue(String key) {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+ @Override public Map<String, ? extends PlcValue> getStruct() {
+ throw new PlcIncompatibleDatatypeException("");
+ }
+
+}
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValues.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValues.java
new file mode 100644
index 0000000..eb884ce
--- /dev/null
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/value/PlcValues.java
@@ -0,0 +1,45 @@
+package org.apache.plc4x.java.api.value;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class PlcValues {
+
+ public static PlcValue of(String s) {
+ return new PlcString(s);
+ }
+
+ public static PlcValue of(Integer i) {
+ return new PlcInteger(i);
+ }
+
+ public static PlcValue of(int i) {
+ return new PlcInteger(i);
+ }
+
+ public static PlcValue of(Boolean b) {
+ return new PlcBoolean(b);
+ }
+
+ public static PlcValue of(boolean b) {
+ return new PlcBoolean(b);
+ }
+
+ public static PlcValue of(List<PlcValue> list) {
+ return new PlcList(list);
+ }
+
+ public static PlcValue of(PlcValue... items) {
+ return new PlcList(Arrays.asList(items));
+ }
+
+ public static PlcValue of(String key, PlcValue value) {
+ return new PlcStruct(Collections.singletonMap(key, value));
+ }
+
+ public static PlcValue of(Map<String, PlcValue> map) {
+ return new PlcStruct(map);
+ }
+}
diff --git a/plc4j/api/src/test/java/org/apache/plc4x/java/api/types/PlcValueTest.java b/plc4j/api/src/test/java/org/apache/plc4x/java/api/types/PlcValueTest.java
new file mode 100644
index 0000000..334b1f0
--- /dev/null
+++ b/plc4j/api/src/test/java/org/apache/plc4x/java/api/types/PlcValueTest.java
@@ -0,0 +1,34 @@
+package org.apache.plc4x.java.api.types;
+
+import org.apache.plc4x.java.api.exceptions.PlcIncompatibleDatatypeException;
+import org.apache.plc4x.java.api.value.PlcValue;
+import org.apache.plc4x.java.api.value.PlcValues;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class PlcValueTest {
+
+ @Nested
+ class Complex {
+
+ @Test
+ void complexTestCase_isComplex() {
+ PlcValue value = PlcValues.of("Entry 1", PlcValues.of(
+ PlcValues.of(true),
+ PlcValues.of("Pimmel"),
+ PlcValues.of(false),
+ PlcValues.of("Arsch"),
+ PlcValues.of(1278391)
+ ));
+
+ System.out.println(value);
+
+ assertThrows(PlcIncompatibleDatatypeException.class, value::getBoolean);
+ assertTrue(value.getValue("Entry 1").getIndex(0).getBoolean());
+ }
+ }
+
+}
\ No newline at end of file