Fix license header violations in sal-binding-broker
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / FutureSchema.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, 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
9 package org.opendaylight.controller.md.sal.binding.impl;
10
11 import com.google.common.base.Predicate;
12 import com.google.common.base.Throwables;
13 import com.google.common.util.concurrent.SettableFuture;
14 import java.net.URI;
15 import java.util.Collection;
16 import java.util.Date;
17 import java.util.List;
18 import java.util.concurrent.CopyOnWriteArrayList;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.TimeoutException;
22 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
23 import org.opendaylight.yangtools.yang.binding.Augmentation;
24
25 class FutureSchema implements AutoCloseable {
26
27     private final List<FutureSchemaPredicate> postponedOperations = new CopyOnWriteArrayList<>();
28     private final long duration;
29     private final TimeUnit unit;
30
31     protected FutureSchema(final long time, final TimeUnit unit) {
32         this.duration = time;
33         this.unit = unit;
34     }
35
36     void onRuntimeContextUpdated(final BindingRuntimeContext context) {
37         for (final FutureSchemaPredicate op : postponedOperations) {
38             op.unlockIfPossible(context);
39         }
40     }
41
42     long getDuration() {
43         return duration;
44     }
45
46     TimeUnit getUnit() {
47         return unit;
48     }
49
50     @Override
51     public void close() {
52         for (final FutureSchemaPredicate op : postponedOperations) {
53             op.cancel();
54         }
55     }
56
57     private static boolean isSchemaAvailable(final Class<?> clz, final BindingRuntimeContext context) {
58         final Object schema;
59         if (Augmentation.class.isAssignableFrom(clz)) {
60             schema = context.getAugmentationDefinition(clz);
61         } else {
62             schema = context.getSchemaDefinition(clz);
63         }
64         return schema != null;
65     }
66
67     boolean waitForSchema(final URI namespace, final Date revision) {
68         final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() {
69
70             @Override
71             public boolean apply(final BindingRuntimeContext input) {
72                 return input.getSchemaContext().findModuleByNamespaceAndRevision(namespace, revision) != null;
73             }
74         };
75         return postponedOp.waitForSchema();
76     }
77
78     boolean waitForSchema(final Collection<Class<?>> bindingClasses) {
79         final FutureSchemaPredicate postponedOp = new FutureSchemaPredicate() {
80
81             @Override
82             public boolean apply(final BindingRuntimeContext context) {
83                 for (final Class<?> clz : bindingClasses) {
84                     if (!isSchemaAvailable(clz, context)) {
85                         return false;
86                     }
87                 }
88                 return true;
89             }
90         };
91         return postponedOp.waitForSchema();
92     }
93
94     private abstract class FutureSchemaPredicate implements Predicate<BindingRuntimeContext> {
95
96         final boolean waitForSchema() {
97             try {
98                 schemaPromise.get(duration, unit);
99                 return true;
100             } catch (final InterruptedException | ExecutionException e) {
101                 throw Throwables.propagate(e);
102             } catch (final TimeoutException e) {
103                 return false;
104             } finally {
105                 postponedOperations.remove(this);
106             }
107         }
108
109         final void unlockIfPossible(final BindingRuntimeContext context) {
110             if (!schemaPromise.isDone() && apply(context)) {
111                 schemaPromise.set(null);
112             }
113         }
114
115         final void cancel() {
116             schemaPromise.cancel(true);
117         }
118
119         private final SettableFuture<?> schemaPromise = SettableFuture.create();
120     }
121
122 }