Merge "Extracted NotificationInvokerImpl to separate class."
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / BindingDOMNotificationServiceAdapter.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 package org.opendaylight.controller.md.sal.binding.impl;
9
10 import com.google.common.collect.ClassToInstanceMap;
11 import com.google.common.collect.ImmutableSet;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.Set;
16 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
17 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMAdapterBuilder.Factory;
18 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
19 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
20 import org.opendaylight.controller.md.sal.dom.api.DOMService;
21 import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
22 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
23 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
24 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
25 import org.opendaylight.yangtools.concepts.ListenerRegistration;
26 import org.opendaylight.yangtools.yang.binding.Notification;
27 import org.opendaylight.yangtools.yang.binding.NotificationListener;
28 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
29 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
30
31 public class BindingDOMNotificationServiceAdapter implements NotificationService, AutoCloseable {
32
33     public static final Factory<NotificationService> BUILDER_FACTORY = new Factory<NotificationService>() {
34
35         @Override
36         public BindingDOMAdapterBuilder<NotificationService> newBuilder() {
37             return new Builder();
38         }
39
40     };
41     private final BindingNormalizedNodeSerializer codec;
42     private final DOMNotificationService domNotifService;
43     private final NotificationInvokerFactory notificationInvokerFactory;
44
45     public BindingDOMNotificationServiceAdapter(final BindingNormalizedNodeSerializer codec, final DOMNotificationService domNotifService, final NotificationInvokerFactory notificationInvokerFactory) {
46         this.codec = codec;
47         this.domNotifService = domNotifService;
48         this.notificationInvokerFactory = notificationInvokerFactory;
49     }
50
51     @Override
52     public <T extends NotificationListener> ListenerRegistration<T> registerNotificationListener(final T listener) {
53         final NotificationInvokerFactory.NotificationInvoker invoker = notificationInvokerFactory.invokerFor(listener);
54         final DOMNotificationListener domListener = new BindingDOMNotificationListenerAdapter(codec, invoker);
55         final Collection<SchemaPath> schemaPaths = convertNotifTypesToSchemaPath(invoker.getSupportedNotifications());
56         final ListenerRegistration<DOMNotificationListener> domRegistration =
57                 domNotifService.registerNotificationListener(domListener, schemaPaths);
58         return new ListenerRegistrationImpl<>(listener, domRegistration);
59     }
60
61
62
63     private Collection<SchemaPath> convertNotifTypesToSchemaPath(final Set<Class<? extends Notification>> notificationTypes) {
64         final List<SchemaPath> schemaPaths = new ArrayList<>();
65         for (final Class<? extends Notification> notificationType : notificationTypes) {
66             schemaPaths.add(SchemaPath.create(true, BindingReflections.findQName(notificationType)));
67         }
68         return schemaPaths;
69     }
70
71     @Override
72     public void close() throws Exception {
73
74     }
75
76     private static class ListenerRegistrationImpl<T extends NotificationListener> extends AbstractListenerRegistration<T> {
77         private final ListenerRegistration<?> listenerRegistration;
78
79         public ListenerRegistrationImpl(final T listener, final ListenerRegistration<?> listenerRegistration) {
80             super(listener);
81             this.listenerRegistration = listenerRegistration;
82         }
83
84         @Override
85         protected void removeRegistration() {
86             listenerRegistration.close();
87         }
88     }
89
90     private static class Builder extends BindingDOMAdapterBuilder<NotificationService> {
91
92
93         @Override
94         protected NotificationService createInstance(final BindingToNormalizedNodeCodec codec,
95                 final ClassToInstanceMap<DOMService> delegates) {
96             final DOMNotificationService domNotification = delegates.getInstance(DOMNotificationService.class);
97             final NotificationInvokerFactory invokerFactory = SingletonHolder.INVOKER_FACTORY;
98             return new BindingDOMNotificationServiceAdapter(codec.getCodecRegistry(), domNotification, invokerFactory);
99         }
100
101         @Override
102         public Set<? extends Class<? extends DOMService>> getRequiredDelegates() {
103             return ImmutableSet.of(DOMNotificationService.class);
104         }
105
106
107
108     }
109 }