3162130ac69e442512e73a6538b3fc8f22fa543b
[ovsdb.git] / library / impl / src / main / java / org / opendaylight / ovsdb / lib / schema / typed / TyperUtils.java
1 /*
2  * Copyright © 2014, 2017 Red Hat, Inc. and others. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.ovsdb.lib.schema.typed;
9
10 import com.google.common.cache.CacheBuilder;
11 import com.google.common.cache.CacheLoader;
12 import com.google.common.cache.LoadingCache;
13 import com.google.common.collect.Range;
14 import java.util.Map;
15 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
16 import org.opendaylight.ovsdb.lib.message.TableUpdates;
17 import org.opendaylight.ovsdb.lib.notation.Row;
18 import org.opendaylight.ovsdb.lib.notation.UUID;
19 import org.opendaylight.ovsdb.lib.notation.Version;
20 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
21 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
22 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
23
24 /**
25  * Utility methods for typed OVSDB schema data.
26  */
27 public final class TyperUtils {
28     private static final LoadingCache<DatabaseSchema, TypedDatabaseSchema> TYPED_CACHE = CacheBuilder.newBuilder()
29             .weakKeys().weakValues().build(new CacheLoader<DatabaseSchema, TypedDatabaseSchema>() {
30                 @Override
31                 public TypedDatabaseSchema load(final DatabaseSchema key) {
32                     return new TypedDatabaseSchemaImpl(key);
33                 }
34             });
35
36     private TyperUtils() {
37         // Prevent instantiating a utility class
38     }
39
40     /**
41      * Retrieve the table schema for the given table in the given database schema.
42      *
43      * @param dbSchema The database schema.
44      * @param klazz The class whose table schema should be retrieved. Classes are matched in the database schema either
45      *     using their {@link TypedTable} annotation, if they have one, or by name.
46      * @return the table schema.
47      */
48     public static GenericTableSchema getTableSchema(final DatabaseSchema dbSchema, final Class<?> klazz) {
49         return dbSchema.table(TypedReflections.getTableName(klazz), GenericTableSchema.class);
50     }
51
52     static ColumnSchema<GenericTableSchema, Object> getColumnSchema(final GenericTableSchema tableSchema,
53             final String columnName, final Class<Object> metaClass) {
54         return tableSchema.column(columnName, metaClass);
55     }
56
57     static void checkVersion(final Version schemaVersion, final Range<Version> range) {
58         if (!range.contains(schemaVersion)) {
59             throw new SchemaVersionMismatchException(schemaVersion,
60                 range.hasLowerBound() ? range.lowerEndpoint() : Version.NULL,
61                         range.hasUpperBound() ? range.upperEndpoint() : Version.NULL);
62         }
63     }
64
65     /**
66      * Returns a Typed Proxy implementation for the klazz passed as a parameter.
67      * Per design choice, the Typed Proxy implementation is just a Wrapper on top of the actual
68      * Row which is untyped.
69      *
70      * <p>Being just a wrapper, it is state-less and more of a convenience functionality to
71      * provide a type-safe infrastructure for the applications to built on top of.
72      * And this Typed infra is completely optional.
73      *
74      * <p>It is the applications responsibility to pass on the raw Row parameter and this method will
75      * return the appropriate Proxy wrapper for the passed klazz Type.
76      * The raw Row parameter may be null if the caller is interested in just the ColumnSchema.
77      * But that is not a very common use-case.
78      *
79      * @param dbSchema DatabaseSchema as learnt from a OVSDB connection
80      * @param klazz Typed Class that represents a Table
81      */
82     public static <T> T getTypedRowWrapper(final DatabaseSchema dbSchema, final Class<T> klazz) {
83         return getTypedRowWrapper(dbSchema, klazz, new Row<>());
84     }
85
86     /**
87      * Returns a Typed Proxy implementation for the klazz passed as a parameter.
88      * Per design choice, the Typed Proxy implementation is just a Wrapper on top of the actual
89      * Row which is untyped.
90      *
91      * <p>Being just a wrapper, it is state-less and more of a convenience functionality
92      * to provide a type-safe infrastructure for the applications to built on top of.
93      * And this Typed infra is completely optional.
94      *
95      * <p>It is the applications responsibility to pass on the raw Row parameter and this method
96      * will return the appropriate Proxy wrapper for the passed klazz Type.
97      * The raw Row parameter may be null if the caller is interested in just the
98      * ColumnSchema. But that is not a very common use-case.
99      *
100      * @param dbSchema DatabaseSchema as learnt from a OVSDB connection
101      * @param klazz Typed Class that represents a Table
102      * @param row The actual Row that the wrapper is operating on. It can be null if the caller
103      *            is just interested in getting ColumnSchema.
104      */
105     public static <T> T getTypedRowWrapper(final DatabaseSchema dbSchema, final Class<T> klazz,
106                                            final Row<GenericTableSchema> row) {
107         return dbSchema == null ? null : getTyped(dbSchema).getTypedRowWrapper(klazz, row);
108     }
109
110     /**
111      * This method extracts all row updates of Class&lt;T&gt; klazz from a TableUpdates
112      * that correspond to insertion or updates of rows of type klazz.
113      * Example:
114      * <code>
115      * Map&lt;UUID,Bridge&gt; updatedBridges = extractRowsUpdated(Bridge.class,updates,dbSchema)
116      * </code>
117      *
118      * @param klazz Class for row type to be extracted
119      * @param updates TableUpdates from which to extract rowUpdates
120      * @param dbSchema Dbschema for the TableUpdates
121      * @return Map&lt;UUID,T&gt; for the type of things being sought
122      */
123     public static <T> Map<UUID,T> extractRowsUpdated(final Class<T> klazz, final TableUpdates updates,
124             final DatabaseSchema dbSchema) {
125         return getTyped(dbSchema).extractRowsUpdated(klazz, updates);
126     }
127
128     /**
129      * This method extracts all row updates of Class&lt;T&gt; klazz from a TableUpdates
130      * that correspond to old version of rows of type klazz that have been updated.
131      * Example:
132      * <code>
133      * Map&lt;UUID,Bridge&gt; oldBridges = extractRowsOld(Bridge.class,updates,dbSchema)
134      * </code>
135      *
136      * @param klazz Class for row type to be extracted
137      * @param updates TableUpdates from which to extract rowUpdates
138      * @param dbSchema Dbschema for the TableUpdates
139      * @return Map&lt;UUID,T&gt; for the type of things being sought
140      */
141     public static <T> Map<UUID, T> extractRowsOld(final Class<T> klazz, final TableUpdates updates,
142             final DatabaseSchema dbSchema) {
143         return getTyped(dbSchema).extractRowsOld(klazz, updates);
144     }
145
146     /**
147      * This method extracts all row updates of Class&lt;T&gt; klazz from a TableUpdates
148      * that correspond to removal of rows of type klazz.
149      * Example:
150      * <code>
151      * Map&lt;UUID,Bridge&gt; updatedBridges = extractRowsRemoved(Bridge.class,updates,dbSchema)
152      * </code>
153      *
154      * @param klazz Class for row type to be extracted
155      * @param updates TableUpdates from which to extract rowUpdates
156      * @param dbSchema Dbschema for the TableUpdates
157      * @return Map&lt;UUID,T&gt; for the type of things being sought
158      */
159     public static <T> Map<UUID,T> extractRowsRemoved(final Class<T> klazz, final TableUpdates updates,
160             final DatabaseSchema dbSchema) {
161         return getTyped(dbSchema).extractRowsRemoved(klazz, updates);
162     }
163
164     private static TypedDatabaseSchema getTyped(final DatabaseSchema dbSchema) {
165         return dbSchema instanceof TypedDatabaseSchema ? (TypedDatabaseSchema) dbSchema
166                 : TYPED_CACHE.getUnchecked(dbSchema);
167     }
168 }