Merge "Simplify YangInstanceIdentifier references"
[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;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
26 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
27 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
28 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
31
32 public class BindingToNormalizedNodeCodec implements SchemaContextListener,AutoCloseable {
33
34     private final BindingIndependentMappingService bindingToLegacy;
35     private final BindingNormalizedNodeCodecRegistry codecRegistry;
36     private DataNormalizer legacyToNormalized;
37     private final GeneratedClassLoadingStrategy classLoadingStrategy;
38
39     public BindingToNormalizedNodeCodec(final GeneratedClassLoadingStrategy classLoadingStrategy, final BindingIndependentMappingService mappingService, final BindingNormalizedNodeCodecRegistry codecRegistry) {
40         super();
41         this.bindingToLegacy = mappingService;
42         this.classLoadingStrategy = classLoadingStrategy;
43         this.codecRegistry = codecRegistry;
44
45     }
46
47     public YangInstanceIdentifier toNormalized(final InstanceIdentifier<? extends DataObject> binding) {
48         return codecRegistry.toYangInstanceIdentifier(binding);
49     }
50
51     @SuppressWarnings({ "unchecked", "rawtypes" })
52     public Entry<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<YangInstanceIdentifier, NormalizedNode<?, ?>> toNormalizedNode(
59             final Entry<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(final YangInstanceIdentifier normalized)
73                     throws DeserializationException {
74         try {
75             return Optional.<InstanceIdentifier<? extends DataObject>>of(codecRegistry.fromYangInstanceIdentifier(normalized));
76         } catch (IllegalArgumentException e) {
77             return Optional.absent();
78         }
79     }
80
81     public DataNormalizer getDataNormalizer() {
82         return legacyToNormalized;
83     }
84
85     @SuppressWarnings("unchecked")
86     public Optional<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> toBinding(
87             final Entry<YangInstanceIdentifier, ? extends NormalizedNode<?, ?>> normalized)
88                     throws DeserializationException {
89         try {
90             @SuppressWarnings("rawtypes")
91             Entry binding = codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue());
92             return Optional.<Entry<InstanceIdentifier<? extends DataObject>, DataObject>>fromNullable(binding);
93         } catch (IllegalArgumentException e) {
94             return Optional.absent();
95         }
96     }
97
98     @Override
99     public void onGlobalContextUpdated(final SchemaContext arg0) {
100         legacyToNormalized = new DataNormalizer(arg0);
101         codecRegistry.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(classLoadingStrategy, arg0));
102     }
103
104     public <T extends DataObject> Function<Optional<NormalizedNode<?, ?>>, Optional<T>>  deserializeFunction(final InstanceIdentifier<T> path) {
105         return codecRegistry.deserializeFunction(path);
106     }
107
108     /**
109      * Returns an default object according to YANG schema for supplied path.
110      *
111      * @param path DOM Path
112      * @return Node with defaults set on.
113      */
114     public NormalizedNode<?, ?> getDefaultNodeFor(final YangInstanceIdentifier path) {
115         Iterator<PathArgument> iterator = path.getPathArguments().iterator();
116         DataNormalizationOperation<?> currentOp = legacyToNormalized.getRootOperation();
117         while (iterator.hasNext()) {
118             PathArgument currentArg = iterator.next();
119             try {
120                 currentOp = currentOp.getChild(currentArg);
121             } catch (DataNormalizationException e) {
122                 throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e);
123             }
124         }
125         return currentOp.createDefault(path.getLastPathArgument());
126     }
127
128     public BindingIndependentMappingService getLegacy() {
129         return bindingToLegacy;
130     }
131
132     @Override
133     public void close() throws Exception {
134         // NOOP Intentionally
135     }
136 }