View Javadoc
1   /*
2    * Copyright (c) 2011-2022, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.http;
31  
32  import com.jcabi.aspects.Immutable;
33  import jakarta.json.JsonStructure;
34  import java.nio.charset.StandardCharsets;
35  import java.util.Map;
36  
37  /**
38   * Request body.
39   *
40   * <p>Instance of this interface is returned by {@link Request#body()},
41   * and can be modified using one of the methods below. When modification
42   * is done, method {@code back()} returns a modified instance of
43   * {@link Request}, for example:
44   *
45   * <pre> new JdkRequest("http://my.example.com")
46   *   .header("Content-Type", "application/x-www-form-urlencoded")
47   *   .body()
48   *   .formParam("name", "Jeff Lebowski")
49   *   .formParam("age", "37")
50   *   .formParam("employment", "none")
51   *   .back() // returns a modified instance of Request
52   *   .fetch()</pre>
53   *
54   * <p>Instances of this interface are immutable and thread-safe.
55   *
56   * @since 0.8
57   */
58  @Immutable
59  public interface RequestBody {
60  
61      /**
62       * Get back to the request it's related to.
63       * @return The request we're in
64       */
65      Request back();
66  
67      /**
68       * Get text content.
69       * @return Content in UTF-8
70       */
71      String get();
72  
73      /**
74       * Set text content.
75       * @param body Body content
76       * @return New alternated body
77       */
78      RequestBody set(String body);
79  
80      /**
81       * Set JSON content.
82       * @param json JSON object
83       * @return New alternated body
84       * @since 0.11
85       */
86      RequestBody set(JsonStructure json);
87  
88      /**
89       * Set byte array content.
90       * @param body Body content
91       * @return New alternated body
92       */
93      RequestBody set(byte[] body);
94  
95      /**
96       * Add form param.
97       * @param name Query param name
98       * @param value Value of the query param to set
99       * @return New alternated body
100      */
101     RequestBody formParam(String name, Object value);
102 
103     /**
104      * Add form params.
105      * @param params Map of params
106      * @return New alternated body
107      * @since 0.10
108      */
109     RequestBody formParams(Map<String, String> params);
110 
111     /**
112      * Printer of byte array.
113      *
114      * @since 1.0
115      */
116     @Immutable
117     final class Printable {
118 
119         /**
120          * Byte array.
121          */
122         @Immutable.Array
123         private final transient byte[] array;
124 
125         /**
126          * Ctor.
127          * @param bytes Bytes to encapsulate
128          */
129         public Printable(final byte[] bytes) {
130             this.array = bytes;
131         }
132 
133         @Override
134         public String toString() {
135             final StringBuilder text = new StringBuilder(0);
136             final char[] chrs = new String(
137                 this.array, StandardCharsets.UTF_8
138             ).toCharArray();
139             if (chrs.length > 0) {
140                 for (final char chr : chrs) {
141                     // @checkstyle MagicNumber (1 line)
142                     if (chr < 128) {
143                         text.append(chr);
144                     } else {
145                         text.append("\\u").append(
146                             Integer.toHexString(chr)
147                         );
148                     }
149                 }
150             } else {
151                 text.append("<<empty>>");
152             }
153             return text.toString();
154         }
155     }
156 
157 }