2 * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.restconf.api;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.base.MoreObjects;
13 import com.google.common.base.MoreObjects.ToStringHelper;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.util.concurrent.atomic.AtomicReference;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.yangtools.concepts.Mutable;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * An body backed by an {@link InputStream}, which can be consumed exactly once.
27 public abstract class ConsumableBody implements AutoCloseable, Mutable {
28 private static final Logger LOG = LoggerFactory.getLogger(ConsumableBody.class);
30 private final AtomicReference<@Nullable InputStream> inputStream;
32 protected ConsumableBody(final InputStream inputStream) {
33 this.inputStream = new AtomicReference<>(requireNonNull(inputStream));
39 * @return An {@link InputStream}
40 * @throws IllegalStateException if this body has already been consumed
42 protected final InputStream consume() {
43 final var is = inputStream.getAndSet(null);
45 throw new IllegalStateException("Input stream has already been consumed");
51 public final void close() {
52 final var is = inputStream.getAndSet(null);
56 } catch (IOException e) {
57 LOG.info("Failed to close input", e);
63 public final String toString() {
64 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
67 protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
68 final var stream = inputStream.get();
69 return helper.add("stream", stream != null ? stream : "CONSUMED");