Turn DatabaseSchema into an interface 09/86209/2
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 30 Nov 2019 10:04:23 +0000 (11:04 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 5 Dec 2019 12:45:59 +0000 (13:45 +0100)
This moves all the implementation details out into a separate class,
allowing DatabaseSchema interface to be extended with additional
functionality.

Change-Id: Ib7a0124993cb89bb448b3c08bda6c6de0fea1dde
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 2d789da44333849b2bb2a93fbf7ae22abbbcfb29)

library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchema.java
library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchemaImpl.java [new file with mode: 0644]
library/impl/src/test/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtilsTest.java

index a80d653d0962eaa8dc942c2c7721ae43dec587cd..f1335a31018238f300ff98e69f01e522c040bbbc 100644 (file)
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.ovsdb.lib.schema;
 
-import static java.util.Objects.requireNonNull;
-
 import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.reflect.Invokable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
-import org.opendaylight.ovsdb.lib.error.ParsingException;
 import org.opendaylight.ovsdb.lib.notation.Version;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Represents an ovsdb database schema, which is comprised of a set of tables.
  */
-public class DatabaseSchema {
-    private static final Logger LOG = LoggerFactory.getLogger(DatabaseSchema.class);
-
-    private final String name;
-    private final Version version;
-    private final ImmutableMap<String, TableSchema> tables;
-
-    public DatabaseSchema(final String name, final Version version, final Map<String, TableSchema> tables) {
-        this.name = requireNonNull(name);
-        this.version = requireNonNull(version);
-        this.tables = ImmutableMap.copyOf(tables);
-    }
-
-    public Set<String> getTables() {
-        return tables.keySet();
-    }
-
-    public boolean hasTable(final String table) {
-        return tables.containsKey(table);
-    }
-
-    public <E extends TableSchema<E>> E table(final String tableName, final Class<E> clazz) {
-        TableSchema<E> table = tables.get(tableName);
-
-        if (clazz.isInstance(table)) {
-            return clazz.cast(table);
-        }
+public interface DatabaseSchema {
+    Set<String> getTables();
 
-        return createTableSchema(clazz, table);
-    }
-
-    protected <E extends TableSchema<E>> E createTableSchema(final Class<E> clazz, final TableSchema<E> table) {
-        Constructor<E> declaredConstructor;
-        try {
-            declaredConstructor = clazz.getDeclaredConstructor(TableSchema.class);
-        } catch (NoSuchMethodException e) {
-            String message = String.format("Class %s does not have public constructor that accepts TableSchema object",
-                    clazz);
-            throw new IllegalArgumentException(message, e);
-        }
-        Invokable<E, E> invokable = Invokable.from(declaredConstructor);
-        try {
-            return invokable.invoke(null, table);
-        } catch (InvocationTargetException | IllegalAccessException e) {
-            String message = String.format("Not able to create instance of class %s using public constructor "
-                    + "that accepts TableSchema object", clazz);
-            throw new IllegalArgumentException(message, e);
-        }
-    }
+    boolean hasTable(String table);
 
-    //todo : this needs to move to a custom factory
-    public static DatabaseSchema fromJson(final String dbName, final JsonNode json) {
-        if (!json.isObject() || !json.has("tables")) {
-            throw new ParsingException("bad DatabaseSchema root, expected \"tables\" as child but was not found");
-        }
-        if (!json.isObject() || !json.has("version")) {
-            throw new ParsingException("bad DatabaseSchema root, expected \"version\" as child but was not found");
-        }
+    <E extends TableSchema<E>> E table(String tableName, Class<E> clazz);
 
-        Version dbVersion = Version.fromString(json.get("version").asText());
+    String getName();
 
-        Map<String, TableSchema> tables = new HashMap<>();
-        for (Iterator<Map.Entry<String, JsonNode>> iter = json.get("tables").fields(); iter.hasNext(); ) {
-            Map.Entry<String, JsonNode> table = iter.next();
-            LOG.trace("Read schema for table[{}]:{}", table.getKey(), table.getValue());
-
-            //todo : this needs to done by a factory
-            tables.put(table.getKey(), GenericTableSchema.fromJson(table.getKey(), table.getValue()));
-        }
-
-        return new DatabaseSchema(dbName, dbVersion, tables);
-    }
+    Version getVersion();
 
-    public String getName() {
-        return name;
-    }
-
-    public Version getVersion() {
-        return version;
-    }
-
-    public DatabaseSchema withInternallyGeneratedColumns() {
-        return haveInternallyGeneratedColumns() ? this : new DatabaseSchema(name, version,
-            Maps.transformValues(tables, TableSchema::withInternallyGeneratedColumns));
-    }
+    DatabaseSchema withInternallyGeneratedColumns();
 
-    protected final boolean haveInternallyGeneratedColumns() {
-        for (TableSchema tableSchema : tables.values()) {
-            if (!tableSchema.haveInternallyGeneratedColumns()) {
-                return false;
-            }
-        }
-        return true;
+    static DatabaseSchema fromJson(final String dbName, final JsonNode json) {
+        return DatabaseSchemaImpl.fromJson(dbName, json);
     }
 }
diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchemaImpl.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchemaImpl.java
new file mode 100644 (file)
index 0000000..8fea7e8
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2014, 2015 EBay Software Foundation and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.lib.schema;
+
+import static java.util.Objects.requireNonNull;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.reflect.Invokable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.ovsdb.lib.error.ParsingException;
+import org.opendaylight.ovsdb.lib.notation.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@VisibleForTesting
+public class DatabaseSchemaImpl implements DatabaseSchema {
+    private static final Logger LOG = LoggerFactory.getLogger(DatabaseSchemaImpl.class);
+
+    private final String name;
+    private final Version version;
+    private final ImmutableMap<String, TableSchema> tables;
+
+    public DatabaseSchemaImpl(final String name, final Version version, final Map<String, TableSchema> tables) {
+        this.name = requireNonNull(name);
+        this.version = requireNonNull(version);
+        this.tables = ImmutableMap.copyOf(tables);
+    }
+
+    //todo : this needs to move to a custom factory
+    public static DatabaseSchema fromJson(final String dbName, final JsonNode json) {
+        if (!json.isObject() || !json.has("tables")) {
+            throw new ParsingException("bad DatabaseSchema root, expected \"tables\" as child but was not found");
+        }
+        if (!json.isObject() || !json.has("version")) {
+            throw new ParsingException("bad DatabaseSchema root, expected \"version\" as child but was not found");
+        }
+
+        Version dbVersion = Version.fromString(json.get("version").asText());
+
+        Map<String, TableSchema> tables = new HashMap<>();
+        for (Iterator<Map.Entry<String, JsonNode>> iter = json.get("tables").fields(); iter.hasNext(); ) {
+            Map.Entry<String, JsonNode> table = iter.next();
+            LOG.trace("Read schema for table[{}]:{}", table.getKey(), table.getValue());
+
+            //todo : this needs to done by a factory
+            tables.put(table.getKey(), GenericTableSchema.fromJson(table.getKey(), table.getValue()));
+        }
+
+        return new DatabaseSchemaImpl(dbName, dbVersion, tables);
+    }
+
+    @Override
+    public Set<String> getTables() {
+        return tables.keySet();
+    }
+
+    @Override
+    public boolean hasTable(final String table) {
+        return tables.containsKey(table);
+    }
+
+    @Override
+    public <E extends TableSchema<E>> E table(final String tableName, final Class<E> clazz) {
+        TableSchema<E> table = tables.get(tableName);
+
+        if (clazz.isInstance(table)) {
+            return clazz.cast(table);
+        }
+
+        return createTableSchema(clazz, table);
+    }
+
+    protected <E extends TableSchema<E>> E createTableSchema(final Class<E> clazz, final TableSchema<E> table) {
+        Constructor<E> declaredConstructor;
+        try {
+            declaredConstructor = clazz.getDeclaredConstructor(TableSchema.class);
+        } catch (NoSuchMethodException e) {
+            String message = String.format("Class %s does not have public constructor that accepts TableSchema object",
+                    clazz);
+            throw new IllegalArgumentException(message, e);
+        }
+        Invokable<E, E> invokable = Invokable.from(declaredConstructor);
+        try {
+            return invokable.invoke(null, table);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            String message = String.format("Not able to create instance of class %s using public constructor "
+                    + "that accepts TableSchema object", clazz);
+            throw new IllegalArgumentException(message, e);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Version getVersion() {
+        return version;
+    }
+
+    @Override
+    public DatabaseSchema withInternallyGeneratedColumns() {
+        return haveInternallyGeneratedColumns() ? this : new DatabaseSchemaImpl(name, version,
+            Maps.transformValues(tables, TableSchema::withInternallyGeneratedColumns));
+    }
+
+    protected final boolean haveInternallyGeneratedColumns() {
+        for (TableSchema tableSchema : tables.values()) {
+            if (!tableSchema.haveInternallyGeneratedColumns()) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
index 7d3e8a521fb7229d8c04932b96c0c6d2af93a91b..34e12a6cbfb00870018ddcb53061dd3acd3d9f35 100644 (file)
@@ -5,7 +5,6 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.ovsdb.lib.schema.typed;
 
 import static org.junit.Assert.assertEquals;
@@ -19,6 +18,7 @@ import org.junit.Test;
 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
 import org.opendaylight.ovsdb.lib.notation.Version;
 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
+import org.opendaylight.ovsdb.lib.schema.DatabaseSchemaImpl;
 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,7 +46,7 @@ public class TyperUtilsTest {
     public void testGetTableSchemaWithIncludedTypedTable() {
         // Given ...
         GenericTableSchema testTableSchema = new GenericTableSchema("TestTypedTable");
-        DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL,
+        DatabaseSchema dbSchema = new DatabaseSchemaImpl("testDb", Version.NULL,
             ImmutableMap.of(testTableSchema.getName(), testTableSchema));
 
         // When ...
@@ -64,7 +64,7 @@ public class TyperUtilsTest {
     public void testGetTableSchemaWithIncludedUntypedTable() {
         // Given ...
         GenericTableSchema testTableSchema = new GenericTableSchema("TestUntypedTable");
-        DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL,
+        DatabaseSchema dbSchema = new DatabaseSchemaImpl("testDb", Version.NULL,
             ImmutableMap.of(testTableSchema.getName(), testTableSchema));
 
         // When ...
@@ -81,7 +81,7 @@ public class TyperUtilsTest {
     @Test(expected = IllegalArgumentException.class)
     public void testGetTableSchemaWithoutIncludedTypedTable() {
         // Given ...
-        DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL, Collections.emptyMap());
+        DatabaseSchema dbSchema = new DatabaseSchemaImpl("testDb", Version.NULL, Collections.emptyMap());
 
         // When ...
         TyperUtils.getTableSchema(dbSchema, TestTypedTable.class);
@@ -94,7 +94,7 @@ public class TyperUtilsTest {
     @Test(expected = IllegalArgumentException.class)
     public void testGetTableSchemaWithoutIncludedUntypedTable() {
         // Given ...
-        DatabaseSchema dbSchema = new DatabaseSchema("testDb", Version.NULL, Collections.emptyMap());
+        DatabaseSchema dbSchema = new DatabaseSchemaImpl("testDb", Version.NULL, Collections.emptyMap());
 
         // When ...
         TyperUtils.getTableSchema(dbSchema, TestUntypedTable.class);