2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.transform;
10 import java.io.IOException;
11 import java.util.HashMap;
13 import java.util.function.Function;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.common.QNameModule;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
20 import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
21 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
24 * Stateless Normalized Node Stream Writer decorator, which performs QName translation.
27 * This class serves as base for Normalized Node Stream Writer decorators with option to transform
28 * QNames by user-implemented {@link #transform(QName)} function.
30 public abstract class QNameTransformingStreamWriter extends ForwardingNormalizedNodeStreamWriter {
32 // FIXME: Probably use loading cache to decrease memory
35 * Returns decorator, which uses supplied function to transform QNames.
37 * @param delegate Underlying normalized node stream writer
38 * @param transformation Transformation function, function is required to return non-null
40 * @return decorator, which uses supplied function to transform QNames.
42 public static NormalizedNodeStreamWriter fromFunction(final NormalizedNodeStreamWriter delegate,
43 final Function<QName, QName> transformation) {
44 return new QNameTransformingStreamWriter() {
47 protected NormalizedNodeStreamWriter delegate() {
52 protected QName transform(final QName key) {
53 return transformation.apply(key);
59 * Returns decorator, which uses supplied map to transform QNames. QNames not present in map are left unchanged.
61 * @param delegate Underlying normalized node stream writer
62 * @param mapping Immutable map which represent mapping from original to new values.
63 * @return decorator, which uses supplied mapping to transform QNames.
65 public static NormalizedNodeStreamWriter createQNameReplacing(final NormalizedNodeStreamWriter delegate,
66 final Map<QName, QName> mapping) {
67 return fromFunction(delegate, new QNameReplacementFunction(mapping));
71 * Returns decorator, which uses supplied map to transform QNameModules. QNameModules not present in map are left
74 * @param delegate Underlying normalized node stream writer
75 * @param mapping Immutable map which represent mapping from original to new values.
76 * @return decorator, which uses supplied mapping to transform QNameModules.
78 public static NormalizedNodeStreamWriter createQNameModuleReplacing(final NormalizedNodeStreamWriter delegate,
79 final Map<QNameModule, QNameModule> mapping) {
80 return fromFunction(delegate, new QNameModuleReplacementFunction(mapping));
84 public void startLeafNode(final NodeIdentifier name) throws IOException {
85 super.startLeafNode(transform(name));
89 public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
90 super.startLeafSet(transform(name), childSizeHint);
94 public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
95 super.startOrderedLeafSet(transform(name), childSizeHint);
99 public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
100 super.startLeafSetEntryNode(transform(name));
104 public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
105 super.startContainerNode(transform(name), childSizeHint);
109 public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IOException {
110 super.startUnkeyedList(transform(name), childSizeHint);
114 public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IOException {
115 super.startUnkeyedListItem(transform(name), childSizeHint);
119 public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
120 super.startMapNode(transform(name), childSizeHint);
124 public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint)
126 super.startMapEntryNode(transform(identifier), childSizeHint);
130 public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
131 super.startOrderedMapNode(transform(name), childSizeHint);
135 public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
136 super.startChoiceNode(transform(name), childSizeHint);
140 public boolean startAnyxmlNode(final NodeIdentifier name, final Class<?> objectModel) throws IOException {
141 return super.startAnyxmlNode(transform(name), objectModel);
145 public void scalarValue(final Object value) throws IOException {
146 // identityref leaf nodes contain identity QName as a value - it needs to be transformed
147 super.scalarValue(value instanceof QName ? transform((QName) value) : value);
151 * Transforms a QName to new mapping.
154 * NOTE: If QName should be unchanged implementation needs to return original QName.
156 * @param key QName to transform.
157 * @return Returns new value of QName.
159 protected abstract @NonNull QName transform(@NonNull QName key);
161 private NodeIdentifier transform(final NodeIdentifier name) {
162 final QName original = name.getNodeType();
163 final QName transformed = transform(original);
164 return transformed == original ? name : new NodeIdentifier(transformed);
167 private <T> NodeWithValue<T> transform(final NodeWithValue<T> name) {
168 final QName original = name.getNodeType();
169 final QName transformed = transform(original);
170 return transformed == original ? name : new NodeWithValue<>(transformed, name.getValue());
173 private NodeIdentifierWithPredicates transform(final NodeIdentifierWithPredicates identifier) {
174 Map<QName, Object> keyValues = new HashMap<>();
175 for (Map.Entry<QName, Object> original : identifier.entrySet()) {
176 keyValues.put(transform(original.getKey()), original.getValue());
178 return NodeIdentifierWithPredicates.of(transform(identifier.getNodeType()), keyValues);