2 * Copyright (c) 2014 Brocade Communications Systems, Inc. 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.yang.common;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.util.concurrent.FluentFuture;
14 import com.google.common.util.concurrent.Futures;
15 import java.io.Serializable;
16 import java.util.Collection;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.concepts.Builder;
19 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
20 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
23 * A builder for creating RpcResult instances.
25 * @author Thomas Pantelis
27 * @param <T> the result value type
29 public final class RpcResultBuilder<T> implements Builder<RpcResult<T>> {
31 private static class RpcResultImpl<T> implements RpcResult<T>, Serializable {
32 private static final long serialVersionUID = 1L;
34 private final ImmutableList<RpcError> errors;
35 private final T result;
36 private final boolean successful;
38 RpcResultImpl(final boolean successful, final T result, final ImmutableList<RpcError> errors) {
39 this.successful = successful;
41 this.errors = requireNonNull(errors);
45 public ImmutableList<RpcError> getErrors() {
50 public T getResult() {
55 public boolean isSuccessful() {
60 public String toString() {
61 return "RpcResult [successful=" + successful + ", result="
62 + result + ", errors=" + errors + "]";
66 private static class RpcErrorImpl implements RpcError, Serializable {
67 private static final long serialVersionUID = 1L;
69 private final String applicationTag;
70 private final String tag;
71 private final String info;
72 private final ErrorSeverity severity;
73 private final String message;
74 private final ErrorType errorType;
75 private final Throwable cause;
77 RpcErrorImpl(final ErrorSeverity severity, final ErrorType errorType,
78 final String tag, final String message, final String applicationTag, final String info,
79 final Throwable cause) {
80 this.severity = severity;
81 this.errorType = errorType;
83 this.message = message;
84 this.applicationTag = applicationTag;
90 public String getApplicationTag() {
91 return applicationTag;
95 public String getTag() {
100 public String getInfo() {
105 public ErrorSeverity getSeverity() {
110 public String getMessage() {
115 public ErrorType getErrorType() {
120 public Throwable getCause() {
125 public String toString() {
126 return "RpcError [message=" + message + ", severity="
127 + severity + ", errorType=" + errorType + ", tag=" + tag
128 + ", applicationTag=" + applicationTag + ", info=" + info
129 + ", cause=" + cause + "]";
133 private ImmutableList.Builder<RpcError> errors;
135 private final boolean successful;
137 private RpcResultBuilder(final boolean successful, final T result) {
138 this.successful = successful;
139 this.result = result;
143 * Returns a builder for a successful result.
145 public static <T> @NonNull RpcResultBuilder<T> success() {
146 return new RpcResultBuilder<>(true, null);
150 * Returns a builder for a successful result.
152 * @param result the result value
154 public static <T> @NonNull RpcResultBuilder<T> success(final T result) {
155 return new RpcResultBuilder<>(true, result);
159 * Returns a builder for a successful result.
161 * @param builder builder for the result value
163 public static <T> @NonNull RpcResultBuilder<T> success(final Builder<T> builder) {
164 return success(builder.build());
168 * Returns a builder for a failed result.
170 public static <T> @NonNull RpcResultBuilder<T> failed() {
171 return new RpcResultBuilder<>(false, null);
175 * Returns a builder based on the given status.
177 * @param success true if successful, false otherwise.
179 public static <T> @NonNull RpcResultBuilder<T> status(final boolean success) {
180 return new RpcResultBuilder<>(success, null);
184 * Returns a builder from another RpcResult.
186 * @param other the other RpcResult.
188 public static <T> @NonNull RpcResultBuilder<T> from(final RpcResult<T> other) {
189 return new RpcResultBuilder<>(other.isSuccessful(), other.getResult())
190 .withRpcErrors(other.getErrors());
194 * Creates an RpcError with severity ERROR for reuse.
196 * @param errorType the conceptual layer at which the error occurred.
197 * @param tag a short string that identifies the general type of error condition. See
198 * {@link RpcError#getTag} for a list of suggested values.
199 * @param message a string suitable for human display that describes the error condition.
201 * @return an RpcError
203 public static @NonNull RpcError newError(final ErrorType errorType, final String tag, final String message) {
204 return new RpcErrorImpl(ErrorSeverity.ERROR, errorType,
205 tag != null ? tag : "operation-failed", message, null, null, null);
209 * Creates an RpcError with severity ERROR for reuse.
211 * @param errorType the conceptual layer at which the error occurred.
212 * @param tag a short string that identifies the general type of error condition. See
213 * {@link RpcError#getTag} for a list of suggested values.
214 * @param message a string suitable for human display that describes the error condition.
215 * @param applicationTag a short string that identifies the specific type of error condition.
216 * @param info a string containing additional information to provide extended
217 * and/or implementation-specific debugging information.
218 * @param cause the exception that triggered the error.
220 * @return an RpcError
222 public static @NonNull RpcError newError(final ErrorType errorType, final String tag, final String message,
223 final String applicationTag, final String info, final Throwable cause) {
224 return new RpcErrorImpl(ErrorSeverity.ERROR, errorType,
225 tag != null ? tag : "operation-failed", message, applicationTag, info, cause);
229 * Creates an RpcError with severity WARNING for reuse.
231 * @param errorType the conceptual layer at which the warning occurred.
232 * @param tag a short string that identifies the general type of warning condition. See
233 * {@link RpcError#getTag} for a list of suggested values.
234 * @param message a string suitable for human display that describes the warning condition.
236 * @return an RpcError
238 public static @NonNull RpcError newWarning(final ErrorType errorType, final String tag, final String message) {
239 return new RpcErrorImpl(ErrorSeverity.WARNING, errorType, tag, message, null, null, null);
243 * Creates an RpcError with severity WARNING for reuse.
245 * @param errorType the conceptual layer at which the warning occurred.
246 * @param tag a short string that identifies the general type of warning condition. See
247 * {@link RpcError#getTag} for a list of suggested values.
248 * @param message a string suitable for human display that describes the warning condition.
249 * @param applicationTag a short string that identifies the specific type of warning condition.
250 * @param info a string containing additional information to provide extended
251 * and/or implementation-specific debugging information.
252 * @param cause the exception that triggered the warning.
254 * @return an RpcError
256 public static @NonNull RpcError newWarning(final ErrorType errorType, final String tag, final String message,
257 final String applicationTag, final String info, final Throwable cause) {
258 return new RpcErrorImpl(ErrorSeverity.WARNING, errorType, tag, message,
259 applicationTag, info, cause);
263 * Sets the value of the result.
265 * @param result the result value
267 @SuppressWarnings("checkstyle:hiddenField")
268 public @NonNull RpcResultBuilder<T> withResult(final T result) {
269 this.result = result;
274 * Sets the value of the result.
276 * @param builder builder for the result value
278 public @NonNull RpcResultBuilder<T> withResult(final Builder<T> builder) {
279 return withResult(builder.build());
282 private void addError(final ErrorSeverity severity, final ErrorType errorType,
283 final String tag, final String message, final String applicationTag, final String info,
284 final Throwable cause) {
286 addError(new RpcErrorImpl(severity, errorType,
287 tag != null ? tag : "operation-failed", message,
288 applicationTag, info, cause));
291 private void addError(final RpcError error) {
293 if (errors == null) {
294 errors = new ImmutableList.Builder<>();
301 * Adds a warning to the result.
303 * @param errorType the conceptual layer at which the warning occurred.
304 * @param tag a short string that identifies the general type of warning condition. See
305 * {@link RpcError#getTag} for a list of suggested values.
306 * @param message a string suitable for human display that describes the warning condition.
308 public @NonNull RpcResultBuilder<T> withWarning(final ErrorType errorType, final String tag, final String message) {
309 addError(ErrorSeverity.WARNING, errorType, tag, message, null, null, null);
314 * Adds a warning to the result.
316 * @param errorType the conceptual layer at which the warning occurred.
317 * @param tag a short string that identifies the general type of warning condition. See
318 * {@link RpcError#getTag} for a list of suggested values.
319 * @param message a string suitable for human display that describes the warning condition.
320 * @param applicationTag a short string that identifies the specific type of warning condition.
321 * @param info a string containing additional information to provide extended
322 * and/or implementation-specific debugging information.
323 * @param cause the exception that triggered the warning.
325 public @NonNull RpcResultBuilder<T> withWarning(final ErrorType errorType, final String tag, final String message,
326 final String applicationTag, final String info, final Throwable cause) {
327 addError(ErrorSeverity.WARNING, errorType, tag, message, applicationTag, info, cause);
332 * Adds an error to the result. The general error tag defaults to "operation-failed".
334 * @param errorType the conceptual layer at which the error occurred.
335 * @param message a string suitable for human display that describes the error condition.
337 public @NonNull RpcResultBuilder<T> withError(final ErrorType errorType, final String message) {
338 addError(ErrorSeverity.ERROR, errorType, null, message, null, null, null);
343 * Adds an error to the result.
345 * @param errorType the conceptual layer at which the error occurred.
346 * @param tag a short string that identifies the general type of error condition. See
347 * {@link RpcError#getTag} for a list of suggested values.
348 * @param message a string suitable for human display that describes the error condition.
350 public @NonNull RpcResultBuilder<T> withError(final ErrorType errorType, final String tag, final String message) {
351 addError(ErrorSeverity.ERROR, errorType, tag, message, null, null, null);
356 * Adds an error to the result. The general error tag defaults to "operation-failed".
358 * @param errorType the conceptual layer at which the error occurred.
359 * @param message a string suitable for human display that describes the error condition.
360 * @param cause the exception that triggered the error.
362 public @NonNull RpcResultBuilder<T> withError(final ErrorType errorType, final String message,
363 final Throwable cause) {
364 addError(ErrorSeverity.ERROR, errorType, null, message, null, null, cause);
369 * Adds an error to the result.
371 * @param errorType the conceptual layer at which the error occurred.
372 * @param tag a short string that identifies the general type of error condition. See
373 * {@link RpcError#getTag} for a list of suggested values.
374 * @param message a string suitable for human display that describes the error condition.
375 * @param applicationTag a short string that identifies the specific type of error condition.
376 * @param info a string containing additional information to provide extended
377 * and/or implementation-specific debugging information.
378 * @param cause the exception that triggered the error.
380 public @NonNull RpcResultBuilder<T> withError(final ErrorType errorType, final String tag, final String message,
381 final String applicationTag, final String info, final Throwable cause) {
382 addError(ErrorSeverity.ERROR, errorType, tag, message, applicationTag, info, cause);
389 * @param error the RpcError
391 public @NonNull RpcResultBuilder<T> withRpcError(final RpcError error) {
399 * @param rpcErrors the list of RpcErrors
401 public RpcResultBuilder<T> withRpcErrors(final Collection<? extends RpcError> rpcErrors) {
402 if (rpcErrors != null) {
403 for (RpcError error : rpcErrors) {
411 public RpcResult<T> build() {
412 return new RpcResultImpl<>(successful, result, errors != null ? errors.build() : ImmutableList.of());
416 * Builds RpcResult and wraps it in a Future.
419 * This is a convenience method to assist those writing RPCs that produce immediate results. It allows you to
420 * replace {@code FluentFuture.from(Futures.immediateFuture(rpcResult.build()))} with
421 * {@code rpcResult.buildFuture()}
423 * @return Future for RpcResult built by RpcResultBuilder
425 public @NonNull FluentFuture<RpcResult<T>> buildFuture() {
426 return FluentFuture.from(Futures.immediateFuture(build()));