af07c092bdf6f3753c8720595b24d1ab9ce8906f
[ovsdb.git] / library / impl / src / main / java / org / opendaylight / ovsdb / lib / schema / DatabaseSchema.java
1 /*
2  * Copyright (c) 2014, 2015 EBay Software Foundation 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
9 package org.opendaylight.ovsdb.lib.schema;
10
11 import com.fasterxml.jackson.databind.JsonNode;
12 import com.google.common.reflect.Invokable;
13 import java.lang.reflect.Constructor;
14 import java.lang.reflect.InvocationTargetException;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Set;
19 import org.opendaylight.ovsdb.lib.error.ParsingException;
20 import org.opendaylight.ovsdb.lib.notation.Version;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Represents an ovsdb database schema, which is comprised of a set of tables.
26  */
27 public class DatabaseSchema {
28
29     private static final Logger LOG = LoggerFactory.getLogger(DatabaseSchema.class);
30
31     private String name;
32
33     private Version version;
34     private Map<String, TableSchema> tables;
35
36     public DatabaseSchema(Map<String, TableSchema> tables) {
37         this.tables = tables;
38     }
39
40     public DatabaseSchema(String name, Version version, Map<String, TableSchema> tables) {
41         this.name = name;
42         this.version = version;
43         this.tables = tables;
44     }
45
46     public Set<String> getTables() {
47         return this.tables.keySet();
48     }
49
50     public boolean hasTable(String table) {
51         return this.getTables().contains(table);
52     }
53
54     public <E extends TableSchema<E>> E table(String tableName, Class<E> clazz) {
55         TableSchema<E> table = tables.get(tableName);
56
57         if (clazz.isInstance(table)) {
58             return clazz.cast(table);
59         }
60
61         return createTableSchema(clazz, table);
62     }
63
64     protected <E extends TableSchema<E>> E createTableSchema(Class<E> clazz, TableSchema<E> table) {
65         Constructor<E> declaredConstructor;
66         try {
67             declaredConstructor = clazz.getDeclaredConstructor(TableSchema.class);
68         } catch (NoSuchMethodException e) {
69             String message = String.format("Class %s does not have public constructor that accepts TableSchema object",
70                     clazz);
71             throw new IllegalArgumentException(message, e);
72         }
73         Invokable<E, E> invokable = Invokable.from(declaredConstructor);
74         try {
75             return invokable.invoke(null, table);
76         } catch (InvocationTargetException | IllegalAccessException e) {
77             String message = String.format("Not able to create instance of class %s using public constructor "
78                     + "that accepts TableSchema object", clazz);
79             throw new IllegalArgumentException(message, e);
80         }
81     }
82
83     //todo : this needs to move to a custom factory
84     public static DatabaseSchema fromJson(String dbName, JsonNode json) {
85         if (!json.isObject() || !json.has("tables")) {
86             throw new ParsingException("bad DatabaseSchema root, expected \"tables\" as child but was not found");
87         }
88         if (!json.isObject() || !json.has("version")) {
89             throw new ParsingException("bad DatabaseSchema root, expected \"version\" as child but was not found");
90         }
91
92         Version dbVersion = Version.fromString(json.get("version").asText());
93
94         Map<String, TableSchema> tables = new HashMap<>();
95         for (Iterator<Map.Entry<String, JsonNode>> iter = json.get("tables").fields(); iter.hasNext(); ) {
96             Map.Entry<String, JsonNode> table = iter.next();
97             LOG.trace("Read schema for table[{}]:{}", table.getKey(), table.getValue());
98
99             //todo : this needs to done by a factory
100             tables.put(table.getKey(), new GenericTableSchema().fromJson(table.getKey(), table.getValue()));
101         }
102
103         return new DatabaseSchema(dbName, dbVersion, tables);
104     }
105
106     public String getName() {
107         return name;
108     }
109
110     public void setName(String name) {
111         this.name = name;
112     }
113
114     public Version getVersion() {
115         return version;
116     }
117
118     public void setVersion(Version version) {
119         this.version = version;
120     }
121
122     public void populateInternallyGeneratedColumns() {
123         for (TableSchema tableSchema : tables.values()) {
124             tableSchema.populateInternallyGeneratedColumns();
125         }
126     }
127 }