Rename binding-runtime-dynamic to binding-loader
[yangtools.git] / common / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / CanonicalValueViolation.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, 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 java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.base.MoreObjects;
14 import com.google.common.base.MoreObjects.ToStringHelper;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.io.Serial;
17 import java.io.Serializable;
18 import java.util.Objects;
19 import java.util.Optional;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.yangtools.concepts.Either;
23 import org.opendaylight.yangtools.concepts.Immutable;
24
25 /**
26  * A violation of a {@link CanonicalValue} validation. Contains details as mandated by RFC7950 Section 8.3.1.
27  *
28  * @author Robert Varga
29  */
30 @Beta
31 @NonNullByDefault
32 public abstract class CanonicalValueViolation implements Immutable, Serializable {
33     public static class Regular extends CanonicalValueViolation {
34         @Serial
35         private static final long serialVersionUID = 1L;
36
37         private final @Nullable String appTag;
38         private final @Nullable String message;
39
40         Regular(final @Nullable String appTag, final @Nullable String message) {
41             this.appTag = appTag;
42             this.message = message;
43         }
44
45         @Override
46         @Nullable String appTag() {
47             return appTag;
48         }
49
50         @Override
51         @Nullable String message() {
52             return message;
53         }
54
55         @Override
56         ToStringHelper addToString(final ToStringHelper helper) {
57             return helper.omitNullValues().add("app-tag", appTag).add("message", message);
58         }
59     }
60
61     @SuppressFBWarnings("NM_CLASS_NOT_EXCEPTION")
62     public static class WithException extends CanonicalValueViolation {
63         @Serial
64         private static final long serialVersionUID = 1L;
65
66         private final Exception cause;
67
68         WithException(final Exception cause) {
69             this.cause = requireNonNull(cause);
70         }
71
72         @Override
73         @Nullable String appTag() {
74             return null;
75         }
76
77         @Override
78         @Nullable String message() {
79             return cause.getMessage();
80         }
81
82         public final Exception getCause() {
83             return cause;
84         }
85
86         @Override
87         ToStringHelper addToString(final ToStringHelper helper) {
88             return helper.add("cause", cause);
89         }
90     }
91
92     private static final CanonicalValueViolation EMPTY = new Regular(null, null);
93     private static final Either<?, CanonicalValueViolation> EMPTY_VARIANT = Either.ofSecond(EMPTY);
94     @Serial
95     private static final long serialVersionUID = 1L;
96
97     public static CanonicalValueViolation empty() {
98         return EMPTY;
99     }
100
101     public static CanonicalValueViolation of(final Exception cause) {
102         return new WithException(cause);
103     }
104
105     public static CanonicalValueViolation of(final @Nullable String appTag, final @Nullable String message) {
106         return appTag == null && message == null ? EMPTY : new Regular(appTag, message);
107     }
108
109     @SuppressWarnings("unchecked")
110     public static <T> Either<T, CanonicalValueViolation> emptyVariant() {
111         return (Either<T, CanonicalValueViolation>) EMPTY_VARIANT;
112     }
113
114     public static <T> Either<T, CanonicalValueViolation> variantOf(final Exception cause) {
115         return Either.ofSecond(CanonicalValueViolation.of(cause));
116     }
117
118     public static <T> Either<T, CanonicalValueViolation> variantOf(final String message) {
119         return variantOf(null, message);
120     }
121
122     public static <T> Either<T, CanonicalValueViolation> variantOf(final @Nullable String appTag,
123             final String message) {
124         return Either.ofSecond(CanonicalValueViolation.of(appTag, message));
125     }
126
127     public final Optional<String> getAppTag() {
128         return nullableString(appTag());
129     }
130
131     public final Optional<String> getMessage() {
132         return nullableString(message());
133     }
134
135     abstract @Nullable String appTag();
136
137     abstract @Nullable String message();
138
139     @Override
140     public final int hashCode() {
141         return Objects.hash(appTag(), message());
142     }
143
144     @Override
145     public final boolean equals(final @Nullable Object obj) {
146         return this == obj || obj instanceof CanonicalValueViolation other
147             && Objects.equals(appTag(), other.appTag()) && Objects.equals(message(), other.message());
148     }
149
150     @Override
151     public final String toString() {
152         return addToString(MoreObjects.toStringHelper(this)).toString();
153     }
154
155     abstract ToStringHelper addToString(ToStringHelper helper);
156
157     private static Optional<String> nullableString(@Nullable final String str) {
158         return str != null ? Optional.of(str) : Optional.empty();
159     }
160 }