1e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar/*
2e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * Copyright 2017 The Android Open Source Project
3e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar *
4e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * you may not use this file except in compliance with the License.
6e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * You may obtain a copy of the License at
7e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar *
8e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar *
10e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * Unless required by applicable law or agreed to in writing, software
11e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * See the License for the specific language governing permissions and
14e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * limitations under the License.
15e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar */
16e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
17ba069d50913c3fb250bb60ec310439db36895337Alan Viverettepackage androidx.room.migration.bundle;
18e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
19ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.annotation.Nullable;
20ba069d50913c3fb250bb60ec310439db36895337Alan Viveretteimport androidx.annotation.RestrictTo;
21e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
22e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyarimport java.util.List;
23e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyarimport java.util.Map;
24e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
25e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar/**
26e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * utility class to run schema equality on collections.
27e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar *
28e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar * @hide
29e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar */
30e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar@RestrictTo(RestrictTo.Scope.LIBRARY)
31e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyarclass SchemaEqualityUtil {
32e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    static <T, K extends SchemaEquality<K>> boolean checkSchemaEquality(
33e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            @Nullable Map<T, K> map1, @Nullable Map<T, K> map2) {
34e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (map1 == null) {
35e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return map2 == null;
36e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
37e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (map2 == null) {
38e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return false;
39e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
40e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (map1.size() != map2.size()) {
41e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return false;
42e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
43e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        for (Map.Entry<T, K> pair : map1.entrySet()) {
44e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            if (!checkSchemaEquality(pair.getValue(), map2.get(pair.getKey()))) {
45e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                return false;
46e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            }
47e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
48e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        return true;
49e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    }
50e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
51e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    static <K extends SchemaEquality<K>> boolean checkSchemaEquality(
52e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            @Nullable List<K> list1, @Nullable List<K> list2) {
53e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (list1 == null) {
54e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return list2 == null;
55e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
56e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (list2 == null) {
57e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return false;
58e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
59e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (list1.size() != list2.size()) {
60e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return false;
61e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
62e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        // we don't care this is n^2, small list + only used for testing.
63e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        for (K item1 : list1) {
64e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            // find matching item
65e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            boolean matched = false;
66e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            for (K item2 : list2) {
67e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                if (checkSchemaEquality(item1, item2)) {
68e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                    matched = true;
69e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                    break;
70e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                }
71e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            }
72e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            if (!matched) {
73e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar                return false;
74e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            }
75e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
76e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        return true;
77e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    }
78e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar
79e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    @SuppressWarnings("SimplifiableIfStatement")
80e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    static <K extends SchemaEquality<K>> boolean checkSchemaEquality(
81e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            @Nullable K item1, @Nullable K item2) {
82e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (item1 == null) {
83e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return item2 == null;
84e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
85e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        if (item2 == null) {
86e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar            return false;
87e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        }
88e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar        return item1.isSchemaEqual(item2);
89e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar    }
9023b05b05914468496d8b39fcf8d8662ca7f3bddbJake Wharton
9123b05b05914468496d8b39fcf8d8662ca7f3bddbJake Wharton    private SchemaEqualityUtil() {
9223b05b05914468496d8b39fcf8d8662ca7f3bddbJake Wharton    }
93e5ed537fe6f14f0bbb43ddef605ed22f09714142Yigit Boyar}
94