From 2d789da44333849b2bb2a93fbf7ae22abbbcfb29 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Sat, 30 Nov 2019 11:04:23 +0100 Subject: [PATCH] Turn DatabaseSchema into an interface 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 --- .../ovsdb/lib/schema/DatabaseSchema.java | 110 ++------------- .../ovsdb/lib/schema/DatabaseSchemaImpl.java | 129 ++++++++++++++++++ .../lib/schema/typed/TyperUtilsTest.java | 10 +- 3 files changed, 143 insertions(+), 106 deletions(-) create mode 100644 library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchemaImpl.java diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchema.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchema.java index a80d653d0..f1335a310 100644 --- a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchema.java +++ b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchema.java @@ -5,121 +5,29 @@ * 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 tables; - - public DatabaseSchema(final String name, final Version version, final Map tables) { - this.name = requireNonNull(name); - this.version = requireNonNull(version); - this.tables = ImmutableMap.copyOf(tables); - } - - public Set getTables() { - return tables.keySet(); - } - - public boolean hasTable(final String table) { - return tables.containsKey(table); - } - - public > E table(final String tableName, final Class clazz) { - TableSchema table = tables.get(tableName); - - if (clazz.isInstance(table)) { - return clazz.cast(table); - } +public interface DatabaseSchema { + Set getTables(); - return createTableSchema(clazz, table); - } - - protected > E createTableSchema(final Class clazz, final TableSchema table) { - Constructor 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 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 table(String tableName, Class clazz); - Version dbVersion = Version.fromString(json.get("version").asText()); + String getName(); - Map tables = new HashMap<>(); - for (Iterator> iter = json.get("tables").fields(); iter.hasNext(); ) { - Map.Entry 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 index 000000000..8fea7e848 --- /dev/null +++ b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/schema/DatabaseSchemaImpl.java @@ -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 tables; + + public DatabaseSchemaImpl(final String name, final Version version, final Map 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 tables = new HashMap<>(); + for (Iterator> iter = json.get("tables").fields(); iter.hasNext(); ) { + Map.Entry 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 getTables() { + return tables.keySet(); + } + + @Override + public boolean hasTable(final String table) { + return tables.containsKey(table); + } + + @Override + public > E table(final String tableName, final Class clazz) { + TableSchema table = tables.get(tableName); + + if (clazz.isInstance(table)) { + return clazz.cast(table); + } + + return createTableSchema(clazz, table); + } + + protected > E createTableSchema(final Class clazz, final TableSchema table) { + Constructor 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 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; + } +} diff --git a/library/impl/src/test/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtilsTest.java b/library/impl/src/test/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtilsTest.java index 7d3e8a521..34e12a6cb 100644 --- a/library/impl/src/test/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtilsTest.java +++ b/library/impl/src/test/java/org/opendaylight/ovsdb/lib/schema/typed/TyperUtilsTest.java @@ -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); -- 2.36.6