This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new d0eaf21f4d TODO-274: CRTP-convert the classic BasicResource hierarchy 
(10.0.0 breaking change)
d0eaf21f4d is described below

commit d0eaf21f4daa8ad5fc45aebe3cd4d9030ec0177b
Author: James Bognar <[email protected]>
AuthorDate: Tue Jul 21 10:36:51 2026 -0400

    TODO-274: CRTP-convert the classic BasicResource hierarchy (10.0.0 breaking 
change)
    
    Generify BasicResource into an abstract self-typed (CRTP) root
    BasicResource<SELF extends BasicResource<SELF>> implements HttpResource, 
mirroring
    the already-shipped BasicHttpEntity<SELF> precedent. Each of the 5 leaves
    (ByteArrayResource, FileResource, ReaderResource, StreamResource, 
StringResource)
    drops its 15 covariant narrowing-setter overrides (~75 total deleted) and 
inherits
    leaf-typed fluent setters for free.
    
    Generifying makes the root effectively abstract, so ResponseContent now 
materializes
    HttpResource/BasicResource response bodies as a concrete StreamResource 
(which IS-A
    BasicResource), and StreamResource gained an HttpResponse constructor for 
this. This
    keeps the breaking surface narrow: .as(BasicResource.class) and @Remote 
methods
    declared to return BasicResource/HttpResource still work; only 
direct/reflective
    new BasicResource(...) instantiation breaks. BasicResource_Test's 
direct-instantiation
    sites were rebased onto concrete leaves.
    
    Co-authored-by: Cursor <[email protected]>
---
 .../rest/client/classic/ResponseContent.java       |   8 +-
 .../http/classic/resource/BasicResource.java       | 136 +++++++++------------
 .../http/classic/resource/ByteArrayResource.java   |  98 +--------------
 .../juneau/http/classic/resource/FileResource.java |  97 +--------------
 .../http/classic/resource/ReaderResource.java      |  97 +--------------
 .../http/classic/resource/StreamResource.java      | 105 ++--------------
 .../http/classic/resource/StringResource.java      |  98 +--------------
 .../http/classic/resource/BasicResource_Test.java  |  59 +++++----
 8 files changed, 114 insertions(+), 584 deletions(-)

diff --git 
a/juneau-rest/juneau-rest-client-classic/src/main/java/org/apache/juneau/rest/client/classic/ResponseContent.java
 
