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.http.entity;
018
019
020import java.io.*;
021
022import org.apache.juneau.http.*;
023import static org.apache.juneau.commons.utils.Shorts.*;
024
025/**
026 * A mutable wrapper around an {@link HttpBody} that allows overriding the content type.
027 *
028 * <p>
029 * Use this class when you need to wrap an existing body and attach (or override) its {@code Content-Type}.
030 *
031 * <p>
032 * Create instances via the static factory methods:
033 * <p class='bjava'>
034 *    <jc>// Wrap a byte array body with a specific content type</jc>
035 *    HttpBody <jv>body</jv> = HttpBodyBean.<jsm>of</jsm>(ByteArrayBody.<jsm>of</jsm>(<jv>bytes</jv>), <js>"application/octet-stream"</js>);
036 * </p>
037 *
038 * <h5 class='section'>See Also:</h5><ul>
039 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a>
040 * </ul>
041 *
042 * @since 9.2.1
043 */
044public final class HttpBodyBean implements HttpBody {
045
046   private final HttpBody delegate;
047   private final String contentType;
048
049   private HttpBodyBean(HttpBody delegate, String contentType) {
050      this.delegate = reqnn("delegate", delegate);
051      this.contentType = contentType;
052   }
053
054   /**
055    * Creates an {@link HttpBodyBean} wrapping the given body with the specified content type.
056    *
057    * @param body The underlying body. Must not be <jk>null</jk>.
058    * @param contentType The content type to report. May be <jk>null</jk>.
059    * @return A new instance. Never <jk>null</jk>.
060    */
061   public static HttpBodyBean of(HttpBody body, String contentType) {
062      return new HttpBodyBean(body, contentType);
063   }
064
065   /**
066    * Creates an {@link HttpBodyBean} wrapping the given body and retaining its content type.
067    *
068    * @param body The underlying body. Must not be <jk>null</jk>.
069    * @return A new instance. Never <jk>null</jk>.
070    */
071   public static HttpBodyBean of(HttpBody body) {
072      reqnn("body", body);
073      return new HttpBodyBean(body, body.getContentType());
074   }
075
076   @Override /* HttpBody */
077   public String getContentType() {
078      return contentType;
079   }
080
081   @Override /* HttpBody */
082   public long getContentLength() {
083      return delegate.getContentLength();
084   }
085
086   @Override /* HttpBody */
087   public boolean isRepeatable() {
088      return delegate.isRepeatable();
089   }
090
091   @Override /* HttpBody */
092   public void writeTo(OutputStream out) throws IOException {
093      delegate.writeTo(out);
094   }
095
096   @Override /* Object */
097   public String toString() {
098      return delegate.toString();
099   }
100}