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 delegate.getMountPoint(path).transform(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     /**
124      * Deprecated.
125
126      * @deprecated this method should never have been exposed publicly - registration should be done via the
127      *         public {@link #createMountPoint} interface. As such, this method expects the {@code mountPoint} param
128      *         to be of type {@link SimpleDOMMountPoint}.
129      */
130     @Deprecated
131     public ObjectRegistration<DOMMountPoint> registerMountPoint(final DOMMountPoint mountPoint) {
132         Preconditions.checkArgument(mountPoint instanceof SimpleDOMMountPoint, "Expected SimpleDOMMountPoint");
133         return doRegisterMountPoint((SimpleDOMMountPoint) mountPoint);
134     }
135
136     @SuppressWarnings("unchecked")
137     ObjectRegistration<DOMMountPoint> doRegisterMountPoint(final SimpleDOMMountPoint mountPoint) {
138         final org.opendaylight.mdsal.dom.api.DOMMountPointService.DOMMountPointBuilder delegateBuilder =
139                 delegate.createMountPoint(mountPoint.getIdentifier());
140
141         if (mountPoint.getSchemaContext() != null) {
142             delegateBuilder.addInitialSchemaContext(mountPoint.getSchemaContext());
143         }
144
145         final ClassToInstanceMap<DOMService> myServices = mountPoint.getServices();
146         for (Entry<Class<? extends DOMService>, DOMService> entry : myServices.entrySet()) {
147             delegateBuilder.addService((Class<DOMService>)entry.getKey(), entry.getValue());
148
149             final CompatFactory<?, ?> compat = KNOWN_SERVICES.get(entry.getKey());
150             if (compat != null) {
151                 compat.addService(delegateBuilder, myServices);
152             }
153         }
154
155         final ObjectRegistration<org.opendaylight.mdsal.dom.api.DOMMountPoint> delegateReg = delegateBuilder.register();
156         return new AbstractObjectRegistration<DOMMountPoint>(mountPoint) {
157             @Override
158             protected void removeRegistration() {
159                 delegateReg.close();
160             }
161         };
162     }
163
164     public class DOMMountPointBuilderImpl implements DOMMountPointBuilder {
165         private final ClassToInstanceMap<DOMService> services = MutableClassToInstanceMap.create();
166         private final YangInstanceIdentifier path;
167         private SimpleDOMMountPoint mountPoint;
168         private SchemaContext schemaContext;
169
170         public DOMMountPointBuilderImpl(final YangInstanceIdentifier path) {
171             this.path = path;
172         }
173
174         @Override
175         public <T extends DOMService> DOMMountPointBuilder addService(final Class<T> type, final T impl) {
176             services.putInstance(type, impl);
177             return this;
178         }
179
180         @Override
181         public DOMMountPointBuilder addInitialSchemaContext(final SchemaContext ctx) {
182             schemaContext = ctx;
183             return this;
184         }
185
186         @Override
187         public ObjectRegistration<DOMMountPoint> register() {
188             Preconditions.checkState(mountPoint == null, "Mount point is already built.");
189             mountPoint = SimpleDOMMountPoint.create(path, services, schemaContext);
190             return doRegisterMountPoint(mountPoint);
191         }
192     }
193 }