2 * Copyright (c) 2016, 2020 PANTHEON.tech, s.r.o. 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.rfc6643.model.api;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import com.google.common.annotations.Beta;
13 import java.io.DataInput;
14 import java.io.DataOutput;
15 import java.io.IOException;
16 import java.util.Arrays;
17 import java.util.regex.Pattern;
18 import java.util.stream.IntStream;
19 import org.checkerframework.checker.regex.qual.Regex;
20 import org.opendaylight.yangtools.concepts.Identifier;
21 import org.opendaylight.yangtools.concepts.WritableObject;
22 import org.opendaylight.yangtools.yang.common.Uint32;
25 * An OID, or ObjectIdentifier, as defined by ITU and ISO/IEC.
27 // TODO: this class could also be Comparable<ObjectIdentifier>
29 public final class ObjectIdentifier implements Identifier, WritableObject {
30 private static final long serialVersionUID = 1L;
32 private static final String CHECK_OID_REGEX = "^\\d+(\\.\\d+)*$";
33 private static final Pattern CHECK_OID_PATTERN = Pattern.compile(CHECK_OID_REGEX);
34 private static final Pattern SPLIT_PATTERN = Pattern.compile(".", Pattern.LITERAL);
36 private final int[] subIdentifiers;
38 private ObjectIdentifier(final int[] subIdentifiers) {
39 this.subIdentifiers = subIdentifiers;
43 * Create an {@link ObjectIdentifier} from its integer components. Each sub-identifier is interpreted as an unsigned
46 * @param subIdentifiers OID sub-identifiers
47 * @return An ObjectIdentifier.
49 public static ObjectIdentifier of(final int... subIdentifiers) {
50 return new ObjectIdentifier(subIdentifiers.clone());
54 * Create an {@link ObjectIdentifier} from its string representation.
56 * @param str String OID representation.
57 * @return An ObjectIdentifier.
59 public static ObjectIdentifier forString(final String str) {
60 return new ObjectIdentifier(parseObjectId(str));
63 public int[] getSubIdentifiers() {
64 // Always make a defensive copy
65 return subIdentifiers.clone();
68 public IntStream streamSubIdentifiers() {
69 return Arrays.stream(subIdentifiers);
73 * Read an {@link ObjectIdentifier} from a DataInput, performing the inverse of {@link #writeTo(DataOutput)}. For
74 * details see {@link WritableObject}.
76 * @param in Data input
77 * @return Object identifier
78 * @throws IOException If an I/O error is reported
80 public static ObjectIdentifier readFrom(final DataInput in) throws IOException {
81 final int count = in.readUnsignedByte();
82 checkArgument(count >= 0 && count <= 128, "Illegal item count %s", count);
84 final int[] oid = new int[count];
85 for (int index = 0; index < count; ++index) {
86 oid[index] = in.readInt();
89 return new ObjectIdentifier(oid);
93 public void writeTo(final DataOutput out) throws IOException {
94 out.writeByte(subIdentifiers.length);
95 for (int i : subIdentifiers) {
101 public int hashCode() {
102 return Arrays.hashCode(subIdentifiers);
106 public boolean equals(final Object obj) {
107 return this == obj || obj instanceof ObjectIdentifier
108 && Arrays.equals(subIdentifiers, ((ObjectIdentifier) obj).subIdentifiers);
112 public String toString() {
113 StringBuilder stringBuilder = new StringBuilder();
114 stringBuilder.append(subIdentifiers[0]);
115 for (int index = 1; index < subIdentifiers.length; index++) {
116 stringBuilder.append('.').append(subIdentifiers[index]);
118 return stringBuilder.toString();
121 private static int[] parseObjectId(final String objectId) {
122 checkArgument(CHECK_OID_PATTERN.matcher(objectId).matches(), "Wrong format for OID: '%s'", objectId);
124 final String[] splitOid = SPLIT_PATTERN.split(objectId);
125 checkArgument(splitOid.length <= 128, "Object Identifier can have at most 128 sub-identifiers");
127 final int[] oid = new int[splitOid.length];
128 for (int index = 0; index < splitOid.length; index ++) {
129 oid[index] = Uint32.valueOf(splitOid[index]).intValue();