2 * Copyright © 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.lib.schema.typed;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.cache.CacheBuilder;
13 import com.google.common.cache.CacheLoader;
14 import com.google.common.cache.LoadingCache;
15 import com.google.common.reflect.Reflection;
16 import java.util.HashMap;
18 import org.opendaylight.ovsdb.lib.message.TableUpdate;
19 import org.opendaylight.ovsdb.lib.message.TableUpdates;
20 import org.opendaylight.ovsdb.lib.notation.Row;
21 import org.opendaylight.ovsdb.lib.notation.UUID;
22 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
23 import org.opendaylight.ovsdb.lib.schema.ForwardingDatabaseSchema;
24 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
26 final class TypedDatabaseSchemaImpl extends ForwardingDatabaseSchema implements TypedDatabaseSchema {
27 private final LoadingCache<Class<?>, TypedRowInvocationHandler> handlers = CacheBuilder.newBuilder()
28 .weakKeys().weakValues().build(new CacheLoader<Class<?>, TypedRowInvocationHandler>() {
30 public TypedRowInvocationHandler load(final Class<?> key) {
31 return MethodDispatch.forTarget(key).bindToSchema(TypedDatabaseSchemaImpl.this);
35 private final DatabaseSchema delegate;
37 TypedDatabaseSchemaImpl(final DatabaseSchema delegate) {
38 this.delegate = requireNonNull(delegate);
42 protected DatabaseSchema delegate() {
47 public TypedDatabaseSchema withInternallyGeneratedColumns() {
48 final DatabaseSchema newDelegate = delegate.withInternallyGeneratedColumns();
49 return newDelegate == delegate ? this : new TypedDatabaseSchemaImpl(newDelegate);
53 public GenericTableSchema getTableSchema(final Class<?> klazz) {
54 return getTableSchema(TypedReflections.getTableName(klazz));
57 private GenericTableSchema getTableSchema(final String tableName) {
58 return table(tableName, GenericTableSchema.class);
62 public <T> T getTypedRowWrapper(final Class<T> klazz, final Row<GenericTableSchema> row) {
63 // Check validity of of the parameter passed to getTypedRowWrapper:
64 // - checks for a valid Database Schema matching the expected Database for a given table
65 // - checks for the presence of the Table in Database Schema.
66 final String dbName = TypedReflections.getTableDatabase(klazz);
67 if (dbName != null && !dbName.equalsIgnoreCase(getName())) {
70 TyperUtils.checkVersion(getVersion(), TypedReflections.getTableVersionRange(klazz));
72 TypedRowInvocationHandler handler = handlers.getUnchecked(klazz);
74 row.setTableSchema(getTableSchema(handler.getTableName()));
75 handler = handler.bindToRow(row);
77 return Reflection.newProxy(klazz, handler);
81 public <T> Map<UUID, T> extractRowsOld(final Class<T> klazz, final TableUpdates updates) {
82 Map<UUID,TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> rowUpdates = extractRowUpdates(
83 requireNonNull(klazz), requireNonNull(updates));
84 Map<UUID,T> result = new HashMap<>();
85 for (TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema> rowUpdate : rowUpdates.values()) {
86 if (rowUpdate != null && rowUpdate.getOld() != null) {
87 Row<GenericTableSchema> row = rowUpdate.getOld();
88 result.put(rowUpdate.getUuid(), getTypedRowWrapper(klazz, row));
95 public <T> Map<UUID, T> extractRowsUpdated(final Class<T> klazz, final TableUpdates updates) {
96 final Map<UUID,TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> rowUpdates =
97 extractRowUpdates(klazz, updates);
98 final Map<UUID,T> result = new HashMap<>();
99 for (TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema> rowUpdate : rowUpdates.values()) {
100 if (rowUpdate != null && rowUpdate.getNew() != null) {
101 Row<GenericTableSchema> row = rowUpdate.getNew();
102 result.put(rowUpdate.getUuid(), getTypedRowWrapper(klazz, row));
109 public <T> Map<UUID, T> extractRowsRemoved(final Class<T> klazz, final TableUpdates updates) {
110 final Map<UUID, TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> rowUpdates =
111 extractRowUpdates(klazz, updates);
112 final Map<UUID, T> result = new HashMap<>();
113 for (TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema> rowUpdate : rowUpdates.values()) {
114 if (rowUpdate != null && rowUpdate.getNew() == null && rowUpdate.getOld() != null) {
115 Row<GenericTableSchema> row = rowUpdate.getOld();
116 result.put(rowUpdate.getUuid(), getTypedRowWrapper(klazz, row));
123 * This method extracts all RowUpdates of Class<T> klazz from a TableUpdates that correspond to rows of type
126 * Map<UUID,TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> updatedBridges =
127 * extractRowsUpdates(Bridge.class,updates,dbSchema)
130 * @param klazz Class for row type to be extracted
131 * @param updates TableUpdates from which to extract rowUpdates
132 * @return Map<UUID,TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>>
133 * for the type of things being sought
135 private Map<UUID,TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> extractRowUpdates(
136 final Class<?> klazz, final TableUpdates updates) {
137 TableUpdate<GenericTableSchema> update = updates.getUpdate(table(TypedReflections.getTableName(klazz),
138 GenericTableSchema.class));
139 Map<UUID, TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> result = new HashMap<>();
140 if (update != null) {
141 Map<UUID, TableUpdate<GenericTableSchema>.RowUpdate<GenericTableSchema>> rows = update.getRows();