/* * Copyright (c) 2016 Cisco and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.fd.honeycomb.translate.util; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import io.fd.honeycomb.translate.SubtreeManager; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.StreamSupport; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class RWUtils { // TODO HONEYCOMB-172 update the utils methods considering Java8. Make sure they still work by wiring a detailed unit test first private RWUtils() {} /** * Collector expecting only a single resulting item from a stream. */ public static Collector singleItemCollector() { return Collectors.collectingAndThen( Collectors.toList(), list -> { if (list.size() != 1) { throw new IllegalStateException("Unexpected size of list: " + list + ". Single item expected"); } return list.get(0); } ); } /** * Find next item in ID after provided type. */ @Nonnull public static InstanceIdentifier.PathArgument getNextId(@Nonnull final InstanceIdentifier id, @Nonnull final InstanceIdentifier type) { final Iterable pathArguments = id.getPathArguments(); final int i = Iterables.indexOf(pathArguments, new Predicate() { @Override public boolean apply(final InstanceIdentifier.PathArgument input) { return input.getType().isAssignableFrom(type.getTargetType()); } }); Preconditions.checkArgument(i >= 0, "Unable to find %s type in %s", type.getTargetType(), id); return Iterables.get(pathArguments, i + 1); } /** * Replace last item in ID with a provided IdentifiableItem of the same type. */ @SuppressWarnings("unchecked") @Nonnull public static , K extends Identifier> InstanceIdentifier replaceLastInId( @Nonnull final InstanceIdentifier id, final InstanceIdentifier.IdentifiableItem currentBdItem) { final Iterable pathArguments = id.getPathArguments(); final Iterable withoutCurrent = Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1); final Iterable concat = Iterables.concat(withoutCurrent, Collections.singleton(currentBdItem)); return (InstanceIdentifier) InstanceIdentifier.create(concat); } /** * Create IdentifiableItem from target type of provided ID with provided key. */ @Nonnull public static , K extends Identifier> InstanceIdentifier.IdentifiableItem getCurrentIdItem( @Nonnull final InstanceIdentifier id, final K key) { return new InstanceIdentifier.IdentifiableItem<>(id.getTargetType(), key); } /** * Trim InstanceIdentifier at indexOf(type). */ @SuppressWarnings("unchecked") @Nonnull public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, @Nonnull final InstanceIdentifier type) { final Iterable pathArguments = id.getPathArguments(); final int i = Iterables.indexOf(pathArguments, new Predicate() { @Override public boolean apply(final InstanceIdentifier.PathArgument input) { return input.getType().equals(type.getTargetType()); } }); Preconditions.checkArgument(i >= 0, "ID %s does not contain %s", id, type); return (InstanceIdentifier) InstanceIdentifier.create(Iterables.limit(pathArguments, i + 1)); } /** * Trim InstanceIdentifier at indexOf(type). */ @Nonnull public static InstanceIdentifier cutId(@Nonnull final InstanceIdentifier id, @Nonnull final Class type) { return cutId(id, InstanceIdentifier.create(type)); } /** * Create an ordered map from a collection, checking for duplicity in the process. */ @Nonnull public static Map uniqueLinkedIndex(@Nonnull final Collection values, @Nonnull final Function keyFunction) { final Map objectObjectLinkedHashMap = Maps.newLinkedHashMap(); for (V value : values) { final K key = keyFunction.apply(value); Preconditions.checkArgument(objectObjectLinkedHashMap.put(key, value) == null, "Duplicate key detected : %s", key); } return objectObjectLinkedHashMap; } public static final Function, Class> MANAGER_CLASS_FUNCTION = new Function, Class>() { @Override public Class apply(final SubtreeManager input) { return input.getManagedDataObjectType().getTargetType(); } }; public static final Function>, Class> MANAGER_CLASS_AUG_FUNCTION = new Function>, Class>() { @Override @SuppressWarnings("unchecked") public Class apply(final SubtreeManager> input) { final Class> targetType = input.getManagedDataObjectType().getTargetType(); Preconditions.checkArgument(DataObject.class.isAssignableFrom(targetType)); return (Class) targetType; } }; /** * Transform a keyed instance identifier into a wildcarded one. *

* ! This has to be called also for wildcarded List instance identifiers * due to weird behavior of equals in InstanceIdentifier ! */ @SuppressWarnings("unchecked") public static InstanceIdentifier makeIidWildcarded(final InstanceIdentifier id) { final List transformedPathArguments = StreamSupport.stream(id.getPathArguments().spliterator(), false) .map(RWUtils::cleanPathArgumentFromKeys) .collect(Collectors.toList()); return (InstanceIdentifier) InstanceIdentifier.create(transformedPathArguments); } /** * Transform a keyed instance identifier into a wildcarded one, keeping keys except the last item. */ @SuppressWarnings("unchecked") public static InstanceIdentifier makeIidLastWildcarded(final InstanceIdentifier id) { final InstanceIdentifier.Item wildcardedItem = new InstanceIdentifier.Item<>(id.getTargetType()); final Iterable pathArguments = id.getPathArguments(); return (InstanceIdentifier) InstanceIdentifier.create( Iterables.concat( Iterables.limit(pathArguments, Iterables.size(pathArguments) - 1), Collections.singleton(wildcardedItem))); } private static InstanceIdentifier.PathArgument cleanPathArgumentFromKeys(final InstanceIdentifier.PathArgument pathArgument) { return pathArgument instanceof InstanceIdentifier.IdentifiableItem ? new InstanceIdentifier.Item<>(pathArgument.getType()) : pathArgument; } }