Proxy MD-SAL interfaces in DOMMountPointServiceImpl
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / mount / DOMMountPointServiceImpl.java
1 /*
2  * Copyright (c) 2014 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.dom.broker.impl.mount;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Optional;
14 import com.google.common.base.Preconditions;
15 import com.google.common.collect.ClassToInstanceMap;
16 import com.google.common.collect.ImmutableMap;
17 import com.google.common.collect.MutableClassToInstanceMap;
18 import java.util.Map;
19 import java.util.Map.Entry;
20 import org.opendaylight.controller.md.sal.dom.api.DOMActionService;
21 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
22 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
23 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
24 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
25 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
26 import org.opendaylight.controller.md.sal.dom.api.DOMService;
27 import org.opendaylight.controller.md.sal.dom.broker.spi.mount.SimpleDOMMountPoint;
28 import org.opendaylight.controller.sal.core.compat.DOMDataBrokerAdapter;
29 import org.opendaylight.controller.sal.core.compat.DOMMountPointAdapter;
30 import org.opendaylight.controller.sal.core.compat.DOMNotificationServiceAdapter;
31 import org.opendaylight.controller.sal.core.compat.DOMRpcServiceAdapter;
32 import org.opendaylight.mdsal.dom.api.DOMMountPointListener;
33 import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
34 import org.opendaylight.yangtools.concepts.ListenerRegistration;
35 import org.opendaylight.yangtools.concepts.ObjectRegistration;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
38
39 public class DOMMountPointServiceImpl implements DOMMountPointService {
40     private abstract static class CompatFactory<M extends org.opendaylight.mdsal.dom.api.DOMService,
41             C extends DOMService> {
42         private final Class<C> controllerClass;
43         private final Class<M> mdsalClass;
44
45         CompatFactory(final Class<C> controllerClass, final Class<M> mdsalClass) {
46             this.controllerClass = requireNonNull(controllerClass);
47             this.mdsalClass = requireNonNull(mdsalClass);
48         }
49
50         final void addService(final org.opendaylight.mdsal.dom.api.DOMMountPointService.DOMMountPointBuilder builder,
51                 final ClassToInstanceMap<DOMService> services) {
52             if (!services.containsKey(mdsalClass)) {
53                 final C controllerService = services.getInstance(controllerClass);
54                 if (controllerService != null) {
55                     final M mdsalService = createService(controllerService);
56                     if (mdsalService != null) {
57                         builder.addService(mdsalClass, mdsalService);
58                     }
59                 }
60             }
61         }
62
63         abstract M createService(C delegate);
64     }
65
66     private static final Map<Class<? extends DOMService>, CompatFactory<?, ?>> KNOWN_SERVICES = ImmutableMap.of(
67         DOMActionService.class, new CompatFactory<org.opendaylight.mdsal.dom.api.DOMActionService, DOMActionService>(
68                 DOMActionService.class, org.opendaylight.mdsal.dom.api.DOMActionService.class) {
69             @Override
70             org.opendaylight.mdsal.dom.api.DOMActionService createService(final DOMActionService delegate) {
71                 return delegate;
72             }
73         },
74         DOMDataBroker.class, new CompatFactory<org.opendaylight.mdsal.dom.api.DOMDataBroker, DOMDataBroker>(
75                 DOMDataBroker.class, org.opendaylight.mdsal.dom.api.DOMDataBroker.class) {
76             @Override
77             org.opendaylight.mdsal.dom.api.DOMDataBroker createService(final DOMDataBroker delegate) {
78                 return new DOMDataBrokerAdapter(delegate);
79             }
80         },
81         DOMNotificationService.class, new CompatFactory<org.opendaylight.mdsal.dom.api.DOMNotificationService,
82                 DOMNotificationService>(DOMNotificationService.class,
83                         org.opendaylight.mdsal.dom.api.DOMNotificationService.class) {
84             @Override
85             org.opendaylight.mdsal.dom.api.DOMNotificationService createService(final DOMNotificationService delegate) {
86                 return new DOMNotificationServiceAdapter(delegate);
87             }
88         },
89         DOMRpcService.class, new CompatFactory<org.opendaylight.mdsal.dom.api.DOMRpcService, DOMRpcService>(
90                 DOMRpcService.class, org.opendaylight.mdsal.dom.api.DOMRpcService.class) {
91             @Override
92             org.opendaylight.mdsal.dom.api.DOMRpcService createService(final DOMRpcService delegate) {
93                 return new DOMRpcServiceAdapter(delegate);
94             }
95         });
96
97     private final org.opendaylight.mdsal.dom.api.DOMMountPointService delegate;
98
99     @VisibleForTesting
100     public DOMMountPointServiceImpl() {
101         this(new org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl());
102     }
103
104     public DOMMountPointServiceImpl(final org.opendaylight.mdsal.dom.api.DOMMountPointService delegate) {
105         this.delegate = delegate;
106     }
107
108     @Override
109     public Optional<DOMMountPoint> getMountPoint(final YangInstanceIdentifier path) {
110         return Optional.fromJavaUtil(delegate.getMountPoint(path).map(DOMMountPointAdapter::new));
111     }
112
113     @Override
114     public DOMMountPointBuilder createMountPoint(final YangInstanceIdentifier path) {
115         return new DOMMountPointBuilderImpl(path);
116     }
117
118     @Override
119     public ListenerRegistration<DOMMountPointListener> registerProvisionListener(final DOMMountPointListener listener) {
120         return delegate.registerProvisionListener(listener);
121     }
122
123     @SuppressWarnings("unchecked")
124     ObjectRegistration<DOMMountPoint> registerMountPoint(final SimpleDOMMountPoint mountPoint) {
125         final org.opendaylight.mdsal.dom.api.DOMMountPointService.DOMMountPointBuilder delegateBuilder =
126                 delegate.createMountPoint(mountPoint.getIdentifier());
127
128         if (mountPoint.getSchemaContext() != null) {
129             delegateBuilder.addInitialSchemaContext(mountPoint.getSchemaContext());
130         }
131
132         final ClassToInstanceMap<DOMService> myServices = mountPoint.getServices();
133         for (Entry<Class<? extends DOMService>, DOMService> entry : myServices.entrySet()) {
134             delegateBuilder.addService((Class<DOMService>)entry.getKey(), entry.getValue());
135
136             final CompatFactory<?, ?> compat = KNOWN_SERVICES.get(entry.getKey());
137             if (compat != null) {
138                 compat.addService(delegateBuilder, myServices);
139             }
140         }
141
142         final ObjectRegistration<org.opendaylight.mdsal.dom.api.DOMMountPoint> delegateReg = delegateBuilder.register();
143         return new AbstractObjectRegistration<DOMMountPoint>(mountPoint) {
144             @Override
145             protected void removeRegistration() {
146                 delegateReg.close();
147             }
148         };
149     }
150
151     public class DOMMountPointBuilderImpl implements DOMMountPointBuilder {
152         private final ClassToInstanceMap<DOMService> services = MutableClassToInstanceMap.create();
153         private final YangInstanceIdentifier path;
154         private SimpleDOMMountPoint mountPoint;
155         private SchemaContext schemaContext;
156
157         public DOMMountPointBuilderImpl(final YangInstanceIdentifier path) {
158             this.path = path;
159         }
160
161         @Override
162         public <T extends DOMService> DOMMountPointBuilder addService(final Class<T> type, final T impl) {
163             services.putInstance(type, impl);
164             return this;
165         }
166
167         @Override
168         public DOMMountPointBuilder addInitialSchemaContext(final SchemaContext ctx) {
169             schemaContext = ctx;
170             return this;
171         }
172
173         @Override
174         public ObjectRegistration<DOMMountPoint> register() {
175             Preconditions.checkState(mountPoint == null, "Mount point is already built.");
176             mountPoint = SimpleDOMMountPoint.create(path, services, schemaContext);
177             return registerMountPoint(mountPoint);
178         }
179     }
180 }