Merge "BUG-576: modified parser to handle refinement of extension instances."
[yangtools.git] / code-generator / binding-data-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / BindingNormalizedNodeCodecRegistry.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.yangtools.binding.data.codec.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.cache.CacheBuilder;
12 import com.google.common.cache.CacheLoader;
13 import com.google.common.cache.LoadingCache;
14
15 import java.util.AbstractMap.SimpleEntry;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Map.Entry;
20
21 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
22 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeWriterFactory;
23 import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
24 import org.opendaylight.yangtools.concepts.Delegator;
25 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
26 import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
27 import org.opendaylight.yangtools.yang.binding.DataObject;
28 import org.opendaylight.yangtools.yang.binding.DataObjectSerializer;
29 import org.opendaylight.yangtools.yang.binding.DataObjectSerializerImplementation;
30 import org.opendaylight.yangtools.yang.binding.DataObjectSerializerRegistry;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
35 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
36 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
37
38 public class BindingNormalizedNodeCodecRegistry implements DataObjectSerializerRegistry, BindingNormalizedNodeWriterFactory, BindingNormalizedNodeSerializer {
39
40     private final DataObjectSerializerGenerator generator;
41     private final LoadingCache<Class<? extends DataObject>, DataObjectSerializer> serializers;
42     private BindingCodecContext codecContext;
43
44     public BindingNormalizedNodeCodecRegistry(final DataObjectSerializerGenerator generator) {
45         this.generator = Preconditions.checkNotNull(generator);
46         this.serializers = CacheBuilder.newBuilder().weakKeys().build(new GeneratorLoader());
47     }
48
49     @Override
50     public DataObjectSerializer getSerializer(final Class<? extends DataObject> type) {
51         return serializers.getUnchecked(type);
52     }
53
54     public BindingCodecContext getCodecContext() {
55         return codecContext;
56     }
57
58     public void onBindingRuntimeContextUpdated(final BindingRuntimeContext context) {
59         codecContext = new BindingCodecContext(context);
60         generator.onBindingRuntimeContextUpdated(context);
61     }
62
63
64     @Override
65     public YangInstanceIdentifier toYangInstanceIdentifier(final InstanceIdentifier<?> binding) {
66         List<YangInstanceIdentifier.PathArgument> builder = new LinkedList<>();
67         codecContext.getCodecContextNode(binding, builder);
68         return codecContext.getInstanceIdentifierCodec().serialize(binding);
69     }
70
71     @Override
72     public InstanceIdentifier<?> fromYangInstanceIdentifier(final YangInstanceIdentifier dom) {
73         return codecContext.getInstanceIdentifierCodec().deserialize(dom);
74    }
75
76     @Override
77     public <T extends DataObject> Entry<YangInstanceIdentifier,NormalizedNode<?,?>> toNormalizedNode(final InstanceIdentifier<T> path, final T data) {
78         NormalizedNodeResult result = new NormalizedNodeResult();
79         // We create dom stream writer which produces normalized nodes
80         NormalizedNodeStreamWriter domWriter = ImmutableNormalizedNodeStreamWriter.from(result);
81
82         // We create Binding Stream Writer wchich translates from Binding to Normalized Nodes
83         Entry<YangInstanceIdentifier, BindingStreamEventWriter> writeCtx = codecContext.newWriter(path, domWriter);
84
85         // We get serializer which reads binding data and uses Binding To NOrmalized Node writer to write result
86         getSerializer(path.getTargetType()).serialize(data, writeCtx.getValue());
87         return new SimpleEntry<YangInstanceIdentifier,NormalizedNode<?,?>>(writeCtx.getKey(),result.getResult());
88     }
89
90     @Override
91     public Entry<InstanceIdentifier<?>, DataObject> fromNormalizedNode(final YangInstanceIdentifier path,
92             final NormalizedNode<?, ?> data) {
93         throw new UnsupportedOperationException("Not implemented yet");
94     }
95
96     @Override
97     public Map<InstanceIdentifier<?>, DataObject> fromNormalizedNodes(
98             final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> dom) {
99         throw new UnsupportedOperationException("Not implemented yet");
100     }
101
102     @Override
103     public Entry<YangInstanceIdentifier, BindingStreamEventWriter> newWriterAndIdentifier(final InstanceIdentifier<?> path, final NormalizedNodeStreamWriter domWriter) {
104         return codecContext.newWriter(path, domWriter);
105     }
106
107     @Override
108     public BindingStreamEventWriter newWriter(final InstanceIdentifier<?> path, final NormalizedNodeStreamWriter domWriter) {
109         return codecContext.newWriterWithoutIdentifier(path, domWriter);
110     }
111
112     private class GeneratorLoader extends CacheLoader<Class<? extends DataObject>, DataObjectSerializer> {
113
114         @Override
115         public DataObjectSerializer load(final Class<? extends DataObject> key) throws Exception {
116             DataObjectSerializerImplementation prototype = generator.getSerializer(key);
117             return new DataObjectSerializerProxy(prototype);
118         }
119     }
120
121     private class DataObjectSerializerProxy implements DataObjectSerializer,
122             Delegator<DataObjectSerializerImplementation> {
123
124         private final DataObjectSerializerImplementation delegate;
125
126         DataObjectSerializerProxy(final DataObjectSerializerImplementation delegate) {
127             this.delegate = delegate;
128         }
129
130         @Override
131         public DataObjectSerializerImplementation getDelegate() {
132             return delegate;
133         }
134
135         @Override
136         public void serialize(final DataObject obj, final BindingStreamEventWriter stream) {
137             delegate.serialize(BindingNormalizedNodeCodecRegistry.this, obj, stream);
138         }
139     }
140
141 }