Merge "Incorrect name of elements in yang case nodes"
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / main / java / org / opendaylight / controller / md / sal / binding / impl / BindingToNormalizedNodeCodec.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.md.sal.binding.impl;
9
10 import com.google.common.base.Function;
11 import com.google.common.base.Optional;
12
13 import java.util.Iterator;
14 import java.util.Map.Entry;
15
16 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
17 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
18 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
19 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
20 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
21 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
25 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
26 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
27 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
28 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
30
31 public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable {
32
33     private final BindingIndependentMappingService bindingToLegacy;
34     private final BindingNormalizedNodeCodecRegistry codecRegistry;
35     private DataNormalizer legacyToNormalized;
36     private final GeneratedClassLoadingStrategy classLoadingStrategy;
37
38     public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, final BindingIndependentMappingService mappingService, final BindingNormalizedNodeCodecRegistry codecRegistry) {
39         super();
40         this.bindingToLegacy = mappingService;
41         this.classLoadingStrategy = classLoadingStrategy;
42         this.codecRegistry = codecRegistry;
43
44     }
45
46     public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toNormalized(
47             final InstanceIdentifier<? extends DataObject> binding) {
48         return codecRegistry.toYangInstanceIdentifier(binding);
49     }
50
51     @SuppressWarnings({ "unchecked", "rawtypes" })
52     public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
53             final InstanceIdentifier<? extends DataObject> bindingPath, final DataObject bindingObject) {
54         return codecRegistry.toNormalizedNode((InstanceIdentifier) bindingPath, bindingObject);
55
56     }
57
58     public Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
59             final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> binding) {
60         return toNormalizedNode(binding.getKey(),binding.getValue());
61     }
62
63     /**
64      *
65      * Returns a Binding-Aware instance identifier from normalized
66      * instance-identifier if it is possible to create representation.
67      *
68      * Returns Optional.absent for cases where target is mixin node except
69      * augmentation.
70      *
71      */
72     public Optional<InstanceIdentifier<? extends DataObject>> toBinding(
73             final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier normalized)
74                     throws DeserializationException {
75         try {
76             return  Optional.<InstanceIdentifier<? extends DataObject>>of(codecRegistry.fromYangInstanceIdentifier(normalized));
77         } catch (IllegalArgumentException e) {
78             return Optional.absent();
79         }
80     }
81
82     public DataNormalizer getDataNormalizer() {
83         return legacyToNormalized;
84     }
85
86     @SuppressWarnings("unchecked")
87     public Optional<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
88             final Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
89                     throws DeserializationException {
90         try {
91             @SuppressWarnings("rawtypes")
92             Entry binding = codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue());
93             return Optional.<Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject>>fromNullable(binding);
94         } catch (IllegalArgumentException e) {
95             return Optional.absent();
96         }
97     }
98
99     @Override
100     public void onGlobalContextUpdated(final SchemaContext arg0) {
101         legacyToNormalized = new DataNormalizer(arg0);
102         codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(classLoadingStrategy, arg0));
103     }
104
105     public <T extends DataObject> Function<Optional<NormalizedNode<?, ?>>, Optional<T>>  deserializeFunction(final InstanceIdentifier<T> path) {
106         return codecRegistry.deserializeFunction(path);
107     }
108
109     /**
110      * Returns an default object according to YANG schema for supplied path.
111      *
112      * @param path DOM Path
113      * @return Node with defaults set on.
114      */
115     public NormalizedNode<?, ?> getDefaultNodeFor(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path) {
116         Iterator<PathArgument> iterator = path.getPathArguments().iterator();
117         DataNormalizationOperation<?> currentOp = legacyToNormalized.getRootOperation();
118         while (iterator.hasNext()) {
119             PathArgument currentArg = iterator.next();
120             try {
121                 currentOp = currentOp.getChild(currentArg);
122             } catch (DataNormalizationException e) {
123                 throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
124             }
125         }
126         return currentOp.createDefault(path.getLastPathArgument());
127     }
128
129     public BindingIndependentMappingService getLegacy() {
130         return bindingToLegacy;
131     }
132
133     @Override
134     public void close() throws Exception {
135         // NOOP Intentionally
136     }
137 }