import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
-import java.util.concurrent.Callable;
+
+import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
-import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
final InstanceIdentifier<? extends DataObject> bindingPath, final DataObject bindingObject) {
- return toNormalizedNode(toEntry(bindingPath, bindingObject));
+ return toNormalizedNode(toBindingEntry(bindingPath, bindingObject));
}
.toNormalized(legacyEntry);
LOG.trace("Serialization of {}, Legacy Representation: {}, Normalized Representation: {}", binding,
legacyEntry, normalizedEntry);
- if (Augmentation.class.isAssignableFrom(binding.getKey().getTargetType())) {
+ if (isAugmentation(binding.getKey().getTargetType())) {
for (DataContainerChild<? extends PathArgument, ?> child : ((DataContainerNode<?>) normalizedEntry
.getValue()).getValue()) {
if (child instanceof AugmentationNode) {
ImmutableList<PathArgument> childArgs = ImmutableList.<PathArgument> builder()
- .addAll(normalizedEntry.getKey().getPath()).add(child.getIdentifier()).build();
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
+ .addAll(normalizedEntry.getKey().getPathArguments()).add(child.getIdentifier()).build();
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.create(
childArgs);
- return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>(
- childPath, child);
+ return toDOMEntry(childPath, child);
}
}
*/
public Optional<InstanceIdentifier<? extends DataObject>> toBinding(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
- throws DeserializationException {
+ throws DeserializationException {
- PathArgument lastArgument = Iterables.getLast(normalized.getPath());
+ PathArgument lastArgument = Iterables.getLast(normalized.getPathArguments());
// Used instance-identifier codec do not support serialization of last
// path
// argument if it is AugmentationIdentifier (behaviour expected by old
private Optional<InstanceIdentifier<? extends DataObject>> toBindingAugmented(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
- throws DeserializationException {
+ throws DeserializationException {
Optional<InstanceIdentifier<? extends DataObject>> potential = toBindingImpl(normalized);
// Shorthand check, if codec already supports deserialization
// of AugmentationIdentifier we will return
}
int normalizedCount = getAugmentationCount(normalized);
- AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPath());
+ AugmentationIdentifier lastArgument = (AugmentationIdentifier) Iterables.getLast(normalized.getPathArguments());
// Here we employ small trick - Binding-aware Codec injects an pointer
// to augmentation class
// if child is referenced - so we will reference child and then shorten
// path.
+ LOG.trace("Looking for candidates to match {}", normalized);
for (QName child : lastArgument.getPossibleChildNames()) {
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
- ImmutableList.<PathArgument> builder().addAll(normalized.getPath()).add(new NodeIdentifier(child))
- .build());
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier childPath = normalized.node(child);
try {
- if (!isNotRepresentable(childPath)) {
- InstanceIdentifier<? extends DataObject> potentialPath = shortenToLastAugment(toBindingImpl(
- childPath).get());
- int potentialAugmentCount = getAugmentationCount(potentialPath);
- if(potentialAugmentCount == normalizedCount) {
- return Optional.<InstanceIdentifier<? extends DataObject>> of(potentialPath);
- }
+ if (isNotRepresentable(childPath)) {
+ LOG.trace("Path {} is not BI-representable, skipping it", childPath);
+ continue;
}
- } catch (Exception e) {
- LOG.trace("Unable to deserialize aug. child path for {}", childPath, e);
+ } catch (DataNormalizationException e) {
+ LOG.warn("Failed to denormalize path {}, skipping it", childPath, e);
+ continue;
+ }
+
+ Optional<InstanceIdentifier<? extends DataObject>> baId = toBindingImpl(childPath);
+ if (!baId.isPresent()) {
+ LOG.debug("No binding-aware identifier found for path {}, skipping it", childPath);
+ continue;
+ }
+
+ InstanceIdentifier<? extends DataObject> potentialPath = shortenToLastAugment(baId.get());
+ int potentialAugmentCount = getAugmentationCount(potentialPath);
+ if (potentialAugmentCount == normalizedCount) {
+ LOG.trace("Found matching path {}", potentialPath);
+ return Optional.<InstanceIdentifier<? extends DataObject>> of(potentialPath);
}
+
+ LOG.trace("Skipping mis-matched potential path {}", potentialPath);
}
+
+ LOG.trace("Failed to find augmentation matching {}", normalized);
return Optional.absent();
}
private Optional<InstanceIdentifier<? extends DataObject>> toBindingImpl(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
- throws DeserializationException {
+ throws DeserializationException {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath;
try {
private DataNormalizationOperation<?> findNormalizationOperation(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized)
- throws DataNormalizationException {
+ throws DataNormalizationException {
DataNormalizationOperation<?> current = legacyToNormalized.getRootOperation();
- for (PathArgument arg : normalized.getPath()) {
+ for (PathArgument arg : normalized.getPathArguments()) {
current = current.getChild(arg);
}
return current;
}
- private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toEntry(
+ private static final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> toBindingEntry(
final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> key,
final DataObject value) {
return new SimpleEntry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>(
key, value);
}
+ private static final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>> toDOMEntry(
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier key,
+ final NormalizedNode<?, ?> value) {
+ return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, NormalizedNode<?, ?>>(
+ key, value);
+ }
+
public DataObject toBinding(final InstanceIdentifier<?> path, final NormalizedNode<?, ?> normalizedNode)
throws DeserializationException {
CompositeNode legacy = null;
public Optional<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
final Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
- throws DeserializationException {
+ throws DeserializationException {
Optional<InstanceIdentifier<? extends DataObject>> potentialPath = toBinding(normalized.getKey());
if (potentialPath.isPresent()) {
InstanceIdentifier<? extends DataObject> bindingPath = potentialPath.get();
if (bindingData == null) {
LOG.warn("Failed to deserialize {} to Binding format. Binding path is: {}", normalized, bindingPath);
}
- return Optional.of(toEntry(bindingPath, bindingData));
+ return Optional.of(toBindingEntry(bindingPath, bindingData));
} else {
return Optional.absent();
}
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) {
int position = 0;
int foundPosition = -1;
- for (PathArgument arg : normalized.getPath()) {
+ for (PathArgument arg : normalized.getPathArguments()) {
position++;
if (arg instanceof AugmentationIdentifier) {
foundPosition = position;
}
}
if (foundPosition > 0) {
- return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(normalized.getPath().subList(0,
- foundPosition));
+ Iterable<PathArgument> shortened = Iterables.limit(normalized.getPathArguments(), foundPosition);
+ return org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.create(shortened);
}
return null;
}
} else if (List.class.isAssignableFrom(returnType)) {
try {
return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(),
- new Callable<Class>() {
-
- @SuppressWarnings("rawtypes")
- @Override
- public Class call() throws Exception {
- Type listResult = ClassLoaderUtils.getFirstGenericParameter(method
- .getGenericReturnType());
- if (listResult instanceof Class
- && DataObject.class.isAssignableFrom((Class) listResult)) {
- return (Class<?>) listResult;
- }
- return null;
- }
-
- });
+ new Supplier<Class>() {
+ @Override
+ public Class get() {
+ Type listResult = ClassLoaderUtils.getFirstGenericParameter(method
+ .getGenericReturnType());
+ if (listResult instanceof Class
+ && DataObject.class.isAssignableFrom((Class) listResult)) {
+ return (Class<?>) listResult;
+ }
+ return null;
+ }
+
+ });
} catch (Exception e) {
LOG.debug("Could not get YANG modeled entity for {}", method, e);
return null;
}
private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed) {
- return Iterables.getLast(processed.getPath()) instanceof AugmentationIdentifier;
+ return Iterables.getLast(processed.getPathArguments()) instanceof AugmentationIdentifier;
}
private static int getAugmentationCount(final InstanceIdentifier<?> potential) {
private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potential) {
int count = 0;
- for(PathArgument arg : potential.getPath()) {
+ for(PathArgument arg : potential.getPathArguments()) {
if(arg instanceof AugmentationIdentifier) {
count++;
}
}
return count;
}
+
+ public Function<Optional<NormalizedNode<?, ?>>, Optional<DataObject>> deserializeFunction(final InstanceIdentifier<?> path) {
+ return new DeserializeFunction(this, path);
+ }
+
+ private static class DeserializeFunction implements Function<Optional<NormalizedNode<?, ?>>, Optional<DataObject>> {
+
+ private final BindingToNormalizedNodeCodec codec;
+ private final InstanceIdentifier<?> path;
+
+ public DeserializeFunction(final BindingToNormalizedNodeCodec codec, final InstanceIdentifier<?> path) {
+ super();
+ this.codec = Preconditions.checkNotNull(codec, "Codec must not be null");
+ this.path = Preconditions.checkNotNull(path, "Path must not be null");
+ }
+
+ @Nullable
+ @Override
+ public Optional<DataObject> apply(@Nullable final Optional<NormalizedNode<?, ?>> normalizedNode) {
+ if (normalizedNode.isPresent()) {
+ final DataObject dataObject;
+ try {
+ dataObject = codec.toBinding(path, normalizedNode.get());
+ } catch (DeserializationException e) {
+ LOG.warn("Failed to create dataobject from node {}", normalizedNode.get(), e);
+ throw new IllegalStateException("Failed to create dataobject", e);
+ }
+
+ if (dataObject != null) {
+ return Optional.of(dataObject);
+ }
+ }
+ return Optional.absent();
+ }
+ }
}