Use RevisionUnion in QNameModule
[yangtools.git] / common / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / QName.java
index 2c19fa9f0295263ad9a6f85f7eed1a7c7ce47e80..5a291d9f88339a19bd97544d5a395c59bbda1b04 100644 (file)
@@ -15,6 +15,7 @@ import com.google.common.collect.Interners;
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
+import java.io.Serial;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.regex.Matcher;
@@ -33,7 +34,7 @@ import org.eclipse.jdt.annotation.Nullable;
  * name, but from different schemas.
  *
  * <p>
- * The local name must conform to <a href="https://tools.ietf.org/html/rfc7950#section-6.2">RFC7950 Section 6.2</a>.
+ * The local name must conform to <a href="https://www.rfc-editor.org/rfc/rfc7950#section-6.2">RFC7950 Section 6.2</a>.
  *
  * <ul>
  * <li><b>XMLNamespace</b> - {@link #getNamespace()} - the namespace assigned to the YANG module which
@@ -45,33 +46,9 @@ import org.eclipse.jdt.annotation.Nullable;
  * </ul>
  */
 public final class QName extends AbstractQName implements Comparable<QName> {
-    /**
-     * A {@link DataInput} which has an understanding of {@link QName}'s semantics.
-     */
-    @Beta
-    public interface QNameAwareDataInput extends DataInput {
-        /**
-         * Read a {@link QName} from the stream.
-         *
-         * @return A QName
-         * @throws IOException if an I/O error occurs.
-         */
-        @NonNull QName readQName() throws IOException;
-    }
-
-    @Beta
-    public interface QNameAwareDataOutput extends DataOutput {
-        /**
-         * Write a {@link QName} into the stream.
-         *
-         * @param qname A QName
-         * @throws  IOException if an I/O error occurs.
-         */
-        void writeQName(@NonNull QName qname) throws IOException;
-    }
-
     private static final Interner<QName> INTERNER = Interners.newWeakInterner();
     // Note: 5398411242927766414L is used for versions < 3.0.0 without writeReplace
+    @Serial
     private static final long serialVersionUID = 1L;
 
     @Regex
@@ -99,7 +76,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      *            YANG schema identifier
      */
     private QName(final XMLNamespace namespace, final String localName) {
-        this(QNameModule.create(namespace), checkLocalName(localName));
+        this(QNameModule.of(namespace), checkLocalName(localName));
     }
 
     public static @NonNull QName create(final String input) {
@@ -146,7 +123,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      */
     public static @NonNull QName create(final XMLNamespace namespace, final @Nullable Revision revision,
             final String localName) {
-        return create(QNameModule.create(namespace, revision), localName);
+        return create(QNameModule.ofRevision(namespace, revision), localName);
     }
 
     /**
@@ -159,7 +136,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      */
     public static @NonNull QName create(final XMLNamespace namespace, final Optional<Revision> revision,
             final String localName) {
-        return create(QNameModule.create(namespace, revision), localName);
+        return create(QNameModule.ofRevision(namespace, revision.orElse(null)), localName);
     }
 
     /**
@@ -171,7 +148,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      * @return Instance of QName
      */
     public static @NonNull QName create(final String namespace, final String localName, final Revision revision) {
-        return create(QNameModule.create(XMLNamespace.of(namespace), revision), localName);
+        return create(QNameModule.of(XMLNamespace.of(namespace), revision), localName);
     }
 
     /**
@@ -186,7 +163,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      *         to {@code YYYY-mm-dd}.
      */
     public static @NonNull QName create(final String namespace, final String revision, final String localName) {
-        return create(XMLNamespace.of(namespace), Revision.of(revision), localName);
+        return create(QNameModule.ofRevision(namespace, revision), localName);
     }
 
     /**
@@ -223,11 +200,11 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      * @throws IOException if I/O error occurs
      */
     public static @NonNull QName readFrom(final DataInput in) throws IOException {
-        if (in instanceof QNameAwareDataInput) {
-            return ((QNameAwareDataInput) in).readQName();
+        if (in instanceof QNameAwareDataInput aware) {
+            return aware.readQName();
         }
 
-        final QNameModule module = QNameModule.readFrom(in);
+        final var module = QNameModule.readFrom(in);
         return new QName(module, checkLocalName(in.readUTF()));
     }
 
@@ -263,7 +240,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      * @return XMLNamespace assigned to the YANG module.
      */
     public @NonNull XMLNamespace getNamespace() {
-        return module.getNamespace();
+        return module.namespace();
     }
 
     /**
@@ -272,7 +249,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      * @return revision of the YANG module if the module has defined revision.
      */
     public @NonNull Optional<Revision> getRevision() {
-        return module.getRevision();
+        return module.findRevision();
     }
 
     @Override
@@ -306,14 +283,8 @@ public final class QName extends AbstractQName implements Comparable<QName> {
      */
     @Override
     public boolean equals(final Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof QName)) {
-            return false;
-        }
-        final QName other = (QName) obj;
-        return Objects.equals(getLocalName(), other.getLocalName()) && module.equals(other.module);
+        return this == obj || obj instanceof QName other && getLocalName().equals(other.getLocalName())
+            && module.equals(other.module);
     }
 
     @Override
@@ -321,7 +292,7 @@ public final class QName extends AbstractQName implements Comparable<QName> {
         final StringBuilder sb = new StringBuilder().append('(').append(getNamespace());
         final Optional<Revision> rev = getRevision();
         if (rev.isPresent()) {
-            sb.append("?revision=").append(rev.get());
+            sb.append("?revision=").append(rev.orElseThrow());
         }
         return sb.append(')').append(getLocalName()).toString();
     }
@@ -371,23 +342,17 @@ public final class QName extends AbstractQName implements Comparable<QName> {
         return getLocalName().equals(other.getLocalName()) && Objects.equals(getNamespace(), other.getNamespace());
     }
 
-    // FIXME: this comparison function looks odd. We are sorting first by local name and then by module? What is
-    //        the impact on iteration order of SortedMap<QName, ?>?
     @Override
     @SuppressWarnings("checkstyle:parameterName")
     public int compareTo(final QName o) {
-        // compare mandatory localName parameter
-        int result = getLocalName().compareTo(o.getLocalName());
-        if (result != 0) {
-            return result;
-        }
-        return module.compareTo(o.module);
+        final int result = module.compareTo(o.module);
+        return result != 0 ? result : getLocalName().compareTo(o.getLocalName());
     }
 
     @Override
     public void writeTo(final DataOutput out) throws IOException {
-        if (out instanceof QNameAwareDataOutput) {
-            ((QNameAwareDataOutput) out).writeQName(this);
+        if (out instanceof QNameAwareDataOutput aware) {
+            aware.writeQName(this);
         } else {
             module.writeTo(out);
             out.writeUTF(getLocalName());