TCK Migration: Move pending jaxrs/ee/rs/core,client,ext tests from jakartaee-tck (#1029)
* Initial change to lift tests from jaxrs/ee/rs/client,core,ext folders in jakartaee-tck
- Removed the build.xml files
- Moved web.xml.template to corresponding resources folder
* fix compilation errors
- rename packages
- add missing classes/jar dependencies
- assertFault change to assertTrue
- deployment code, test run log
* JAXRSClient to JAXRSClientIT for test files
* enable and fix tests
- add @Test annotation
- change assertTrue arguments to append as string
- add classes or packages for archive deployable
- JAXRSProvidersClientIT not to inherit core.application.JAXRSClientIT , duplicate test methods
* fix securitycontext tests, disable failing tests
* correct bad values for system variables
diff --git a/jaxrs-tck/pom.xml b/jaxrs-tck/pom.xml
index 16e7867..5119ba6 100644
--- a/jaxrs-tck/pom.xml
+++ b/jaxrs-tck/pom.xml
@@ -153,7 +153,11 @@
<version>2.0.1</version>
</dependency>
-
+ <dependency>
+ <groupId>jakarta.validation</groupId>
+ <artifactId>jakarta.validation-api</artifactId>
+ <version>3.0.0</version>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/ContextProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/ContextProvider.java
new file mode 100644
index 0000000..742c11d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/ContextProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ContextProvider implements ClientRequestFilter {
+
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ throw new Fault("this TCK method is not implemented yet");
+ }
+
+ @Override
+ public void filter(ClientRequestContext context) throws IOException {
+ try {
+ checkFilterContext(context);
+ } catch (Fault e) {
+ throw new IOException(e);
+ }
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java
new file mode 100644
index 0000000..153725a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+/**
+ * Counter should remain the same as any change would suggest that the
+ * getPropertyNames collection is not immutable
+ */
+public class GetPropertyNamesIsImmutableProvider extends ContextProvider {
+ private AtomicInteger counter;
+
+ public static final String NEWNAME = "AnyNewNameAddedToPropertyNames";
+
+ public GetPropertyNamesIsImmutableProvider(AtomicInteger counter) {
+ super();
+ this.counter = counter;
+ }
+
+ @Override
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ Collection<String> properties = context.getPropertyNames();
+ try {
+ properties.add(NEWNAME);
+ } catch (Exception e) {
+ // any possible exception here is ok as collection should be
+ // immutable
+ }
+ properties = context.getPropertyNames();
+ if (properties.contains(NEWNAME))
+ counter.set(counter.get() + 100);
+ context.abortWith(Response.ok(counter.get()).build());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java
new file mode 100644
index 0000000..0ea80fc
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class GetPropertyNamesProvider extends ContextProvider {
+ private AtomicInteger counter;
+
+ public GetPropertyNamesProvider(AtomicInteger counter) {
+ super();
+ this.counter = counter;
+ }
+
+ @Override
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ if (counter.incrementAndGet() == 2) {
+ Collection<String> properties = context.getPropertyNames();
+ String entity = properties == null ? "NULL"
+ : JaxrsUtil.iterableToString(";", properties);
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ } else {
+ context.setProperty("PROPERTY1", "value1");
+ context.setProperty("PROPERTY2", "value2");
+ }
+ }
+
+ protected static <T> String collectionToString(Collection<T> collection) {
+ StringBuilder sb = new StringBuilder();
+ for (T t : collection)
+ sb.append(t).append(";");
+ return sb.toString();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java
new file mode 100644
index 0000000..56ae44a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class GetSetPropertyProvider extends ContextProvider {
+ private AtomicInteger counter;
+
+ public GetSetPropertyProvider(AtomicInteger counter) {
+ super();
+ this.counter = counter;
+ }
+
+ @Override
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ Object property = context.getProperty("PROPERTY");
+ String entity = property == null ? "NULL" : property.toString();
+ if (counter.incrementAndGet() == 2) {
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ } else
+ context.setProperty("PROPERTY", "value");
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java
new file mode 100644
index 0000000..3686107
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java
@@ -0,0 +1,1485 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.io.ByteArrayInputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+import jakarta.ws.rs.tck.common.provider.StringBeanWithAnnotation;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ * ts_home;
+ */
+public class JAXRSClient extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = 8883841555516513076L;
+
+ /**
+ * Entry point for different-VM execution. It should delegate to method
+ * run(String[], PrintWriter, PrintWriter), and this method should not contain
+ * any test configuration.
+ */
+ // public static void main(String[] args) {
+ // new JAXRSClient().run(args);
+ // }
+
+ /* Run test */
+
+ /*
+ * @testName: abortWithTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:427; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Abort the filter chain with a response. This method breaks
+ * the filter chain processing and returns the provided response back to the
+ * client. The provided response goes through the chain of applicable response
+ * filters.
+ *
+ * ClientRequestFilter.filter ClientRequestFilter.abortWith
+ */
+ public void abortWithTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Response r = Response.status(Status.CREATED).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation i = buildInvocation(provider);
+ Response r = invoke(i);
+ assertStatus(r, Status.CREATED);
+ }
+
+ /*
+ * @testName: getAcceptableLanguagesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a list of languages that are acceptable for the
+ * response. Returns: a read-only list of acceptable languages sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.filter ClientRequestFilter.abortWith
+ */
+ public void getAcceptableLanguagesTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<Locale> locales = context.getAcceptableLanguages();
+ String languages = JaxrsUtil.iterableToString(";", locales);
+ Response r = Response.ok(languages).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation.Builder builder = buildBuilder(provider);
+ Invocation invocation;
+ invocation = builder.acceptLanguage(Locale.CANADA_FRENCH)
+ .acceptLanguage(Locale.PRC).buildGet();
+ Response response = invoke(invocation);
+ String entity = response.readEntity(String.class);
+ assertContains(entity, Locale.CANADA_FRENCH.toString());
+ assertContains(entity, Locale.PRC.toString());
+ }
+
+ /*
+ * @testName: getAcceptableLanguagesByWeightsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: a read-only list of requested response media types sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.filter ClientRequestFilter.abortWith
+ */
+ public void getAcceptableLanguagesByWeightsTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<Locale> locales = context.getAcceptableLanguages();
+ String languages = JaxrsUtil.iterableToString(";", locales);
+ Response r = Response.ok(languages).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation.Builder builder = buildBuilder(provider);
+ Invocation invocation;
+ invocation = builder.acceptLanguage("da, en-gb;q=0.6, en-us;q=0.7")
+ .buildGet();
+ Response response = invoke(invocation);
+ String entity = response.readEntity(String.class).toLowerCase();
+ assertContains(entity, "da");
+ assertContains(entity, "gb");
+ assertContains(entity, "us");
+ int indexDa = entity.indexOf("da");
+ int indexUs = entity.indexOf("us");
+ int indexGb = entity.indexOf("gb");
+
+ assertTrue(indexDa < indexUs && indexUs < indexGb,
+ "List of acceptable languages"+ entity+ "is not sorted by q values");
+ }
+
+ /*
+ * @testName: getAcceptableLanguagesIsImmutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: a read-only list of requested response media types sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getAcceptableLanguagesIsImmutableTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<Locale> locales = context.getAcceptableLanguages();
+ try {
+ locales.add(Locale.JAPAN);
+ } catch (Exception e) {
+ // either exception is thrown, or add does nothing
+ }
+ locales = context.getAcceptableLanguages();
+ boolean b = locales.contains(Locale.JAPAN);
+ assertTrue(!b, "getAcceptableLanguages is not read-only");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ WebTarget target = buildTarget(provider);
+ Invocation.Builder builder = target.request();
+ Invocation invocation;
+ invocation = builder
+ .header("Accept-Language", "da, en-gb;q=0.6, en-us;q=0.7").buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getAcceptableMediaTypesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a list of media types that are acceptable for the
+ * response. Returns a read-only list of requested response media types sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getAcceptableMediaTypesTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<MediaType> types = context.getAcceptableMediaTypes();
+ String medias = JaxrsUtil.iterableToString(";", types);
+ Response r = Response.ok(medias).build();
+ context.abortWith(r);
+ }
+ };
+ String media = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5";
+ Invocation.Builder builder = buildBuilder(provider);
+ Invocation invocation = builder.header("Accept", media).buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "text/*");
+ assertContains(entity, "text/html");
+ assertContains(entity, "*/*");
+ }
+
+ /*
+ * @testName: getAcceptableMediaTypesIsSortedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a list of media types that are acceptable for the
+ * response. Returns a read-only list of requested response media types sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getAcceptableMediaTypesIsSortedTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<MediaType> types = context.getAcceptableMediaTypes();
+ String medias = JaxrsUtil.iterableToString(";", types);
+ Response r = Response.ok(medias).build();
+ context.abortWith(r);
+ }
+ };
+ String media = "text/plain;q=0.3, text/html;q=0.7, text/xml;level=1, text/java;level=2;q=0.4, */*;q=0.5";
+ Invocation.Builder builder = buildBuilder(provider);
+ Invocation invocation = builder.header("Accept", media).buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class).toLowerCase();
+ int indexXml = entity.indexOf(MediaType.TEXT_XML);
+ int indexHtml = entity.indexOf(MediaType.TEXT_HTML);
+ int indexAny = entity.indexOf(MediaType.WILDCARD);
+ int indexJava = entity.indexOf("text/java");
+ int indexPlain = entity.indexOf(MediaType.TEXT_PLAIN);
+
+ assertTrue(indexXml < indexHtml && indexHtml < indexAny
+ && indexAny < indexJava && indexJava < indexPlain, "Media Types"+
+ entity+ "are not sorted");
+ }
+
+ /*
+ * @testName: getAcceptableMediaTypesIsImmutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a list of media types that are acceptable for the
+ * response. Returns a read-only list of requested response media types sorted
+ * according to their q-value, with highest preference first.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getAcceptableMediaTypesIsImmutableTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ List<MediaType> types = context.getAcceptableMediaTypes();
+ try {
+ types.add(MediaType.APPLICATION_JSON_TYPE);
+ } catch (Exception e) {
+ // either exception is thrown or add does nothing
+ }
+ types = context.getAcceptableMediaTypes();
+ boolean b = types.contains(MediaType.APPLICATION_JSON_TYPE);
+ assertTrue(!b, "getAcceptableMediaTypes is not read only");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ String media = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5";
+ Invocation.Builder builder = buildBuilder(provider);
+ Invocation invocation = builder.header("Accept", media).buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getClientTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:430; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the client instance associated with the request.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getClientTest() throws Fault {
+ final Client client = ClientBuilder.newClient();
+
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Client contextClient = context.getClient();
+ assertTrue(client == contextClient,
+ "the client instance is different from the context one");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ client.register(provider);
+ WebTarget target = client.target(getUrl());
+ Invocation invocation = target.request().buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getConfigurationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:977; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the immutable configuration of the request.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getConfigurationTest() throws Fault {
+ final Client client = ClientBuilder.newClient();
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Client contextClient = context.getClient();
+ assertEquals(contextClient, client,
+ "the client instance is different from the context one");
+ Configuration contextConfig = context.getConfiguration();
+ assertNotNull(contextConfig,
+ "context.getConfiguration() returned null");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ client.register(provider);
+ WebTarget target = client.target(getUrl());
+ Invocation invocation = target.request().buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getCookiesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:432; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get any cookies that accompanied the request. Returns a
+ * read-only map of cookie name (String) to Cookie.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getCookiesTest() throws Fault {
+ Cookie cts = new Cookie("cts", "cts");
+ Cookie tck = new Cookie("tck", "tck");
+ Cookie jee = new Cookie("jee", "jee");
+
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ String cookies = JaxrsUtil.iterableToString(";",
+ context.getCookies().values());
+ Response r = Response.ok(cookies).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).cookie(cts).cookie(tck)
+ .cookie(jee).buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "cts");
+ assertContains(entity, "tck");
+ assertContains(entity, "jee");
+ }
+
+ /*
+ * @testName: getCookiesIsImmutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:432; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get any cookies that accompanied the request. Returns a
+ * read-only map of cookie name (String) to Cookie.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getCookiesIsImmutableTest() throws Fault {
+ final Cookie cts = new Cookie("cts", "cts");
+
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Map<String, Cookie> cookies = context.getCookies();
+ try {
+ cookies.put("test", cts);
+ } catch (Exception e) {
+ // either exception is thrown or put does nothing
+ }
+ cookies = context.getCookies();
+ Cookie cookie = cookies.get("test");
+ assertTrue(cookie == null, "getCookies is not read-only");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).cookie(cts).buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getDateNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:433; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get message date. Returns: the message date, otherwise null
+ * if not present.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getDateNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Date date = context.getDate();
+ Response r = Response.ok(date == null ? "NULL" : date.toString())
+ .build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildInvocation(provider);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "NULL");
+ }
+
+ /*
+ * @testName: getDateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:433; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get message date. Returns: the message date, otherwise null
+ * if not present.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getDateTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Date date = context.getDate();
+ Response r = Response.ok(date.toString()).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider)
+ .header("Date", "Tue, 15 Nov 1994 08:12:31 GMT").buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "Nov");
+ assertContains(entity, "1994");
+ assertContains(entity, "31");
+ }
+
+ /*
+ * @testName: getEntityNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:434; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the message entity Java instance. Returns null if the
+ * message does not contain an entity.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Object entity = context.getEntity();
+ Response r = Response.ok(entity == null ? "NULL" : entity.toString())
+ .build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildInvocation(provider);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "NULL");
+ }
+
+ /*
+ * @testName: getEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:434; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get the message entity Java instance. Returns null if the
+ * message does not contain an entity.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Object entity = context.getEntity();
+ Response r = Response.ok(entity.toString()).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> post = createEntity("test");
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "test");
+ }
+
+ /*
+ * @testName: getEntityAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the annotations attached to the entity. Note that the
+ * returned annotations array contains only those annotations explicitly
+ * attached to entity instance (such as the ones attached using
+ * Entity.Entity(Object, jakarta.ws.rs.core.MediaType,
+ * java.lang.annotation.Annotation[]) method).
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityAnnotationsTest() throws Fault {
+ Annotation[] annotations = ContextProvider.class.getAnnotations();
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Annotation[] annotations = context.getEntityAnnotations();
+ String first = annotations == null ? "NULL"
+ : annotations.length == 0 ? "0"
+ : annotations[0].annotationType().getName();
+ Response r = Response.ok(first).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> post = Entity.entity("test", MediaType.WILDCARD_TYPE,
+ annotations);
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, annotations[0].annotationType().getName());
+ }
+
+ /*
+ * @testName: getEntityAnnotationsIsNotTakenFromEntityClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the annotations attached to the entity. Note that the
+ * returned annotations array contains only those annotations explicitly
+ * attached to entity instance (such as the ones attached using
+ * Entity.Entity(Object, jakarta.ws.rs.core.MediaType,
+ * java.lang.annotation.Annotation[]) method). The entity instance annotations
+ * array does not include annotations declared on the entity implementation
+ * class or its ancestors.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityAnnotationsIsNotTakenFromEntityClassTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Annotation[] annotations = context.getEntityAnnotations();
+ String first = annotations == null ? "0"
+ : String.valueOf(annotations.length);
+ Response r = Response.ok(first).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<StringBeanWithAnnotation> post = createEntity(
+ new StringBeanWithAnnotation("test"));
+ Invocation invocation = buildTarget(provider)
+ .register(StringBeanEntityProvider.class).request().buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "0");
+ }
+
+ /*
+ * @testName: getEntityAnnotationsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the annotations attached to the entity.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityAnnotationsNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Annotation[] annotations = context.getEntityAnnotations();
+ String len = annotations == null ? "0"
+ : String.valueOf(annotations.length);
+ Response r = Response.ok(len).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> post = createEntity("test");
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "0");
+ }
+
+ /*
+ * @testName: getEntityClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:436; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the raw entity type information.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityClassTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Class<?> clazz = context.getEntityClass();
+ Response r = Response.ok(clazz.getName()).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<ByteArrayInputStream> post = createEntity(
+ new ByteArrayInputStream("test".getBytes()));
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, ByteArrayInputStream.class.getName());
+ }
+
+ /*
+ * @testName: getEntityClassListStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:436; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the raw entity type information.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityClassListStringTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Class<?> clazz = context.getEntityClass();
+ Response r = Response.ok(clazz.getName()).build();
+ context.abortWith(r);
+ }
+ };
+ List<String> list = new ArrayList<String>();
+ Entity<List<String>> post = createEntity(list);
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, ArrayList.class.getName());
+ }
+
+ /*
+ * @testName: getEntityTypeListStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:438; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the generic entity type information.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getEntityTypeListStringTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Type type = context.getEntityType();
+ String entity = type.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ List<String> list = new ArrayList<String>();
+ GenericEntity<List<String>> generic = new GenericEntity<List<String>>(
+ list) {
+ };
+ Entity<GenericEntity<List<String>>> post = createEntity(generic);
+ Invocation invocation = buildBuilder(provider).buildPost(post);
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, String.class.getName());
+ }
+
+ /*
+ * @testName: getHeadersTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:439; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the mutable request headers multivalued map.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getHeadersTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ String entity = JaxrsUtil.iterableToString(";", headers.keySet());
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider)
+ .header("Accept", MediaType.TEXT_HTML).header("tck", "cts")
+ .header("Date", "Tue, 15 Nov 1994 08:12:31 GMT").buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "Accept");
+ assertContains(entity, "Date");
+ assertContains(entity, "tck");
+ }
+
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the mutable request headers multivalued map.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getHeadersIsMutableTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ headers.add("Accept", MediaType.APPLICATION_JSON);
+
+ headers = context.getHeaders();
+ String entity = JaxrsUtil.iterableToString(";", headers.keySet());
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).buildGet();
+ Response response = invoke(invocation);
+
+ String entity = response.readEntity(String.class);
+ assertContains(entity, "Accept");
+ }
+
+ /*
+ * @testName: getHeaderStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a message header as a single string value.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getHeaderStringTest() throws Fault {
+ final String TCK = "cts";
+ final String DATE = "Tue, 15 Nov 1994 08:12:31 GMT";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ String value;
+ value = context.getHeaderString("tck");
+ assertContainsIgnoreCase(value, TCK, "The expected value", TCK,
+ "was not found, found", value, "instead");
+ value = context.getHeaderString("accept");
+ assertContainsIgnoreCase(value, MediaType.TEXT_HTML,
+ "The expected value", MediaType.TEXT_HTML, "was not found, found",
+ value, "instead");
+ value = context.getHeaderString("date");
+ assertContainsIgnoreCase(value, DATE, "The expected value", DATE,
+ "was not found, found", value, "instead");
+ Response r = Response.ok().build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider)
+ .header("Accept", MediaType.TEXT_HTML)
+ .header("tck", new StringBuffer().append(TCK)) // toString()
+ .header("Date", DATE).buildGet();
+ Response response = invoke(invocation);
+ assertStatus(response, Status.OK);
+ }
+
+ /*
+ * @testName: getHeaderStringUsingHeaderDelegateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a message header as a single string value. Each single
+ * header value is converted to String using a RuntimeDelegate.HeaderDelegate.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getHeaderStringUsingHeaderDelegateTest() throws Fault {
+ final String name = "BEAN";
+ final StringBean bean = new StringBean(name);
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ String value = context.getHeaderString(name);
+ Response r = Response.ok(value).build();
+ context.abortWith(r);
+ }
+ };
+ RuntimeDelegate original = RuntimeDelegate.getInstance();
+ RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+ try {
+ Invocation invocation = buildBuilder(provider).header(name, bean)
+ .buildGet();
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertContains(name.toLowerCase(), body.toLowerCase());
+ } finally {
+ RuntimeDelegate.setInstance(original);
+ StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+ }
+ }
+
+ /*
+ * @testName: getLanguageIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:441; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the language of the entity. Returns: the language of
+ * the entity or null if not specified
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getLanguageIsNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Locale lang = context.getLanguage();
+ String entity = lang == null ? "NULL" : lang.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> entity = createEntity("TEST");
+ Invocation invocation = buildBuilder(provider).buildPost(entity);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "NULL");
+ }
+
+ /*
+ * @testName: getLanguageTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:441; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the language of the entity. Returns: the language of
+ * the entity or null if not specified
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getLanguageTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Locale lang = context.getLanguage();
+ String entity = lang == null ? "NULL" : lang.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Locale locale = Locale.TRADITIONAL_CHINESE;
+ Variant variant = new Variant(MediaType.TEXT_XML_TYPE, locale, null);
+ Entity<String> entity = Entity.entity("TEST", variant);
+ Invocation invocation = buildBuilder(provider).buildPost(entity);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class).toLowerCase().replace('-',
+ '_');
+ assertContains(body, locale.toString().toLowerCase());
+ }
+
+ /*
+ * @testName: getMediaTypeIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:442; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the media type of the entity. Returns: the media type
+ * or null if not specified (e.g. there's no request entity).
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getMediaTypeIsNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MediaType media = context.getMediaType();
+ String entity = media == null ? "NULL" : media.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).buildGet();
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "NULL");
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:442; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the media type of the entity. Returns: the media type
+ * or null if not specified (e.g. there's no request entity).
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getMediaTypeTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MediaType media = context.getMediaType();
+ String entity = media == null ? "NULL" : media.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> entity = Entity.entity("TEST",
+ MediaType.APPLICATION_FORM_URLENCODED);
+ Invocation invocation = buildBuilder(provider).buildPost(entity);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, MediaType.APPLICATION_FORM_URLENCODED);
+ }
+
+ /*
+ * @testName: getMethodTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:443; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the request method.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getMethodTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ String method = context.getMethod();
+ Response r = Response.ok(method).build();
+ context.abortWith(r);
+ }
+ };
+ Entity<String> entity = createEntity("TEST");
+ Invocation invocation;
+ Response response;
+
+ for (String method : new String[] { "OPTIONS", "DELETE", "GET", "TRACE" }) {
+ invocation = buildBuilder(provider).build(method);
+ response = invoke(invocation);
+ String body = response.readEntity(String.class).toUpperCase();
+ assertContains(body, method);
+ }
+
+ for (String method : new String[] { "PUT", "POST" }) {
+ invocation = buildBuilder(provider).build(method, entity);
+ response = invoke(invocation);
+ String body = response.readEntity(String.class).toUpperCase();
+ assertContains(body, method);
+ }
+ }
+
+ /*
+ * @testName: getPropertyIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:444; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Returns the property with the given name registered in the
+ * current request/response exchange context, or null if there is no property
+ * by that name.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getPropertyIsNullTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ Object property = context.getProperty("PROPERTY");
+ String entity = property == null ? "NULL" : property.toString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).buildGet();
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "NULL");
+ }
+
+ /*
+ * @testName: getSetPropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:444; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+ * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Returns the property with the given name registered in the
+ * current request/response exchange context, or null if there is no property
+ * by that name.
+ *
+ * Binds an object to a given property name in the current request/response
+ * exchange context.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getSetPropertyTest() throws Fault {
+ final AtomicInteger counter = new AtomicInteger(0);
+ ContextProvider provider = new GetSetPropertyProvider(counter);
+ ContextProvider provider2 = new GetSetPropertyProvider(counter) {
+ };
+
+ Invocation invocation = buildInvocation(provider, provider2);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "value");
+ }
+
+ /*
+ * @testName: getPropertyNamesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:978; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+ * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Returns an immutable collection containing the property
+ * names available within the context of the current request/response exchange
+ * context.
+ *
+ * Binds an object to a given property name in the current request/response
+ * exchange context.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getPropertyNamesTest() throws Fault {
+ final AtomicInteger counter = new AtomicInteger(0);
+ ContextProvider provider = new GetPropertyNamesProvider(counter);
+ ContextProvider provider2 = new GetPropertyNamesProvider(counter) {
+ };
+
+ Invocation invocation = buildInvocation(provider, provider2);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "PROPERTY1");
+ assertContains(body, "PROPERTY2");
+ }
+
+ /*
+ * @testName: getPropertyNamesIsImmutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:978; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+ * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Returns an immutable collection containing the property
+ * names available within the context of the current request/response exchange
+ * context.
+ *
+ * Binds an object to a given property name in the current request/response
+ * exchange context.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getPropertyNamesIsImmutableTest() throws Fault {
+ final AtomicInteger counter = new AtomicInteger(0);
+ ContextProvider provider = new GetPropertyNamesIsImmutableProvider(counter);
+
+ Invocation invocation = buildInvocation(provider);
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertEqualsInt(0, counter.get(),
+ "getPropertyNames collection is not immutable");
+ assertEquals("0", body, "getPropertyNames collection is not immutable");
+ logMsg("getPropertyNames is immutable as expected");
+ }
+
+ /*
+ * @testName: getStringHeadersTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a string view of header values associated with the
+ * message.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getStringHeadersTest() throws Fault {
+ final String TCK = "cts";
+ final String DATE = "Tue, 15 Nov 1994 08:12:31 GMT";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MultivaluedMap<String, String> map;
+ map = context.getStringHeaders();
+ StringBuilder value = new StringBuilder();
+ value.append(map.getFirst("Accept")).append(" ");
+ value.append(map.getFirst("tck")).append(" ");
+ value.append(map.getFirst("Date"));
+ Response r = Response.ok(value.toString()).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider)
+ .header("Accept", MediaType.TEXT_HTML).header("tck", TCK)
+ .header("Date", DATE).buildGet();
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertContains(body, MediaType.TEXT_HTML);
+ assertContains(body, TCK);
+ assertContains(body, DATE);
+ }
+
+ /*
+ * @testName: getStringHeadersReflectsTheUnderlayingMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a string view of header values associated with the
+ * message. Changes in the underlying headers map are reflected in this view.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getStringHeadersReflectsTheUnderlayingMapTest() throws Fault {
+ final String TCK = "cts";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ context.getHeaders().add(TCK, TCK);
+ MultivaluedMap<String, String> map;
+ map = context.getStringHeaders();
+ String value = map.getFirst(TCK);
+ Response r = Response.ok(value).build();
+ context.abortWith(r);
+ }
+ };
+ Invocation invocation = buildBuilder(provider).buildGet();
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertContains(body, TCK);
+ }
+
+ /*
+ * @testName: getStringHeadersUsingHeaderDelegateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get a string view of header values associated with the
+ * message. The method converts the non-string header values to strings using
+ * a RuntimeDelegate.HeaderDelegate
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getStringHeadersUsingHeaderDelegateTest() throws Fault {
+ final String TCK = "cts";
+ final StringBean bean = new StringBean(TCK);
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MultivaluedMap<String, String> map;
+ map = context.getStringHeaders();
+ StringBuilder value = new StringBuilder();
+ value.append(map.getFirst(TCK));
+ Response r = Response.ok(value.toString()).build();
+ context.abortWith(r);
+ }
+ };
+ RuntimeDelegate delegate = RuntimeDelegate.getInstance();
+ RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(delegate));
+ try {
+ Invocation invocation = buildBuilder(provider).header(TCK, bean)
+ .buildGet();
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertContains(body, TCK);
+ } finally {
+ RuntimeDelegate.setInstance(delegate);
+ StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+ }
+ }
+
+ /*
+ * @testName: getUriTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:447; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Get the request URI.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void getUriTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ URI uri = context.getUri();
+ String entity = uri.toASCIIString();
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+
+ Invocation invocation = buildInvocation(provider);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, getUrl());
+ }
+
+ /*
+ * @testName: hasEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:448; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy: Check if there is an entity available in the request. The
+ * method returns true if the entity is present, returns false otherwise.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void hasEntityTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ boolean has = context.hasEntity();
+ String entity = String.valueOf(has);
+ Response r = Response.ok(entity).build();
+ context.abortWith(r);
+ }
+ };
+
+ Invocation invocation = buildInvocation(provider);
+ Response response = invoke(invocation);
+ String body = response.readEntity(String.class);
+ assertContains(body, "false");
+
+ Entity<String> entity = createEntity("TEST");
+ WebTarget target = buildTarget(provider);
+ invocation = target.request().buildPost(entity);
+ response = invoke(invocation);
+ body = response.readEntity(String.class);
+ assertContains(body, "true");
+ }
+
+ /*
+ * @testName: removePropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:449; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+ *
+ * @test_Strategy:Removes a property with the given name from the current
+ * request/response exchange context. After removal, subsequent calls to
+ * getProperty(java.lang.String) to retrieve the property value will return
+ * null.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void removePropertyTest() throws Fault {
+ final AtomicInteger counter = new AtomicInteger(0);
+ ContextProvider provider = new RemovePropertyProvider(counter);
+ ContextProvider provider2 = new RemovePropertyProvider(counter) {
+ };
+ ContextProvider provider3 = new RemovePropertyProvider(counter) {
+ };
+
+ Invocation invocation = buildInvocation(provider, provider2, provider3);
+ Response response = invoke(invocation);
+
+ String body = response.readEntity(String.class);
+ assertContains(body, "NULL");
+ }
+
+ /*
+ * @testName: setEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:450; JAXRS:JAVADOC:434; JAXRS:JAVADOC:435;
+ * JAXRS:JAVADOC:438; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Set a new response message entity. It is the callers
+ * responsibility to wrap the actual entity with
+ * jakarta.ws.rs.core.GenericEntity if preservation of its generic type is
+ * required.
+ *
+ * ClientRequestFilter.abortWith
+ */
+ public void setEntityTest() throws Fault {
+ final AtomicInteger counter = new AtomicInteger(0);
+
+ ContextProvider provider = new SetEntityProvider(counter);
+ ContextProvider provider2 = new SetEntityProvider(counter) {
+ };
+
+ Entity<ByteArrayInputStream> entity = createEntity(
+ new ByteArrayInputStream("test".getBytes()));
+
+ WebTarget target = buildTarget(provider, provider2);
+ Invocation invocation = target.request().buildPost(entity);
+ Response response = invoke(invocation);
+
+ assertStatus(response, Status.OK);
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ /**
+ * Call given provider CheckContextFilter method
+ */
+ protected static Response invoke(Invocation i) throws Fault {
+ Response r = null;
+ try {
+ r = i.invoke();
+ } catch (Exception e) {
+ Object cause = e.getCause();
+ if (cause instanceof Fault)
+ throw (Fault) cause;
+ else
+ throw new Fault(e);
+ }
+ return r;
+ }
+
+ protected static Invocation buildInvocation(ContextProvider... provider) {
+ WebTarget target = buildTarget(provider);
+ Invocation i = target.request().buildGet();
+ return i;
+ }
+
+ protected static WebTarget buildTarget(ContextProvider... providers) {
+ Client client = ClientBuilder.newClient();
+ for (ContextProvider provider : providers)
+ client.register(provider);
+ WebTarget target = client.target(getUrl());
+ return target;
+ }
+
+ protected static Invocation.Builder buildBuilder(
+ ContextProvider... provider) {
+ Invocation.Builder builder = buildTarget(provider).request();
+ return builder;
+ }
+
+ protected static void assertStatus(Response r, Status status) throws Fault {
+ assertTrue(r.getStatus() == status.getStatusCode(), "Expected"+
+ status.getStatusCode()+ "got"+ r.getStatus());
+ TestUtil.logMsg("Found expected status: " + status.getStatusCode());
+ }
+
+ protected static void assertContains(String string, String substring)
+ throws Fault {
+ assertTrue(string.contains(substring), string+ "does NOT contain"+
+ substring+ ", it is:"+ string);
+ TestUtil.logMsg("Found expected substring: " + substring);
+ }
+
+ /**
+ * @return any possible url
+ */
+ protected static String getUrl() {
+ return "http://localhost:8080/404URL/";
+ }
+
+ protected <T> Entity<T> createEntity(T entity) {
+ return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java
new file mode 100644
index 0000000..be186e3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class RemovePropertyProvider extends ContextProvider {
+ private AtomicInteger counter;
+
+ public RemovePropertyProvider(AtomicInteger counter) {
+ super();
+ this.counter = counter;
+ }
+
+ @Override
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ String propName = "PROPERTY";
+ switch (counter.incrementAndGet()) {
+ case 1:
+ Object property = context.getProperty(propName);
+ assertFault(property == null, "property already exist");
+ context.setProperty(propName, propName);
+ break;
+ case 2:
+ property = context.getProperty(propName);
+ assertFault(property != null, "property not exist");
+ context.removeProperty(propName);
+ break;
+ case 3:
+ property = context.getProperty(propName);
+ assertFault(property == null, "property already exist");
+ Response response = Response.ok("NULL").build();
+ context.abortWith(response);
+ break;
+ }
+ }
+
+ /**
+ * @param conditionTrue
+ * @param message
+ * @throws Fault
+ * when conditionTrue is not met with message provided
+ */
+ protected static void //
+ assertFault(boolean conditionTrue, Object... message) throws Fault {
+ if (!conditionTrue) {
+ StringBuilder sb = new StringBuilder();
+ for (Object msg : message)
+ sb.append(msg).append(" ");
+ throw new Fault(sb.toString());
+ }
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java
new file mode 100644
index 0000000..376827e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+public class SetEntityProvider extends ContextProvider {
+ private AtomicInteger counter;
+
+ protected Annotation anno1 = new GET() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+
+ protected Annotation anno2 = new POST() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+ };
+
+ protected Annotation[] annos = new Annotation[] { anno1, anno2 };
+
+ protected MediaType type = MediaType.MULTIPART_FORM_DATA_TYPE;
+
+ protected String entityName = "ENTITY";
+
+ public SetEntityProvider(AtomicInteger counter) {
+ super();
+ this.counter = counter;
+ }
+
+ /**
+ * This method expects the request with entity != String.class has been sent
+ * Also, the mediaType is MediaType.WILDCARD_TYPE
+ */
+ @Override
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ Object entity;
+ MediaType mtype;
+ Annotation[] annotations;
+ Type clz;
+ switch (counter.incrementAndGet()) {
+ case 1:
+ TestUtil.logMsg("Counter is 1");
+ // get
+ entity = context.getEntity();
+ mtype = context.getMediaType();
+ annotations = context.getEntityAnnotations();
+ clz = context.getEntityType();
+ // check
+ assertFault(entity != null, "there is no entity, yet");
+ assertFault(!entity.toString().equals(entityName),
+ "the fake entity was already set");
+ assertFault(annotations == null || annotations.length == 0,
+ "there are already annotations!");
+ assertFault(!mtype.equals(type), "fake MediaType is already set");
+ assertFault(clz != String.class, "String entity is already set");
+ // set
+ context.setEntity(entityName, annos, type);
+ break;
+ case 2:
+ TestUtil.logMsg("Counter is 2");
+ // get
+ entity = context.getEntity();
+ mtype = context.getMediaType();
+ annotations = context.getEntityAnnotations();
+ clz = context.getEntityType();
+ // check
+ assertFault(entity != null, "there is no entity set");
+ assertFault(entity.toString().equals(entityName),
+ "there is no fake entity set, yet");
+ assertFault(annotations.length == 2,
+ "the fake annotations were not set, yet");
+ assertFault(mtype.equals(type), "fake MediaType was not set, yet");
+ assertFault(clz == String.class, "String entity not set, yet");
+ // set
+ context.setEntity(entityName, annos, type);
+ Response response = Response.ok().build();
+ context.abortWith(response);
+ break;
+ }
+ }
+
+ /**
+ * @param conditionTrue
+ * @param message
+ * @throws Fault
+ * when conditionTrue is not met with message provided
+ */
+ protected static void //
+ assertFault(boolean conditionTrue, Object message) throws Fault {
+ if (!conditionTrue) {
+ throw new Fault(message.toString());
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java
new file mode 100644
index 0000000..66ca227
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.WebTarget;
+
+public abstract class Assertable {
+ final static String[] LOCATION = { "Client", "WebTarget",
+ "Invocation.Builder", "Invocation" };
+
+ private int locationIndex = 0;
+
+ public abstract void check1OnClient(Client client) throws Fault;
+
+ public abstract void check2OnTarget(WebTarget target) throws Fault;
+
+ public void incrementLocation() {
+ locationIndex = (locationIndex + 1 == LOCATION.length) ? 0
+ : locationIndex + 1;
+ }
+
+ public String getLocation() {
+ return new StringBuilder().append("on ").append(LOCATION[locationIndex])
+ .append(" configuration").toString();
+ }
+
+ public static String getLocation(int index) {
+ return LOCATION[index];
+ }
+
+ public int getLocationIndex() {
+ return locationIndex;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java
new file mode 100644
index 0000000..d8d406e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class CallableProvider
+ implements MessageBodyWriter<Callable<?>>, MessageBodyReader<Callable<?>> {
+
+ @Override
+ public long getSize(Callable<?> arg0, Class<?> arg1, Type arg2,
+ Annotation[] arg3, MediaType arg4) {
+ return arg0.toString().length();
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return Callable.class.isAssignableFrom(arg0);
+ }
+
+ @Override
+ public void writeTo(Callable<?> arg0, Class<?> arg1, Type arg2,
+ Annotation[] arg3, MediaType arg4, MultivaluedMap<String, Object> arg5,
+ OutputStream arg6) throws IOException, WebApplicationException {
+ arg6.write(arg0.toString().getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return isWriteable(type, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public Callable<?> readFrom(Class<Callable<?>> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders,
+ final InputStream entityStream)
+ throws IOException, WebApplicationException {
+ String content = null;
+ try {
+ content = JaxrsUtil.readFromStream(entityStream);
+ entityStream.close();
+ } catch (Exception e) {
+ content = "Error while reading Callable from InputStream";
+ }
+ return createCallable(content);
+ }
+
+ public static Callable<String> createCallable(final String content) {
+ Callable<String> callable = new Callable<String>() {
+ @Override
+ public String call() throws Exception {
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ return content;
+ }
+ };
+ return callable;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java
new file mode 100644
index 0000000..27e5b01
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Configurable;
+
+/**
+ * Wraps Client, WebTarget and Invocation objects that have configuration()
+ * method
+ */
+public interface ConfigurableObject {
+
+ void config(Configurable<?> config);
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java
new file mode 100644
index 0000000..650cf11
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+
+public class FeatureReturningFalse implements Feature {
+ @Override
+ public boolean configure(FeatureContext context) {
+ // false returning feature is not to be registered
+ return false;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java
new file mode 100644
index 0000000..d0cda9e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ * ts_home;
+ */
+public class JAXRSClient extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = -6880902064949040518L;
+
+ private int registeredClassesCnt = -1;
+
+ private int registeredInstancesCnt = -1;
+
+ /**
+ * Entry point for different-VM execution. It should delegate to method
+ * run(String[], PrintWriter, PrintWriter), and this method should not contain
+ * any test configuration.
+ */
+ // public static void main(String[] args) {
+ // new JAXRSClient().run(args);
+ // }
+
+ /* Run test */
+
+ /*
+ * @testName: registerFeatureClassReturningFalseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:754;
+ *
+ * @test_Strategy: Register a feature meta-provider to be instantiated and
+ * used in the scope of this configurable context.
+ *
+ * Any subsequent registration attempts for a component type, for which a
+ * class or instance-based registration already exists in the system MUST be
+ * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+ * inform the user about the rejected registration.
+ */
+ public void registerFeatureClassReturningFalseTest() throws Fault {
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int cnt = config.getConfiguration().getClasses().size();
+ assertEqualsInt(cnt, 1 + registeredClassesCnt,
+ "unexpected number of registered classes found:", cnt,
+ getLocation());
+ logMsg("Found", cnt, "features");
+ }
+
+ };
+ Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+ FeatureReturningFalse.class };
+ checkConfig(assertable, classes);
+ }
+
+ /*
+ * @testName: registerFeatureClassReturningFalseWithPriorityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:755;
+ *
+ * @test_Strategy: Register a feature meta-provider to be instantiated and
+ * used in the scope of this configurable context.
+ *
+ * Any subsequent registration attempts for a component type, for which a
+ * class or instance-based registration already exists in the system MUST be
+ * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+ * inform the user about the rejected registration.
+ */
+ public void registerFeatureClassReturningFalseWithPriorityTest()
+ throws Fault {
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int cnt = config.getConfiguration().getClasses().size();
+ assertEqualsInt(cnt, 1 + registeredClassesCnt,
+ "unexpected number of registered classes found:", cnt,
+ getLocation());
+ logMsg("Found", cnt, "features");
+ }
+
+ };
+
+ Registrar registrar = new Registrar() {
+ int priority = 0;
+
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ config.register((Class<?>) registerable, ++priority);
+ }
+ };
+
+ Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+ FeatureReturningFalse.class };
+ checkConfig(registrar, assertable, classes);
+ }
+
+ /*
+ * @testName: registerFeatureInstanceReturningFalseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:758;
+ *
+ * @test_Strategy: Register a feature. In case the registered provider is a
+ * client-side Feature feature, this object instantiates the feature and
+ * invokes the Feature#configure(FeatureContext) method and lets the feature
+ * update it's internal configuration state.
+ */
+ public void registerFeatureInstanceReturningFalseTest() throws Fault {
+ final Feature feature = new FeatureReturningFalse();
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int cnt = config.getConfiguration().getInstances().size();
+ assertEqualsInt(cnt, 1 + registeredInstancesCnt,
+ "unexpected number of registered instances found:", cnt,
+ getLocation());
+ logMsg("Found", cnt, "features");
+ }
+
+ };
+ Object[] features = new Object[] { feature, feature };
+ checkConfig(assertable, features);
+ }
+
+ /*
+ * @testName: registerClassContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: Register a feature meta-provider to be instantiated and
+ * used in the scope of this configurable context.
+ *
+ * Any subsequent registration attempts for a component type, for which a
+ * class or instance-based registration already exists in the system MUST be
+ * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+ * inform the user about the rejected registration.
+ */
+ public void registerClassContractsTest() throws Fault {
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int cnt = config.getConfiguration().getClasses().size();
+ assertEqualsInt(cnt, 1 + registeredClassesCnt,
+ "unexpected number of registered classes found:", cnt,
+ getLocation());
+ logMsg("Found", cnt, "features");
+ }
+
+ };
+
+ Registrar registrar = new Registrar() {
+ int priority = 0;
+
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ config.register((Class<?>) registerable, ++priority);
+ }
+ };
+
+ Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+ FeatureReturningFalse.class };
+ checkConfig(registrar, assertable, classes);
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ /**
+ * Check on every possible setting of configuration by a Feature or a
+ * singleton
+ *
+ */
+ protected void checkConfig(Assertable assertable, Object[] registerables)
+ throws Fault {
+ checkConfig(new Registrar(), assertable, registerables);
+ }
+
+ protected void checkConfig(Registrar registrar, Assertable assertable,
+ Object[] registerables) throws Fault {
+ Client client = ClientBuilder.newClient();
+ Configuration config = client.getConfiguration();
+ registeredClassesCnt = config.getClasses().size();
+ registeredInstancesCnt = config.getInstances().size();
+ logMsg("Already registered", registeredClassesCnt, "classes");
+ logMsg("Already registered", registeredInstancesCnt, "instances");
+
+ register(registrar, client, registerables[0]);
+ assertable.check1OnClient(client);
+ assertable.incrementLocation();
+
+ WebTarget target = client.target("http://tck.cts:888");
+ register(registrar, target, registerables[1]);
+ assertable.check2OnTarget(target);
+ assertable.incrementLocation();
+ }
+
+ protected void register(Registrar registrar, Configurable<?> config,
+ Object registerable) {
+ registrar.register(config, registerable);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java
new file mode 100644
index 0000000..efd796b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Configurable;
+
+/**
+ * We need the possibility to override the way the registerable is registered
+ * The default behavior is for single argument register method
+ */
+public class Registrar {
+ public void register(Configurable<?> config, Object registerable) {
+ if (registerable instanceof Class) // register(Class)
+ config.register((Class<?>) registerable);
+ else if (registerable instanceof String) // setProperty()
+ config.property((String) registerable, registerable);
+ else
+ // register(Object)
+ config.register(registerable);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java
new file mode 100644
index 0000000..3c4a76a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+
+public abstract class SingleCheckAssertable extends Assertable {
+
+ protected abstract void check(Configurable<?> configurable) throws Fault;
+
+ @Override
+ public void check1OnClient(Client client) throws Fault {
+ check(client);
+ }
+
+ @Override
+ public void check2OnTarget(WebTarget target) throws Fault {
+ check(target);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java
new file mode 100644
index 0000000..d53401b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+/**
+ * These annotations are to get them set in InterceptorBodyOne#setAnnotations()
+ */
+public enum ContextOperation {
+ GETANNOTATIONS, GETGENERICTYPE, GETMEDIATYPE, GETPROPERTY, GETPROPERTYNAMES, GETPROPERTYNAMESISREADONLY, GETTYPE, REMOVEPROPERTY, SETANNOTATIONS, SETANNOTATIONSNULL, SETGENERICTYPE, SETMEDIATYPE, SETPROPERTY, SETPROPERTYNULL, SETTYPE, IOEXCEPTION, WEBAPPLICATIONEXCEPTION
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java
new file mode 100644
index 0000000..18ae459
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class InputStreamReaderProvider implements
+ MessageBodyReader<InputStreamReader>, MessageBodyWriter<InputStreamReader> {
+
+ @Override
+ public long getSize(InputStreamReader arg0, Class<?> arg1, Type arg2,
+ Annotation[] arg3, MediaType arg4) {
+ return InputStreamReader.class.getName().length();
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return arg0 == InputStreamReader.class;
+ }
+
+ @Override
+ public void writeTo(InputStreamReader arg0, Class<?> arg1, Type arg2,
+ Annotation[] arg3, MediaType arg4, MultivaluedMap<String, Object> arg5,
+ OutputStream arg6) throws IOException, WebApplicationException {
+ String entity = JaxrsUtil.readFromReader(arg0);
+ arg0.close();
+ arg6.write(entity.getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return isWriteable(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public InputStreamReader readFrom(Class<InputStreamReader> arg0, Type arg1,
+ Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4,
+ InputStream arg5) throws IOException, WebApplicationException {
+ return new InputStreamReader(arg5);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java
new file mode 100644
index 0000000..f7dbce8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.InterceptorContext;
+
+public class InterceptorBodyOne<CONTEXT extends InterceptorContext>
+ extends TemplateInterceptorBody<CONTEXT> {
+
+ public void getAnnotations() {
+ Annotation[] annotations = context.getAnnotations();
+ setSeparatedEntity(";", annotations);
+ }
+
+ public void getGenericType() {
+ Type type = context.getGenericType();
+ String entity = null;
+ if (type instanceof Class)
+ entity = ((Class<?>) type).getName();
+ else
+ entity = type.toString();
+ setEntity(entity);
+ }
+
+ public void getMediaType() {
+ MediaType type = context.getMediaType();
+ setEntity(type);
+ }
+
+ public void getProperty() {
+ Object o = context.getProperty(PROPERTY);
+ setEntity(o == null ? NULL : ENTITY2);
+ }
+
+ public void getPropertyNames() {
+ for (int i = 0; i != 5; i++)
+ context.setProperty(PROPERTY + i, PROPERTY);
+ }
+
+ public void getPropertyNamesIsReadOnly() {
+ Collection<String> names = context.getPropertyNames();
+ int size = names.size();
+ for (int i = 0; i != 5; i++)
+ try {
+ names.add(PROPERTY + i);
+ } catch (Exception e) {
+ // exception is possible
+ }
+ names = context.getPropertyNames();
+ assertTrue(names.size() == size, "Unexpected property names", names);
+ setEntity(NULL);
+ }
+
+ public void getType() {
+ Class<?> type = context.getType();
+ setEntity(type.getName());
+ }
+
+ public void removeProperty() {
+ context.setProperty(PROPERTY, NULL);
+ assertTrue(NULL.equals(context.getProperty(PROPERTY)), PROPERTY,
+ "property not found");
+ context.removeProperty(PROPERTY);
+ Object o = context.getProperty(PROPERTY);
+ setEntity(o == null ? NULL : o.toString());
+ }
+
+ public void setAnnotations() {
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ context.setAnnotations(annotations);
+ getAnnotations();
+ }
+
+ public void setAnnotationsNull() {
+ try {
+ context.setAnnotations(null);
+ setEntity(NULL);
+ } catch (NullPointerException e) {
+ setEntity(NPE);
+ }
+ }
+
+ public void setGenericType() {
+ byte[] array = new byte[0];
+ context.setGenericType(array.getClass());
+ getGenericType();
+ }
+
+ public void setMediaType() {
+ MediaType type = MediaType.APPLICATION_FORM_URLENCODED_TYPE;
+ context.setMediaType(type);
+ getMediaType();
+ }
+
+ public void setProperty() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ENTITY2);
+ context.setProperty(PROPERTY, NULL);
+ context.setProperty(PROPERTY, sb);
+ }
+
+ public void setPropertyNull() {
+ context.setProperty(ENTITY2, ENTITY2);
+ assertTrue(context.getProperty(ENTITY2) != null, "Property", ENTITY2,
+ "set but not found");
+ context.setProperty(ENTITY2, null);
+ String o = (String) context.getProperty(ENTITY2);
+ setEntity(o == null ? NULL : o);
+ }
+
+ public void setType() {
+ context.setType(InputStreamReader.class);
+ getType();
+ }
+
+ public void ioException() throws IOException {
+ throw new IOException(IOE);
+ }
+
+ public void webApplicationException() {
+ throw new WebApplicationException(
+ Response.status(Status.CONFLICT).entity(ENTITY2).build());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java
new file mode 100644
index 0000000..bb6a6eb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.ext.InterceptorContext;
+
+public class InterceptorBodyTwo<CONTEXT extends InterceptorContext>
+ extends TemplateInterceptorBody<CONTEXT> {
+
+ @Override
+ protected Object operationMethodNotFound(String operation)
+ throws IOException {
+ return proceed();
+ }
+
+ public void getPropertyNames() {
+ Collection<String> names = context.getPropertyNames();
+ setEntity(JaxrsUtil.iterableToString(";", names));
+ }
+
+ public void setProperty() {
+ Object property = context.getProperty(PROPERTY);
+ if (property instanceof StringBuilder)
+ setEntity(property.toString());
+ else
+ setEntity(NULL);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java
new file mode 100644
index 0000000..78bf87e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+
+/**
+ * Every InterceptorContext has different way to get header OPERATION, proceed,
+ * or write an entity to a response. Therefore, TemplateInterceptorBody is given
+ * the implementation of this interface so that it can abstractly call these
+ * methods no matter the given context.
+ *
+ * It is passed as an argument to the only call-able method
+ * {@link TemplateInterceptorBody#executeMethod()}
+ */
+public interface InterceptorCallbackMethods {
+ void writeEntity(String entity);
+
+ Object proceed() throws IOException;
+
+ String getHeaderString();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java
new file mode 100644
index 0000000..039a772
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.ext.InterceptorContext;
+
+/**
+ * Body for both reader and writer interceptor body The body is injected into
+ * Template<Reader/Writer>Interceptor
+ *
+ * @param <CONTEXT>
+ * The context the body methods will use.
+ */
+public abstract class TemplateInterceptorBody<CONTEXT extends InterceptorContext> {
+ public static final String OPERATION = "OPERATION";
+
+ public static final String ENTITY = "Entity";
+
+ public static final String ENTITY2 = "Other Entity";
+
+ public static final String PROPERTY = "Property";
+
+ public static final String NULL = "None";
+
+ public static final String NPE = "NullPointerException has been thrown as expected";
+
+ public static final String IOE = "IOException has been thrown as expected";
+
+ public static final String WAE = "WebApplicationException has been thrown as expected";
+
+ protected CONTEXT context;
+
+ protected InterceptorCallbackMethods callback;
+
+ public Object executeMethod(CONTEXT context,
+ InterceptorCallbackMethods callback) throws IOException {
+ this.context = context;
+ this.callback = callback;
+ String operation = getHeaderString();
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods)
+ if (operation.equalsIgnoreCase(method.getName())) {
+ try {
+ Object ret = method.invoke(this);
+ if (ret == null)
+ return proceed();
+ else
+ return ret; // the method ensures the call of proceed();
+ } catch (Exception e) {
+ if (IOException.class.isInstance(e.getCause()))
+ throw (IOException) e.getCause();
+ else if (e.getCause() instanceof RuntimeException)
+ throw (RuntimeException) e.getCause();
+ else
+ throwIOEAndLog(operation, e);
+ }
+ }
+ return operationMethodNotFound(operation);
+ }
+
+ private static void throwIOEAndLog(String operation, Throwable e)
+ throws IOException {
+ System.out.println("Error while invoking method " + operation);
+ e.printStackTrace();
+ throw new IOException(e);
+ }
+
+ protected Object operationMethodNotFound(String operation)
+ throws IOException {
+ throw new IOException("Operation " + operation + " not implemented");
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ protected void assertTrue(boolean conditionTrue, Object... msg) {
+ if (conditionTrue)
+ return;
+ StringBuilder sb = new StringBuilder();
+ if (msg != null)
+ for (Object str : msg)
+ sb.append(str).append(" ");
+ throw new RuntimeException(new IOException(sb.toString()));
+ }
+
+ protected <T> void setEntity(T... entity) {
+ setSeparatedEntity(" ", entity);
+ }
+
+ protected <T> void setSeparatedEntity(String separator, T... entity) {
+ String complete = JaxrsUtil.iterableToString(separator, entity);
+ writeEntity(complete);
+ }
+
+ protected void writeEntity(String entity) {
+ callback.writeEntity(entity);
+ }
+
+ protected Object proceed() throws IOException {
+ return callback.proceed();
+ }
+
+ protected String getHeaderString() {
+ return callback.getHeaderString();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java
new file mode 100644
index 0000000..06e5046
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ *
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class ReaderClient<CONTEXTOPERATION extends Enum<?>>
+ extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 7145627888730121260L;
+
+ /**
+ * Create response to be faked as returned from server
+ */
+ protected Response.ResponseBuilder createResponse(CONTEXTOPERATION op) {
+ Response.ResponseBuilder builder = Response.ok()
+ .header(TemplateInterceptorBody.OPERATION, op.name())
+ .entity(TemplateInterceptorBody.ENTITY);
+ return builder;
+ }
+
+ /**
+ * Create a request filter to be aborted with given fake response simulating
+ * the resource from a request
+ *
+ * @param response
+ * @return
+ */
+ protected static ClientRequestFilter createRequestFilter(
+ final Response response) {
+ ClientRequestFilter outFilter = new ClientRequestFilter() {
+
+ @Override
+ public void filter(ClientRequestContext context) throws IOException {
+ Response r;
+ if (response == null)
+ r = Response.ok().build();
+ else
+ r = response;
+ context.abortWith(r);
+ }
+ };
+ return outFilter;
+ }
+
+ /**
+ * Invoke and convert IOException to Fault
+ */
+ protected void invoke() throws Fault {
+ try {
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "404URL/"));
+ super.invoke();
+ } catch (Exception cause) {
+ if (cause instanceof IOException)
+ throw new Fault(cause.getMessage());
+ else
+ throw new Fault(cause);
+ }
+ }
+
+ /**
+ * Register providers to client configuration
+ *
+ * @param response
+ * ClientRequestFilter#abortWith response
+ */
+ protected void addProviders(Response response) throws Fault {
+ ClientRequestFilter requestFilter = createRequestFilter(response);
+ addProvider(requestFilter);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java
new file mode 100644
index 0000000..a717918
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptor;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+/**
+ * This class is a superclass for any interceptor @Provider. Any such provider
+ * is then given a body, inherited from TemplateInterceptorBody. The body
+ * actually contains methods with name equalIgnoreCase to ContextOperation items
+ * name, the name of the method executed is passed by http header OPERATION
+ *
+ * @see TemplateInterceptorBody
+ *
+ * The injection of the body solves the issue with inheritance from two
+ * super-classes.
+ */
+public abstract class TemplateReaderInterceptor
+ implements ReaderInterceptor, InterceptorCallbackMethods {
+
+ protected ReaderInterceptorContext readerCtx;
+
+ protected TemplateInterceptorBody<ReaderInterceptorContext> interceptorBody;
+
+ public TemplateReaderInterceptor(
+ TemplateInterceptorBody<ReaderInterceptorContext> interceptorBody) {
+ super();
+ this.interceptorBody = interceptorBody;
+ }
+
+ @Override
+ public Object aroundReadFrom(ReaderInterceptorContext ctx)
+ throws IOException, WebApplicationException {
+ this.readerCtx = ctx;
+ return interceptorBody.executeMethod(readerCtx, this);
+ }
+
+ @Override
+ public void writeEntity(String entity) {
+ readerCtx.setInputStream(new ByteArrayInputStream(entity.getBytes()));
+ }
+
+ @Override
+ public Object proceed() throws IOException {
+ return readerCtx.proceed();
+ }
+
+ @Override
+ public String getHeaderString() {
+ MultivaluedMap<String, String> headers = readerCtx.getHeaders();
+ return headers.getFirst(TemplateInterceptorBody.OPERATION);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java
new file mode 100644
index 0000000..3e6eedd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ * ts_home;
+ */
+public class JAXRSClient extends ReaderClient<ContextOperation> {
+
+ private static final long serialVersionUID = -8828149277776372718L;
+
+ /* Run test */
+ /*
+ * @testName: getAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation. The
+ * annotations are not on client reader.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getAnnotationsTest() throws Fault {
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ ResponseBuilder builder = createResponse(ContextOperation.GETANNOTATIONS);
+ Response fake = builder.entity(TemplateInterceptorBody.ENTITY, annotations)
+ .build();
+ addProviders(fake);
+ for (Annotation a : annotations)
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * If abortWith is invoked, execution is aborted
+ */
+ public void getGenericTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETGENERICTYPE);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get media type of HTTP entity.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getMediaTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETMEDIATYPE);
+ Response fake = builder.type(MediaType.APPLICATION_JSON_TYPE).build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Returns null if there is no property by that name.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getPropertyIsNullTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETPROPERTY);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection collection
+ * containing the property names available within the context of the current
+ * request/response exchange context.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getPropertyNamesTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETPROPERTYNAMES);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ for (int i = 0; i != 5; i++)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.PROPERTY + i);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesIsReadOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection containing the
+ * property names available within the context of the current request/response
+ * exchange context.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getPropertyNamesIsReadOnlyTest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.GETPROPERTYNAMESISREADONLY);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get Java type supported by corresponding message body
+ * provider.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETTYPE);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: removePropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Removes a property with the given name from the current
+ * request/response exchange context. After removal, subsequent calls to
+ * getProperty(java.lang.String) to retrieve the property value will return
+ * null.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void removePropertyTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.REMOVEPROPERTY);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Update annotations on the formal declaration of the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setAnnotationsTest() throws Fault {
+ Annotation[] annotations = ReaderInterceptorOne.class.getAnnotations();
+ ResponseBuilder builder = createResponse(ContextOperation.SETANNOTATIONS);
+ Response fake = builder.build();
+ addProviders(fake);
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsNullThrowsNPETest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Throws NullPointerException - in case the input parameter
+ * is null.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setAnnotationsNullThrowsNPETest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.SETANNOTATIONSNULL);
+ Response fake = builder.entity(TemplateInterceptorBody.ENTITY).build();
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+ invoke();
+ }
+
+ /*
+ * @testName: setGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Update type of the object to be produced or written.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setGenericTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETGENERICTYPE);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, "[B");
+ invoke();
+ }
+
+ /*
+ * @testName: setMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Update media type of HTTP entity.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setMediaTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETMEDIATYPE);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Binds an object to a given property name in the current
+ * request/response exchange context. If the name specified is already used
+ * for a property, this method will replace the value of the property with the
+ * new value.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setPropertyTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETPROPERTY);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: If a null value is passed, the effect is the same as
+ * calling the removeProperty(String) method.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setPropertyNullTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETPROPERTYNULL);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Update Java type before calling message body provider.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setTypeTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETTYPE);
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ TemplateInterceptorBody.ENTITY.getBytes());
+ Reader reader = new InputStreamReader(bais);
+ Response fake = builder.entity(reader).build();
+
+ addProviders(fake);
+ addProvider(InputStreamReaderProvider.class);
+ invoke();
+ InputStreamReader isr = getResponseBody(InputStreamReader.class);
+ try {
+ String entity = JaxrsUtil.readFromReader(isr);
+ assertTrue(entity.contains(InputStreamReader.class.getName()),
+ "Expected"+ InputStreamReader.class.getName()+ "not found");
+ logMsg("#setType set correct type", entity);
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+
+ /*
+ * @testName: ioExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:921; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Throws IOException - if an IO error arises.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void ioExceptionTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.IOEXCEPTION);
+ Response fake = builder.build();
+ addProviders(fake);
+ invoke();
+ try {
+ getResponseBody();
+ } catch (Exception e) {
+ assertNotNull(e.getMessage(), "Returned unexpected exception", e);
+ IOException io = assertCause(e, IOException.class,
+ "Unexpected exception has been found:", e);
+ assertContains(io.getMessage(), TemplateInterceptorBody.IOE,
+ "Found unexpected message from IOException", e.getMessage());
+ logMsg("found expected IOException", io);
+ return;
+ }
+ fault("Expected IOException not found");
+ }
+
+ /*
+ * @testName: webApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:922; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: throws WebApplicationException thrown by wrapped method.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void webApplicationExceptionTest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.WEBAPPLICATIONEXCEPTION);
+ Response fake = builder.build();
+ addProviders(fake);
+ invoke();
+ try {
+ getResponseBody();
+ } catch (Exception e) {
+ WebApplicationException we = assertCause(e, WebApplicationException.class,
+ "Found unexpected exception", e);
+ assertNotNull(we.getResponse(),
+ "WebApplicationException.getResponse is null");
+ Response response = we.getResponse();
+ String entity = response.getEntity().toString();
+ assertEqualsInt(Status.CONFLICT.getStatusCode(), response.getStatus(),
+ "Unexcpected status returned from WebApplicationException.getResponse",
+ response.getStatus());
+ assertEquals(TemplateInterceptorBody.ENTITY2, entity,
+ "Found unexpected body content from WebApplicationException.getResponse",
+ entity);
+ logMsg("found expected WebApplicationException", we);
+ return;
+ }
+ fault("Expected WebApplicationException not found");
+ }
+
+ // /////////////////////////////////////////////////////////////////////
+ @Override
+ protected void addProviders(Response response) throws Fault {
+ super.addProviders(response);
+ addProvider(ReaderInterceptorTwo.class);
+ addProvider(new ReaderInterceptorOne());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java
new file mode 100644
index 0000000..9d270b6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+@Provider
+@Priority(100)
+public class ReaderInterceptorOne extends TemplateReaderInterceptor {
+
+ public ReaderInterceptorOne() {
+ super(new InterceptorBodyOne<ReaderInterceptorContext>());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java
new file mode 100644
index 0000000..bbd968a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+@Provider
+@Priority(200)
+public class ReaderInterceptorTwo extends TemplateReaderInterceptor {
+
+ public ReaderInterceptorTwo() {
+ super(new InterceptorBodyTwo<ReaderInterceptorContext>());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java
new file mode 100644
index 0000000..6fb82e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+public enum ContextOperation {
+ GETHEADERS, GETHEADERSISMUTABLE, GETINPUTSTREAM, PROCEEDTHROWSIOEXCEPTION, PROCEEDTHROWSWEBAPPEXCEPTION, SETINPUTSTREAM
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java
new file mode 100644
index 0000000..b5d799a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.WebApplicationException;
+
+public class ExceptionThrowingStringBean extends StringBean {
+
+ public ExceptionThrowingStringBean(String header) {
+ super(header);
+ if (!header.equals(TemplateInterceptorBody.WAE))
+ throw new WebApplicationException(new IOException(header));
+ }
+
+ public ExceptionThrowingStringBean(String header, boolean b) {
+ super(header);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java
new file mode 100644
index 0000000..5ee679c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ExceptionThrowingStringBeanEntityProvider
+ implements MessageBodyReader<ExceptionThrowingStringBean>,
+ MessageBodyWriter<ExceptionThrowingStringBean> {
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return type == ExceptionThrowingStringBean.class;
+ }
+
+ @Override
+ public long getSize(ExceptionThrowingStringBean t, Class<?> type,
+ Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return t.get().length();
+ }
+
+ @Override
+ public void writeTo(ExceptionThrowingStringBean t, Class<?> type,
+ Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+ throws IOException, WebApplicationException {
+ entityStream.write(t.get().getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return isWriteable(type, genericType, annotations, mediaType);
+ }
+
+ @Override
+ public ExceptionThrowingStringBean readFrom(
+ Class<ExceptionThrowingStringBean> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ String entity = JaxrsUtil.readFromStream(entityStream);
+ entityStream.close();
+ return new ExceptionThrowingStringBean(entity);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java
new file mode 100644
index 0000000..8fc8f0d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+public class InterceptorOneBody
+ extends TemplateInterceptorBody<ReaderInterceptorContext> {
+
+ public void getHeaders() {
+ MultivaluedMap<String, String> headers = context.getHeaders();
+ setEntity(JaxrsUtil.iterableToString(";", headers.keySet()));
+ }
+
+ public void getHeadersIsMutable() {
+ MultivaluedMap<String, String> headers = context.getHeaders();
+ headers.add(PROPERTY, PROPERTY);
+ }
+
+ public void getInputStream() throws IOException {
+ InputStream stream = context.getInputStream();
+ String entity = JaxrsUtil.readFromStream(stream);
+ stream.close();
+ setEntity(entity);
+ }
+
+ public void proceedThrowsIOException() {
+ try {
+ context.proceed();
+ setEntity(NULL);
+ } catch (IOException ioe) {
+ setEntity(IOE);
+ }
+ }
+
+ public Object proceedThrowsWebAppException()
+ throws WebApplicationException, IOException {
+ Object proceedObject = new ExceptionThrowingStringBean(NULL, false);
+ try {
+ proceedObject = context.proceed();
+ } catch (WebApplicationException e) {
+ // Exception has been thrown, message body reader has read nothing
+ // hence we need to set expected value;
+ ((StringBean) proceedObject).set(WAE);
+ }
+ return proceedObject;
+ }
+
+ public void setInputStream() {
+ ByteArrayInputStream stream = new ByteArrayInputStream(NULL.getBytes());
+ context.setInputStream(stream);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java
new file mode 100644
index 0000000..c15be8d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+public class InterceptorTwoBody
+ extends TemplateInterceptorBody<ReaderInterceptorContext> {
+ @Override
+ protected Object operationMethodNotFound(String operation)
+ throws IOException {
+ return proceed();
+ }
+
+ public void getHeadersIsMutable() {
+ MultivaluedMap<String, String> headers = context.getHeaders();
+ String first = headers.getFirst(PROPERTY);
+ setEntity(first == null ? NULL : PROPERTY);
+ }
+
+ public void proceedThrowsIOException() throws IOException {
+ throw new IOException("Interceptor#proceed IOException tck test");
+ }
+
+ public Object proceedThrowsWebAppException()
+ throws WebApplicationException, IOException {
+ return context.proceed();
+ }
+
+ public void setInputStream() throws IOException {
+ InputStream stream = context.getInputStream();
+ String entity = JaxrsUtil.readFromStream(stream);
+ setEntity(NULL.equals(entity) ? ENTITY2 : NULL);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java
new file mode 100644
index 0000000..45fa157
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ * ts_home;
+ */
+public class JAXRSClient extends ReaderClient<ContextOperation> {
+
+ private static final long serialVersionUID = -6962070973647934636L;
+
+ /* Run test */
+ /*
+ * @testName: getHeadersOperationSetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getHeadersOperationSetTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETHEADERS);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+ TemplateInterceptorBody.OPERATION);
+ invoke();
+ }
+
+ /*
+ * @testName: getHeadersHeadersSetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getHeadersHeadersSetTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.GETHEADERS);
+ for (int i = 0; i != 5; i++) {
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.PROPERTY + i);
+ builder = builder.header(TemplateInterceptorBody.PROPERTY + i, "any");
+ }
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setTextCaser(TextCaser.LOWER);
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.OPERATION);
+ invoke();
+ }
+
+ /* Run test */
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getHeadersIsMutableTest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.GETHEADERSISMUTABLE);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+ invoke();
+ }
+
+ /*
+ * @testName: getInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:924; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Get the input stream of the object to be read.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void getInputStreamTest() throws Fault {
+ String entity = "getInputStreamEntity";
+ ResponseBuilder builder = createResponse(ContextOperation.GETINPUTSTREAM);
+ Response fake = builder.entity(entity).build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, entity);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsIOExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:926; JAXRS:JAVADOC:920;
+ * JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Throws: IOException - if an IO error arises
+ *
+ * Proceed is tested in any of the interceptor tests.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void proceedThrowsIOExceptionTest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:1008; JAXRS:JAVADOC:920;
+ * JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Throws: WebApplicationException - thrown by the wrapped
+ * {@code MessageBodyReader.readFrom} method.
+ *
+ * Proceed is tested in any of the intercepter tests.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+ ResponseBuilder builder = createResponse(
+ ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+ Response fake = builder.build();
+ addProviders(fake);
+ addProvider(ExceptionThrowingStringBeanEntityProvider.class);
+ invoke();
+ // Exception thrown, caught in InterceptorBodyOne
+ StringBean bean = getResponseBody(ExceptionThrowingStringBean.class);
+ //
+ assertContains(bean.get(), TemplateInterceptorBody.WAE,
+ "WebApplicationException has not been thrown and the message is",
+ bean.get());
+ logMsg("WebApplicationException has been thrown as expected", bean.get());
+ }
+
+ /*
+ * @testName: setInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:927; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+ *
+ * @test_Strategy: Update the input stream of the object to be read.
+ *
+ * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+ * aborted
+ */
+ public void setInputStreamTest() throws Fault {
+ ResponseBuilder builder = createResponse(ContextOperation.SETINPUTSTREAM);
+ Response fake = builder.build();
+
+ addProviders(fake);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke();
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ /**
+ * Do not forget to register providers
+ */
+ @Override
+ protected void addProviders(Response response) throws Fault {
+ super.addProviders(response);
+ addProvider(ReaderInterceptorTwo.class);
+ addProvider(ReaderInterceptorOne.class);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java
new file mode 100644
index 0000000..79badd9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class ReaderInterceptorOne extends TemplateReaderInterceptor {
+
+ public ReaderInterceptorOne() {
+ super(new InterceptorOneBody());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java
new file mode 100644
index 0000000..82c7104
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class ReaderInterceptorTwo extends TemplateReaderInterceptor {
+
+ public ReaderInterceptorTwo() {
+ super(new InterceptorTwoBody());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
index f69dd67..e41d223 100644
--- a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
@@ -677,8 +677,6 @@
* @param message
* a space separated message[i].toString() compilation for
* i=<0,message.length)
- * @
- * when conditionTrue is not met with message provided
*/
//public static void //
// assertTrue(boolean condition, Object... message) {
@@ -694,13 +692,11 @@
* @param message
* a space separated message[i].toString() compilation for
* i=<0,message.length)
- * @
- * when condition is not false with message provided
*/
- /*public static void //
- assertFalse(boolean condition, Object... message) {
- assertTrue(!condition, message);
- }*/
+ // public static void //
+ // assertFalse(boolean condition, Object... message) {
+ // assertTrue(!condition, message);
+ // }
/**
* Asserts that two objects are equal. When instances of Comparable, such as
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java
new file mode 100644
index 0000000..8ba1d44
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.provider;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+@Consumes(MediaType.TEXT_PLAIN)
+@Produces(MediaType.TEXT_PLAIN)
+/**
+ * It does not make sense to put any of these annotations. But for test e.g.
+ * getEntityAnnotationsIsNotTakenFromEntityClassTest we need to check that
+ * context.getAnnotations won't have these annotations.
+ */
+public class StringBeanWithAnnotation extends StringBean {
+
+ public StringBeanWithAnnotation(String header) {
+ super(header);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java
new file mode 100644
index 0000000..cc8dfc7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ContextProvider implements ClientRequestFilter {
+
+ protected void checkFilterContext(ClientRequestContext context) throws Fault {
+ throw new Fault("this TCK method is not implemented yet");
+ }
+
+ @Override
+ public void filter(ClientRequestContext context) throws IOException {
+ try {
+ checkFilterContext(context);
+ } catch (Fault e) {
+ throw new IOException(e);
+ }
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..de6c77f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.api.client.clientrequestcontext.ContextProvider;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.impl.ReplacingOutputStream;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -3234850442044177095L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_rs_client_clientrequestcontext_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_clientrequestcontext_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class, ContextProvider.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getEntityStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:437; JAXRS:JAVADOC:451; JAXRS:JAVADOC:455;
+ * JAXRS:JAVADOC:456;
+ *
+ * @test_Strategy: Get the entity output stream. Set a new entity output
+ * stream.
+ */
+ @Test
+ public void getEntityStreamTest() throws Fault {
+ final String entityStreamWorks = "ENTITY_STREAM_WORKS";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ OutputStream stream = context.getEntityStream();
+ ReplacingOutputStream wrapper = new ReplacingOutputStream(stream, 'X',
+ 'T');
+ context.setEntityStream(wrapper);
+ }
+ };
+ ByteArrayInputStream entity = new ByteArrayInputStream(
+ entityStreamWorks.replace('T', 'X').getBytes());
+ addProvider(provider);
+ setRequestContentEntity(entity);
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "post"));
+ invoke();
+
+ String body = getResponseBody();
+ assertContains(body, entityStreamWorks);
+ }
+
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:439; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ *
+ * @test_Strategy: Get the generic entity type information.
+ */
+ @Test
+ public void getHeadersIsMutableTest() throws Fault {
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ headers.add("Accept-Language", "en_gb");
+ headers.add("Date", "Tue, 15 Nov 1994 08:12:31 GMT");
+ headers.add("tck", "cts");
+ }
+ };
+ addProvider(provider);
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "headers"));
+ invoke();
+
+ String body = getResponseBody().toLowerCase();
+ assertContains(body, "accept-language");
+ assertContains(body, "date");
+ assertContains(body, "tck");
+ }
+
+ /*
+ * @testName: setMethodTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:452; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+ *
+ * @test_Strategy: Set the request method.
+ */
+ @Test
+ public void setMethodTest() throws Fault {
+ String entity = "ENTITY";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ context.setMethod("PUT");
+ }
+ };
+ addProvider(provider);
+ setRequestContentEntity(entity);
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "put"));
+ invoke();
+
+ String body = getResponseBody();
+ assertContains(body, entity);
+ }
+
+ /*
+ * @testName: setUriTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:454; JAXRS:JAVADOC:447; JAXRS:JAVADOC:455;
+ * JAXRS:JAVADOC:456;
+ *
+ * @test_Strategy: Set a new request URI. Get the request URI.
+ */
+ @Test
+ public void setUriTest() throws Fault {
+ String entity = "ENTITY";
+ ContextProvider provider = new ContextProvider() {
+ @Override
+ protected void checkFilterContext(ClientRequestContext context)
+ throws Fault {
+ URI uri = context.getUri();
+ try {
+ uri = new URI(uri.toASCIIString().replace("qwerty", "post"));
+ } catch (URISyntaxException e) {
+ throw new Fault(e);
+ }
+ context.setUri(uri);
+ }
+ };
+ addProvider(provider);
+ setRequestContentEntity(entity);
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "qwerty"));
+ invoke();
+
+ String body = getResponseBody();
+ assertContains(body, entity);
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ protected static void assertContains(String string, String substring)
+ throws Fault {
+ assertTrue(string.contains(substring), string+ "does NOT contain"+
+ substring);
+ TestUtil.logMsg("Found expected substring: " + substring);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java
new file mode 100644
index 0000000..7b7c857
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.util.Collection;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+
+@Path("resource")
+public class Resource {
+
+ @POST
+ @Path("post")
+ public String post(String value) {
+ return value;
+ }
+
+ @PUT
+ @Path("put")
+ public String put(String value) {
+ return value;
+ }
+
+ @GET
+ @Path("headers")
+ public String headers(@Context HttpHeaders headers) {
+ String hdrs = collectionToString(headers.getRequestHeaders().keySet());
+ return hdrs;
+ }
+
+ protected static <T> String collectionToString(Collection<T> collection) {
+ StringBuilder sb = new StringBuilder();
+ for (T t : collection)
+ sb.append(t).append(";");
+ return sb.toString();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java
new file mode 100644
index 0000000..9a302e6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..fe355dd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/JAXRSClientIT.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+import java.util.Locale;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.client.JdkLoggingFilter;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.AsyncInvoker;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -8097693127928445210L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_rs_client_invocationbuilder_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_invocationbuilder_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ static final String[] METHODS = { "delete", "get", "options" };
+
+ static final String[] ENTITY_METHODS = { "put", "post" };
+
+ /* Run test */
+ /*
+ * @testName: acceptLanguageByLocalesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:524;
+ *
+ * @test_Strategy: Add acceptable languages.
+ */
+ @Test
+ public void acceptLanguageByLocalesTest() throws Fault {
+ Invocation.Builder builder = createBuilderForMethod("languages");
+ builder = builder.acceptLanguage(Locale.GERMAN, Locale.ITALIAN,
+ Locale.FRENCH);
+ String response = builder.buildGet().invoke(String.class);
+ String error = "Expected locale was not found in the response:";
+ assertContainsIgnoreCase(response, Locale.GERMAN, error, response);
+ assertContainsIgnoreCase(response, Locale.ITALIAN, error, response);
+ assertContainsIgnoreCase(response, Locale.FRENCH, error, response);
+ }
+
+ /*
+ * @testName: acceptLanguageByStringsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:525;
+ *
+ * @test_Strategy: Add acceptable languages.
+ */
+ @Test
+ public void acceptLanguageByStringsTest() throws Fault {
+ Invocation.Builder builder = createBuilderForMethod("languages");
+ builder = builder.acceptLanguage(langToString(Locale.GERMAN),
+ langToString(Locale.ITALIAN), langToString(Locale.FRENCH));
+ String response = builder.buildGet().invoke(String.class);
+ String error = "Expected locale was not found in the response:";
+ assertContainsIgnoreCase(response, Locale.GERMAN, error, response);
+ assertContainsIgnoreCase(response, Locale.ITALIAN, error, response);
+ assertContainsIgnoreCase(response, Locale.FRENCH, error, response);
+ }
+
+ /*
+ * @testName: asyncTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:526;
+ *
+ * @test_Strategy: Access the asynchronous uniform request invocation
+ * interface to asynchronously invoke the built request.
+ */
+ @Test
+ public void asyncTest() throws Fault {
+ Invocation.Builder builder = createBuilderForMethod("forbid");
+ AsyncInvoker async = builder.async();
+ assertTrue(async != null, "Builder.async() does not work properly");
+ }
+
+ /*
+ * @testName: buildTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:527;
+ *
+ * @test_Strategy: Build a request invocation using an arbitrary request
+ * method name.
+ */
+ @Test
+ public void buildTest() throws Fault {
+ String error = "Unexpected response returned:";
+ for (String method : METHODS) {
+ Invocation.Builder builder = createBuilderForMethod(method);
+ String response = builder.build(method.toUpperCase())
+ .invoke(String.class);
+ assertContainsIgnoreCase(response, method, error, response);
+ }
+ }
+
+ /*
+ * @testName: buildWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:528;
+ *
+ * @test_Strategy: Build a request invocation using an arbitrary request
+ * method name and request entity
+ */
+ @Test
+ public void buildWithEntityTest() throws Fault {
+ String error = "Unexpected response returned:";
+ for (String method : ENTITY_METHODS) {
+ Invocation.Builder builder = createBuilderForMethod(method);
+ Entity<String> entity = createEntity(method);
+ String response = builder.build(method.toUpperCase(), entity)
+ .invoke(String.class);
+ assertContainsIgnoreCase(response, method, error, response);
+ }
+ }
+
+ /*
+ * @testName: buildDeleteTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:529;
+ *
+ * @test_Strategy: Build a DELETE request invocation.
+ */
+ @Test
+ public void buildDeleteTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("delete");
+ String response = builder.buildDelete().invoke(String.class);
+ assertContainsIgnoreCase(response, "delete", error, response);
+ }
+
+ /*
+ * @testName: buildGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:530;
+ *
+ * @test_Strategy: Build a GET request invocation.
+ */
+ @Test
+ public void buildGetTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("get");
+ String response = builder.buildGet().invoke(String.class);
+ assertContainsIgnoreCase(response, "get", error, response);
+ }
+
+ /*
+ * @testName: buildPostTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:531;
+ *
+ * @test_Strategy: Build a POST request invocation.
+ */
+ @Test
+ public void buildPostTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("post");
+ Entity<String> entity = createEntity("post");
+ String response = builder.buildPost(entity).invoke(String.class);
+ assertContainsIgnoreCase(response, "post", error, response);
+ }
+
+ /*
+ * @testName: buildPutTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:532;
+ *
+ * @test_Strategy: Build a PUT request invocation.
+ */
+ @Test
+ public void buildPutTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("put");
+ Entity<String> entity = createEntity("put");
+ String response = builder.buildPut(entity).invoke(String.class);
+ assertContainsIgnoreCase(response, "put", error, response);
+ }
+
+ /*
+ * @testName: cacheControlTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:533;
+ *
+ * @test_Strategy: Set the cache control data of the message.
+ */
+ @Test
+ public void cacheControlTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("headerstostring");
+ CacheControl control = new CacheControl();
+ control.setMaxAge(2);
+ String response = builder.cacheControl(control).buildGet()
+ .invoke(String.class).toLowerCase();
+ assertContainsIgnoreCase(response, "max-age", error, response);
+ }
+
+ /*
+ * @testName: cookieCookieTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:535;
+ *
+ * @test_Strategy: Add a cookie to be set.
+ */
+ @Test
+ public void cookieCookieTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("cookie");
+ Cookie cookie = new Cookie("tck", "cts");
+ String response = builder.cookie(cookie).buildGet().invoke(String.class);
+ assertContainsIgnoreCase(response, "cts", error, response);
+ }
+
+ /*
+ * @testName: cookieStringStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:536;
+ *
+ * @test_Strategy: Add a cookie to be set.
+ */
+ @Test
+ public void cookieStringStringTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("cookie");
+ String response = builder.cookie("tck", "cts").buildGet()
+ .invoke(String.class);
+ assertContainsIgnoreCase(response, "cts", error, response);
+ }
+
+ /*
+ * @testName: headerObjectTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:537;
+ *
+ * @test_Strategy: Add an arbitrary header.
+ */
+ @Test
+ public void headerObjectTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("headerstostring");
+ String response = builder.header("tck-header", "cts-header").buildGet()
+ .invoke(String.class);
+ assertContainsIgnoreCase(response, "tck-header", error, response);
+ assertContainsIgnoreCase(response, "cts-header", error, response);
+ }
+
+ /*
+ * @testName: headersMultivaluedMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:538;
+ *
+ * @test_Strategy: Replaces all existing headers with the newly supplied
+ * headers.
+ */
+ @Test
+ public void headersMultivaluedMapTest() throws Fault {
+ String error = "Unexpected response returned:";
+ Invocation.Builder builder = createBuilderForMethod("headerstostring");
+ MultivaluedMap<String, Object> map = new MultivaluedHashMap<String, Object>();
+ map.add("tck-header", "cts-header");
+ String response = builder.header("unexpected-header", "unexpected-header")
+ .headers(map).buildGet().invoke(String.class);
+ assertTrue(!response.contains("unexpected-header"),
+ "unexpected-header found in the response");
+ assertContainsIgnoreCase(response, "tck-header", error, response);
+ assertContainsIgnoreCase(response, "cts-header", error, response);
+ }
+
+ /*
+ * @testName: headersMultivaluedMapIsNullReplacesAllTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:538;
+ *
+ * @test_Strategy: headers - new headers to be set, if null all existing
+ * headers will be removed.
+ */
+ @Test
+ public void headersMultivaluedMapIsNullReplacesAllTest() throws Fault {
+ Invocation.Builder builder = createBuilderForMethod("headerstostring");
+ String response = builder.header("unexpected-header", "unexpected-header")
+ .headers((MultivaluedMap<String, Object>) null).buildGet()
+ .invoke(String.class);
+ assertTrue(!response.contains("unexpected-header"),
+ "unexpected-header found in the response");
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+
+ protected String getUrl(String method) {
+ StringBuilder url = new StringBuilder();
+ url.append("http://").append(_hostname).append(":").append(_port);
+ url.append(getContextRoot()).append("/").append(method);
+ return url.toString();
+ }
+
+ /**
+ * Create Invocation.Builder for given resource method and start time
+ */
+ protected Invocation.Builder createBuilderForMethod(String methodName) {
+ Client client = ClientBuilder.newClient();
+ client.register(new JdkLoggingFilter(false));
+ WebTarget target = client.target(getUrl(methodName));
+ Invocation.Builder builder = target.request();
+ return builder;
+ }
+
+ protected <T> Entity<T> createEntity(T entity) {
+ return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+ }
+
+ /**
+ * @return simulates toLanguageTag() for java prior version 7
+ */
+ protected String langToString(Locale language) {
+ return language.toString().replace("_", "-");
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java
new file mode 100644
index 0000000..f04e8de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+import java.util.List;
+import java.util.Map.Entry;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.CookieParam;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HEAD;
+import jakarta.ws.rs.OPTIONS;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+@Path("resource")
+public class Resource {
+
+ @GET
+ @Path("languages")
+ public String languages(@Context HttpHeaders headers) {
+ return JaxrsUtil.iterableToString(" ", headers.getAcceptableLanguages());
+ }
+
+ @GET
+ @Path("headerstostring")
+ public String headersToString(@Context HttpHeaders headers) {
+ MultivaluedMap<String, String> map = headers.getRequestHeaders();
+ StringBuilder sb = new StringBuilder();
+ for (Entry<String, List<String>> header : map.entrySet())
+ sb.append(header.getKey()).append(":")
+ .append(JaxrsUtil.iterableToString(" ", header.getValue()))
+ .append(";");
+ return sb.toString();
+ }
+
+ @GET
+ @Path("cookie")
+ public String cookie(@CookieParam("tck") String cookie) {
+ return cookie;
+ }
+
+ @GET
+ @Path("allow")
+ public String allow() {
+ return "allow";
+ }
+
+ @DELETE
+ @Path("forbid")
+ public String forbid() {
+ return "forbid";
+ }
+
+ @GET
+ @Path("get")
+ public String get() {
+ return "get";
+ }
+
+ @HEAD
+ @Path("head")
+ public String head() {
+ return "head";
+ }
+
+ @PUT
+ @Path("put")
+ public String put(String value) {
+ return value;
+ }
+
+ @POST
+ @Path("post")
+ public String post(String value) {
+ return value;
+ }
+
+ @DELETE
+ @Path("delete")
+ public String delete() {
+ return "delete";
+ }
+
+ @OPTIONS
+ @Path("options")
+ public String options() {
+ return "options";
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java
new file mode 100644
index 0000000..6cd7cd5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/JAXRSClientIT.java
new file mode 100644
index 0000000..89297cb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/JAXRSClientIT.java
@@ -0,0 +1,2171 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.client.JdkLoggingFilter;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.SyncInvoker;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 4942772066511819511L;
+
+ protected long millis;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_rs_client_syncinvoker_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_syncinvoker_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class, jakarta.ws.rs.tck.common.impl.TRACE.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ static final String[] METHODS = { "DELETE", "GET", "OPTIONS" };
+
+ static final String[] ENTITY_METHODS = { "PUT", "POST" };
+
+ /* Run test */
+ // --------------------------------------------------------------------
+ // ---------------------- DELETE --------------------------------------
+ // --------------------------------------------------------------------
+ /*
+ * @testName: deleteTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:541;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response deleteTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("delete");
+ Response response = sync.delete();
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: deleteThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:541;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void deleteThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.delete();
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: deleteWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:543;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * synchronously.
+ */
+ @Test
+ public String deleteWithStringClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("delete");
+ String response = sync.delete(String.class);
+ assertResponseString(response, "delete");
+ return response;
+ }
+
+ /*
+ * @testName: deleteWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:543;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response deleteWithResponseClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("delete");
+ Response response = sync.delete(Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: deleteWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:543;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void deleteWithStringClassThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.delete(String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: deleteWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:543;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void deleteWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+ sync.delete(String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: deleteWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:543;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void deleteWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+ Response response = sync.delete(Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:546;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * synchronously.
+ */
+ @Test
+ public String deleteWithGenericTypeStringTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("delete");
+ GenericType<String> generic = createGeneric(String.class);
+ String response = sync.delete(generic);
+ assertResponseString(response, "delete");
+ return response;
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:546;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response deleteWithGenericTypeResponseTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("delete");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.delete(generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:546;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void deleteWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ GenericType<String> generic = createGeneric(String.class);
+ sync.delete(generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:546;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void deleteWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.delete(generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:546;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void deleteWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.delete(generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------GET------------------------------------
+ // ------------------------------------------------------------------
+ /*
+ * @testName: getTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:549;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response getTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("get");
+ Response response = sync.get();
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: getThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:549;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void getThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.get();
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: getWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:551;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * synchronously.
+ */
+ @Test
+ public String getWithStringClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("get");
+ String response = sync.get(String.class);
+ assertResponseString(response, "get");
+ return response;
+ }
+
+ /*
+ * @testName: getWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:551;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response getWithResponseClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("get");
+ Response response = sync.get(Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: getWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:551;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void getWithStringClassThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.get(String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: getWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:551;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void getWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+ sync.get(String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: getWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:551;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void getWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+ Response response = sync.get(Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: getWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:554;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * synchronously.
+ */
+ @Test
+ public String getWithGenericTypeStringTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("get");
+ GenericType<String> generic = createGeneric(String.class);
+ String response = sync.get(generic);
+ assertResponseString(response, "get");
+ return response;
+ }
+
+ /*
+ * @testName: getWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:554;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response getWithGenericTypeResponseTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("get");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.get(generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: getWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:554;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void getWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ GenericType<String> generic = createGeneric(String.class);
+ sync.get(generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: getWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:554;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void getWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.get(generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: getWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:554;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void getWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.get(generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------HEAD-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: headTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:557;
+ *
+ * @test_Strategy: Invoke HTTP HEAD method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response headTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("head");
+ Response response = sync.head();
+ Status status = Status.fromStatusCode(response.getStatus());
+ assertTrue(status == Status.OK || status == Status.NO_CONTENT,
+ "Incorrect status for head received");
+ return response;
+ }
+
+ /*
+ * @testName: headThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:557;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.head throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void headThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.head();
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------METHOD-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: methodTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:559;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodTest() throws Fault {
+ Response response = null;
+ for (String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ response = sync.method(method);
+ assertResponseOk(response);
+ }
+ }
+
+ /*
+ * @testName: methodThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:559;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodThrowsProcessingExceptionTest() throws Fault {
+ for (final String method : METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.method(method);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:561;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithStringClassTest() throws Fault {
+ String response = null;
+ for (String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ response = sync.method(method, String.class);
+ assertResponseString(response, method.toLowerCase());
+ }
+ }
+
+ /*
+ * @testName: methodWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:561;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithResponseClassTest() throws Fault {
+ Response response = null;
+ for (String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ response = sync.method(method, Response.class);
+ assertResponseOk(response);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:561;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void methodWithStringClassThrowsProcessingExceptionTest()
+ throws Fault {
+ for (final String method : METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.method(method, String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:561;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void methodWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ sync.method(method, String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:561;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Response response = sync.method(method, Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:564;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithGenericTypeStringTest() throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ String response = null;
+ for (String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ response = sync.method(method, generic);
+ assertResponseString(response, method.toLowerCase());
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:564;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithGenericTypeResponseTest() throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = null;
+ for (String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ response = sync.method(method, generic);
+ assertResponseOk(response);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:564;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ final GenericType<String> generic = createGeneric(String.class);
+ for (final String method : METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.method(method, generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:564;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(GenericType<String>)
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ final GenericType<String> generic = createGeneric(String.class);
+ for (final String method : METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ sync.method(method, generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:564;
+ *
+ * @test_Strategy:
+ * jakarta.ws.rs.client.SyncInvoker.method(GenericType<Response>) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void methodWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = null;
+ for (final String method : METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ response = sync.method(method, generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:567;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response methodWithEntityTest() throws Fault {
+ Response response = null;
+ for (String method : ENTITY_METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = createEntity(method.toLowerCase());
+ response = sync.method(method, entity);
+ assertResponseOk(response);
+ }
+ return response;
+ }
+
+ /*
+ * @testName: methodWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:567;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity)
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodWithEntityThrowsProcessingExceptionTest() throws Fault {
+ final Entity<String> entity = createEntity("entity");
+ for (final String method : ENTITY_METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.method(method, entity);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:569;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public String methodWithStringClassWithEntityTest() throws Fault {
+ String response = null;
+ for (String method : ENTITY_METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = createEntity(method.toLowerCase());
+ response = sync.method(method, entity, String.class);
+ assertResponseString(response, method.toLowerCase());
+ }
+ return response;
+ }
+
+ /*
+ * @testName: methodWithResponseClassWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:569;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public String methodWithResponseClassWithEntityTest() throws Fault {
+ String response = null;
+ for (String method : ENTITY_METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = createEntity(method.toLowerCase());
+ response = sync.method(method, entity, String.class);
+ assertResponseString(response, method.toLowerCase());
+ }
+ return response;
+ }
+
+ /*
+ * @testName: methodWithStringClassWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:569;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * Class) throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodWithStringClassWithEntityThrowsProcessingExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity(method.toLowerCase());
+ sync.method(method, entity, String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassWithEntityThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:569;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * Class) throws WebApplicationException - in case the response status code of
+ * the response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void methodWithStringClassWithEntityThrowsWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = createEntity(method.toLowerCase());
+ sync.method(method, entity, String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithResponseClassWithEntityThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:569;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * Class) throws WebApplicationException - in case the response status code of
+ * the response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void methodWithResponseClassWithEntityThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = createEntity(method.toLowerCase());
+ Response response = sync.method(method, entity, Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:572;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithGenericTypeStringWithEntityTest() throws Fault {
+ String response = null;
+ for (String method : ENTITY_METHODS) {
+ GenericType<String> generic = createGeneric(String.class);
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = createEntity(method.toLowerCase());
+ response = sync.method(method, entity, generic);
+ assertResponseString(response, method.toLowerCase());
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeResponseWithEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:572;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * synchronously.
+ */
+ @Test
+ public void methodWithGenericTypeResponseWithEntityTest() throws Fault {
+ Response response = null;
+ for (String method : ENTITY_METHODS) {
+ GenericType<Response> generic = createGeneric(Response.class);
+ SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = createEntity(method.toLowerCase());
+ response = sync.method(method, entity, generic);
+ assertResponseOk(response);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithGenericTypeStringWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:572;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * GenericType) throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void methodWithGenericTypeStringWithEntityThrowsProcessingExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ GenericType<String> generic = createGeneric(String.class);
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity(method);
+ sync.method(method, entity, generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithGenericTypeStringWithEntityThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:572;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * GenericType) throws WebApplicationException - in case the response status
+ * code of the response returned by the server is not successful and the
+ * specified response type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeStringWithEntityThrowsWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ GenericType<String> generic = createGeneric(String.class);
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = createEntity(method);
+ sync.method(method, entity, generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithGenericTypeResponseWithEntityThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:572;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+ * GenericType) throws WebApplicationException - in case the response status
+ * code of the response returned by the server is not successful and the
+ * specified response type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeResponseWithEntityThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ for (final String method : ENTITY_METHODS) {
+ GenericType<Response> generic = createGeneric(Response.class);
+ SyncInvoker sync = createSyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = createEntity(method);
+ Response response = sync.method(method, entity, generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------OPTIONS--------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: optionsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:575;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response optionsTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("options");
+ Response response = sync.options();
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: optionsThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:575;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void optionsThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.options();
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: optionsWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:577;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * synchronously.
+ */
+ @Test
+ public String optionsWithStringClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("options");
+ String response = sync.options(String.class);
+ assertResponseString(response, "options");
+ return response;
+ }
+
+ /*
+ * @testName: optionsWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:577;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response optionsWithResponseClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("options");
+ Response response = sync.options(Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: optionsWithStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:577;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void optionsWithStringThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.options(String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: optionsWithStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:577;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void optionsWithStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+ sync.options(String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: optionsWithResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:577;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void optionsWithResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+ Response response = sync.options(Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:580;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * synchronously.
+ */
+ @Test
+ public String optionsWithGenericTypeStringTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("options");
+ GenericType<String> generic = createGeneric(String.class);
+ String response = sync.options(generic);
+ assertResponseString(response, "options");
+ return response;
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:580;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response optionsWithGenericTypeResponseTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("options");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.options(generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:580;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void optionsWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ GenericType<String> generic = createGeneric(String.class);
+ sync.options(generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:580;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void optionsWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.options(generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName:
+ * optionsWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:580;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void optionsWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.options(generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------POST-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: postTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:583;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response postTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("post");
+ Entity<String> entity = createEntity("post");
+ Response response = sync.post(entity);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: postThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:583;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post(Entity) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void postThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("post");
+ sync.post(entity);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: postWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:585;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * synchronously.
+ */
+ @Test
+ public String postWithStringClassTest() throws Fault {
+ Entity<String> entity = createEntity("post");
+ SyncInvoker sync = createSyncInvokerForMethod("post");
+ String response = sync.post(entity, String.class);
+ assertResponseString(response, "post");
+ return response;
+ }
+
+ /*
+ * @testName: postWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:585;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response postWithResponseClassTest() throws Fault {
+ Entity<String> entity = createEntity("post");
+ SyncInvoker sync = createSyncInvokerForMethod("post");
+ Response response = sync.post(entity, Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: postWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:585;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void postWithStringClassThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("post");
+ sync.post(entity, String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: postWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:585;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void postWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+ Entity<String> entity = createEntity("post");
+ sync.post(entity, String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: postWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:585;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void postWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+ Entity<String> entity = createEntity("post");
+ Response response = sync.post(entity, Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: postWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:588;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * synchronously.
+ */
+ @Test
+ public String postWithGenericTypeStringTest() throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = createEntity("post");
+ SyncInvoker sync = createSyncInvokerForMethod("post");
+ String response = sync.post(entity, generic);
+ assertResponseString(response, "post");
+ return response;
+ }
+
+ /*
+ * @testName: postWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:588;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response postWithGenericTypeResponseTest() throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Entity<String> entity = createEntity("post");
+ SyncInvoker sync = createSyncInvokerForMethod("post");
+ Response response = sync.post(entity, generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: postWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:588;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void postWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("post");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.post(entity, generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: postWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:588;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void postWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+ Entity<String> entity = createEntity("post");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.post(entity, generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: postWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:588;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void postWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+ Entity<String> entity = createEntity("post");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.post(entity, generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------PUT -----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: putTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:591;
+ *
+ * @test_Strategy: Invoke HTTP PUT method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response putTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("put");
+ Entity<String> entity = createEntity("put");
+ Response response = sync.put(entity);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: putThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:591;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put(Entity) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void putThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("put");
+ sync.put(entity);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: putWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:593;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * synchronously.
+ */
+ @Test
+ public String putWithStringClassTest() throws Fault {
+ Entity<String> entity = createEntity("put");
+ SyncInvoker sync = createSyncInvokerForMethod("put");
+ String response = sync.put(entity, String.class);
+ assertResponseString(response, "put");
+ return response;
+ }
+
+ /*
+ * @testName: putWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:593;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response putWithResponseClassTest() throws Fault {
+ Entity<String> entity = createEntity("put");
+ SyncInvoker sync = createSyncInvokerForMethod("put");
+ Response response = sync.put(entity, Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: putWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:593;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void putWithStringClassThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("put");
+ sync.put(entity, String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: putWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:593;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void putWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+ Entity<String> entity = createEntity("put");
+ sync.put(entity, String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: putWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:593;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+ * WebApplicationException - in case the response status code of the response
+ * returned by the server is not successful and the specified response type is
+ * not Response.
+ */
+ @Test
+ public void putWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+ Entity<String> entity = createEntity("put");
+ Response response = sync.put(entity, Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: putWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:596;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * synchronously.
+ */
+ @Test
+ public String putWithGenericTypeStringTest() throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = createEntity("put");
+ SyncInvoker sync = createSyncInvokerForMethod("put");
+ String response = sync.put(entity, generic);
+ assertResponseString(response, "put");
+ return response;
+ }
+
+ /*
+ * @testName: putWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:596;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response putWithGenericTypeResponseTest() throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Entity<String> entity = createEntity("put");
+ SyncInvoker sync = createSyncInvokerForMethod("put");
+ Response response = sync.put(entity, generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: putWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:596;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, GenericType )
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void putWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ Entity<String> entity = createEntity("put");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.put(entity, generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: putWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:596;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void putWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+ Entity<String> entity = createEntity("put");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.put(entity, generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: putWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:596;
+ *
+ * @test_Strategy: throws WebApplicationException - in case the response
+ * status code of the response returned by the server is not successful and
+ * the specified response type is not Response.
+ */
+ @Test
+ public void putWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+ Entity<String> entity = createEntity("put");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.put(entity, generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------TRACE -----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: traceTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:599;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response traceTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("trace");
+ Response response = sync.trace();
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: traceThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:599;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace(Entity) throws
+ * ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void traceThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.trace();
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: traceWithStringClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:601;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * synchronously.
+ */
+ @Test
+ public String traceWithStringClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("trace");
+ String response = sync.trace(String.class);
+ assertResponseString(response, "trace");
+ return response;
+ }
+
+ /*
+ * @testName: traceWithResponseClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:601;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response traceWithResponseClassTest() throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("trace");
+ Response response = sync.trace(Response.class);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: traceWithStringClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:601;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void traceWithStringClassThrowsProcessingExceptionTest() throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ sync.trace(String.class);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: traceWithStringClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:601;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void traceWithStringClassThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+ sync.trace(String.class);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: traceWithResponseClassThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:601;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ //@Test
+ public void traceWithResponseClassThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+ Response response = sync.trace(Response.class);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: traceWithGenericTypeStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:604;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * synchronously.
+ */
+ @Test
+ public String traceWithGenericTypeStringTest() throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ SyncInvoker sync = createSyncInvokerForMethod("trace");
+ String response = sync.trace(generic);
+ assertResponseString(response, "trace");
+ return response;
+ }
+
+ /*
+ * @testName: traceWithGenericTypeResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:604;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * synchronously.
+ */
+ @Test
+ public Response traceWithGenericTypeResponseTest() throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ SyncInvoker sync = createSyncInvokerForMethod("trace");
+ Response response = sync.trace(generic);
+ assertResponseOk(response);
+ return response;
+ }
+
+ /*
+ * @testName: traceWithGenericTypeStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:604;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+ * throws ProcessingException in case the invocation failed.
+ */
+ @Test
+ public void traceWithGenericTypeStringThrowsProcessingExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerWrongUrl();
+ GenericType<String> generic = createGeneric(String.class);
+ sync.trace(generic);
+ }
+ };
+ assertProcessingException(run);
+ }
+
+ /*
+ * @testName: traceWithGenericTypeStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:604;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ @Test
+ public void traceWithGenericTypeStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+ GenericType<String> generic = createGeneric(String.class);
+ sync.trace(generic);
+ }
+ };
+ assertWebApplicationException(run);
+ }
+
+ /*
+ * @testName: traceWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:604;
+ *
+ * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+ * throws WebApplicationException - in case the response status code of the
+ * response returned by the server is not successful and the specified
+ * response type is not Response.
+ */
+ //@Test
+ public void traceWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+ throws Fault {
+ SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Response response = sync.trace(generic);
+ assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ // utility methods
+
+ protected String getUrl(String method) {
+ StringBuilder url = new StringBuilder();
+ url.append("http://").append(_hostname).append(":").append(_port);
+ url.append(getContextRoot()).append("/").append(method);
+ return url.toString();
+ }
+
+ /**
+ * Create SyncInvoker for given resource method and start time
+ */
+ protected SyncInvoker createSyncInvokerForMethod(String methodName) {
+ Client client = ClientBuilder.newClient();
+ client.register(new JdkLoggingFilter(false));
+ WebTarget target = client.target(getUrl(methodName));
+ SyncInvoker sync = target.request();
+ return sync;
+ }
+
+ protected SyncInvoker createSyncInvokerWrongUrl() {
+ _hostname = "tck.cts";
+ _port = 888;
+ return createSyncInvokerForMethod("wrongurl");
+ }
+
+ protected static void assertStatusAndLog(Response response, Status status)
+ throws Fault {
+ assertTrue(response.getStatus() == status.getStatusCode(),
+ "Returned unexpected status"+ response.getStatus());
+ String msg = new StringBuilder().append("Returned status ")
+ .append(status.getStatusCode()).append(" (").append(status.name())
+ .append(")").toString();
+ TestUtil.logMsg(msg);
+ }
+
+ protected static void assertResponseOk(Response response) throws Fault {
+ assertStatusAndLog(response, Status.OK);
+ }
+
+ protected static void assertResponseString(String response,
+ String expectedValue) throws Fault {
+ assertTrue(expectedValue.equals(response), "expected value"+ expectedValue+
+ "differes from acquired value"+ response);
+ }
+
+ protected static <T> Entity<T> createEntity(T entity) {
+ return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+ }
+
+ protected static <T> GenericType<T> createGeneric(Class<T> clazz) {
+ return new GenericType<T>(clazz);
+ }
+
+ protected static void assertProcessingException(Runnable runnable)
+ throws Fault {
+ assertException(runnable, ProcessingException.class);
+ }
+
+ protected static//
+ void assertWebApplicationException(Runnable runnable) throws Fault {
+ assertException(runnable, WebApplicationException.class);
+ }
+
+ protected static <T extends Exception> void assertException(Runnable runnable,
+ Class<T> exception) throws Fault {
+ try {
+ runnable.run();
+ } catch (Exception e) {
+ if (exception != null && exception.isInstance(e)) {
+ return;
+ }
+ throw new Fault("unexpected exception", e);
+ }
+ fault("ProcessingException has not been thrown");
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java
new file mode 100644
index 0000000..c2e456a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+import jakarta.ws.rs.tck.common.impl.TRACE;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HEAD;
+import jakarta.ws.rs.OPTIONS;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+@Path("resource")
+public class Resource {
+
+ @GET
+ @Path("get")
+ public String get() {
+ return "get";
+ }
+
+ @GET
+ @Path("getnotok")
+ public Response getNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @HEAD
+ @Path("head")
+ public String head() {
+ return "head";
+ }
+
+ @HEAD
+ @Path("headnotok")
+ public Response headNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @PUT
+ @Path("put")
+ public String put(String value) {
+ return value;
+ }
+
+ @PUT
+ @Path("putnotok")
+ public Response putNotOk(String value) {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @POST
+ @Path("post")
+ public String post(String value) {
+ return value;
+ }
+
+ @POST
+ @Path("postnotok")
+ public Response postNotOk(String value) {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @DELETE
+ @Path("delete")
+ public String delete() {
+ return "delete";
+ }
+
+ @DELETE
+ @Path("deletenotok")
+ public Response deleteNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @OPTIONS
+ @Path("options")
+ public String options() {
+ return "options";
+ }
+
+ @OPTIONS
+ @Path("optionsnotok")
+ public Response optionsNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @TRACE
+ @Path("trace")
+ public String trace() {
+ return "trace";
+ }
+
+ @TRACE
+ @Path("tracenotok")
+ public Response traceNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java
new file mode 100644
index 0000000..1b657bf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationHolderSingleton.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationHolderSingleton.java
new file mode 100644
index 0000000..2c1fd89
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationHolderSingleton.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+/**
+ * ApplicationHolderSingleton is a Singleton that is a dummy provider, too, to
+ * conform requirement on Provider
+ */
+public class ApplicationHolderSingleton
+ implements MessageBodyReader<Application> {
+ private Application application;
+
+ public ApplicationHolderSingleton(Application application) {
+ super();
+ this.application = application;
+ }
+
+ public Application getApplication() {
+ return application;
+ }
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ return true;
+ }
+
+ @Override
+ public Application readFrom(Class<Application> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ return null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java
new file mode 100644
index 0000000..8e83069
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Response;
+
+@Path("ApplicationTest")
+public class ApplicationServlet {
+
+ @GET
+ @Path("/GetSingletons")
+ public Response testGetSingletons(@Context Application application) {
+ // Derived from the default, thus return empty implementation
+ if (application.getSingletons() == null)
+ return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+ // Passed
+ return Response.ok(String.valueOf(application.getSingletons().size()))
+ .build();
+ }
+
+ @GET
+ @Path("/GetClasses")
+ public Response testGetClasses(@Context Application application) {
+ // Context Issue
+ application = getDeproxiedApplication(application);
+ if (!application.getClasses().contains(ApplicationServlet.class))
+ return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+ // Passed
+ return Response.ok(String.valueOf(application.getClasses().size())).build();
+ }
+
+ @Path("properties")
+ @GET
+ public Response getProperties(@Context Application application) {
+ Response response = null;
+ application = getDeproxiedApplication(application);
+ Map<String, Object> properties = application.getProperties();
+ if (properties == null || properties.size() == 0) {
+ response = Response.noContent().build();
+ } else {
+ Object val0 = properties.get(TSAppConfig.KEYS[0]);
+ Object val1 = properties.get(TSAppConfig.KEYS[1]);
+ if (TSAppConfig.VALUES[0].equals(val0)
+ && TSAppConfig.VALUES[1].equals(val1))
+ response = Response.ok(JaxrsUtil.mapToString(properties)).build();
+ else
+ response = Response.status(Response.Status.NOT_ACCEPTABLE).build();
+ }
+ return response;
+ }
+
+ // ////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Deproxy
+ */
+ protected static Application getDeproxiedApplication(
+ Application application) {
+ Set<Object> singletons = application.getSingletons();
+ for (Object s : singletons)
+ if (s.getClass() == ApplicationHolderSingleton.class)
+ return ((ApplicationHolderSingleton) s).getApplication();
+ throw new IllegalStateException(
+ "ApplicationHolderSingleton has not been found in a list of singletons");
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java
new file mode 100644
index 0000000..6340618
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.io.IOException;
+import java.util.Map;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response.Status;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_application_web/ApplicationTest");
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected int expectedSingletons = 1;
+
+ protected int expectedClasses = 1;
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_application_web.war");
+ archive.addClasses(TSAppConfig.class, ApplicationServlet.class, ApplicationHolderSingleton.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /*
+ * @testName: getSingletonsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:23
+ *
+ * @test_Strategy: Check that vi does not modify the getSingletons()
+ */
+ @Test
+ public void getSingletonsTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "GetSingletons"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ assertTrue(getReturnedNumber() == expectedSingletons,
+ "Application.getSingletons() return incorrect value:"+
+ getReturnedNumber());
+ }
+
+ /*
+ * @testName: getClassesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:22; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check the implementation injects TSAppConfig
+ */
+ @Test
+ public void getClassesTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "GetClasses"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ assertTrue(getReturnedNumber() == expectedClasses,
+ "Application.getClasses() return incorrect value:"+
+ getReturnedNumber());
+ }
+
+ /*
+ * @testName: getPropertiesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1035; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: The returned properties are reflected in the application
+ * configuration passed to the server-side features or injected into
+ * server-side JAX-RS components.
+ */
+ @Test
+ public void getPropertiesTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "properties"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ setProperty(Property.SEARCH_STRING, TSAppConfig.KEYS[0]);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultGetPropertiesIsEmptyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1035;
+ *
+ * @test_Strategy: The default implementation returns an empty set.
+ */
+ @Test
+ public void defaultGetPropertiesIsEmptyTest() throws Fault {
+ Application application = new Application();
+ Map<String, Object> properties = application.getProperties();
+ assertNotNull(properties,
+ "Default implementation is not empty map, but null");
+ assertTrue(properties.isEmpty(), "Default implementation is not empty, but"+
+ JaxrsUtil.mapToString(properties));
+ logMsg("Default implementation gets empty map as expected");
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ protected int getReturnedNumber() throws Fault {
+ HttpResponse response = _testCase.getResponse();
+ String body;
+ try {
+ body = response.getResponseBodyAsString();
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ return Integer.parseInt(body);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java
new file mode 100644
index 0000000..91ecf49
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+ static final String[] KEYS = { "key1", "key2" };
+
+ static final String[] VALUES = { "value1", "value2" };
+
+ private Map<String, Object> properties = new TreeMap<String, Object>();
+
+ public TSAppConfig() {
+ properties.put(KEYS[0], VALUES[0]);
+ properties.put(KEYS[1], VALUES[1]);
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ Set<Object> set = new HashSet<Object>();
+ set.add(new ApplicationHolderSingleton(this));
+ return set;
+ }
+
+ @Override
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(ApplicationServlet.class);
+ return resources;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java
new file mode 100644
index 0000000..51acda4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.io.IOException;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class FirstFilter implements ClientRequestFilter {
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.setEntity(getClass().getName(), null,
+ MediaType.WILDCARD_TYPE);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java
new file mode 100644
index 0000000..7235422
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java
@@ -0,0 +1,1280 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.core.configurable.Assertable;
+import jakarta.ws.rs.tck.api.rs.core.configurable.CallableProvider;
+import jakarta.ws.rs.tck.api.rs.core.configurable.Registrar;
+import jakarta.ws.rs.tck.api.rs.core.configurable.SingleCheckAssertable;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -8051302528257391040L;
+
+ private static final int configurableCnt = 2;
+
+ private int registeredClassesCnt = -1;
+
+ private int registeredInstancesCnt = -1;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_configurable_web/resource");
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_configurable_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class, Assertable.class, CallableProvider.class, Registrar.class, SingleCheckAssertable.class, jakarta.ws.rs.tck.api.rs.core.configurable.ConfigurableObject.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: registerClassWriterContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Class) except the JAX-RS component class is only registered as a
+ * provider of the listed extension provider or meta-provider contracts.
+ */
+ @Test
+ public void registerClassWriterContractsTest() throws Fault {
+ final String content = "registerClassWriterContractsTest";
+
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = getCallableEntity(content);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register((Class<?>) registerable, MessageBodyWriter.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 1);
+
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ Response response = i.invoke();
+ response.bufferEntity();
+ String responseString = response.readEntity(String.class);
+ assertEquals(content, responseString, "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully wrote Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ // check message body reader contract
+ try {
+ Callable<?> callable = response.readEntity(Callable.class);
+ fault("MessageBodyReader contract has been unexpectedly registered",
+ callable);
+ } catch (Exception e) {
+ logMsg("MessageBodyReader contract has not been registered as expected",
+ e);
+ }
+ }
+ }
+
+ /*
+ * @testName: registerClassReaderContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Class) except the JAX-RS component class is only registered as a
+ * provider of the listed extension provider or meta-provider contracts.
+ */
+ @Test
+ public void registerClassReaderContractsTest() throws Fault {
+ final String content = "registerClassReaderContractsTest";
+
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register((Class<?>) registerable, MessageBodyReader.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 1);
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ Response response = i.invoke();
+ Callable<?> callable = response.readEntity(Callable.class);
+ assertEquals(content, callable.toString(), "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully read Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ }
+ }
+
+ /*
+ * @testName: registerClassEmptyContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: Implementations MUST ignore attempts to register a
+ * component class for an empty collection of contracts via this method and
+ * SHOULD raise a warning about such event.
+ */
+ @Test
+ public void registerClassEmptyContractsTest() throws Fault {
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register((Class<?>) registerable, new Class<?>[] {});
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProvider();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, classes, entity);
+ logMsg("The provider of with contracts has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassNotAssignableContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: Contracts that are not assignable from the registered
+ * component class MUST be ignored
+ */
+ @Test
+ public void registerClassNotAssignableContractsTest() throws Fault {
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register((Class<?>) registerable, ClientRequestFilter.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProvider();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, classes, entity);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassNullContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:756;
+ *
+ * @test_Strategy: Implementations MUST ignore attempts to register a
+ * component class for a null collection of contracts via this method and
+ * SHOULD raise a warning about such event.
+ */
+ @Test
+ public void registerClassNullContractsTest() throws Fault {
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register((Class<?>) registerable, (Class<?>[]) null);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProvider();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, classes, entity);
+ logMsg("The provider with null contract has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassBindingPriorityFirstIsSecondTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:755;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Class) except that any binding priority specified on the
+ * registered JAX-RS component class via
+ *
+ * @Priority annotation is overridden with the supplied bindingPriority value.
+ */
+ @Test
+ public void registerClassBindingPriorityFirstIsSecondTest() throws Fault {
+ final String content = "registerClassBindingPriorityFirstIsSecondTest";
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ config.register(FirstFilter.class, 400);
+ config.register(SecondFilter.class, 399);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 2);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ String response = i.invoke(String.class);
+ assertEquals(FirstFilter.class.getName(), response,
+ "Unexpected filter ordering, the last was", response);
+ logMsg(response, "has been executed as second, as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassBindingPriorityFirstIsFirstTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:755;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Class) except that any binding priority specified on the
+ * registered JAX-RS component class via
+ *
+ * @Priority annotation is overridden with the supplied bindingPriority value.
+ */
+ @Test
+ public void registerClassBindingPriorityFirstIsFirstTest() throws Fault {
+ final String content = "registerClassBindingPriorityFirstIsFirstTest";
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ config.register(FirstFilter.class, 300);
+ config.register(SecondFilter.class, 399);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 2);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ String response = i.invoke(String.class);
+ assertEquals(SecondFilter.class.getName(), response,
+ "Unexpected filter ordering, the last was", response);
+ logMsg(response, "has been executed as second, as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectBindingPriorityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:759;
+ *
+ * @test_Strategy: Any binding priority specified on the registered JAX-RS
+ * component class via
+ *
+ * @Priority annotation is overridden with the supplied bindingPriority value.
+ */
+ @Test
+ public void registerObjectBindingPriorityTest() throws Fault {
+ final String content = "registerObjectBindingPriorityTest";
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ config.register(new FirstFilter(), 400);
+ config.register(new SecondFilter(), 399);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 2);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ String response = i.invoke(String.class);
+ assertEquals(FirstFilter.class.getName(), response,
+ "Unexpected filter ordering, the last was", response);
+ logMsg(response, "has been executed as second, as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectWriterContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:760;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Object) except the JAX-RS component class is only registered as a
+ * provider of the listed extension provider or meta-provider contracts.
+ */
+ @Test
+ public void registerObjectWriterContractsTest() throws Fault {
+ final String content = "registerObjectWriterContractsTest";
+
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = getCallableEntity(content);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register(registerable, MessageBodyWriter.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 1);
+
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, instances, entity);
+ Response response = i.invoke();
+ response.bufferEntity();
+ String responseString = response.readEntity(String.class);
+ assertEquals(content, responseString, "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully wrote Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ // check message body reader contract
+ try {
+ Callable<?> callable = response.readEntity(Callable.class);
+ fault("MessageBodyReader contract has been unexpectedly registered",
+ callable);
+ } catch (Exception e) {
+ logMsg("MessageBodyReader contract has not been registered as expected",
+ e);
+ }
+ }
+ }
+
+ /*
+ * @testName: registerObjectReaderContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:760;
+ *
+ * @test_Strategy: This registration method provides the same functionality as
+ * register(Object) except the JAX-RS component class is only registered as a
+ * provider of the listed extension provider or meta-provider contracts.
+ */
+ @Test
+ public void registerObjectReaderContractsTest() throws Fault {
+ final String content = "registerClassReaderContractsTest";
+
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register(registerable, MessageBodyReader.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 1);
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, instances, entity);
+ Response response = i.invoke();
+ Callable<?> callable = response.readEntity(Callable.class);
+ assertEquals(content, callable.toString(), "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully read Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ }
+ }
+
+ /*
+ * @testName: registerObjectEmptyContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:760;
+ *
+ * @test_Strategy: Implementations MUST ignore attempts to register a
+ * component class for an empty collection of contracts via this method and
+ * SHOULD raise a warning about such event.
+ */
+ @Test
+ public void registerObjectEmptyContractsTest() throws Fault {
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register(registerable, new Class<?>[] {});
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, instances, entity);
+ logMsg("The provider with empty contracts has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectNotAssignableContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:760;
+ *
+ * @test_Strategy: Contracts that are not assignable from the registered
+ * component class MUST be ignored
+ */
+ @Test
+ public void registerObjectNotAssignableContractsTest() throws Fault {
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register(registerable, ClientRequestFilter.class);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, instances, entity);
+ logMsg(
+ "The provider withO unassignable contract has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectNullContractsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:760;
+ *
+ * @test_Strategy: Implementations MUST ignore attempts to register a
+ * component class for a null collection of contracts via this method and
+ * SHOULD raise a warning about such event.
+ */
+ @Test
+ public void registerObjectNullContractsTest() throws Fault {
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue)
+ config.register(registerable, (Class<?>[]) null);
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProvider();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, instances, entity);
+ logMsg("The provider with null contract has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassWriterContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:989;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Class, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerClassWriterContractsInMapTest() throws Fault {
+ final String content = "registerClassWriterContractsInMapTest";
+
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = getCallableEntity(content);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(MessageBodyWriter.class, 100);
+ config.register((Class<?>) registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 1);
+
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ Response response = i.invoke();
+ response.bufferEntity();
+ String responseString = response.readEntity(String.class);
+ assertEquals(content, responseString, "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully wrote Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ // check message body reader contract
+ try {
+ Callable<?> callable = response.readEntity(Callable.class);
+ fault("MessageBodyReader contract has been unexpectedly registered",
+ callable);
+ } catch (Exception e) {
+ logMsg("MessageBodyReader contract has not been registered as expected",
+ e);
+ }
+ }
+ }
+
+ /*
+ * @testName: registerClassReaderContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:989;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Class, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerClassReaderContractsInMapTest() throws Fault {
+ final String content = "registerClassReaderContractsInMapTest";
+
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(MessageBodyReader.class, 100);
+ config.register((Class<?>) registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 1);
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ Response response = i.invoke();
+ Callable<?> callable = response.readEntity(Callable.class);
+ assertEquals(content, callable.toString(), "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully read Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ }
+ }
+
+ /*
+ * @testName: registerClassBindingPriorityInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:989;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Class, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerClassBindingPriorityInMapTest() throws Fault {
+ final String content = "registerClassBindingPriorityInMapTest";
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(ClientRequestFilter.class, 400);
+ config.register(FirstFilter.class, contracts);
+ contracts.clear();
+ contracts.put(ClientRequestFilter.class, 300);
+ config.register(SecondFilter.class, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+ cnt, 2);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ String response = i.invoke(String.class);
+ assertEquals(FirstFilter.class.getName(), response,
+ "Unexpected filter ordering, the last was", response);
+ logMsg(response, "has been executed as second, as expected");
+ }
+ }
+
+ /*
+ * @testName: registerClassNotAssignableContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:989;
+ *
+ * @test_Strategy: Contracts that are not assignable from the registered
+ * component class MUST be ignored
+ */
+ @Test
+ public void registerClassNotAssignableContractsInMapTest() throws Fault {
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(ClientRequestFilter.class, 400);
+ config.register((Class<?>) registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, classes, entity);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectWriterContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:990;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Object, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerObjectWriterContractsInMapTest() throws Fault {
+ final String content = "registerObjectWriterContractsInMapTest";
+
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = getCallableEntity(content);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(MessageBodyWriter.class, 100);
+ config.register(registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 1);
+
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, instances, entity);
+ Response response = i.invoke();
+ response.bufferEntity();
+ String responseString = response.readEntity(String.class);
+ assertEquals(content, responseString, "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully wrote Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ // check message body reader contract
+ try {
+ Callable<?> callable = response.readEntity(Callable.class);
+ fault("MessageBodyReader contract has been unexpectedly registered",
+ callable);
+ } catch (Exception e) {
+ logMsg("MessageBodyReader contract has not been registered as expected",
+ e);
+ }
+ }
+ }
+
+ /*
+ * @testName: registerObjectReaderContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:990;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Object, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerObjectReaderContractsInMapTest() throws Fault {
+ final String content = "registerObjectReaderContractsInMapTest";
+
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(MessageBodyReader.class, 100);
+ config.register(registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 1);
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Invocation i = checkConfig(registrar, assertable, instances, entity);
+ Response response = i.invoke();
+ Callable<?> callable = response.readEntity(Callable.class);
+ assertEquals(content, callable.toString(), "Expected", content,
+ "differs from given", response);
+ logMsg(
+ "sucessufully read Callable by provider registered on Configurable",
+ Assertable.getLocation(cnt));
+ }
+ }
+
+ /*
+ * @testName: registerObjectBindingPriorityInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:990;
+ *
+ * @test_Strategy: This registration method provides same functionality as
+ * register(Object, Class[]) except that any binding priority specified on the
+ * registered JAX-RS component class using @Priority annotation is overridden
+ * for each extension provider contract type separately with an integer
+ * binding priority value specified as a value in the supplied map.
+ */
+ @Test
+ public void registerObjectBindingPriorityInMapTest() throws Fault {
+ final String content = "registerObjectBindingPriorityInMapTest";
+ Class<?>[] classes = createProviderClasses();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(ClientRequestFilter.class, 400);
+ config.register(new FirstFilter(), contracts);
+ contracts.clear();
+ contracts.put(ClientRequestFilter.class, 300);
+ config.register(new SecondFilter(), contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ cnt, 2);
+ Invocation i = checkConfig(registrar, assertable, classes, entity);
+ String response = i.invoke(String.class);
+ assertEquals(FirstFilter.class.getName(), response,
+ "Unexpected filter ordering, the last was", response);
+ logMsg(response, "has been executed as second, as expected");
+ }
+ }
+
+ /*
+ * @testName: registerObjectNotAssignableContractsInMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:990;
+ *
+ * @test_Strategy: Contracts that are not assignable from the registered
+ * component class MUST be ignored
+ */
+ @Test
+ public void registerObjectNotAssignableContractsInMapTest() throws Fault {
+ Object[] instances = createProviderInstances();
+ // entity to send to a server
+ Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+ // register only once per client build
+ IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+ @Override
+ public void register(Configurable<?> config, Object registerable) {
+ if (currentValue++ == finalValue) {
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(ClientRequestFilter.class, 400);
+ config.register(registerable, contracts);
+ }
+ }
+ };
+
+ setResourceMethod("echo");
+ // build client configurableCnt times to register provider using a
+ // different
+ // configurable each time
+ Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+ for (int cnt = 0; cnt != configurableCnt; cnt++) {
+ // Check the provider is registered
+ logMsg("Check on Configurable", Assertable.getLocation(cnt));
+ // set we want to register the provider on Configurable
+ // Assertable::LOCATION[cnt]
+ registrar.setCurrentValue(0).setFinalValue(cnt);
+ checkConfig(registrar, assertable, instances, entity);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ private Assertable getAssertableWithRegisteredProviderClassesOnConfigurable(
+ final int configurableIndex, final int numberOfRegisteredClasses) {
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int size = config.getConfiguration().getClasses().size();
+ int shouldBe = getLocationIndex() >= configurableIndex
+ ? numberOfRegisteredClasses
+ : 0;
+ shouldBe += registeredClassesCnt;
+ assertEqualsInt(size, shouldBe,
+ "unexpected number of registered classes found:", size,
+ getLocation());
+ logMsg("Found", size, "provider(s) as expected");
+ }
+ };
+ return assertable;
+ }
+
+ private Assertable getAssertableWithRegisteredProviderInstancesOnConfigurable(
+ final int configurableIndex, final int numberOfRegisteredInstances) {
+ Assertable assertable = new SingleCheckAssertable() {
+ @Override
+ protected void check(Configurable<?> configurable) throws Fault {
+ assertSizeAndLog(configurable);
+ }
+
+ void assertSizeAndLog(Configurable<?> config) throws Fault {
+ int size = config.getConfiguration().getInstances().size();
+ int shouldBe = getLocationIndex() >= configurableIndex
+ ? numberOfRegisteredInstances
+ : 0;
+ shouldBe += registeredInstancesCnt;
+ assertEqualsInt(size, shouldBe,
+ "unexpected number of registered classes found:", size,
+ getLocation());
+ logMsg("Found", size, "provider(s) as expected");
+ }
+ };
+ return assertable;
+ }
+
+ private Assertable getAssertableWithNoRegisteredProvider() {
+ return getAssertableWithRegisteredProviderClassesOnConfigurable(0, 0);
+ }
+
+ private Assertable getAssertableWithNoRegisteredProviderInstance() {
+ return getAssertableWithRegisteredProviderInstancesOnConfigurable(0, 0);
+ }
+
+ /**
+ * Provider has to not be anonymous class, because we need @Provider
+ * annotation there
+ */
+ protected Object[] createProviderInstances() {
+ Object[] instances = new CallableProvider[] { new CallableProvider() {
+ }, new CallableProvider() {
+ } };
+ return instances;
+ }
+
+ protected static Class<?>[] createProviderClasses() {
+ Class<?>[] classes = new Class<?>[] { CallableProvider.class,
+ CallableProvider.class };
+ return classes;
+ }
+
+ protected Invocation checkConfig(Registrar registrar, Assertable assertable,
+ Object[] registerables, Entity<?> entity) throws Fault {
+ Client client = ClientBuilder.newClient();
+ Configuration config = client.getConfiguration();
+ registeredClassesCnt = config.getClasses().size();
+ registeredInstancesCnt = config.getInstances().size();
+ logMsg("Already registered", registeredClassesCnt, "classes");
+ logMsg("Already registered", registeredInstancesCnt, "instances");
+
+ register(registrar, client, registerables[0]);
+ assertable.check1OnClient(client);
+ assertable.incrementLocation();
+
+ WebTarget target = client.target(getAbsoluteUrl());
+ register(registrar, target, registerables[1]);
+ assertable.check2OnTarget(target);
+ assertable.incrementLocation();
+
+ Invocation.Builder builder = target.request();
+ Invocation invocation = builder.buildPost(entity);
+ return invocation;
+ }
+
+ protected void register(Registrar registrar, Configurable<?> config,
+ Object registerable) {
+ registrar.register(config, registerable);
+ }
+
+ protected class IncrementableRegistrar extends Registrar {
+ int currentValue;
+
+ int finalValue;
+
+ int getFinalValue() {
+ return finalValue;
+ }
+
+ IncrementableRegistrar setFinalValue(int finalValue) {
+ this.finalValue = finalValue;
+ return this;
+ }
+
+ IncrementableRegistrar(int initValue, int finalValue) {
+ currentValue = initValue;
+ this.finalValue = finalValue;
+ }
+
+ int getCurrentValue() {
+ return currentValue;
+ }
+
+ IncrementableRegistrar setCurrentValue(int set) {
+ currentValue = set;
+ return this;
+ }
+ }
+
+ private void setResourceMethod(String method) {
+ setContextRoot(getContextRoot() + "/" + method);
+ }
+
+ private static Entity<?> getCallableEntity(final String content) {
+ Entity<?> entity = Entity.entity(CallableProvider.createCallable(content),
+ MediaType.WILDCARD_TYPE);
+ return entity;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java
new file mode 100644
index 0000000..b8f2c16
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+ @POST
+ @Path("echo")
+ public String echo(String value) {
+ return value;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java
new file mode 100644
index 0000000..52d78ab
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.io.IOException;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class SecondFilter implements ClientRequestFilter {
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ requestContext.setEntity(getClass().getName(), null,
+ MediaType.WILDCARD_TYPE);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java
new file mode 100644
index 0000000..c2f52f2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configuration/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configuration/JAXRSClientIT.java
new file mode 100644
index 0000000..459ab7f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configuration/JAXRSClientIT.java
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configuration;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.core.configurable.Assertable;
+import jakarta.ws.rs.tck.api.rs.core.configurable.Registrar;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.MediaType;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+
+/**
+ * <p>
+ * These tests follow the intended JAXRS rule to enable Features in the order of
+ * them being registered. By this rule, it is possible to check the previous
+ * Feature has been / has not been enabled.
+ * </p>
+ *
+ * <p>
+ * The isEnabled works only in runtime which has its own version of
+ * configuration, i.e. it does not work on Configurable.getConfiguration()
+ * </p>
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 7215781408688132392L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_configuration_web/resource/echo");
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_configuration_web.war");
+ archive.addClasses(jakarta.ws.rs.tck.ee.rs.core.configurable.Resource.class,
+ jakarta.ws.rs.tck.ee.rs.core.configurable.TSAppConfig.class,
+ jakarta.ws.rs.tck.api.rs.core.configurable.Assertable.class,
+ jakarta.ws.rs.tck.api.rs.core.configurable.Registrar.class,
+ jakarta.ws.rs.tck.api.rs.core.configurable.CallableProvider.class,
+ jakarta.ws.rs.tck.api.rs.core.configurable.SingleCheckAssertable.class,
+ jakarta.ws.rs.tck.api.rs.core.configurable.ConfigurableObject.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: isEnabledFeatureReturningFalseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:999; JAXRS:JAVADOC:1003;
+ *
+ * @test_Strategy: Check if a feature instance of featureClass class has been
+ * previously enabled in the runtime configuration context.
+ *
+ * Returns true if the feature was successfully enabled, false otherwise
+ */
+ @Test
+ public void isEnabledFeatureReturningFalseTest() throws Fault {
+ final CheckingFeature feature1 = new FeatureReturningFalse1();
+ final CheckingFeature feature2 = new FeatureReturningFalse2();
+ final CheckingFeature feature3 = new FeatureReturningFalse3();
+ final CheckingFeature feature4 = new FeatureReturningFalse4();
+
+ feature1.addDisabledFeatures(feature2, feature3, feature4)
+ .setName("feature1");
+ feature2.addDisabledFeatures(feature1, feature3, feature4)
+ .setName("feature2");
+ feature3.addDisabledFeatures(feature1, feature2, feature4)
+ .setName("feature3");
+ feature4.addDisabledFeatures(feature1, feature2, feature3)
+ .setName("feature4");
+
+ Assertable assertable = new Assertable() {
+ @Override
+ public void check1OnClient(Client client) throws Fault {
+ assertIsDisabled(client, feature1);
+ assertIsDisabled(client, feature2);
+ assertIsDisabled(client, feature3);
+ assertIsDisabled(client, feature4);
+ }
+
+ @Override
+ public void check2OnTarget(WebTarget target) throws Fault {
+ assertIsDisabled(target, feature1);
+ assertIsDisabled(target, feature2);
+ assertIsDisabled(target, feature3);
+ assertIsDisabled(target, feature4);
+ }
+
+ void assertIsDisabled(Configurable<?> config, CheckingFeature feature)
+ throws Fault {
+ boolean isEnabled = config.getConfiguration().isEnabled(feature);
+ assertFalse(isEnabled, "Feature"+ feature.getName()+
+ "is unexpectedly enabled"+ getLocation());
+ logMsg("No feature enabled as expected", getLocation());
+ }
+ };
+ Object[] instances = { feature1, feature2, feature3, feature4 };
+ checkConfig(assertable, instances);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+
+ /*
+ * @testName: isEnabledFeatureReturningTrueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:999; JAXRS:JAVADOC:1003;
+ *
+ * @test_Strategy: Check if a feature instance of featureClass class has been
+ * previously enabled in the runtime configuration context.
+ *
+ * Returns true if the feature was successfully enabled, false otherwise
+ */
+ @Test
+ public void isEnabledFeatureReturningTrueTest() throws Fault {
+ final CheckingFeature feature1 = new FeatureReturningTrue1();
+ final CheckingFeature feature2 = new FeatureReturningTrue2();
+ final CheckingFeature feature3 = new FeatureReturningTrue3();
+ final CheckingFeature feature4 = new FeatureReturningTrue4();
+
+ feature1.addDisabledFeatures(feature2, feature3, feature4)
+ .setName("feature1");
+ feature2.addDisabledFeatures(feature3, feature4)
+ .addEnabledFeatures(feature1).setName("feature2");
+ feature3.addDisabledFeatures(feature4)
+ .addEnabledFeatures(feature1, feature2).setName("feature3");
+ feature4.addEnabledFeatures(feature1, feature2, feature3)
+ .setName("feature4");
+
+ Assertable assertable = new Assertable() {
+ @Override
+ public void check1OnClient(Client client) throws Fault {
+ assertIsRegistered(client, feature1);
+ assertIsNotRegistered(client, feature2);
+ assertIsNotRegistered(client, feature3);
+ assertIsNotRegistered(client, feature4);
+ }
+
+ @Override
+ public void check2OnTarget(WebTarget target) throws Fault {
+ assertIsRegistered(target, feature1);
+ assertIsRegistered(target, feature2);
+ assertIsNotRegistered(target, feature3);
+ assertIsNotRegistered(target, feature4);
+ }
+
+ void assertIsRegistered(Configurable<?> config, CheckingFeature feature)
+ throws Fault {
+ Configuration configuration = config.getConfiguration();
+ assertTrue(configuration.isRegistered(feature), "Feature"+
+ feature.getName()+ "is NOT registered"+ getLocation());
+ logMsg("Feature", feature.getName(), "registered as expected",
+ getLocation());
+ }
+
+ void assertIsNotRegistered(Configurable<?> config,
+ CheckingFeature feature) throws Fault {
+ Configuration configuration = config.getConfiguration();
+ assertFalse(configuration.isRegistered(feature), "Feature"+
+ feature.getName()+ "is unexpectedly registered"+ getLocation());
+ logMsg("Feature", feature.getName(), "NOT registered as expected",
+ getLocation());
+ }
+
+ };
+ Object[] instances = { feature1, feature2, feature3, feature4 };
+ checkConfig(assertable, instances);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+
+ /*
+ * @testName: isEnabledClassReturningFalseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1000; JAXRS:JAVADOC:1003;
+ *
+ * @test_Strategy: Check if a feature instance of featureClass class has been
+ * previously enabled in the runtime configuration context.
+ *
+ * Returns true if the feature was successfully enabled, false otherwise
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void isEnabledClassReturningFalseTest() throws Fault {
+ final CheckingFeature feature1 = new FeatureReturningFalse1();
+ final CheckingFeature feature2 = new FeatureReturningFalse2();
+ final CheckingFeature feature3 = new FeatureReturningFalse3();
+ final CheckingFeature feature4 = new FeatureReturningFalse4();
+
+ feature1
+ .addDisabledClasses(FeatureReturningFalse2.class,
+ FeatureReturningFalse3.class, FeatureReturningFalse4.class)
+ .setName("feature1");
+ feature2
+ .addDisabledClasses(FeatureReturningFalse1.class,
+ FeatureReturningFalse3.class, FeatureReturningFalse4.class)
+ .setName("feature2");
+ feature3
+ .addDisabledClasses(FeatureReturningFalse1.class,
+ FeatureReturningFalse2.class, FeatureReturningFalse4.class)
+ .setName("feature3");
+ feature4
+ .addDisabledClasses(FeatureReturningFalse1.class,
+ FeatureReturningFalse2.class, FeatureReturningFalse3.class)
+ .setName("feature4");
+
+ Assertable assertable = new Assertable() {
+ @Override
+ public void check1OnClient(Client client) throws Fault {
+ assertIsDisabled(client, feature1);
+ assertIsDisabled(client, feature2);
+ assertIsDisabled(client, feature3);
+ assertIsDisabled(client, feature4);
+ }
+
+ @Override
+ public void check2OnTarget(WebTarget target) throws Fault {
+ assertIsDisabled(target, feature1);
+ assertIsDisabled(target, feature2);
+ assertIsDisabled(target, feature3);
+ assertIsDisabled(target, feature4);
+ }
+
+ void assertIsDisabled(Configurable<?> config, CheckingFeature feature)
+ throws Fault {
+ boolean isEnabled = config.getConfiguration().isEnabled(feature);
+ assertFalse(isEnabled, "Feature"+ feature.getName()+
+ "is unexpectedly enabled"+ getLocation());
+ logMsg("No feature enabled as expected", getLocation());
+ }
+ };
+ Object[] instances = { feature1, feature2, feature3, feature4 };
+ checkConfig(assertable, instances);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+
+ /*
+ * @testName: isEnabledFeatureClassReturningTrueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1000; JAXRS:JAVADOC:1003;
+ *
+ * @test_Strategy: Check if a feature instance of featureClass class has been
+ * previously enabled in the runtime configuration context.
+ *
+ * Returns true if the feature was successfully enabled, false otherwise
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void isEnabledFeatureClassReturningTrueTest() throws Fault {
+ final CheckingFeature feature1 = new FeatureReturningTrue1();
+ final CheckingFeature feature2 = new FeatureReturningTrue2();
+ final CheckingFeature feature3 = new FeatureReturningTrue3();
+ final CheckingFeature feature4 = new FeatureReturningTrue4();
+
+ feature1
+ .addDisabledClasses(FeatureReturningTrue2.class,
+ FeatureReturningTrue3.class, FeatureReturningTrue4.class)
+ .setName("feature1");
+ feature2
+ .addDisabledClasses(FeatureReturningTrue3.class,
+ FeatureReturningTrue4.class)
+ .addEnabledClasses(FeatureReturningTrue1.class).setName("feature2");
+ feature3.addDisabledClasses(FeatureReturningTrue4.class)
+ .addEnabledClasses(FeatureReturningTrue1.class,
+ FeatureReturningTrue2.class)
+ .setName("feature3");
+ feature4
+ .addEnabledClasses(FeatureReturningTrue1.class,
+ FeatureReturningTrue2.class, FeatureReturningTrue3.class)
+ .setName("feature4");
+
+ Assertable assertable = new Assertable() {
+ @Override
+ public void check1OnClient(Client client) throws Fault {
+ assertIsRegistered(client, feature1);
+ assertIsNotRegistered(client, feature2);
+ assertIsNotRegistered(client, feature3);
+ assertIsNotRegistered(client, feature4);
+ }
+
+ @Override
+ public void check2OnTarget(WebTarget target) throws Fault {
+ assertIsRegistered(target, feature1);
+ assertIsRegistered(target, feature2);
+ assertIsNotRegistered(target, feature3);
+ assertIsNotRegistered(target, feature4);
+ }
+
+ void assertIsRegistered(Configurable<?> config, CheckingFeature feature)
+ throws Fault {
+ Configuration configuration = config.getConfiguration();
+ assertTrue(configuration.isRegistered(feature), "Feature"+
+ feature.getName()+ "is NOT registered"+ getLocation());
+ logMsg("Feature", feature.getName(), "registered as expected",
+ getLocation());
+ }
+
+ void assertIsNotRegistered(Configurable<?> config,
+ CheckingFeature feature) throws Fault {
+ Configuration configuration = config.getConfiguration();
+ assertFalse(configuration.isRegistered(feature), "Feature"+
+ feature.getName()+ "is unexpectedly registered"+ getLocation());
+ logMsg("Feature", feature.getName(), "NOT registered as expected",
+ getLocation());
+ }
+
+ };
+ Object[] instances = { feature1, feature2, feature3, feature4 };
+ checkConfig(assertable, instances);
+ logMsg(
+ "The provider with unassignable contract has ben ignored as expected");
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ /**
+ * Check on every possible setting of configuration by a Feature or a
+ * singleton
+ *
+ */
+ protected void checkConfig(Assertable assertable, Object[] registerables)
+ throws Fault {
+ checkConfig(new Registrar(), assertable, registerables);
+ }
+
+ protected void checkConfig(Registrar registrar, Assertable assertable,
+ Object[] registerables) throws Fault {
+ Entity<String> entity = Entity.entity("echo", MediaType.WILDCARD_TYPE);
+
+ Client client = ClientBuilder.newClient();
+ logMsg("Registering on Client");
+ register(registrar, client, registerables[0]);
+
+ WebTarget target = client.target(getAbsoluteUrl());
+ logMsg("Registering on WebTarget");
+ register(registrar, target, registerables[1]);
+
+ Invocation.Builder builder = target.request();
+ Invocation invocation = builder.buildPost(entity);
+
+ String response = invocation.invoke(String.class);
+ assertEquals(entity.getEntity(), response, "Unexpected response received",
+ response);
+
+ assertable.check1OnClient(client);
+ assertable.incrementLocation();
+ assertable.check2OnTarget(target);
+ }
+
+ protected void register(Registrar registrar, Configurable<?> config,
+ Object registerable) {
+ registrar.register(config, registerable);
+ }
+
+ // //////////////////////////////////////////////////////////////////////
+ private abstract class NamedFeature implements Feature {
+ String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public NamedFeature setName(String name) {
+ this.name = name;
+ return this;
+ }
+ }
+
+ class CheckingFeature extends NamedFeature {
+ List<NamedFeature> enabledFeatures = new LinkedList<NamedFeature>();
+
+ List<NamedFeature> disabledFeatures = new LinkedList<NamedFeature>();
+
+ List<Class<? extends NamedFeature>> enabledFeatureClasses = new LinkedList<Class<? extends NamedFeature>>();
+
+ List<Class<? extends NamedFeature>> disabledFeatureClasses = new LinkedList<Class<? extends NamedFeature>>();
+
+ @Override
+ public boolean configure(FeatureContext context) {
+ for (NamedFeature feature : enabledFeatures) {
+ if (!context.getConfiguration().isEnabled(feature))
+ throw new RuntimeException(
+ "Feature " + feature.getName() + " has NOT been enabled");
+ logMsg("Feature", feature.getName(), "has been enabled as expected");
+ }
+ for (NamedFeature feature : disabledFeatures) {
+ if (context.getConfiguration().isEnabled(feature))
+ throw new RuntimeException("Feature " + feature.getName()
+ + " has been unexpectedly enabled");
+ logMsg("Feature", feature.getName(),
+ "has NOT been enabled as expected");
+ }
+ for (Class<? extends NamedFeature> feature : enabledFeatureClasses) {
+ if (!context.getConfiguration().isEnabled(feature))
+ throw new RuntimeException(
+ "Feature " + feature.getName() + " has NOT been enabled");
+ logMsg("Feature", feature.getName(), "has been enabled as expected");
+ }
+ for (Class<? extends NamedFeature> feature : disabledFeatureClasses) {
+ if (context.getConfiguration().isEnabled(feature))
+ throw new RuntimeException("Feature " + feature.getName()
+ + " has been unexpectedly enabled");
+ logMsg("Feature", feature.getName(),
+ "has NOT been enabled as expected");
+ }
+ return true;
+ }
+
+ public CheckingFeature addEnabledFeatures(NamedFeature... features) {
+ if (features != null)
+ for (NamedFeature feature : features)
+ enabledFeatures.add(feature);
+ return this;
+ }
+
+ public CheckingFeature addDisabledFeatures(NamedFeature... features) {
+ if (features != null)
+ for (NamedFeature feature : features)
+ disabledFeatures.add(feature);
+ return this;
+ }
+
+ public CheckingFeature addEnabledClasses(
+ Class<? extends NamedFeature>... features) {
+ if (features != null)
+ for (Class<? extends NamedFeature> feature : features)
+ enabledFeatureClasses.add(feature);
+ return this;
+ }
+
+ public CheckingFeature addDisabledClasses(
+ Class<? extends NamedFeature>... features) {
+ if (features != null)
+ for (Class<? extends NamedFeature> feature : features)
+ disabledFeatureClasses.add(feature);
+ return this;
+ }
+ }
+
+ private class FeatureReturningFalse extends CheckingFeature {
+ @Override
+ public boolean configure(FeatureContext context) {
+ super.configure(context);
+ // false returning feature is not to be registered
+ return false;
+ }
+ }
+
+ private class FeatureReturningTrue extends CheckingFeature {
+ @Override
+ public boolean configure(FeatureContext context) {
+ return super.configure(context);
+ }
+ }
+
+ private class FeatureReturningFalse1 extends FeatureReturningFalse {
+ };
+
+ private class FeatureReturningFalse2 extends FeatureReturningFalse {
+ };
+
+ private class FeatureReturningFalse3 extends FeatureReturningFalse {
+ };
+
+ private class FeatureReturningFalse4 extends FeatureReturningFalse {
+ };
+
+ private class FeatureReturningTrue1 extends FeatureReturningTrue {
+ };
+
+ private class FeatureReturningTrue2 extends FeatureReturningTrue {
+ };
+
+ private class FeatureReturningTrue3 extends FeatureReturningTrue {
+ };
+
+ private class FeatureReturningTrue4 extends FeatureReturningTrue {
+ };
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java
new file mode 100644
index 0000000..f37116e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+@Path(value = "/HeadersTest")
+public class HttpHeadersTest {
+
+ @Context
+ HttpHeaders hs;
+
+ StringBuffer sb;
+
+ @GET
+ @Path("/headers")
+ public String headersGet() {
+ sb = new StringBuffer();
+ List<String> myHeaders = Arrays.asList("Accept", "Content-Type");
+
+ try {
+ MultivaluedMap<String, String> rqhdrs = hs.getRequestHeaders();
+ Set<String> keys = rqhdrs.keySet();
+ sb.append("getRequestHeaders= ");
+ for (String header : myHeaders) {
+ if (keys.contains(header)) {
+ sb.append(
+ "Found " + header + ": " + hs.getRequestHeader(header) + "; ");
+ }
+ }
+ } catch (Throwable ex) {
+ sb.append("Unexpected exception thrown in getRequestHeaders: "
+ + ex.getMessage());
+ ex.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/acl")
+ public String aclGet() {
+ sb = new StringBuffer();
+ try {
+ sb.append("Accept-Language");
+
+ List<Locale> acl = hs.getAcceptableLanguages();
+ sb.append("getLanguage= ");
+ for (Locale tmp : acl) {
+ sb.append(langToString(tmp)).append("; ");
+ }
+ } catch (Throwable ex) {
+ sb.append("Unexpected exception thrown in getAcceptableLanguages: "
+ + ex.getMessage());
+ ex.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/amt")
+ public String amtGet() {
+ sb = new StringBuffer();
+ try {
+ sb.append("getAcceptableMediaTypes");
+ List<MediaType> acmts = hs.getAcceptableMediaTypes();
+
+ for (MediaType mt : acmts) {
+ sb.append(mt.getType());
+ sb.append("/");
+ sb.append(mt.getSubtype());
+ }
+ } catch (Throwable ex) {
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ ex.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/mt")
+ public String mtGet() {
+ sb = new StringBuffer();
+
+ try {
+ sb.append("getMediaType");
+ MediaType mt = hs.getMediaType();
+ if (mt != null) {
+ sb.append(mt.getType());
+ sb.append("/");
+ sb.append(mt.getSubtype());
+ sb.append(" ");
+
+ java.util.Map<java.lang.String, java.lang.String> pmap = mt
+ .getParameters();
+
+ sb.append("MediaType size=" + pmap.size());
+
+ Iterator<Entry<String, String>> k = pmap.entrySet().iterator();
+ while (k.hasNext()) {
+ Entry<String, String> next = k.next();
+ String key = next.getKey();
+ sb.append("Key " + key + "; Value " + next.getValue());
+ }
+
+ sb.append(mt.toString());
+
+ sb.append("MediaType= " + mt.toString() + "; ");
+ } else {
+ sb.append("MediaType= null; ");
+ }
+ } catch (Throwable ex) {
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ ex.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/cookie")
+ public String cookieGet() {
+ sb = new StringBuffer();
+
+ try {
+ sb.append("getCookies= ");
+ Map<String, Cookie> cookies = hs.getCookies();
+ sb.append("Cookie Size=" + cookies.size());
+
+ for (Entry<String, Cookie> entry : cookies.entrySet()) {
+ sb.append("key=" + entry.getKey() + "; value=" + entry.getValue());
+ Cookie c = entry.getValue();
+ sb.append("Cookie Name=" + c.getName());
+ sb.append("Cookie Value=" + c.getValue());
+ sb.append("Cookie Path=" + c.getPath());
+ sb.append("Cookie Domain=" + c.getDomain());
+ sb.append("Cookie Version=" + c.getVersion());
+
+ }
+ } catch (Throwable ex) {
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ ex.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ @PUT
+ public String headersPlainPut(String nil) {
+ sb = new StringBuffer();
+ sb.append("Content-Language");
+ sb.append(langToString(hs.getLanguage()));
+ return sb.toString();
+ }
+
+ @POST
+ @Path("date")
+ public String date(@Context HttpHeaders headers, String nil) {
+ Date date = headers.getDate();
+ long time = date.getTime();
+ return String.valueOf(time);
+ }
+
+ @POST
+ @Path("headerstring")
+ public String headerString(@Context HttpHeaders headers, String headerName) {
+ String header = headers.getHeaderString(headerName);
+ return header;
+ }
+
+ @GET
+ @Path("length")
+ public String headerLength(@Context HttpHeaders headers) {
+ return String.valueOf(headers.getLength());
+ }
+
+ private static String langToString(Locale locale) {
+ return locale.toString().replace("_", "-");
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java
new file mode 100644
index 0000000..1d50c1d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.TimeZone;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Variant;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -5727774504018187299L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_headers_web/HeadersTest");
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_headers_web.war");
+ archive.addClasses(TSAppConfig.class, HttpHeadersTest.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: cookieTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:77;
+ *
+ * @test_Strategy: Client invokes GET request on root resource at
+ * /HeadersTest/cookie with Cookie set; Verify that all Cookies properties are
+ * set by the request
+ */
+ @Test
+ public void cookieTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ "Cookie: $Version=1; name1=value1; $Domain=" + _hostname
+ + "; $Path=/jaxrs_ee_core_headers_web");
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "cookie"));
+ setProperty(Property.SEARCH_STRING,
+ "getCookie|Cookie Name=name1|Cookie Value=value1"
+ + "|Cookie Path=/jaxrs_ee_core_headers_web" + "|Cookie Domain="
+ + "|Cookie Version=1");
+ invoke();
+ }
+
+ /*
+ * @testName: acceptLanguageTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:75;
+ *
+ * @test_Strategy: Client invokes GET request on root resource at
+ * /HeadersTes/acl with Language Header set; Verify that HttpHeaders got the
+ * property set by the request
+ */
+ @Test
+ public void acceptLanguageTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ buildAccept(MediaType.TEXT_PLAIN_TYPE));
+ setProperty(Property.REQUEST_HEADERS, "Accept-Language:en-US");
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "acl"));
+ setProperty(Property.SEARCH_STRING, "Accept-Language|en-US");
+ invoke();
+ }
+
+ /*
+ * @testName: contentLanguageTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:78;
+ *
+ * @test_Strategy: Client invokes PUT request on root resource at /HeadersTest
+ * with Language Header set; Verify that HttpHeaders got the property set by
+ * the request
+ */
+ @Test
+ public void contentLanguageTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ buildAccept(MediaType.TEXT_PLAIN_TYPE));
+ Variant variant = new Variant(MediaType.WILDCARD_TYPE, "en-US", null);
+ Entity<String> entity = Entity.entity("anything", variant);
+ setRequestContentEntity(entity);
+ setProperty(Property.REQUEST, buildRequest(Request.PUT, ""));
+ setProperty(Property.SEARCH_STRING_IGNORE_CASE, "Content-Language|en-US");
+ invoke();
+ }
+
+ /*
+ * @testName: mediaTypeTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8; JAXRS:JAVADOC:79;
+ *
+ * @test_Strategy: Client invokes GET request on a sub resource at
+ * /HeadersTest/mt with Content-Type Header set; Verify that HttpHeaders got
+ * the property set by the request
+ */
+ @Test
+ public void mediaTypeTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type:application/xml;charset=utf8");
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "mt"));
+ setProperty(Property.SEARCH_STRING, "getMediaType|application/xml"
+ + "|MediaType size=1|Key charset|Value utf8");
+ invoke();
+ }
+
+ /*
+ * @testName: mediaTypeAcceptableTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:76;
+ *
+ * @test_Strategy: Client invokes GET request on a sub resource at
+ * /HeadersTest/amt with Accept MediaType Header set; Verify that HttpHeaders
+ * got the property set by the request
+ */
+ @Test
+ public void mediaTypeAcceptableTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ "Accept:text/*, text/html, text/html;level=1, */*");
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "amt"));
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ "getAcceptableMediaTypes|text/*|text/html|text/html|*/*");
+ invoke();
+ }
+
+ /*
+ * @testName: requestHeadersTest
+ *
+ * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8; JAXRS:SPEC:40;
+ * JAXRS:JAVADOC:80; JAXRS:JAVADOC:81;
+ *
+ * @test_Strategy: Client invokes GET request on a sub resource at
+ * /HeadersTest/sub2 with Accept MediaType and Content-Type Headers set;
+ * Verify that HttpHeaders got the property set by the request
+ */
+ @Test
+ public void requestHeadersTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ "Accept:text/*, text/html, text/html;level=1, */*");
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type:application/xml;charset=utf8");
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "headers"));
+ setProperty(Property.SEARCH_STRING, "getRequestHeaders=|Accept:|text/*");
+ setProperty(Property.SEARCH_STRING, "text/html|text/html|*/*");
+ setProperty(Property.SEARCH_STRING, "Content-Type:|application/xml");
+ setProperty(Property.SEARCH_STRING, "charset=utf8");
+ invoke();
+ }
+
+ /*
+ * @testName: getDateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:779;
+ *
+ * @test_Strategy: Get message date
+ */
+ @Test
+ public void getDateTest() throws Fault {
+ long currentTime = System.currentTimeMillis();
+ DateFormat format = JaxrsUtil.createDateFormat(TimeZone.getTimeZone("GMT"));
+ String gmt = format.format(currentTime);
+
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "date"));
+ setProperty(Property.CONTENT, "getDate");
+ setProperty(Property.REQUEST_HEADERS, "Date:" + gmt);
+ invoke();
+ long responseTime = Long.parseLong(getResponseBody());
+ boolean check = Math.abs(currentTime - responseTime) < 1001L;
+ assertTrue(check, "HttpHeaders.getDate()="+ responseTime+
+ "differs from expected"+ currentTime+ "by more than 1000 ms.");
+ logMsg("#getDate() returned expected Date instance");
+ }
+
+ /*
+ * @testName: getHeaderStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:780;
+ *
+ * @test_Strategy: Get a HTTP header as a single string value.
+ */
+ @Test
+ public void getHeaderStringTest() throws Fault {
+ String[] headers = { "askdjb", "ksadbva", "klwiaslkfn", "klwvasbk" };
+ for (String header : headers) {
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "headerstring"));
+ setProperty(Property.CONTENT, header);
+ setProperty(Property.REQUEST_HEADERS, header + ":" + header + header);
+ setProperty(Property.SEARCH_STRING, header + header);
+ invoke();
+ }
+ logMsg("#getHeaderString() returned expected header values");
+ }
+
+ /*
+ * @testName: getHeaderStringUsesToStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:780;
+ *
+ * @test_Strategy: Get a HTTP header as a single string value. Each single
+ * header value is converted to String using its toString method if a header
+ * delegate is not available.
+ */
+ @Test
+ public void getHeaderStringUsesToStringTest() throws Fault {
+ final StringBean bean = new StringBean("bean");
+ ClientRequestFilter filter = new ClientRequestFilter() {
+ @Override
+ public void filter(ClientRequestContext ctx) throws IOException {
+ ctx.getHeaders().add(bean.get(), bean);
+ }
+ };
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "headerstring"));
+ setProperty(Property.CONTENT, bean.get());
+ addProvider(filter);
+ setProperty(Property.SEARCH_STRING, bean.toString());
+ invoke();
+ logMsg(
+ "#getHeaderString() returned expected header converted by toString() method");
+ }
+
+ /*
+ * @testName: getLengthTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:781;
+ *
+ * @test_Strategy: Get Content-Length value
+ */
+ @Test
+ public void getLengthTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(Request.GET, "length"));
+ invoke();
+ String body = getResponseBody();
+ assertTrue(body != null && body.length() > 0, "Nothing returned");
+ long length = Long.parseLong(body);
+ assertTrue(length != 0, "Nothing returned");
+ logMsg("#getLength() returned expected length", body);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java
new file mode 100644
index 0000000..0c5538c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+/**
+ *
+ * @author diannejiao
+ */
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(HttpHeadersTest.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java
new file mode 100644
index 0000000..0da365b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+/**
+ * This is the dummy class to get annotations from it
+ */
+public abstract class AnnotatedClass {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java
new file mode 100644
index 0000000..91979eb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CorruptedInputStream extends ByteArrayInputStream {
+
+ AtomicInteger atomic;
+
+ private boolean corrupted = false;
+
+ public static final int CLOSEVALUE = 999;
+
+ public static final String IOETEXT = "CorruptedInputStream tck test IOException";
+
+ public CorruptedInputStream(byte[] buf, AtomicInteger atomic) {
+ super(buf);
+ this.atomic = atomic;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (corrupted) {
+ atomic.set(CLOSEVALUE);
+ throw new IOException(IOETEXT);
+ }
+ super.close();
+ }
+
+ public boolean isCorrupted() {
+ return corrupted;
+ }
+
+ public void setCorrupted(boolean corrupted) {
+ this.corrupted = corrupted;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java
new file mode 100644
index 0000000..0d83139
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateReaderWriter
+ implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+
+ public static final int ANNOTATION_NONE = 0;
+
+ public static final int ANNOTATION_CONSUMES = 1 << 2;
+
+ public static final int ANNOTATION_PROVIDER = 1 << 3;
+
+ public static final int ANNOTATION_UNKNOWN = 1 << 7;
+
+ private AtomicInteger atom;
+
+ public DateReaderWriter(AtomicInteger atom) {
+ super();
+ this.atom = atom;
+ }
+
+ @Override
+ public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4) {
+ return String.valueOf(Long.MAX_VALUE).length();
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return arg0 == Date.class;
+ }
+
+ @Override
+ public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+ throws IOException, WebApplicationException {
+ parseAnnotations(arg3);
+ stream.write(String.valueOf(date.getTime()).getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return isWriteable(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+ throws IOException, WebApplicationException {
+ parseAnnotations(arg2);
+
+ InputStreamReader reader = new InputStreamReader(arg5);
+ BufferedReader br = new BufferedReader(reader);
+ long date = Long.parseLong(br.readLine());
+ return new Date(date);
+ }
+
+ protected void parseAnnotations(Annotation[] annotations) {
+ int value = ANNOTATION_NONE;
+ if (annotations != null)
+ for (Annotation annotation : annotations)
+ if (annotation.annotationType() == Consumes.class)
+ value |= ANNOTATION_CONSUMES;
+ else if (annotation.annotationType() == Provider.class)
+ value |= ANNOTATION_PROVIDER;
+ else
+ value |= ANNOTATION_UNKNOWN;
+ atom.set(value);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java
new file mode 100644
index 0000000..dd54287
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java
@@ -0,0 +1,1825 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.Link.Builder;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Response.StatusType;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/**
+ * Some tests are the same as the tests in api.rs.core package except how the
+ * Response is created. This is because implementation of inbound and outbound
+ * Response differ.
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 4182256439207983256L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_response_web/resource");
+ setPrintEntity(true);
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_response_web.war");
+ archive.addClasses(TSAppConfig.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class, ResponseTest.class, CorruptedInputStream.class, jakarta.ws.rs.tck.common.provider.StringBean.class, jakarta.ws.rs.tck.common.provider.StringBeanHeaderDelegate.class, jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider.class, jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate.class, jakarta.ws.rs.tck.common.provider.PrintingErrorHandler.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /*
+ * @class.setup_props: webServerHost; webServerPort; ts_home;
+ */
+ /* Run test */
+
+ /*
+ * @testName: statusTest
+ *
+ * @assertion_ids: JAXRS:SPEC:14.2; JAXRS:JAVADOC:131; JAXRS:JAVADOC:139;
+ *
+ * @test_Strategy: Client send request to a resource, verify that correct
+ * status code returned
+ *
+ */
+ @Test
+ public void statusTest() throws Fault {
+ for (Response.Status status : Response.Status.values()) {
+ if (status == Status.RESET_CONTENT)
+ continue; // it takes some time
+ setProperty(Property.STATUS_CODE, getStatusCode(status));
+ invokeGet("status?status=" + getStatusCode(status));
+ }
+ }
+
+ /*
+ * @testName: bufferEntityBuffersDataTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:838;
+ *
+ * @test_Strategy: Buffer the message entity. In case the message entity is
+ * backed by an unconsumed entity input stream, all the bytes of the original
+ * entity input stream are read and stored locally.
+ *
+ * This operation is idempotent, i.e. it can be invoked multiple times with
+ * the same effect which also means that calling the bufferEntity() method on
+ * an already buffered (and thus closed) message instance is legal and has no
+ * further effect.
+ */
+ @Test
+ public void bufferEntityBuffersDataTest() throws Fault {
+ Response response = invokeGet("entity");
+ boolean buffer = response.bufferEntity();
+ assertTrue(buffer, "#bufferEntity() did not buffer opened stream");
+ buffer = response.bufferEntity();
+ assertTrue(buffer, "#bufferEntity() is not idempotent");
+
+ String read = response.readEntity(String.class);
+ assertTrue(read.equals(ResponseTest.ENTITY), "Read entity"+ read+
+ "instead of"+ ResponseTest.ENTITY);
+ read = response.readEntity(String.class);
+ assertTrue(read.equals(ResponseTest.ENTITY), "Read entity"+ read+
+ "instead of"+ ResponseTest.ENTITY);
+ logMsg("#bufferEntity did buffer opened stream as expected");
+ }
+
+ /*
+ * @testName: bufferEntityThrowsExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:838;
+ *
+ * @test_Strategy: Throws: ProcessingException - if there was an error while
+ * buffering the entity input stream.
+ */
+ @Test
+ public void bufferEntityThrowsExceptionTest() throws Fault {
+ setCorruptedStream(); // the error is on buffering, which calls close()
+ Response response = invokeGet("corrupted");
+ catchCorruptedStreamExceptionOnBufferEntity(response);
+ logMsg("ProcessingException has been thrown as expected");
+ }
+
+ /*
+ * @testName: bufferEntityThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:838;
+ *
+ * @test_Strategy: throws IllegalStateException - in case the response has
+ * been #close() closed.
+ */
+ @Test
+ public void bufferEntityThrowsIllegalStateExceptionTest() throws Fault {
+ Response response = invokeGet("entity");
+ response.close();
+ try {
+ response.bufferEntity();
+ fault("buffer entity did not throw IllegalStateException when closed");
+ } catch (IllegalStateException e) {
+ logMsg("#bufferEntity throws IllegalStateException as expected");
+ }
+ }
+
+ /*
+ * @testName: closeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:841;
+ *
+ * @test_Strategy: Close the message entity input stream (if available and
+ * open). This operation is idempotent, i.e. it can be invoked multiple times
+ * with the same effect which also means that calling the method on an already
+ * closed message instance is legal and has no further effect
+ */
+ @Test
+ public void closeTest() throws Fault {
+ // make new Client, the one from super class calls bufferEntity()
+ Client client = ClientBuilder.newClient();
+ WebTarget target = client
+ .target("http://" + _hostname + ":" + _port + getContextRoot())
+ .path("entity");
+ Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+ .invoke();
+ response.close(); // calling the method on an already closed message
+ response.close(); // instance is legal
+
+ // Any attempts to manipulate (read, get, buffer) a message entity on a
+ // closed response will result in an IllegalStateException being thrown
+ try {
+ String entity = response.readEntity(String.class);
+ assertTrue(false, "IllegalStateException has not been thrown when"+
+ "#close() and #readEntity() but entity"+ entity+ "has been read");
+ } catch (IllegalStateException e) {
+ logMsg(
+ "#close() closed the stream, and consecutive reading threw IllegalStateException as expected");
+ }
+ }
+
+ /*
+ * @testName: closeThrowsExceptionWhenErrorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:841;
+ *
+ * @test_Strategy: throws ProcessingException - if there is an error closing
+ * the response.
+ */
+ @Test
+ public void closeThrowsExceptionWhenErrorTest() throws Fault {
+ setCorruptedStream();
+ Response response = invokeGet("corrupted");
+ try {
+ response.close(); // response.close should call stream.close()
+ assertTrue(false, "ProcessingException has not been thrown when"+
+ "CorruptedInputStream#close()");
+ } catch (ProcessingException e) {
+ // it is corrupted, #close throws IOException
+ assertNotNull(e.getCause(), "unknown exception thrown", e);
+ assertEquals(e.getCause().getMessage(), CorruptedInputStream.IOETEXT,
+ "unknown exception thrown", e);
+ logMsg("#close() threw ProcessingException as expected");
+ }
+ }
+
+ /*
+ * @testName: getAllowedMethodsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:843;
+ *
+ * @test_Strategy: Get the allowed HTTP methods from the Allow HTTP header.
+ */
+ @Test
+ public void getAllowedMethodsTest() throws Fault {
+ String allowed = Request.POST.name() + " " + Request.TRACE.name();
+ Response response = invokePost("allowedmethods", allowed);
+ Set<String> set = response.getAllowedMethods();
+ String methods = JaxrsUtil.iterableToString(";", set);
+ assertContainsIgnoreCase(methods, Request.POST.name(), Request.POST.name(),
+ "method has not been found");
+ assertContainsIgnoreCase(methods, Request.TRACE.name(),
+ Request.TRACE.name(), "method has not been found");
+ assertTrue(
+ methods.length() < Request.TRACE.name().length()
+ + Request.POST.name().length() + 3,
+ "Request contains some additional methods then expected"+ methods);
+ logMsg("#getAllowedMethods returned expected methods", methods);
+ }
+
+ /*
+ * @testName: getCookiesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:844;
+ *
+ * @test_Strategy: Get any new cookies set on the response message.
+ */
+ @Test
+ public void getCookiesTest() throws Fault {
+ Response response = invokeGet("cookies");
+ // getCookies test
+ Map<String, NewCookie> map = response.getCookies();
+ for (Entry<String, NewCookie> entry : map.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue().getValue();
+ if (key.equals("c1"))
+ assertEquals(value, "v1", value, "does not match expected v1");
+ else if (key.equals("c2"))
+ assertEquals(value, "v2", value, "does not match expected v2");
+ else
+ fault("Got unknown cookie", entry.getKey());
+ }
+
+ logMsg("#getCookies returned expected cookies");
+ }
+
+ /*
+ * @testName: getCookiesIsImmutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:844;
+ *
+ * @test_Strategy: returns a read-only map of cookie name (String) to Cookie.
+ */
+ @Test
+ public void getCookiesIsImmutableTest() throws Fault {
+ NewCookie cookie3 = new NewCookie("c3", "v3");
+ Response response = invokeGet("cookies");
+ // getCookies test
+ Map<String, NewCookie> map;
+ try {
+ map = response.getCookies();
+ map.put("c3", cookie3);
+ } catch (Exception e) {
+ // can throw an exception or nothing or return a copy map
+ }
+ map = response.getCookies();
+ assertFalse(map.containsKey("c3"), "getCookies is not read-only returned"+
+ map.get("c3"));
+ logMsg("#getCookies is read-only as expected");
+ }
+
+ /*
+ * @testName: getDateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:845;
+ *
+ * @test_Strategy: Get message date.
+ */
+ @Test
+ public void getDateTest() throws Fault {
+ long date = getCurrentTimeMillis();
+ Response response = invokePost("date", String.valueOf(date));
+ long responseDate = response.getDate().getTime();
+ // assertEqualsLong(date, responseDate, "Original date", date,
+ // "and response#getDate()", responseDate, "differs");
+ // int TC, the Date settings is overriden by underlaying containers
+ // But getDate is to be tested, not setDate, hence
+ assertTrue(Math.abs(responseDate - date) < (10 * 60 * 1000),
+ "#getDate() returned time that differes by more than 10 minutes");
+ logMsg("#getDate matches the Date HTTP header");
+ }
+
+ /*
+ * @testName: getEntityThrowsIllegalStateExceptionTestWhenClosed
+ *
+ * @assertion_ids: JAXRS:JAVADOC:123;
+ *
+ * @test_Strategy: if the entity was previously fully consumed as an
+ * InputStream input stream, or if the response has been #close() closed.
+ */
+ @Test
+ public void getEntityThrowsIllegalStateExceptionTestWhenClosed()
+ throws Fault {
+ Response response = invokeGet("entity");
+ response.close();
+ try {
+ Object entity = response.getEntity();
+ fault("No exception has been thrown, entity=", entity);
+ } catch (IllegalStateException e) {
+ logMsg("#getEntity throws IllegalStateException as expected", e);
+ }
+ }
+
+ /*
+ * @testName: getEntityThrowsIllegalStateExceptionWhenConsumedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:123;
+ *
+ * @test_Strategy: if the entity was previously fully consumed as an
+ * InputStream input stream, or if the response has been #close() closed.
+ */
+ @Test
+ public void getEntityThrowsIllegalStateExceptionWhenConsumedTest()
+ throws Fault {
+ Response response = invokeGet("entity");
+ response.readEntity(String.class);
+ try {
+ Object entity = response.getEntity();
+ fault("No exception has been thrown entity=", entity);
+ } catch (IllegalStateException e) {
+ logMsg("#getEntity throws IllegalStateException as expected", e);
+ }
+ }
+
+ /*
+ * @testName: getEntityTagTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:847;
+ *
+ * @test_Strategy: Get the entity tag.
+ */
+ @Test
+ public void getEntityTagTest() throws Fault {
+ String tag = "ABCDEF0123456789";
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.NOT_MODIFIED));
+ Response response = invokePost("entitytag", tag);
+ EntityTag responseTag = response.getEntityTag();
+ assertEquals(tag, responseTag.getValue(), "response#getEntityTag()",
+ responseTag.getValue(), "is unequal to expected EntityTag", tag);
+ logMsg("#getEntityTag is", responseTag, "as expected");
+ }
+
+ /*
+ * @testName: getEntityTagNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:847;
+ *
+ * @test_Strategy: Get null if not present.
+ */
+ @Test
+ public void getEntityTagNotPresentTest() throws Fault {
+ ResponseHeaderValue<EntityTag> value = new ResponseHeaderValue<>();
+ addProvider(new HeaderNotPresent<EntityTag>(value) {
+ @Override
+ protected void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<EntityTag> header) {
+ header.value = responseContext.getEntityTag();
+ }
+ });
+
+ Response response = invokePost("entitytag", null);
+ EntityTag responseTag = response.getEntityTag();
+ assertHeaderNull(responseTag, value, "getEntityTag");
+ }
+
+ /*
+ * @testName: getHeadersTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:848;
+ *
+ * @test_Strategy: Get view of the response headers and their object values.
+ */
+ @Test
+ public void getHeadersTest() throws Fault {
+ Response response = invokePost("headers", "notnull");
+ logMsg("Found following objects:");
+ logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+
+ MultivaluedMap<String, Object> headers = response.getHeaders();
+ String header = null;
+
+ header = headers.getFirst(HttpHeaders.CACHE_CONTROL).toString();
+ assertContainsIgnoreCase(header, "no-transform",
+ "Cache-Control:no-transform has not been found");
+
+ header = headers.getFirst(HttpHeaders.SET_COOKIE).toString();
+ assertContainsIgnoreCase(header, "cookie=eikooc",
+ "Set-Cookie:cookie=eikooc has not been found");
+
+ header = headers.getFirst(HttpHeaders.CONTENT_ENCODING).toString();
+ assertContainsIgnoreCase(header, "gzip",
+ "Content-Encoding:gzip has not been found");
+
+ header = headers.getFirst(HttpHeaders.EXPIRES).toString();
+ assertNotNull(header, "Expires has not been found");
+
+ header = headers.getFirst(HttpHeaders.CONTENT_LANGUAGE).toString();
+ assertContainsIgnoreCase(langToString(header),
+ langToString(Locale.CANADA_FRENCH), "Content-Language:",
+ langToString(Locale.CANADA_FRENCH), "has not been found");
+
+ Object noHeader = headers.getFirst("unknown");
+ assertNull(noHeader, "Unknown header has been found", header);
+ }
+
+ /*
+ * @testName: getHeadersUsingHeaderDelegateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:848;
+ *
+ * @test_Strategy: Get view of the response headers and their object values.
+ */
+ @Test
+ public void getHeadersUsingHeaderDelegateTest() throws Fault {
+ invokeGet("setstringbeanruntime");
+
+ Response response = invokePost("headerstring", "notnull");
+ String[] metadata = JaxrsCommonClient.getMetadata(response.getHeaders());
+ logMsg("Received:");
+ logMsg((Object[]) metadata);
+ String headers = JaxrsUtil.iterableToString(";", (Object[]) metadata);
+ for (int i = 1; i != 4; i++) {
+ String header = "s" + i + ":s" + i;
+ assertContainsIgnoreCase(headers, header, "Expected header", header,
+ "was not found in received headers", headers);
+ }
+ logMsg("Received expected headers", headers);
+
+ invokeGet("setoriginalruntime");
+ }
+
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:848;
+ *
+ * @test_Strategy: Get view of the response headers and their object values.
+ * Changes in the underlying header data are reflected in this view.
+ */
+ @Test
+ public void getHeadersIsMutableTest() throws Fault {
+ String header = "header";
+ Response response = invokePost("headers", null);
+ MultivaluedMap<String, Object> headers = response.getHeaders();
+ Object value = headers.getFirst(header);
+ assertNull(value, "Unexpected header", header, ":", value);
+ headers.add(header, header);
+ headers = response.getHeaders();
+ value = headers.getFirst(header);
+ assertContainsIgnoreCase(value, header, "Unexpected header value", header,
+ ":", value);
+ logMsg("getHeaders is mutable");
+ }
+
+ /*
+ * @testName: getHeaderStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:849;
+ *
+ * @test_Strategy: Get a message header as a single string value.
+ */
+ @Test
+ public void getHeaderStringTest() throws Fault {
+ Response response = invokePost("headers", "headerstring");
+ logMsg("Found following objects:");
+ logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+ assertContainsIgnoreCase(
+ response.getHeaderString(HttpHeaders.CACHE_CONTROL), "no-transform",
+ "Cache-Control:no-transform has not been found");
+ assertContainsIgnoreCase(response.getHeaderString(HttpHeaders.SET_COOKIE),
+ "cookie=eikooc", "Set-Cookie:cookie=eikooc has not been found");
+ assertContainsIgnoreCase(
+ response.getHeaderString(HttpHeaders.CONTENT_ENCODING), "gzip",
+ "Content-Encoding:gzip has not been found");
+ assertNotNull(response.getHeaderString(HttpHeaders.EXPIRES),
+ "Expires has not been found");
+ assertContainsIgnoreCase(
+ langToString(response.getHeaderString("Content-Language")),
+ langToString(Locale.CANADA_FRENCH), "Content-Language:",
+ langToString(Locale.CANADA_FRENCH), "has not been found");
+ assertNull(response.getHeaderString("unknown"),
+ "Unknown header has been found", response.getHeaderString("unknown"));
+ }
+
+ /*
+ * @testName: getHeaderStringUsingHeaderDelegateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:849;
+ *
+ * @test_Strategy: Get a message header as a single string value. Each single
+ * header value is converted to String using a RuntimeDelegate.HeaderDelegate
+ * or using its toString
+ */
+ @Test
+ public void getHeaderStringUsingHeaderDelegateTest() throws Fault {
+ invokeGet("setstringbeanruntime");
+
+ Response response = invokePost("headerstring", "delegate");
+ String header = response.getHeaderString("s3");
+ assertContainsIgnoreCase(header, "s3", "Header", "s3",
+ "has unexpected value", header);
+ logMsg("HeaderDelegate is used for header as expected");
+
+ invokeGet("setoriginalruntime");
+ }
+
+ /*
+ * @testName: getHeaderStringUsingToStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:849;
+ *
+ * @test_Strategy: Get a message header as a single string value. Each single
+ * header value is converted to String using a RuntimeDelegate.HeaderDelegate
+ * or using its toString
+ */
+ @Test
+ public void getHeaderStringUsingToStringTest() throws Fault {
+ Response response = invokePost("headerstring", "toString");
+ String header = response.getHeaderString("s1");
+ assertContainsIgnoreCase(header, "s1", "Header s1 has unexpected value",
+ header);
+
+ header = response.getHeaderString("s2");
+ assertContainsIgnoreCase(header, "s2", "Header s2 has unexpected value",
+ header);
+
+ logMsg("toString method is used as expected");
+ }
+
+ /*
+ * @testName: getLanguageTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:850;
+ *
+ * @test_Strategy: Get the language of the message entity.
+ */
+ @Test
+ public void getLanguageTest() throws Fault {
+ Response response = invokePost("language",
+ Locale.CANADA_FRENCH.getCountry());
+ Locale locale = response.getLanguage();
+ assertTrue(Locale.CANADA_FRENCH.equals(locale), "Locale"+
+ Locale.CANADA_FRENCH+ "does NOT match response#getLocale()"+ locale);
+ logMsg("#getLocale matches the Content-Language HTTP header");
+ }
+
+ /*
+ * @testName: getLanguageNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:850;
+ *
+ * @test_Strategy: Get null if not present.
+ */
+ @Test
+ public void getLanguageNotPresentTest() throws Fault {
+ ResponseHeaderValue<Locale> value = new ResponseHeaderValue<>();
+ addProvider(new HeaderNotPresent<Locale>(value) {
+ @Override
+ protected void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<Locale> header) {
+ header.value = responseContext.getLanguage();
+ }
+ });
+
+ Response response = invokePost("language", null);
+ Locale locale = response.getLanguage();
+ assertHeaderNull(locale, value, "getLanguage");
+ }
+
+ /*
+ * @testName: getLastModifiedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:851;
+ *
+ * @test_Strategy: Get the last modified date.
+ */
+ @Test
+ public void getLastModifiedTest() throws Fault {
+ long time = getCurrentTimeMillis();
+ Response response = invokePost("lastmodified", String.valueOf(time));
+ long responseDate = response.getLastModified().getTime();
+ assertEqualsLong(time, responseDate, "Last Modified date", time,
+ "does NOT match response#getLastModified()", responseDate);
+ logMsg("#getLastModified matches the Last-Modified HTTP header");
+ }
+
+ /*
+ * @testName: getLastModifiedNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:851;
+ *
+ * @test_Strategy: Get null if not present.
+ */
+ @Test
+ public void getLastModifiedNotPresentTest() throws Fault {
+ ResponseHeaderValue<Date> containerValue = new ResponseHeaderValue<>();
+ addProvider(new HeaderNotPresent<Date>(containerValue) {
+ @Override
+ protected void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<Date> header) {
+ header.value = responseContext.getLastModified();
+ }
+ });
+
+ Response response = invokePost("lastmodified", null);
+ Date responseDate = response.getLastModified();
+ assertHeaderNull(responseDate, containerValue, "getLastModified");
+ }
+
+ /*
+ * @testName: getLengthTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:852;
+ *
+ * @test_Strategy: Get Content-Length value.
+ */
+ @Test
+ public void getLengthTest() throws Fault {
+ Response response = invokePost("length", "1234567890");
+ int len = response.getLength();
+ assertTrue(len > 9, "Expected Content-Length > 9"+
+ "does NOT match response#getLength()"+ len);
+ logMsg("#getLength matches expected Content-Length", len);
+ }
+
+ /*
+ * @testName: getLengthNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:852;
+ *
+ * @test_Strategy: In other cases returns -1.
+ */
+ @Test
+ public void getLengthNotPresentTest() throws Fault {
+ Response response = invokePost("length", null);
+ int len = response.getLength();
+ String headerLen = response.getHeaderString(HttpHeaders.CONTENT_LENGTH);
+ if (headerLen == null)
+ assertEqualsInt(len, -1, "Expected Content-Length = -1",
+ "does NOT match response#getLength()", len);
+ else
+ assertEqualsInt(len, Integer.parseInt(headerLen),
+ "Expected Content-Length =", headerLen,
+ "does NOT match response#getLength()=", len);
+ logMsg("#getLength matches expected Content-Length", len);
+ }
+
+ /*
+ * @testName: getLinkTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:853;
+ *
+ * @test_Strategy: Get the link for the relation.
+ */
+ @Test
+ public void getLinkTest() throws Fault {
+ String rel = "getLinkTest";
+ Response response = invokePost("link", rel);
+ Link responseLink = response.getLink(rel);
+ assertNotNull(responseLink, "#getLink is null");
+ assertContains(rel, responseLink.getRel(),
+ "#getLink() returned unexpected Link", responseLink);
+ logMsg("#getLink matches expected Link");
+ }
+
+ /*
+ * @testName: getLinkNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:853;
+ *
+ * @test_Strategy: returns null if not present.
+ */
+ @Test
+ public void getLinkNotPresentTest() throws Fault {
+ ResponseHeaderValue<Link> containerValue = new ResponseHeaderValue<>();
+ addProvider(new HeaderNotPresent<Link>(containerValue) {
+ @Override
+ protected void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<Link> header) {
+ header.value = responseContext.getLink("getLinkTest");
+ }
+ });
+
+ Response response = invokePost("link", null);
+ Link responseLink = response.getLink("getLinkTest");
+ assertHeaderNull(responseLink, containerValue, "getLink");
+ }
+
+ /*
+ * @testName: getLinkBuilderForTheRelationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:854;
+ *
+ * @test_Strategy: Convenience method that returns a Link.Builder for the
+ * relation.
+ */
+ @Test
+ public void getLinkBuilderForTheRelationTest() throws Fault {
+ String rel = "anyrelation";
+ Response response = invokePost("linkbuilder", rel);
+ Link responseLink = response.getLink(rel);
+ assertNotNull(responseLink, "#getLinkBuilder('relation') returned null");
+ logMsg("#getLinkBuilder creates correct Link for given relation");
+ }
+
+ /*
+ * @testName: getLinkBuilderForTheNotPresentRelationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:854;
+ *
+ * @test_Strategy: returns null if not present.
+ */
+ @Test
+ public void getLinkBuilderForTheNotPresentRelationTest() throws Fault {
+ Response response = invokeGet("entity");
+ Builder builder = response.getLinkBuilder("anyrelation");
+ assertNull(builder,
+ "#getLinkBuilder('relation') returned unexpected builder", builder);
+ logMsg("#getLinkBuilder returned null as expected");
+ }
+
+ /*
+ * @testName: getLinksTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:855;
+ *
+ * @test_Strategy: Get the links attached to the message as header.
+ */
+ @Test
+ public void getLinksTest() throws Fault {
+ Response response = invokeGet("links");
+ Set<Link> responseLinks = response.getLinks();
+ assertEqualsInt(responseLinks.size(), 2,
+ "#getLinks() returned set of unexpected size", responseLinks.size());
+ logMsg("#getLinks contains expected links");
+ }
+
+ /*
+ * @testName: getLinksIsNotNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:855;
+ *
+ * @test_Strategy: Does not return null.
+ */
+ @Test
+ public void getLinksIsNotNullTest() throws Fault {
+ Response response = invokeGet("entity");
+ Set<Link> responseLinks = response.getLinks();
+ assertTrue(responseLinks != null, "#getLinks() returned null!");
+ assertTrue(responseLinks.size() == 0,
+ "#getLinks() returned non-empty map!");
+ logMsg("#getLinks contains no links as expected");
+ }
+
+ /*
+ * @testName: getLocationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:856;
+ *
+ * @test_Strategy: Get the location.
+ */
+ @Test
+ public void getLocationTest() throws Fault {
+ String path = "path";
+ URI serverUri = ResponseTest.createUri(path);
+ Response response = invokePost("location", path);
+ URI responseLocation = response.getLocation();
+ assertEquals(responseLocation, serverUri, "#getLocation()",
+ responseLocation, "differs from expected", serverUri);
+ logMsg("#getLocation contains expected location");
+ }
+
+ /*
+ * @testName: getLocationNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:856;
+ *
+ * @test_Strategy: Get null when no present.
+ */
+ @Test
+ public void getLocationNotPresentTest() throws Fault {
+ ResponseHeaderValue<URI> containerValue = new ResponseHeaderValue<>();
+ addProvider(new HeaderNotPresent<URI>(containerValue) {
+ @Override
+ protected void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<URI> header) {
+ header.value = responseContext.getLocation();
+ }
+ });
+
+ Response response = invokeGet("entity");
+ URI responseLocation = response.getLocation();
+ assertHeaderNull(responseLocation, containerValue, "getLocation");
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:857;
+ *
+ * @test_Strategy: Get the media type of the message entity.
+ */
+ @Test
+ public void getMediaTypeTest() throws Fault {
+ MediaType mediaType = MediaType.APPLICATION_ATOM_XML_TYPE;
+ Response response = invokePost("mediatype", mediaType.toString());
+ MediaType responseMedia = response.getMediaType();
+ assertEquals(mediaType, responseMedia, "#getMediaType()", responseMedia,
+ "differs from expected", MediaType.APPLICATION_ATOM_XML);
+ logMsg("#getMediaType returned expected MediaType");
+ }
+
+ /*
+ * @testName: getStatusInfoTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:858;
+ *
+ * @test_Strategy: Get the complete status information associated with the
+ * response.
+ */
+ @Test
+ public void getStatusInfoTest() throws Fault {
+ for (Status status : Status.values()) {
+ setProperty(Property.STATUS_CODE, getStatusCode(status));
+ Response response = invokePost("statusinfo", status.name());
+ StatusType info = response.getStatusInfo();
+ assertEqualsInt(info.getStatusCode(), status.getStatusCode(),
+ "#getStatusInfo returned unexpected value", info);
+ }
+ logMsg("#getStatusInfo returned expected StatusTypes");
+ }
+
+ /*
+ * @testName: getStringHeadersUsingToStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:859;
+ *
+ * @test_Strategy: Get view of the response headers and their string values.
+ * Each single header value is converted to String using a
+ * RuntimeDelegate.HeaderDelegate or using its toString
+ */
+ @Test
+ public void getStringHeadersUsingToStringTest() throws Fault {
+ Response response = invokePost("headerstring", "stringheaders");
+ MultivaluedMap<String, String> headers = response.getStringHeaders();
+ String header = headers.getFirst("s1");
+ assertContainsIgnoreCase(header, "s1", "Header", "s1",
+ "has unexpected value", header);
+
+ header = headers.getFirst("s2");
+ assertContainsIgnoreCase(header, "s2", "Header", "s2",
+ "has unexpected value", header);
+
+ logMsg("#getStringHeaders contains expected values",
+ JaxrsUtil.iterableToString(",", headers.entrySet()));
+ }
+
+ /*
+ * @testName: getStringHeadersUsingHeaderDelegateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:859;
+ *
+ * @test_Strategy: Get view of the response headers and their string values.
+ * Each single header value is converted to String using a
+ * RuntimeDelegate.HeaderDelegate or using its toString
+ */
+ @Test
+ public void getStringHeadersUsingHeaderDelegateTest() throws Fault {
+ invokeGet("setstringbeanruntime");
+
+ Response response = invokePost("headerstring", "stringheaders");
+ MultivaluedMap<String, String> headers = response.getStringHeaders();
+ String header = headers.getFirst("s3");
+ assertContainsIgnoreCase("s3", header, "Header", "s3",
+ "has unexpected value", header);
+
+ logMsg("#getStringHeaders contains expected values",
+ JaxrsUtil.iterableToString(",", headers.entrySet()));
+
+ invokeGet("setoriginalruntime");
+ }
+
+ /*
+ * @testName: hasEntityWhenEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:860;
+ *
+ * @test_Strategy: Check if there is an entity available in the response.
+ */
+ @Test
+ public void hasEntityWhenEntityTest() throws Fault {
+ Response response = invokeGet("entity");
+ assertTrue(response.hasEntity(), "#hasEntity did not found the entity");
+ logMsg("#hasEntity found the entity as expected");
+ }
+
+ /*
+ * @testName: hasEntityWhenNoEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:860;
+ *
+ * @test_Strategy: Check if there is an entity available in the response.
+ */
+ @Test
+ public void hasEntityWhenNoEntityTest() throws Fault {
+ Response response = invokePost("headerstring", null);
+ assertFalse(response.hasEntity(), "#hasEntity did found the entity");
+ logMsg("#hasEntity has not found any entity as expected");
+ }
+
+ /*
+ * @testName: hasEntityThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:860;
+ *
+ * @test_Strategy: throws java.lang.IllegalStateException - in case the
+ * response has been closed.
+ */
+ @Test
+ public void hasEntityThrowsIllegalStateExceptionTest() throws Fault {
+ Response response = invokeGet("entity");
+ response.close();
+ try {
+ response.hasEntity();
+ fault("No exception has been thrown");
+ } catch (IllegalStateException e) {
+ logMsg("IllegalStateException has been thrown as expected");
+ }
+
+ }
+
+ /*
+ * @testName: hasLinkWhenLinkTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:862;
+ *
+ * @test_Strategy: Check if link for relation exists.
+ */
+ @Test
+ public void hasLinkWhenLinkTest() throws Fault {
+ Response response = invokePost("link", "path");
+ assertTrue(response.hasLink("path"), "#hasLink did not found a Link");
+ logMsg("#hasEntity found the Link as expected");
+ }
+
+ /*
+ * @testName: hasLinkWhenNoLinkTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:862;
+ *
+ * @test_Strategy: Check if link for relation exists.
+ */
+ @Test
+ public void hasLinkWhenNoLinkTest() throws Fault {
+ Response response = invokeGet("entity");
+ assertFalse(response.hasLink("rel"), "#has Link did found some Link");
+ logMsg("#hasLink has not found any Link as expected");
+ }
+
+ /*
+ * @testName: readEntityClassTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: Read the message entity input stream as an instance of
+ * specified Java type using a MessageBodyReader that supports mapping the
+ * message entity stream onto the requested type
+ */
+ @Test
+ public void readEntityClassTest() throws Fault {
+ Response response = invokeGet("entity");
+ response.bufferEntity();
+ String line;
+
+ Reader reader = response.readEntity(Reader.class);
+ line = readLine(reader);
+ assertTrue(ResponseTest.ENTITY.equals(line), "#readEntity(Reader)={"+ line+
+ "} differs from expected"+ ResponseTest.ENTITY);
+
+ byte[] buffer = new byte[0];
+ buffer = response.readEntity(buffer.getClass());
+ line = new String(buffer);
+ assertTrue(ResponseTest.ENTITY.equals(line), "#readEntity(byte[].class)={"+
+ line+ "} differs from expected"+ ResponseTest.ENTITY);
+
+ logMsg("Got expected", line);
+ }
+
+ /*
+ * @testName: readEntityClassIsNullWhenNoEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: If the message does not contain an entity body null is
+ * returned.
+ */
+ @Test
+ public void readEntityClassIsNullWhenNoEntityTest() throws Fault {
+ Response response = invokeGet("status?status=200");
+ String entity = response.readEntity(String.class);
+ assertTrue(entity == null || "".equals(entity),
+ "entity is not null or zero length"+ entity);
+ logMsg("Null or zero length entity returned when no entity as expected");
+ }
+
+ /*
+ * @testName: readEntityClassCloseIsCalledTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityClassCloseIsCalledTest() throws Fault {
+ AtomicInteger ai = setCorruptedStream();
+ final Response response = invokeGet("corrupted");
+ catchCorruptedStreamException(new Runnable() {
+ @Override
+ public void run() {
+ response.readEntity(String.class);
+ }
+ });
+ assertEquals(ai.get(), CorruptedInputStream.CLOSEVALUE,
+ "Close has not been called");
+ logMsg("Close() has been called on an entity stream as expected");
+ }
+
+ /*
+ * @testName: readEntityClassCloseIsNotCalledOnInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityClassCloseIsNotCalledOnInputStreamTest() throws Fault {
+ AtomicInteger ai = setCorruptedStream();
+ Response response = invokeGet("corrupted");
+ try {
+ response.readEntity(InputStream.class);
+ logMsg("Close() has not been called on entity stream as expected");
+ } catch (Exception e) {
+ throw new Fault("Close was called", e);
+ }
+ assertTrue(ai.get() == 0, "Close was called");
+ }
+
+ /*
+ * @testName: readEntityClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: Method throws an ProcessingException if the content of the
+ * message cannot be mapped to an entity of the requested type
+ */
+ @Test
+ public void readEntityClassThrowsProcessingExceptionTest() throws Fault {
+ Response response = invokeGet("entity");
+ try {
+ response.readEntity(Void.class);
+ throw new Fault(
+ "No exception has been thrown when reader for entity class is not known");
+ } catch (ProcessingException e) {
+ logMsg("ProcessingException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityClassThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:863;
+ *
+ * @test_Strategy: if the entity is not backed by an input stream, or if the
+ * entity input stream has been fully consumed already and has not been
+ * buffered prior consuming.
+ */
+ @Test
+ public void readEntityClassThrowsIllegalStateExceptionTest() throws Fault {
+ Client client = ClientBuilder.newClient(); // create a new client
+ WebTarget target = client.target( // with no bufferEntity called
+ "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+ Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+ .invoke();
+ String entity = response.readEntity(String.class);
+ assertTrue(ResponseTest.ENTITY.equals(entity),
+ "#readEntity(String.class)={"+ entity+ "} differs from expected"+
+ ResponseTest.ENTITY);
+ try {
+ response.readEntity(Reader.class);
+ throw new Fault(
+ "No exception has been thrown when reader for entity is not buffered");
+ } catch (IllegalStateException e) {
+ logMsg("IllegalStateException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: Read the message entity input stream as an instance of
+ * specified Java type using a MessageBodyReader that supports mapping the
+ * message entity stream onto the requested type
+ */
+ @Test
+ public void readEntityGenericTypeTest() throws Fault {
+ Response response = invokeGet("entity");
+ response.bufferEntity();
+ String line;
+
+ Reader reader = response.readEntity(generic(Reader.class));
+ line = readLine(reader);
+ assertTrue(ResponseTest.ENTITY.equals(line),
+ "#readEntity(GenericType<Reader>)={"+ line+ "} differs from expected"+
+ ResponseTest.ENTITY);
+
+ byte[] buffer = new byte[0];
+ buffer = response.readEntity(generic(buffer.getClass()));
+ assertTrue(buffer != null,
+ "response.readEntity(GenericType<byte[]>) is null");
+ line = new String(buffer);
+ assertTrue(ResponseTest.ENTITY.equals(line),
+ "#readEntity(GenericType<byte[]>)={"+ line+ "} differs from expected"+
+ ResponseTest.ENTITY);
+
+ logMsg("Got expected", line);
+ }
+
+ /*
+ * @testName: readEntityGenericIsNullWhenNoEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: If the message does not contain an entity body null is
+ * returned.
+ */
+ @Test
+ public void readEntityGenericIsNullWhenNoEntityTest() throws Fault {
+ String request = buildRequest(Request.GET, "status?status=200");
+ setProperty(Property.REQUEST, request);
+ invoke();
+ Response response = getResponse();
+ String entity = response.readEntity(generic(String.class));
+ assertTrue(entity == null || "".equals(entity),
+ "entity is not null or zero length"+ entity);
+ logMsg("Null or zero length entity returned when no entity as expected");
+ }
+
+ /*
+ * @testName: readEntityGenericCloseIsCalledTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityGenericCloseIsCalledTest() throws Fault {
+ AtomicInteger ai = setCorruptedStream();
+ final Response response = invokeGet("corrupted");
+ catchCorruptedStreamException(new Runnable() {
+ @Override
+ public void run() {
+ response.readEntity(generic(String.class));
+ }
+ });
+ assertTrue(ai.get() == CorruptedInputStream.CLOSEVALUE,
+ "Close has not been called");
+ logMsg("Close() has been called on an entity stream as expected");
+ }
+
+ /*
+ * @testName: readEntityGenericTypeCloseIsNotCalledOnInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityGenericTypeCloseIsNotCalledOnInputStreamTest()
+ throws Fault {
+ AtomicInteger ai = setCorruptedStream();
+ Response response = invokeGet("corrupted");
+ try {
+ response.readEntity(generic(InputStream.class));
+ logMsg("Close() has not been called on entity stream as expected");
+ } catch (Exception e) {
+ throw new Fault("Close was called", e);
+ }
+ assertTrue(ai.get() == 0, "Close was called");
+ }
+
+ /*
+ * @testName: readEntityGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: Method throws an ProcessingException if the content of the
+ * message cannot be mapped to an entity of the requested type
+ */
+ @Test
+ public void readEntityGenericTypeThrowsProcessingExceptionTest()
+ throws Fault {
+ Response response = invokeGet("entity");
+ try {
+ response.readEntity(generic(Void.class));
+ throw new Fault(
+ "No exception has been thrown when reader for entity class is not known");
+ } catch (ProcessingException e) {
+ logMsg("ProcessingException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityGenericTypeThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:866;
+ *
+ * @test_Strategy: if the entity is not backed by an input stream, or if the
+ * entity input stream has been fully consumed already and has not been
+ * buffered prior consuming.
+ */
+ @Test
+ public void readEntityGenericTypeThrowsIllegalStateExceptionTest()
+ throws Fault {
+ Client client = ClientBuilder.newClient(); // create a new client
+ WebTarget target = client.target( // with no bufferEntity called
+ "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+ Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+ .invoke();
+ String entity = response.readEntity(generic(String.class));
+ assertTrue(ResponseTest.ENTITY.equals(entity),
+ "#readEntity(GenericType<byte[]>)={"+ entity+ "} differs from expected"+
+ ResponseTest.ENTITY);
+ try {
+ response.readEntity(generic(Reader.class));
+ throw new Fault(
+ "No exception has been thrown when reader for entity is not buffered");
+ } catch (IllegalStateException e) {
+ logMsg("IllegalStateException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: Read the message entity input stream as an instance of
+ * specified Java type using a MessageBodyReader that supports mapping the
+ * message entity stream onto the requested type. annotations - annotations
+ * that will be passed to the MessageBodyReader.
+ */
+ @Test
+ public void readEntityClassAnnotationTest() throws Fault {
+ Date date = Calendar.getInstance().getTime();
+ String sDate = String.valueOf(date.getTime());
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ int expected = DateReaderWriter.ANNOTATION_CONSUMES
+ | DateReaderWriter.ANNOTATION_PROVIDER;
+
+ AtomicInteger ai = new AtomicInteger();
+ DateReaderWriter drw = new DateReaderWriter(ai);
+ addProvider(drw);
+
+ Response response = invokeGet("date?date=" + sDate);
+ response.bufferEntity();
+
+ Date entity = response.readEntity(Date.class, annotations);
+ assertTrue(date.equals(entity), "#readEntity(Date, annotations)={"+ entity+
+ "} differs from expected"+ date);
+
+ assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+ expected+ "which suggest a problem with annotation passing");
+
+ String responseDate = response.readEntity(String.class, annotations);
+ assertTrue(sDate.equals(responseDate),
+ "#readEntity(String.class, annotations)={"+ responseDate+
+ "} differs from expected"+ sDate);
+
+ assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+ expected+ "which suggest a problem with annotation passing");
+
+ logMsg("Got expected date", date);
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationIsNullWhenNoEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: If the message does not contain an entity body null is
+ * returned.
+ */
+ @Test
+ public void readEntityClassAnnotationIsNullWhenNoEntityTest() throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Response response = invokeGet("status?status=200");
+ String entity = response.readEntity(String.class, annotations);
+ assertTrue(entity == null || "".equals(entity),
+ "entity is not null or zero length"+ entity);
+ logMsg("Null or zero length entity returned when no entity as expected");
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationCloseIsCalledTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityClassAnnotationCloseIsCalledTest() throws Fault {
+ final Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ AtomicInteger ai = setCorruptedStream();
+ final Response response = invokeGet("corrupted");
+ catchCorruptedStreamException(new Runnable() {
+ @Override
+ public void run() {
+ response.readEntity(String.class, annotations);
+ }
+ });
+ assertEqualsInt(ai.get(), CorruptedInputStream.CLOSEVALUE,
+ "Close has not been called");
+ logMsg("Close() has been called on an entity stream as expected");
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationCloseIsNotCalledOnInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityClassAnnotationCloseIsNotCalledOnInputStreamTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ AtomicInteger ai = setCorruptedStream();
+ Response response = invokeGet("corrupted");
+ try {
+ response.readEntity(InputStream.class, annotations);
+ logMsg("Close() has not been called on entity stream as expected");
+ } catch (ProcessingException e) {
+ throw new Fault("Close was called", e);
+ }
+ assertTrue(ai.get() == 0, "Close was called");
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: Method throws an ProcessingException if the content of the
+ * message cannot be mapped to an entity of the requested type
+ */
+ @Test
+ public void readEntityClassAnnotationThrowsProcessingExceptionTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Response response = invokeGet("entity");
+ try {
+ response.readEntity(Void.class, annotations);
+ throw new Fault(
+ "No exception has been thrown when reader for entity class is not known");
+ } catch (ProcessingException e) {
+ logMsg("ProcessingException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityClassAnnotationThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:869;
+ *
+ * @test_Strategy: if the entity is not backed by an input stream, or if the
+ * entity input stream has been fully consumed already and has not been
+ * buffered prior consuming.
+ */
+ @Test
+ public void readEntityClassAnnotationThrowsIllegalStateExceptionTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Client client = ClientBuilder.newClient(); // create a new client
+ WebTarget target = client.target( // with no bufferEntity called
+ "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+ Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+ .invoke();
+ String entity = response.readEntity(String.class, annotations);
+ assertTrue(ResponseTest.ENTITY.equals(entity),
+ "#readEntity(String.class, annotations)={"+ entity+
+ "} differs from expected"+ ResponseTest.ENTITY);
+ try {
+ response.readEntity(Reader.class, annotations);
+ throw new Fault(
+ "No exception has been thrown when reader for entity is not buffered");
+ } catch (IllegalStateException e) {
+ logMsg("IllegalStateException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: Read the message entity input stream as an instance of
+ * specified Java type using a MessageBodyReader that supports mapping the
+ * message entity stream onto the requested type. annotations - annotations
+ * that will be passed to the MessageBodyReader.
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationTest() throws Fault {
+ Date date = Calendar.getInstance().getTime();
+ String sDate = String.valueOf(date.getTime());
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ int expected = DateReaderWriter.ANNOTATION_CONSUMES
+ | DateReaderWriter.ANNOTATION_PROVIDER;
+
+ AtomicInteger ai = new AtomicInteger();
+ DateReaderWriter drw = new DateReaderWriter(ai);
+ addProvider(drw);
+
+ Response response = invokeGet("date?date=" + sDate);
+ response.bufferEntity();
+
+ Date entity = response.readEntity(generic(Date.class), annotations);
+ assertTrue(date.equals(entity), "#readEntity(Date, annotations)={"+ entity+
+ "} differs from expected"+ date);
+
+ assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+ expected+ "which suggest a problem with annotation passing");
+
+ String responseDate = response.readEntity(generic(String.class),
+ annotations);
+ assertTrue(sDate.equals(responseDate),
+ "#readEntity(String.class, annotations)={"+ responseDate+
+ "} differs from expected"+ sDate);
+
+ assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+ expected+ "which suggest a problem with annotation passing");
+
+ logMsg("Got expected date", date);
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationIsNullWhenNoEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: If the message does not contain an entity body null is
+ * returned.
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationIsNullWhenNoEntityTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Response response = invokeGet("status?status=200");
+ String entity = response.readEntity(generic(String.class), annotations);
+ assertTrue(entity == null || "".equals(entity),
+ "entity is not null or zero length"+ entity);
+ logMsg("Null or zero length entity returned when no entity as expected");
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationCloseIsCalledTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationCloseIsCalledTest() throws Fault {
+ final Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ AtomicInteger ai = setCorruptedStream();
+ final Response response = invokeGet("corrupted");
+ catchCorruptedStreamException(new Runnable() {
+ @Override
+ public void run() {
+ response.readEntity(generic(String.class), annotations);
+ }
+ });
+ assertEqualsInt(ai.get(), CorruptedInputStream.CLOSEVALUE,
+ "Close has not been called");
+ logMsg("Close() has been called on an entity stream as expected");
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationCloseIsNotCalledOnInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: Unless the supplied entity type is an input stream, this
+ * method automatically closes the consumed response entity stream if it is
+ * not buffered.
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationCloseIsNotCalledOnInputStreamTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ AtomicInteger ai = setCorruptedStream();
+ Response response = invokeGet("corrupted");
+ try {
+ response.readEntity(generic(InputStream.class), annotations);
+ } catch (ProcessingException e) {
+ fault("Close was called", e);
+ }
+ assertEqualsInt(ai.get(), 0, "Close was called");
+ logMsg("Close() has not been called on entity stream as expected");
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: Method throws an ProcessingException if the content of the
+ * message cannot be mapped to an entity of the requested type
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationThrowsProcessingExceptionTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Response response = invokeGet("entity");
+ try {
+ response.readEntity(generic(Void.class), annotations);
+ throw new Fault(
+ "No exception has been thrown when reader for entity class is not known");
+ } catch (ProcessingException e) {
+ logMsg("ProcessingException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: readEntityGenericTypeAnnotationThrowsIllegalStateExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:872;
+ *
+ * @test_Strategy: if the entity is not backed by an input stream, or if the
+ * entity input stream has been fully consumed already and has not been
+ * buffered prior consuming.
+ */
+ @Test
+ public void readEntityGenericTypeAnnotationThrowsIllegalStateExceptionTest()
+ throws Fault {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Client client = ClientBuilder.newClient(); // create a new client
+ WebTarget target = client.target( // with no bufferEntity called
+ "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+ Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+ .invoke();
+ String entity = response.readEntity(generic(String.class), annotations);
+ assertTrue(ResponseTest.ENTITY.equals(entity),
+ "#readEntity(GenericType<String>, annotations)={"+ entity+
+ "} differs from expected"+ ResponseTest.ENTITY);
+ try {
+ response.readEntity(generic(Reader.class), annotations);
+ throw new Fault(
+ "No exception has been thrown when reader for entity is not buffered");
+ } catch (IllegalStateException e) {
+ logMsg("IllegalStateException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: responseCreatedRelativeURITest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:121;
+ *
+ * @test_Strategy: The resource calls Response.created() to set the Location header with a
+ * relative URI. The relative URI should be converted into an absolute URI by resolving it
+ * relative to the base URI.
+ */
+ @Test
+ public void responseCreatedRelativeURITest()
+ throws Fault {
+ String resourceUrl = getAbsoluteUrl();
+ String expected = resourceUrl.substring(0, resourceUrl.length() - "resource".length()) + "created";
+ Response response = invokeGet("created");
+ try {
+ assertTrue(expected.equals(response.getHeaderString("location")),
+ "#response.getHeaderString(\"location\") [" +
+ response.getHeaderString("location") + "] differs from "+ expected);
+ } finally {
+ response.close();
+ }
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ protected <T> GenericType<T> generic(Class<T> clazz) {
+ return new GenericType<T>(clazz);
+ }
+
+ protected Response invokeGet(String method) throws Fault {
+ String request = buildRequest(Request.GET, method);
+ setProperty(Property.REQUEST_HEADERS,
+ buildAccept(MediaType.TEXT_PLAIN_TYPE));
+ setProperty(Property.REQUEST, request);
+ invoke();
+ return getResponse();
+ }
+
+ protected Response invokePost(String method, Object entity) throws Fault {
+ String request = buildRequest(Request.POST, method);
+ setProperty(Property.REQUEST, request);
+ setRequestContentEntity(entity);
+ invoke();
+ return getResponse();
+ }
+
+ protected String readLine(Reader reader) throws Fault {
+ String line = null;
+ BufferedReader buffered = new BufferedReader(reader);
+ try {
+ line = buffered.readLine();
+ } catch (IOException e) {
+ try {
+ buffered.close();
+ } catch (IOException ie) {
+ }
+ throw new Fault(e);
+ }
+ return line;
+ }
+
+ protected AtomicInteger setCorruptedStream() {
+ final AtomicInteger ai = new AtomicInteger(0);
+ ClientResponseFilter filter = new ClientResponseFilter() {
+ @Override
+ public void filter(ClientRequestContext arg0,
+ ClientResponseContext response) throws IOException {
+ CorruptedInputStream cis = new CorruptedInputStream(
+ ResponseTest.ENTITY.getBytes(), ai);
+ cis.setCorrupted(true);
+ response.setEntityStream(cis);
+ }
+ };
+ addProvider(filter);
+
+ // do not use new entity stream in logging filter for the case of priority
+ // disfunction, the CorruptedInputStream would be then replaced, wrongly
+ // informing about not closing the stream
+ super.setPrintEntity(false);
+
+ return ai;
+ }
+
+ protected long getCurrentTimeMillis() {
+ long millis = System.currentTimeMillis() / 1000;
+ millis *= 1000;
+ return millis;
+ }
+
+ protected String langToString(Object object) {
+ Locale locale = null;
+ if (object instanceof List)
+ object = ((List<?>) object).iterator().next();
+ if (object instanceof Locale)
+ locale = (Locale) object;
+ String value = locale == null ? object.toString() : locale.toString();
+ return value.replace("_", "-");
+ }
+
+ protected void catchCorruptedStreamException(Runnable runnable) throws Fault {
+ try {
+ runnable.run();
+ } catch (ProcessingException e) {
+ // it is corrupted, #close throws IOException
+ assertNotNull(e.getCause(), "unknown exception thrown", e);
+ assertEquals(e.getCause().getMessage(), CorruptedInputStream.IOETEXT,
+ "unknown exception thrown", e);
+ }
+ }
+
+ protected void catchCorruptedStreamExceptionOnBufferEntity(
+ final Response response) throws Fault {
+ catchCorruptedStreamException(new Runnable() {
+ @Override
+ public void run() {
+ // The original entity input stream is
+ // consumed and automatically closed
+ response.bufferEntity();
+ }
+ });
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // Even though the test itself do not set the headers, possibly the vendor's
+ ////////////////////////////////////////////////////////////////////////////////////////////// container
+ ////////////////////////////////////////////////////////////////////////////////////////////// does.
+ // In that case, the ResponseFilter checks the value; if it is not expected
+ ////////////////////////////////////////////////////////////////////////////////////////////// null,
+ ////////////////////////////////////////////////////////////////////////////////////////////// the
+ ////////////////////////////////////////////////////////////////////////////////////////////// response
+ // should return the same value the response context does.
+
+ private <T> void assertHeaderNull(T actualHeader,
+ ResponseHeaderValue<T> filterValue, String method) throws Fault {
+ if (filterValue.value == null) {
+ assertNull(actualHeader, "response#" + method + "() should be null, was ",
+ actualHeader);
+ logMsg("response#" + method + "() was null as expected");
+ } else {
+ assertEquals(filterValue.value, actualHeader,
+ "response#" + method + "() was set to " + filterValue.value,
+ "by container but was ", actualHeader);
+ logMsg("response#" + method + "() was set to " + actualHeader
+ + " as preset by container");
+ }
+ }
+
+ class ResponseHeaderValue<T> {
+ private T value;
+ }
+
+ abstract class HeaderNotPresent<T> implements ClientResponseFilter {
+ private ResponseHeaderValue<T> headerValue;
+
+ public HeaderNotPresent(ResponseHeaderValue<T> headerValue) {
+ this.headerValue = headerValue;
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext,
+ ClientResponseContext responseContext) throws IOException {
+ setHeader(responseContext, headerValue);
+ }
+
+ protected abstract void setHeader(ClientResponseContext responseContext,
+ ResponseHeaderValue<T> header);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java
new file mode 100644
index 0000000..7874bab
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+@Path("resource")
+public class ResponseTest {
+ public static final String ENTITY = "ENtiTy";
+
+ @GET
+ @Path("status")
+ @Produces(value = "text/plain")
+ public Response statusTest(@QueryParam("status") int status) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("status code in request = " + status);
+ ResponseBuilder builder = Response.status(status);
+ Response res = builder.header("TESTHEADER", sb.toString()).build();
+ return res;
+ }
+
+ @GET
+ @Path("entity")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String entity() {
+ return ENTITY;
+ }
+
+ @GET
+ @Path("corrupted")
+ public CorruptedInputStream corrupted() {
+ return new CorruptedInputStream(ENTITY.getBytes(), null);
+ }
+
+ @GET
+ @Path("date")
+ public String date(@QueryParam("date") String date) {
+ return date;
+ }
+
+ @POST
+ @Path("allowedmethods")
+ public Response getAllowedMethods(String methods) {
+ ResponseBuilder builder = Response.ok();
+ StringTokenizer tokenizer = new StringTokenizer(methods);
+ List<String> allowed = new LinkedList<String>();
+ while (tokenizer.hasMoreTokens())
+ allowed.add(tokenizer.nextToken());
+ builder.allow(allowed.toArray(new String[0]));
+ return builder.build();
+ }
+
+ @GET
+ @Path("cookies")
+ public Response getCookies() {
+ NewCookie cookie1 = new NewCookie("c1", "v1");
+ NewCookie cookie2 = new NewCookie("c2", "v2");
+ Response response = Response.ok().cookie(cookie1).cookie(cookie2).build();
+ return response;
+ }
+
+ @POST
+ @Path("date")
+ public Response getDate(String date) throws InterruptedException {
+ ResponseBuilder builder = Response.ok();
+ Thread.sleep(1500L);
+ if (date != null && date.length() != 0) {
+ long millis = Long.parseLong(date);
+ Date dateFromMillis = new Date(millis);
+ builder = builder.header(HttpHeaders.DATE, dateFromMillis);
+ }
+ Response response = builder.build();
+ return response;
+ }
+
+ @POST
+ @Path("entitytag")
+ public Response getEntityTag(String tag) {
+ ResponseBuilder builder;
+ if (tag != null && tag.length() != 0) {
+ EntityTag entityTag = new EntityTag(tag);
+ builder = Response.notModified(entityTag);
+ } else
+ builder = Response.ok();
+ Response response = builder.build();
+ return response;
+ }
+
+ @POST
+ @Path("headers")
+ public Response getHeaders(String headers) {
+ CacheControl ccl = new CacheControl();
+ NewCookie cookie = new NewCookie("cookie", "eikooc");
+ String encoding = "gzip";
+ Date date = Calendar.getInstance().getTime();
+ ResponseBuilder builder = Response.ok();
+ if (headers != null && headers.length() != 0) {
+ builder = builder.cacheControl(ccl).cookie(cookie).encoding(encoding)
+ .expires(date).language(Locale.CANADA_FRENCH);
+ }
+ return builder.build();
+ }
+
+ @POST
+ @Path("headerstring")
+ public Response getHeaderString(String headers) {
+ StringBuilder builder = new StringBuilder("s1");
+ StringBuffer buffer = new StringBuffer("s2");
+ StringBean bean = new StringBean("s3");
+ ResponseBuilder response = Response.ok();
+ if (headers != null && headers.length() != 0)
+ response = response.header(builder.toString(), builder)
+ .header(buffer.toString(), buffer).header(bean.get(), bean);
+ return response.build();
+ }
+
+ @POST
+ @Path("language")
+ public Response getLanguage(String lang) {
+ ResponseBuilder builder = Response.ok();
+ Locale locale = null;
+ if (Locale.CANADA_FRENCH.getCountry().equals(lang))
+ locale = Locale.CANADA_FRENCH;
+ if (locale != null)
+ builder = builder.language(locale);
+ return builder.build();
+ }
+
+ @POST
+ @Path("lastmodified")
+ public Response lastModified(String date) {
+ ResponseBuilder builder = Response.ok();
+ if (date != null && date.length() != 0) {
+ long millis = Long.parseLong(date);
+ Date dateFromMillis = new Date(millis);
+ builder = builder.lastModified(dateFromMillis);
+ }
+ Response response = builder.build();
+ return response;
+ }
+
+ @POST
+ @Path("length")
+ public Response getLength(String entity) {
+ Response response = null;
+ if (entity == null || entity.length() == 0)
+ response = Response.ok().build();
+ else
+ response = Response.ok(entity)
+ .header(HttpHeaders.CONTENT_LENGTH, entity.length()).build();
+ return response;
+ }
+
+ @POST
+ @Path("link")
+ public Response getLink(String rel) {
+ ResponseBuilder builder = Response.ok();
+ if (rel != null && rel.length() != 0)
+ builder.links(createLink("path", rel));
+ return builder.build();
+ }
+
+ @POST
+ @Path("linkbuilder")
+ public Response getLinkBuilder(String rel) {
+ Link link1 = createLink("path1", rel);
+ Response response = Response.ok().links(link1).build();
+ Link builderLink = response.getLinkBuilder(rel).build();
+ response = Response.ok().links(builderLink).build();
+ return response;
+ }
+
+ @GET
+ @Path("links")
+ public Response getLinks() {
+ Link link1 = createLink("path1", "rel1");
+ Link link2 = createLink("path2", "rel2");
+ Response response = Response.ok().links(link1, link2).build();
+ return response;
+ }
+
+ @POST
+ @Path("location")
+ public Response getLocation(String path) {
+ URI location = createUri(path);
+ Response response = Response.ok().location(location).build();
+ return response;
+ }
+
+ @POST
+ @Path("mediatype")
+ public Response getMediaType(String mediaType) {
+ MediaType media = MediaType.WILDCARD_TYPE;
+ if (mediaType.equals(MediaType.APPLICATION_ATOM_XML))
+ media = MediaType.APPLICATION_ATOM_XML_TYPE;
+ Response response = Response.ok().type(media).build();
+ return response;
+ }
+
+ @POST
+ @Path("statusinfo")
+ public Response getStatusInfo(String status) {
+ Status stat = Status.valueOf(status);
+ Response response = Response.status(stat).build();
+ return response;
+ }
+
+ // For the methods that checks for the header delegate this is the way
+ // to add header delegate by switching runtimedelegate
+ // As long as the runtime delegate is one only for whole classloader
+ @Path("setstringbeanruntime")
+ @GET
+ public Response setStringBeanRuntime() {
+ RuntimeDelegate original = RuntimeDelegate.getInstance();
+ if (!(original instanceof StringBeanRuntimeDelegate)) {
+ StringBeanRuntimeDelegate sbrd = new StringBeanRuntimeDelegate(original);
+ RuntimeDelegate.setInstance(sbrd);
+ }
+ return Response.ok().build();
+ }
+
+ // We need to switch back to the original runtime delegate since
+ // we cannot be sure what happen when the war with our runtimedelegate gets
+ // undeployed
+ @Path("setoriginalruntime")
+ @GET
+ public Response setOriginalRuntime() {
+ Response response = null;
+ RuntimeDelegate stringBeanDelegate = RuntimeDelegate.getInstance();
+ if (stringBeanDelegate instanceof StringBeanRuntimeDelegate) {
+ RuntimeDelegate original = ((StringBeanRuntimeDelegate) stringBeanDelegate)
+ .getOriginal();
+ RuntimeDelegate.setInstance(original);
+ response = Response.ok().build();
+ } else
+ response = Response.status(Status.NO_CONTENT).build();
+ return response;
+ }
+
+ @Path("created")
+ @GET
+ public Response setLocationHeader() {
+ try {
+ Response response = Response.created(new URI("created")).status(200).build();
+ return response;
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ protected static Link createLink(String path, String rel) {
+ return Link.fromUri(createUri(path)).rel(rel).build();
+ }
+
+ protected static URI createUri(String path) {
+ URI uri;
+ try {
+ uri = new URI("http://localhost.tck:888/url404/" + path);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ return uri;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java
new file mode 100644
index 0000000..16b355c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.provider.PrintingErrorHandler;
+import jakarta.ws.rs.tck.common.provider.StringBeanHeaderDelegate;
+
+import jakarta.ws.rs.core.Application;
+
+/**
+ *
+ * @author diannejiao
+ */
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(ResponseTest.class);
+ resources.add(StringBeanHeaderDelegate.class);
+ resources.add(PrintingErrorHandler.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java
new file mode 100644
index 0000000..5e495b1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+/**
+ * This is the dummy class to get annotations from it
+ */
+public abstract class AnnotatedClass {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java
new file mode 100644
index 0000000..6c0db80
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateClientReaderWriter
+ implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+ private StringBuilder atom;
+
+ public DateClientReaderWriter(StringBuilder atom) {
+ super();
+ this.atom = atom;
+ }
+
+ @Override
+ public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4) {
+ return String.valueOf(Long.MAX_VALUE).length()
+ + DateContainerReaderWriter.SPLITTER.length();
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return arg0 == Date.class;
+ }
+
+ @Override
+ public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+ throws IOException, WebApplicationException {
+ stream.write(dateToString(date).getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return isWriteable(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+ throws IOException, WebApplicationException {
+ InputStreamReader reader = new InputStreamReader(arg5);
+ BufferedReader br = new BufferedReader(reader);
+ String data = br.readLine();
+ String[] split = data == null ? new String[] { "0" }
+ : data.split(DateContainerReaderWriter.SPLITTER);
+ long date = Long.parseLong(split[0]);
+ atom.append(split[1]);
+ return new Date(date);
+ }
+
+ public static final String dateToString(Date date) {
+ return String.valueOf(date.getTime());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java
new file mode 100644
index 0000000..02f6865
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateContainerReaderWriter
+ implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+
+ public static final int ANNOTATION_NONE = 0;
+
+ public static final int ANNOTATION_CONSUMES = 1 << 2;
+
+ public static final int ANNOTATION_PROVIDER = 1 << 3;
+
+ public static final int ANNOTATION_UNKNOWN = 1 << 7;
+
+ public static final String SPLITTER = " ANNOTATION_VALUE ";
+
+ @Override
+ public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4) {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ return String.valueOf(Long.MAX_VALUE).length() + SPLITTER.length()
+ + annotations[0].annotationType().getName().length()
+ + annotations[1].annotationType().getName().length();
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return arg0 == Date.class;
+ }
+
+ @Override
+ public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+ MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+ throws IOException, WebApplicationException {
+ String annotation = parseAnnotations(arg3);
+ stream.write(dateToString(date).getBytes());
+ stream.write(SPLITTER.getBytes());
+ stream.write(annotation.getBytes());
+ }
+
+ @Override
+ public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3) {
+ return isWriteable(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+ throws IOException, WebApplicationException {
+ InputStreamReader reader = new InputStreamReader(arg5);
+ BufferedReader br = new BufferedReader(reader);
+ long date = Long.parseLong(br.readLine());
+ return new Date(date);
+ }
+
+ protected String parseAnnotations(Annotation[] annotations) {
+ StringBuilder value = new StringBuilder();
+ if (annotations != null)
+ for (Annotation annotation : annotations)
+ value.append(annotation.annotationType().getName()).append(", ");
+ return value.toString();
+ }
+
+ public static final String dateToString(Date date) {
+ return String.valueOf(date.getTime());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..3e28970
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.util.Calendar;
+import java.util.Date;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.Response;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 1L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_responsebuilder_web/resource");
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_responsebuilder_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class, AnnotatedClass.class, DateContainerReaderWriter.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: entityObjectTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:879;
+ *
+ * @test_Strategy: Set the message entity content encoding.
+ */
+ @Test
+ public void entityObjectTest() throws Fault {
+ Date date = Calendar.getInstance().getTime();
+ String entity = DateContainerReaderWriter.dateToString(date);
+ StringBuilder sb = new StringBuilder();
+ DateClientReaderWriter rw = new DateClientReaderWriter(sb);
+ addProvider(rw);
+
+ setProperty(Property.REQUEST, buildRequest(Request.POST, "entity"));
+ setProperty(Property.CONTENT, entity);
+ invoke();
+
+ Response response = getResponse();
+ Date responseDate = response.readEntity(Date.class);
+ assertTrue(date.equals(responseDate), "entity date"+ date+
+ "differs from acquired"+ responseDate);
+
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ for (Annotation annotation : annotations) {
+ String name = annotation.annotationType().getName();
+ assertTrue(sb.toString().contains(name), sb+ "does not contain"+ name+
+ ", annotations not passed to MessageBodyWriter?");
+ }
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ protected <T> GenericType<T> generic(Class<T> clazz) {
+ return new GenericType<T>(clazz);
+ }
+
+ protected String readLine(Reader reader) throws Fault {
+ String line = null;
+ BufferedReader buffered = new BufferedReader(reader);
+ try {
+ line = buffered.readLine();
+ } catch (IOException e) {
+ try {
+ buffered.close();
+ } catch (IOException ie) {
+ }
+ throw new Fault(e);
+ }
+ return line;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java
new file mode 100644
index 0000000..8bb17fd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.lang.annotation.Annotation;
+import java.util.Date;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+
+@Path("resource")
+public class Resource {
+ @POST
+ @Path("entity")
+ public Response entity(Date date) {
+ Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+ Response response = Response.ok().entity(date, annotations).build();
+ return response;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java
new file mode 100644
index 0000000..527a686
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(DateContainerReaderWriter.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java
new file mode 100644
index 0000000..32aba1c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+import java.util.Properties;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import jakarta.ws.rs.core.Response;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+public abstract class JAXRSClient extends JAXRSCommonClient {
+ private static final long serialVersionUID = 1L;
+
+ protected static final String URL = "Context";
+
+ protected HttpResponse response;
+
+ protected String wwwAuthenticate;
+
+ protected String user;
+
+ protected String password;
+
+ protected String authuser;
+
+ protected String authpassword;
+
+ public void setup() {
+ user = System.getProperty("user");
+ password = System.getProperty("password");
+ authuser = System.getProperty("authuser");
+ authpassword = System.getProperty("authpassword");
+ assertTrue(!isNullOrEmpty(user), "user was not set");
+ assertTrue(!isNullOrEmpty(password),
+ "password was not set");
+ assertTrue(!isNullOrEmpty(authuser),
+ "authuser was not set");
+ assertTrue(!isNullOrEmpty(authpassword),
+ "authpassword was not set");
+ super.setup();
+ }
+
+ public void noAuthorizationTest() throws Fault {
+ setProperty(STATUS_CODE, getStatusCode(Response.Status.UNAUTHORIZED));
+ invokeRequest();
+ assertTrue(wwwAuthenticate != null,
+ "Expected authentication request missing!");
+ }
+
+ protected void invokeRequest() throws Fault {
+ setProperty(REQUEST, buildRequest("GET", URL));
+ invoke();
+ response = _testCase.getResponse();
+ Header header = response.getResponseHeader("WWW-Authenticate");
+ wwwAuthenticate = header == null ? null : header.getValue();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java
new file mode 100644
index 0000000..f7ef354
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(TestServlet.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java
new file mode 100644
index 0000000..c3b05ba
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.SecurityContext;
+
+@Path("/Servlet")
+public class TestServlet {
+ public static enum Security {
+ SECURED, UNSECURED
+ };
+
+ public static enum Scheme {
+ BASIC, DIGEST, NOSCHEME
+ }
+
+ public static enum Role {
+ DIRECTOR, OTHERROLE, NOROLE
+ }
+
+ private static void addSecuredInfo(SecurityContext context,
+ StringBuilder sb) {
+ Security security;
+ security = context.isSecure() ? Security.SECURED : Security.UNSECURED;
+ sb.append(security).append("|");
+ }
+
+ private static void addSchemaInfo(SecurityContext context, StringBuilder sb) {
+ Scheme scheme;
+ String authScheme = context.getAuthenticationScheme();
+ if (authScheme == null)
+ scheme = Scheme.NOSCHEME;
+ else if (authScheme.equalsIgnoreCase(Scheme.BASIC.name()))
+ scheme = Scheme.BASIC;
+ else
+ scheme = Scheme.DIGEST;
+ sb.append(scheme).append("|");
+ }
+
+ private static void addRoleInfo(SecurityContext context, StringBuilder sb) {
+ java.security.Principal userPrincipal = context.getUserPrincipal();
+ String principal = userPrincipal == null ? "" : userPrincipal.getName();
+ sb.append(principal).append("|");
+ }
+
+ private static void addPrincipalInfo(SecurityContext context,
+ StringBuilder sb) {
+ Role role;
+ if (context.isUserInRole(Role.DIRECTOR.name()))
+ role = Role.DIRECTOR;
+ else if (context.isUserInRole(Role.OTHERROLE.name()))
+ role = Role.OTHERROLE;
+ else
+ role = Role.NOROLE;
+ sb.append(role).append("|");
+ }
+
+ @GET
+ @Path("/Context")
+ public Response test(@Context SecurityContext context) {
+ StringBuilder sb = new StringBuilder();
+ addSecuredInfo(context, sb);
+ addPrincipalInfo(context, sb);
+ addRoleInfo(context, sb);
+ addSchemaInfo(context, sb);
+ return Response.ok(sb.toString()).build();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java
new file mode 100644
index 0000000..b692372
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext.basic;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet;
+import jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet.Scheme;
+
+import jakarta.ws.rs.core.Response;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ * user;
+ * password;
+ * authuser;
+ * authpassword;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSBasicClientIT
+ extends jakarta.ws.rs.tck.ee.rs.core.securitycontext.JAXRSClient {
+
+ private static final long serialVersionUID = 340277879725875946L;
+
+ public JAXRSBasicClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_securitycontext_basic_web/Servlet");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException {
+
+ InputStream inStream = JAXRSBasicClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_securitycontext_basic_web.war");
+ archive.addClasses(jakarta.ws.rs.tck.ee.rs.core.securitycontext.TSAppConfig.class, jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet.class);
+ archive.setWebXML(new StringAsset(webXml));
+ archive.addAsResource("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml");
+ archive.addAsResource("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml");
+ return archive;
+
+ }
+
+ /* Run test */
+
+ /*
+ * @testName: noAuthorizationTest
+ *
+ * @assertion_ids:
+ *
+ * @test_Strategy: Send no authorization, make sure of 401 response
+ */
+ @Test
+ public void noAuthorizationTest() throws Fault {
+ super.noAuthorizationTest();
+ }
+
+ /*
+ * @testName: basicAuthorizationAdminTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:169; JAXRS:JAVADOC:170; JAXRS:JAVADOC:171;
+ * JAXRS:JAVADOC:172; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Send basic authorization, check security context
+ */
+ //@Test
+ public void basicAuthorizationAdminTest() throws Fault {
+ setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+ setProperty(Property.BASIC_AUTH_USER, user);
+ setProperty(Property.BASIC_AUTH_PASSWD, password);
+
+ setProperty(Property.SEARCH_STRING, TestServlet.Security.UNSECURED.name());
+ setProperty(Property.SEARCH_STRING, TestServlet.Role.DIRECTOR.name());
+ setProperty(Property.SEARCH_STRING, user);
+ setProperty(Property.SEARCH_STRING, TestServlet.Scheme.BASIC.name());
+ invokeRequest();
+ }
+
+ /*
+ * @testName: basicAuthorizationIncorrectUserTest
+ *
+ * @assertion_ids:
+ *
+ * @test_Strategy: Send basic authorization, check security context
+ */
+ @Test
+ public void basicAuthorizationIncorrectUserTest() throws Fault {
+ setProperty(Property.STATUS_CODE,
+ getStatusCode(Response.Status.UNAUTHORIZED));
+ setProperty(Property.BASIC_AUTH_USER, Scheme.NOSCHEME.name());
+ setProperty(Property.BASIC_AUTH_PASSWD, password);
+ invokeRequest();
+ }
+
+ /*
+ * @testName: basicAuthorizationIncorrectPasswordTest
+ *
+ * @assertion_ids:
+ *
+ * @test_Strategy: Send basic authorization, check security context
+ */
+ @Test
+ public void basicAuthorizationIncorrectPasswordTest() throws Fault {
+ setProperty(Property.STATUS_CODE,
+ getStatusCode(Response.Status.UNAUTHORIZED));
+ setProperty(Property.BASIC_AUTH_USER, authuser);
+ setProperty(Property.BASIC_AUTH_PASSWD, password);
+ invokeRequest();
+ }
+
+ /*
+ * @testName: basicAuthorizationStandardUserTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:169; JAXRS:JAVADOC:170; JAXRS:JAVADOC:171;
+ * JAXRS:JAVADOC:172; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Send basic authorization with made up Realm, check security
+ * context
+ */
+ //@Test
+ public void basicAuthorizationStandardUserTest() throws Fault {
+ setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+ setProperty(Property.BASIC_AUTH_USER, authuser);
+ setProperty(Property.BASIC_AUTH_PASSWD, authpassword);
+
+ setProperty(Property.SEARCH_STRING, TestServlet.Security.UNSECURED.name());
+ setProperty(Property.SEARCH_STRING, TestServlet.Role.OTHERROLE.name());
+ setProperty(Property.SEARCH_STRING, authuser);
+ setProperty(Property.SEARCH_STRING, TestServlet.Scheme.BASIC.name());
+ invokeRequest();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml
new file mode 100644
index 0000000..3b846be
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml
@@ -0,0 +1,58 @@
+<!--
+
+ Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project name="jaxrs_ee_core_securitycontext" basedir="." default="package" >
+ <property name="resource.classes"
+ value="com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet.class,
+ com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Security.class,
+ com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Scheme.class,
+ com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Role.class,
+ com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Principal.class"/>
+ <property name="appconfig.class"
+ value="com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TSAppConfig.class" />
+
+ <include file="../../../../common/common.xml"/>
+
+ <target name="package" depends="build.TSAppConfig">
+ <ant antfile="${ts.home}/src/com/sun/ts/tests/jaxrs/common/common.xml" target="package"/>
+ <antcall target="copy.sun-web.xml"/>
+ <antcall target="copy.sun-application.xml"/>
+ </target>
+
+ <target name="copy.sun-web.xml">
+ <copy failonerror="true"
+ file="${app.name}_web.war.sun-web.xml"
+ tofile="${ts.home}/dist/${pkg.dir}/${app.name}_web.war.sun-web.xml"/>
+ </target>
+
+ <target name="copy.sun-application.xml">
+ <copy failonerror="true"
+ file="${app.name}_web.ear.sun-application.xml"
+ tofile="${ts.home}/dist/${pkg.dir}/${app.name}_web.ear.sun-application.xml" />
+ </target>
+
+ <target name="check.TSAppConfig.built">
+ <available file="${ts.home}/classes/${appconfig.class}" property="ts.app.config.present"/>
+ </target>
+
+ <target name="build.TSAppConfig" depends="check.TSAppConfig.built" unless="ts.app.config.present">
+ <echo>BUILDING</echo>
+ <ant antfile="../build.xml" useNativeBasedir="true" target="compile"/>
+ </target>
+
+</project>
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java
new file mode 100644
index 0000000..9d4a4e8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.uriinfo;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = -5479757659703717839L;
+
+ protected static final String ROOT = "jaxrs_ee_core_uriinfo_web";
+
+ protected static final String RESOURCE = "resource";
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/" + ROOT + "/" + RESOURCE);
+ }
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_uriinfo_web.war");
+ archive.addClasses(TSAppConfig.class, URIInfoTest.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: queryTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:249; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that
+ * UriInfo.getQueryParameters() works.
+ */
+ @Test
+ public void queryTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "query?stringtest=cts&inttest=-2147483648?"));
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ "stringtest=cts|inttest=-2147483648?");
+ invoke();
+ }
+
+ /*
+ * @testName: queryTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:250; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that
+ * UriInfo.getQueryParameters(true) works.
+ */
+ @Test
+ public void queryTest1() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET,
+ "query1?stringtest=cts%20&inttest=-2147483648?%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ "stringtest=cts |inttest=-2147483648? 10");
+ invoke();
+ }
+
+ /*
+ * @testName: queryTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:250; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that
+ * UriInfo.getQueryParameters(false) works.
+ */
+ @Test
+ public void queryTest2() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "query2?stringtest=cts%20&inttest=-2147483648%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ "stringtest=cts%20|inttest=-2147483648%2010");
+ invoke();
+ }
+
+ /*
+ * @testName: aPathTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:236; JAXRS:JAVADOC:237;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getAbsolutePath() and
+ * getAbsolutePathBuilder() work.
+ */
+ @Test
+ public void aPathTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "apath"));
+ setProperty(Property.SEARCH_STRING,
+ "http://" + _hostname + ":" + _port + getContextRoot() + "/apath");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+ invoke();
+ }
+
+ /*
+ * @testName: baseUriTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:238; JAXRS:JAVADOC:239;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getBaseUri() and
+ * getBaseUriBuilder() work.
+ */
+ @Test
+ public void baseUriTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "baseuri"));
+ setProperty(Property.SEARCH_STRING,
+ "http://" + _hostname + ":" + _port + "/" + ROOT);
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+ invoke();
+ }
+
+ /*
+ * @testName: pathTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:243;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPath() work.
+ */
+ @Test
+ public void pathTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "path"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/path");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:244;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPath(true) work.
+ */
+ @Test
+ public void pathTest1() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "path1%20/%2010"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/path1 / 10");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:244;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPath(false) work.
+ */
+ @Test
+ public void pathTest2() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "path2%20/%2010"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/path2%20/%2010");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathSegTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:247;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathSegments() work.
+ */
+ @Test
+ public void pathSegTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathseg"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+ setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathSegTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:248;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathSegments(true) work.
+ */
+ @Test
+ public void pathSegTest1() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathseg1%20/%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+ setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg1 / 10/");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathSegTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:248;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathSegments(false) work.
+ */
+ @Test
+ public void pathSegTest2() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathseg2%20/%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+ setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg2%20/%2010/");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:245; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathParameters() work.
+ */
+ @Test
+ public void pathParamTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathparam/a/b"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, "a=a|b=b");
+ invoke();
+ }
+
+ /*
+ * @testName: pathParamTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:246; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathParameters(true) work.
+ */
+ @Test
+ public void pathParamTest1() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathparam1/%20/%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, "a= |b= 10");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathParamTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:246; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Client send a request to a resource, which handles the
+ * request using UriInfo. Verify that UriInfo.getPathParameters(false) work.
+ */
+ @Test
+ public void pathParamTest2() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "pathparam2/%20/%2010"));
+ setProperty(Property.UNORDERED_SEARCH_STRING, "a=%20|b=%2010");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+ invoke();
+ }
+
+ /*
+ * @testName: requestURITest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:251; JAXRS:JAVADOC:252;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that getRequestUri() and
+ * getRequestUriBuilder() work.
+ */
+ @Test
+ public void requestURITest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "request?stringtest=cts&inttest=-2147483648"));
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ "http://" + _hostname + ":" + _port + getContextRoot()
+ + "/request?stringtest=cts&inttest=-2147483648");
+ setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+ invoke();
+ }
+
+ /*
+ * @testName: getMatchedResourcesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:240; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that getMatchedResources()
+ * work.
+ */
+ @Test
+ public void getMatchedResourcesTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "resource"));
+ setProperty(Property.SEARCH_STRING, URIInfoTest.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getMatchedURIsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:241;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that getMatchedURIs() work.
+ */
+ @Test
+ public void getMatchedURIsTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "uri"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/uri");
+ setProperty(Property.SEARCH_STRING, RESOURCE);
+ setProperty(Property.SEARCH_STRING, "number=2");
+ invoke();
+ }
+
+ /*
+ * @testName: getMatchedURIsTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:242;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that getMatchedURIs(true)
+ * work.
+ */
+ @Test
+ public void getMatchedURIsTest1() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "uri1"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/uri1");
+ setProperty(Property.SEARCH_STRING, RESOURCE);
+ setProperty(Property.SEARCH_STRING, "number=2");
+ invoke();
+ }
+
+ /*
+ * @testName: getMatchedURIsTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:242;
+ *
+ * @test_Strategy: Client send a request with query parameters to a resource,
+ * which handles the request using UriInfo. Verify that getMatchedURIs(false)
+ * work.
+ */
+ @Test
+ public void getMatchedURIsTest2() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, "uri2"));
+ setProperty(Property.SEARCH_STRING, RESOURCE + "/uri2");
+ setProperty(Property.SEARCH_STRING, RESOURCE);
+ setProperty(Property.SEARCH_STRING, "number=2");
+ invoke();
+ }
+
+ /*
+ * @testName: getNormalizedUriTest
+ *
+ * @assertion_ids: JAXRS:SPEC:61;
+ *
+ * @test_Strategy: The normalized request URI MUST be reflected in the URIs
+ * obtained from an injected UriInfo
+ */
+ @Test
+ public void getNormalizedUriTest() throws Fault {
+ setProperty(Property.REQUEST, buildRequest(GET, URIInfoTest.DECODED));
+ invoke();
+ assertBodyGreaterThanOne();
+
+ setProperty(Property.REQUEST, buildRequest(GET, URIInfoTest.ENCODED));
+ invoke();
+ assertBodyGreaterThanOne();
+ }
+
+ private void assertBodyGreaterThanOne() throws Fault {
+ int i = Integer.parseInt(getResponseBody());
+ assertTrue(i > 1, "Got unexpected response body"+ getResponseBody());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java
new file mode 100644
index 0000000..346b2e7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.uriinfo;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(URIInfoTest.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java
new file mode 100644
index 0000000..e744479
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.uriinfo;
+
+import java.net.URI;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.PathSegment;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.UriInfo;
+
+@Path(value = "resource")
+public class URIInfoTest {
+
+ @GET
+ @Path("/query")
+ public String queryTest(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getQueryParameters().keySet()) {
+ buf.append(param + "=" + info.getQueryParameters().getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/query1")
+ public String queryTest1(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getQueryParameters(true).keySet()) {
+ buf.append(param + "=" + info.getQueryParameters(true).getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/query2")
+ public String queryTest2(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getQueryParameters(false).keySet()) {
+ buf.append(param + "=" + info.getQueryParameters(false).getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/apath")
+ public String apathTest(@Context UriInfo info) {
+ StringBuilder sb = new StringBuilder();
+ URI uri = info.getAbsolutePath();
+ UriBuilder urib = info.getAbsolutePathBuilder();
+
+ sb.append(uri.toString());
+ if (!uri.toString().equals(urib.build().toString())) {
+ sb.append("Got unexpected = " + urib.build().toString());
+ sb.append("FAILED");
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/path")
+ public String pathTest(@Context UriInfo info) {
+ return info.getPath();
+ }
+
+ @GET
+ @Path("/path1%20/%2010")
+ public String pathTest1(@Context UriInfo info) {
+ return info.getPath(true);
+ }
+
+ @GET
+ @Path("/path2%20/%2010")
+ public String pathTest2(@Context UriInfo info) {
+ return info.getPath(false);
+ }
+
+ @GET
+ @Path("/baseuri")
+ public String baseUriTest(@Context UriInfo info) {
+ StringBuilder sb = new StringBuilder();
+ URI uri = info.getBaseUri();
+ UriBuilder urib = info.getBaseUriBuilder();
+
+ sb.append(uri.toString());
+ if (!uri.toString().equals(urib.build().toString())) {
+ sb.append("Got unexpected = " + urib.build().toString());
+ sb.append("FAILED");
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/pathparam/{a}/{b}")
+ public String pathparamTest(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getPathParameters().keySet()) {
+ buf.append(param + "=" + info.getPathParameters().getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/pathparam1/{a}/{b}")
+ public String pathparamTest1(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getPathParameters(true).keySet()) {
+ buf.append(param + "=" + info.getPathParameters(true).getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/pathparam2/{a}/{b}")
+ public String pathparamTest2(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String param : info.getPathParameters(false).keySet()) {
+ buf.append(param + "=" + info.getPathParameters(false).getFirst(param));
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/pathseg")
+ public String pathsegTest(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (PathSegment param : info.getPathSegments()) {
+ buf.append(param.getPath() + "/");
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/pathseg1%20/%2010")
+ public String pathsegTest1(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (PathSegment param : info.getPathSegments(true)) {
+ buf.append(param.getPath() + "/");
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/pathseg2%20/%2010")
+ public String pathsegTest2(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (PathSegment param : info.getPathSegments(false)) {
+ buf.append(param.getPath() + "/");
+ }
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/request")
+ public String requestTest(@Context UriInfo info) {
+ StringBuilder sb = new StringBuilder();
+ URI uri = info.getRequestUri();
+ UriBuilder urib = info.getRequestUriBuilder();
+
+ sb.append(uri.toString());
+ if (!uri.toString().equals(urib.build().toString())) {
+ sb.append("Got unexpected = " + urib.build().toString());
+ sb.append("FAILED");
+ }
+ return sb.toString();
+ }
+
+ @GET
+ @Path("/resource")
+ public String resourcesTest(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (Object resource : info.getMatchedResources()) {
+ buf.append(resource.toString() + "=");
+ }
+ buf.append("number=" + info.getMatchedResources().size());
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/uri")
+ public String urisTest(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (Object resource : info.getMatchedURIs()) {
+ buf.append(resource.toString() + "=");
+ }
+ buf.append("number=" + info.getMatchedURIs().size());
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/uri1")
+ public String urisTest1(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String resource : info.getMatchedURIs(true)) {
+ buf.append(resource + "=");
+ }
+ buf.append("number=" + info.getMatchedURIs(true).size());
+ return buf.toString();
+ }
+
+ @GET
+ @Path("/uri2")
+ public String urisTest2(@Context UriInfo info) {
+ StringBuilder buf = new StringBuilder();
+ for (String resource : info.getMatchedURIs(false)) {
+ buf.append(resource + "=");
+ }
+ buf.append("number=" + info.getMatchedURIs(false).size());
+ return buf.toString();
+ }
+
+ public static final String ENCODED = "%50%51%52%30%39%70%71%72/%7e%2d%2E%5f";
+
+ public static final String DECODED = "PQR09pqr/~-._";
+
+ @GET
+ @Path("{id1}/{id2}")
+ public String normalizedUri(@Context UriInfo info) {
+ int ret = 1;
+ if (!info.getAbsolutePath().toString().contains(ENCODED))
+ ret += 10;
+ if (!info.getPath().toString().contains(ENCODED))
+ ret += 100;
+ if (!info.getRequestUri().toString().contains(ENCODED))
+ ret += 1000;
+ return String.valueOf(ret);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java
new file mode 100644
index 0000000..9a3532e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.contextresolver;
+
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class EnumContextResolver implements ContextResolver<EnumProvider> {
+
+ @Override
+ public EnumProvider getContext(Class<?> type) {
+ return type == EnumProvider.class ? EnumProvider.JAXRS : null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java
new file mode 100644
index 0000000..e0b69e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.contextresolver;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+public enum EnumProvider {
+ TCK, CTS, JAXRS;
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java
new file mode 100644
index 0000000..5ade242
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.contextresolver;
+
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+@Produces(MediaType.TEXT_PLAIN)
+public class TextPlainEnumContextResolver
+ implements ContextResolver<EnumProvider> {
+ @Override
+ public EnumProvider getContext(Class<?> type) {
+ return type == EnumProvider.class ? EnumProvider.CTS : null;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java
new file mode 100644
index 0000000..6065478
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class AnyExceptionExceptionMapper implements ExceptionMapper<Exception> {
+
+ @Override
+ public Response toResponse(Exception arg0) {
+ Status status = Status.NO_CONTENT;
+ if (arg0 instanceof WebApplicationException)
+ return ((WebApplicationException) arg0).getResponse();
+ else if (arg0 instanceof RuntimeException)
+ throw new RuntimeException("CTS Test RuntimeException", arg0);
+ else if (arg0 instanceof IOException)
+ status = Status.SERVICE_UNAVAILABLE;
+ else if (arg0 != null)
+ status = Status.NOT_ACCEPTABLE;
+ return Response.status(status).build();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java
new file mode 100644
index 0000000..3d37bbe
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class IOExceptionExceptionMapper
+ implements ExceptionMapper<IOException> {
+
+ @Override
+ public Response toResponse(IOException exception) {
+ return Response.status(Status.ACCEPTED).build();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java
new file mode 100644
index 0000000..f0a4b6f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ *
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class WriterClient<CONTEXTOPERATION extends Enum<?>>
+ extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 8110273180216593061L;
+
+ /**
+ * Set the header OPERATION to a proper value Also set the entity, it is good
+ * as it is here for most of the tests. For the rest, the entity needs to be
+ * replaced.
+ */
+ protected void setOperationAndEntity(CONTEXTOPERATION op) {
+ addHeader(TemplateInterceptorBody.OPERATION, op.name());
+ setRequestContentEntity(TemplateInterceptorBody.ENTITY);
+ }
+
+ /**
+ * Invoke and convert IOException to Fault
+ */
+ protected void invoke() throws Fault {
+ try {
+ setProperty(Property.REQUEST, buildRequest(Request.POST, ""));
+ super.invoke();
+ } catch (Exception cause) {
+ if (cause instanceof IOException)
+ throw new Fault(cause.getMessage());
+ else
+ throw new Fault(cause);
+ }
+ }
+
+ /**
+ * Register providers to client configuration
+ *
+ * @param response
+ * ClientRequestFilter#abortWith response
+ */
+ protected abstract void addProviders();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..fdb6680
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorTwo;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+ private static final long serialVersionUID = -5479399808367387477L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_clientwriter_interceptorcontext_web/resource");
+ addProviders();
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_clientwriter_interceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getAnnotationsTest() throws Fault {
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+ MediaType.WILDCARD_TYPE, annotations);
+ setOperationAndEntity(ContextOperation.GETANNOTATIONS);
+ setRequestContentEntity(entity);
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getGenericTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETGENERICTYPE);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get media type of HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getMediaTypeTest() throws Fault {
+ Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+ MediaType.APPLICATION_JSON_TYPE);
+ setOperationAndEntity(ContextOperation.GETMEDIATYPE);
+ setRequestContentEntity(entity);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns null if there is no property by that name.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyIsNullTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns an enumeration containing the property names
+ * available within the context of the current request/response exchange
+ * context.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyNamesTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTYNAMES);
+ for (int i = 0; i != 5; i++)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.PROPERTY + i);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesIsReadOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection containing the
+ * property names available within the context of the current request/response
+ * exchange context.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyNamesIsReadOnlyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTYNAMESISREADONLY);
+ setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get Java type supported by corresponding message body
+ * provider.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETTYPE);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: removePropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Removes a property with the given name from the current
+ * request/response exchange context. After removal, subsequent calls to
+ * getProperty(java.lang.String) to retrieve the property value will return
+ * null.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void removePropertyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.REMOVEPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update annotations on the formal declaration of the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setAnnotationsTest() throws Fault {
+ Annotation[] annotations = WriterInterceptorOne.class.getAnnotations();
+ setOperationAndEntity(ContextOperation.SETANNOTATIONS);
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsNullThrowsNPETest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Throws NullPointerException - in case the input parameter
+ * is null.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setAnnotationsNullThrowsNPETest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETANNOTATIONSNULL);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+ invoke();
+ }
+
+ /*
+ * @testName: setGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update type of the object to be produced or written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setGenericTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETGENERICTYPE);
+ setProperty(Property.SEARCH_STRING, "[B");
+ invoke();
+ }
+
+ /*
+ * @testName: setMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update media type of HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setMediaTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETMEDIATYPE);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Binds an object to a given property name in the current
+ * request/response exchange context. If the name specified is already used
+ * for a property, this method will replace the value of the property with the
+ * new value.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setPropertyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: If a null value is passed, the effect is the same as
+ * calling the removeProperty(String) method.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setPropertyNullTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETPROPERTYNULL);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update Java type before calling message body provider.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setTypeTest() throws Fault {
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ TemplateInterceptorBody.ENTITY.getBytes());
+ Reader reader = new InputStreamReader(bais);
+ setOperationAndEntity(ContextOperation.SETTYPE);
+ setRequestContentEntity(reader);
+ addProvider(InputStreamReaderProvider.class);
+ invoke();
+ InputStreamReader isr = getResponseBody(InputStreamReader.class);
+ try {
+ String entity = JaxrsUtil.readFromReader(isr);
+ assertTrue(entity.contains(InputStreamReader.class.getName()),
+ "Expected"+ InputStreamReader.class.getName()+ "not found");
+ logMsg("#setType set correct type", entity);
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+
+ // /////////////////////////////////////////////////////////////////////
+ @Override
+ protected void addProviders() {
+ addProvider(WriterInterceptorTwo.class);
+ addProvider(new WriterInterceptorOne());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java
new file mode 100644
index 0000000..45c0545
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+ @POST
+ public String post(String entity) {
+ return entity;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..070c688
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..4cdb0e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.OnWriteExceptionThrowingStringBean;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ProceedException;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorTwo;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+ private static final long serialVersionUID = 2500912584762173255L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_clientwriter_writerinterceptorcontext_web/resource");
+ addProviders();
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_clientwriter_writerinterceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:933; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get object to be written as HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getEntityTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETENTITY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY);
+ invoke();
+ }
+
+ /*
+ * @testName: getHeadersOperationOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersOperationOnlyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETHEADERS);
+ setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+ TemplateInterceptorBody.OPERATION);
+ invoke();
+ }
+
+ /*
+ * @testName: getHeadersTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersTest() throws Fault {
+ Property p = Property.UNORDERED_SEARCH_STRING;
+ setOperationAndEntity(ContextOperation.GETHEADERS);
+ setProperty(p, TemplateInterceptorBody.OPERATION);
+ setTextCaser(TextCaser.LOWER);
+ for (int i = 0; i != 5; i++) {
+ addHeader(TemplateInterceptorBody.PROPERTY + i, "any");
+ setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+ }
+ invoke();
+ }
+
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersIsMutableTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETHEADERSISMUTABLE);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+ invoke();
+ }
+
+ /*
+ * @testName: getOutputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:935; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get the output stream for the object to be written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getOutputStreamTest() throws Fault {
+ Property p = Property.UNORDERED_SEARCH_STRING;
+ setOperationAndEntity(ContextOperation.GETOUTPUTSTREAM);
+ setProperty(p, TemplateInterceptorBody.ENTITY);
+ setProperty(p, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsIOExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:937; JAXRS:JAVADOC:930;
+ * JAXRS:JAVADOC:931;
+ *
+ * @test_Strategy: Proceed to the next interceptor in the chain.
+ * Throws:IOException - if an IO exception arises.
+ *
+ * proceed is actually called in every clientwriter.writerinterceptorcontext
+ * test
+ *
+ * WriterInterceptor.aroundWriteTo
+ *
+ * WriterInterceptor.aroundWriteTo throws IOException
+ */
+ @Test
+ public void proceedThrowsIOExceptionTest() throws Fault {
+ setOperationAndEntity(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:1009; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Proceed to the next interceptor in the chain.
+ * Throws:WebApplicationException - thrown by the wrapped {@code
+ * MessageBodyWriter.writeTo} method.
+ *
+ * proceed is actually called in every clientwriter.writerinterceptorcontext
+ * test
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+ addProvider(StringBeanEntityProvider.class);
+ addHeader(TemplateInterceptorBody.OPERATION,
+ ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION.name());
+ setRequestContentEntity(
+ new OnWriteExceptionThrowingStringBean(TemplateInterceptorBody.ENTITY));
+ try {
+ invoke();
+ } catch (Exception e) {
+ ProceedException p = assertCause(e, ProceedException.class,
+ "Proceed did not throw exception");
+ assertContains(p.getMessage(), TemplateInterceptorBody.WAE,
+ "Unexpected message received", p.getMessage());
+ logMsg(p.getMessage());
+ }
+ }
+
+ /*
+ * @testName: setEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:938; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update object to be written as HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setEntityTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETENTITY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+ invoke();
+ }
+
+ /*
+ * @testName: setOutputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:939; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update the output stream for the object to be written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setOutputStreamTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETOUTPUTSTREAM);
+ setProperty(Property.SEARCH_STRING,
+ TemplateInterceptorBody.ENTITY.replace('t', 'x'));
+ invoke();
+ }
+
+ // /////////////////////////////////////////////////////////////////////
+ @Override
+ protected void addProviders() {
+ addProvider(new WriterInterceptorTwo());
+ addProvider(WriterInterceptorOne.class);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..14e1c30
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+ @POST
+ public String post(String entity) {
+ return entity;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..18ef1de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/ReaderClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/ReaderClient.java
new file mode 100644
index 0000000..22949b1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/ReaderClient.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ *
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class ReaderClient<CONTEXTOPERATION extends Enum<?>>
+ extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 8110273180216593061L;
+
+ /**
+ * Set the header OPERATION to a proper value Also set the entity, it is good
+ * as it is here for most of the tests. For the rest, the entity needs to be
+ * replaced.
+ */
+ protected void setOperationAndEntity(CONTEXTOPERATION op) {
+ addHeader(TemplateInterceptorBody.OPERATION, op.name());
+ setRequestContentEntity(TemplateInterceptorBody.ENTITY);
+ }
+
+ /**
+ * Invoke and convert IOException to Fault
+ */
+ protected void invoke() throws Fault {
+ invoke("string");
+ }
+
+ /**
+ * Invoke and convert IOException to Fault
+ */
+ protected void invoke(String method) throws Fault {
+ try {
+ setProperty(Property.REQUEST, buildRequest(Request.POST, method));
+ super.invoke();
+ } catch (Exception cause) {
+ if (cause instanceof IOException)
+ throw new Fault(cause.getMessage());
+ else
+ throw new Fault(cause);
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..604dcc2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.ReaderClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends ReaderClient<ContextOperation> {
+
+ private static final long serialVersionUID = 6573164759617152350L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_containerreader_interceptorcontext_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerreader_interceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class,
+ jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+ jakarta.ws.rs.tck.common.JAXRSCommonClient.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorOne.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorTwo.class,
+ Resource.class);
+ archive.addPackages(false, "jakarta.ws.rs.tck.common.client",
+ "jakarta.ws.rs.tck.common.webclient",
+ "jakarta.ws.rs.tck.common.webclient.handler",
+ "jakarta.ws.rs.tck.common.webclient.http",
+ "jakarta.ws.rs.tck.common.webclient.validation",
+ "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+ "jakarta.ws.rs.tck.api.rs.ext.interceptor.reader"
+ );
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getAnnotationsTest() throws Fault {
+ Method m;
+ try {
+ m = Resource.class.getMethod("post", String.class);
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ Annotation[] annotations = m.getParameterAnnotations()[0];
+ Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+ MediaType.WILDCARD_TYPE, annotations);
+ setOperationAndEntity(ContextOperation.GETANNOTATIONS);
+ setRequestContentEntity(entity);
+ setTextCaser(TextCaser.LOWER); // Case insensitive
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getGenericTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETGENERICTYPE);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get media type of HTTP entity.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getMediaTypeTest() throws Fault {
+ Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+ MediaType.APPLICATION_JSON_TYPE);
+ setOperationAndEntity(ContextOperation.GETMEDIATYPE);
+ setRequestContentEntity(entity);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Returns null if there is no property by that name.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getPropertyIsNullTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection containing the
+ * property names available within the context of the current request/response
+ * exchange context.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getPropertyNamesTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTYNAMES);
+ for (int i = 0; i != 5; i++)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.PROPERTY + i);
+ invoke();
+ }
+
+ /*
+ * @testName: getPropertyNamesIsReadOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection containing the
+ * property names available within the context of the current request/response
+ * exchange context.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getPropertyNamesIsReadOnlyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETPROPERTYNAMESISREADONLY);
+ setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: getTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get Java type supported by corresponding message body
+ * provider.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETTYPE);
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke();
+ }
+
+ /*
+ * @testName: removePropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Removes a property with the given name from the current
+ * request/response exchange context. After removal, subsequent calls to
+ * getProperty(java.lang.String) to retrieve the property value will return
+ * null.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void removePropertyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.REMOVEPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Update annotations on the formal declaration of the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setAnnotationsTest() throws Fault {
+ Annotation[] annotations = WriterInterceptorOne.class.getAnnotations();
+ setOperationAndEntity(ContextOperation.SETANNOTATIONS);
+ setTextCaser(TextCaser.LOWER);
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke();
+ }
+
+ /*
+ * @testName: setAnnotationsNullThrowsNPETest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Throws NullPointerException - in case the input parameter
+ * is null.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setAnnotationsNullThrowsNPETest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETANNOTATIONSNULL);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+ invoke();
+ }
+
+ /*
+ * @testName: setGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Update type of the object to be produced or written.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setGenericTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETGENERICTYPE);
+ setProperty(Property.SEARCH_STRING, "[B");
+ invoke();
+ }
+
+ /*
+ * @testName: setMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Update media type of HTTP entity.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setMediaTypeTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETMEDIATYPE);
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Binds an object to a given property name in the current
+ * request/response exchange context. If the name specified is already used
+ * for a property, this method will replace the value of the property with the
+ * new value.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setPropertyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETPROPERTY);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke();
+ }
+
+ /*
+ * @testName: setPropertyNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: If a null value is passed, the effect is the same as
+ * calling the removeProperty(String) method.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setPropertyNullTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETPROPERTYNULL);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke();
+ }
+
+ /*
+ * @testName: setTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Update Java type before calling message body provider.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setTypeTest() throws Fault {
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ TemplateInterceptorBody.ENTITY.getBytes());
+ Reader reader = new InputStreamReader(bais);
+ setOperationAndEntity(ContextOperation.SETTYPE);
+ setRequestContentEntity(reader);
+ addProvider(InputStreamReaderProvider.class);
+ invoke("inputstreamreader");
+ InputStreamReader isr = getResponseBody(InputStreamReader.class);
+ try {
+ String entity = JaxrsUtil.readFromReader(isr);
+ assertTrue(entity.contains(InputStreamReader.class.getName()),
+ "Expected"+ InputStreamReader.class.getName()+ "not found");
+ logMsg("#setType set correct type", entity);
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java
new file mode 100644
index 0000000..1997acc
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+ @POST
+ @Path("string")
+ public String post(@NotNull @Size(min = 2) String entity) {
+ return entity;
+ }
+
+ @POST
+ @Path("inputstreamreader")
+ public String post(InputStreamReader reader) throws IOException {
+ String entity = JaxrsUtil.readFromReader(reader);
+ reader.close();
+ return entity;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..451b74a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorTwo;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(ReaderInterceptorOne.class);
+ resources.add(ReaderInterceptorTwo.class);
+ resources.add(InputStreamReaderProvider.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..c54b3ef
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.ReaderClient;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends ReaderClient<ContextOperation> {
+
+ private static final long serialVersionUID = 3006391868445878375L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_containerreader_readerinterceptorcontext_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerreader_readerinterceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class,
+ jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+ jakarta.ws.rs.tck.common.provider.StringBean.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBean.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBeanEntityProvider.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorOne.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorTwo.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.InterceptorOneBody.class,
+ jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.InterceptorTwoBody.class
+ );
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: getHeadersOperationOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getHeadersOperationOnlyTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETHEADERS);
+ setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+ TemplateInterceptorBody.OPERATION);
+ setPrintEntity(true);
+ invoke();
+ }
+
+ /*
+ * @testName: getHeadersHeadersSetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getHeadersHeadersSetTest() throws Fault {
+ Property p = Property.UNORDERED_SEARCH_STRING;
+ setOperationAndEntity(ContextOperation.GETHEADERS);
+ setProperty(p, TemplateInterceptorBody.OPERATION);
+ setTextCaser(TextCaser.LOWER);
+ for (int i = 0; i != 5; i++) {
+ addHeader(TemplateInterceptorBody.PROPERTY + i, "any");
+ setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+ }
+ invoke();
+ }
+
+ /* Run test */
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getHeadersIsMutableTest() throws Fault {
+ setOperationAndEntity(ContextOperation.GETHEADERSISMUTABLE);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+ invoke();
+ }
+
+ /*
+ * @testName: getInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:924; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Get the input stream of the object to be read.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void getInputStreamTest() throws Fault {
+ String entity = "getInputStreamEntity";
+ setOperationAndEntity(ContextOperation.GETINPUTSTREAM);
+ setRequestContentEntity(entity);
+ setProperty(Property.SEARCH_STRING, entity);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsIOExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:926; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Throws: IOException - if an IO error arises
+ *
+ * proceed is actually called in every
+ * containerreader.readerinterceptorcontext test
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void proceedThrowsIOExceptionTest() throws Fault {
+ setOperationAndEntity(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+ invoke();
+ }
+
+ /*
+ * @testName: proceedThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:1008; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Throws: WebApplicationException - thrown by the wrapped
+ * {@code MessageBodyReader.readFrom} method.
+ *
+ * Proceed is tested in any of the interceptor tests.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+ setOperationAndEntity(ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.WAE);
+ invoke("errorbean");
+ }
+
+ /*
+ * @testName: setInputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:927; JAXRS:JAVADOC:920;
+ *
+ * @test_Strategy: Update the input stream of the object to be read.
+ *
+ * ReaderInterceptor.aroundReadFrom
+ */
+ @Test
+ public void setInputStreamTest() throws Fault {
+ setOperationAndEntity(ContextOperation.SETINPUTSTREAM);
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke();
+ }
+
+ // =====================
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..2a08540
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBean;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+ @POST
+ @Path("string")
+ public String post(String entity) {
+ return entity;
+ }
+
+ @POST
+ @Path("errorbean")
+ public String errorBean(ExceptionThrowingStringBean bean) {
+ return bean.get();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..cad2721
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBeanEntityProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorTwo;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(ReaderInterceptorOne.class);
+ resources.add(ReaderInterceptorTwo.class);
+ resources.add(ExceptionThrowingStringBeanEntityProvider.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java
new file mode 100644
index 0000000..840f835
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ *
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class WriterClient<CONTEXTOPERATION extends Enum<?>>
+ extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -9222693803307311300L;
+
+ /**
+ * Invoke and convert CONTEXTOPERATION to a path
+ */
+ protected void invoke(CONTEXTOPERATION op) throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(Request.GET, op.name().toLowerCase()));
+ super.invoke();
+ }
+
+ /**
+ * Invoke and convert CONTEXTOPERATION to a path
+ */
+ protected void invoke(CONTEXTOPERATION op, Request method) throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(method, op.name().toLowerCase()));
+ super.invoke();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..a588331
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.WriterClient;
+
+import jakarta.ws.rs.core.MediaType;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+ private static final long serialVersionUID = -3980167967224950515L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_containerwriter_interceptorcontext_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerwriter_interceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class,
+ jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+ jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor.class,
+ Resource.class);
+ archive.addPackages(false, "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+ "jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext");
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getAnnotationsTest() throws Fault {
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke(ContextOperation.GETANNOTATIONS);
+ }
+
+ /*
+ * @testName: getGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get an array of the annotations formally declared on the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getGenericTypeTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke(ContextOperation.GETGENERICTYPE);
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get media type of HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getMediaTypeTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+ invoke(ContextOperation.GETMEDIATYPE);
+ }
+
+ /*
+ * @testName: getPropertyIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns null if there is no property by that name.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyIsNullTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke(ContextOperation.GETPROPERTY);
+ }
+
+ /*
+ * @testName: getPropertyNamesIsReadOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns immutable java.util.Collection containing the
+ * property names available within the context of the current request/response
+ * exchange context.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyNamesIsReadOnlyTest() throws Fault {
+ setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke(ContextOperation.GETPROPERTYNAMESISREADONLY);
+ }
+
+ /*
+ * @testName: getPropertyNamesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Returns an enumeration containing the property names
+ * available within the context of the current request/response exchange
+ * context.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getPropertyNamesTest() throws Fault {
+ for (int i = 0; i != 5; i++)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ TemplateInterceptorBody.PROPERTY + i);
+ invoke(ContextOperation.GETPROPERTYNAMES);
+ }
+
+ /*
+ * @testName: getTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get Java type supported by corresponding message body
+ * provider.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getTypeTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, String.class.getName());
+ invoke(ContextOperation.GETTYPE);
+ }
+
+ /*
+ * @testName: removePropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Removes a property with the given name from the current
+ * request/response exchange context. After removal, subsequent calls to
+ * getProperty(java.lang.String) to retrieve the property value will return
+ * null.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void removePropertyTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke(ContextOperation.REMOVEPROPERTY);
+ }
+
+ /*
+ * @testName: setAnnotationsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update annotations on the formal declaration of the
+ * artifact that initiated the intercepted entity provider invocation.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setAnnotationsTest() throws Fault {
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ for (Annotation a : annotations)
+ setProperty(Property.UNORDERED_SEARCH_STRING,
+ a.annotationType().getName());
+ invoke(ContextOperation.SETANNOTATIONS);
+ }
+
+ /*
+ * @testName: setAnnotationsNullThrowsNPETest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Throws NullPointerException - in case the input parameter
+ * is null.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setAnnotationsNullThrowsNPETest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+ invoke(ContextOperation.SETANNOTATIONSNULL);
+ }
+
+ /*
+ * @testName: setGenericTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update type of the object to be produced or written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setGenericTypeTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, "[B");
+ invoke(ContextOperation.SETGENERICTYPE);
+ }
+
+ /*
+ * @testName: setMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update media type of HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setMediaTypeTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+ invoke(ContextOperation.SETMEDIATYPE);
+ }
+
+ /*
+ * @testName: setPropertyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Binds an object to a given property name in the current
+ * request/response exchange context. If the name specified is already used
+ * for a property, this method will replace the value of the property with the
+ * new value.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setPropertyTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+ invoke(ContextOperation.SETPROPERTY);
+ }
+
+ /*
+ * @testName: setPropertyNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: If a null value is passed, the effect is the same as
+ * calling the removeProperty(String) method.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setPropertyNullTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+ invoke(ContextOperation.SETPROPERTYNULL);
+ }
+
+ /*
+ * @testName: setTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update Java type before calling message body provider.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setTypeTest() throws Fault {
+ addProvider(InputStreamReaderProvider.class);
+ invoke(ContextOperation.SETTYPE);
+ InputStreamReader isr = getResponseBody(InputStreamReader.class);
+ try {
+ String entity = JaxrsUtil.readFromReader(isr);
+ assertTrue(entity.contains(InputStreamReader.class.getName()),
+ "Expected"+ InputStreamReader.class.getName()+ "not found");
+ logMsg("#setType set correct type", entity);
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java
new file mode 100644
index 0000000..4ca8081
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+@Path("resource")
+public class Resource {
+
+ @GET
+ @Path("{id}")
+ public Response genericResponse(@PathParam("id") String path) {
+ ContextOperation op = ContextOperation.valueOf(path.toUpperCase());
+ ResponseBuilder builder = createResponseBuilderWithHeader(op);
+ switch (op) {
+ case GETANNOTATIONS:
+ Annotation[] annotations = ContextOperation.class.getAnnotations();
+ builder = builder.entity(TemplateInterceptorBody.ENTITY, annotations);
+ break;
+ case GETMEDIATYPE:
+ builder = builder.type(MediaType.APPLICATION_JSON_TYPE);
+ break;
+ case SETTYPE:
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ TemplateInterceptorBody.ENTITY.getBytes());
+ Reader reader = new InputStreamReader(bais);
+ builder = builder.entity(reader);
+ break;
+ default:
+ break;
+ }
+ Response response = builder.build();
+ return response;
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ ResponseBuilder createResponseBuilderWithHeader(ContextOperation op) {
+ Response.ResponseBuilder builder = Response.ok();
+ // set a header with ContextOperation so that the filter knows what to
+ // do
+ builder = builder.header(TemplateInterceptorBody.OPERATION, op.name());
+ builder = builder.entity(TemplateInterceptorBody.ENTITY);
+ return builder;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..780adce
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorTwo;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(WriterInterceptorOne.class);
+ resources.add(WriterInterceptorTwo.class);
+ resources.add(InputStreamReaderProvider.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..76f6b40
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+ private static final long serialVersionUID = -8158424518609416304L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot(
+ "/jaxrs_ee_rs_ext_interceptor_containerwriter_writerinterceptorcontext_web/resource");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerwriter_writerinterceptorcontext_web.war");
+ archive.addClasses(TSAppConfig.class,
+ jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+ jakarta.ws.rs.tck.common.provider.StringBean.class,
+ jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider.class,
+ jakarta.ws.rs.tck.common.impl.ReplacingOutputStream.class,
+ jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor.class,
+ Resource.class);
+ archive.addPackages(false,
+ "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+ "jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext");
+
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+ /*
+ * @testName: getEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:933; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get object to be written as HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getEntityTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY);
+ invoke(ContextOperation.GETENTITY);
+ }
+
+ /*
+ * @testName: getHeadersOperationOnlyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersOperationOnlyTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+ invoke(ContextOperation.GETHEADERS);
+ }
+
+ /*
+ * @testName: getHeadersTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersTest() throws Fault {
+ Property p = Property.UNORDERED_SEARCH_STRING;
+ setProperty(p, TemplateInterceptorBody.OPERATION);
+ for (int i = 0; i != 5; i++)
+ setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+ invoke(ContextOperation.GETHEADERS);
+ }
+
+ /*
+ * @testName: getHeadersIsMutableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get mutable map of HTTP headers.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getHeadersIsMutableTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+ invoke(ContextOperation.GETHEADERSISMUTABLE);
+ }
+
+ /*
+ * @testName: getOutputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:935; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Get the output stream for the object to be written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void getOutputStreamTest() throws Fault {
+ Property p = Property.UNORDERED_SEARCH_STRING;
+ setProperty(p, TemplateInterceptorBody.ENTITY);
+ setProperty(p, TemplateInterceptorBody.NULL);
+ invoke(ContextOperation.GETOUTPUTSTREAM);
+ }
+
+ /*
+ * @testName: proceedThrowsIOExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:937; JAXRS:JAVADOC:930;
+ * JAXRS:JAVADOC:931;
+ *
+ * @test_Strategy: Proceed to the next interceptor in the chain.
+ * Throws:IOException - if an IO exception arises.
+ *
+ * proceed is actually called in every clientwriter.writerinterceptorcontext
+ * test
+ *
+ * WriterInterceptor.aroundWriteTo
+ *
+ * WriterInterceptor.aroundWriteTo throws IOException
+ */
+ @Test
+ public void proceedThrowsIOExceptionTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+ invoke(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+ }
+
+ /*
+ * @testName: proceedThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:1009; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Proceed to the next interceptor in the chain.
+ * Throws:WebApplicationException thrown by the wrapped {@code
+ * MessageBodyWriter.writeTo} method.
+ *
+ * proceed is actually called in every clientwriter.writerinterceptorcontext
+ * test
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.WAE);
+ invoke(ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+ }
+
+ /*
+ * @testName: setEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:938; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update object to be written as HTTP entity.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setEntityTest() throws Fault {
+ setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+ invoke(ContextOperation.SETENTITY);
+ }
+
+ /*
+ * @testName: setOutputStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:939; JAXRS:JAVADOC:930;
+ *
+ * @test_Strategy: Update the output stream for the object to be written.
+ *
+ * WriterInterceptor.aroundWriteTo
+ */
+ @Test
+ public void setOutputStreamTest() throws Fault {
+ setProperty(Property.SEARCH_STRING,
+ TemplateInterceptorBody.ENTITY.replace('t', 'x'));
+ invoke(ContextOperation.SETOUTPUTSTREAM);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..a4ad607
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.OnWriteExceptionThrowingStringBean;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+@Path("resource")
+public class Resource {
+
+ @GET
+ @Path("{id}")
+ public Response genericResponse(@PathParam("id") String path) {
+ ContextOperation op = ContextOperation.valueOf(path.toUpperCase());
+ ResponseBuilder builder = createResponseBuilderWithHeader(op);
+ switch (op) {
+ case GETHEADERS:
+ for (int i = 0; i != 5; i++)
+ builder = builder.header(TemplateInterceptorBody.PROPERTY + i, "any");
+ break;
+ case PROCEEDTHROWSWEBAPPEXCEPTION:
+ builder.entity(new OnWriteExceptionThrowingStringBean(
+ TemplateInterceptorBody.ENTITY));
+ break;
+ default:
+ break;
+ }
+ Response response = builder.build();
+ return response;
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ static ResponseBuilder createResponseBuilderWithHeader(ContextOperation op) {
+ Response.ResponseBuilder builder = Response.ok();
+ // set a header with ContextOperation so that the filter knows what to
+ // do
+ builder = builder.header(TemplateInterceptorBody.OPERATION, op.name());
+ builder = builder.entity(TemplateInterceptorBody.ENTITY);
+ return builder;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..88a442e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ProceedExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorTwo;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(WriterInterceptorOne.class);
+ resources.add(WriterInterceptorTwo.class);
+ resources.add(InputStreamReaderProvider.class);
+ resources.add(StringBeanEntityProvider.class);
+ resources.add(ProceedExceptionMapper.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java
new file mode 100644
index 0000000..86c3e87
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptor;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+/**
+ * This class is a superclass for any interceptor @Provider. Any such provider
+ * is then given a body, inherited from TemplateInterceptorBody. The body
+ * actually contains methods with name equalIgnoreCase to ContextOperation items
+ * name, the name of the method executed is passed by http header OPERATION
+ *
+ * @see TemplateInterceptorBody
+ *
+ * The injection of the body solves the issue with inheritance from two
+ * super-classes.
+ */
+public abstract class TemplateWriterInterceptor
+ implements WriterInterceptor, InterceptorCallbackMethods {
+
+ protected WriterInterceptorContext writerCtx;
+
+ protected TemplateInterceptorBody<WriterInterceptorContext> interceptorBody;
+
+ public TemplateWriterInterceptor(
+ TemplateInterceptorBody<WriterInterceptorContext> interceptorBody) {
+ super();
+ this.interceptorBody = interceptorBody;
+ }
+
+ @Override
+ public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException {
+ this.writerCtx = ctx;
+ interceptorBody.executeMethod(writerCtx, this);
+ }
+
+ @Override
+ public void writeEntity(String entity) {
+ Type type = writerCtx.getGenericType();
+ if (type instanceof Class) {
+ Class<?> clazz = ((Class<?>) type);
+ if (clazz == InputStreamReader.class) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(entity.getBytes());
+ InputStreamReader reader = new InputStreamReader(bis);
+ writerCtx.setEntity(reader);
+ } else {
+ writerCtx.setEntity(entity);
+ }
+ }
+ }
+
+ @Override
+ public Object proceed() throws IOException {
+ writerCtx.proceed();
+ return null;
+ }
+
+ @Override
+ public String getHeaderString() {
+ MultivaluedMap<String, Object> headers = writerCtx.getHeaders();
+ return (String) headers.getFirst(TemplateInterceptorBody.OPERATION);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java
new file mode 100644
index 0000000..73ab437
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+@Provider
+@Priority(100)
+public class WriterInterceptorOne extends TemplateWriterInterceptor {
+
+ public WriterInterceptorOne() {
+ super(new InterceptorBodyOne<WriterInterceptorContext>());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java
new file mode 100644
index 0000000..79145f6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+@Provider
+@Priority(200)
+public class WriterInterceptorTwo extends TemplateWriterInterceptor {
+
+ public WriterInterceptorTwo() {
+ super(new InterceptorBodyTwo<WriterInterceptorContext>());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java
new file mode 100644
index 0000000..5482efa
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+public enum ContextOperation {
+ GETENTITY, GETHEADERS, GETHEADERSISMUTABLE, GETOUTPUTSTREAM, FROMPROCEEDTHROWSWEBAPPEXCEPTION, // On
+ // return
+ // with
+ // WebAppException
+ // The
+ // Exception
+ // is
+ // not
+ // thrown
+ // again
+ PROCEEDTHROWSIOEXCEPTION, PROCEEDTHROWSWEBAPPEXCEPTION, SETENTITY, SETOUTPUTSTREAM
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java
new file mode 100644
index 0000000..aa68c01
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.impl.ReplacingOutputStream;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+public class InterceptorBodyOne
+ extends TemplateInterceptorBody<WriterInterceptorContext> {
+
+ public void getEntity() {
+ Object entity = context.getEntity();
+ setEntity(entity);
+ }
+
+ public void getHeaders() {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ String keys = JaxrsUtil.iterableToString(";", headers.keySet());
+ setEntity(keys);
+ }
+
+ public void getHeadersIsMutable() {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ Object o = headers.getFirst(PROPERTY);
+ assertTrue(o == null, PROPERTY, "header allready exist");
+ headers.add(PROPERTY, PROPERTY);
+ }
+
+ public void getOutputStream() throws IOException {
+ setEntityToOutputStream(NULL);
+ }
+
+ public void proceedThrowsIOException() {
+ try {
+ context.proceed(); // Should throw IOException which is wrapped in
+ setEntity(NULL); // TemplateWriterInterceptor to RuntimeExecption
+ } catch (IOException ioe) {
+ setEntity(IOE); // let the client know
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ public String proceedThrowsWebAppException() throws IOException {
+ try {
+ context.proceed(); // Should throw WebApplicationException in
+ throw new ProceedException(NULL); // TemplateWriterInterceptor
+ } catch (WebApplicationException e) {
+ throw new ProceedException(WAE);
+ } catch (IOException e) {
+ throw new ProceedException(NULL); // TemplateWriterInterceptor to
+ // RuntimeExecption
+ }
+ }
+
+ public void fromProceedThrowsWebAppException() throws IOException {
+ // intentionally blank, no need to do enything
+ // this is called on an interceptor on a response given by
+ // ProceedException.getResponse()
+ }
+
+ public void setEntity() {
+ context.setEntity(OPERATION);
+ }
+
+ public void setOutputStream() throws IOException {
+ OutputStream originalStream = context.getOutputStream();
+ OutputStream replace = new ReplacingOutputStream(originalStream, 't', 'x');
+ context.setOutputStream(replace);
+ }
+
+ private void setEntityToOutputStream(String entity) throws IOException {
+ OutputStream stream = context.getOutputStream();
+ stream.write(entity.getBytes());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java
new file mode 100644
index 0000000..79b505a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+public class InterceptorBodyTwo
+ extends TemplateInterceptorBody<WriterInterceptorContext> {
+ @Override
+ protected Object operationMethodNotFound(String operation)
+ throws IOException {
+ return proceed();
+ }
+
+ public void getHeadersIsMutable() {
+ MultivaluedMap<String, Object> headers = context.getHeaders();
+ Object o = headers.getFirst(PROPERTY);
+ assertTrue(o != null, PROPERTY, "header NOT found");
+ setEntity(o);
+ }
+
+ public void proceedThrowsIOException() throws IOException {
+ throw new IOException("Interceptor test IoException");
+ }
+
+ public void proceedThrowsWebAppException() throws IOException {
+ context.proceed();
+ }
+
+ public void setEntity() {
+ Object entity = context.getEntity();
+ setEntity(entity);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java
new file mode 100644
index 0000000..0951377
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.WebApplicationException;
+
+public class OnWriteExceptionThrowingStringBean extends StringBean {
+
+ public OnWriteExceptionThrowingStringBean(String header) {
+ super(header);
+ }
+
+ @Override
+ public String get() {
+ String header = super.get();
+ if (header.equals(TemplateInterceptorBody.WAE))
+ return header;
+ else
+ throw new WebApplicationException(new IOException(header));
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java
new file mode 100644
index 0000000..67c45cd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+
+public class ProceedException extends WebApplicationException {
+
+ private static final long serialVersionUID = -8012949565468746147L;
+
+ private String msg;
+
+ public ProceedException(String msg) {
+ super(
+ Response.ok(msg)
+ .header(TemplateInterceptorBody.OPERATION,
+ ContextOperation.FROMPROCEEDTHROWSWEBAPPEXCEPTION.name())
+ .build());
+ this.msg = msg;
+ }
+
+ /**
+ * Acyclic getCause() returns equivalent of this
+ */
+ @Override
+ public Throwable getCause() {
+ return new ProceedException(msg) {
+ private static final long serialVersionUID = 256996856963444570L;
+
+ @Override
+ public Throwable getCause() {
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public String getMessage() {
+ return msg;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java
new file mode 100644
index 0000000..44568c6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+
+public class ProceedExceptionMapper
+ implements ExceptionMapper<ProceedException> {
+
+ @Override
+ public Response toResponse(ProceedException exception) {
+ return exception.getResponse();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java
new file mode 100644
index 0000000..92dc4de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class WriterInterceptorOne extends TemplateWriterInterceptor {
+
+ public WriterInterceptorOne() {
+ super(new InterceptorBodyOne());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java
new file mode 100644
index 0000000..0bae703
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class WriterInterceptorTwo extends TemplateWriterInterceptor {
+
+ public WriterInterceptorTwo() {
+ super(new InterceptorBodyTwo());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java
new file mode 100644
index 0000000..9f5e01f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EntityAnnotation {
+ String value();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java
new file mode 100644
index 0000000..d7669e7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.AbstractMessageBodyRW;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class EntityMessageReader extends AbstractMessageBodyRW
+ implements MessageBodyReader<ReadableWritableEntity> {
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType,
+ Annotation[] annotations, MediaType mediaType) {
+ String path = getSpecifiedAnnotationValue(annotations,
+ EntityAnnotation.class);
+ if (path == null)
+ return false;
+ path = path.toLowerCase();
+ boolean readable = path.contains("body");
+ readable |= path.contains("head");
+ readable |= path.contains("ioexception");
+ readable |= path.contains("webexception");
+ readable &= MediaType.TEXT_XML_TYPE.isCompatible(mediaType);
+ readable &= ReadableWritableEntity.class.isAssignableFrom(type);
+ return readable;
+ }
+
+ @Override
+ public ReadableWritableEntity readFrom(Class<ReadableWritableEntity> type,
+ Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+ throws IOException, WebApplicationException {
+ String ea = getSpecifiedAnnotationValue(annotations, EntityAnnotation.class)
+ .toLowerCase();
+ String entity = "null";
+ if (ea.contains("body"))
+ entity = readInputStream(entityStream);
+ else if (ea.contains("head"))
+ entity = httpHeaders.getFirst(ReadableWritableEntity.NAME);
+ else if (ea.contains("ioexception"))
+ throw new IOException("CTS test IOException");
+ else if (ea.contains("webexception")) {
+ entity = httpHeaders.getFirst(ReadableWritableEntity.NAME);
+ throw new WebApplicationException(Status.valueOf(entity));
+ }
+ return ReadableWritableEntity.fromString(entity);
+ }
+
+ String readInputStream(InputStream is) throws IOException {
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ return br.readLine();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
index cac6e91..052313f 100644
--- a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
@@ -31,7 +31,7 @@
/**
* This class is used by
- * com.sun.ts.tests.jaxrs.ee.rs.ext.providers.ProvidersServlet
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
*/
@Provider
public class EntityMessageWriter extends AbstractMessageBodyRW
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
index 5143385..cea33cb 100644
--- a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
@@ -18,7 +18,7 @@
/**
* This class is used by
- * com.sun.ts.tests.jaxrs.ee.rs.ext.providers.ProvidersServlet
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
*/
public class ReadableWritableEntity {
private String entity;
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java
new file mode 100644
index 0000000..80202f3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverter.Lazy;
+
+@Lazy
+public class AtomicIntegerLazyParamConverter
+ implements ParamConverter<AtomicInteger> {
+
+ @Override
+ public AtomicInteger fromString(String value)
+ throws IllegalArgumentException {
+ return new AtomicInteger(Integer.parseInt(value));
+ }
+
+ @Override
+ public String toString(AtomicInteger value) throws IllegalArgumentException {
+ return String.valueOf(value.get());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java
new file mode 100644
index 0000000..195fa93
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class AtomicIntegerLazyParamConverterProvider
+ implements ParamConverterProvider {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+ Annotation[] annotations) {
+ if (rawType == AtomicInteger.class)
+ return (ParamConverter<T>) new AtomicIntegerLazyParamConverter();
+ return null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java
new file mode 100644
index 0000000..1ad24ff
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.tck.common.impl.StringDataSource;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.ParamConverter;
+
+public class DataSourceParamConverter implements ParamConverter<DataSource> {
+
+ @Override
+ public DataSource fromString(String value) throws IllegalArgumentException {
+ StringDataSource sds = new StringDataSource(value,
+ MediaType.TEXT_PLAIN_TYPE);
+ return sds;
+ }
+
+ @Override
+ public String toString(DataSource value) throws IllegalArgumentException {
+ return value.getName();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java
new file mode 100644
index 0000000..33b5b6a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DataSourceParamConverterProvider
+ implements ParamConverterProvider {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+ Annotation[] annotations) {
+ if (DataSource.class.isAssignableFrom(rawType))
+ return (ParamConverter<T>) new DataSourceParamConverter();
+ return null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java
new file mode 100644
index 0000000..f75f5d1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response.Status;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = 863071027768369551L;
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_ext_paramconverter_web");
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_ext_paramconverter_web.war");
+ archive.addClasses(Resource.class, Locator.class, DataSourceParamConverter.class, DataSourceParamConverterProvider.class,
+ StringBeanParamConverter.class, StringBeanParamConverterProvider.class, AtomicIntegerLazyParamConverter.class, AtomicIntegerLazyParamConverterProvider.class,
+ jakarta.ws.rs.tck.common.provider.PrintingErrorHandler.class,
+ jakarta.ws.rs.tck.common.provider.StringBean.class,
+ jakarta.ws.rs.tck.common.impl.StringDataSource.class,
+ TSAppConfig.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+
+ /* Run test */
+
+ /*
+ * @testName: isParamCoverterInApplicationSingletonsUsedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:919;
+ *
+ * @test_Strategy: Providers implementing ParamConverterProvider contract must
+ * be either programmatically registered in a JAX-RS runtime
+ */
+ @Test
+ public void isParamCoverterInApplicationSingletonsUsedTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequest(Request.GET, "dsquery?param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: isParamCoverterInApplicationClassesUsedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:919;
+ *
+ * @test_Strategy: Providers implementing ParamConverterProvider contract must
+ * be either programmatically registered in a JAX-RS runtime
+ */
+ @Test
+ public void isParamCoverterInApplicationClassesUsedTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequest(Request.GET, "sbquery?param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: atomicIntegerPassesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:919;
+ *
+ * @test_Strategy: Providers implementing ParamConverterProvider contract must
+ * be either programmatically registered in a JAX-RS runtime
+ */
+ @Test
+ public void atomicIntegerPassesTest() throws Fault {
+ String query = "10";
+ setPropertyRequest(Request.GET, "aiquery?param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: atomicIntegerIsLazyDeployableAndThrowsErrorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:919;
+ *
+ * @test_Strategy: Providers implementing ParamConverterProvider contract must
+ * be either programmatically registered in a JAX-RS runtime
+ */
+ @Test
+ public void atomicIntegerIsLazyDeployableAndThrowsErrorTest() throws Fault {
+ setPropertyRequest(Request.GET, "aiquery");
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.NOT_ACCEPTABLE));
+ invoke();
+ }
+
+ /*
+ * @testName: pathParamUsesParamConvertorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void pathParamUsesParamConvertorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequest(Request.GET, "sbpath/", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: matrixParamUsesParamConvertorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void matrixParamUsesParamConvertorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequest(Request.GET, "sbmatrix;param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: formParamUsesParamConvertorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void formParamUsesParamConvertorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setProperty(Property.REQUEST_HEADERS,
+ buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+ setPropertyRequest(Request.POST, "sbform/");
+ setProperty(Property.CONTENT, "param=" + query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: cookieParamUsesParamConvertorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void cookieParamUsesParamConvertorTest() throws Fault {
+ String query = "ABCDEFGH";
+ buildCookie(query);
+ setPropertyRequest(Request.GET, "sbcookie");
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: headerParamUsesParamConvertorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void headerParamUsesParamConvertorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setProperty(Property.REQUEST_HEADERS, "param:" + query);
+ setPropertyRequest(Request.GET, "sbheader");
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInQueryParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInQueryParamTest() throws Fault {
+ setPropertyRequest(Request.GET, "sbquery");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInMatrixParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInMatrixParamTest() throws Fault {
+ setPropertyRequest(Request.GET, "sbmatrix;");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInPathParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInPathParamTest() throws Fault {
+ setPropertyRequest(Request.GET, "sbpath/default");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInFormParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInFormParamTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+ setPropertyRequest(Request.POST, "sbform/");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInCookieParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInCookieParamTest() throws Fault {
+ setPropertyRequest(Request.GET, "sbcookie");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueInHeaderParamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value in the resource or provider
+ * model, that is during the application deployment, before any value default
+ * or otherwise is actually required
+ */
+ @Test
+ public void defaultValueInHeaderParamTest() throws Fault {
+ setPropertyRequest(Request.GET, "sbheader");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: queryParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void queryParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequestInLocator(Request.GET, "sbquery/sbquery?param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueQueryParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValueQueryParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequestInLocator(Request.GET, "sbquery/sbquery?", query);
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: pathParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void pathParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequestInLocator(Request.GET, "sbpath/sbpath/", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValuePathParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValuePathParamInLocatorTest() throws Fault {
+ setPropertyRequestInLocator(Request.GET, "sbpath/sbpath/default");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: matrixParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void matrixParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setPropertyRequestInLocator(Request.GET, "sbmatrix/sbmatrix;param=", query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueMatrixParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValueMatrixParamInLocatorTest() throws Fault {
+ setPropertyRequestInLocator(Request.GET, "sbmatrix/sbmatrix");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: formParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void formParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setProperty(Property.REQUEST_HEADERS,
+ buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+ setPropertyRequestInLocator(Request.POST, "sbform/sbform");
+ setProperty(Property.CONTENT, "param=" + query);
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueFormParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValueFormParamInLocatorTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+ setPropertyRequestInLocator(Request.POST, "sbform/sbform");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: cookieParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void cookieParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ buildCookie(query);
+ setPropertyRequestInLocator(Request.GET, "sbcookie/sbcookie");
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueCookieParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValueCookieParamInLocatorTest() throws Fault {
+ setPropertyRequestInLocator(Request.GET, "sbcookie/sbcookie");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ /*
+ * @testName: headerParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: Parse the supplied value and create an instance of
+ */
+ @Test
+ public void headerParamInLocatorTest() throws Fault {
+ String query = "ABCDEFGH";
+ setProperty(Property.REQUEST_HEADERS, "param:" + query);
+ setPropertyRequestInLocator(Request.GET, "sbheader/sbheader");
+ setProperty(Property.SEARCH_STRING, query);
+ invoke();
+ }
+
+ /*
+ * @testName: defaultValueHeaderParamInLocatorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:915;
+ *
+ * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+ * JAX-RS runtime to convert any default value
+ */
+ @Test
+ public void defaultValueHeaderParamInLocatorTest() throws Fault {
+ setPropertyRequestInLocator(Request.GET, "sbheader/sbheader");
+ setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+ invoke();
+ }
+
+ // ////////////////////////////////////////////////////////////////////
+ private//
+ void setPropertyRequestInResource(Request request, String... resource) {
+ StringBuilder sb = new StringBuilder("resource/");
+ for (String r : resource)
+ sb.append(r);
+ setProperty(Property.REQUEST, buildRequest(request, sb.toString()));
+ }
+
+ private void setPropertyRequest(Request request, String... resource) {
+ setPropertyRequestInResource(request, resource);
+ }
+
+ private//
+ void setPropertyRequestInLocator(Request request, String... resource) {
+ StringBuilder sb = new StringBuilder("locator/");
+ for (String r : resource)
+ sb.append(r);
+ setProperty(Property.REQUEST, buildRequest(request, sb.toString()));
+ }
+
+ private void buildCookie(String cookieValue) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Cookie: param=").append(cookieValue);
+ setProperty(Property.REQUEST_HEADERS, sb.toString());
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java
new file mode 100644
index 0000000..6f32344
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("locator")
+public class Locator {
+
+ @Path("sbquery")
+ public Resource stringBeanQuery() {
+ return new Resource();
+ }
+
+ @Path("sbpath")
+ public Resource stringBeanPath() {
+ return new Resource();
+ }
+
+ @Path("sbmatrix")
+ public Resource stringBeanMatrix() {
+ return new Resource();
+ }
+
+ @Path("sbform")
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public Resource stringBeanForm() {
+ return new Resource();
+ }
+
+ @Path("sbcookie")
+ public Resource stringBeanCookie() {
+ return new Resource();
+ }
+
+ @Path("sbheader")
+ public Resource stringBeanHeader() {
+ return new Resource();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java
new file mode 100644
index 0000000..6f2b061
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.CookieParam;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.MatrixParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("resource")
+public class Resource {
+ public static final String NULL = "NULL";
+
+ public static final String DEFAULT = "DEFAULT";
+
+ @Path("sbquery")
+ @GET
+ public String stringBeanQuery(
+ @DefaultValue(DEFAULT) @QueryParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("dsquery")
+ @GET
+ public String dataSourceQuery(@QueryParam("param") DataSource param) {
+ return param.getName();
+ }
+
+ @Path("aiquery")
+ @GET
+ public String atomicIntegerQuery(
+ @DefaultValue(DEFAULT) @QueryParam("param") AtomicInteger param) {
+ return String.valueOf(param.get());
+ }
+
+ @Path("sbpath/{param}")
+ @GET
+ public String stringBeanPath(@PathParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("sbpath/default")
+ @GET
+ public String stringBeanPathNeverHere(
+ @DefaultValue(DEFAULT) @PathParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("sbmatrix")
+ @GET
+ public String stringBeanMatrix(
+ @DefaultValue(DEFAULT) @MatrixParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("sbform")
+ @POST
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public String stringBeanForm(
+ @DefaultValue(DEFAULT) @FormParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("sbcookie")
+ @GET
+ public String stringBeanCookie(
+ @DefaultValue(DEFAULT) @CookieParam("param") StringBean param) {
+ return param.get();
+ }
+
+ @Path("sbheader")
+ @GET
+ public String stringBeanHeader(
+ @DefaultValue(DEFAULT) @HeaderParam("param") StringBean param) {
+ return param.get();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java
new file mode 100644
index 0000000..1a03c70
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.ext.ParamConverter;
+
+public class StringBeanParamConverter implements ParamConverter<StringBean> {
+
+ @Override
+ public StringBean fromString(String value) throws IllegalArgumentException {
+ return new StringBean(value);
+ }
+
+ @Override
+ public String toString(StringBean value) throws IllegalArgumentException {
+ return value.get();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java
new file mode 100644
index 0000000..02d46e9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class StringBeanParamConverterProvider
+ implements ParamConverterProvider {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+ Annotation[] annotations) {
+ if (rawType == StringBean.class)
+ return (ParamConverter<T>) new StringBeanParamConverter();
+ return null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java
new file mode 100644
index 0000000..dfe52e2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.provider.PrintingErrorHandler;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ @Override
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(Resource.class);
+ resources.add(Locator.class);
+ resources.add(StringBeanParamConverterProvider.class);
+ resources.add(AtomicIntegerLazyParamConverterProvider.class);
+ resources.add(PrintingErrorHandler.class);
+ return resources;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ Set<Object> set = new HashSet<Object>();
+ set.add(new DataSourceParamConverterProvider());
+ return set;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java
new file mode 100644
index 0000000..d369738
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response.Status;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSProvidersClientIT
+ //extends jakarta.ws.rs.tck.ee.rs.core.application.JAXRSClientIT {
+ extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = -935293219512493643L;
+
+ protected int expectedSingletons = 1;
+
+ protected int expectedClasses = 1;
+
+ public JAXRSProvidersClientIT() {
+ setup();
+ TSAppConfig cfg = new TSAppConfig();
+ setContextRoot("/jaxrs_ee_ext_providers_web/ProvidersServlet");
+ expectedClasses = cfg.getClasses().size();
+ expectedSingletons = cfg.getSingletons().size();
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSProvidersClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template");
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_ext_providers_web.war");
+ archive.addClasses(TSAppConfig.class, ProvidersServlet.class,
+ jakarta.ws.rs.tck.common.AbstractMessageBodyRW.class,
+ jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet.class,
+ jakarta.ws.rs.tck.ee.rs.core.application.ApplicationHolderSingleton.class,
+ jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider.class,
+ jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumContextResolver.class,
+ jakarta.ws.rs.tck.ee.rs.ext.contextresolver.TextPlainEnumContextResolver.class,
+ jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper.class,
+ jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.IOExceptionExceptionMapper.class,
+ jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityAnnotation.class,
+ jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageReader.class,
+ jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageWriter.class,
+ jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity.class
+ );
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+ /* Run test */
+
+ /*
+ * @testName: getSingletonsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:23
+ *
+ * @test_Strategy: Check that the implementation returns set of
+ * TSAppConfig.CLASSLIST
+ */
+ @Test
+ public void getSingletonsTest() throws Fault {
+ //super.getSingletonsTest();
+ setProperty(REQUEST, buildRequest(GET, "GetSingletons"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ assertTrue(getReturnedNumber() == expectedSingletons,
+ "Application.getSingletons() return incorrect value:"+
+ getReturnedNumber());
+ }
+
+ /*
+ * @testName: getClassesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:22
+ *
+ * @test_Strategy: Check the implementation injects TSAppConfig
+ */
+ @Test
+ public void getClassesTest() throws Fault {
+ //super.getClassesTest();
+ setProperty(REQUEST, buildRequest(GET, "GetClasses"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ assertTrue(getReturnedNumber() == expectedClasses,
+ "Application.getClasses() return incorrect value:"+
+ getReturnedNumber());
+ }
+
+ /*
+ * @testName: isRegisteredTextPlainContextResolverTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:269; JAXRS:JAVADOC:280; JAXRS:JAVADOC:299;
+ * JAXRS:SPEC:40; JAXRS:SPEC:80; JAXRS:SPEC:81;
+ *
+ * @test_Strategy: Register ContextResolver and try to get proper Provider
+ *
+ * When injecting an instance of one of the types listed in section 9.2, the
+ * instance supplied MUST be capable of selecting the correct context for a
+ * particular request.
+ *
+ * Context providers MAY return null from the getContext method if they do not
+ * wish to provide their context for a particular Java type.
+ *
+ * Context provider implementations MAY restrict the media types they support
+ * using the @Produces annotation.
+ */
+ @Test
+ public void isRegisteredTextPlainContextResolverTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredTextPlainContextResolver"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredAppJsonContextResolverTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:269; JAXRS:JAVADOC:280; JAXRS:JAVADOC:299;
+ * JAXRS:SPEC:40; JAXRS:SPEC:80; JAXRS:SPEC:81;
+ *
+ * @test_Strategy: Register ContextResolver and try to get proper Provider
+ *
+ * When injecting an instance of one of the types listed in section 9.2, the
+ * instance supplied MUST be capable of selecting the correct context for a
+ * particular request.
+ *
+ * Context providers MAY return null from the getContext method if they do not
+ * wish to provide their context for a particular Java type.
+ *
+ * Context provider implementations MAY restrict the media types they support
+ * using the @Produces annotation. Absence implies that any media type is
+ * supported.
+ */
+ @Test
+ public void isRegisteredAppJsonContextResolverTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredAppJsonContextResolver"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredExceptionMapperRuntimeExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:270; JAXRS:JAVADOC:281; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Try to get proper ExceptionMapper
+ */
+ @Test
+ public void isRegisteredExceptionMapperRuntimeExceptionTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredExceptionMapperRuntimeEx"));
+ setProperty(Property.STATUS_CODE,
+ getStatusCode(Status.INTERNAL_SERVER_ERROR));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredExceptionMapperNullExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:281;
+ *
+ * @test_Strategy: Try to get proper ExceptionMapper
+ */
+ @Test
+ public void isRegisteredExceptionMapperNullExceptionTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredExceptionMapperNullEx"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.NO_CONTENT));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredRuntimeExceptionExceptionMapperTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:281; JAXRS:JAVADOC:300; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Try to get RuntimeExceptionExceptionMapper but there is
+ * none
+ */
+ @Test
+ public void isRegisteredRuntimeExceptionExceptionMapperTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredRuntimeExceptionMapper"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredIOExceptionExceptionMapperTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:281;
+ *
+ * @test_Strategy: Try to get IOExceptionExceptionMapper
+ */
+ @Test
+ public void isRegisteredIOExceptionExceptionMapperTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredIOExceptionMapper"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredMessageBodyWriterWildcardTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+ * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check what is returned for wildcard is for text/plain
+ */
+ @Test
+ public void isRegisteredMessageBodyWriterWildcardTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredWriterWildcard"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredMessageBodyWriterXmlTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+ * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check BodyWriter is returned for text/xml
+ */
+ @Test
+ public void isRegisteredMessageBodyWriterXmlTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredMessageWriterXml"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredMessageBodyReaderWildcardTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:282;
+ * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check what is returned for wildcard is for text/plain
+ */
+ @Test
+ public void isRegisteredMessageBodyReaderWildcardTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredMessageReaderWildCard"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: isRegisteredMessageBodReaderXmlTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:282;
+ * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check BodyReader is returned for text/xml
+ */
+ @Test
+ public void isRegisteredMessageBodReaderXmlTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "isRegisteredMessageReaderXml"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: writeBodyEntityUsingWriterTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+ * JAXRS:JAVADOC:132; JAXRS:JAVADOC:275; JAXRS:JAVADOC:276; JAXRS:JAVADOC:304;
+ *
+ * @test_Strategy: Check BodyWriter is used for text/xml to write entity
+ */
+ @Test
+ public void writeBodyEntityUsingWriterTest() throws Fault {
+ String ename = EnumProvider.JAXRS.name();
+ String search = new ReadableWritableEntity(ename).toXmlString();
+ setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "writeBodyEntityUsingWriter"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ setProperty(Property.SEARCH_STRING, search);
+ invoke();
+ }
+
+ /*
+ * @testName: writeHeaderEntityUsingWriterTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:132;
+ * JAXRS:JAVADOC:275; JAXRS:JAVADOC:277; JAXRS:JAVADOC:304;
+ *
+ * @test_Strategy: Check HeaderWriter is used for text/xml to write entity
+ */
+ @Test
+ public void writeHeaderEntityUsingWriterTest() throws Fault {
+ String ename = EnumProvider.JAXRS.name();
+ String search = new ReadableWritableEntity(ename).toXmlString();
+ setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "writeHeaderEntityUsingWriter"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ setProperty(Property.EXPECTED_HEADERS,
+ ReadableWritableEntity.NAME + ":" + search);
+ invoke();
+ }
+
+ /*
+ * @testName: writeIOExceptionUsingWriterTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:281; JAXRS:JAVADOC:304; JAXRS:JAVADOC:87;
+ * JAXRS:JAVADOC:132; JAXRS:JAVADOC:277; JAXRS:JAVADOC:278;
+ *
+ * @test_Strategy: Check EntityWriter is used and IOException is written using
+ * mapper
+ */
+ @Test
+ public void writeIOExceptionUsingWriterTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "writeIOExceptionUsingWriter"));
+ // Depending whether the response has been committed
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+ setProperty(Property.STATUS_CODE,
+ getStatusCode(Status.INTERNAL_SERVER_ERROR));
+ invoke();
+ }
+
+ /*
+ * @testName: writeIOExceptionWithoutWriterTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:304; JAXRS:JAVADOC:281; JAXRS:SPEC:16.2;
+ *
+ * @test_Strategy: Check IOExceptionExceptionMapper is chosen
+ */
+ @Test
+ public void writeIOExceptionWithoutWriterTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "writeIOExceptionWithoutWriter"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+ invoke();
+ }
+
+ /*
+ * @testName: readEntityFromHeaderTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:JAVADOC:138;
+ * JAXRS:JAVADOC:304; JAXRS:JAVADOC:282;
+ *
+ * @test_Strategy: Put entity to header and read it using reader
+ */
+ @Test
+ public void readEntityFromHeaderTest() throws Fault {
+ ReadableWritableEntity entity;
+ entity = new ReadableWritableEntity(EnumProvider.JAXRS.name());
+ String header = ReadableWritableEntity.NAME + ":" + entity.toXmlString();
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST_HEADERS, header);
+ setProperty(Property.REQUEST, buildRequest("POST", "readEntityFromHeader"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: readEntityFromBodyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:JAVADOC:138;
+ * JAXRS:JAVADOC:304; JAXRS:JAVADOC:282;
+ *
+ * @test_Strategy: Put entity to body and read it using reader
+ */
+ @Test
+ public void readEntityFromBodyTest() throws Fault {
+ ReadableWritableEntity entity;
+ entity = new ReadableWritableEntity(EnumProvider.JAXRS.name());
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST, buildRequest("POST", "readEntityFromBody"));
+ setProperty(Property.CONTENT, entity.toXmlString());
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: readEntityIOExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:273; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+ * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272;
+ *
+ * @test_Strategy: Put entity to body and read it using reader
+ */
+ @Test
+ public void readEntityIOExceptionTest() throws Fault {
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest("POST", "readEntityIOException"));
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+ invoke();
+ }
+
+ /*
+ * @testName: readEntityWebException400Test
+ *
+ * @assertion_ids: JAXRS:JAVADOC:274; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+ * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:SPEC:16.2;
+ *
+ * @test_Strategy: Put entity to body and read it using reader
+ */
+ @Test
+ public void readEntityWebException400Test() throws Fault {
+ String code = ReadableWritableEntity.NAME + ":" + Status.BAD_REQUEST.name();
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest("POST", "readEntityWebException"));
+ setProperty(Property.REQUEST_HEADERS, code);
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.BAD_REQUEST));
+ invoke();
+ }
+
+ /*
+ * @testName: readEntityWebException410Test
+ *
+ * @assertion_ids: JAXRS:JAVADOC:274; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+ * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:SPEC:16.2;
+ *
+ * @test_Strategy: Put entity to body and read it using reader
+ */
+ @Test
+ public void readEntityWebException410Test() throws Fault {
+ String code = ReadableWritableEntity.NAME + ":" + Status.GONE.name();
+ setProperty(Property.REQUEST_HEADERS,
+ "Content-Type: " + MediaType.TEXT_XML);
+ setProperty(Property.REQUEST,
+ buildRequest("POST", "readEntityWebException"));
+ setProperty(Property.REQUEST_HEADERS, code);
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.GONE));
+ invoke();
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+
+ protected int getReturnedNumber() throws Fault {
+ HttpResponse response = _testCase.getResponse();
+ String body;
+ try {
+ body = response.getResponseBodyAsString();
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ return Integer.parseInt(body);
+ }
+
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java
new file mode 100644
index 0000000..fb7560b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityAnnotation;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
+
+@Path("ProvidersServlet")
+public class ProvidersServlet extends ApplicationServlet {
+ @Context
+ Providers providers;
+
+ private EnumProvider getEnumProvider(MediaType type) {
+ ContextResolver<EnumProvider> scr = providers
+ .getContextResolver(EnumProvider.class, type);
+ EnumProvider ep = scr.getContext(EnumProvider.class);
+ return ep;
+ }
+
+ Response getResponseByEnumProvider(EnumProvider expected,
+ EnumProvider given) {
+ Status status = Status.NO_CONTENT;
+ if (given != null)
+ status = given != expected ? Status.NOT_ACCEPTABLE : Status.OK;
+ return Response.status(status).build();
+ }
+
+ @GET
+ @Path("isRegisteredContextResolver")
+ public Response isRegisteredContextResolver() {
+ EnumProvider ep = getEnumProvider(MediaType.WILDCARD_TYPE);
+ return getResponseByEnumProvider(EnumProvider.JAXRS, ep);
+ }
+
+ @GET
+ @Path("isRegisteredTextPlainContextResolver")
+ public Response isRegisteredTextPlainContextResolver() {
+ EnumProvider ep = getEnumProvider(MediaType.TEXT_PLAIN_TYPE);
+ return getResponseByEnumProvider(EnumProvider.CTS, ep);
+ }
+
+ @GET
+ @Path("isRegisteredAppJsonContextResolver")
+ public Response isRegisteredAppJsonContextResolver() {
+ EnumProvider ep = getEnumProvider(MediaType.APPLICATION_JSON_TYPE);
+ return getResponseByEnumProvider(EnumProvider.JAXRS, ep);
+ }
+
+ @GET
+ @Path("isRegisteredExceptionMapperRuntimeEx")
+ public Response isRegisteredExceptionMapperRuntimeException() {
+ ExceptionMapper<Exception> em = providers
+ .getExceptionMapper(Exception.class);
+ return em.toResponse(new RuntimeException());
+ }
+
+ @GET
+ @Path("isRegisteredExceptionMapperNullEx")
+ public Response isRegisteredExceptionMapperNullException() {
+ ExceptionMapper<Exception> em = providers
+ .getExceptionMapper(Exception.class);
+ return em.toResponse(null);
+ }
+
+ @GET
+ @Path("isRegisteredRuntimeExceptionMapper")
+ public Response isRegisteredRuntimeExceptionMapper() {
+ ExceptionMapper<RuntimeException> em = providers
+ .getExceptionMapper(RuntimeException.class);
+ Status status = Status.NOT_ACCEPTABLE;
+ if (em != null && AnyExceptionExceptionMapper.class.isInstance(em))
+ status = Status.OK;
+ // This serverError() is to get ResponseBuilder with status != OK
+ return Response.serverError().status(status).build();
+ }
+
+ @GET
+ @Path("isRegisteredIOExceptionMapper")
+ public Response isRegisteredIOExceptionExceptionMapper() {
+ ExceptionMapper<IOException> em = providers
+ .getExceptionMapper(IOException.class);
+ return em.toResponse(new IOException());
+ }
+
+ @GET
+ @Path("isRegisteredMessageReaderWildCard")
+ public Response isRegisteredEntityMessageReaderWildcard() {
+ MessageBodyReader<ReadableWritableEntity> reader;
+ reader = providers.getMessageBodyReader(ReadableWritableEntity.class, null,
+ getArgumentAnnotations("readEntityFromBody"), MediaType.WILDCARD_TYPE);
+ Status status = reader == null ? Status.NOT_ACCEPTABLE : Status.OK;
+ return Response.status(status).build();
+ }
+
+ @GET
+ @Path("isRegisteredMessageReaderXml")
+ public Response isRegisteredEntityMessageReaderXml() {
+ MessageBodyReader<ReadableWritableEntity> reader;
+ reader = providers.getMessageBodyReader(ReadableWritableEntity.class, null,
+ getArgumentAnnotations("readEntityFromBody"), MediaType.TEXT_XML_TYPE);
+ Status status = reader == null ? Status.NOT_ACCEPTABLE : Status.OK;
+ return Response.status(status).build();
+ }
+
+ @GET
+ @Path("isRegisteredWriterWildcard")
+ public Response isRegisteredWriterWildCard() {
+ MessageBodyWriter<ReadableWritableEntity> writer;
+ writer = providers.getMessageBodyWriter(ReadableWritableEntity.class, null,
+ getMethodAnnotations("writeBodyEntityUsingWriter"),
+ MediaType.WILDCARD_TYPE);
+ Status status = writer == null ? Status.NOT_ACCEPTABLE : Status.OK;
+ return Response.status(status).build();
+ }
+
+ @GET
+ @Path("isRegisteredMessageWriterXml")
+ public Response isRegisteredWriterXml() {
+ MessageBodyWriter<ReadableWritableEntity> entity;
+ entity = providers.getMessageBodyWriter(ReadableWritableEntity.class, null,
+ getMethodAnnotations("writeBodyEntityUsingWriter"),
+ MediaType.TEXT_XML_TYPE);
+ Status status = entity == null ? Status.NOT_ACCEPTABLE : Status.OK;
+ return Response.status(status).build();
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_XML)
+ @Path("writeBodyEntityUsingWriter")
+ public Response writeBodyEntityUsingWriter() {
+ ReadableWritableEntity rwe = new ReadableWritableEntity(
+ EnumProvider.JAXRS.name());
+ return Response.ok(rwe).build();
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_XML)
+ @Path("writeHeaderEntityUsingWriter")
+ public Response writeHeaderEntityUsingWriter() {
+ ReadableWritableEntity rwe = new ReadableWritableEntity(
+ EnumProvider.JAXRS.name());
+ return Response.ok(rwe).build();
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_XML)
+ @Path("writeIOExceptionWithoutWriter")
+ public Response writeIOExceptionWithoutWriter() throws IOException {
+ throw new IOException("123 exception");
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_XML)
+ @Path("writeIOExceptionUsingWriter")
+ public Response writeIOExceptionUsingWriter() throws IOException {
+ ReadableWritableEntity rwe = new ReadableWritableEntity("");
+ return Response.ok(rwe).build();
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_XML)
+ @Path("readEntityFromHeader")
+ public Response readEntityFromHeader(
+ @EntityAnnotation("Header") ReadableWritableEntity entity) {
+ Status status = Status.NO_CONTENT;
+ if (entity != null) {
+ boolean b = entity.toString().equals(EnumProvider.JAXRS.name());
+ status = b ? Status.OK : Status.NOT_ACCEPTABLE;
+ }
+ return Response.status(status).build();
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_XML)
+ @Path("readEntityFromBody")
+ public Response readEntityFromBody(
+ @EntityAnnotation("Body") ReadableWritableEntity entity) {
+ Status status = Status.NO_CONTENT;
+ if (entity != null) {
+ boolean b = entity.toString().equals(EnumProvider.JAXRS.name());
+ status = b ? Status.OK : Status.NOT_ACCEPTABLE;
+ }
+ return Response.status(status).build();
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_XML)
+ @Path("readEntityIOException")
+ public Response readEntityIOException(
+ @EntityAnnotation("IOException") ReadableWritableEntity entity) {
+ return Response.ok().build();
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_XML)
+ @Path("readEntityWebException")
+ public Response readEntityWebException(
+ @EntityAnnotation("WebException") ReadableWritableEntity entity) {
+ return Response.ok().build();
+ }
+
+ private Annotation[] getMethodAnnotations(String methodName) {
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods)
+ if (method.getName().equals(methodName))
+ return method.getAnnotations();
+ return null;
+ }
+
+ private Annotation[] getArgumentAnnotations(String methodName) {
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods)
+ if (method.getName().equals(methodName))
+ return method.getParameterAnnotations()[0];
+ return null;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java
new file mode 100644
index 0000000..a2fc9b8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationHolderSingleton;
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumContextResolver;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.TextPlainEnumContextResolver;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.IOExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageReader;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageWriter;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+ @Override
+ public java.util.Set<java.lang.Class<?>> getClasses() {
+ Set<Class<?>> resources = new HashSet<Class<?>>();
+ resources.add(ProvidersServlet.class);
+ resources.add(EnumContextResolver.class);
+ resources.add(ApplicationServlet.class);
+ resources.add(TextPlainEnumContextResolver.class);
+ resources.add(AnyExceptionExceptionMapper.class);
+ resources.add(IOExceptionExceptionMapper.class);
+ resources.add(EntityMessageWriter.class);
+ resources.add(EntityMessageReader.class);
+ return resources;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ Set<Object> singletons = new HashSet<Object>();
+ singletons.add(EnumProvider.CTS);
+ singletons.add(new ReadableWritableEntity(""));
+ singletons.add(new ApplicationHolderSingleton(this));
+ return singletons;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml
new file mode 100644
index 0000000..c08b530
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml
@@ -0,0 +1,29 @@
+<!--
+
+ Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project name="jaxrs_ee_ext_runtime_delegate_common" basedir="." default="usage">
+
+ <import file="../../../../../../../../../../bin/xml/ts.import.xml" />
+
+ <target name="compile">
+ <ant antfile="../../../../api/rs/ext/runtimedelegate/build.xml" useNativeBasedir="true" target="compile" />
+ <ts.javac includes="${pkg.dir}/**/*.java,
+ com/sun/ts/tests/jaxrs/common/*.java" />
+ </target>
+
+</project>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template
new file mode 100644
index 0000000..e125eef
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_CLIENTREQUESTCONTEXT</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_CLIENTREQUESTCONTEXT</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template
new file mode 100644
index 0000000..79cf8d0
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_INVOCATIONBUILDER</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.client.invocationbuilder.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_INVOCATIONBUILDER</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template
new file mode 100644
index 0000000..119e198
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_SYNCINVOKER</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.client.syncinvoker.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_SYNCINVOKER</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template
new file mode 100644
index 0000000..07ea02f
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSAPPSERVLET</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.application.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSAPPSERVLET</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template
new file mode 100644
index 0000000..3ecbaa2
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSConfigurable</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.configurable.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSConfigurable</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template
new file mode 100644
index 0000000..bebac5a
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSConfiguration</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.configurable.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSConfiguration</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template
new file mode 100644
index 0000000..0ca9800
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAX-RSCOREHEADERS</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.headers.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAX-RSCOREHEADERS</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template
new file mode 100644
index 0000000..dcab3cf
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAX-RSRESPONSE</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.response.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAX-RSRESPONSE</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template
new file mode 100644
index 0000000..20b661e
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTS_JAXRS_RESPONSEBUILDER</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.responsebuilder.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTS_JAXRS_RESPONSEBUILDER</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml
new file mode 100644
index 0000000..0e9e638
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 J2EE Application 1.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-application_1_4-0.dtd">
+<sun-application>
+ <web>
+ <web-uri>jaxrs_ee_core_securitycontext_basic_web.war</web-uri>
+ <context-root>jaxrs_ee_core_securitycontext_basic_web</context-root>
+ </web>
+ <unique-id>0</unique-id>
+ <security-role-mapping>
+ <role-name>DIRECTOR</role-name>
+ <principal-name>j2ee</principal-name>
+ </security-role-mapping>
+ <security-role-mapping>
+ <role-name>OTHERROLE</role-name>
+ <principal-name>javajoe</principal-name>
+ </security-role-mapping>
+</sun-application>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
new file mode 100644
index 0000000..5f9a0f3
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 Servlet 2.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-web-app_2_5-0.dtd">
+<sun-web-app>
+ <context-root>jaxrs_ee_core_securitycontext_basic_web</context-root>
+ <security-role-mapping>
+ <role-name>DIRECTOR</role-name>
+ <principal-name>j2ee</principal-name>
+ </security-role-mapping>
+ <security-role-mapping>
+ <role-name>OTHERROLE</role-name>
+ <principal-name>javajoe</principal-name>
+ </security-role-mapping>
+</sun-web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template
new file mode 100644
index 0000000..8b45684
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSSECURITYCONTEXTBASIC</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.securitycontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ <security-role-ref>
+ <role-name>staff</role-name>
+ <role-link>DIRECTOR</role-link>
+ </security-role-ref>
+ <security-role-ref>
+ <role-name>guest</role-name>
+ <role-link>OTHERROLE</role-link>
+ </security-role-ref>
+ </servlet>
+ <security-constraint>
+ <display-name>Servlet</display-name>
+ <web-resource-collection>
+ <web-resource-name>Servlet</web-resource-name>
+ <description></description>
+ <url-pattern>/Servlet/*</url-pattern>
+ <http-method>GET</http-method>
+ <http-method>POST</http-method>
+ <http-method>HEAD</http-method>
+ <http-method>PUT</http-method>
+ </web-resource-collection>
+ <auth-constraint>
+ <description>Have to be a USER</description>
+ <role-name>DIRECTOR</role-name>
+ <role-name>OTHERROLE</role-name>
+ </auth-constraint>
+ <user-data-constraint>
+ <transport-guarantee>NONE</transport-guarantee>
+ </user-data-constraint>
+ </security-constraint>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSSECURITYCONTEXTBASIC</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+ <security-role>
+ <description>director</description>
+ <role-name>DIRECTOR</role-name>
+ </security-role>
+ <security-role>
+ <description>some other role name</description>
+ <role-name>OTHERROLE</role-name>
+ </security-role>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template
new file mode 100644
index 0000000..12132bc
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAX-RSURIINFO</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.core.uriinfo.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAX-RSURIINFO</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..10730d2
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CLIENT_WRITER_INTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CLIENT_WRITER_INTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..4289c5a
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CLIENT_WRITER_WRITERINTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CLIENT_WRITER_WRITERINTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..67a5a61
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CONTAINER_READER_INTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CONTAINER_READER_INTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..d683a97
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CONTAINER_READER_READERINTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CONTAINER_READER_READERINTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..570b1ec
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CONTAINER_WRITER_INTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CONTAINER_WRITER_INTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..7088145
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRS_CONTAINER_WRITER_WRITERINTERCEPTOR</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRS_CONTAINER_WRITER_WRITERINTERCEPTOR</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template
new file mode 100644
index 0000000..605baf7
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSEXTPARAMCONVERTER</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.paramconverter.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSEXTPARAMCONVERTER</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template
new file mode 100644
index 0000000..7a17b02
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+ <servlet>
+ <servlet-name>CTSJAXRSEXTPROVIDERS</servlet-name>
+ <servlet-class>servlet_adaptor</servlet-class>
+ <init-param>
+ <param-name>jakarta.ws.rs.Application</param-name>
+ <param-value>jakarta.ws.rs.tck.ee.rs.ext.providers.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAXRSEXTPROVIDERS</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+</web-app>
diff --git a/jersey-tck/pom.xml b/jersey-tck/pom.xml
index 79dd4f5..8f10525 100644
--- a/jersey-tck/pom.xml
+++ b/jersey-tck/pom.xml
@@ -134,6 +134,10 @@
<webServerHost>localhost</webServerHost>
<webServerPort>8080</webServerPort>
<junit.log.traceflag>true</junit.log.traceflag>
+ <user>j2ee</user>
+ <password>j2ee</password>
+ <authuser>javajoe</authuser>
+ <authpassword>javajoe</authpassword>
<porting.ts.url.class.1>jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL</porting.ts.url.class.1>
</systemPropertyVariables>
<environmentVariables>