b/juneau-rest/juneau-rest-client-classic/src/main/java/org/apache/juneau/rest/client/classic/ResponseContent.java
index b6be172e19..41f3d19432 100644
--- 
a/juneau-rest/juneau-rest-client-classic/src/main/java/org/apache/juneau/rest/client/classic/ResponseContent.java
+++ 
b/juneau-rest/juneau-rest-client-classic/src/main/java/org/apache/juneau/rest/client/classic/ResponseContent.java
@@ -162,7 +162,7 @@ public class ResponseContent implements HttpEntity {
         *                      <li>{@link ResponseContent}/{@link HttpEntity} 
- Returns access to this object.
         *                      <li>{@link Reader} - Returns access to the raw 
reader of the response.
         *                      <li>{@link InputStream} - Returns access to the 
raw input stream of the response.
-        *                      <li>{@link HttpResource} - Response will be 
converted to an {@link BasicResource}.
+        *                      <li>{@link HttpResource} - Response will be 
converted to a {@link StreamResource}.
         *                      <li>Any type that takes in an {@link 
HttpResponse} object.
         *              </ul>
         *      <li class='note'>
@@ -254,8 +254,8 @@ public class ResponseContent implements HttpEntity {
                        if (type.is(HttpResponse.class))
                                return (T)response;
 
-                       if (type.is(HttpResource.class))
-                               type = 
(ClassMeta<T>)getClassMeta(BasicResource.class);
+                       if (type.is(HttpResource.class) || 
type.is(BasicResource.class))
+                               type = 
(ClassMeta<T>)getClassMeta(StreamResource.class);
 
                        var result = type.getPublicConstructor(x -> 
x.hasParameterTypes(HttpResponse.class)).map(ci -> safe(() -> 
(T)ci.newInstance(response)));
                        if (result.isPresent())
@@ -429,7 +429,7 @@ public class ResponseContent implements HttpEntity {
         *                      <li>{@link ResponseContent}/{@link HttpEntity} 
- Returns access to this object.
         *                      <li>{@link Reader} - Returns access to the raw 
reader of the response.
         *                      <li>{@link InputStream} - Returns access to the 
raw input stream of the response.
-        *                      <li>{@link HttpResource} - Response will be 
converted to an {@link BasicResource}.
+        *                      <li>{@link HttpResource} - Response will be 
converted to a {@link StreamResource}.
         *                      <li>Any type that takes in an {@link 
HttpResponse} object.
         *              </ul>
         *      <li class='note'>
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/BasicResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/BasicResource.java
index 284a5e0a57..07adaa327e 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/BasicResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/BasicResource.java
@@ -44,16 +44,23 @@ import org.apache.juneau.test.assertions.*;
  *             Externally-supplied/dynamic content.
  * </ul>
  *
+ * <p>
+ * This is a self-typed (CRTP) root: a leaf declares <c>class StringResource 
<jk>extends</jk> BasicResource&lt;StringResource&gt;</c>
+ * and inherits leaf-typed fluent setters with no covariant overrides.
+ *
  * <h5 class='section'>See Also:</h5><ul>
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
+ *
+ * @param <SELF> The self type for fluent setters.
  */
 @BeanIgnore /* Use toString() to serialize */
 @SuppressWarnings({
        "resource", // Depends on entity (streams); value equality not practical
        "java:S1206", // equals/hashCode not overridden; value equality not 
practical for this class
+       "java:S119", // 'SELF' (CRTP self-type) is intentional and clearer than 
a single-letter name.
 })
-public class BasicResource implements HttpResource {
+public abstract class BasicResource<SELF extends BasicResource<SELF>> 
implements HttpResource {
        BasicHttpEntity<?> entity;
        HeaderList headers = HeaderList.create();
 
@@ -71,7 +78,7 @@ public class BasicResource implements HttpResource {
         *
         * @param copyFrom The bean being copied.  Must not be <jk>null</jk>.
         */
-       public BasicResource(BasicResource copyFrom) {
+       public BasicResource(BasicResource<?> copyFrom) {
                this.entity = copyFrom.entity.copy();
                this.headers = copyFrom.headers.copy();
        }
@@ -100,10 +107,10 @@ public class BasicResource implements HttpResource {
         * @param value The header value.
         * @return This object.
         */
-       public BasicResource addHeader(String name, String value) {
+       public SELF addHeader(String name, String value) {
                if (nn(name) && nn(value))
                        headers.append(name, value);
-               return this;
+               return self();
        }
 
        /**
@@ -112,7 +119,7 @@ public class BasicResource implements HttpResource {
         * @param values The headers to set.  <jk>null</jk> headers and headers 
with <jk>null</jk> names or values are ignored.
         * @return This object.
         */
-       public BasicResource addHeaders(Header...values) {
+       public SELF addHeaders(Header...values) {
                for (var h : values) {
                        if (nn(h)) {
                                var n = h.getName();
@@ -129,7 +136,7 @@ public class BasicResource implements HttpResource {
                                }
                        }
                }
-               return this;
+               return self();
        }
 
        /**
@@ -154,7 +161,7 @@ public class BasicResource implements HttpResource {
         * @return A new fluent assertion.
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
-       public FluentByteArrayAssertion<BasicResource> assertBytes() throws 
IOException {
+       public FluentByteArrayAssertion<BasicResource<?>> assertBytes() throws 
IOException {
                return new FluentByteArrayAssertion<>(asBytes(), this);
        }
 
@@ -167,7 +174,7 @@ public class BasicResource implements HttpResource {
         * @return A new fluent assertion.
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
-       public FluentStringAssertion<BasicResource> assertString() throws 
IOException {
+       public FluentStringAssertion<BasicResource<?>> assertString() throws 
IOException {
                return new FluentStringAssertion<>(asString(), this);
        }
 
@@ -197,9 +204,7 @@ public class BasicResource implements HttpResource {
         *
         * @return A new builder bean.
         */
-       public BasicResource copy() {
-               return new BasicResource(this);
-       }
+       public abstract SELF copy();
 
        /**
         * Copies the contents of the specified HTTP response to this builder.
@@ -208,11 +213,11 @@ public class BasicResource implements HttpResource {
         * @return This object.
         * @throws IOException If content could not be retrieved.
         */
-       public BasicResource copyFrom(HttpResponse response) throws IOException 
{
+       public SELF copyFrom(HttpResponse response) throws IOException {
                assertArgNotNull("response", response);
                addHeaders(response.getAllHeaders());
                setContent(response.getEntity().getContent());
-               return this;
+               return self();
        }
 
        @Override /* Overridden from HttpEntity */
@@ -260,9 +265,9 @@ public class BasicResource implements HttpResource {
         * @return This object.
         * @throws IOException If entity could not be read into memory.
         */
-       public BasicResource setCached() throws IOException {
+       public SELF setCached() throws IOException {
                entity.setCached();
-               return this;
+               return self();
        }
 
        /**
@@ -275,9 +280,9 @@ public class BasicResource implements HttpResource {
         *
         * @return This object.
         */
-       public BasicResource setChunked() {
+       public SELF setChunked() {
                entity.setChunked();
-               return this;
+               return self();
        }
 
        /**
@@ -291,9 +296,9 @@ public class BasicResource implements HttpResource {
         * @param value The new value for this flag.
         * @return This object.
         */
-       public BasicResource setChunked(boolean value) {
+       public SELF setChunked(boolean value) {
                entity.setChunked(value);
-               return this;
+               return self();
        }
 
        /**
@@ -302,9 +307,9 @@ public class BasicResource implements HttpResource {
         * @param value The entity content, can be <jk>null</jk>.
         * @return This object.
         */
-       public BasicResource setContent(Object value) {
+       public SELF setContent(Object value) {
                entity.setContent(value);
-               return this;
+               return self();
        }
 
        /**
@@ -317,9 +322,9 @@ public class BasicResource implements HttpResource {
         * @param value The entity content, can be <jk>null</jk>.
         * @return This object.
         */
-       public BasicResource setContent(Supplier<?> value) {
+       public SELF setContent(Supplier<?> value) {
                entity.setContent(value);
-               return this;
+               return self();
        }
 
        /**
@@ -328,9 +333,9 @@ public class BasicResource implements HttpResource {
         * @param value The new <c>Content-Encoding</c> header, or 
<jk>null</jk> to unset.
         * @return This object.
         */
-       public BasicResource setContentEncoding(ContentEncoding value) {
+       public SELF setContentEncoding(ContentEncoding value) {
                entity.setContentEncoding(value);
-               return this;
+               return self();
        }
 
        /**
@@ -339,9 +344,9 @@ public class BasicResource implements HttpResource {
         * @param value The new <c>Content-Encoding</c> header, or 
<jk>null</jk> to unset.
         * @return This object.
         */
-       public BasicResource setContentEncoding(String value) {
+       public SELF setContentEncoding(String value) {
                entity.setContentEncoding(value);
-               return this;
+               return self();
        }
 
        /**
@@ -350,9 +355,9 @@ public class BasicResource implements HttpResource {
         * @param value The new <c>Content-Length</c> header value, or 
<c>-1</c> to unset.
         * @return This object.
         */
-       public BasicResource setContentLength(long value) {
+       public SELF setContentLength(long value) {
                entity.setContentLength(value);
-               return this;
+               return self();
        }
 
        /**
@@ -361,9 +366,9 @@ public class BasicResource implements HttpResource {
         * @param value The new <c>Content-Type</c> header, or <jk>null</jk> to 
unset.
         * @return This object.
         */
-       public BasicResource setContentType(ContentType value) {
+       public SELF setContentType(ContentType value) {
                entity.setContentType(value);
-               return this;
+               return self();
        }
 
        /**
@@ -372,9 +377,9 @@ public class BasicResource implements HttpResource {
         * @param value The new <c>Content-Type</c> header, or <jk>null</jk> to 
unset.
         * @return This object.
         */
-       public BasicResource setContentType(String value) {
+       public SELF setContentType(String value) {
                entity.setContentType(value);
-               return this;
+               return self();
        }
 
        /**
@@ -387,10 +392,10 @@ public class BasicResource implements HttpResource {
         * @param value The header value.
         * @return This object.
         */
-       public BasicResource setHeader(String name, String value) {
+       public SELF setHeader(String name, String value) {
                if (nn(name) && nn(value))
                        headers.set(name, value);
-               return this;
+               return self();
        }
 
        /**
@@ -399,7 +404,7 @@ public class BasicResource implements HttpResource {
         * @param values The headers to add.  <jk>null</jk> values are ignored.
         * @return This object.
         */
-       public BasicResource setHeaders(Header...values) {
+       public SELF setHeaders(Header...values) {
                for (var h : values) {
                        if (nn(h)) {
                                var n = h.getName();
@@ -416,7 +421,7 @@ public class BasicResource implements HttpResource {
                                }
                        }
                }
-               return this;
+               return self();
        }
 
        /**
@@ -425,7 +430,7 @@ public class BasicResource implements HttpResource {
         * @param value The new value.  Must not be <jk>null</jk>.
         * @return This object.
         */
-       public BasicResource setHeaders(HeaderList value) {
+       public SELF setHeaders(HeaderList value) {
                return modify(() -> headers = value.copy());
        }
 
@@ -437,33 +442,41 @@ public class BasicResource implements HttpResource {
         *
         * @return An unmodifiable snapshot of this bean, or this bean if it is 
already unmodifiable.
         */
-       public BasicResource unmodifiable() {
-               return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
-       }
+       public abstract SELF unmodifiable();
 
        @Override /* Overridden from HttpEntity */
        public void writeTo(OutputStream outStream) throws IOException {
                entity.writeTo(outStream);
        }
 
+       /**
+        * Returns this object cast to the self type.
+        *
+        * @return This object.
+        */
+       @SuppressWarnings({
+               "unchecked" // CRTP self-type cast is safe: SELF is bound to 
the concrete leaf type.
+       })
+       protected final SELF self() { return (SELF) this; }
+
        /**
         * Single mutation funnel for direct-field state changes on this bean.
         *
         * <p>
-        * The nested {@link Unmodifiable} snapshot overrides this method to 
throw.  Mutators that delegate to the entity or
-        * header sub-beans are frozen by the {@link #freeze()} deep-freeze of 
those sub-beans; this funnel additionally
-        * covers the direct-field {@link #setHeaders(HeaderList)} reassignment.
+        * Each leaf's nested {@code Unmodifiable} snapshot overrides this 
method to throw.  Mutators that delegate to the
+        * entity or header sub-beans are frozen by the {@link #freeze()} 
deep-freeze of those sub-beans; this funnel
+        * additionally covers the direct-field {@link #setHeaders(HeaderList)} 
reassignment.
         *
         * @param mutation The state change to apply.
         * @return This object.
         */
-       protected BasicResource modify(Runnable mutation) {
+       protected SELF modify(Runnable mutation) {
                mutation.run();
-               return this;
+               return self();
        }
 
        /**
-        * Deep-freeze hook invoked from the nested {@link Unmodifiable} 
constructor after the snapshot copy completes.
+        * Deep-freeze hook invoked from a leaf's nested {@code Unmodifiable} 
constructor after the snapshot copy completes.
         *
         * <p>
         * The mutable sub-beans are frozen here by <b>direct field 
assignment</b> (never via a setter, which would route
@@ -473,33 +486,4 @@ public class BasicResource implements HttpResource {
                entity = entity.unmodifiable();   // DIRECT field write — 
snapshot the copied entity.
                headers = headers.unmodifiable(); // DIRECT field write — 
snapshot the copied HeaderList.
        }
-
-       /**
-        * An unmodifiable snapshot of a {@link BasicResource}.
-        *
-        * <p>
-        * Its behavioral override is a throwing {@link #modify(Runnable)}, and 
its constructor deep-freezes the entity and
-        * header sub-beans via {@link #freeze()}.  Together these freeze the 
entire mutation surface: direct-field mutators
-        * throw through {@code modify(...)}, and sub-bean-delegating mutators 
throw through the frozen entity/headers.
-        */
-       public static class Unmodifiable extends BasicResource implements 
UnmodifiableBean {
-
-               /**
-                * Constructor.
-                *
-                * @param copyFrom The bean to snapshot-copy.  Must not be 
<jk>null</jk>.
-                */
-               @SuppressWarnings({
-                       "java:S1699" // Paradigm intentionally calls the 
overridable freeze() from the ctor to deep-freeze sub-beans.
-               })
-               protected Unmodifiable(BasicResource copyFrom) {
-                       super(copyFrom);
-                       freeze();
-               }
-
-               @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
-                       throw uoex("Bean is unmodifiable.");
-               }
-       }
 }
\ No newline at end of file
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ByteArrayResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ByteArrayResource.java
index 238b69e63c..b5c8935569 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ByteArrayResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ByteArrayResource.java
@@ -18,10 +18,6 @@ package org.apache.juneau.http.classic.resource;
 
 import static org.apache.juneau.commons.utils.Shorts.*;
 
-import java.io.*;
-import java.util.function.*;
-
-import org.apache.http.*;
 import org.apache.juneau.http.UnmodifiableBean;
 import org.apache.juneau.http.classic.entity.*;
 import org.apache.juneau.http.classic.header.*;
@@ -33,7 +29,7 @@ import org.apache.juneau.http.classic.header.*;
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
  */
-public class ByteArrayResource extends BasicResource {
+public class ByteArrayResource extends BasicResource<ByteArrayResource> {
 
        /**
         * Constructor.
@@ -62,100 +58,10 @@ public class ByteArrayResource extends BasicResource {
        }
 
        @Override /* Overridden from BasicResource */
-       public ByteArrayResource addHeader(String name, String value) {
-               super.addHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource addHeaders(Header...values) {
-               super.addHeaders(values);
-               return this;
-       }
-
-       @Override
        public ByteArrayResource copy() {
                return new ByteArrayResource(this);
        }
 
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setCached() throws IOException {
-               super.setCached();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setChunked() {
-               super.setChunked();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setChunked(boolean value) {
-               super.setChunked(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContent(Object value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContent(Supplier<?> value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContentEncoding(ContentEncoding value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContentEncoding(String value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContentLength(long value) {
-               super.setContentLength(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContentType(ContentType value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setContentType(String value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setHeader(String name, String value) {
-               super.setHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setHeaders(Header...values) {
-               super.setHeaders(values);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ByteArrayResource setHeaders(HeaderList value) {
-               super.setHeaders(value);
-               return this;
-       }
-
        @Override /* Overridden from BasicResource */
        public ByteArrayResource unmodifiable() {
                return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
@@ -180,7 +86,7 @@ public class ByteArrayResource extends BasicResource {
                }
 
                @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
+               protected ByteArrayResource modify(Runnable mutation) {
                        throw uoex("Bean is unmodifiable.");
                }
        }
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/FileResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/FileResource.java
index c4eb9d9ddd..7920b55fe4 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/FileResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/FileResource.java
@@ -19,9 +19,6 @@ package org.apache.juneau.http.classic.resource;
 import static org.apache.juneau.commons.utils.Shorts.*;
 
 import java.io.*;
-import java.util.function.*;
-
-import org.apache.http.*;
 import org.apache.juneau.http.UnmodifiableBean;
 import org.apache.juneau.http.classic.entity.*;
 import org.apache.juneau.http.classic.header.*;
@@ -33,7 +30,7 @@ import org.apache.juneau.http.classic.header.*;
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
  */
-public class FileResource extends BasicResource {
+public class FileResource extends BasicResource<FileResource> {
 
        /**
         * Constructor.
@@ -62,100 +59,10 @@ public class FileResource extends BasicResource {
        }
 
        @Override /* Overridden from BasicResource */
-       public FileResource addHeader(String name, String value) {
-               super.addHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource addHeaders(Header...values) {
-               super.addHeaders(values);
-               return this;
-       }
-
-       @Override
        public FileResource copy() {
                return new FileResource(this);
        }
 
-       @Override /* Overridden from BasicResource */
-       public FileResource setCached() throws IOException {
-               super.setCached();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setChunked() {
-               super.setChunked();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setChunked(boolean value) {
-               super.setChunked(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContent(Object value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContent(Supplier<?> value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContentEncoding(ContentEncoding value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContentEncoding(String value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContentLength(long value) {
-               super.setContentLength(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContentType(ContentType value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setContentType(String value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setHeader(String name, String value) {
-               super.setHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setHeaders(Header...values) {
-               super.setHeaders(values);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public FileResource setHeaders(HeaderList value) {
-               super.setHeaders(value);
-               return this;
-       }
-
        @Override /* Overridden from BasicResource */
        public FileResource unmodifiable() {
                return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
@@ -180,7 +87,7 @@ public class FileResource extends BasicResource {
                }
 
                @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
+               protected FileResource modify(Runnable mutation) {
                        throw uoex("Bean is unmodifiable.");
                }
        }
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ReaderResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ReaderResource.java
index 1fdf757d55..a474eb2b71 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ReaderResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/ReaderResource.java
@@ -19,9 +19,6 @@ package org.apache.juneau.http.classic.resource;
 import static org.apache.juneau.commons.utils.Shorts.*;
 
 import java.io.*;
-import java.util.function.*;
-
-import org.apache.http.*;
 import org.apache.juneau.http.UnmodifiableBean;
 import org.apache.juneau.http.classic.entity.*;
 import org.apache.juneau.http.classic.header.*;
@@ -33,7 +30,7 @@ import org.apache.juneau.http.classic.header.*;
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
  */
-public class ReaderResource extends BasicResource {
+public class ReaderResource extends BasicResource<ReaderResource> {
 
        /**
         * Constructor.
@@ -62,100 +59,10 @@ public class ReaderResource extends BasicResource {
        }
 
        @Override /* Overridden from BasicResource */
-       public ReaderResource addHeader(String name, String value) {
-               super.addHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource addHeaders(Header...values) {
-               super.addHeaders(values);
-               return this;
-       }
-
-       @Override
        public ReaderResource copy() {
                return new ReaderResource(this);
        }
 
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setCached() throws IOException {
-               super.setCached();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setChunked() {
-               super.setChunked();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setChunked(boolean value) {
-               super.setChunked(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContent(Object value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContent(Supplier<?> value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContentEncoding(ContentEncoding value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContentEncoding(String value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContentLength(long value) {
-               super.setContentLength(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContentType(ContentType value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setContentType(String value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setHeader(String name, String value) {
-               super.setHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setHeaders(Header...values) {
-               super.setHeaders(values);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public ReaderResource setHeaders(HeaderList value) {
-               super.setHeaders(value);
-               return this;
-       }
-
        @Override /* Overridden from BasicResource */
        public ReaderResource unmodifiable() {
                return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
@@ -180,7 +87,7 @@ public class ReaderResource extends BasicResource {
                }
 
                @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
+               protected ReaderResource modify(Runnable mutation) {
                        throw uoex("Bean is unmodifiable.");
                }
        }
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StreamResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StreamResource.java
index b100855bd1..96375ee4d4 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StreamResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StreamResource.java
@@ -19,8 +19,6 @@ package org.apache.juneau.http.classic.resource;
 import static org.apache.juneau.commons.utils.Shorts.*;
 
 import java.io.*;
-import java.util.function.*;
-
 import org.apache.http.*;
 import org.apache.juneau.http.UnmodifiableBean;
 import org.apache.juneau.http.classic.entity.*;
@@ -33,7 +31,7 @@ import org.apache.juneau.http.classic.header.*;
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
  */
-public class StreamResource extends BasicResource {
+public class StreamResource extends BasicResource<StreamResource> {
 
        /**
         * Constructor.
@@ -61,101 +59,24 @@ public class StreamResource extends BasicResource {
                super(copyFrom);
        }
 
-       @Override /* Overridden from BasicResource */
-       public StreamResource addHeader(String name, String value) {
-               super.addHeader(name, value);
-               return this;
+       /**
+        * Constructor.
+        *
+        * <p>
+        * This is the constructor used when converting an HTTP response into a 
resource.
+        *
+        * @param response The HTTP response to copy from.  Must not be 
<jk>null</jk>.
+        * @throws IOException Rethrown from {@link HttpEntity#getContent()}.
+        */
+       public StreamResource(HttpResponse response) throws IOException {
+               super(response);
        }
 
        @Override /* Overridden from BasicResource */
-       public StreamResource addHeaders(Header...values) {
-               super.addHeaders(values);
-               return this;
-       }
-
-       @Override
        public StreamResource copy() {
                return new StreamResource(this);
        }
 
-       @Override /* Overridden from BasicResource */
-       public StreamResource setCached() throws IOException {
-               super.setCached();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setChunked() {
-               super.setChunked();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setChunked(boolean value) {
-               super.setChunked(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContent(Object value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContent(Supplier<?> value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContentEncoding(ContentEncoding value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContentEncoding(String value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContentLength(long value) {
-               super.setContentLength(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContentType(ContentType value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setContentType(String value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setHeader(String name, String value) {
-               super.setHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setHeaders(Header...values) {
-               super.setHeaders(values);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StreamResource setHeaders(HeaderList value) {
-               super.setHeaders(value);
-               return this;
-       }
-
        @Override /* Overridden from BasicResource */
        public StreamResource unmodifiable() {
                return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
@@ -180,7 +101,7 @@ public class StreamResource extends BasicResource {
                }
 
                @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
+               protected StreamResource modify(Runnable mutation) {
                        throw uoex("Bean is unmodifiable.");
                }
        }
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StringResource.java
 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StringResource.java
index 93dff6340f..7504238683 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StringResource.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/main/java/org/apache/juneau/http/classic/resource/StringResource.java
@@ -18,10 +18,6 @@ package org.apache.juneau.http.classic.resource;
 
 import static org.apache.juneau.commons.utils.Shorts.*;
 
-import java.io.*;
-import java.util.function.*;
-
-import org.apache.http.*;
 import org.apache.juneau.http.UnmodifiableBean;
 import org.apache.juneau.http.classic.entity.*;
 import org.apache.juneau.http.classic.header.*;
@@ -33,7 +29,7 @@ import org.apache.juneau.http.classic.header.*;
  *     <li class='link'><a class="doclink" 
href="https://juneau.apache.org/docs/topics/JuneauRestCommon";>juneau-rest-common
 Basics</a>
  * </ul>
  */
-public class StringResource extends BasicResource {
+public class StringResource extends BasicResource<StringResource> {
 
        /**
         * Constructor.
@@ -62,100 +58,10 @@ public class StringResource extends BasicResource {
        }
 
        @Override /* Overridden from BasicResource */
-       public StringResource addHeader(String name, String value) {
-               super.addHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource addHeaders(Header...values) {
-               super.addHeaders(values);
-               return this;
-       }
-
-       @Override
        public StringResource copy() {
                return new StringResource(this);
        }
 
-       @Override /* Overridden from BasicResource */
-       public StringResource setCached() throws IOException {
-               super.setCached();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setChunked() {
-               super.setChunked();
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setChunked(boolean value) {
-               super.setChunked(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContent(Object value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContent(Supplier<?> value) {
-               super.setContent(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContentEncoding(ContentEncoding value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContentEncoding(String value) {
-               super.setContentEncoding(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContentLength(long value) {
-               super.setContentLength(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContentType(ContentType value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setContentType(String value) {
-               super.setContentType(value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setHeader(String name, String value) {
-               super.setHeader(name, value);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setHeaders(Header...values) {
-               super.setHeaders(values);
-               return this;
-       }
-
-       @Override /* Overridden from BasicResource */
-       public StringResource setHeaders(HeaderList value) {
-               super.setHeaders(value);
-               return this;
-       }
-
        @Override /* Overridden from BasicResource */
        public StringResource unmodifiable() {
                return this instanceof UnmodifiableBean ? this : new 
Unmodifiable(this);
@@ -180,7 +86,7 @@ public class StringResource extends BasicResource {
                }
 
                @Override /* Overridden from BasicResource */
-               protected BasicResource modify(Runnable mutation) {
+               protected StringResource modify(Runnable mutation) {
                        throw uoex("Bean is unmodifiable.");
                }
        }
diff --git 
a/juneau-rest/juneau-rest-common-classic/src/test/java/org/apache/juneau/http/classic/resource/BasicResource_Test.java
 
b/juneau-rest/juneau-rest-common-classic/src/test/java/org/apache/juneau/http/classic/resource/BasicResource_Test.java
index f153ef7fc8..0ed9b7b153 100644
--- 
a/juneau-rest/juneau-rest-common-classic/src/test/java/org/apache/juneau/http/classic/resource/BasicResource_Test.java
+++ 
b/juneau-rest/juneau-rest-common-classic/src/test/java/org/apache/juneau/http/classic/resource/BasicResource_Test.java
@@ -25,7 +25,6 @@ import java.io.*;
 import org.apache.http.*;
 import org.apache.http.message.*;
 import org.apache.juneau.*;
-import org.apache.juneau.http.classic.entity.*;
 import org.apache.juneau.http.classic.header.*;
 import org.junit.jupiter.api.*;
 
@@ -40,7 +39,7 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void a01_constructor_entity() throws Exception {
-               var x = new BasicResource(new 
StringEntity(contentType("text/plain"), "foo"));
+               var x = new StringResource(contentType("text/plain"), "foo");
                assertEquals("foo", toUtf8(x.getContent()));
                assertEquals("text/plain", x.getContentType().getValue());
                assertNotNull(x.getEntity());
@@ -48,9 +47,9 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void a02_constructor_copy() throws Exception {
-               var src = new BasicResource(new 
StringEntity(contentType("text/plain"), "foo"))
+               var src = new StringResource(contentType("text/plain"), "foo")
                        .setHeader("Foo", "bar");
-               var x = new BasicResource(src);
+               var x = new StringResource(src);
                assertNotSame(src, x);
                assertEquals("foo", toUtf8(x.getContent()));
                assertEquals("text/plain", x.getContentType().getValue());
@@ -64,7 +63,7 @@ class BasicResource_Test extends TestBase {
                resp.addHeader("Content-Type", "text/plain");
                resp.addHeader("Content-Encoding", "identity");
                resp.addHeader("Content-Length", "5");
-               var x = new BasicResource(resp);
+               var x = new StreamResource(resp);
                assertEquals("hello", toUtf8(x.getContent()));
                assertEquals("bar", 
x.getHeaders().getFirst("X-Foo").get().getValue());
                assertEquals("text/plain", x.getContentType().getValue());
@@ -77,7 +76,7 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void b01_addHeader_basic() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .addHeader("Foo", "bar")
                        .addHeader("Foo", "baz")
                        .setHeader("Qux", "quux");
@@ -88,7 +87,7 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void b02_addHeader_nullSafe() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .addHeader(null, "bar")
                        .addHeader("Foo", null)
                        .setHeader(null, "x")
@@ -97,7 +96,7 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void b03_addHeaders_specialHeaders() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .addHeaders(
                                header("Content-Type", "text/plain"),
                                header("Content-Encoding", "identity"),
@@ -113,7 +112,7 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void b04_setHeaders_specialHeaders() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .setHeaders(
                                header("Content-Type", "text/plain"),
                                header("Content-Encoding", "identity"),
@@ -130,7 +129,7 @@ class BasicResource_Test extends TestBase {
 
        @Test void b05_setHeaders_headerList() {
                var hl = HeaderList.create().append("Foo", "bar");
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .setHeaders(hl);
                assertEquals("bar", 
x.getHeaders().getFirst("Foo").get().getValue());
        }
@@ -140,47 +139,47 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void c01_setContent_value() throws Exception {
-               var x = new BasicResource(new StringEntity(null, "old"))
+               var x = new StringResource(null, "old")
                        .setContent("new");
                assertEquals("new", toUtf8(x.getContent()));
        }
 
        @Test void c02_setContent_supplier() throws Exception {
-               var x = new BasicResource(new StringEntity(null, null))
+               var x = new StringResource(null, null)
                        .setContent(() -> "newish");
                assertEquals("newish", toUtf8(x.getContent()));
        }
 
        @Test void c03_setContentType_string_andContentType() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .setContentType("text/plain");
                assertEquals("text/plain", x.getContentType().getValue());
 
-               var x2 = new BasicResource(new StringEntity(null, "foo"))
+               var x2 = new StringResource(null, "foo")
                        .setContentType(contentType("text/html"));
                assertEquals("text/html", x2.getContentType().getValue());
        }
 
        @Test void c04_setContentEncoding_string_andContentEncoding() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .setContentEncoding("identity");
                assertEquals("identity", x.getContentEncoding().getValue());
 
-               var x2 = new BasicResource(new StringEntity(null, "foo"))
+               var x2 = new StringResource(null, "foo")
                        .setContentEncoding(contentEncoding("gzip"));
                assertEquals("gzip", x2.getContentEncoding().getValue());
        }
 
        @Test void c05_setContentLength() {
-               var x = new BasicResource(new StringEntity(null, "foo"))
+               var x = new StringResource(null, "foo")
                        .setContentLength(10L);
                assertEquals(10L, x.getContentLength());
        }
 
        @Test void c06_chunked() {
-               var x = new BasicResource(new StringEntity(null, 
"foo")).setChunked();
+               var x = new StringResource(null, "foo").setChunked();
                assertTrue(x.isChunked());
-               var x2 = new BasicResource(new StringEntity(null, 
"foo")).setChunked(false);
+               var x2 = new StringResource(null, "foo").setChunked(false);
                assertFalse(x2.isChunked());
        }
 
@@ -189,7 +188,7 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void d01_setCached_andRepeatable() throws Exception {
-               var x = new BasicResource(new StringEntity(null, 
"foo")).setCached();
+               var x = new StringResource(null, "foo").setCached();
                assertEquals("foo", toUtf8(x.getContent()));
                assertEquals("foo", toUtf8(x.getContent()));
                assertTrue(x.isRepeatable());
@@ -197,19 +196,19 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void d02_asBytes_asString() throws Exception {
-               var x = new BasicResource(new StringEntity(null, "hello"));
+               var x = new StringResource(null, "hello");
                assertEquals("hello", new String(x.asBytes()));
                assertEquals("hello", x.asString());
        }
 
        @Test void d03_assertBytes_assertString() throws Exception {
-               var x = new BasicResource(new StringEntity(null, "abc"));
+               var x = new StringResource(null, "abc");
                assertNotNull(x.assertBytes());
                assertNotNull(x.assertString());
        }
 
        @Test void d04_copy_method() throws Exception {
-               var x = new BasicResource(new 
StringEntity(contentType("text/plain"), "foo"))
+               var x = new StringResource(contentType("text/plain"), "foo")
                        .setHeader("Foo", "bar");
                var x2 = x.copy();
                assertNotSame(x, x2);
@@ -219,14 +218,14 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void d05_writeTo() throws Exception {
-               var x = new BasicResource(new StringEntity(null, "writeMe"));
+               var x = new StringResource(null, "writeMe");
                var out = new ByteArrayOutputStream();
                x.writeTo(out);
                assertEquals("writeMe", out.toString("UTF-8"));
        }
 
        @Test void d06_consumeContent() {
-               var x = new BasicResource(new StringEntity(null, "foo"));
+               var x = new StringResource(null, "foo");
                // consumeContent() is a no-op that must complete without 
throwing.
                assertDoesNotThrow(x::consumeContent);
        }
@@ -236,12 +235,12 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void e01_isUnmodifiable_default() {
-               var x = new BasicResource(new StringEntity(null, "foo"));
+               var x = new StringResource(null, "foo");
                assertFalse(x.isUnmodifiable());
        }
 
        @Test void e02_unmodifiable_returnsFrozenSnapshot() {
-               var x = new BasicResource(new StringEntity(null, "foo"));
+               var x = new StringResource(null, "foo");
                var u = x.unmodifiable();
                assertFalse(x.isUnmodifiable());
                assertTrue(u.isUnmodifiable());
@@ -256,13 +255,13 @@ class BasicResource_Test extends TestBase {
        }
 
        @Test void e03_unmodifiable_idempotent() {
-               var u = new BasicResource(new StringEntity(null, 
"foo")).unmodifiable();
+               var u = new StringResource(null, "foo").unmodifiable();
                // D1 idempotency: unmodifiable() on an already-unmodifiable 
snapshot returns the same instance.
                assertSame(u, u.unmodifiable());
        }
 
        @Test void e04_unmodifiable_snapshotIndependence() {
-               var x = new BasicResource(new StringEntity(null, 
"foo")).addHeader("X-A", "a");
+               var x = new StringResource(null, "foo").addHeader("X-A", "a");
                var u = x.unmodifiable();
                var before = u.getHeaders().size();
                x.addHeader("X-B", "b"); // Mutate original after snapshotting.
@@ -274,7 +273,7 @@ class BasicResource_Test extends TestBase {
        
//------------------------------------------------------------------------------------------------------------------
 
        @Test void f01_fluentReturns() {
-               var x = new BasicResource(new StringEntity(null, "foo"));
+               var x = new StringResource(null, "foo");
                assertSame(x, x.addHeader("X-A", "a"));
                assertSame(x, x.setHeader("X-B", "b"));
                assertSame(x, x.addHeaders(header("X-C", "c")));


Reply via email to