/* * Copyright (c) 2014 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.md.sal.common.impl.routing; import java.util.Map.Entry; import org.opendaylight.controller.md.sal.common.api.data.DataReader; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.Path; import org.opendaylight.yangtools.concepts.Registration; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; /** * Base abstract implementation of DataReadRouter, which performs * a read operation on multiple data readers and then merges result. * * @param
* @param , D> implements DataReader {
Multimap > configReaders = Multimaps.synchronizedSetMultimap(HashMultimap. >create());
Multimap > operationalReaders = Multimaps.synchronizedSetMultimap(HashMultimap. >create());
@Override
public D readConfigurationData(P path) {
FluentIterable input) {
return input.readConfigurationData(path);
}
};
}
/**
* Returns a function which performs operational read for supplied path
*
* @param path
* @return function which performs operational read for supplied path
*/
private Function input) {
return input.readOperationalData(path);
}
};
}
// Registrations
/**
* Register's a reader for operational data.
*
* @param path Path which is served by this reader
* @param reader Reader instance which is responsible for reading particular subpath.
* @return
*/
public Registration reader) {
OperationalDataReaderRegistration ret = new OperationalDataReaderRegistration<>(path, reader);
operationalReaders.put(path, ret);
return ret;
}
public Registration reader) {
ConfigurationDataReaderRegistration ret = new ConfigurationDataReaderRegistration<>(path, reader);
configReaders.put(path, ret);
return ret;
}
Iterable > readerMap, P path) {
return FluentIterable
.from(readerMap.entries()) //
.filter(affects(path)) //
.transform(retrieveInstance());
}
private void removeRegistration(OperationalDataReaderRegistration, ?> registration) {
operationalReaders.remove(registration.getKey(), registration);
}
private void removeRegistration(ConfigurationDataReaderRegistration, ?> registration) {
configReaders.remove(registration.getKey(), registration);
}
private Function super Entry >, DataReader > retrieveInstance() {
return new Function >() {
@Override
public DataReader apply(Entry > input) {
return input.getValue().getInstance();
}
};
}
private Predicate super Entry >> affects(final P path) {
return new Predicate > input) {
final P key = input.getKey();
return key.contains(path) || ((P) path).contains(key);
}
};
}
@SuppressWarnings("hiding")
private class ConfigurationDataReaderRegistration , D> extends DataReaderRegistration {
public ConfigurationDataReaderRegistration(P key, DataReader instance) {
super(key, instance);
}
@Override
protected void removeRegistration() {
AbstractDataReadRouter.this.removeRegistration(this);
}
}
@SuppressWarnings("hiding")
private class OperationalDataReaderRegistration , D> extends DataReaderRegistration {
public OperationalDataReaderRegistration(P key, DataReader instance) {
super(key, instance);
}
@Override
protected void removeRegistration() {
AbstractDataReadRouter.this.removeRegistration(this);
}
}
private abstract static class DataReaderRegistration , D> extends
AbstractObjectRegistration instance) {
super(instance);
this.key = key;
}
}
}