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 com.google.common.collect.ImmutableList;
11 import com.google.common.util.concurrent.FluentFuture;
12 import com.google.common.util.concurrent.Futures;
13 import java.io.Serializable;
14 import java.util.Collection;
15 import org.opendaylight.yangtools.concepts.Builder;
16 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
17 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
20 * A builder for creating RpcResult instances.
22 * @author Thomas Pantelis
24 * @param <T> the result value type
26 public final class RpcResultBuilder<T> implements Builder<RpcResult<T>> {
28 private static class RpcResultImpl<T> implements RpcResult<T>, Serializable {
29 private static final long serialVersionUID = 1L;
31 private final Collection<RpcError> errors;
32 private final T result;
33 private final boolean successful;
35 RpcResultImpl(final boolean successful, final T result,
36 final Collection<RpcError> errors) {
37 this.successful = successful;
43 public Collection<RpcError> getErrors() {
48 public T getResult() {
53 public boolean isSuccessful() {
58 public String toString() {
59 return "RpcResult [successful=" + successful + ", result="
60 + result + ", errors=" + errors + "]";
64 private static class RpcErrorImpl implements RpcError, Serializable {
65 private static final long serialVersionUID = 1L;
67 private final String applicationTag;
68 private final String tag;
69 private final String info;
70 private final ErrorSeverity severity;
71 private final String message;
72 private final ErrorType errorType;
73 private final Throwable cause;
75 RpcErrorImpl(final ErrorSeverity severity, final ErrorType errorType,
76 final String tag, final String message, final String applicationTag, final String info,
77 final Throwable cause) {
78 this.severity = severity;
79 this.errorType = errorType;
81 this.message = message;
82 this.applicationTag = applicationTag;
88 public String getApplicationTag() {
89 return applicationTag;
93 public String getTag() {
98 public String getInfo() {
103 public ErrorSeverity getSeverity() {
108 public String getMessage() {
113 public ErrorType getErrorType() {
118 public Throwable getCause() {
123 public String toString() {
124 return "RpcError [message=" + message + ", severity="
125 + severity + ", errorType=" + errorType + ", tag=" + tag
126 + ", applicationTag=" + applicationTag + ", info=" + info
127 + ", cause=" + cause + "]";
131 private ImmutableList.Builder<RpcError> errors;
133 private final boolean successful;
135 private RpcResultBuilder(final boolean successful, final T result) {
136 this.successful = successful;
137 this.result = result;
141 * Returns a builder for a successful result.
143 public static <T> RpcResultBuilder<T> success() {
144 return new RpcResultBuilder<>(true, null);
148 * Returns a builder for a successful result.
150 * @param result the result value
152 public static <T> RpcResultBuilder<T> success(final T result) {
153 return new RpcResultBuilder<>(true, result);
157 * Returns a builder for a successful result.
159 * @param builder builder for the result value
161 public static <T> RpcResultBuilder<T> success(final Builder<T> builder) {
162 return success(builder.build());
166 * Returns a builder for a failed result.
168 public static <T> RpcResultBuilder<T> failed() {
169 return new RpcResultBuilder<>(false, null);
173 * Returns a builder based on the given status.
175 * @param success true if successful, false otherwise.
177 public static <T> RpcResultBuilder<T> status(final boolean success) {
178 return new RpcResultBuilder<>(success, null);
182 * Returns a builder from another RpcResult.
184 * @param other the other RpcResult.
186 public static <T> RpcResultBuilder<T> from(final RpcResult<T> other) {
187 return new RpcResultBuilder<>(other.isSuccessful(), other.getResult())
188 .withRpcErrors(other.getErrors());
192 * Creates an RpcError with severity ERROR for reuse.
194 * @param errorType the conceptual layer at which the error occurred.
195 * @param tag a short string that identifies the general type of error condition. See
196 * {@link RpcError#getTag} for a list of suggested values.
197 * @param message a string suitable for human display that describes the error condition.
199 * @return an RpcError
201 public static RpcError newError(final ErrorType errorType, final String tag, final String message) {
202 return new RpcErrorImpl(ErrorSeverity.ERROR, errorType,
203 tag != null ? tag : "operation-failed", message, null, null, null);
207 * Creates an RpcError with severity ERROR for reuse.
209 * @param errorType the conceptual layer at which the error occurred.
210 * @param tag a short string that identifies the general type of error condition. See
211 * {@link RpcError#getTag} for a list of suggested values.
212 * @param message a string suitable for human display that describes the error condition.
213 * @param applicationTag a short string that identifies the specific type of error condition.
214 * @param info a string containing additional information to provide extended
215 * and/or implementation-specific debugging information.
216 * @param cause the exception that triggered the error.
218 * @return an RpcError
220 public static RpcError newError(final ErrorType errorType, final String tag, final String message,
221 final String applicationTag, final String info, final Throwable cause) {
222 return new RpcErrorImpl(ErrorSeverity.ERROR, errorType,
223 tag != null ? tag : "operation-failed", message, applicationTag, info, cause);
227 * Creates an RpcError with severity WARNING for reuse.
229 * @param errorType the conceptual layer at which the warning occurred.
230 * @param tag a short string that identifies the general type of warning condition. See
231 * {@link RpcError#getTag} for a list of suggested values.
232 * @param message a string suitable for human display that describes the warning condition.
234 * @return an RpcError
236 public static RpcError newWarning(final ErrorType errorType, final String tag, final String message) {
237 return new RpcErrorImpl(ErrorSeverity.WARNING, errorType, tag, message, null, null, null);
241 * Creates an RpcError with severity WARNING for reuse.
243 * @param errorType the conceptual layer at which the warning occurred.
244 * @param tag a short string that identifies the general type of warning condition. See
245 * {@link RpcError#getTag} for a list of suggested values.
246 * @param message a string suitable for human display that describes the warning condition.
247 * @param applicationTag a short string that identifies the specific type of warning condition.
248 * @param info a string containing additional information to provide extended
249 * and/or implementation-specific debugging information.
250 * @param cause the exception that triggered the warning.
252 * @return an RpcError
254 public static RpcError newWarning(final ErrorType errorType, final String tag, final String message,
255 final String applicationTag, final String info, final Throwable cause) {
256 return new RpcErrorImpl(ErrorSeverity.WARNING, errorType, tag, message,
257 applicationTag, info, cause);
261 * Sets the value of the result.
263 * @param result the result value
265 @SuppressWarnings("checkstyle:hiddenField")
266 public RpcResultBuilder<T> withResult(final T result) {
267 this.result = result;
272 * Sets the value of the result.
274 * @param builder builder for the result value
276 public RpcResultBuilder<T> withResult(final Builder<T> builder) {
277 return withResult(builder.build());
280 private void addError(final ErrorSeverity severity, final ErrorType errorType,
281 final String tag, final String message, final String applicationTag, final String info,
282 final Throwable cause) {
284 addError(new RpcErrorImpl(severity, errorType,
285 tag != null ? tag : "operation-failed", message,
286 applicationTag, info, cause));
289 private void addError(final RpcError error) {
291 if (errors == null) {
292 errors = new ImmutableList.Builder<>();
299 * Adds a warning to the result.
301 * @param errorType the conceptual layer at which the warning occurred.
302 * @param tag a short string that identifies the general type of warning condition. See
303 * {@link RpcError#getTag} for a list of suggested values.
304 * @param message a string suitable for human display that describes the warning condition.
306 public RpcResultBuilder<T> withWarning(final ErrorType errorType, final String tag, final String message) {
307 addError(ErrorSeverity.WARNING, errorType, tag, message, null, null, null);
312 * Adds a warning to the result.
314 * @param errorType the conceptual layer at which the warning occurred.
315 * @param tag a short string that identifies the general type of warning condition. See
316 * {@link RpcError#getTag} for a list of suggested values.
317 * @param message a string suitable for human display that describes the warning condition.
318 * @param applicationTag a short string that identifies the specific type of warning condition.
319 * @param info a string containing additional information to provide extended
320 * and/or implementation-specific debugging information.
321 * @param cause the exception that triggered the warning.
323 public RpcResultBuilder<T> withWarning(final ErrorType errorType, final String tag, final String message,
324 final String applicationTag, final String info, final Throwable cause) {
325 addError(ErrorSeverity.WARNING, errorType, tag, message, applicationTag, info, cause);
330 * Adds an error to the result. The general error tag defaults to "operation-failed".
332 * @param errorType the conceptual layer at which the error occurred.
333 * @param message a string suitable for human display that describes the error condition.
335 public RpcResultBuilder<T> withError(final ErrorType errorType, final String message) {
336 addError(ErrorSeverity.ERROR, errorType, null, message, null, null, null);
341 * Adds an error to the result.
343 * @param errorType the conceptual layer at which the error occurred.
344 * @param tag a short string that identifies the general type of error condition. See
345 * {@link RpcError#getTag} for a list of suggested values.
346 * @param message a string suitable for human display that describes the error condition.
348 public RpcResultBuilder<T> withError(final ErrorType errorType, final String tag, final String message) {
349 addError(ErrorSeverity.ERROR, errorType, tag, message, null, null, null);
354 * Adds an error to the result. The general error tag defaults to "operation-failed".
356 * @param errorType the conceptual layer at which the error occurred.
357 * @param message a string suitable for human display that describes the error condition.
358 * @param cause the exception that triggered the error.
360 public RpcResultBuilder<T> withError(final ErrorType errorType, final String message,
361 final Throwable cause) {
362 addError(ErrorSeverity.ERROR, errorType, null, message, null, null, cause);
367 * Adds an error to the result.
369 * @param errorType the conceptual layer at which the error occurred.
370 * @param tag a short string that identifies the general type of error condition. See
371 * {@link RpcError#getTag} for a list of suggested values.
372 * @param message a string suitable for human display that describes the error condition.
373 * @param applicationTag a short string that identifies the specific type of error condition.
374 * @param info a string containing additional information to provide extended
375 * and/or implementation-specific debugging information.
376 * @param cause the exception that triggered the error.
378 public RpcResultBuilder<T> withError(final ErrorType errorType, final String tag, final String message,
379 final String applicationTag, final String info, final Throwable cause) {
380 addError(ErrorSeverity.ERROR, errorType, tag, message, applicationTag, info, cause);
387 * @param error the RpcError
389 public RpcResultBuilder<T> withRpcError(final RpcError error) {
397 * @param rpcErrors the list of RpcErrors
399 public RpcResultBuilder<T> withRpcErrors(final Collection<? extends RpcError> rpcErrors) {
400 if (rpcErrors != null) {
401 for (RpcError error : rpcErrors) {
409 public RpcResult<T> build() {
410 return new RpcResultImpl<>(successful, result, errors != null ? errors.build() : ImmutableList.of());
414 * Builds RpcResult and wraps it in a Future.
417 * This is a convenience method to assist those writing RPCs that produce immediate results. It allows you to
418 * replace {@code FluentFuture.from(Futures.immediateFuture(rpcResult.build()))} with
419 * {@code rpcResult.buildFuture()}
421 * @return Future for RpcResult built by RpcResultBuilder
423 public FluentFuture<RpcResult<T>> buildFuture() {
424 return FluentFuture.from(Futures.immediateFuture(build()));