001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.client;
018
019
020import java.io.*;
021
022import org.apache.juneau.http.*;
023import static org.apache.juneau.commons.utils.Shorts.*;
024
025/**
026 * The body of a transport-layer request — a thin wrapper around {@link HttpBody} that gives transports a
027 * stable contract without needing to know about higher-level body types.
028 *
029 * <p>
030 * Transport implementations call {@link HttpBody#writeTo(OutputStream)} to stream the body directly to the
031 * underlying connection, avoiding full in-memory buffering.
032 *
033 * @since 9.2.1
034 */
035public final class TransportBody {
036
037   private final HttpBody body;
038
039   private TransportBody(HttpBody body) {
040      this.body = body;
041   }
042
043   /**
044    * Wraps the given {@link HttpBody} as a {@link TransportBody}.
045    *
046    * @param body The HTTP body. Must not be <jk>null</jk>.
047    * @return A new instance. Never <jk>null</jk>.
048    */
049   public static TransportBody of(HttpBody body) {
050      return new TransportBody(reqnn("body", body));
051   }
052
053   /**
054    * Returns the content type of this body (e.g. {@code "application/json; charset=UTF-8"}), or {@code null} if unknown.
055    *
056    * @return The content type, possibly <jk>null</jk>.
057    */
058   public String getContentType() {
059      return body.getContentType();
060   }
061
062   /**
063    * Returns the content length in bytes, or {@code -1} if unknown (signals chunked transfer).
064    *
065    * @return The content length, or {@code -1}.
066    */
067   public long getContentLength() {
068      return body.getContentLength();
069   }
070
071   /**
072    * Streams the body content to the given output stream.
073    *
074    * <p>
075    * The caller must not close {@code out}.
076    *
077    * @param out The output stream. Must not be <jk>null</jk>.
078    * @throws IOException If an I/O error occurs.
079    */
080   public void writeTo(OutputStream out) throws IOException {
081      body.writeTo(out);
082   }
083
084   /**
085    * Returns {@code true} if this body can be written more than once.
086    *
087    * @return {@code true} if repeatable.
088    */
089   public boolean isRepeatable() {
090      return body.isRepeatable();
091   }
092}