Define a feature-parent
[yangtools.git] / common / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / XMLNamespace.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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.common;
9
10 import static com.google.common.base.Verify.verifyNotNull;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.collect.Interner;
14 import com.google.common.collect.Interners;
15 import java.io.DataInput;
16 import java.io.DataOutput;
17 import java.io.IOException;
18 import java.io.ObjectInputStream;
19 import java.io.ObjectOutputStream;
20 import java.io.ObjectStreamException;
21 import java.io.Serial;
22 import java.io.Serializable;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.opendaylight.yangtools.concepts.Immutable;
28 import org.opendaylight.yangtools.concepts.WritableObject;
29
30 /**
31  * A simple type capture of {@code namespace} statement's argument according to
32  * <a href="https://www.rfc-editor.org/rfc/rfc6020#section-7.1.3">RFC6020</a>.
33  */
34 @NonNullByDefault
35 public final class XMLNamespace implements Comparable<XMLNamespace>, Immutable, Serializable, WritableObject {
36     @java.io.Serial
37     private static final long serialVersionUID = 1L;
38     private static final Interner<XMLNamespace> INTERNER = Interners.newWeakInterner();
39
40     private final String namespace;
41
42     private XMLNamespace(final String namespace) {
43         this.namespace = requireNonNull(namespace);
44     }
45
46     // FIXME: add documentation
47     public static XMLNamespace of(final String namespace) {
48         try {
49             // FIXME: we want this validation, can we get it without the object allocation?
50             verifyNotNull(new URI(namespace));
51         } catch (final URISyntaxException e) {
52             throw new IllegalArgumentException("Namespace '" + namespace + "' is not a valid URI", e);
53         }
54
55         return new XMLNamespace(namespace);
56     }
57
58     /**
59      * Return an interned reference to a equivalent XMLNamespace.
60      *
61      * @return Interned reference, or this object if it was interned.
62      */
63     public XMLNamespace intern() {
64         return INTERNER.intern(this);
65     }
66
67     @Override
68     @SuppressWarnings("checkstyle:parameterName")
69     public int compareTo(final XMLNamespace o) {
70         return namespace.compareTo(o.namespace);
71     }
72
73     @Override
74     public void writeTo(final DataOutput out) throws IOException {
75         out.writeUTF(namespace);
76     }
77
78     public static XMLNamespace readFrom(final DataInput in) throws IOException {
79         try {
80             return of(in.readUTF());
81         } catch (IllegalArgumentException e) {
82             throw new IOException("Invalid namespace", e);
83         }
84     }
85
86     @Override
87     public int hashCode() {
88         return namespace.hashCode();
89     }
90
91     @Override
92     public boolean equals(final @Nullable Object obj) {
93         return this == obj || obj instanceof XMLNamespace other && namespace.equals(other.namespace);
94     }
95
96     @Override
97     public String toString() {
98         return namespace;
99     }
100
101     @Serial
102     Object writeReplace() {
103         return new XNv1(this);
104     }
105
106     @java.io.Serial
107     private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
108         Revision.throwNSE();
109     }
110
111     @java.io.Serial
112     private void readObjectNoData() throws ObjectStreamException {
113         Revision.throwNSE();
114     }
115
116     @java.io.Serial
117     private void writeObject(final ObjectOutputStream stream) throws IOException {
118         Revision.throwNSE();
119     }
120 }