Revert "Unify ORv1 and IIv5"
[yangtools.git] / data / yang-data-util / src / main / java / org / opendaylight / yangtools / yang / data / util / AbstractNodeDataWithSchema.java
1 /*
2  * Copyright (c) 2016 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.yang.data.util;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.collect.ImmutableMap;
15 import java.io.IOException;
16 import java.util.Objects;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
22 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.MetadataExtension;
23 import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.ContainerLike;
26 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
30
31 /**
32  * Utility abstract class for tracking parser state, as needed by StAX-like parser.
33  * This class is to be used only by respective XML and JSON parsers in yang-data-codec-xml and yang-data-codec-gson.
34  */
35 @Beta
36 public abstract sealed class AbstractNodeDataWithSchema<T extends DataSchemaNode>
37         permits SimpleNodeDataWithSchema, CompositeNodeDataWithSchema {
38     private final T schema;
39     private ImmutableMap<QName, Object> attributes;
40
41     AbstractNodeDataWithSchema(final T schema) {
42         this.schema = requireNonNull(schema);
43     }
44
45     public static @NonNull AbstractNodeDataWithSchema<?> of(final DataSchemaNode schema) {
46         return switch (schema) {
47             case AnyxmlSchemaNode anyxml -> new AnyXmlNodeDataWithSchema(anyxml);
48             case ContainerLike containerLike -> new ContainerNodeDataWithSchema(containerLike);
49             case LeafSchemaNode leaf -> new LeafNodeDataWithSchema(leaf);
50             case ListSchemaNode list -> new ListNodeDataWithSchema(list);
51             case LeafListSchemaNode leafList -> new LeafListNodeDataWithSchema(leafList);
52             case AnydataSchemaNode anydata -> new AnydataNodeDataWithSchema(anydata);
53             default -> throw new IllegalStateException("Unsupported schema " + schema);
54         };
55     }
56
57     /**
58      * Return the associated schema node.
59      *
60      * @return Associated schema node.
61      */
62     public final @NonNull T getSchema() {
63         return schema;
64     }
65
66     /**
67      * Set the associated attributes.
68      *
69      * @param attributes parsed attributes
70      */
71     public final void setAttributes(final ImmutableMap<QName, Object> attributes) {
72         checkState(this.attributes == null, "Node '%s' has already set its attributes to %s.", getSchema().getQName(),
73                 this.attributes);
74         this.attributes = attributes;
75     }
76
77     /**
78      * Return the associated attributes.
79      *
80      * @return associated attributes
81      */
82     public final ImmutableMap<QName, Object> getAttributes() {
83         return attributes;
84     }
85
86     /**
87      * Emit this node's events into the specified writer.
88      *
89      * @param writer Target writer
90      * @throws IOException reported when thrown by the writer.
91      */
92     public final void write(final NormalizedNodeStreamWriter writer) throws IOException {
93         write(writer, writer.extension(MetadataExtension.class));
94     }
95
96     protected abstract void write(NormalizedNodeStreamWriter writer, @Nullable MetadataExtension metaWriter)
97         throws IOException;
98
99     protected final NodeIdentifier provideNodeIdentifier() {
100         return NodeIdentifier.create(schema.getQName());
101     }
102
103     protected final void writeMetadata(final MetadataExtension metaWriter) throws IOException {
104         if (metaWriter != null && attributes != null && !attributes.isEmpty()) {
105             metaWriter.metadata(attributes);
106         }
107     }
108
109     @Override
110     public int hashCode() {
111         final int prime = 31;
112         int result = 1;
113         result = prime * result + Objects.hashCode(schema);
114         return result;
115     }
116
117     @Override
118     public boolean equals(final Object obj) {
119         if (this == obj) {
120             return true;
121         }
122         if (obj == null) {
123             return false;
124         }
125         if (getClass() != obj.getClass()) {
126             return false;
127         }
128         final var other = (AbstractNodeDataWithSchema<?>) obj;
129         return schema.equals(other.schema);
130     }
131
132 }