+++ /dev/null
-/*
- * Copyright (c) 2015, 2017 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.facade.xml.osgi;
-
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.capability.ModuleListener;
-import org.opendaylight.controller.config.util.capability.YangModuleCapability;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
-
-public class YangStoreService implements YangStoreContext {
-
- private final SchemaSourceProvider<YangTextSchemaSource> sourceProvider;
- private final ExecutorService notificationExecutor = Executors.newSingleThreadExecutor(
- new ThreadFactoryBuilder().setDaemon(true).setNameFormat("yangstore-capability-notifications").build());
-
- /**
- * Guarded by explicit lock to allow for properly synchronizing the initial
- * notification and modification of the listener set.
- */
- @GuardedBy("listeners")
- private final Set<ModuleListener> listeners = new HashSet<>();
-
- /**
- * This is the latest snapshot. Some of its state is always initialized, but the
- * MXBean maps potentially cause recomputation. Accessing those two specific
- * methods needs to re-check whether the snapshot has changed asynchronously and
- * retry if it didi.
- */
- private volatile YangStoreSnapshot snap;
-
- public YangStoreService(final SchemaContextProvider schemaContextProvider,
- final SchemaSourceProvider<YangTextSchemaSource> sourceProvider) {
- this.sourceProvider = sourceProvider;
- }
-
- public YangStoreContext getCurrentSnapshot() {
- return this.snap;
- }
-
- @Deprecated
- @Override
- public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
- Map<String, Map<String, ModuleMXBeanEntry>> ret;
- YangStoreSnapshot snapshot;
-
- do {
- snapshot = this.snap;
- ret = snapshot.getModuleMXBeanEntryMap();
- } while (!snapshot.equals(this.snap));
-
- return ret;
- }
-
- @Override
- public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
- Map<QName, Map<String, ModuleMXBeanEntry>> ret;
- YangStoreSnapshot snapshot;
-
- do {
- snapshot = this.snap;
- ret = snapshot.getQNamesToIdentitiesToModuleMXBeanEntries();
- } while (!snapshot.equals(this.snap));
-
- return ret;
- }
-
- @Override
- public Set<Module> getModules() {
- return this.snap.getModules();
- }
-
- @Override
- public String getModuleSource(final SourceIdentifier moduleIdentifier) {
- return this.snap.getModuleSource(moduleIdentifier);
- }
-
- @Override
- public EnumResolver getEnumResolver() {
- return this.snap.getEnumResolver();
- }
-
- public void refresh(final BindingRuntimeContext runtimeContext) {
- final YangStoreSnapshot next = new YangStoreSnapshot(runtimeContext, this.sourceProvider);
- final YangStoreSnapshot previous = this.snap;
- this.snap = next;
- this.notificationExecutor.submit(() -> notifyListeners(previous, next));
- }
-
- public AutoCloseable registerModuleListener(final ModuleListener listener) {
- final YangStoreContext context = this.snap;
-
- synchronized (this.listeners) {
- if (context != null) {
- listener.onCapabilitiesChanged(toCapabilities(context.getModules(), context),
- Collections.<Capability>emptySet());
- }
- this.listeners.add(listener);
- }
-
- return () -> {
- synchronized (YangStoreService.this.listeners) {
- YangStoreService.this.listeners.remove(listener);
- }
- };
- }
-
- void notifyListeners(final YangStoreSnapshot previous, final YangStoreSnapshot current) {
- final Set<Module> prevModules = previous.getModules();
- final Set<Module> currModules = current.getModules();
- final Set<Module> removed = Sets.difference(prevModules, currModules);
- final Set<Module> added = Sets.difference(currModules, prevModules);
-
- final Set<Capability> addedCaps = toCapabilities(added, current);
- final Set<Capability> removedCaps = toCapabilities(removed, current);
-
- synchronized (this.listeners) {
- for (final ModuleListener listener : this.listeners) {
- listener.onCapabilitiesChanged(addedCaps, removedCaps);
- }
- }
- }
-
- private static Set<Capability> toCapabilities(final Set<Module> modules, final YangStoreContext current) {
- return ImmutableSet.copyOf(Collections2.transform(modules,
- input -> new YangModuleCapability(input, current.getModuleSource(
- RevisionSourceIdentifier.create(input.getName(), input.getRevision())))));
- }
-}