+ private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalizedAugmented(
+ final InstanceIdentifier<?> augPath) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed = toNormalizedImpl(augPath);
+ // If used instance identifier codec added supports for deserialization
+ // of last AugmentationIdentifier we will just reuse it
+ if (isAugmentationIdentifier(processed)) {
+ return processed;
+ }
+ // Here we employ small trick - DataNormalizer injects augmentation
+ // identifier if child is
+ // also part of the path (since using a child we can safely identify
+ // augmentation)
+ // so, we scan augmentation for children add it to path
+ // and use original algorithm, then shorten it to last augmentation
+ for (@SuppressWarnings("rawtypes")
+ Class augChild : getAugmentationChildren(augPath.getTargetType())) {
+ @SuppressWarnings("unchecked")
+ InstanceIdentifier<?> childPath = augPath.child(augChild);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = toNormalizedImpl(childPath);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potentialDiscovered = shortenToLastAugmentation(normalized);
+ if (potentialDiscovered != null) {
+ return potentialDiscovered;
+ }
+ }
+ return processed;
+ }
+
+ private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier shortenToLastAugmentation(
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized) {
+ int position = 0;
+ int foundPosition = -1;
+ for (PathArgument arg : normalized.getPath()) {
+ position++;
+ if (arg instanceof AugmentationIdentifier) {
+ foundPosition = position;
+ }
+ }
+ if (foundPosition > 0) {
+ return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(normalized.getPath().subList(0,
+ foundPosition));
+ }
+ return null;
+ }
+
+ private InstanceIdentifier<? extends DataObject> shortenToLastAugment(
+ final InstanceIdentifier<? extends DataObject> binding) {
+ int position = 0;
+ int foundPosition = -1;
+ for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : binding.getPathArguments()) {
+ position++;
+ if (isAugmentation(arg.getType())) {
+ foundPosition = position;
+ }
+ }
+ return InstanceIdentifier.create(Iterables.limit(binding.getPathArguments(), foundPosition));
+ }
+
+ private org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toNormalizedImpl(
+ final InstanceIdentifier<? extends DataObject> binding) {
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier legacyPath = bindingToLegacy
+ .toDataDom(binding);
+ final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalized = legacyToNormalized
+ .toNormalized(legacyPath);
+ return normalized;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Iterable<Class<? extends DataObject>> getAugmentationChildren(final Class<?> targetType) {
+ List<Class<? extends DataObject>> ret = new LinkedList<>();
+ for (Method method : targetType.getMethods()) {
+ Class<?> entity = getYangModeledType(method);
+ if (entity != null) {
+ ret.add((Class<? extends DataObject>) entity);
+ }
+ }
+ return ret;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private Class<? extends DataObject> getYangModeledType(final Method method) {
+ if (method.getName().equals("getClass") || !method.getName().startsWith("get")
+ || method.getParameterTypes().length > 0) {
+ return null;
+ }
+
+ Class<?> returnType = method.getReturnType();
+ if (DataContainer.class.isAssignableFrom(returnType)) {
+ return (Class) returnType;
+ } else if (List.class.isAssignableFrom(returnType)) {
+ try {
+ return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(),
+ 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;
+ }
+
+ }
+ return null;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private static InstanceIdentifier<?> toWildcarded(final InstanceIdentifier<?> orig) {
+ List<org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument> wildArgs = new LinkedList<>();
+ for (org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : orig.getPathArguments()) {
+ wildArgs.add(new Item(arg.getType()));
+ }
+ return InstanceIdentifier.create(wildArgs);
+ }
+
+ private static boolean isAugmentation(final Class<? extends DataObject> type) {
+ return Augmentation.class.isAssignableFrom(type);
+ }
+
+ private static boolean isAugmentationIdentifier(final InstanceIdentifier<?> potential) {
+ return Augmentation.class.isAssignableFrom(potential.getTargetType());
+ }
+
+ private boolean isAugmentationIdentifier(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier processed) {
+ return Iterables.getLast(processed.getPath()) instanceof AugmentationIdentifier;
+ }
+
+ private static int getAugmentationCount(final InstanceIdentifier<?> potential) {
+ int count = 0;
+ for(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : potential.getPathArguments()) {
+ if(isAugmentation(arg.getType())) {
+ count++;
+ }
+
+ }
+ return count;
+ }
+
+ private static int getAugmentationCount(final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier potential) {
+ int count = 0;
+ for(PathArgument arg : potential.getPath()) {
+ if(arg instanceof AugmentationIdentifier) {
+ count++;
+ }
+ }
+ return count;
+ }