TCK Migration: Move first set of REST tck tests from jakartaee-tck (#1002)
* Initial changes lifted directly from jakartaee-tck repo to run com.sun.ts.tests.jaxrs.api.rs.core.responsebuilder tests
jakartaee-tck(source) - > jaxrs-api (target)
src/com/sun/ts/tests/jaxrs/api/rs/core/responsebuilder - > jaxrs-api/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder
src/com/sun/ts/tests/jaxrs/api/rs/core/responseclient - > jaxrs-api/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient
src/com/sun/ts/tests/common/webclient - > jaxrs-api/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient
src.../tests/jaxrs/common -> common
src.../tests/jaxrs/common/util -> common/util
src/com/sun/ts/lib/porting -> lib/porting/
src.../lib/util -> lib/util
src.../tests/servlet/common/util/Data.java -> lib/util/Data.java
* changes to run tck tests at jakarta.ws.rs.tck.api.rs.core.responsebuilder
* files added directly from jakartaee-tck repo to run set of ee tests
* use arquillian to start running tests in ee/rs/core/request/ using gf container
* temp fix to get server tests passing
* address some of the pending issues and review comments
- Use system properties set in jersey-tck/pom.xml (hostname, portnumber, servlet adaptor)
- replace the jersey jars in glassfish bundle used as container, so the server tests are run against the expected jersey jars.
- Bring back Fault class extending Exception that will be thrown if test fails. The original source of Fault class is https://github.com/eclipse-ee4j/jakartaee-tck/blob/master/src/com/sun/ts/lib/harness/EETest.java
- Uncomment one more test in request/JAXRSClientIT (was commented by mistake)
* adress Markus review comments
- fix pom file indentation
- use latest versions of junit-jupiter jars
- use jdk11 version (glassfish 6.1)
- remove arquillian.xml for now
* move glassfish specific jar out of jaxrs tck module
* add junit version range, remove redundant compiler version
* address recent review comments
- set porting.ts.url.class.1 as system variable
- remove commented code
* add more client tests from api.rs.core.uribuilder, improve logging
- added new system variable junit.log.traceflag for logging TestUtil.logTrace,
- printing more logs using TestUtil.logMsg
- added client tests from api.rs.core.uribuilder
* edit web xml template before deployment
- removed the hardcoded web xml string
- move web.xml.template to resources
* Tests at ee/rs/client/asyncinvoker and associated files lifted directly from jakartaee-tck
* fix to run tests at jakarta/ws/rs/tck/ee/rs/client/asyncinvoker
* fix to run the tests in api/rs/core/responseclient (85 tests)
- test files api/rs/core/responseclient were already moved, now enabled them to run
* reverting bad change in previous commit to use wrong jdk version
* disabling 13 failing tests to address later, add jaxrs api jar to glassfish for container tests
diff --git a/jaxrs-tck/pom.xml b/jaxrs-tck/pom.xml
index c7ee0a9..cb39cad 100644
--- a/jaxrs-tck/pom.xml
+++ b/jaxrs-tck/pom.xml
@@ -17,7 +17,8 @@
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jakarta.ws.rs</groupId>
@@ -29,8 +30,9 @@
<url>https://github.com/eclipse-ee4j/jaxrs-api</url>
<properties>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <junit.jupiter.version>[5.7.2, 5.8-A00)</junit.jupiter.version>
</properties>
<organization>
@@ -78,6 +80,20 @@
<tag>HEAD</tag>
</scm>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>3.0.0-M5</version>
+ </plugin>
+
+ </plugins>
+ </build>
+
<dependencies>
<dependency>
<groupId>jakarta.ws.rs</groupId>
@@ -87,8 +103,21 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <version>[5.5.2, 5.6-A00)</version>
+ <artifactId>junit-jupiter</artifactId>
+ <version>${junit.jupiter.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.platform</groupId>
+ <artifactId>junit-platform-launcher</artifactId>
+ <version>1.7.2</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
</dependency>
<dependency>
@@ -96,5 +125,18 @@
<artifactId>hamcrest-library</artifactId>
<version>[2.2, 2.3-A00)</version>
</dependency>
+
+ <dependency>
+ <groupId>org.jboss.arquillian.junit5</groupId>
+ <artifactId>arquillian-junit5-container</artifactId>
+ <version>1.7.0.Alpha10</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jakarta.annotation</groupId>
+ <artifactId>jakarta.annotation-api</artifactId>
+ <version>2.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/rs/core/responsebuilder/BuilderClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder/BuilderClientIT.java
new file mode 100644
index 0000000..caf9d47
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder/BuilderClientIT.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2011, 2021 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.responsebuilder;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.TreeSet;
+
+import jakarta.ws.rs.tck.api.rs.core.responseclient.VerificationResult;
+import jakarta.ws.rs.tck.common.impl.SinglevaluedMap;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.Invocation.Builder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+public class BuilderClientIT
+ extends jakarta.ws.rs.tck.api.rs.core.responseclient.JAXRSClientIT {
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ /*
+ * @testName: statusTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:153; JAXRS:JAVADOC:141;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:125; JAXRS:JAVADOC:124;
+ *
+ * @test_Strategy: Create an instance of ResponseBuilder Response.ok();
+ * Setting status using ResponseBuilder.status(int); verify that correct
+ * status code is returned
+ */
+ @Test
+ public void statusTest1() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+ ResponseBuilder respb = null;
+ for (int status : status_codes) {
+ respb = Response.ok();
+ respb = respb.status(status);
+ resp = respb.build();
+ result.append(verifyStatus(resp, status));
+ }
+ logMsg(result);
+ assertTrue(result.pass);
+ }
+
+ /*
+ * @testName: statusTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:154; JAXRS:JAVADOC:141;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of ResponseBuilder Response.ok();
+ * Setting status using ResponseBuilder.status(Status); verify that correct
+ * status code is returned
+ */
+ @Test
+ public void statusTest2() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+ ResponseBuilder respb = null;
+ for (int i = 0; i < status_codes.length - 1; i++) {
+ respb = Response.ok();
+ respb = respb.status(resp_status[i]);
+ resp = respb.build();
+ result.append(verifyStatus(resp, status_codes[i]));
+ }
+ logMsg(result);
+ assertTrue(result.pass);
+ }
+
+ /*
+ * @testName: expiresTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:147;
+ *
+ * @test_Strategy: Set Expires to ResponseBuilder, build a response and check
+ * expires timestamp.
+ */
+ @Test
+ public void expiresTest() throws Fault {
+ Date now = Calendar.getInstance().getTime();
+ ResponseBuilder rs = Response.ok();
+ rs.expires(now);
+ Response response = rs.build();
+ MultivaluedMap<String, Object> metadata = response.getMetadata();
+ if (metadata == null)
+ fail("No metadata in response");
+ List<Object> expires = response.getMetadata().get("Expires");
+ if (expires == null || expires.isEmpty())
+ fail("No Expires property in metadata");
+ boolean condition = false;
+ Object fetched = expires.iterator().next();
+ if (Date.class.isInstance(fetched))
+ condition = ((Date) fetched).compareTo(now) == 0;
+ else if (String.class.isInstance(fetched))
+ condition = formats(now).contains(fetched.toString());
+ else
+ fail("Fetched object not recognised");
+
+ assertTrue(condition, "Expires value not matched, set: " + now.toString()+
+ "fetched:"+ fetched.toString());
+ logMsg("Set and fetched expire dates matched");
+ }
+
+ /*
+ * @testName: allowStringArrayTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:875;
+ *
+ * @test_Strategy: Set the list of allowed methods for the resource.
+ */
+ @Test
+ public void allowStringArrayTest() throws Fault {
+ String[] methods = { Request.OPTIONS.name(), Request.TRACE.name() };
+ ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+ Response response = rb.allow(methods).build();
+ Set<String> set = response.getAllowedMethods();
+ String responseMethods = JaxrsUtil.iterableToString(" ", set);
+
+ for (String method : methods) {
+ assertContains(responseMethods, method, "Expected allow method", method,
+ "was not found in response allowed methods", responseMethods);
+ logMsg("Found expected allowed method", method);
+ }
+ }
+
+ /*
+ * @testName: allowStringArrayTruncateDuplicatesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:875;
+ *
+ * @test_Strategy: Set the list of allowed methods for the resource.
+ */
+ @Test
+ public void allowStringArrayTruncateDuplicatesTest() throws Fault {
+ String[] methods = { Request.OPTIONS.name(), Request.OPTIONS.name() };
+ ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+ Response response = rb.allow(methods).build();
+ Set<String> set = response.getAllowedMethods();
+ assertEqualsInt(1, set.size(), "Only one allow method should be present");
+ assertEquals(set.iterator().next(), Request.OPTIONS.name(),
+ Request.OPTIONS.name(), "has not been found in allowed methods");
+ logMsg(Request.OPTIONS.name(), "has been found in allowed methods");
+ }
+
+ /*
+ * @testName: allowStringArrayNullRemovesAllTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:875;
+ *
+ * @test_Strategy: if null any existing allowed method list will be removed.
+ */
+ @Test
+ public void allowStringArrayNullRemovesAllTest() throws Fault {
+ String[] methods = { Request.OPTIONS.name(), Request.GET.name() };
+ ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+ Response response = rb.allow(methods).allow((String[]) null).build();
+ Set<String> set = response.getAllowedMethods();
+ assertEqualsInt(0, set.size(), "No one allow method should be present");
+ logMsg("Allowed methods has been removed by null value as expected");
+ }
+
+ /*
+ * @testName: allowStringSetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:876;
+ *
+ * @test_Strategy: Set the list of allowed methods for the resource.
+ */
+ @Test
+ public void allowStringSetTest() throws Fault {
+ Set<String> methods = new TreeSet<String>();
+ methods.add(Request.OPTIONS.name());
+ methods.add(Request.TRACE.name());
+
+ ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+ Response response = rb.allow(methods).build();
+ Set<String> set = response.getAllowedMethods();
+ String responseMethods = JaxrsUtil.iterableToString(" ", set);
+
+ for (String method : methods) {
+ assertContains(responseMethods, method, "Expected allow method", method,
+ "was not found in response allowed methods", responseMethods);
+ logMsg("Found expected allowed method", method);
+ }
+ }
+
+ /*
+ * @testName: allowStringSetNullRemovesAllTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:876;
+ *
+ * @test_Strategy: if null any existing allowed method list will be removed.
+ */
+ @Test
+ public void allowStringSetNullRemovesAllTest() throws Fault {
+ Set<String> methods = new TreeSet<String>();
+ methods.add(Request.OPTIONS.name());
+ methods.add(Request.TRACE.name());
+
+ ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+ Response response = rb.allow(methods).allow((Set<String>) null).build();
+ Set<String> set = response.getAllowedMethods();
+ assertEqualsInt(0, set.size(), "No one allow method should be present");
+ logMsg("Allowed methods has been removed by null value as expected");
+ }
+
+ /*
+ * @testName: encodingTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:878;
+ *
+ * @test_Strategy: Set the message entity content encoding.
+ */
+ @Test
+ public void encodingTest() throws Fault {
+ String[] encodings = { "gzip", "ccitt", "pic" };
+ VerificationResult vr = new VerificationResult();
+ for (String encoding : encodings) {
+ Response response = Response.ok().encoding(encoding).build();
+ vr.append(verifyEncoding(response, Collections.singletonList(encoding)));
+ }
+ logMsg(vr.message);
+ assertTrue(vr.pass);
+ logMsg("Found expected encodings");
+ }
+
+ /*
+ * @testName: linkUriStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:880;
+ *
+ * @test_Strategy: Add a link header.
+ */
+ @Test
+ public void linkUriStringTest() throws Fault {
+ URI uri = null;
+ try {
+ uri = new URI(URL);
+ } catch (URISyntaxException e) {
+ fail(e.getMessage());
+ }
+ String rel = "REL";
+ Response response = Response.ok().link(uri, rel).build();
+ Link link = response.getLink(rel);
+ assertTrue(link != null, "link is null");
+ assertTrue(link.toString().contains(URL), "link"+ link+
+ "does not contain expected"+ URL);
+ logMsg("Found expected link", link);
+ }
+
+ /*
+ * @testName: linkStringStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:881;
+ *
+ * @test_Strategy: Add a link header.
+ */
+ @Test
+ public void linkStringStringTest() throws Fault {
+ String rel = "REL";
+ Response response = Response.ok().link(URL, rel).build();
+ Link link = response.getLink(rel);
+ assertTrue(link != null, "link is null");
+ assertTrue(link.toString().contains(URL), "link"+ link+
+ "does not contain expected"+ URL);
+ logMsg("Found expected link", link);
+ }
+
+ /*
+ * @testName: linksTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:882;
+ *
+ * @test_Strategy: Add one or more link headers.
+ */
+ @Test
+ public void linksTest() throws Fault {
+ String rel = "REL";
+ Link link1 = Link.fromUri(URL).rel(rel + "1").build();
+ Link link11 = Link.fromUri(URL).rel(rel + "11").build();
+ Link link2 = Link.fromUri(URL + "/link2").rel(rel + "2").build();
+
+ Response response = Response.ok().links(link1, link11, link2).build();
+ Link link = response.getLink(rel + "1");
+ assertTrue(link != null, "link is null");
+ assertTrue(link.toString().contains(URL), "link"+ link+
+ "does not contain expected"+ URL);
+ link = response.getLink(rel + "11");
+ assertTrue(link != null, "link is null");
+ assertTrue(link.toString().contains(URL), "link"+ link+
+ "does not contain expected"+ URL);
+ link = response.getLink(rel + "2");
+ assertTrue(link != null, "link is null");
+ assertTrue(link.toString().contains(URL + "/link2"), "link"+ link+
+ "does not contain expected"+ URL + "/link2");
+
+ logMsg("Found expected links");
+ }
+
+ /*
+ * @testName: replaceAllTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:883;
+ *
+ * @test_Strategy: Replaces all existing headers with the newly supplied
+ * headers.
+ */
+ @Test
+ public void replaceAllTest() throws Fault {
+ String[] headers = { "header1", "header2", "header3" };
+ String header99 = "header99";
+ MultivaluedMap<String, Object> mv = new SinglevaluedMap<String, Object>();
+ mv.add(header99, header99);
+ Response response = Response.ok().header(headers[0], headers[0])
+ .header(headers[1], headers[1]).header(headers[2], headers[2])
+ .replaceAll(mv).build();
+ for (String header : headers)
+ assertTrue(response.getHeaderString(header) == null,
+ "response contains non replaced header" + header);
+
+ assertTrue(response.getHeaderString(header99).equals(header99),
+ "response does not contain header from replacedAll map"+ header99);
+ }
+
+ /*
+ * @testName: replaceAllByNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:883;
+ *
+ * @test_Strategy: Replaces all existing headers with the newly supplied
+ * headers. if null all existing headers will be removed.
+ */
+ @Test
+ public void replaceAllByNullTest() throws Fault {
+ String[] headers = { "header1", "header2", "header3" };
+ Response response = Response.ok().header(headers[0], headers[0])
+ .header(headers[1], headers[1]).header(headers[2], headers[2])
+ .replaceAll(null).build();
+ for (String header : headers)
+ assertTrue(response.getHeaderString(header) == null,
+ "response contains non replaced header"+ header);
+ }
+
+ /*
+ * @testName: variantsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:884;
+ *
+ * @test_Strategy: Add a Vary header that lists the available variants.
+ */
+ @Test
+ public void variantsTest() throws Fault {
+ List<String> encoding = Arrays.asList("gzip", "compress");
+ List<String> vars = Arrays.asList(HttpHeaders.ACCEPT_LANGUAGE,
+ HttpHeaders.ACCEPT_ENCODING);
+ MediaType mt = MediaType.APPLICATION_JSON_TYPE;
+ ResponseBuilder rb = Response.ok();
+ rb = rb.variants(getVariantList(encoding, mt).toArray(new Variant[0]));
+ Response response = rb.build();
+ VerificationResult result = new VerificationResult();
+ result.append(verifyVary(response, vars));
+ logMsg(result.message);
+ assertTrue(result.pass);
+ }
+
+ // //////////////////////////////////////////////////////////////////
+
+ private static String formats(Date date) {
+ DateFormat format;
+ TestUtil.logMsg("Creating possible string format list");
+ StringBuilder sb = new StringBuilder();
+ for (String tz : TimeZone.getAvailableIDs()) {
+ format = JaxrsUtil.createDateFormat(TimeZone.getTimeZone(tz));
+ sb.append(format.format(date));
+ }
+ return sb.toString();
+ }
+
+ protected Invocation.Builder invocation() {
+ Client client = ClientBuilder.newClient();
+ WebTarget target = client.target(URL);
+ Builder b = target.request();
+ return b;
+ }
+
+ static final String URL = "http://localhost:888/noUrl";
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java
new file mode 100644
index 0000000..00ebe0b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java
@@ -0,0 +1,2565 @@
+/*
+ * Copyright (c) 2007, 2021 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.responseclient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+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.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.GenericEntity;
+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 jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = -2343034378084516380L;
+
+ // name it to ensure sorting
+ protected final Response.Status[] resp_status = { Response.Status.OK,
+ Response.Status.CREATED, Response.Status.ACCEPTED,
+ Response.Status.NO_CONTENT, Response.Status.RESET_CONTENT,
+ Response.Status.PARTIAL_CONTENT, Response.Status.MOVED_PERMANENTLY,
+ Response.Status.FOUND, Response.Status.SEE_OTHER,
+ Response.Status.NOT_MODIFIED, Response.Status.USE_PROXY,
+ Response.Status.TEMPORARY_REDIRECT, Response.Status.BAD_REQUEST,
+ Response.Status.UNAUTHORIZED, Response.Status.PAYMENT_REQUIRED,
+ Response.Status.FORBIDDEN, Response.Status.NOT_FOUND,
+ Response.Status.METHOD_NOT_ALLOWED, Response.Status.NOT_ACCEPTABLE,
+ Response.Status.PROXY_AUTHENTICATION_REQUIRED,
+ Response.Status.REQUEST_TIMEOUT, Response.Status.CONFLICT,
+ Response.Status.GONE, Response.Status.LENGTH_REQUIRED,
+ Response.Status.PRECONDITION_FAILED,
+ Response.Status.REQUEST_ENTITY_TOO_LARGE,
+ Response.Status.REQUEST_URI_TOO_LONG,
+ Response.Status.UNSUPPORTED_MEDIA_TYPE,
+ Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE,
+ Response.Status.EXPECTATION_FAILED, Response.Status.PRECONDITION_REQUIRED,
+ Response.Status.TOO_MANY_REQUESTS,
+ Response.Status.REQUEST_HEADER_FIELDS_TOO_LARGE,
+ Response.Status.INTERNAL_SERVER_ERROR, Response.Status.NOT_IMPLEMENTED,
+ Response.Status.BAD_GATEWAY, Response.Status.SERVICE_UNAVAILABLE,
+ Response.Status.GATEWAY_TIMEOUT,
+ Response.Status.HTTP_VERSION_NOT_SUPPORTED,
+ Response.Status.NETWORK_AUTHENTICATION_REQUIRED };
+
+ // name it to ensure sorting
+ protected final int[] status_codes = { 200, 201, 202, 204, 205, 206, 301, 302,
+ 303, 304, 305, 307, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410,
+ 411, 412, 413, 414, 415, 416, 417, 428, 429, 431, 500, 501, 502, 503, 504,
+ 505, 511 };
+
+ // name it to ensure sorting
+ protected final Response.Status.Family[] status_family = {
+ Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+ Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+ Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+ Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+ Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+ Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.SERVER_ERROR,
+ Response.Status.Family.SERVER_ERROR, Response.Status.Family.SERVER_ERROR,
+ Response.Status.Family.SERVER_ERROR, Response.Status.Family.SERVER_ERROR,
+ Response.Status.Family.SERVER_ERROR,
+ Response.Status.Family.SERVER_ERROR };
+
+ protected final Response.Status.Family[] status_family_list = {
+ Response.Status.Family.CLIENT_ERROR, Response.Status.Family.INFORMATIONAL,
+ Response.Status.Family.OTHER, Response.Status.Family.REDIRECTION,
+ Response.Status.Family.SERVER_ERROR, Response.Status.Family.SUCCESSFUL };
+
+ protected final String[] status = { "OK", "Created", "Accepted", "No Content",
+ "Reset Content", "Partial Content", "Moved Permanently", "Found",
+ "See Other", "Not Modified", "Use Proxy", "Temporary Redirect",
+ "Bad Request", "Unauthorized", "Payment Required", "Forbidden",
+ "Not Found", "Method Not Allowed", "Not Acceptable",
+ "Proxy Authentication Required", "Request Timeout", "Conflict", "Gone",
+ "Length Required", "Precondition Failed", "Request Entity Too Large",
+ "Request-URI Too Long", "Unsupported Media Type",
+ "Requested Range Not Satisfiable", "Expectation Failed",
+ "Precondition Required", "Too Many Requests",
+ "Request Header Fields Too Large", "Internal Server Error",
+ "Not Implemented", "Bad Gateway", "Service Unavailable",
+ "Gateway Timeout", "HTTP Version Not Supported",
+ "Network Authentication Required" };
+
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ /*
+ * @class.setup_props: webServerHost; webServerPort;
+ */
+ /* Run test */
+
+ /*
+ * @testName: okTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using Response.ok().build()
+ * verify that correct status code is returned
+ */
+ @Test
+ public void okTest1() throws Fault {
+ VerificationResult result;
+ Response response = null;
+ int status = 200;
+ response = Response.ok().build();
+ result = verifyStatus(response, status);
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: okTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:132; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ok(String).build() verify that correct status code is returned
+ */
+ @Test
+ public void okTest2() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 200;
+ String content = "Test only";
+ resp = Response.ok(content).build();
+ result = verifyContent(resp, content);
+ result.append(verifyStatus(resp, status));
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: okTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:134; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using Response.ok(String,
+ * String).build() verify that correct status code is returned
+ */
+ @Test
+ public void okTest3() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 200;
+ String content = "Test only";
+ String type = MediaType.TEXT_PLAIN;
+ resp = Response.ok(content, type).build();
+ result = verifyContent(resp, content);
+ result.append(verifyStatus(resp, status));
+ result.append(verifyContentType(resp, Collections.singletonList(type)));
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: okTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:133; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using Response.ok(String,
+ * MediaType).build() verify that correct status code is returned
+ */
+ @Test
+ public void okTest4() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 200;
+ String content = "Test only";
+ String type = MediaType.TEXT_PLAIN;
+ MediaType mt = new MediaType(MediaType.TEXT_PLAIN_TYPE.getType(),
+ MediaType.TEXT_PLAIN_TYPE.getSubtype());
+ resp = Response.ok(content, mt).build();
+ result = verifyContent(resp, content);
+ result.append(verifyStatus(resp, status));
+ result.append(verifyContentType(resp, Collections.singletonList(type)));
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: okTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:135; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:91; JAXRS:JAVADOC:268;
+ * JAXRS:JAVADOC:267; JAXRS:JAVADOC:266; JAXRS:JAVADOC:265; JAXRS:JAVADOC:263;
+ * JAXRS:JAVADOC:264;
+ *
+ * @test_Strategy: Create an instance of Response using Response.ok(String,
+ * Variant).build() verify that correct status code is returned
+ */
+ @Test
+ public void okTest5() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+ int status = 200;
+ String content = "Test Only";
+ List<String> encoding = Arrays.asList("gzip", "compress");
+
+ MediaType mt = new MediaType("text", "plain");
+ List<Variant> vts = getVariantList(encoding, mt);
+
+ for (int i = 0; i < vts.size(); i++) {
+ Variant vt = vts.get(i);
+ resp = Response.ok(content, vt).build();
+ result.append(verifyContent(resp, content));
+ result.append(verifyStatus(resp, status));
+ result.append(verifyEncoding(resp, encoding));
+ result.append(verifyLanguage(resp, getLangList()));
+ result.append(
+ verifyContentType(resp, Collections.singletonList(mt.toString())));
+ }
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: noContentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:126; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.noContent().build() verify that correct status code is returned
+ */
+ @Test
+ public void noContentTest() throws Fault {
+ VerificationResult result;
+
+ Response resp = null;
+ int status = 204;
+
+ resp = Response.noContent().build();
+ result = verifyStatus(resp, status);
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: notAcceptableTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:127; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:91; JAXRS:JAVADOC:268;
+ * JAXRS:JAVADOC:267; JAXRS:JAVADOC:266; JAXRS:JAVADOC:265; JAXRS:JAVADOC:263;
+ * JAXRS:JAVADOC:264;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.notAcceptable(vts).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void notAcceptableTest() throws Fault {
+ VerificationResult result;
+
+ Response resp = null;
+ int status = 406;
+
+ List<String> encoding = Arrays.asList("gzip", "compress");
+
+ MediaType mt = new MediaType("text", "plain");
+ List<Variant> vts = getVariantList(encoding, mt);
+
+ resp = Response.notAcceptable(vts).build();
+ result = verifyStatus(resp, status);
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: notModifiedTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:128; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.notModified().build() verify that correct status code is returned
+ */
+ @Test
+ public void notModifiedTest1() throws Fault {
+ VerificationResult result;
+
+ Response resp = null;
+ int status = 304;
+ resp = Response.notModified().build();
+
+ result = verifyStatus(resp, status);
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: notModifiedTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:130; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.notModified(String).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void notModifiedTest2() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 304;
+ String tags = "TestOnly";
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("ETAG", tags);
+
+ resp = Response.notModified(tags).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: notModifiedTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:129; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.notModified(EntityTag).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void notModifiedTest3() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 304;
+ String value = "TestOnly";
+
+ EntityTag et = new EntityTag(value);
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("ETAG", value);
+
+ resp = Response.notModified(et).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:123; JAXRS:JAVADOC:124;
+ * JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(int).build() verify that correct status code is returned
+ */
+ @Test
+ public void statusTest1() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+
+ for (int status : status_codes) {
+ resp = Response.status(status).build();
+ result.append(verifyStatus(resp, status));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:138; JAXRS:JAVADOC:123; JAXRS:JAVADOC:124;
+ * JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(Response.Status).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void statusTest2() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+
+ for (int i = 0; i < status_codes.length; i++) {
+ resp = Response.status(resp_status[i]).build();
+ result.append(verifyStatus(resp, status_codes[i]));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:131; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.status(int).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void statusTest3() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+
+ for (int status : status_codes) {
+ resp = Response.ok().status(status).build();
+ result.append(verifyStatus(resp, status));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:138; JAXRS:JAVADOC:131; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.status(Response.Status).build() verify that
+ * correct status code is returned
+ */
+ @Test
+ public void statusTest4() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+
+ for (int i = 0; i < status_codes.length; i++) {
+ resp = Response.ok().status(resp_status[i]).build();
+ result.append(verifyStatus(resp, status_codes[i]));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: createdTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:121; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.created(URI).build() verify that correct status code is returned
+ */
+ @Test
+ public void createdTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+ "news:comp.lang.java", "urn:isbn:096139210x",
+ "http://java.sun.com/j2se/1.3/",
+ "docs/guide/collections/designfaq.html#28",
+ "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+ URI test_uri = null;
+ for (String uri_string : uri_expected) {
+ try {
+ test_uri = new URI(uri_string);
+ } catch (URISyntaxException ex) {
+ result.message.append("Unexpected exception thrown:")
+ .append(ex.getMessage());
+ result.pass = false;
+ }
+ Response resp = Response.created(test_uri).build();
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Location", uri_string);
+ result.append(verifyStatus(resp, 201));
+ result.append(verifyHeaders(resp, expected_map));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: serverErrorTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:137; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.serverError().build() verify that correct status code is returned
+ */
+ @Test
+ public void serverErrorTest() throws Fault {
+ VerificationResult result;
+
+ Response resp = Response.serverError().build();
+ result = verifyStatus(resp, 500);
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: seeOtherTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:136; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.seeOther(URI).build() verify that correct status code is returned
+ */
+ @Test
+ public void seeOtherTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ URI test_uri = null;
+ try {
+ test_uri = new URI("http://java.sun.com/j2se/1.3/");
+ } catch (URISyntaxException ex) {
+ result.message.append("Unexpected exception thrown:")
+ .append(ex.getMessage());
+ result.pass = false;
+ }
+ Response resp = Response.seeOther(test_uri).build();
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Location", "http://java.sun.com/j2se/1.3/");
+ result.append(verifyStatus(resp, 303));
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: temporaryRedirectTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:140; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.temporaryRedirect(URI).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void temporaryRedirectTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ URI test_uri = null;
+ try {
+ test_uri = new URI("http://java.sun.com/j2se/1.3/");
+ } catch (URISyntaxException ex) {
+ result.message.append("Unexpected exception thrown:")
+ .append(ex.getMessage());
+ result.pass = false;
+ }
+ Response resp = Response.temporaryRedirect(test_uri).build();
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Location", "http://java.sun.com/j2se/1.3/");
+ result.append(verifyStatus(resp, 307));
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: fromResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:122; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+ * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.fromResponse(Response).build() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void fromResponseTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ int status = 200;
+ String content = "Test Only";
+ List<String> type = Arrays.asList("text/plain", "text/html");
+ List<String> encoding = Arrays.asList("gzip", "compress");
+
+ MediaType mt1 = new MediaType("text", "plain");
+ MediaType mt2 = new MediaType("text", "html");
+ List<Variant> vts = getVariantList(encoding, mt1, mt2);
+
+ for (int i = 0; i < vts.size(); i++) {
+ Variant vt = vts.get(i);
+ Response resp1 = Response.ok(content, vt).build();
+ Response resp = Response.fromResponse(resp1).build();
+ result.append(verifyContent(resp, content));
+ result.append(verifyStatus(resp, status));
+ result.append(verifyEncoding(resp, encoding));
+ result.append(verifyLanguage(resp, getLangList()));
+ result.append(verifyContentType(resp, type));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: entityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:146;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.entity(String).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void entityTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ int status = 200;
+ String content = "Test Only";
+
+ Response resp = Response.status(status).entity(content).build();
+ result.append(verifyContent(resp, content));
+ result.append(verifyStatus(resp, status));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: languageTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:149;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.language(String).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void languageTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+
+ int status = 200;
+ List<String> lang = getLangList();
+
+ for (String language : lang) {
+ Response resp = Response.status(status).language(language).build();
+ result.append(verifyStatus(resp, status));
+ result.append(verifyLanguage(resp, lang));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: languageTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:150;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.language(Locale).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void languageTest1() throws Fault {
+ VerificationResult result = new VerificationResult();
+ int status = 200;
+
+ for (String language : getLangList()) {
+ Response resp = Response.status(status).language(language).build();
+ result.append(verifyStatus(resp, status));
+ result.append(verifyLanguage(resp, Arrays.asList(language)));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: typeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:158;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.type(String).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void typeTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ int status = 200;
+ String type = MediaType.TEXT_PLAIN;
+
+ Response resp = Response.status(status).type(type).build();
+ result.append(verifyStatus(resp, status));
+ result.append(verifyContentType(resp, Arrays.asList(type)));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: typeTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:157;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.type(MediaType).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void typeTest1() throws Fault {
+ VerificationResult result;
+
+ int status = 200;
+ List<String> types = Arrays.asList("text/plain", "text/html");
+
+ MediaType mt1 = new MediaType("text", "plain");
+ MediaType mt2 = new MediaType("text", "html");
+
+ Response resp = Response.status(status).type(mt1).type(mt2).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyContentType(resp, types));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: tagTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:156;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.tag(String).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void tagTest1() throws Fault {
+ VerificationResult result;
+
+ int status = 200;
+ String tag = "TestOnly";
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("ETAG", tag);
+
+ Response resp = Response.status(status).tag(tag).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: tagTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:155;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.tag(EntityTag).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void tagTest2() throws Fault {
+ VerificationResult result;
+ int status = 200;
+ EntityTag et1 = new EntityTag("StrongEntityTagTest", true);
+ EntityTag et2 = new EntityTag("TestOnly", false);
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("ETAG", "TestOnly");
+
+ Response resp = Response.status(status).tag(et1).tag(et2).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: variantTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:159;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(int).variant(Variant).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void variantTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response resp = null;
+ int status = 200;
+ List<String> encoding = Arrays.asList("gzip", "compress");
+
+ MediaType mt = new MediaType("text", "plain");
+ List<Variant> vts = getVariantList(encoding, mt);
+
+ for (int i = 0; i < vts.size(); i++) {
+ Variant vt = vts.get(i);
+ resp = Response.status(status).variant(vt).build();
+ verifyStatus(resp, status);
+ verifyEncoding(resp, encoding);
+ verifyLanguage(resp, getLangList());
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: variantsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:160;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(int).variants(List<Variant>).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void variantsTest() throws Fault {
+ VerificationResult result;
+ Response resp = null;
+ int status = 200;
+ // String type = "text/plain";
+ List<String> encoding = Arrays.asList("gzip", "compress");
+ List<String> vars = Arrays.asList("accept-language", "accept-encoding");
+
+ MediaType mt = new MediaType("text", "plain");
+ List<Variant> vts = getVariantList(encoding, mt);
+ resp = Response.status(status).variants(vts).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyVary(resp, vars));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: locationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:152;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(status).location(URI).build() verify that correct status
+ * code is returned
+ */
+ @Test
+ public void locationTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ int status = 200;
+ List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+ "news:comp.lang.java", "urn:isbn:096139210x",
+ "http://java.sun.com/j2se/1.3/",
+ "docs/guide/collections/designfaq.html#28",
+ "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+ URI test_uri = null;
+ for (String uri_string : uri_expected) {
+ try {
+ test_uri = new URI(uri_string);
+ } catch (URISyntaxException ex) {
+ result.message.append("Unexpected exception thrown:")
+ .append(ex.getMessage());
+ result.pass = false;
+ }
+ Response resp = Response.status(status).location(test_uri).build();
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Location", uri_string);
+ result.append(verifyStatus(resp, status));
+ result.append(verifyHeaders(resp, expected_map));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: contentLocationTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:144;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.status(status).contentLocation(URI).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void contentLocationTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ int status = 200;
+ List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+ "news:comp.lang.java", "urn:isbn:096139210x",
+ "http://java.sun.com/j2se/1.3/",
+ "docs/guide/collections/designfaq.html#28",
+ "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+ URI test_uri = null;
+ for (String uri_string : uri_expected) {
+ try {
+ test_uri = new URI(uri_string);
+ } catch (URISyntaxException ex) {
+ result.message.append("Unexpected exception thrown:")
+ .append(ex.getMessage());
+ result.pass = false;
+ }
+ Response resp = Response.status(status).contentLocation(test_uri).build();
+
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Content-Location", uri_string);
+ result.append(verifyStatus(resp, 200));
+ result.append(verifyHeaders(resp, expected_map));
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: cacheControlTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:142;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.cacheControl(String).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void cacheControlTest() throws Fault {
+ VerificationResult result;
+ int status = 200;
+ boolean nostore = true;
+
+ CacheControl ccl4 = new CacheControl();
+ ccl4.setNoStore(nostore);
+
+ List<String> ccl = Arrays.asList("no-store", "no-transform");
+
+ Response resp = Response.status(status).cacheControl(ccl4).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyCacheControl(resp, ccl));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: cookieTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:145;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.cookie(NewCookie).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void cookieTest() throws Fault {
+ VerificationResult result;
+ int status = 200;
+
+ String name = "name_1";
+ String value = "value_1";
+ // int maxage = jakarta.ws.rs.core.NewCookie.DEFAULT_MAX_AGE;
+
+ Cookie ck1 = new Cookie(name, value);
+ NewCookie nck1 = new NewCookie(ck1);
+
+ name = "name_2";
+ value = "value_2";
+ String path = "/acme";
+ String domain = "";
+
+ Cookie ck2 = new Cookie(name, value, path, domain);
+ NewCookie nck2 = new NewCookie(ck2);
+
+ name = "name_3";
+ value = "value_3";
+ path = "";
+ domain = "y.x.foo.com";
+
+ Cookie ck3 = new Cookie(name, value, path, domain);
+ NewCookie nck3 = new NewCookie(ck3);
+
+ List<String> cookies = Arrays.asList(nck1.toString().toLowerCase(),
+ nck2.toString().toLowerCase(), nck3.toString().toLowerCase());
+
+ Response resp = Response.status(status).cookie(nck1, nck2, nck3).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyCookies(resp, cookies));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: lastModifiedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:151;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.lastModified(Date).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void lastModifiedTest() throws Fault {
+ VerificationResult result;
+ int status = 200;
+ long dt = 123456789;
+ Date date = new Date(dt);
+ HashMap<String, String> expected_map = new HashMap<String, String>();
+ expected_map.put("Last-Modified", "123456789");
+
+ Response resp = Response.status(status).lastModified(date).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyHeaders(resp, expected_map));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: headerTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:148;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:97;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.header(String, Object).build() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void headerTest() throws Fault {
+ VerificationResult result;
+ int status = 200;
+ List<String> type = Arrays.asList("text/plain", "text/html");
+ List<String> encoding = Arrays.asList("gzip", "compress");
+
+ String name = "name_1";
+ String value = "value_1";
+ Cookie ck1 = new Cookie(name, value);
+ NewCookie nck1 = new NewCookie(ck1);
+
+ List<String> cookies = Arrays.asList(nck1.toString().toLowerCase());
+
+ Response resp = Response.status(status)
+ .header(HttpHeaders.CONTENT_ENCODING, encoding.get(0))
+ .header(HttpHeaders.CONTENT_ENCODING, encoding.get(1))
+ .header("Content-Language", "en-US").header("Content-Language", "en-GB")
+ .header("Content-Language", "zh-CN")
+ .header("Cache-Control", "no-transform")
+ .header("Set-Cookie", "name_1=value_1;version=1")
+ .header(HttpHeaders.CONTENT_TYPE, type.get(0))
+ .header(HttpHeaders.CONTENT_TYPE, type.get(1)).build();
+ result = verifyStatus(resp, status);
+ result.append(verifyEncoding(resp, encoding));
+ result.append(verifyLanguage(resp, getLangList()));
+ result.append(verifyContentType(resp, type));
+ result.append(verifyCookies(resp, cookies));
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: cloneTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:143;
+ * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+ *
+ * @test_Strategy: Create an instance of Response using
+ * Response.ResponseBuilder.clone() verify that correct status code is
+ * returned
+ */
+ @Test
+ public void cloneTest() throws Fault {
+ VerificationResult result;
+ int status = 200;
+ List<String> type = Arrays.asList("text/plain", "text/html");
+ List<String> encoding = Arrays.asList("gzip");
+ List<String> lang = getLangList();
+
+ String name = "name_1";
+ String value = "value_1";
+ Cookie ck1 = new Cookie(name, value);
+ NewCookie nck1 = new NewCookie(ck1);
+
+ List<String> cookies = Arrays.asList(nck1.toString().toLowerCase());
+
+ Response.ResponseBuilder respb1 = Response.status(status)
+ .header("Content-type", "text/plain")
+ .header("Content-type", "text/html").header("Content-Language", "en-US")
+ .header("Content-Language", "en-GB").header("Content-Language", "zh-CN")
+ .header("Cache-Control", "no-transform")
+ .header("Set-Cookie", "name_1=value_1;version=1")
+ .header(HttpHeaders.CONTENT_ENCODING, "gzip");
+ Response.ResponseBuilder respb2;
+ respb2 = respb1.clone();
+
+ Response resp2 = respb2.build();
+ result = verifyStatus(resp2, status);
+ result.append(verifyEncoding(resp2, encoding));
+ result.append(verifyLanguage(resp2, lang));
+ result.append(verifyContentType(resp2, type));
+ result.append(verifyCookies(resp2, cookies));
+
+ String content = "TestOnly";
+ Response resp1 = respb1.entity(content).cookie((NewCookie[]) null).build();
+ result.append(verifyContent(resp1, content));
+ result.append(verifyStatus(resp1, status));
+ result.append(verifyEncoding(resp1, encoding));
+ result.append(verifyLanguage(resp1, lang));
+ result.append(verifyContentType(resp1, type));
+
+ MultivaluedMap<java.lang.String, java.lang.Object> mvp = resp1
+ .getMetadata();
+ if (mvp.containsKey("Set-Cookie")) {
+ result.pass = false;
+ result.message.append("Response contains unexpected Set-Cookie: ")
+ .append(mvp.getFirst("Set-Cookie").toString()).append(newline);
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:161;
+ *
+ * @test_Strategy: Call Response.Status.fromStatusCode(int) verify that
+ * correct Response.Status is returned
+ */
+ @Test
+ public void statusTest5() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response.Status tmp = null;
+
+ for (int i = 0; i < status_codes.length; i++) {
+ tmp = Response.Status.fromStatusCode(status_codes[i]);
+
+ if (tmp != resp_status[i]) {
+ result.pass = false;
+ result.message.append("fromStatusCode[").append(status_codes[i])
+ .append("] failed with ").append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: getFamilyTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:162;
+ *
+ * @test_Strategy: Call Response.Status.getFamily() verify that correct
+ * Response.Status.Family is returned
+ */
+ @Test
+ public void getFamilyTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response.Status.Family tmp = null;
+
+ assertTrue(status_family.length == Response.Status.values().length,
+ "Response.Status.values() are unexpected");
+
+ for (int i = 0; i < status_family.length; i++) {
+ tmp = resp_status[i].getFamily();
+
+ if (tmp != status_family[i]) {
+ result.pass = false;
+ result.message.append("getFamily failed with ").append(resp_status[i])
+ .append(" ").append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusTest7
+ *
+ * @assertion_ids: JAXRS:JAVADOC:163;
+ *
+ * @test_Strategy: Call Response.Status.getStatusCode() verify that correct
+ * status code is returned
+ */
+ @Test
+ public void statusTest7() throws Fault {
+ VerificationResult result = new VerificationResult();
+ int tmp = 0;
+
+ for (int i = 0; i < status_codes.length; i++) {
+ tmp = resp_status[i].getStatusCode();
+
+ if (tmp != status_codes[i]) {
+ result.pass = false;
+ result.message.append("getStatusCode() failed with ")
+ .append(resp_status[i]).append(newline);
+ result.message.append("expecting ").append(status_codes[i])
+ .append(", got ").append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: toStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:164;
+ *
+ * @test_Strategy: Call Response.Status.toString() verify that correct reason
+ * phase is returned
+ */
+ @Test
+ public void toStringTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ String tmp = null;
+
+ for (int i = 0; i < resp_status.length; i++) {
+ tmp = resp_status[i].toString();
+
+ if (!tmp.equals(status[i])) {
+ result.pass = false;
+ result.message.append("Status.toString() failed with ")
+ .append(resp_status[i]).append(newline);
+ result.message.append("expecting ").append(status[i]).append(", got ")
+ .append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: getReasonPhraseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:301; JAXRS:JAVADOC:166;
+ *
+ * @test_Strategy: Call Response.Status.getReasonPhrase() verify that correct
+ * reason phase is returned
+ */
+ @Test
+ public void getReasonPhraseTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ String tmp = null;
+
+ assertTrue(status.length == Response.Status.values().length,
+ "Response.Status.values() are unexpected");
+
+ for (int i = 0; i < resp_status.length; i++) {
+ tmp = resp_status[i].getReasonPhrase();
+
+ if (!tmp.equals(status[i])) {
+ result.pass = false;
+ result.message.append("Status.toString() failed with ")
+ .append(resp_status[i]).append(newline);
+ result.message.append("expecting ").append(status[i]).append(", got ")
+ .append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusValueOfTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:165; JAXRS:JAVADOC:166;
+ *
+ * @test_Strategy: Call Response.Status.valueOf(String) verify that correct
+ * Status is returned
+ */
+ @Test
+ public void statusValueOfTest() throws Fault {
+ VerificationResult result = new VerificationResult();
+ Response.Status tmp = null;
+ for (int i = 0; i < resp_status.length; i++) {
+ try {
+ tmp = Response.Status.valueOf(
+ status[i].replace(" ", "_").replace("-", "_").toUpperCase());
+ } catch (Exception ex) {
+ result.message.append("Exception thrown with status name ")
+ .append(status[i]).append(newline);
+ result.message.append(ex.getMessage());
+ result.pass = false;
+ }
+ if (!tmp.equals(resp_status[i])) {
+ result.pass = false;
+ result.message.append("Status.toString() failed with ")
+ .append(resp_status[i]).append(newline);
+ result.message.append("expecting ").append(resp_status[i])
+ .append(", got ").append(tmp).append(newline);
+ }
+ }
+ logMsg(result);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: statusFamilyValueOfTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:167; JAXRS:JAVADOC:168;
+ *
+ * @test_Strategy: Call Response.Status.Family.valueOf() verify that correct
+ * Family is returned
+ */
+ @Test
+ public void statusFamilyValueOfTest() throws Fault {
+ Response.Status.Family[] families = Response.Status.Family.values();
+ assertTrue(families.length == status_family_list.length,
+ "Response.Status.Family.values() are unexpected");
+ Arrays.sort(status_family_list);
+ for (int i = 0; i != families.length; i++) {
+ int match = Arrays.binarySearch(status_family_list,
+ Response.Status.Family.valueOf(families[i].name()));
+ assertTrue(match != -1, "Unknown Response Status Family"+ families[i]);
+ }
+ }
+
+ /*
+ * @testName: statusFamilyValuesTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:168;
+ *
+ * @test_Strategy: Call Response.Status.Family.values() verify that correct
+ * Family is returned
+ */
+ @Test
+ public void statusFamilyValuesTest() throws Fault {
+ Response.Status.Family[] families = Response.Status.Family.values();
+ assertTrue(families.length == status_family_list.length,
+ "Response.Status.Family.values() are unexpected");
+ Arrays.sort(status_family_list);
+ for (int i = 0; i != families.length; i++) {
+ int match = Arrays.binarySearch(status_family_list, families[i]);
+ assertTrue(match != -1, "Unknown Resposne Status Family"+ families[i]);
+ }
+ }
+
+ /*
+ * @testName: acceptedNoArgTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:836;
+ *
+ * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status.
+ */
+ @Test
+ public void acceptedNoArgTest() throws Fault {
+ VerificationResult result;
+ Response response = null;
+ response = Response.accepted().build();
+ result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: acceptedStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:837;
+ *
+ * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status that
+ * contains a representation. It is the callers responsibility to wrap the
+ * actual entity with GenericEntity if preservation of its generic type is
+ * required.
+ */
+ @Test
+ public void acceptedStringTest() throws Fault {
+ VerificationResult result;
+ String entity = "ENtiTy";
+ Response response = null;
+ response = Response.accepted(entity).build();
+ result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+ result.append(verifyContent(response, entity));
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: acceptedGenericEntityTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:837;
+ *
+ * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status that
+ * contains a representation. It is the callers responsibility to wrap the
+ * actual entity with GenericEntity if preservation of its generic type is
+ * required.
+ */
+ @Test
+ public void acceptedGenericEntityTest() throws Fault {
+ VerificationResult result;
+ String entity = "ENtiTy";
+ GenericEntity<String> generic = new GenericEntity<String>(entity,
+ String.class);
+ Response response = Response.accepted(generic).build();
+ result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+ result.append(verifyContent(response, entity));
+ logMsg(result.message);
+ assertResultTrue(result);
+ }
+
+ /*
+ * @testName: bufferEntityIgnoreNoBackingStreamTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:838;
+ *
+ * @test_Strategy: In case the response entity instance is not backed by an
+ * unconsumed input stream an invocation of bufferEntity method is ignored and
+ * the method returns false.
+ */
+ @Test
+ public void bufferEntityIgnoreNoBackingStreamTest() throws Fault {
+ Response response = Response.ok().build();
+ boolean result = response.bufferEntity();
+ assertTrue(!result, "#bufferEntity() did not ignore no backing stream");
+ logMsg("#bufferEntity did ignore no backing stream 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 = Response.ok().build();
+ response.close();
+ try {
+ response.bufferEntity();
+ fault("buffer entity did not throw IllegalStateException when closed");
+ } catch (IllegalStateException e) {
+ logMsg("#bufferEntity throws IllegalStateException 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 {
+ Response response = Response.ok()
+ .header(HttpHeaders.ALLOW, Request.POST.name())
+ .header(HttpHeaders.ALLOW, Request.TRACE.name()).build();
+ 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 {
+ NewCookie cookie1 = new NewCookie("c1", "v1");
+ NewCookie cookie2 = new NewCookie("c2", "v2");
+ List<String> cookies = Arrays.asList(cookie1.toString().toLowerCase(),
+ cookie2.toString().toLowerCase());
+ Response response = Response.ok().cookie(cookie1).cookie(cookie2).build();
+ // verifyCookies style test
+ VerificationResult result = verifyCookies(response, cookies);
+ logMsg(result);
+ assertResultTrue(result);
+ // getCookies test
+ Map<String, NewCookie> map = response.getCookies();
+ for (Entry<String, NewCookie> entry : map.entrySet())
+ if (entry.getKey().equals("c1"))
+ assertTrue(entry.getValue().equals(cookie1), cookie1.toString()+
+ "not match"+ entry.getValue());
+ else if (entry.getKey().equals("c2"))
+ assertTrue(entry.getValue().equals(cookie2), cookie2.toString()+
+ "not match"+ entry.getValue());
+ else
+ assertTrue(false, "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 cookie1 = new NewCookie("c1", "v1");
+ NewCookie cookie2 = new NewCookie("c2", "v2");
+ Response response = Response.ok().cookie(cookie1).build();
+ // getCookies test
+ Map<String, NewCookie> map;
+ try {
+ map = response.getCookies();
+ map.put("c2", cookie2);
+ } catch (Exception e) {
+ // can throw an exception or nothing or return a copy map
+ }
+ map = response.getCookies();
+ assertTrue(!map.containsKey("c2"), "getCookies is not read-only returned"+
+ map.get("c2"));
+ 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 {
+ Date date = Calendar.getInstance().getTime();
+ Response response = Response.ok().header("Date", date).build();
+
+ Date responseDate = response.getDate();
+ assertTrue(date.equals(responseDate), "Original date"+ date+
+ "and response#getDate()"+ responseDate+ "differs");
+ logMsg("#getDate matches the Date HTTP header");
+ }
+
+ /*
+ * @testName: getDateNotPresentTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:845;
+ *
+ * @test_Strategy: Get null if not present.
+ */
+ @Test
+ public void getDateNotPresentTest() throws Fault {
+ Response response = Response.ok().build();
+ Date responseDate = response.getDate();
+ assertTrue(responseDate == null, "response#getDate() should be null, was"+
+ responseDate);
+ logMsg("#getDate is null as expected");
+ }
+
+ /*
+ * @testName: getEntityThrowsIllegalStateExceptionTest
+ *
+ * @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 getEntityThrowsIllegalStateExceptionTest() throws Fault {
+ Response response = Response.ok("entity").build();
+ response.close();
+ try {
+ response.getEntity();
+ fault("No exception has been thrown");
+ } 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 {
+ EntityTag tag = new EntityTag("getEntityTag");
+ Response response = Response.notModified(tag).build();
+ EntityTag responseTag = response.getEntityTag();
+ assertTrue(tag.equals(responseTag), "response#getEntityTag()"+ responseTag+
+ "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 {
+ Response response = Response.ok().build();
+ EntityTag responseTag = response.getEntityTag();
+ assertTrue(responseTag == null,
+ "response#getEntityTag() should be null, was"+ responseTag);
+ logMsg("#getEntityTag() is null as expected");
+ }
+
+ /*
+ * @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 {
+ CacheControl ccl = new CacheControl();
+ NewCookie cookie = new NewCookie("cookie", "eikooc");
+ String encoding = "gzip";
+ Date date = Calendar.getInstance().getTime();
+
+ Response response = Response.ok().cacheControl(ccl).cookie(cookie)
+ .encoding(encoding).expires(date).language(Locale.CANADA_FRENCH)
+ .build();
+ 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: 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 = Response.ok().build();
+ 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 {
+ CacheControl ccl = new CacheControl();
+ ccl.setNoStore(true);
+ NewCookie cookie = new NewCookie("cookie", "eikooc");
+ String encoding = "gzip";
+ Date date = Calendar.getInstance().getTime();
+
+ Response response = Response.ok().cacheControl(ccl).cookie(cookie)
+ .encoding(encoding).expires(date).language(Locale.CANADA_FRENCH)
+ .build();
+ logMsg("Found following objects:");
+ logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+ assertContainsIgnoreCase(
+ response.getHeaderString(HttpHeaders.CACHE_CONTROL), "no-store",
+ "Cache-Control:no-store has not been found");
+ 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 {
+ StringBean bean = new StringBean("s3");
+ RuntimeDelegate original = RuntimeDelegate.getInstance();
+ RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+ try {
+ Response response = Response.ok().header(bean.get(), bean).build();
+ String header = response.getHeaderString(bean.get());
+ assertContainsIgnoreCase(header, bean.get(), "Header", bean.get(),
+ "has unexpected value", header);
+ logMsg("HeaderDelegate is used for header", bean.get());
+ } finally {
+ RuntimeDelegate.setInstance(original);
+ StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+ }
+ }
+
+ /*
+ * @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 {
+ StringBuilder builder = new StringBuilder("s1");
+ StringBuffer buffer = new StringBuffer("s2");
+ Response response = Response.ok().header(builder.toString(), builder)
+ .header(buffer.toString(), buffer).build();
+ String header = response.getHeaderString(builder.toString());
+ assertContainsIgnoreCase(header, builder.toString(), "Header", builder,
+ "has unexpected value", header);
+
+ header = response.getHeaderString(buffer.toString());
+ assertContainsIgnoreCase(header, buffer.toString(), "Header", builder,
+ "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 = Response.ok().language(Locale.CANADA_FRENCH).build();
+ 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 {
+ Response response = Response.ok().build();
+ Locale locale = response.getLanguage();
+ assertTrue(locale == null, "response#getLanguage() should be null, was"+
+ locale);
+ logMsg("#getLanguage() is null as expected");
+ }
+
+ /*
+ * @testName: getLastModifiedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:851;
+ *
+ * @test_Strategy: Get the last modified date.
+ */
+ @Test
+ public void getLastModifiedTest() throws Fault {
+ Date date = Calendar.getInstance().getTime();
+ Response response = Response.ok().lastModified(date).build();
+ Date responseDate = response.getLastModified();
+ assertTrue(date.equals(responseDate), "Last Modified date"+ date+
+ "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 {
+ Response response = Response.ok().build();
+ Date responseDate = response.getLastModified();
+ assertTrue(responseDate == null,
+ "response#getLastModified() should be null, was"+ responseDate);
+ logMsg("#getLastModified() is null as expected");
+ }
+
+ /*
+ * @testName: getLengthTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:852;
+ *
+ * @test_Strategy: Get Content-Length value.
+ */
+ @Test
+ public void getLengthTest() throws Fault {
+ Response response = Response.ok("1234567890")
+ .header(HttpHeaders.CONTENT_LENGTH, "10").build();
+ 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 = Response.ok().build();
+ int len = response.getLength();
+ assertTrue(len == -1, "Expected Content-Length = -1"+
+ "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 {
+ Link link = createLink("path", "getLinkTest");
+ Response response = Response.ok().links(link).build();
+ Link responseLink = response.getLink("getLinkTest");
+ assertTrue(link.equals(responseLink),
+ "#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 {
+ Response response = Response.ok().build();
+ Link responseLink = response.getLink("getLinkTest");
+ assertTrue(responseLink == null, "#getLink() returned unexpected Link"+
+ responseLink);
+ logMsg("#getLink return null as expected");
+ }
+
+ /*
+ * @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 = Response.ok().link("http://abc.com/b/", rel).build();
+ Link builderLink = response.getLinkBuilder("anyrelation").build();
+ response = Response.ok().links(builderLink).build();
+ Link responseLink = response.getLink("anyrelation");
+ 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 = Response.ok().build();
+ Builder builder = response.getLinkBuilder("anyrelation");
+ assertTrue(builder == null,
+ "#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 {
+ Link link1 = createLink("path1", "rel1");
+ Link link2 = createLink("path2", "rel2");
+ Response response = Response.ok().links(link1, link2).build();
+ Set<Link> responseLinks = response.getLinks();
+ assertEqualsInt(responseLinks.size(), 2,
+ "#getLinks() returned set of unexpected size", responseLinks.size());
+ assertTrue(responseLinks.contains(link1), "#getLinks does not contain"+
+ link1);
+ assertTrue(responseLinks.contains(link2), "#getLinks does not contain"+
+ link2);
+ 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 = Response.ok().build();
+ 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 {
+ URI location = createUri("path");
+ Response response = Response.ok().location(location).build();
+ URI responseLocation = response.getLocation();
+ assertTrue(responseLocation.equals(location), "#getLocation()"+
+ responseLocation+ "differs from expected"+ location);
+ 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 {
+ Response response = Response.ok().build();
+ URI responseLocation = response.getLocation();
+ assertTrue(responseLocation == null, "#getLocation()"+ responseLocation+
+ "should be null");
+ logMsg("#getLocation returns null as expected");
+ }
+
+ /*
+ * @testName: getMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:857;
+ *
+ * @test_Strategy: Get the media type of the message entity.
+ */
+ @Test
+ public void getMediaTypeTest() throws Fault {
+ Response response = Response.ok().type(MediaType.APPLICATION_ATOM_XML)
+ .build();
+ MediaType responseMedia = response.getMediaType();
+ assertTrue(MediaType.APPLICATION_ATOM_XML_TYPE.equals(responseMedia),
+ "#getMediaType()"+ responseMedia+ "differs from expected"+
+ MediaType.APPLICATION_ATOM_XML);
+ logMsg("#getMediaType returned expected MediaType");
+ }
+
+ /*
+ * @testName: getMediaTypeNoMediaTypeTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:857;
+ *
+ * @test_Strategy: null if there is no response entity.
+ */
+ @Test
+ public void getMediaTypeNoMediaTypeTest() throws Fault {
+ Response response = Response.ok().build();
+ MediaType responseMedia = response.getMediaType();
+ assertTrue(responseMedia == null, "#getMediaType()"+ responseMedia+
+ "should be null");
+ logMsg("#getMediaType returned null as expected");
+ }
+
+ /*
+ * @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()) {
+ Response response = Response.status(status).build();
+ StatusType info = response.getStatusInfo();
+ assertTrue(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 {
+ RuntimeDelegate original = RuntimeDelegate.getInstance();
+ RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+ try {
+ StringBuilder builder = new StringBuilder("s1");
+ StringBuffer buffer = new StringBuffer("s2");
+ StringBean bean = new StringBean("s3");
+ Response response = Response.ok().header(builder.toString(), builder)
+ .header(buffer.toString(), buffer).header(bean.get(), bean).build();
+ MultivaluedMap<String, String> headers = response.getStringHeaders();
+ String header = headers.getFirst(builder.toString());
+ assertContainsIgnoreCase(header, builder.toString(), "Header", builder,
+ "has unexpected value", header);
+
+ header = headers.getFirst(buffer.toString());
+ assertContainsIgnoreCase(header, buffer.toString(), "Header", builder,
+ "has unexpected value", header);
+
+ logMsg("#getStringHeaders contains expected values",
+ JaxrsUtil.iterableToString(",", headers.entrySet()));
+ } finally {
+ RuntimeDelegate.setInstance(original);
+ StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+ }
+ }
+
+ /*
+ * @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 {
+ RuntimeDelegate original = RuntimeDelegate.getInstance();
+ RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+ try {
+ StringBuilder builder = new StringBuilder("s1");
+ StringBuffer buffer = new StringBuffer("s2");
+ StringBean bean = new StringBean("s3");
+ Response response = Response.ok().header(builder.toString(), builder)
+ .header(buffer.toString(), buffer).header(bean.get(), bean).build();
+ MultivaluedMap<String, String> headers = response.getStringHeaders();
+ String header = headers.getFirst(bean.get());
+ assertContainsIgnoreCase(bean.get(), header, "Header", bean.get(),
+ "has unexpected value", header);
+
+ logMsg("#getStringHeaders contains expected values",
+ JaxrsUtil.iterableToString(",", headers.entrySet()));
+ } finally {
+ RuntimeDelegate.setInstance(original);
+ StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+ }
+ }
+
+ /*
+ * @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 = Response.ok("entity").build();
+ 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 = Response.ok().build();
+ assertTrue(!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 = Response.ok().build();
+ 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 {
+ Link link = createLink("path", "rel");
+ Response response = Response.ok().links(link).build();
+ assertTrue(response.hasLink("rel"), "#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 = Response.ok().build();
+ assertTrue(!response.hasLink("rel"), "#has Link did found some Link");
+ logMsg("#hasLink has not found any Link as expected");
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+
+ protected VerificationResult verifyContent(Response response,
+ String content) {
+ VerificationResult result = new VerificationResult();
+ if ((content == null) || (content == "")) {
+ if (!(response.getEntity() == null)
+ || (response.getEntity().equals(""))) {
+ result.pass = false;
+ result.message.append(indent)
+ .append("Entity verification failed: expecting no content, got ")
+ .append(response.getEntity()).append(newline);
+ }
+ } else if (!content.equals(response.getEntity())) {
+ result.pass = false;
+ result.message.append(indent)
+ .append("Entity verification failed: expecting ").append(content)
+ .append(", got ").append(response.getEntity()).append(newline);
+ } else {
+ result.message.append(indent)
+ .append("Correct content found in Response: ")
+ .append(response.getEntity()).append(newline);
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyStatus(Response response, int status) {
+ VerificationResult result = new VerificationResult();
+ if (response.getStatus() != status) {
+ result.pass = false;
+ result.message.append(indent)
+ .append("Status code verification failed: expecting ").append(status)
+ .append(", got ").append(response.getStatus()).append(newline);
+ } else {
+ result.message.append(indent).append("Correct status found in Response: ")
+ .append(status).append(newline);
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyHeaders(Response response,
+ HashMap<String, String> expected) {
+ MultivaluedMap<java.lang.String, java.lang.Object> headers = response
+ .getMetadata();
+ VerificationResult result = new VerificationResult();
+ result.message.append("========== Verifying a Response with Map: ")
+ .append(newline);
+ for (String key_actual : headers.keySet()) {
+ result.message.append(indent).append("Response contains key: ")
+ .append(key_actual).append(newline);
+ }
+ result.message.append(indent)
+ .append("Verifying the following keys in Response:").append(newline);
+ String actual;
+
+ for (Entry<String, String> entry : expected.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+
+ if (!headers.containsKey(key)) {
+ result.pass = false;
+ result.message.append(indent).append(indent).append("Key: ").append(key)
+ .append(" is not found in Response;").append(newline);
+ } else if (key.equalsIgnoreCase("last-modified")) {
+ result.message.append(indent).append(indent)
+ .append("Key Last-Modified is found in response").append(newline);
+ } else {
+ actual = headers.getFirst(key).toString().toLowerCase();
+
+ if (actual.startsWith("\"") && actual.endsWith("\""))
+ actual = actual.substring(1, actual.length() - 1);
+
+ if (!actual.equalsIgnoreCase(value)) {
+ result.pass = false;
+ result.message.append(indent).append(indent);
+ result.message.append("Key: ").append(key);
+ result.message.append(" found in Response, but with different value;")
+ .append(newline);
+ result.message.append(indent).append(indent).append("Expecting ")
+ .append(value).append("; got ").append(headers.getFirst(key))
+ .append(newline);
+ }
+ result.message.append(indent).append(indent).append("Processed key ")
+ .append(key).append(" with expected value ").append(value)
+ .append(newline);
+ }
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyEncoding(Response response,
+ List<String> encoding) {
+ VerificationResult result = new VerificationResult();
+ List<Object> enc = response.getHeaders().get(HttpHeaders.CONTENT_ENCODING);
+ if (enc == null) {
+ result.pass = false;
+ result.message.append(HttpHeaders.CONTENT_ENCODING)
+ .append(" headers is null").append(newline);
+ result.message.append("Headers :").append(response.getHeaders())
+ .append(newline);
+ } else
+ for (Object e : enc)
+ if (!encoding.contains(e.toString().toLowerCase())) {
+ result.pass = false;
+ result.message.append(indent).append(indent).append("Encoding ")
+ .append(e).append(" was not found in headers")
+ .append(response.getHeaders()).append(newline);
+ } else
+ result.message.append(indent).append("Encoding ").append(e)
+ .append(" was found").append(newline);
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyLanguage(Response response,
+ List<String> languages) {
+ VerificationResult result = new VerificationResult();
+ List<Object> responseLangs = response.getHeaders()
+ .get(HttpHeaders.CONTENT_LANGUAGE); // one only
+ if (responseLangs == null) {
+ result.pass = false;
+ result.message.append(HttpHeaders.CONTENT_LANGUAGE)
+ .append(" headers is null").append(newline);
+ result.message.append("Headers :").append(response.getHeaders())
+ .append(newline);
+ } else {
+ String lang = langToString(JaxrsUtil.iterableToString(" ", languages))
+ .toLowerCase();
+ for (Object responseLang : responseLangs)
+ if (!lang.contains(langToString(responseLang).toLowerCase())) {
+ result.pass = false;
+ result.message.append(indent).append(indent)
+ .append("language test failed: ").append(responseLang)
+ .append(" is not expected in Response")
+ .append(response.getHeaders()).append(newline);
+ for (String tt : languages) {
+ result.message.append(indent).append(indent)
+ .append("Expecting Content-Language ").append(tt)
+ .append(newline);
+ }
+ } else
+ result.message.append(indent).append("Content Language ").append(lang)
+ .append(" was found").append(newline);
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyContentType(Response response,
+ List<String> type) {
+ VerificationResult result = new VerificationResult();
+ List<Object> enc = response.getHeaders().get(HttpHeaders.CONTENT_TYPE);
+ if (enc == null) {
+ result.pass = false;
+ result.message.append(HttpHeaders.CONTENT_TYPE).append(" headers is null")
+ .append(newline);
+ result.message.append("Headers :").append(response.getHeaders())
+ .append(newline);
+ } else
+ for (Object e : enc)
+ if (!type.contains(e.toString().toLowerCase())) {
+ result.pass = false;
+ result.message.append(indent).append(indent).append("Content-Type ")
+ .append(e).append(" was not found in headers")
+ .append(response.getHeaders()).append(newline);
+ } else
+ result.message.append(indent).append("Content Type ").append(e)
+ .append(" was found").append(newline);
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyVary(Response response, List<String> var) {
+ VerificationResult result = new VerificationResult();
+ if (var != null)
+ for (Entry<String, List<Object>> entry : response.getMetadata()
+ .entrySet())
+ if (entry.getKey().equalsIgnoreCase("Vary"))
+ for (String value : var) {
+ String actual = entry.getValue().toString().toLowerCase();
+ if (actual.indexOf(value.toLowerCase()) < 0) {
+ result.pass = false;
+ result.message.append(indent).append(indent)
+ .append("Expected header ").append(value)
+ .append(" not set in Vary.").append(newline);
+ } else {
+ result.message.append(indent).append(indent)
+ .append("Found expected header ").append(value).append(".")
+ .append(newline);
+ }
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyCacheControl(Response response,
+ List<String> ccl) {
+ VerificationResult result = new VerificationResult();
+ if (ccl != null) {
+ for (String tt : ccl)
+ result.message.append("Expecting Cache-Control ").append(tt)
+ .append(newline);
+ for (Entry<String, List<Object>> entry : response.getMetadata()
+ .entrySet())
+ if (entry.getKey().equalsIgnoreCase("Cache-Control"))
+ for (Object all_ccl : entry.getValue())
+ for (String cc : ccl)
+ if (!(all_ccl.toString().toLowerCase()
+ .indexOf(cc.toLowerCase()) > -1)) {
+ result.pass = false;
+ result.message.append(indent).append(indent)
+ .append("Cache-Control test failed: ").append(cc)
+ .append(" is not found in Response.").append(newline);
+ }
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected VerificationResult verifyCookies(Response response,
+ List<String> cookies) {
+ VerificationResult result = new VerificationResult();
+ if (cookies != null) {
+ for (String tt : cookies)
+ result.message.append(indent).append(indent)
+ .append("Expecting Set-Cookie").append(tt).append(newline);
+ for (Entry<String, List<Object>> entry : response.getMetadata()
+ .entrySet()) {
+ if (entry.getKey().equalsIgnoreCase("Set-Cookie"))
+ for (Object nck_actual : entry.getValue()) {
+ result.message.append(indent).append(indent).append("Processing ")
+ .append(nck_actual.toString()).append(newline);
+ if (!cookies.contains(
+ nck_actual.toString().toLowerCase().replace(" ", ""))) {
+ result.pass = false;
+ result.message.append(indent).append(indent)
+ .append("Set-Cookie test failed: ").append(nck_actual)
+ .append(" is not expected in Response.").append(newline);
+ } else {
+ result.message.append(indent).append(indent)
+ .append("Expected Set-Cookie: ").append(nck_actual)
+ .append(" is found in Response.").append(newline);
+ }
+ }
+ }
+ }
+ result.message.append(newline);
+ return result;
+ }
+
+ protected static void assertResultTrue(VerificationResult result) {
+ assertTrue(result.pass, "At least one assertion failed");
+ }
+
+ protected static List<String> getLangList() {
+ return Arrays.asList("en-US", "en-GB", "zh-CN");
+ }
+
+ protected static List<Variant> getVariantList(List<String> encoding,
+ MediaType... mt) {
+ return Variant.VariantListBuilder.newInstance().mediaTypes(mt)
+ .languages(new Locale("en", "US"), new Locale("en", "GB"),
+ new Locale("zh", "CN"))
+ .encodings(encoding.toArray(new String[0])).add().build();
+ }
+
+ protected static 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 static Link createLink(String path, String rel) throws Fault {
+ return Link.fromUri(createUri(path)).rel(rel).build();
+ }
+
+ protected static URI createUri(String path) throws Fault {
+ URI uri;
+ try {
+ uri = new URI("http://localhost.tck:888/url404/" + path);
+ } catch (URISyntaxException e) {
+ throw new Fault(e);
+ }
+ return uri;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java
new file mode 100644
index 0000000..c2fb11a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2021 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.responseclient;
+
+/**
+ * Verification holder structure
+ */
+public class VerificationResult {
+ public boolean pass;
+
+ public StringBuilder message;
+
+ public VerificationResult() {
+ pass = true;
+ message = new StringBuilder();
+ }
+
+ public VerificationResult(VerificationResult result) {
+ this.pass = result.pass;
+ this.message = new StringBuilder().append(message);
+ }
+
+ public VerificationResult append(VerificationResult result) {
+ this.pass &= result.pass;
+ this.message.append(result.message).append("\n");
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return message.toString();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..32e02c0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java
@@ -0,0 +1,3338 @@
+/*
+ * Copyright (c) 2007, 2021 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.uribuilder;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.UriBuilderException;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = 1814450070599603168L;
+
+ private static final String LOCALHOST = "http://localhost:8080";
+
+ private static final String EXPECTED_PATH = "path-rootless/test2/x%25yz//path-absolute/test1/fred@example.com/x%25yz";
+
+ private static final String ENCODED_EXPECTED_PATH = "path-rootless%2Ftest2/x%25yz/%2Fpath-absolute%2F%2525test1/fred@example.com/x%25yz";
+
+ StringBuilder sb;
+
+ boolean pass = true;
+
+ URI uri;
+
+ public JAXRSClientIT() {
+ setContextRoot("/jaxrs_rs.core_uribuilder_web");
+ pass = true;
+ sb = new StringBuilder();
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ /*
+ * @testName: buildTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+ *
+ * @test_Strategy: Create an Uri instance using
+ * UriBuilder.fromPath(String).build(String)
+ */
+ @Test
+ public void buildTest1() throws Fault {
+ String value = "test1#test2";
+ String expected_value = "test1%23test2";
+
+ try {
+ uri = UriBuilder.fromPath("{arg1}").build(value);
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:177;
+ *
+ * @test_Strategy: Create an Uri instance using
+ * UriBuilder.fromPath(String).build(null); Verify that
+ * IllegalArgumentException is thrown.
+ */
+ @Test
+ public void buildTest2() throws Fault {
+ String value = null;
+
+ try {
+ UriBuilder.fromPath("{arg1}").build(value);
+ pass = false;
+ sb.append("Expected IllegalArgumentException not thrown" + newline);
+
+ } catch (IllegalArgumentException ilex) {
+ sb.append("Expected IllegalArgumentException thrown");
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fragmentTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:189; JAXRS:JAVADOC:190;
+ *
+ * @test_Strategy: Create an Uri instance using
+ * UriBuilder.fromPath(String).fragment(String).build()
+ */
+ @Test
+ public void fragmentTest1() throws Fault {
+ String expected_value = "test#xyz";
+
+ try {
+ uri = UriBuilder.fromPath("test").fragment("xyz").build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromMapTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:185;
+ *
+ * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+ * Verify % is encoded; and all parameter are replaced by values supplied in
+ * Map.
+ */
+ @Test
+ public void buildFromMapTest1() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/%25test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+
+ try {
+ uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+ .buildFromMap(maps);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromMapTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:185;
+ *
+ * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+ * Verify % is encoded; and all parameter are replaced by values supplied in
+ * Map.
+ */
+ @Test
+ public void buildFromMapTest2() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/%25test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+ .buildFromMap(maps);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+
+ /*
+ * @testName: buildFromMapTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:185;
+ *
+ * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+ * Verify IllegalArgumentException is thrown when one parameter value is null.
+ */
+ @Test
+ public void buildFromMapTest3() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", null);
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}").buildFromMap(maps);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ex) {
+ TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+ }
+ }
+
+ /*
+ * @testName: buildFromMapTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:185;
+ *
+ * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+ * Verify IllegalArgumentException is thrown when one parameter value is null.
+ */
+ @Test
+ public void buildFromMapTest4() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ UriBuilder.fromPath("").path("{w}/{v}/{x}/{y}/{z}/{x}")
+ .buildFromMap(maps);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ex) {
+ TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+ }
+ }
+
+ /*
+ * @testName: buildFromMapTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:185;
+ *
+ * @test_Strategy: Create multiple URI instances from the same UriBuilder
+ * instance using the UriBuilder.buildFromMap(Map); Verify that the builder is
+ * not affected.
+ */
+ @Test
+ public void buildFromMapTest5() throws Fault {
+ UriBuilder ub;
+
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/%25test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+
+ Map<String, String> maps1 = new HashMap<String, String>();
+ maps1.put("x", "x%20yz");
+ maps1.put("y", "/path-absolute/test1");
+ maps1.put("z", "fred@example.com");
+ maps1.put("w", "path-rootless/test2");
+
+ Map<String, String> maps2 = new HashMap<String, String>();
+ maps2.put("x", "x%yz");
+ maps2.put("y", "/path-absolute/%25test1");
+ maps2.put("z", "fred@example.com");
+ maps2.put("w", "path-rootless/test2");
+ maps2.put("v", "xyz");
+
+ String expected_path_1 = "path-rootless%2Ftest2/x%2520yz/%2Fpath-absolute%2Ftest1/fred@example.com/x%2520yz";
+
+ try {
+ ub = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+
+ uri = ub.buildFromMap(maps);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+
+ uri = ub.buildFromMap(maps1);
+ gotExpectedPass(uri.getRawPath(), expected_path_1);
+
+ uri = ub.buildFromMap(maps2);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ } catch (Throwable ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromEncodedMapTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:182;
+ *
+ * @test_Strategy: Create an URI instance using
+ * UriBuilder.buildFromEncodedMap(Map); Verify % is encoded when needed; and
+ * all parameter are replaced by values supplied in Map.
+ */
+ @Test
+ public void buildFromEncodedMapTest1() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%20yz");
+ maps.put("y", "/path-absolute/%test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+
+ String expected_path = "path-rootless/test2/x%20yz//path-absolute/%25test1/fred@example.com/x%20yz";
+
+ try {
+ uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncodedMap(maps);
+ gotExpectedPass(uri.getRawPath(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromEncodedMapTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:182;
+ *
+ * @test_Strategy: Create an URI instance using
+ * UriBuilder.buildFromEncodedMap(Map); Verify % is encoded; and all parameter
+ * are replaced by values supplied in Map.
+ */
+ @Test
+ public void buildFromEncodedMapTest2() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncodedMap(maps);
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromEncodedMapTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:183;
+ *
+ * @test_Strategy: Create an URI instance using
+ * UriBuilder.buildFromEncodedMap(Map); Verify IllegalArgumentException is
+ * thrown when one parameter value is null.
+ */
+ @Test
+ public void buildFromEncodedMapTest3() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", null);
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncodedMap(maps);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ex) {
+ TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+ }
+ }
+
+ /*
+ * @testName: buildFromEncodedMapTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:183;
+ *
+ * @test_Strategy: Create an URI instance using
+ * UriBuilder.buildFromEncodedMap(Map); Verify IllegalArgumentException is
+ * thrown when one parameter value is null.
+ */
+ @Test
+ public void buildFromEncodedMapTest4() throws Fault {
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+ maps.put("u", "extra");
+
+ try {
+ UriBuilder.fromPath("").path("{w}/{v}/{x}/{y}/{z}/{x}")
+ .buildFromEncodedMap(maps);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ex) {
+ TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+ }
+ }
+
+ /*
+ * @testName: buildFromEncodedMapTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:182;
+ *
+ * @test_Strategy: Create multiple URI instances from the same UriBuilder
+ * instance using the UriBuilder.buildFromEncodedMap(Map); Verify that the
+ * builder is not affected.
+ */
+ @Test
+ public void buildFromEncodedMapTest5() throws Fault {
+ UriBuilder ub;
+
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+
+ Map<String, String> maps1 = new HashMap<String, String>();
+ maps1.put("x", "x%20yz");
+ maps1.put("y", "/path-absolute/test1");
+ maps1.put("z", "fred@example.com");
+ maps1.put("w", "path-rootless/test2");
+
+ Map<String, String> maps2 = new HashMap<String, String>();
+ maps2.put("x", "x%yz");
+ maps2.put("y", "/path-absolute/test1");
+ maps2.put("z", "fred@example.com");
+ maps2.put("w", "path-rootless/test2");
+ maps2.put("v", "xyz");
+
+ String expected_path_1 = "path-rootless/test2/x%20yz//path-absolute/test1/fred@example.com/x%20yz";
+
+ try {
+ ub = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+
+ uri = ub.buildFromEncodedMap(maps);
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+
+ uri = ub.buildFromEncodedMap(maps1);
+ gotExpectedPass(uri.getRawPath(), expected_path_1);
+
+ uri = ub.buildFromEncodedMap(maps2);
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+ } catch (Throwable ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fromPathTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String)
+ */
+ @Test
+ public void fromPathTest1() throws Fault {
+ String[] paths = { "/", "", "/path-absolute/test1", "fred@example.com",
+ "path-rootless/test2" };
+
+ int j = 0;
+ while (j < paths.length) {
+ try {
+ uri = UriBuilder.fromPath(paths[j]).build();
+ gotExpectedPass(uri.getPath(), paths[j]);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+ j++;
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fromPathTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:191;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(null) Verify that IllegalArgumentException is thrown.
+ */
+ @Test
+ public void fromPathTest2() throws Fault {
+ String path = null;
+
+ try {
+ UriBuilder.fromPath(path);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ilex) {
+ }
+ }
+
+ /*
+ * @testName: fromResourceTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:192;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromResource(null) Verify that IllegalArgumentException is
+ * thrown.
+ */
+ @Test
+ public void fromResourceTest1() throws Fault {
+ Class<?> res = null;
+
+ try {
+ UriBuilder.fromResource(res);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ilex) {
+ }
+ }
+
+ /*
+ * @testName: fromResourceTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:192;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromResource(Class) Verify that Uri can be built from it with
+ * correct path.
+ */
+ @Test
+ public void fromResourceTest2() throws Fault {
+ Class<?> res = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String expected_path = "/TestPath";
+
+ try {
+ uri = UriBuilder.fromResource(res).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fromUriTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:194;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri((URI)null) Verify that IllegalArgumentException is
+ * thrown.
+ */
+ @Test
+ public void fromUriTest1() throws Fault {
+ try {
+ UriBuilder.fromUri(uri);
+
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ilex) {
+ }
+ }
+
+ /*
+ * @testName: fromUriTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:196;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri((String)null) Verify that IllegalArgumentException is
+ * thrown.
+ */
+ @Test
+ public void fromUriTest2() throws Fault {
+ String uri = null;
+
+ try {
+ UriBuilder.fromUri(uri);
+ throw new Fault(
+ "Test Failed: expected IllegalArgumentException not thrown");
+ } catch (IllegalArgumentException ilex) {
+ }
+ }
+
+ /*
+ * @testName: fromUriTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:196;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri(String)
+ */
+ @Test
+ public void fromUriTest3() throws Fault {
+ String[] uris = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+ "mailto:java-net@java.sun.com", "news:comp.lang.java",
+ "urn:isbn:096139210x", "http://www.ietf.org/rfc/rfc2396.txt",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+ "telnet://192.0.2.16:80/",
+ "foo://example.com:8042/over/there?name=ferret#nose" };
+
+ int j = 0;
+ while (j < 9) {
+ try {
+ uri = UriBuilder.fromUri(uris[j]).build();
+ gotExpectedPass(uri.toString().trim(), uris[j]);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+ j++;
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fromUriTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:194;
+ *
+ * @test_Strategy: Create an UriBuilder instance using UriBuilder.fromUri(URI)
+ */
+ @Test
+ public void fromUriTest4() throws Fault {
+ String[] uris = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+ "mailto:java-net@java.sun.com", "news:comp.lang.java",
+ "urn:isbn:096139210x", "http://www.ietf.org/rfc/rfc2396.txt",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+ "telnet://192.0.2.16:80/",
+ "foo://example.com:8042/over/there?name=ferret#nose" };
+
+ int j = 0;
+ while (j < 9) {
+ try {
+ uri = UriBuilder.fromUri(new URI(uris[j])).build();
+ gotExpectedPass(uri.toString().trim(), uris[j]);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+ j++;
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:202;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path("/TestPath"), Verify that "/TestPath" is
+ * appended as specified
+ */
+ @Test
+ public void pathTest() throws Fault {
+ String path = "test1#test2";
+ String path1 = "/TestPath";
+ String expected_path = "test1%23test2/TestPath";
+
+ try {
+ URI uri = UriBuilder.fromPath(path).path(path1).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest0
+ *
+ * @assertion_ids: JAXRS:JAVADOC:202;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path("TestPath"), Verify that "TestPath" is
+ * appended as specified
+ */
+ @Test
+ public void pathTest0() throws Fault {
+ String path = "test1#test2";
+ String path1 = "TestPath";
+ String expected_path = "test1%23test2/TestPath";
+
+ try {
+ URI uri = UriBuilder.fromPath(path).path(path1).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:202;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(String null), Verify that
+ * IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest1() throws Fault {
+ String path = "test1#test2";
+ String path1 = null;
+
+ try {
+ UriBuilder.fromPath(path).path(path1);
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:204;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(Class TestPath), TestPath is annonated
+ * with @Path, Verify that TestPath is appended as specified
+ */
+ @Test
+ public void pathTest2() throws Fault {
+ String path = "test1#test2";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String expected_path = "test1%23test2/TestPath";
+
+ try {
+ uri = UriBuilder.fromPath(path).path(path1).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:204;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(Class null), Verify that
+ * IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest3() throws Fault {
+ String path = "test1#test2";
+ Class<?> path1 = null;
+
+ try {
+ UriBuilder.fromPath(path).path(path1);
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:204;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(Class TestPathBad), TestPathBad is not
+ * annonated with @Path, Verify that IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest4() throws Fault {
+ String path = "test1#test2";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPathBad.class;
+
+ try {
+ UriBuilder.fromPath(path).path(path1);
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:206;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Class TestPath, String "headSub"),
+ * Verify that "/sub" is appended as specified
+ */
+ @Test
+ public void pathTest5() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String md = "headSub";
+ String expected_path = "/TestPath/sub";
+
+ try {
+ uri = UriBuilder.fromPath(path).path(path1, md).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest6
+ *
+ * @assertion_ids: JAXRS:JAVADOC:206;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Class TestPath, String "getPlain"),
+ * Verify that IllegalArgumentException is thrown since Method getPlain is not
+ * annonated with @Path
+ */
+ @Test
+ public void pathTest6() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String md = "getPlain";
+
+ try {
+ UriBuilder.fromPath(path).path(path1, md).build();
+ throw new Fault(
+ "Test failed, expected IllegalArgumentException not thrown."
+ + newline);
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest7
+ *
+ * @assertion_ids: JAXRS:JAVADOC:206;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Class TestPath, null), Verify that
+ * IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest7() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String md = null;
+
+ try {
+ UriBuilder.fromPath(path).path(path1, md).build();
+ throw new Fault(
+ "Test failed, expected IllegalArgumentException not thrown."
+ + newline);
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest8
+ *
+ * @assertion_ids: JAXRS:JAVADOC:206;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Class null, "headSub"), Verify that
+ * IllegalArgumentException is thrown since Method getPlan is not annonated
+ * with @Path
+ */
+ @Test
+ public void pathTest8() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = null;
+ String md = "headSub";
+
+ try {
+ UriBuilder.fromPath(path).path(path1, md).build();
+ throw new Fault(
+ "Test failed, expected IllegalArgumentException not thrown."
+ + newline);
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest9
+ *
+ * @assertion_ids: JAXRS:JAVADOC:206;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(TestPath,"test1"), Verify that
+ * IllegalArgumentException is thrown, since there are two methods annotated
+ * with @Path in TestPath
+ */
+ @Test
+ public void pathTest9() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String md = "test1";
+
+ try {
+ UriBuilder.fromPath(path).path(path1, md).build();
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest10
+ *
+ * @assertion_ids: JAXRS:JAVADOC:208;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Method headSub), Verify that "/sub"
+ * is appended as specified
+ */
+ @Test
+ public void pathTest10() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String expected_path = "/TestPath/sub";
+
+ try {
+ Method md = path1.getMethod("headSub", new Class[] {});
+ URI uri = UriBuilder.fromPath(path).path(md).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest11
+ *
+ * @assertion_ids: JAXRS:JAVADOC:208;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").path(Method headSub), Verify that "/sub1"
+ * is appended as specified
+ */
+ @Test
+ public void pathTest11() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+ String expected_path = "/TestPath/sub1";
+
+ try {
+ Method md = path1.getMethod("test1", new Class[] {});
+ URI uri = UriBuilder.fromPath(path).path(md).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: pathTest12
+ *
+ * @assertion_ids: JAXRS:JAVADOC:208;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(Method getPlain), Verify that
+ * IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest12() throws Fault {
+ String path = "/TestPath";
+ Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+
+ try {
+ Method md = path1.getMethod("getPlain", new Class[] {});
+ UriBuilder.fromPath(path).path(md).build();
+
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ } catch (NoSuchMethodException ex) {
+ throw new Fault(
+ "Test Failed. Unexpected exception thrown: " + ex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: pathTest13
+ *
+ * @assertion_ids: JAXRS:JAVADOC:208;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String).path(Method null), Verify that
+ * IllegalArgumentException is thrown
+ */
+ @Test
+ public void pathTest13() throws Fault {
+ String path = "test1#test2";
+ java.lang.reflect.Method path1 = null;
+
+ try {
+ UriBuilder.fromPath(path).path(path1);
+ throw new Fault(
+ "Test Failed. Expected IllegalArgumentException not thrown.");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace(
+ "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: replacePathTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:218;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").replacePath(String newPath), Verify that
+ * path is updated as specified
+ */
+ @Test
+ public void replacePathTest1() throws Fault {
+ String path = "/TestPath";
+ String new_path = "/TestPathAgain";
+
+ try {
+ URI uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+ gotExpectedPass(uri.toString(), new_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replacePathTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:218;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath1/TestPath2").replacePath(String null),
+ * Verify that all existing path cleared as specified
+ */
+ @Test
+ public void replacePathTest2() throws Fault {
+ String path = "/TestPath1/TestPath2";
+ String new_path = null;
+
+ try {
+ URI uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+ boolean conditionTrue = uri.toString() == null
+ || uri.toString().trim().compareTo("") == 0;
+ gotExpectedPass(!conditionTrue, uri.toString(), new_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replacePathTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:218;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("TestPath").replacePath(String newPath), Verify that
+ * all existing path cleared as specified
+ */
+ @Test
+ public void replacePathTest3() throws Fault {
+ String path = "TestPath";
+ String new_path = null;
+
+ try {
+ uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+ boolean conditionTrue = uri.toString() == null
+ || uri.toString().trim().compareTo("") == 0;
+ gotExpectedPass(!conditionTrue, uri.toString(), new_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: portTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:210;
+ *
+ * @test_Strategy: Call UriBuilder.port(int), Veify that port number updated
+ * accordingly.
+ */
+ @Test
+ public void portTest1() throws Fault {
+ String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+ String uri_string_expected = "foo://example.com:2008/over/there?name=ferret#nose";
+ int port = 2008;
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).port(port).build();
+ gotExpectedPass(uri.toString().trim(), uri_string_expected);
+ } catch (Exception ex) {
+ throw new Fault("Test Failed: unexpected Exception thrown", ex);
+ }
+ }
+
+ /*
+ * @testName: portTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:210;
+ *
+ * @test_Strategy: Call UriBuilder.port(int) with an invalid port number;
+ * Verify that IllegalArgumentException is thrown.
+ */
+ @Test
+ public void portTest2() throws Fault {
+ String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+ int port = -10;
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).port(port).build();
+ throw new Fault(
+ "Test failed, expected IllegalArgumentException not thrown."
+ + "Got uri=" + uri.toString() + " instead.");
+ } catch (IllegalArgumentException ex) {
+ TestUtil
+ .logTrace("Test Passed: expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: hostTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:198;
+ *
+ * @test_Strategy: Call UriBuilder.host(String), verify that hostame updated
+ * accordingly
+ */
+ @Test
+ public void hostTest1() throws Fault {
+ String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+ String uri_string_1 = "foo://java.net:8042/over/there?name=ferret#nose";
+ String host = "java.net";
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).host(host).build();
+ gotExpectedPass(uri.toString().trim(), uri_string_1);
+ } catch (Exception ex) {
+ throw new Fault("Test Failed: unexpected Exception thrown", ex);
+ }
+ }
+
+ /*
+ * @testName: hostTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:198;
+ *
+ * @test_Strategy: Call UriBuilder.host(hostname) with incorrect hstname,
+ * verify that IllegalArgumentException is thrown.
+ */
+ @Test
+ public void hostTest2() throws Fault {
+ String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+ String host = "";
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).host(host).build();
+ throw new Fault(
+ "Test failed, expected IllegalArgumentException not thrown."
+ + "Got uri=" + uri.toString() + " instead.");
+ } catch (IllegalArgumentException ex) {
+ TestUtil
+ .logTrace("Test Passed: expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: schemeTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:196; JAXRS:JAVADOC:223;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri(String)
+ */
+ @Test
+ public void schemeTest1() throws Fault {
+ String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+ String uri_string_1 = "http://example.com:8042/over/there?name=ferret#nose";
+ String scheme = "http";
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).scheme(scheme).build();
+ gotExpectedPass(uri.toString().trim(), uri_string_1);
+ } catch (Exception ex) {
+ throw new Fault("Test Failed: unexpected Exception thrown", ex);
+ }
+ }
+
+ /*
+ * @testName: schemeTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:223;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri(null); Verify that scheme is cleared.
+ */
+ @Test
+ public void schemeTest2() throws Fault {
+ String uri_string = "http://example.com:8042/over/there?name=ferret#nose";
+ String scheme = null;
+
+ try {
+ uri = UriBuilder.fromUri(uri_string).scheme(scheme).build();
+ assertTrue(uri.getRawSchemeSpecificPart() == null,
+ "scheme not cleared as expected, got"+ uri.getSchemeSpecificPart());
+ } catch (Throwable ex) {
+ TestUtil.logTrace(
+ "Unexpected Exception thrown. Test Failed." + ex.getMessage());
+ }
+ }
+
+ /*
+ * @testName: schemeSpecificPartTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:225;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri(String); Call method schemeSpecificPart(String) Verify
+ * the method works.
+ */
+ @Test
+ public void schemeSpecificPartTest() throws Fault {
+ String uri_1 = "http://example.com:8042/uber/here?name=ferret#nose";
+ String uri_2 = "//example1.com:8041/over/there?name=monkey";
+ String uri_3 = "http://example1.com:8041/over/there?name=monkey#nose";
+
+ try {
+ uri = UriBuilder.fromUri(uri_1).schemeSpecificPart(uri_2).build();
+ gotExpectedPass(uri.toString().trim(), uri_3);
+ } catch (Exception ex) {
+ throw new Fault("Test Failed: unexpected Exception thrown", ex);
+ }
+ }
+
+ /*
+ * @testName: schemeSpecificPartTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:225;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromUri(String); Call method schemeSpecificPart(null) Verify
+ * that IllegalArgumentException is thrown.
+ */
+ @Test
+ public void schemeSpecificPartTest1() throws Fault {
+ String uri_1 = "http://example.com:8042/uber/here?name=ferret#nose";
+ String uri_2 = null;
+
+ try {
+ UriBuilder.fromUri(uri_1).schemeSpecificPart(uri_2).build();
+ sb.append(
+ "Test Failed: expected IllegalArgumentException Exception not thrown.");
+ pass = false;
+ } catch (IllegalArgumentException ex) {
+ sb.append("Expected IllegalArgumentException thrown. Test PASSED.");
+ } catch (Exception ex) {
+ sb.append("Test Failed: wrong Exception thrown" + ex.getMessage());
+ pass = false;
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: templateTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:189; JAXRS:JAVADOC:190;
+ *
+ * @test_Strategy: Create an Uri instance using
+ * UriBuilder.fromPath(String).fragment(String).build(String)
+ */
+ @Test
+ public void templateTest1() throws Fault {
+ String expected_value = "test#xyz";
+
+ try {
+ uri = UriBuilder.fromPath("{arg1}").fragment("{arg2}").build("test",
+ "xyz");
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: templateTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+ *
+ * @test_Strategy: Create an Uri instance using
+ * UriBuilder.fromPath(String).build(String)
+ */
+ @Test
+ public void templateTest2() throws Fault {
+ String expected_value = "test1/test2/test1";
+
+ try {
+ uri = UriBuilder.fromPath("{arg1}/{arg2}/{arg1}").build("test1", "test2",
+ "test3");
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: uriTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:194; JAXRS:JAVADOC:229;
+ *
+ * @test_Strategy: Create a set of UriBuilder instances with diffeent schemes;
+ * using UriBuilder instances using UriBuilder.fromUri(URI) Call uri(URI)
+ * method on all instances; verify it works correctly on all of the instances.
+ */
+ @Test
+ public void uriTest() throws Fault {
+ String[] uris_orig = getOrigUris();
+ URI uris_replace[] = getReplacementUris();
+ String[] uris_expect = getExpectedUris();
+
+ int j = 0;
+ int i = 0;
+ int k = 0;
+ while (j < 17) {
+ try {
+ sb.append("Replace uri with ").append(uris_replace[j]).append(newline);
+ uri = UriBuilder.fromUri(new URI(uris_orig[j])).uri(uris_replace[j])
+ .build();
+ if (gotExpectedPass(uri.toString().trim(), uris_expect[j]) != 0)
+ i++;
+ else
+ k++;
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: ").append(ex.getMessage())
+ .append(newline);
+ sb.append("Test failed with exception for expected uri: ")
+ .append(uris_expect[j]).append(newline);
+ }
+ j++;
+ }
+
+ assertTrue(pass, k+ "assertion passed."+ newline+ i+ "assertion(s) failed:"+
+ sb.toString()+ newline);
+ logMsg(sb);
+ }
+
+ /*
+ * @testName: uriTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:229;
+ *
+ * @test_Strategy: Calling UriBuilder.uri(URI null) verify the
+ * IllegalStateException thrown..
+ */
+ @Test
+ public void uriTest1() throws Fault {
+ try {
+ UriBuilder.fromPath("/").uri(uri);
+ throw new Fault("Expected IllegalArgumentException not thrown" + newline);
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: fromEncodedTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:179;
+ *
+ * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+ * Object.toString() is encoded.
+ */
+ @Test
+ public void fromEncodedTest1() throws Fault {
+ String expected_value_1 = "http://localhost:8080/a/%25/=/%25G0/%25/=";
+ String expected_value_2 = "http://localhost:8080/xy/%20/%25/xy";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncoded("a", "%25", "=", "%G0", "%", "23");
+ gotExpectedPass(uri.toString(), expected_value_1);
+
+ uri = UriBuilder.fromPath(LOCALHOST).path("/{x}/{y}/{z}/{x}")
+ .buildFromEncoded("xy", " ", "%");
+ gotExpectedPass(uri.toString(), expected_value_2);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: fromEncodedTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:180;
+ *
+ * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+ * IllegalArgumentException is thrown when one template is missing its value
+ */
+ @Test
+ public void fromEncodedTest2() throws Fault {
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncoded("a", "%25", "=", "%G0");
+ throw new Fault("Expected IllegalArgumentException Not thrown. uri ="
+ + uri.toString());
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: fromEncodedTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:180;
+ *
+ * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+ * IllegalArgumentException is thrown when one value is null.
+ */
+ @Test
+ public void fromEncodedTest3() throws Fault {
+ try {
+ UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+ .buildFromEncoded("a", "%25", null, "%G0");
+ throw new Fault("Expected IllegalArgumentException Not thrown");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: queryParamTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:212;
+ *
+ * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+ * value). verify IllegalArgumentException is thrown when name is null.
+ */
+ @Test
+ public void queryParamTest1() throws Fault {
+ String name = null;
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", "y");
+ throw new Fault("Expected IllegalArgumentException Not thrown");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: queryParamTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:212;
+ *
+ * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+ * value). verify IllegalArgumentException is thrown when values is null.
+ */
+ @Test
+ public void queryParamTest2() throws Fault {
+ String name = "name";
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).queryParam(name, (Object) null);
+ throw new Fault("Expected IllegalArgumentException Not thrown");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: queryParamTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:212;
+ *
+ * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+ * value). verify IllegalArgumentException is thrown when one of values is
+ * null.
+ */
+ @Test
+ public void queryParamTest3() throws Fault {
+ String name = "name";
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", null);
+ throw new Fault("Expected IllegalArgumentException Not thrown");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: queryParamTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:212;
+ *
+ * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+ * value). verify that when two values are supplied, both are present in final
+ * URI.
+ */
+ @Test
+ public void queryParamTest4() throws Fault {
+ String name = "name";
+ String expected_value = "http://localhost:8080?name=x&name=y";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", "y").build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: queryParamTest5
+ *
+ * @assertion_ids: JAXRS:JAVADOC:212;
+ *
+ * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+ * value). verify that values are encoded properly in final URI.
+ */
+ @Test
+ public void queryParamTest5() throws Fault {
+ String name = "name";
+ String actual = null;
+ String expected_value = "http://localhost:8080?name=x%3D&name=y?&name=x+y&name=%26";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&").build();
+ actual = uri.toString().replace("%3F", "?").replace("%3f", "?");
+ gotExpectedPass(actual, expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceQueryTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:219;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQuery(String name). verify that
+ * query is replaced properly in final URI.
+ */
+ @Test
+ public void replaceQueryTest1() throws Fault {
+ String name = "name";
+ String expected_value = "http://localhost:8080?name1=xyz";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&").replaceQuery("name1=xyz")
+ .build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceQueryTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:219;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQuery(String null). verify that
+ * query is cleared properly in final URI.
+ */
+ @Test
+ public void replaceQueryTest2() throws Fault {
+ String name = "name";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&").replaceQuery(null).build();
+ gotExpectedPass(uri.toString(), LOCALHOST);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceQueryTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:219;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQuery(String query). verify that
+ * query is replaced properly in final URI.
+ */
+ @Test
+ public void replaceQueryTest3() throws Fault {
+ String name = "name";
+ String expected_value = "http://localhost:8080?name1=x&name2=%20&name3=x+y&name4=23&name5=x%20y";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&")
+ .replaceQuery("name1=x&name2=%20&name3=x+y&name4=23&name5=x y")
+ .build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * testName: replaceQueryTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:219;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQuery(String query). verify that
+ * IllegalArgumentException is thrown when query cannot be parsed.
+ */
+ @Test
+ public void replaceQueryTest4() throws Fault {
+ String value = "http://localhost:8080?name1=x&name2=%20&name3=x+y&name4=x%20y";
+
+ try {
+ uri = UriBuilder.fromPath(value)
+ .replaceQuery("name$*()^@!+-]}[{|<>,./:;'#1==x?&name2=%20y").build();
+ pass = false;
+ sb.append("Expected IllegalArgumentException not thrown");
+ sb.append("uri=" + uri.getQuery());
+ } catch (IllegalArgumentException ex) {
+ sb.append("Expected IllegalArgumentException thrown");
+ } catch (Exception ex1) {
+ pass = false;
+ sb.append("Wrong type Exception thrown" + ex1.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceQueryParamTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:221;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQueryParam(String null, Object...
+ * value). verify IllegalArgumentException is thrown
+ */
+ @Test
+ public void replaceQueryParamTest1() throws Fault {
+ String name = null;
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", null);
+ throw new Fault("Expected IllegalArgumentException Not thrown");
+ } catch (IllegalArgumentException ilex) {
+ TestUtil.logTrace("Expected IllegalArgumentException thrown");
+ }
+ }
+
+ /*
+ * @testName: replaceQueryParamTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:221;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQueryParam(String name, Object...
+ * value). verify all query params are cleared when values is null.
+ */
+ @Test
+ public void replaceQueryParamTest2() throws Fault {
+ String name = "name";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&")
+ .replaceQueryParam(name, (Object[]) null).build();
+ gotExpectedPass(uri.toString(), LOCALHOST);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceQueryParamTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:221;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceQueryParam(String name, Object...
+ * value). verify that query parameter is updated accordingly
+ */
+ @Test
+ public void replaceQueryParamTest3() throws Fault {
+ String name = "name";
+ String expected_value = "http://localhost:8080?name=x&name=y&name=y+x&name=x%25y&name=%20";
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .queryParam(name, "x=", "y?", "x y", "&")
+ .replaceQueryParam(name, "x", "y", "y x", "x%y", "%20").build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: segmentTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:227;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify
+ * IllegalArgumentException if any element of paths is null
+ */
+ @Test
+ public void segmentTest1() throws Fault {
+ String path = null;
+
+ try {
+ UriBuilder.fromPath("/").segment(path).build();
+ throw new Fault(
+ "TestFailed: expected IllegalArgumentException not thrown.");
+
+ } catch (IllegalArgumentException ex) {
+ TestUtil
+ .logTrace("Test Passed: Expected IllegalArgumentException thrown.");
+ }
+ }
+
+ /*
+ * @testName: segmentTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:227;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify "/" is
+ * added when needed and characters are encoded as needed.
+ */
+ @Test
+ public void segmentTest2() throws Fault {
+ String path1 = "";
+ String[] path2 = { "a1", "/", "3b " };
+ String expected_path = "a1/%2F/3b%20";
+
+ try {
+ uri = UriBuilder.fromPath(path1).segment(path2).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: segmentTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:227;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify that a
+ * single value is only a single URI path segment. and characters are encoded
+ * as needed.
+ */
+ @Test
+ public void segmentTest3() throws Fault {
+ String path1 = "ab";
+ String[] path2 = { "a1", "x/y", "3b " };
+ String expected_path = "ab/a1/x%2Fy/3b%20";
+
+ try {
+ uri = UriBuilder.fromPath(path1).segment(path2).build();
+ gotExpectedPass(uri.toString(), expected_path);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: uriBuilderExceptionTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:232;
+ *
+ * @test_Strategy: Create an UriBuilderException instance using
+ * UriBuilderException(). Verify that empty message is associated with the
+ * exception.
+ */
+ @Test
+ public void uriBuilderExceptionTest1() throws Fault {
+ try {
+ throw new UriBuilderException();
+ } catch (UriBuilderException ube) {
+ if (ube.getMessage() == "" || ube.getMessage() == null) {
+ TestUtil.logTrace(
+ "Test Passed with empty message: " + ube.getMessage() + ".");
+ } else {
+ throw new Fault("Test Failed. Expecting empty message," + " Got "
+ + ube.getMessage());
+ }
+ }
+ }
+
+ /*
+ * @testName: uriBuilderExceptionTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:233;
+ *
+ * @test_Strategy: Create an UriBuilderException instance using
+ * UriBuilderException(String msg). Verify that message msg is associated with
+ * the exception.
+ */
+ @Test
+ public void uriBuilderExceptionTest2() throws Fault {
+ String msg = "JAX-RS Test Message: xyz";
+
+ try {
+ throw new UriBuilderException(msg);
+ } catch (UriBuilderException ube) {
+ if (msg.equals(ube.getMessage())) {
+ TestUtil.logTrace(
+ "Test Passed with correct message: " + ube.getMessage() + ".");
+ } else {
+ throw new Fault("Test Failed. Expecting message," + msg + ", got "
+ + ube.getMessage() + ".");
+ }
+ }
+ }
+
+ /*
+ * @testName: uriBuilderExceptionTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:234;
+ *
+ * @test_Strategy: Create an UriBuilderException instance using
+ * UriBuilderException(String msg, throwable ex). Verify that message msg is
+ * associated with the exception.
+ */
+ @Test
+ public void uriBuilderExceptionTest3() throws Fault {
+ String msg = "JAX-RS Test Message: xyz";
+ String msg1 = "JAX-RS Test Message Again: xyz";
+
+ try {
+ throw new UriBuilderException(msg, new Exception(msg1));
+ } catch (UriBuilderException ube) {
+ if (ube.getMessage().contains(msg)) {
+ TestUtil.logTrace(
+ "Test Passed with correct message: " + ube.getMessage() + ".");
+ } else {
+ throw new Fault("Test Failed. Expecting message," + msg + ", got "
+ + ube.getMessage() + ".");
+ }
+ }
+ }
+
+ /*
+ * @testName: uriBuilderExceptionTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:235;
+ *
+ * @test_Strategy: Create an UriBuilderException instance using
+ * UriBuilderException(String msg, throwable ex). Verify that message msg is
+ * associated with the exception.
+ */
+ @Test
+ public void uriBuilderExceptionTest4() throws Fault {
+ String msg = "JAX-RS Test Message Again: xyz";
+
+ try {
+ throw new UriBuilderException(new Exception(msg));
+ } catch (UriBuilderException ube) {
+ if (ube.getMessage().contains(msg)) {
+ TestUtil.logTrace(
+ "Test Passed with correct message: " + ube.getMessage() + ".");
+ } else {
+ throw new Fault("Test Failed. Expecting message," + msg + ", got "
+ + ube.getMessage() + ".");
+ }
+ }
+ }
+
+ /*
+ * @testName: cloneTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:188;
+ *
+ * @test_Strategy: Create an UriBuilder instance using
+ * UriBuilder.fromPath(String); Create another UriBuilder instance using
+ * UriBuilder.clone(); Verify that both are created correctly.
+ */
+ @Test
+ public void cloneTest1() throws Fault {
+ UriBuilder ub, ub1;
+ URI uri1;
+ String path1 = "test";
+ String frag = "xyz";
+ String expected_path_1 = "test#xyz";
+
+ Map<String, String> maps = new HashMap<String, String>();
+ maps.put("x", "x%yz");
+ maps.put("y", "/path-absolute/%25test1");
+ maps.put("z", "fred@example.com");
+ maps.put("w", "path-rootless/test2");
+
+ String expected_path_2 = "test/" + ENCODED_EXPECTED_PATH + "#xyz";
+
+ try {
+ ub = UriBuilder.fromPath(path1).fragment(frag);
+ ub1 = ub.clone();
+ uri = ub.build();
+ gotExpectedPass(uri.toString(), expected_path_1);
+
+ uri1 = ub1.path("{w}/{x}/{y}/{z}/{x}").buildFromMap(maps);
+ gotExpectedPass(uri1.toString(), expected_path_2);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: " + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: matrixParamTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:200;
+ *
+ * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+ * value). verify IllegalArgumentException is thrown when name is null.
+ */
+ @Test
+ public void matrixParamTest1() throws Fault {
+ String name = null;
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x", "y");
+ sb.append("Expected IllegalArgumentException Not thrown");
+ pass = false;
+ } catch (IllegalArgumentException ilex) {
+ sb.append("Expected IllegalArgumentException thrown");
+ } catch (Throwable th) {
+ pass = false;
+ sb.append("Incorrect Exception thrown: " + th.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: matrixParamTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:200;
+ *
+ * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+ * value). verify IllegalArgumentException is thrown when values is null.
+ */
+ @Test
+ public void matrixParamTest2() throws Fault {
+ String name = "name";
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).matrixParam(name, (Object) null);
+ sb.append("Expected IllegalArgumentException Not thrown");
+ pass = false;
+ } catch (IllegalArgumentException ilex) {
+ sb.append("Expected IllegalArgumentException thrown");
+ } catch (Throwable th) {
+ pass = false;
+ sb.append("Incorrect Exception thrown: " + th.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: matrixParamTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:200;
+ *
+ * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+ * value). verify that when two values are supplied, both are present in final
+ * URI.
+ */
+ @Test
+ public void matrixParamTest3() throws Fault {
+ String name = "name";
+ String expected_value = "http://localhost:8080;name=x;name=y";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x", "y").build();
+ gotExpectedPass(uri.toString(), expected_value);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixParamTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:216;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+ * Object... value). verify IllegalArgumentException when name is null.
+ */
+ @Test
+ public void replaceMatrixParamTest1() throws Fault {
+ String name = "name";
+
+ try {
+ UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x=", "y?", "x y", "&")
+ .replaceMatrixParam(null, "x", "y").build();
+ pass = false;
+ sb.append("Expected exception not thrown.");
+ } catch (IllegalArgumentException ex) {
+ sb.append("Expected exception thrown.");
+ } catch (Throwable th) {
+ pass = false;
+ sb.append("Wrong type of Exception thrown" + th.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixParamTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:216;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+ * Object... value). verify all values are cleared when value is null.
+ */
+ @Test
+ public void replaceMatrixParamTest2() throws Fault {
+ String name = "name";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .matrixParam(name, "x=", "y?", "x y", "&").replaceMatrixParam(name)
+ .build();
+ gotExpectedPass(uri.toString(), LOCALHOST);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixParamTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:216;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+ * Object... value). verify that matrix parameter is updated accordingly
+ */
+ @Test
+ public void replaceMatrixParamTest3() throws Fault {
+ String name = "name";
+ String expected = "http://localhost:8080;name=x;name=y;name=y%20x;name=x%25y;name=%20";
+
+ try {
+ uri = UriBuilder
+ .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+ .replaceMatrixParam(name, "x", "y", "y x", "x%y", "%20").build();
+ gotExpectedPass(uri.toString(), expected);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixParamTest4
+ *
+ * @assertion_ids: JAXRS:JAVADOC:216;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+ * Object... value). verify that matrix parameter is updated accordingly
+ */
+ @Test
+ public void replaceMatrixParamTest4() throws Fault {
+ String name = "name1";
+ String expected = "http://localhost:8080;name=x=;name=y%3F;name=x%20y;name=&;name1=x;name1=y;name1=y%20x;name1=x%25y;name1=%20";
+
+ try {
+ uri = UriBuilder
+ .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+ .replaceMatrixParam(name, "x", "y", "y x", "x%y", "%20").build();
+ gotExpectedPass(uri.toString(), expected);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixTest1
+ *
+ * @assertion_ids: JAXRS:JAVADOC:214;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify all
+ * values are cleared when value is null.
+ */
+ @Test
+ public void replaceMatrixTest1() throws Fault {
+ String name = "name";
+ String expected1 = "http://localhost:8080;";
+
+ try {
+ uri = UriBuilder.fromPath(LOCALHOST)
+ .matrixParam(name, "x=", "y?", "x y", "&").replaceMatrix(null)
+ .build();
+ String sUri = uri.toString();
+ boolean condition = sUri.compareToIgnoreCase(LOCALHOST) == 0
+ || sUri.compareToIgnoreCase(expected1) == 0;
+ gotExpectedPass(!condition, sUri, LOCALHOST);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixTest2
+ *
+ * @assertion_ids: JAXRS:JAVADOC:214;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify that
+ * Matrix parameter is updated accordingly
+ */
+ @Test
+ public void replaceMatrixTest2() throws Fault {
+ String expected = "http://localhost:8080;name=x;name=y;name=y%20x;name=x%25y;name=%20";
+ String value = "name=x;name=y;name=y x;name=x%y;name= ";
+
+ try {
+ uri = UriBuilder
+ .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+ .replaceMatrix(value).build();
+ gotExpectedPass(uri.toString(), expected);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: replaceMatrixTest3
+ *
+ * @assertion_ids: JAXRS:JAVADOC:214;
+ *
+ * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify that
+ * matrix parameter is updated accordingly
+ */
+ @Test
+ public void replaceMatrixTest3() throws Fault {
+ String expected = "http://localhost:8080;name1=x;name1=y;name1=y%20x;name1=x%25y;name1=%20";
+ String value = "name1=x;name1=y;name1=y x;name1=x%y;name1= ";
+
+ try {
+ uri = UriBuilder
+ .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+ .replaceMatrix(value).build();
+ gotExpectedPass(uri.toString(), expected);
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected Exception thrown" + ex.getMessage());
+ }
+
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: userInfoTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:231;
+ *
+ * @test_Strategy: call UriBuilder.userInfo in different states of UriBuilder
+ * Check the userInfo on built java.net.URI
+ */
+ @Test
+ public void userInfoTest() throws Fault {
+ String unexpected = "Unexpected user info:";
+ String userInfo = "foo:foo";
+
+ uri = UriBuilder.fromUri(LOCALHOST).build();
+ assertTrue(uri.getUserInfo() == null, unexpected+ uri.getUserInfo());
+
+ uri = UriBuilder.fromUri(LOCALHOST).userInfo(userInfo).build();
+ assertTrue(uri.getRawUserInfo().equals(userInfo), unexpected+
+ uri.getRawUserInfo());
+ System.out.println(uri.getRawUserInfo());
+
+ uri = UriBuilder.fromUri("http://foo2:foo2@localhost:8080")
+ .userInfo(userInfo).build();
+ System.out.println(uri.getRawUserInfo());
+ assertTrue(userInfo.equals(uri.getRawUserInfo()), unexpected+
+ uri.getRawUserInfo());
+
+ uri = UriBuilder.fromPath("").scheme("http").userInfo(userInfo)
+ .host("localhost").port(8080).build();
+ assertTrue(uri.getRawUserInfo().equals(userInfo), unexpected+
+ uri.getRawUserInfo());
+ }
+
+ /*
+ * @testName: buildObjectsBooleanEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:886;
+ *
+ * @test_Strategy: Build a URI, using the supplied values in order to replace
+ * any URI template parameters. Values are converted to String using their
+ * toString() method and are then encoded to match the rules of the URI
+ * component to which they pertain. The slash ('/') characters in parameter
+ * values will be encoded if the template is placed in the URI path component.
+ */
+ @Test
+ public void buildObjectsBooleanEncodedTest() throws Fault {
+ Object s[] = { "path-rootless/test2", new StringBuilder("x%yz"),
+ "/path-absolute/%25test1", "fred@example.com" };
+ uri = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}")
+ .build(new Object[] { s[0], s[1], s[2], s[3], s[1] }, true);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildObjectsBooleanNotEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:886;
+ *
+ * @test_Strategy: Build a URI, using the supplied values in order to replace
+ * any URI template parameters. Values are converted to String using their
+ * toString() method and are then encoded to match the rules of the URI
+ * component to which they pertain.
+ */
+ @Test
+ public void buildObjectsBooleanNotEncodedTest() throws Fault {
+ Object s[] = { new StringBuffer("path-rootless/test2"), "x%yz",
+ "/path-absolute", "test1", "fred@example.com" };
+ uri = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{z}/{w}")
+ .build(new Object[] { s[0], s[1], s[2], s[3], s[4], s[1] }, false);
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildObjectsBooleanThrowsIAEWhenNoValueSuppliedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:887;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if there are any URI
+ * template parameters without a supplied value
+ */
+ @Test
+ public void buildObjectsBooleanThrowsIAEWhenNoValueSuppliedTest()
+ throws Fault {
+ try {
+ uri = UriBuilder.fromPath("").path("{v}/{w}")
+ .build(new Object[] { "first" }, false);
+ fault("IllegalArgumentException has not been thrown, uri:", uri);
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: buildObjectsBooleanThrowsIAEWhenValueIsNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:887;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if a value is null.
+ */
+ @Test
+ public void buildObjectsBooleanThrowsIAEWhenValueIsNullTest() throws Fault {
+ try {
+ uri = UriBuilder.fromPath("").path("{v}/{w}")
+ .build(new Object[] { "first", null }, false);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: buildFromMapWithBooleanSlashEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:889;
+ *
+ * @test_Strategy: Build a URI. Any URI template parameters will be replaced
+ * by the value in the supplied map. Values are converted to String using
+ * their toString() method and are then encoded to match the rules of the URI
+ * component to which they pertain. All '%' characters in the stringified
+ * values will be encoded. The state of the builder is unaffected; this method
+ * may be called multiple times on the same builder instance. The slash ('/')
+ * characters in parameter values will be encoded if the template is placed in
+ * the URI path component.
+ */
+ @Test
+ public void buildFromMapWithBooleanSlashEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/%25test1"));
+ map.put("z", new Object() {
+ public String toString() {
+ return "fred@example.com";
+ }
+ });
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ builder.buildFromMap(map, false); // can be called multiple times
+ uri = builder.buildFromMap(map, true);
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromMapWithBooleanSlashNotEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:889;
+ *
+ * @test_Strategy: Build a URI. Any URI template parameters will be replaced
+ * by the value in the supplied map. Values are converted to String using
+ * their toString() method and are then encoded to match the rules of the URI
+ * component to which they pertain. All '%' characters in the stringified
+ * values will be encoded. The state of the builder is unaffected; this method
+ * may be called multiple times on the same builder instance.
+ */
+ @Test
+ public void buildFromMapWithBooleanSlashNotEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/test1"));
+ map.put("z", new Object() {
+ public String toString() {
+ return "fred@example.com";
+ }
+ });
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ uri = builder.buildFromMap(map, false);
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: buildFromMapWithBooleanThrowsIAEWhenNoSuppliedValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:890;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if there are any URI
+ * template parameters without a supplied value
+ */
+ @Test
+ public void buildFromMapWithBooleanThrowsIAEWhenNoSuppliedValueTest()
+ throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/test1"));
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ try {
+ uri = builder.buildFromMap(map, false);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: buildFromMapWithBooleanThrowsIAEWhenNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:890;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if a template
+ * parameter value is null.
+ */
+ @Test
+ public void buildFromMapWithBooleanThrowsIAEWhenNullValueTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/test1"));
+ map.put("z", null);
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ try {
+ uri = builder.buildFromMap(map, false);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: fromLinkTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:892;
+ *
+ * @test_Strategy: Create a new instance initialized from a Link.
+ */
+ @Test
+ public void fromLinkTest() throws Fault {
+ URI uri = UriBuilder.fromUri(LOCALHOST).build();
+ Link link = Link.fromUri(uri).build();
+ URI uri2 = UriBuilder.fromLink(link).build();
+ assertTrue(uri.equals(uri2), "URI"+ uri+ "and"+ uri2+ "are not equal");
+ logMsg("URI fromLink is equal to the expected URI");
+ }
+
+ /*
+ * @testName: fromLinkThrowsIllegalArgumentExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:892;
+ *
+ * @test_Strategy: throws IllegalArgumentException - if link is {@code null}
+ */
+ @Test
+ public void fromLinkThrowsIllegalArgumentExceptionTest() throws Fault {
+ try {
+ UriBuilder.fromLink((Link) null);
+ throw new Fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected");
+ }
+ }
+
+ /*
+ * @testName: fromMethodTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:894;
+ *
+ * @test_Strategy: Create a new instance representing a relative URI
+ * initialized from a Path-annotated method. This method can only be used in
+ * cases where there is a single method with the specified name that is
+ * annotated with Path.
+ */
+ @Test
+ public void fromMethodTest() throws Fault {
+ URI uri = UriBuilder.fromMethod(TestPath.class, "headSub").build();
+ assertTrue(uri.toASCIIString().equals("/sub"),
+ "There is no /sub in the URI");
+ logMsg("URI fromMethod is equal to the expected URI", uri);
+ }
+
+ /*
+ * @testName: fromMethodThrowsIllegalArgumentExceptionWhenMorePathsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:894;
+ *
+ * @test_Strategy: Throws: IllegalArgumentException - if resource or method is
+ * null, or there is more than or less than one variant of the method
+ * annotated with Path.
+ */
+ @Test
+ public void fromMethodThrowsIllegalArgumentExceptionWhenMorePathsTest()
+ throws Fault {
+ try {
+ UriBuilder.fromMethod(TestPath.class, "test1");
+ throw new Fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been sucessfully thrown", e);
+ }
+ }
+
+ /*
+ * @testName: fromMethodThrowsIllegalArgumentExceptionWhenNoPathTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:894;
+ *
+ * @test_Strategy: Throws: IllegalArgumentException - if resource or method is
+ * null, or there is more than or less than one variant of the method
+ * annotated with Path.
+ */
+ @Test
+ public void fromMethodThrowsIllegalArgumentExceptionWhenNoPathTest()
+ throws Fault {
+ try {
+ UriBuilder.fromMethod(TestPath.class, "getPlain");
+ throw new Fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been sucessfully thrown", e);
+ }
+ }
+
+ /*
+ * @testName: toTemplateTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:896;
+ *
+ * @test_Strategy: Get the URI template string represented by this URI
+ * builder.
+ */
+ @Test
+ public void toTemplateTest() throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template);
+ assertEquals(template, builder.toTemplate(), "Given template", template,
+ "differs from obtain", builder.toTemplate());
+ logMsg("Got expected template", template);
+ }
+
+ /*
+ * @testName: uriStringTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:897;
+ *
+ * @test_Strategy: Parses the string and copies the parsed components of the
+ * supplied URI to the UriBuilder replacing any existing values for those
+ * components.
+ */
+ @Test
+ public void uriStringTest() throws Fault {
+ String origUris[] = getOrigUris();
+ URI[] replaceUris = getReplacementUris();
+ String[] expectUris = getExpectedUris();
+
+ int cnt = 0;
+ int failed = 0;
+ int passed = 0;
+ while (cnt < 17) {
+ try {
+ sb.append("Replace uri ").append(origUris[cnt]).append(" with ")
+ .append(replaceUris[cnt].toASCIIString()).append(newline);
+ uri = UriBuilder.fromUri(new URI(origUris[cnt]))
+ .uri(replaceUris[cnt].toASCIIString()).build();
+ if (gotExpectedPass(uri.toString().trim(), expectUris[cnt]) != 0)
+ failed++;
+ else
+ passed++;
+ } catch (Exception ex) {
+ pass = false;
+ sb.append("Unexpected exception thrown: ").append(ex.getMessage())
+ .append(newline);
+ sb.append("Test failed with exception for expected uri: ")
+ .append(expectUris[cnt]).append(newline);
+ failed++;
+ }
+ cnt++;
+ }
+
+ assertTrue(pass, passed+ "assertion passed."+ newline+ failed+
+ "assertion(s) failed:"+ sb.toString()+ newline);
+ }
+
+ /*
+ * @testName: uriStringThrowsIAEWhenNullTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:896;
+ *
+ * @test_Strategy: throws IllegalArgumentException - if URI template or is
+ * {@code null}.
+ */
+ @Test
+ public void uriStringThrowsIAEWhenNullTest() throws Fault {
+ try {
+ UriBuilder.fromMethod(TestPath.class, "headSub").uri((String) null);
+ throw new Fault("No Exception has been thrown for #uri(null)");
+ } catch (IllegalArgumentException e) {
+ logMsg(
+ "#IllegalArgumentException has been thrown as expected for #uri(null)");
+ }
+ }
+
+ /*
+ * @testName: uriStringThrowsIAEWhenNoUriTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:896;
+ *
+ * @test_Strategy: throws IllegalArgumentException - if {@code uriTemplate} is
+ * not a valid URI template
+ */
+ @Test
+ public void uriStringThrowsIAEWhenNoUriTest() throws Fault {
+ String sUri = "://";
+ try {
+ uri = UriBuilder.fromUri(new URI("news//:comp.lang.java")).uri(sUri)
+ .build();
+ fault("No Exception has been thrown for #uri(noURI)", uri);
+ } catch (IllegalArgumentException e) {
+ logMsg(
+ "#IllegalArgumentException has been thrown as expected for #uri(noURI)");
+ } catch (URISyntaxException e) {
+ throw new Fault(e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:957;
+ *
+ * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+ * instance using a supplied value
+ */
+ @Test
+ public void resolveTemplateStringObjectTest() throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template)
+ .resolveTemplate("v", new StringBuilder("aaa"));
+ String resolvedTemplate = template.replace("{v}", "aaa");
+ String builderTemplate = builder.toTemplate();
+ assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+ "was not resolved correctly, remains", builderTemplate);
+ logMsg("Got expected template", template);
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectThrowsIAEOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:957;
+ *
+ * @test_Strategy: if the resolved template name or value is null.
+ */
+ @Test
+ public void resolveTemplateStringObjectThrowsIAEOnNullNameTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template);
+ try {
+ builder.resolveTemplate(null, "aaa");
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectThrowsIAEOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:957;
+ *
+ * @test_Strategy: if the resolved template name or value is null.
+ */
+ @Test
+ public void resolveTemplateStringObjectThrowsIAEOnNullValueTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template);
+ try {
+ builder.resolveTemplate("v", null);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectBooleanSlashEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:959;
+ *
+ * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+ * instance using a supplied value. The slash ('/') characters in template
+ * values will be encoded.
+ */
+ @Test
+ public void resolveTemplateStringObjectBooleanSlashEncodedTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template)
+ .resolveTemplate("v", new StringBuilder("a/a/a"), true);
+ String resolvedTemplate = template.replace("{v}", "a%2Fa%2Fa");
+ String builderTemplate = builder.toTemplate().replace("%2f", "%2F");
+ assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+ "was not resolved correctly, remains", builderTemplate);
+ logMsg("Got expected template", template);
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectBooleanSlashNotEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:959;
+ *
+ * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+ * instance using a supplied value.
+ */
+ @Test
+ public void resolveTemplateStringObjectBooleanSlashNotEncodedTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template)
+ .resolveTemplate("v", new StringBuilder("a/a/a"), false);
+ String resolvedTemplate = template.replace("{v}", "a/a/a");
+ String builderTemplate = builder.toTemplate();
+ assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+ "was not resolved correctly, remains", builderTemplate);
+ logMsg("Got expected template", template);
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectBooleanThrowsIAEOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:959;
+ *
+ * @test_Strategy: if the resolved template name or value is null.
+ */
+ @Test
+ public void resolveTemplateStringObjectBooleanThrowsIAEOnNullNameTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template);
+ try {
+ builder.resolveTemplate(null, "aaa", false);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateStringObjectBooleanThrowsIAEOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:959;
+ *
+ * @test_Strategy: if the resolved template name or value is null.
+ */
+ @Test
+ public void resolveTemplateStringObjectBooleanThrowsIAEOnNullValueTest()
+ throws Fault {
+ String template = "{v}/{w}/{x}/{y}/{w}";
+ UriBuilder builder = UriBuilder.fromPath("").path(template);
+ try {
+ builder.resolveTemplate("v", null, false);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateFromEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:961;
+ *
+ * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+ * instance using a supplied encoded value.
+ */
+ @Test
+ public void resolveTemplateFromEncodedTest() throws Fault {
+ Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%25yz"),
+ "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ builder = builder.resolveTemplateFromEncoded("v", s[0]);
+ builder = builder.resolveTemplateFromEncoded("w", s[1]);
+ builder = builder.resolveTemplateFromEncoded("x", s[2]);
+ builder = builder.resolveTemplateFromEncoded("y", s[3]);
+ uri = builder.build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplateFromEncodedPercentEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:961;
+ *
+ * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+ * instance using a supplied encoded value. All % characters in the
+ * stringified values that are not followed by two hexadecimal numbers will be
+ * encoded.
+ */
+ @Test
+ public void resolveTemplateFromEncodedPercentEncodedTest() throws Fault {
+ Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%yz"),
+ "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ builder = builder.resolveTemplateFromEncoded("v", s[0]);
+ builder = builder.resolveTemplateFromEncoded("w", s[1]);
+ builder = builder.resolveTemplateFromEncoded("x", s[2]);
+ builder = builder.resolveTemplateFromEncoded("y", s[3]);
+ uri = builder.build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplateFromEncodedThrowsNullOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:961;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if the resolved
+ * template name or encoded value is null.
+ */
+ @Test
+ public void resolveTemplateFromEncodedThrowsNullOnNullNameTest()
+ throws Fault {
+ Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%25yz"),
+ "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ try {
+ builder.resolveTemplateFromEncoded(null, s[0]);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplateFromEncodedThrowsNullOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:961;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if the resolved
+ * template name or encoded value is null.
+ */
+ @Test
+ public void resolveTemplateFromEncodedThrowsNullOnNullValueTest()
+ throws Fault {
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ try {
+ builder.resolveTemplateFromEncoded("v", (Object) null);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:963;
+ *
+ * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+ * instance using supplied name-value pairs.
+ */
+ @Test
+ public void resolveTemplatesMapTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/%25test1"));
+ map.put("z", new Object() {
+ public String toString() {
+ return "fred@example.com";
+ }
+ });
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ uri = builder.resolveTemplates(map).build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplatesMapThrowsIAEOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:963;
+ *
+ * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesMapThrowsIAEOnNullNameTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("a", new StringBuilder("x%yz"));
+ map.put(null, "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+ try {
+ builder.resolveTemplates(map);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesMapThrowsIAEOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:963;
+ *
+ * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesMapThrowsIAEOnNullValueTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("a", null);
+ map.put("b", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+ try {
+ builder.resolveTemplates(map);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesMapBooleanSlashEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:965;
+ *
+ * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+ * instance using supplied name-value pairs.
+ */
+ @Test
+ public void resolveTemplatesMapBooleanSlashEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/%25test1"));
+ map.put("z", new Object() {
+ public String toString() {
+ return "fred@example.com";
+ }
+ });
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ uri = builder.resolveTemplates(map, true).build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplatesMapBooleanSlashNotEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:965;
+ *
+ * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+ * instance using supplied name-value pairs.
+ */
+ @Test
+ public void resolveTemplatesMapBooleanSlashNotEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("x", new StringBuilder("x%yz"));
+ map.put("y", new StringBuffer("/path-absolute/test1"));
+ map.put("z", new Object() {
+ public String toString() {
+ return "fred@example.com";
+ }
+ });
+ map.put("w", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+ uri = builder.resolveTemplates(map, false).build();
+ gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:966;
+ *
+ * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesMapBooleanThrowsIAEOnNullNameTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("a", new StringBuilder("x%yz"));
+ map.put(null, "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+ try {
+ builder.resolveTemplates(map, true);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:966;
+ *
+ * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesMapBooleanThrowsIAEOnNullValueTest()
+ throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("a", null);
+ map.put("b", "path-rootless/test2");
+ UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+ try {
+ builder.resolveTemplates(map, false);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:966;
+ *
+ * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesMapBooleanThrowsIAEOnNullMapTest() throws Fault {
+ UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+ try {
+ builder.resolveTemplates((Map<String, Object>) null, false);
+ fault("IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException has been thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesFromEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:967;
+ *
+ * @test_Strategy: Resolve one or more URI templates in this instance using
+ * supplied name-value pairs.
+ */
+ @Test
+ public void resolveTemplatesFromEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("v", new StringBuilder("path-rootless%2Ftest2"));
+ map.put("w", new StringBuilder("x%25yz"));
+ map.put("x", new Object() {
+ public String toString() {
+ return "%2Fpath-absolute%2F%2525test1";
+ }
+ });
+ map.put("y", "fred@example.com");
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ builder = builder.resolveTemplatesFromEncoded(map);
+ uri = builder.build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplatesFromEncodedPercentEncodedTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:967;
+ *
+ * @test_Strategy: Resolve one or more URI templates in this instance using
+ * supplied name-value pairs. All % characters in the stringified values that
+ * are not followed by two hexadecimal numbers will be encoded.
+ */
+ @Test
+ public void resolveTemplatesFromEncodedPercentEncodedTest() throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("v", new StringBuilder("path-rootless%2Ftest2"));
+ map.put("w", new StringBuilder("x%yz"));
+ map.put("x", new Object() {
+ public String toString() {
+ return "%2Fpath-absolute%2F%2525test1";
+ }
+ });
+ map.put("y", "fred@example.com");
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ builder = builder.resolveTemplatesFromEncoded(map);
+ uri = builder.build();
+ gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+ assertPassAndLog();
+ }
+
+ /*
+ * @testName: resolveTemplatesFromEncodedThrowsNullOnNullNameTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:967;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesFromEncodedThrowsNullOnNullNameTest()
+ throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put(null, "aa");
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ try {
+ builder.resolveTemplatesFromEncoded(map);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesFromEncodedThrowsNullOnNullValueTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:967;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesFromEncodedThrowsNullOnNullValueTest()
+ throws Fault {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("v", null);
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ try {
+ builder.resolveTemplatesFromEncoded(map);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException thrown as expected", e);
+ }
+ }
+
+ /*
+ * @testName: resolveTemplatesFromEncodedThrowsNullOnNullMapTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:967;
+ *
+ * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+ * or any of the names or values in the map is null.
+ */
+ @Test
+ public void resolveTemplatesFromEncodedThrowsNullOnNullMapTest()
+ throws Fault {
+ UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+ try {
+ builder.resolveTemplatesFromEncoded((Map<String, Object>) null);
+ fault("No exception has been thrown");
+ } catch (IllegalArgumentException e) {
+ logMsg("IllegalArgumentException thrown as expected", e);
+ }
+ }
+
+
+ // ////////////////////////////////////////////////////////////////////////
+ /**
+ * This is the pattern used in all over the tests. Add to stringBuilder what's
+ * expected, what's got and set pass value.
+ *
+ * @param got
+ * @param expected
+ * @return got.compareToIgnoreCase(expected)
+ */
+ private int gotExpectedPass(String got, String expected) {
+ got = got.replace("%2f", "%2F");
+ int compare = got.compareToIgnoreCase(expected);
+ gotExpectedPass(compare != 0, got, expected);
+ return compare;
+ }
+
+ private boolean gotExpectedPass(boolean conditionFalse, String got,
+ String expected) {
+ if (conditionFalse) {
+ pass = false;
+ sb.append("Incorrect URI returned: ").append(got);
+ sb.append(", expecting ").append(expected);
+ } else
+ sb.append("Got expected return: ").append(expected);
+ sb.append(newline);
+ return conditionFalse;
+
+ }
+
+ private void assertPassAndLog() throws Fault {
+ assertTrue(pass, "At least one assertion failed:"+ sb.toString());
+ TestUtil.logTrace(sb.toString());
+ }
+
+ private static String[] getOrigUris() {
+ String[] uris_orig = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+ "ftp://ftp.is.co.za/rfc/rfc1808.txt", "mailto:java-net@java.sun.com",
+ "mailto:java-net@java.sun.com", "news:comp.lang.java",
+ "news:comp.lang.java", "urn:isbn:096139210x",
+ "http://www.ietf.org/rfc/rfc2396.txt",
+ "http://www.ietf.org/rfc/rfc2396.txt",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+ "tel:+1-816-555-1212", "telnet://192.0.2.16:80/",
+ "telnet://192.0.2.16:80/",
+ "foo://example.com:8042/over/there?name=ferret#nose",
+ "foo://example.com:8042/over/there?name=ferret#nose" };
+ return uris_orig;
+ }
+
+ private static URI[] getReplacementUris() throws Fault {
+ URI uris_replace[] = { null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null };
+
+ try {
+ uris_replace[0] = new URI("http", "//ftp.is.co.za/rfc/rfc1808.txt", null);
+ uris_replace[1] = new URI(null, "ftp.is.co.za", "/test/rfc1808.txt", null,
+ null);
+ uris_replace[2] = new URI("mailto", "java-net@java.sun.com", null);
+ uris_replace[3] = new URI(null, "testuser@sun.com", null);
+ uris_replace[4] = new URI("http", "//comp.lang.java", null);
+ uris_replace[5] = new URI(null, "news.lang.java", null);
+ uris_replace[6] = new URI("urn:isbn:096139210x");
+ uris_replace[7] = new URI(null, "//www.ietf.org/rfc/rfc2396.txt", null);
+ uris_replace[8] = new URI(null, "www.ietf.org", "/rfc/rfc2396.txt", null,
+ null);
+ uris_replace[9] = new URI("ldap", "//[2001:db8::7]/c=GB?objectClass?one",
+ null);
+ uris_replace[10] = new URI(null, "//[2001:db8::7]/c=GB?objectClass?one",
+ null);
+ uris_replace[11] = new URI("tel", "+1-816-555-1212", null);
+ uris_replace[12] = new URI(null, "+1-866-555-1212", null);
+ uris_replace[13] = new URI("telnet", "//192.0.2.16:80/", null);
+ uris_replace[14] = new URI(null, "//192.0.2.16:81/", null);
+ uris_replace[15] = new URI("http",
+ "//example.com:8042/over/there?name=ferret", null);
+ uris_replace[16] = new URI(null,
+ "//example.com:8042/over/there?name=ferret", "mouth");
+ } catch (Exception ex) {
+ throw new Fault(
+ "========== Exception thrown constructing replacing URIs: "
+ + ex.getMessage() + newline);
+ }
+ return uris_replace;
+ }
+
+ private static String[] getExpectedUris() {
+ String[] uris_expect = { "http://ftp.is.co.za/rfc/rfc1808.txt",
+ "ftp://ftp.is.co.za/test/rfc1808.txt", "mailto:java-net@java.sun.com",
+ "mailto:testuser@sun.com", "http://comp.lang.java",
+ "news:news.lang.java", "urn:isbn:096139210x",
+ "http://www.ietf.org/rfc/rfc2396.txt",
+ "http://www.ietf.org/rfc/rfc2396.txt",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one",
+ "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+ "tel:+1-866-555-1212", "telnet://192.0.2.16:80/",
+ "telnet://192.0.2.16:81/",
+ "http://example.com:8042/over/there?name=ferret#nose",
+ "foo://example.com:8042/over/there?name=ferret#mouth" };
+ return uris_expect;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java
new file mode 100644
index 0000000..fbfbca0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2021 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.uribuilder;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.Response;
+
+@Path(value = "/TestPath")
+public class TestPath {
+
+ @GET
+ public Response getPlain() {
+ return Response.ok().build();
+ }
+
+ @Path(value = "/sub")
+ public Response headSub() {
+ return Response.ok().build();
+ }
+
+ @Path(value = "sub1")
+ public Response test1() {
+ return Response.ok().build();
+ }
+
+ @Path(value = "/sub2")
+ public Response test1(@QueryParam("testName") String test) {
+ return Response.ok(test).build();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java
new file mode 100644
index 0000000..4f8ed3c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2007, 2021 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.uribuilder;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.core.Response;
+
+public class TestPathBad {
+ @GET
+ public Response getPlain() {
+ return Response.ok().build();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java
new file mode 100644
index 0000000..a4c74d7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 2021 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;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.Path;
+
+/**
+ * This class is a superclass used in MessageBodyWriters which need to check
+ *
+ * @Path annotation value
+ */
+public abstract class AbstractMessageBodyRW {
+
+ public static String getPathValue(Annotation[] annotations) {
+ return getSpecifiedAnnotationValue(annotations, Path.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T extends Annotation> T getSpecifiedAnnotation(
+ Annotation[] annotations, Class<T> clazz) {
+ T t = null;
+ for (Annotation a : annotations)
+ if (a.annotationType() == clazz)
+ t = (T) a;
+ return t != null ? t : null;
+ }
+
+ public static <T extends Annotation> String getSpecifiedAnnotationValue(
+ Annotation[] annotations, Class<T> clazz) {
+ T t = getSpecifiedAnnotation(annotations, clazz);
+ try {
+ Method m = clazz.getMethod("value");
+ return (String) m.invoke(t);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+}
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
new file mode 100644
index 0000000..f69dd67
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
@@ -0,0 +1,1212 @@
+ /*
+ * Copyright (c) 2007, 2021 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;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.nio.charset.StandardCharsets;
+
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpState;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.validation.CheckOneOfStatusesTokenizedValidator;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.common.util.Data;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+/**
+ *
+ * @author dianne jiao
+ * @author jan supol
+ */
+//public abstract class JAXRSCommonClient extends ServiceEETest {
+public abstract class JAXRSCommonClient {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * TS Webserver host property
+ */
+ protected static final String SERVLETHOSTPROP = "webServerHost";
+
+ /**
+ * TS Webserver port property
+ */
+ protected static final String SERVLETPORTPROP = "webServerPort";
+
+ /**
+ * TS home property
+ */
+ protected static final String TSHOME = "ts_home";
+
+ /**
+ * Test properties
+ */
+ protected static final Hashtable<Property, String> TEST_PROPS = new Hashtable<Property, String>();
+
+ /**
+ * StatusCode property
+ */
+ protected static final String STATUS_CODE = "STATUS_CODE";
+
+ /**
+ * Request property
+ */
+ protected static final String REQUEST = "REQUEST";
+
+ /**
+ * Request headers property
+ */
+ protected static final String REQUEST_HEADERS = "REQUEST_HEADERS";
+
+ /**
+ * Goldenfile property
+ */
+ protected static final String GOLDENFILE = "goldenfile";
+
+ /**
+ * Search string property
+ */
+ protected static final String SEARCH_STRING = "SEARCH_STRING";
+
+ /**
+ * Search string case insensitive property
+ */
+ protected String TESTDIR = null;
+
+ /**
+ * Goldenfile directory
+ */
+ protected String GOLDENFILEDIR = "/src/web";
+
+ /**
+ * Default request method
+ */
+ protected static final String GET = "GET ";
+
+ /**
+ * HTTP 1.0
+ */
+ protected static final String HTTP10 = " HTTP/1.0";
+
+ /**
+ * HTTP 1.1
+ */
+ protected static final String HTTP11 = " HTTP/1.1";
+
+ /**
+ * Forward slash
+ */
+ protected static final String SL = "/";
+
+ /**
+ * Goldenfile suffix
+ */
+ protected static final String GF_SUFFIX = ".gf";
+
+ /**
+ * JSP suffix
+ */
+ /**
+ * Current test name
+ */
+ protected String _testName = null;
+
+ /**
+ * location of _tsHome
+ */
+ protected String _tsHome = null;
+
+ /**
+ * Context root of target tests
+ */
+ public String _contextRoot = null;
+
+ /**
+ * General file/request URI for both gfiles and tests
+ */
+ protected String _generalURI = null;
+
+ /**
+ * Target webserver hostname
+ */
+ protected String _hostname = null;
+
+ /**
+ * Target webserver port
+ */
+ protected int _port = 0;
+
+ /**
+ * HttpState that may be used for multiple invocations requiring state.
+ */
+ protected HttpState _state = null;
+
+ /**
+ * Test case.
+ */
+ protected WebTestCase _testCase = null;
+
+ /**
+ * Use saved state.
+ */
+ protected boolean _useSavedState = false;
+
+ /**
+ * Save state.
+ */
+ protected boolean _saveState = false;
+
+ protected boolean _redirect = false;
+
+ public static final String newline = System.getProperty("line.separator");
+
+ public static final String servletAdaptor = System.getProperty("servlet_adaptor", "org.glassfish.jersey.servlet.ServletContainer");
+
+ public static final String indent = " ";
+
+ /**
+ * List of possible requests
+ */
+ protected enum Request {
+ GET, PUT, POST, HEAD, OPTIONS, DELETE, TRACE
+ }
+
+ /**
+ * the list of properties to be put into a property table
+ */
+ protected enum Property {
+ APITEST, BASIC_AUTH_PASSWD, BASIC_AUTH_REALM, BASIC_AUTH_USER, //
+ CONTENT, DONOTUSEServletName, EXPECT_RESPONSE_BODY, EXPECTED_HEADERS, //
+ FOLLOW_REDIRECT, GOLDENFILE, IGNORE_BODY, IGNORE_STATUS_CODE, //
+ REASON_PHRASE, REQUEST, REQUEST_HEADERS, RESPONSE_MATCH, SAVE_STATE, //
+ SEARCH_STRING, SEARCH_STRING_IGNORE_CASE, STANDARD, STATUS_CODE, //
+ STRATEGY, TEST_NAME, UNEXPECTED_HEADERS, UNEXPECTED_RESPONSE_MATCH, //
+ UNORDERED_SEARCH_STRING, USE_SAVED_STATE;
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+ /**
+ * <code>setTestDir</code> sets the current test directory.
+ *
+ * @param testDir
+ * a <code>String</code> value
+ */
+ public void setTestDir(String testDir) {
+ TestUtil.logTrace("[JAXRSCommonClient] setTestDir");
+ TESTDIR = testDir;
+ }
+
+ public void setContextRoot(String root) {
+ TestUtil.logTrace("[JAXRSCommonClient] Contextroot set at " + root);
+ _contextRoot = root;
+ }
+
+ public String getContextRoot() {
+ TestUtil.logTrace("[JAXRSCommonClient]getContextRoot");
+ return _contextRoot;
+ }
+
+ /**
+ * <code>setup</code> is by the test harness to initialize the tests.
+ *
+ * @param args
+ * a <code>String[]</code> value
+ * @param p
+ * a <code>Properties</code> value
+ * @exception Fault
+ * if an error occurs
+ */
+ //public void setup(String[] args, Properties p) {
+ public void setup() {
+ TestUtil.logTrace("setup method JAXRSCommonClient");
+
+ String hostname = System.getProperty(SERVLETHOSTPROP);
+ String portnum = System.getProperty(SERVLETPORTPROP);
+ //String tshome = p.getProperty(TSHOME);
+
+ assertTrue(!isNullOrEmpty(hostname),
+ "[JAXRSCommonClient] 'webServerHost' was not set.");
+ _hostname = hostname.trim();
+ assertTrue(!isNullOrEmpty(portnum),
+ "[JAXRSCommonClient] 'webServerPort' was not set.");
+ _port = Integer.parseInt(portnum.trim());
+
+ //assertTrue(!isNullOrEmpty(tshome),
+ // "[JAXRSCommonClient] 'tshome' was not set in the build.properties.");
+ //_tsHome = tshome.trim();
+
+ TestUtil.logMsg("[JAXRSCommonClient] Test setup OK");
+ }
+
+ /**
+ * <code>cleanup</code> is called by the test harness to cleanup after text
+ * execution
+ *
+ * @exception Fault
+ * if an error occurs
+ */
+ public void cleanup() throws Fault {
+ TestUtil.logMsg("[JAXRSCommonClient] Test cleanup OK");
+ }
+
+ /*
+ * protected methods
+ * ========================================================================
+ */
+ /**
+ * <PRE>
+ * Invokes a test based on the properties
+ * stored in TEST_PROPS. Once the test has completed,
+ * the properties in TEST_PROPS will be cleared.
+ * </PRE>
+ *
+ * @throws Fault
+ * If an error occurs during the test run
+ */
+ protected void invoke() throws Fault {
+ TestUtil.logTrace("[JAXRSCommonClient] invoke");
+ try {
+ _testCase = new WebTestCase();
+ setTestProperties(_testCase);
+ TestUtil.logTrace("[JAXRSCommonClient] EXECUTING");
+ if (_useSavedState && _state != null) {
+ _testCase.getRequest().setState(_state);
+ }
+ if (_redirect != false) {
+ TestUtil.logTrace("##########Call setFollowRedirects");
+ _testCase.getRequest().setFollowRedirects(_redirect);
+ }
+ _testCase.execute();
+ if (_saveState) {
+ _state = _testCase.getResponse().getState();
+ }
+ } catch (TestFailureException tfe) {
+ Throwable t = tfe.getRootCause();
+ if (t != null) {
+ TestUtil.logErr("Root cause of Failure: " + t.getMessage(), t);
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ } else if (t instanceof Error) {
+ throw (Error) t;
+ } else {
+ throw new RuntimeException(t);
+ }
+ }
+ throw new Fault("[JAXRSCommonClient] " + _testName
+ + " failed! Check output for cause of failure.", tfe);
+ } finally {
+ _useSavedState = false;
+ _saveState = false;
+ _redirect = false;
+ clearTestProperties();
+ }
+ }
+
+ /**
+ * <PRE>
+ * Sets the appropriate test properties based
+ * on the values stored in TEST_PROPS
+ * </PRE>
+ */
+ protected void setTestProperties(WebTestCase testCase) {
+ TestUtil.logTrace("[JAXRSCommonClient] setTestProperties");
+
+ setStandardProperties(TEST_PROPS.get(Property.STANDARD), testCase);
+ setApiTestProperties(TEST_PROPS.get(Property.APITEST), testCase);
+
+ if (TEST_PROPS.get(Property.STATUS_CODE) == null)
+ setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+
+ HttpRequest req = testCase.getRequest();
+
+ // Check for a request object. If doesn't exist, then
+ // check for a REQUEST property and create the request object.
+ if (req == null)
+ req = setWebTestCaseRequest(testCase, null);
+ setWebTestCaseProperties(testCase, req);
+ }
+
+ protected HttpRequest setWebTestCaseRequest(WebTestCase testCase,
+ HttpRequest req) {
+ String request = TEST_PROPS.get(Property.REQUEST);
+ boolean isRequest = false;
+ for (Request r : Request.values())
+ if (request.startsWith(r.name()))
+ isRequest = true;
+ if (request.endsWith(HTTP10) || request.endsWith(HTTP11))
+ isRequest = true;
+ if (isRequest) {
+ // user has overridden default request behavior
+ req = createHttpRequest(request, _hostname, _port);
+ testCase.setRequest(req);
+ } else {
+ req = createHttpRequest(getTSRequest(request), _hostname, _port);
+ testCase.setRequest(req);
+ }
+ return req;
+ }
+
+ protected void setWebTestCaseProperties(WebTestCase testCase,
+ HttpRequest req) {
+ Property key = null;
+ String value = null;
+ // process the remainder of the properties
+ for (Enumeration<Property> e = TEST_PROPS.keys(); e.hasMoreElements();) {
+ key = e.nextElement();
+ value = TEST_PROPS.get(key);
+ switch (key) {
+ case APITEST:
+ break;
+ case BASIC_AUTH_PASSWD:
+ case BASIC_AUTH_REALM:
+ case BASIC_AUTH_USER:
+ String user = TEST_PROPS.get(Property.BASIC_AUTH_USER);
+ String password = TEST_PROPS.get(Property.BASIC_AUTH_PASSWD);
+ String realm = TEST_PROPS.get(Property.BASIC_AUTH_REALM);
+ req.setAuthenticationCredentials(user, password,
+ HttpRequest.BASIC_AUTHENTICATION, realm);
+ break;
+ case CONTENT:
+ req.setContent(value);
+ break;
+ case DONOTUSEServletName:
+ break;
+ case EXPECT_RESPONSE_BODY:
+ // FIXME
+ // setExpectResponseBody(false);
+ break;
+ case EXPECTED_HEADERS:
+ testCase.addExpectedHeader(value);
+ break;
+ case FOLLOW_REDIRECT:
+ TestUtil.logTrace("##########Found redirect Property");
+ _redirect = true;
+ break;
+ case GOLDENFILE:
+ StringBuffer sb = new StringBuffer(50);
+ sb.append(_tsHome).append(GOLDENFILEDIR);
+ sb.append(_generalURI).append(SL);
+ sb.append(value);
+ testCase.setGoldenFilePath(sb.toString());
+ break;
+ case IGNORE_BODY:
+ // FIXME
+ // setIgnoreResponseBody(true);
+ testCase.setGoldenFilePath(null);
+ break;
+ case IGNORE_STATUS_CODE:
+ testCase.setExpectedStatusCode("-1");
+ break;
+ case REASON_PHRASE:
+ testCase.setExpectedReasonPhrase(value);
+ break;
+ case REQUEST:
+ break;
+ case REQUEST_HEADERS:
+ req.addRequestHeader(value);
+ break;
+ case RESPONSE_MATCH:
+ // setResponseMatch(TEST_PROPS.getProperty(key));
+ break;
+ case SAVE_STATE:
+ _saveState = true;
+ break;
+ case SEARCH_STRING:
+ testCase.setResponseSearchString(value);
+ break;
+ case SEARCH_STRING_IGNORE_CASE:
+ testCase.setResponseSearchStringIgnoreCase(value);
+ break;
+ case STANDARD:
+ break;
+ case STATUS_CODE:
+ if (value.contains("|"))
+ testCase.setStrategy(
+ CheckOneOfStatusesTokenizedValidator.class.getName());
+ testCase.setExpectedStatusCode(value);
+ break;
+ case STRATEGY:
+ testCase.setStrategy(value);
+ break;
+ case TEST_NAME:
+ // testName = TEST_PROPS.getProperty(key);
+ break;
+ case UNEXPECTED_HEADERS:
+ testCase.addUnexpectedHeader(value);
+ break;
+ case UNEXPECTED_RESPONSE_MATCH:
+ testCase.setUnexpectedResponseSearchString(value);
+ break;
+ case UNORDERED_SEARCH_STRING:
+ testCase.setUnorderedSearchString(value);
+ break;
+ case USE_SAVED_STATE:
+ _useSavedState = true;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Create request <type> /<contextroot>/<path> HTTP/1.1. ContextRoot is
+ * defined in every client.
+ *
+ * @param type
+ * PUT, GET, POST, ...
+ * @param path
+ * path defined in a servlet
+ * @return String representing HTTP request
+ */
+ protected String buildRequest(String type, String... path) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(type).append(" ").append(_contextRoot).append(SL);
+ for (String segment : path)
+ sb.append(segment);
+ sb.append(HTTP11);
+ return sb.toString();
+ }
+
+ protected String buildRequest(Request type, String... path) {
+ return buildRequest(type.name(), path);
+ }
+
+ protected String buildRequest10(Request type, String... path) {
+ return buildRequest(type, path).replace(HTTP11, HTTP10);
+ }
+
+ /**
+ * Create counterpart to @Produces
+ *
+ * @param type
+ * @return Accept:{@code type}.{@link #toString()}
+ */
+ protected static String buildAccept(MediaType type) {
+ return buildHeaderMediaType("Accept", type);
+ }
+
+ /**
+ * Create counterpart to @Consumes
+ *
+ * @param type
+ * @return
+ */
+ protected static String buildContentType(MediaType type) {
+ return buildHeaderMediaType("Content-Type", type);
+ }
+
+ protected static String buildHeaderMediaType(String header, MediaType type) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(header).append(":").append(type.getType()).append(SL);
+ sb.append(type.getSubtype());
+ return sb.toString();
+ }
+
+ public static String editWebXmlString(InputStream inStream) throws IOException{
+ String line;
+ String webXmlTemplate = "";
+ try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(inStream, StandardCharsets.UTF_8))) {
+ while ((line = bufReader.readLine()) != null) {
+ webXmlTemplate = webXmlTemplate + line + System.lineSeparator();
+ }
+ }
+
+ String webXml = webXmlTemplate.replaceAll("servlet_adaptor", servletAdaptor);
+ return webXml;
+ }
+
+ /**
+ * @return http response body as string
+ * @throws Fault
+ * when an error occur
+ */
+ protected String getResponseBody() throws Fault {
+ try {
+ jakarta.ws.rs.tck.common.webclient.http.HttpResponse response;
+ response = _testCase.getResponse();
+ boolean isNull = response.getResponseBodyAsRawStream() == null;
+ return isNull ? null : response.getResponseBodyAsString();
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+
+ /**
+ * @return http response body as string
+ * @throws Fault
+ * when an error occur
+ */
+ protected String[] getResponseHeaders() throws Fault {
+ Header[] headerEntities = _testCase.getResponse().getResponseHeaders();
+ String[] headers = new String[headerEntities.length];
+ for (int i = 0; i != headerEntities.length; i++)
+ headers[i] = headerEntities[i].toString();
+ return headers;
+ }
+
+ /**
+ * @param s
+ * the header to search
+ * @throws Fault
+ * when header not found
+ */
+ protected void assertResponseHeadersContain(String s) throws Fault {
+ boolean found = false;
+ for (String header : getResponseHeaders())
+ if (header.contains(s)) {
+ found = true;
+ break;
+ }
+ assertTrue(found, "Response headers do not contain"+ s);
+ }
+
+ /**
+ * @param s
+ * the entity to search
+ * @throws Fault
+ * when entity not found
+ */
+ protected void assertResponseBodyContain(String s) throws Fault {
+ boolean found = getResponseBody().contains(s);
+ assertTrue(found, "Response body does not contain"+ s);
+ }
+
+ /**
+ * get HttpResponse#statusCode
+ *
+ * @return JAXRS Response.Status equivalent of HttpResponse#statusCode
+ */
+ protected Response.Status getResponseStatusCode() {
+ String status = _testCase.getResponse().getStatusCode();
+ return Response.Status.fromStatusCode(Integer.parseInt(status));
+ }
+
+ /**
+ * Set TEST_PROPS property value. If it already exists, the value is appended
+ */
+ protected void setProperty(String key, String value) {
+ Property property = Property.valueOf(key);
+ setProperty(property, value);
+ }
+
+ /*
+ * @since 2.0.1
+ */
+ protected void setProperty(Property key, String... value) {
+ setProperty(key, objectsToString("", (Object[]) value));
+ }
+
+ protected void setProperty(Property key, String value) {
+ String oldValue = TEST_PROPS.get(key);
+ if (oldValue == null) {
+ TEST_PROPS.put(key, value);
+ } else {
+ int len = value.length() + oldValue.length() + 1;
+ StringBuilder combinedValue = new StringBuilder(len);
+ combinedValue.append(oldValue).append("|").append(value);
+ TEST_PROPS.put(key, combinedValue.toString());
+ }
+ }
+
+ protected void clearProperty(Property key) {
+ TEST_PROPS.remove(key);
+ }
+
+ /**
+ * This pattern is used in all subclasses
+ */
+ //protected Status run(String[] args) {
+ // Status s;
+ // s = run(args, new PrintWriter(System.out), new PrintWriter(System.err));
+ // s.exit();
+ // return s;
+ //}
+
+ /**
+ * Asserts that a condition is true.
+ *
+ * @param conditionTrue
+ * tested condition
+ * @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 //
+ assertFault(boolean conditionTrue, Object... message) {
+ assertTrue(conditionTrue, message);
+ }*/
+
+ /**
+ * Asserts that a condition is true.
+ *
+ * @param condition
+ * tested condition
+ * @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) {
+ // if (!condition)
+ // fail(message);
+ //}
+
+ /**
+ * Asserts that a condition is false.
+ *
+ * @param condition
+ * tested condition
+ * @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);
+ }*/
+
+ /**
+ * Asserts that two objects are equal. When instances of Comparable, such as
+ * String, compareTo is used.
+ *
+ * @param first
+ * first object
+ * @param second
+ * second object
+ * @param message
+ * a space separated message[i].toString() compilation for
+ * i=<0,message.length)
+ * @
+ * when objects are not equal with message provided
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> void //
+ assertEquals(T first, T second, Object... message) {
+ if (first == null && second == null)
+ return;
+ assertFalse(first == null && second != null, message.toString());
+ assertFalse(first != null && second == null, message.toString());
+ if (first instanceof Comparable)
+ assertTrue(((Comparable<T>) first).compareTo(second) == 0, message.toString());
+ else
+ assertTrue(first.equals(second), message.toString());
+ }
+
+ public static <T> void //
+ assertEqualsInt(int first, int second, Object... message) {
+ assertTrue(first == second, message.toString());
+ }
+
+ public static <T> void //
+ assertEqualsLong(long first, long second, Object... message)
+ {
+ assertTrue(first == second, message.toString());
+ }
+
+ public static <T> void //
+ assertEqualsBool(boolean first, boolean second, Object... message)
+ {
+ assertTrue(first == second, message.toString());
+ }
+
+ /**
+ * Asserts that an object is null.
+ *
+ * @param object
+ * Assert that object is not null
+ * @param message
+ * a space separated message[i].toString() compilation for
+ * i=<0,message.length)
+ */
+ public static void //
+ assertNull(Object object, Object... message) {
+ assertTrue(object == null, message.toString());
+ }
+
+ /**
+ * Asserts that an object is not null.
+ *
+ * @param object
+ * Assert that object is not null
+ * @param message
+ * a space separated message[i].toString() compilation for
+ * i=<0,message.length)
+ */
+ public static void //
+ assertNotNull(Object object, Object... message) {
+ assertTrue(object != null, message.toString());
+ }
+
+ /**
+ * Throws Fault with space separated objects[1],object[2],...,object[n]
+ * message
+ *
+ * @param objects
+ * objects whose toString() results will be added to Fault message
+ * @throws Fault
+ * fault with space separated objects.toString values
+ */
+ public static void fault(Object... objects) throws Fault {
+ throw new Fault(objectsToString(objects));
+ }
+
+ /**
+ * Assert that given substring is a substring of given string
+ *
+ * @param string
+ * the string to search substring in
+ * @param substring
+ * the substring to be searched in a given string
+ * @param message
+ * space separated message values to be thrown
+ * @
+ * throws
+ */
+ public static void assertContains(String string, String substring,
+ Object... message) {
+ assertTrue(string.contains(substring), message.toString());
+ }
+
+ /**
+ * Assert that given substring is a substring of given string, case
+ * insensitive
+ *
+ * @param string
+ * the string to search substring in
+ * @param substring
+ * the substring to be searched in a given string
+ * @param message
+ * space separated message values to be thrown
+ * @
+ */
+ public static void assertContainsIgnoreCase(String string, String substring,
+ Object... message) {
+ assertTrue(string.toLowerCase().contains(substring.toLowerCase()), message.toString());
+ }
+
+ /**
+ * Assert that given subtext.toString() subject is a substring of given text
+ *
+ * @param text
+ * the text.toString() object to search subtext.toString() in
+ * @param subtext
+ * the subtext.toString() to be searched in a given text.toString()
+ * @param message
+ * space separated message values to be thrown
+ * @
+ */
+ public static <T> void assertContains(T text, T subtext, Object... message)
+ {
+ assertContains(text.toString(), subtext.toString(), message.toString());
+ }
+
+ /**
+ * Assert that given subtext.toString() subject is a substring of given text,
+ * case insensitive
+ *
+ * @param text
+ * the text.toString() object to search subtext.toString() in
+ * @param subtext
+ * the subtext.toString() to be searched in a given text.toString()
+ * @param message
+ * space separated message values to be thrown
+ * @
+ */
+ public static <T> void assertContainsIgnoreCase(T text, T subtext,
+ Object... message) {
+ assertContainsIgnoreCase(text.toString(), subtext.toString(), message.toString());
+ }
+
+ /**
+ * Searches an encapsulated exception cause in parent exception
+ */
+ protected static <T extends Throwable> T assertCause(Throwable parent,
+ Class<T> wrapped, Object... msg) {
+ T t = hasCause(parent, wrapped);
+ assertNotNull(t, msg);
+ return t;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends Throwable> T //
+ hasCause(Throwable parent, Class<? extends Throwable> cause) {
+ while (parent != null) {
+ if (cause.isInstance(parent))
+ return (T) parent;
+ parent = parent.getCause();
+ }
+ return null;
+ }
+
+ public static String getStatusCode(Response.Status status) {
+ return String.valueOf(status.getStatusCode());
+ }
+
+ public static void logMsg(Object... msg) {
+ TestUtil.logMsg(objectsToString(msg));
+ }
+
+ public static void logTrace(Object... msg) {
+ TestUtil.logTrace(objectsToString(msg));
+ }
+
+ /**
+ * Use rather this method than
+ * {@link JaxrsUtil#iterableToString(String, Iterable)} since not all wars
+ * (for servlet vehicle, api) do contain JaxrsUtil
+ *
+ * @param objects
+ * @return objects in a single string , each object separated by " "
+ */
+ protected static String objectsToString(Object... objects) {
+ return objectsToString(" ", objects);
+ }
+
+ /**
+ * @since 2.0.1
+ */
+ protected static String objectsToString(String delimiter, Object... objects) {
+ StringBuilder sb = new StringBuilder();
+ for (Object o : objects)
+ sb.append(o).append(delimiter);
+ return sb.toString().trim();
+ }
+
+ /*
+ * private methods
+ * ========================================================================
+ */
+ private String getTSRequest(String request) {
+ TestUtil.logTrace("[JAXRSCommonClient] getTSRequest");
+ StringBuffer finReq = new StringBuffer(50);
+ finReq.append(GET).append(_contextRoot).append(SL).append(_generalURI);
+ finReq.append(SL).append(request).append(HTTP11);
+ return finReq.toString();
+ }
+
+ /**
+ * Clears the contents of TEST_PROPS
+ */
+ protected void clearTestProperties() {
+ TEST_PROPS.clear();
+ }
+
+ protected boolean isNullOrEmpty(String val) {
+ return val == null || val.trim().equals("");
+ }
+
+ private InetAddress[] _addrs = null;
+
+ protected String _servlet = null;
+
+ /**
+ * Sets the request, testname, and a search string for test passed. A search
+ * is also added for test failure. If found, the test will fail.
+ *
+ * @param testValue
+ * - a logical test identifier
+ * @param testCase
+ * - the current test case
+ */
+ private void setApiTestProperties(String testValue, WebTestCase testCase) {
+ TestUtil.logTrace("[JAXRSCommonClient] setApiTestProperties");
+
+ if (testValue == null) {
+ return;
+ }
+
+ // An API test consists of a request with a request parameter of
+ // testname, a search string of Test PASSED, and a logical test name.
+
+ // set the testname
+ _testName = testValue;
+
+ // set the request
+ StringBuffer sb = new StringBuffer(50);
+ if ((_servlet != null)
+ && (TEST_PROPS.get(Property.DONOTUSEServletName) == null)) {
+ sb.append(GET).append(_contextRoot).append(SL);
+ sb.append(_servlet).append("?testname=").append(testValue);
+ sb.append(HTTP11);
+ } else {
+ sb.append(GET).append(_contextRoot).append(SL);
+ sb.append(testValue).append(HTTP10);
+ }
+ System.out.println("REQUEST LINE: " + sb.toString());
+
+ HttpRequest req = createHttpRequest(sb.toString(), _hostname, _port);
+ testCase.setRequest(req);
+
+ String value = TEST_PROPS.get(Property.SEARCH_STRING);
+ if (isNullOrEmpty(value)) {
+ testCase.setResponseSearchString(Data.PASSED);
+ testCase.setUnexpectedResponseSearchString(Data.FAILED);
+ }
+ }
+
+ protected HttpRequest createHttpRequest(String requestLine, String host,
+ int port) {
+ return new HttpRequest(requestLine, host, port);
+ }
+
+ /**
+ * Consists of a test name, a request, and a goldenfile.
+ *
+ * @param testValue
+ * - a logical test identifier
+ * @param testCase
+ * - the current test case
+ */
+ private void setStandardProperties(String testValue, WebTestCase testCase) {
+ TestUtil.logTrace("[JAXRSCommonClient] setStandardProperties");
+
+ if (testValue == null) {
+ return;
+ }
+ // A standard test sets consists of a testname
+ // a request, and a goldenfile. The URI is not used
+ // in this case since the JSP's are assumed to be located
+ // at the top of the contextRoot
+ String req;
+
+ // set the testname
+ _testName = testValue;
+
+ if (_servlet != null) {
+ req = buildRequest(Request.GET, _servlet, "?testname=", testValue);
+ } else {
+ req = buildRequest10(Request.GET, testValue);
+ }
+ System.out.println("REQUEST LINE: " + req);
+ System.out.println("_hostname=" + _hostname);
+ HttpRequest httpReq = createHttpRequest(req, _hostname, _port);
+ testCase.setRequest(httpReq);
+
+ // set the goldenfile
+ StringBuffer sb = new StringBuffer(50);
+ sb.append(_tsHome).append(GOLDENFILEDIR);
+ sb.append(_generalURI).append(SL);
+ sb.append(testValue).append(GF_SUFFIX);
+ testCase.setGoldenFilePath(sb.toString());
+ }
+
+ /**
+ * Sets the name of the servlet to use when building a request for a single
+ * servlet API test.
+ *
+ * @param servlet
+ * - the name of the servlet
+ */
+ protected void setServletName(String servlet) {
+ TestUtil.logTrace("[JAXRSCommonClient] setServletName");
+ _servlet = servlet;
+ }
+
+ protected String getServletName() {
+ return _servlet;
+ }
+
+ protected String getLocalInterfaceInfo(boolean returnAddresses) {
+ String result = null;
+ initInetAddress();
+ if (_addrs.length != 0) {
+ StringBuffer sb = new StringBuffer(32);
+ if (!returnAddresses) {
+ // localhost might not show up if aliased
+ sb.append("localhost,");
+ } else {
+ // add 127.0.0.1
+ sb.append("127.0.0.1,");
+ }
+
+ for (int i = 0; i < _addrs.length; i++) {
+ if (returnAddresses) {
+ String ip = _addrs[i].getHostAddress();
+ if (!ip.equals("127.0.0.1")) {
+ if (ip.contains("%")) {
+ int scope_id = ip.indexOf("%");
+ ip = ip.substring(0, scope_id);
+ }
+ sb.append(ip);
+ }
+ } else {
+ String host = _addrs[i].getCanonicalHostName();
+ if (!host.equals("localhost")) {
+ sb.append(host);
+ }
+ }
+ if (i + 1 != _addrs.length) {
+ sb.append(",");
+ }
+ }
+ result = sb.toString();
+ TestUtil.logTrace("[AbstractUrlClient] Interface info: " + result);
+ }
+ return result;
+ }
+
+ private void initInetAddress() {
+ if (_addrs == null) {
+ try {
+ _addrs = InetAddress
+ .getAllByName(InetAddress.getLocalHost().getCanonicalHostName());
+ } catch (UnknownHostException uhe) {
+ TestUtil.logMsg(
+ "[AbstractUrlClient][WARNING] Unable to obtain local host information.");
+ }
+ }
+ }
+
+ protected String getAbsoluteUrl() {
+ return getAbsoluteUrl(null);
+ }
+
+ protected String getAbsoluteUrl(String method) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("http://").append(_hostname).append(":").append(_port)
+ .append(getContextRoot());
+ if (method != null)
+ sb.append("/").append(method);
+ return sb.toString();
+ }
+
+ /**
+ * This exception must be thrown to signify a
+ * test failure. Overrides 3 printStackTrace methods to preserve the original
+ * stack trace.
+ *
+ * @author Kyle Grucci
+ */
+
+ public static class Fault extends Exception {
+ private static final long serialVersionUID = -1574745208867827913L;
+
+ public Throwable t;
+
+ /**
+ * creates a Fault with a message
+ */
+ public Fault(String msg) {
+ super(msg);
+ TestUtil.logErr(msg);
+ }
+
+ /**
+ * creates a Fault with a message.
+ *
+ * @param msg
+ * the message
+ * @param t
+ * prints this exception's stacktrace
+ */
+ public Fault(String msg, Throwable t) {
+ super(msg);
+ this.t = t;
+ TestUtil.logErr(msg, t);
+ }
+
+ /**
+ * creates a Fault with a Throwable.
+ *
+ * @param t
+ * the Throwable
+ */
+ public Fault(Throwable t) {
+ super(t);
+ this.t = t;
+ }
+
+ /**
+ * Prints this Throwable and its backtrace to the standard error stream.
+ *
+ */
+ public void printStackTrace() {
+ if (this.t != null) {
+ this.t.printStackTrace();
+ } else {
+ super.printStackTrace();
+ }
+ }
+
+ /**
+ * Prints this throwable and its backtrace to the specified print stream.
+ *
+ * @param s
+ * <code>PrintStream</code> to use for output
+ */
+ public void printStackTrace(PrintStream s) {
+ if (this.t != null) {
+ this.t.printStackTrace(s);
+ } else {
+ super.printStackTrace(s);
+ }
+ }
+
+ /**
+ * Prints this throwable and its backtrace to the specified print writer.
+ *
+ * @param s
+ * <code>PrintWriter</code> to use for output
+ */
+ public void printStackTrace(PrintWriter s) {
+ if (this.t != null) {
+ this.t.printStackTrace(s);
+ } else {
+ super.printStackTrace(s);
+ }
+ }
+
+ @Override
+ public Throwable getCause() {
+ return t;
+ }
+
+ @Override
+ public synchronized Throwable initCause(Throwable cause) {
+ if (t != null)
+ throw new IllegalStateException("Can't overwrite cause");
+ if (!Exception.class.isInstance(cause))
+ throw new IllegalArgumentException("Cause not permitted");
+ this.t = (Exception) cause;
+ return this;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java
new file mode 100644
index 0000000..269b5de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 2021 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;
+
+/**
+ * There were references to the following versions of TCK:
+ * <p>
+ * 1.0 - The tests that used jakarta.ws.rs.tck.common.JAXRSCommonClient as
+ * a superclass.
+ * </p>
+ * <p>
+ * 1.1 - The tests that used jakarta.ws.rs.tck.common.JAXRSCommonClient as
+ * a superclass.
+ * </p>
+ * <p>
+ * 2.0 - The tests that used mainly
+ * jakarta.ws.rs.tck.common.client.JaxrsCommonClient, sometimes
+ * jakarta.ws.rs.tck.common.JAXRSCommonClient as a superclass.
+ * </p>
+ * <p>
+ * 2.0.1 - The code that has been created after JAXRS 2.0 TCK bundle has been
+ * built
+ * </p>
+ * <p>
+ * 2.1 - The code that has been created for JAXRS 2.1 TCK
+ *
+ * @since 2.0.1
+ */
+public interface Version {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java
new file mode 100644
index 0000000..b6e0004
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+
+public class ApacheRequestAdapter extends HttpRequest {
+
+ public ApacheRequestAdapter(String requestLine, String host, int port) {
+ super(requestLine, host, port);
+ }
+
+ /**
+ * <code>getRequestPath</code> returns the request path for this particular
+ * request.
+ *
+ * @return String request path
+ */
+ public String getRequestPath() {
+ return super.getRequestPath();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java
new file mode 100644
index 0000000..16eedcf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.httpclient.Header;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+public class ApacheResponseAdapter extends HttpResponse {
+
+ public ApacheResponseAdapter(jakarta.ws.rs.core.Response response, String host,
+ int port) {
+ super(host, port, port == 443, null, null);
+ this.response = response;
+ this.caser = TextCaser.NONE;
+ }
+
+ public ApacheResponseAdapter(jakarta.ws.rs.core.Response response, String host,
+ int port, TextCaser caser) {
+ this(response, host, port);
+ this.caser = caser;
+ }
+
+ private jakarta.ws.rs.core.Response response;
+
+ private String entity = null;
+
+ private TextCaser caser = null;
+
+ /**
+ * Returns the HTTP status code returned by the server
+ *
+ * @return HTTP status code
+ */
+ public String getStatusCode() {
+ return Integer.toString(response.getStatus());
+ }
+
+ @Override
+ public String getResponseBodyAsString() throws IOException {
+ if (entity == null)
+ entity = response.readEntity(String.class);
+ return entity == null ? "" : caser.getCasedText(entity);
+ }
+
+ @Override
+ public String getResponseBodyAsRawString() throws IOException {
+ return getResponseBodyAsString();
+ }
+
+ @Override
+ public String getReasonPhrase() {
+ return response.toString();// getReasonPhrase();
+ }
+
+ @Override
+ public Header[] getResponseHeaders() {
+ List<Header> headers = new LinkedList<Header>();
+ MultivaluedMap<String, Object> mHeaders = response.getMetadata();
+ String[] sHeaders = JaxrsCommonClient.getMetadata(mHeaders);
+ for (String header : sHeaders) {
+ String[] split = header.split(":", 2);
+ headers.add(new Header(split[0], split[1]));
+ }
+ return headers.toArray(new Header[headers.size()]);
+ }
+
+ @Override
+ public Header getResponseHeader(String headerName) {
+ for (Header header : getResponseHeaders())
+ if (header.getName().equals(headerName))
+ return header;
+ return null;
+ }
+
+ @Override
+ public String getResponseEncoding() {
+ String encoding = null;
+ Header header = getResponseHeader("Content-Type");
+ if (header != null) {
+ String headerVal = header.getValue();
+ int idx = headerVal.indexOf(";charset=");
+ if (idx > -1) {
+ // content encoding included in response
+ encoding = headerVal.substring(idx + 9);
+ }
+ }
+ return encoding;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java
new file mode 100644
index 0000000..b16bda8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import jakarta.ws.rs.tck.lib.util.BASE64Encoder;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.validation.CheckOneOfStatusesTokenizedValidator;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.client.JaxrsWebTestCase.Execution;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+public class JaxrsCommonClient extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = 1L;
+
+ protected transient JaxrsWebTestCase testCase;
+
+ protected boolean isTestCaseAfterInvocation;
+
+ // list of clients to be closed automatically at cleanup
+ protected List<Client> clients = new LinkedList<Client>();
+
+ /**
+ * <PRE>
+ * Sets the appropriate test properties based
+ * on the values stored in TEST_PROPS
+ * </PRE>
+ */
+ protected void setTestProperties(JaxrsWebTestCase testCase) {
+ TestUtil.logTrace("[JAXRSCommonClient] setTestProperties");
+
+ if (TEST_PROPS.get(Property.STATUS_CODE) == null)
+ setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+ setWebTestCaseProperties(testCase);
+ }
+
+ protected void setWebTestCaseProperties(JaxrsWebTestCase testCase) {
+ Property key = null;
+ String value = null;
+ // process the remainder of the properties
+ for (Enumeration<Property> e = TEST_PROPS.keys(); e.hasMoreElements();) {
+ key = e.nextElement();
+ value = TEST_PROPS.get(key);
+ switch (key) {
+ case APITEST:
+ break;
+ case BASIC_AUTH_PASSWD:
+ case BASIC_AUTH_REALM:
+ break;
+ case BASIC_AUTH_USER:
+ String user = TEST_PROPS.get(Property.BASIC_AUTH_USER);
+ String password = TEST_PROPS.get(Property.BASIC_AUTH_PASSWD);
+ String base64 = new BASE64Encoder()
+ .encode((user + ":" + password).getBytes());
+ testCase.addHeader("Authorization", " Basic " + base64);
+ break;
+ case CONTENT:
+ // req.setContent(value);
+ testCase.setEntity(value);
+ break;
+ case DONOTUSEServletName:
+ break;
+ case EXPECT_RESPONSE_BODY:
+ // FIXME
+ // setExpectResponseBody(false);
+ break;
+ case EXPECTED_HEADERS:
+ testCase.addExpectedHeader(value);
+ break;
+ case FOLLOW_REDIRECT:
+ TestUtil.logTrace("##########Found redirect Property");
+ _redirect = true;
+ break;
+ case GOLDENFILE:
+ StringBuffer sb = new StringBuffer(50);
+ sb.append(_tsHome).append(GOLDENFILEDIR);
+ sb.append(_generalURI).append(SL);
+ sb.append(value);
+ testCase.setGoldenFilePath(sb.toString());
+ break;
+ case IGNORE_BODY:
+ // FIXME
+ // setIgnoreResponseBody(true);
+ testCase.setGoldenFilePath(null);
+ break;
+ case IGNORE_STATUS_CODE:
+ testCase.setExpectedStatusCode("-1");
+ break;
+ case REASON_PHRASE:
+ testCase.setExpectedReasonPhrase(value);
+ break;
+ case REQUEST:
+ testCase.setUrlRequest(value);
+ break;
+ case REQUEST_HEADERS:
+ String[] headers = splitByColon(value);
+ for (String header : headers) {
+ String[] split = header.split(":", 2);
+ testCase.addHeader(split[0].trim(), split[1].trim());
+ }
+ break;
+ case RESPONSE_MATCH:
+ // setResponseMatch(TEST_PROPS.getProperty(key));
+ break;
+ case SAVE_STATE:
+ _saveState = true;
+ break;
+ case SEARCH_STRING:
+ value = testCase.getTextCaser().getCasedText(value);
+ testCase.setResponseSearchString(value);
+ break;
+ case SEARCH_STRING_IGNORE_CASE:
+ testCase.setResponseSearchStringIgnoreCase(value);
+ break;
+ case STANDARD:
+ break;
+ case STATUS_CODE:
+ if (value.contains("|"))
+ testCase.setStrategy(
+ CheckOneOfStatusesTokenizedValidator.class.getName());
+ testCase.setExpectedStatusCode(value);
+ break;
+ case STRATEGY:
+ testCase.setStrategy(value);
+ break;
+ case TEST_NAME:
+ // testName = TEST_PROPS.getProperty(key);
+ break;
+ case UNEXPECTED_HEADERS:
+ testCase.addUnexpectedHeader(value);
+ break;
+ case UNEXPECTED_RESPONSE_MATCH:
+ testCase.setUnexpectedResponseSearchString(value);
+ break;
+ case UNORDERED_SEARCH_STRING:
+ value = testCase.getTextCaser().getCasedText(value);
+ testCase.setUnorderedSearchString(value);
+ break;
+ case USE_SAVED_STATE:
+ _useSavedState = true;
+ break;
+ }
+ }
+ }
+
+ /**
+ * Replaces String#split("|"), as it does not split for special character '|'
+ */
+ protected static String[] splitByColon(String value) {
+ int colonIndex = -1, lastIndex = 0;
+ LinkedList<String> list = new LinkedList<String>();
+ while ((colonIndex = value.indexOf('|', lastIndex)) != -1) {
+ list.add(value.substring(lastIndex, colonIndex));
+ lastIndex = colonIndex + 1;
+ }
+ if (lastIndex < value.length())
+ list.add(value.substring(lastIndex));
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * <PRE>
+ * Invokes a test based on the properties
+ * stored in TEST_PROPS. Once the test has completed,
+ * the properties in TEST_PROPS will be cleared.
+ * </PRE>
+ *
+ * @throws Fault
+ * If an error occurs during the test run
+ */
+ protected void invoke() throws Fault {
+ TestUtil.logTrace("[JAXRSCommonClient] invoke");
+ try {
+ getTestCase().setPort(_port);
+ getTestCase().setHostname(_hostname);
+ setTestProperties(testCase);
+ TestUtil.logTrace("[JAXRSCommonClient] EXECUTING");
+ if (_useSavedState && _state != null) {
+ testCase.getRequest().setState(_state);
+ }
+ if (_redirect != false) {
+ TestUtil.logTrace("##########Call setFollowRedirects");
+ testCase.getRequest().setFollowRedirects(_redirect);
+ }
+ testCase.execute();
+ isTestCaseAfterInvocation = true;
+ if (_saveState) {
+ _state = testCase.getResponse().getState();
+ }
+ } catch (TestFailureException tfe) {
+ Throwable t = tfe.getRootCause();
+ if (t != null) {
+ TestUtil.logErr("Root cause of Failure: " + t.getMessage(), t);
+ }
+ throw new Fault("[JAXRSCommonClient] " + _testName
+ + " failed! Check output for cause of failure.", tfe);
+ } finally {
+ _useSavedState = false;
+ _saveState = false;
+ _redirect = false;
+ clearTestProperties();
+ clients.add(testCase.client);
+ }
+ }
+
+ @Override
+ public void cleanup() throws Fault{
+ super.cleanup();
+ // The client.close has to be called on cleanup, because after invoke,
+ // some methods are called and resources might not be available then
+ // (javadoc: Close client instance and all it's associated resources).
+ // Since more invoke() invocations are possible, the clients are stored
+ // in a list to be closed on cleanup
+ for (Client c : clients)
+ c.close();
+ clients.clear();
+ }
+
+ /*public void setup(String[] args, Properties p) {
+ super.setup(args, p);
+ String property = System.getProperty("cts.tmp");
+ if (property != null)
+ System.setProperty("java.io.tmpdir", property);
+ }*/
+
+ protected JaxrsWebTestCase getTestCase() {
+ if (testCase == null || isTestCaseAfterInvocation) {
+ testCase = new JaxrsWebTestCase();
+ isTestCaseAfterInvocation = false;
+ }
+ return testCase;
+ }
+
+ @Override
+ protected String buildRequest(Request type, String... path) {
+ getTestCase().setRequestType(type.name());
+ StringBuilder sb = new StringBuilder();
+ sb.append(_contextRoot == null ? "" : _contextRoot).append(SL);
+ for (String segment : path)
+ sb.append(segment);
+ return sb.toString();
+ }
+
+ @Override
+ @Deprecated
+ protected void setProperty(String key, String value) {
+ super.setProperty(key, value);
+ }
+
+ @Override
+ @Deprecated
+ protected String buildRequest(String type, String... path) {
+ return super.buildRequest(type, path);
+ }
+
+ protected Response getResponse() {
+ return testCase.getJaxrsResponse();
+ }
+
+ @Override
+ protected String getResponseBody() {
+ return getResponseBody(String.class);
+ }
+
+ protected <T> T getResponseBody(Class<T> clazz) {
+ return getResponse().readEntity(clazz);
+ }
+
+ public List<Object> getProvidersToRegister() {
+ return getTestCase().getProvidersToRegister();
+ }
+
+ public void addProvider(Object providerToRegister) {
+ getTestCase().addProviderToRegister(providerToRegister);
+ }
+
+ @Override
+ protected String[] getResponseHeaders() throws Fault {
+ return getMetadata(getResponse().getMetadata());
+ }
+
+ /**
+ * Calls setHeader(Property.REQUEST_HEADERS, header : values);
+ *
+ * @param header
+ * Recommended one of HttpHeaders static values
+ * @param values
+ * the value[1]value[2]...value[n] which are to be assigned to
+ * {@code}header name
+ */
+ protected void addHeader(String header, String... values) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(header).append(":");
+ if (values != null)
+ for (String value : values)
+ sb.append(value);
+ setProperty(Property.REQUEST_HEADERS, sb.toString());
+ }
+
+ /**
+ * This method is typically used to transform http headers metadata into a
+ * String array. The headers are in a form of java class instance, e.g.
+ * stream(!), or String
+ *
+ * @param metadata
+ * @return
+ */
+ public static String[] getMetadata(MultivaluedMap<String, Object> metadata) {
+ String[] headers = new String[metadata.size()];
+ int i = 0;
+ for (Entry<String, List<Object>> e : metadata.entrySet()) {
+ headers[i++] = e.getKey() + ":" + listToString(e.getValue());
+ }
+ return headers;
+ }
+
+ @Override
+ protected Status getResponseStatusCode() {
+ return Status.fromStatusCode(getResponse().getStatus());
+ }
+
+ protected void setRequestContentEntity(Object object) {
+ getTestCase().setEntity(object);
+ }
+
+ public static <T> String listToString(List<T> list) {
+ StringBuilder sb = new StringBuilder();
+ for (T s : list)
+ sb.append(s).append(" ");
+ return sb.toString().trim();
+ }
+
+ protected void printClientCall(boolean print) {
+ getTestCase().setPrintClientCall(print);
+ }
+
+ protected void setAsynchronousProcessing() {
+ getTestCase().setProcessingType(Execution.ASYNCHRONOUS);
+ }
+
+ protected void setPrintEntity(boolean printEntity) {
+ getTestCase().setPrintEntity(printEntity);
+ }
+
+ protected void bufferEntity(boolean buffer) {
+ getTestCase().bufferEntity(buffer);
+ }
+
+ protected void setTextCaser(TextCaser caser) {
+ getTestCase().setTextCaser(caser);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java
new file mode 100644
index 0000000..82cb16c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.Future;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationFactory;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationStrategy;
+
+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.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Replaces WebTestCase to be used with JAXRS client instead of apache client
+ *
+ * @author supol
+ */
+public class JaxrsWebTestCase extends WebTestCase {
+
+ /**
+ * The JAXRS request instance
+ */
+ protected Request request;
+
+ /**
+ * The JAXRS response instance
+ */
+ protected Response response;
+
+ /**
+ * GET, PUT, OPTIONS, ...
+ */
+ protected String requestType;
+
+ /**
+ * The URL of the Request
+ */
+ protected String urlRequest;
+
+ /**
+ * The HTTP content entity. A MessageBodyWriter<entity.getClass()> needs to be
+ * registered if not a standard entity type supported by JAXRS
+ */
+ protected Object entity;
+
+ /**
+ * port of the server
+ */
+ protected int port;
+
+ /**
+ * host name of the server
+ */
+ protected String hostname;
+
+ /**
+ * HTTP header list
+ */
+ protected Map<String, String> headerMap;
+
+ /**
+ * Apache HTTP response mock
+ */
+ protected HttpResponse _response;
+
+ /**
+ * print the response entity
+ */
+ protected boolean printEntity = true;
+
+ /**
+ * buffer the returned entity
+ */
+ protected boolean bufferEntity = false;
+
+ /**
+ * Provider logging the request and response
+ */
+ protected Object loggingFilter;
+
+ /**
+ * other providers, such as MessageBodyReader, or MessageBodyWriter
+ */
+ protected List<Object> providersToRegister;
+
+ /**
+ * Strategy to use when validating the test case against the server's
+ * response.
+ */
+ protected ValidationStrategy strategy = null;
+
+ /**
+ * Show the call client code, used to be printed when report issues
+ */
+ protected boolean printClientCall = false;
+
+ /**
+ * Upper case, lower case, or exact text matching?
+ */
+ protected TextCaser textCaser = TextCaser.NONE;
+
+ /**
+ * Type of execution
+ */
+ protected enum Execution {
+ SYNCHRONOUS, ASYNCHRONOUS
+ }
+
+ /**
+ * Runnable to run while asynchronous
+ */
+ protected Runnable asyncRunnable;
+
+ /**
+ * Execution type instance
+ */
+ protected Execution executionType = Execution.SYNCHRONOUS;
+
+ /**
+ * Client instance here not to be garbage collected before end of test.
+ */
+ protected Client client;
+
+ public JaxrsWebTestCase() {
+ strategy = ValidationFactory.getInstance(TOKENIZED_STRATEGY);
+ headerMap = new HashMap<String, String>();
+ providersToRegister = new LinkedList<Object>();
+ closeClient();
+ }
+
+ /**
+ * Sets the validation strategy for this test case instance.
+ *
+ * @param validator
+ * - the fully qualified class name of the response validator to use.
+ */
+ public void setStrategy(String validator) {
+ ValidationStrategy strat = ValidationFactory.getInstance(validator);
+ if (strat != null) {
+ strategy = strat;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[WebTestCase][WARNING] An attempt was made to use a ");
+ sb.append("non-existing validator (");
+ sb.append(validator);
+ sb.append("). Falling back to the TokenizedValidator");
+ TestUtil.logMsg(sb.toString());
+ }
+ }
+
+ // /**
+ // * Executes the test case.
+ // *
+ // * @throws TestFailureException
+ // * if the test fails for any reason.
+ // * @throws IllegalStateException
+ // * if no request was configured or if no Validator is available at
+ // * runtime.
+ // */
+ // public void execute() throws TestFailureException {
+ // verifyValidationStrategy();
+ // verifySettings();
+ // try {
+ // String url = logClientRequestAndGetUrl();
+
+ // client = getClientWithRegisteredProviders();
+ // WebTarget target = client.target(url.toString());
+ // Invocation i = buildRequest(target);
+ // response = invoke(i);
+ // if (bufferEntity)
+ // response.bufferEntity();
+ // } catch (Throwable t) {
+ // String message = t.getMessage();
+
+ // StringBuilder sb = new StringBuilder();
+ // sb.append("[FATAL] Unexpected failure during test execution.\n");
+ // // print client call code to report into JIRA when needed
+ // sb.append(printClientCall().toString());
+ // // Inherited message
+ // sb.append((message == null ? t.toString() : message));
+
+ // throw new TestFailureException(sb.toString(), t);
+ // }
+
+ // // Validate this test case instance
+ // if (!strategy.validate(this)) {
+ // throw new TestFailureException("Test FAILED!");
+ // }
+ // }
+
+ public void closeClient() {
+ if (client != null)
+ client.close();
+ client = null;
+ }
+
+ protected void verifyValidationStrategy() {
+ // If no strategy instance is available (strange, but has happened),
+ // fail.
+ try {
+ getStrategy();
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("[FATAL] No Validator available.");
+ }
+ }
+
+ protected void verifySettings() throws TestFailureException {
+ if (hostname == null)
+ throw new TestFailureException("No hostname set");
+ if (port == 0)
+ throw new TestFailureException("Port not set");
+ if (requestType == null)
+ throw new TestFailureException("No request method set");
+ if (urlRequest == null)
+ throw new TestFailureException("No resource url request set");
+ }
+
+ // /**
+ // * @return Client with all providers already registered
+ // */
+ // protected Client getClientWithRegisteredProviders() {
+ // Client client = ClientBuilder.newClient();
+ // client.register(new JdkLoggingFilter(isPrintedEntity()));
+ // for (Object o : providersToRegister)
+ // if (o instanceof Class)
+ // client.register((Class<?>) o); // otherwise it does not work
+ // else
+ // client.register(o);
+ // return client;
+ // }
+
+ protected String logClientRequestAndGetUrl() {
+ StringBuilder url = new StringBuilder();
+ url.append("http://").append(hostname).append(":").append(port);
+ url.append(urlRequest);
+
+ StringBuilder msg = new StringBuilder();
+ msg.append("[Request] Dispatching request: '").append(requestType)
+ .append(" ").append(url).append("' to target server at '")
+ .append(hostname).append(":").append(port).append("'");
+ TestUtil.logMsg(msg.toString());
+ TestUtil.logMsg("###############################");
+
+ if (printClientCall)
+ TestUtil.logMsg(printClientCall().toString());
+
+ return url.toString();
+ }
+
+ /**
+ * Log java code executed
+ */
+ protected StringBuilder printClientCall() {
+ StringBuilder url = new StringBuilder();
+ url.append("http://").append(hostname).append(":").append(port);
+ url.append(urlRequest);
+
+ StringBuilder sb = new StringBuilder();
+ // print client call code to report into JIRA when needed
+ sb.append("Client client = ClientFactory.newClient();\n");
+ for (Object o : providersToRegister) {
+ sb.append("client.configuration().register(");
+ if (o instanceof Class)
+ sb.append(((Class<?>) o).getName()).append(".class");
+ else
+ sb.append(o.getClass().getName());
+ sb.append(");\n");
+ }
+ sb.append("WebTarget target = client.target(\"").append(url.toString())
+ .append("\");\n");
+ sb.append("Invocation.Builder builder;\n");
+ sb.append("builder = target.request(\"").append(getAcceptMediaType())
+ .append("\");\n");
+ for (Entry<String, String> entry : headerMap.entrySet()) {
+ sb.append("builder.header(\"").append(entry.getKey()).append("\",\"")
+ .append(entry.getValue()).append("\");\n");
+ }
+ sb.append("Invocation i;\n");
+ sb.append("i=builder.build(\"").append(requestType).append("\"");
+ if (entity != null)
+ sb.append(",").append("Entity.entity(").append(entity.toString())
+ .append(",").append(getContentType());
+ sb.append(");\n");
+ sb.append("i.invoke();\n");
+
+ return sb;
+ }
+
+ /**
+ * Build Invocation
+ */
+ protected Invocation buildRequest(WebTarget target) {
+ Invocation.Builder builder;
+ builder = target.request(getAcceptMediaType());
+ for (Entry<String, String> entry : headerMap.entrySet()) {
+ if (!entry.getKey().equals("Accept"))
+ builder.header(entry.getKey(), entry.getValue());
+ }
+ Invocation i;
+ if (entity != null) {
+ if (entity instanceof Entity)
+ i = builder.build(requestType, (Entity<?>) entity);
+ else
+ i = builder.build(requestType, Entity.entity(entity, getContentType()));
+ TestUtil.logMsg("[Request] Adding entity: " + entity);
+ } else
+ i = builder.build(requestType);
+ return i;
+ }
+
+ /**
+ * Invoke the invocation synchronously, or asynchronously
+ */
+ protected Response invoke(Invocation invocation) throws TestFailureException {
+ Response response = null;
+ switch (executionType) {
+ case SYNCHRONOUS:
+ response = invocation.invoke();
+ break;
+ case ASYNCHRONOUS:
+ int cnt = 0;
+ try {
+ final boolean[] buffered = { false };
+ InvocationCallback<Response> callback = new InvocationCallback<Response>() {
+ @Override
+ public void completed(Response res) {
+ try {
+ JaxrsWebTestCase.this.response = res;
+ // buffer before stream is closed
+ getResponse().getResponseBodyAsString();
+ buffered[0] = true;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void failed(Throwable throwable) {
+ throw new RuntimeException(throwable);
+ }
+ };
+ Future<Response> future = invocation.submit(callback);
+ while (!buffered[0] && cnt++ < 50) {
+ Thread.sleep(100L);
+ }
+ response = future.get();
+ // response = invocation.submit().get();
+ } catch (Exception e) {
+ throw new TestFailureException(e);
+ }
+ if (cnt > 49) {
+ throw new TestFailureException(
+ "Invocation callback has not been called within 5 second");
+ }
+ }
+ return response;
+ }
+
+ /**
+ * Get media type in Request Content Type
+ */
+ protected String getAcceptMediaType() {
+ String media = headerMap.get("Accept");
+ if (media == null)
+ media = MediaType.WILDCARD;
+ return media;
+ }
+
+ /**
+ * Get media type in Request Content Type
+ */
+ protected String getContentType() {
+ String media = headerMap.get("Content-Type");
+ if (media == null)
+ media = MediaType.WILDCARD;
+ return media;
+ }
+
+ // ---------------------------------------------------------------------
+ // Apache adaptor methods
+
+ @Override
+ public HttpRequest getRequest() {
+ if (super.getRequest() == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(requestType).append(" ").append(urlRequest).append("/");
+ sb.append(" HTTP/1.1");
+ super.setRequest(new ApacheRequestAdapter(sb.toString(), hostname, port));
+ }
+ return super.getRequest();
+ }
+
+ @Override
+ public synchronized HttpResponse getResponse() {
+ if (_response == null) {
+ _response = new ApacheResponseAdapter(response, hostname, port,
+ textCaser);
+ }
+ return _response;
+ }
+
+ // ---------------------------------------------------------------------
+ // Getters and Setters
+
+ public void setRequestType(String requestType) {
+ this.requestType = requestType;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+
+ public String getUrlRequest() {
+ return urlRequest;
+ }
+
+ public void setUrlRequest(String urlRequest) {
+ this.urlRequest = urlRequest;
+ }
+
+ public void addHeader(String name, String value) {
+ headerMap.put(name, value);
+ }
+
+ public Response getJaxrsResponse() {
+ return response;
+ }
+
+ public void setEntity(Object entity) {
+ this.entity = entity;
+ }
+
+ /**
+ * Returns the Request for this particular test case.
+ *
+ * @return Request of this test case
+ */
+ public Request getJaxrsRequest() {
+ return request;
+ }
+
+ public boolean isPrintedEntity() {
+ return printEntity;
+ }
+
+ /**
+ * Set whether the entity is to be printed in trace log or not;
+ */
+ public void setPrintEntity(boolean printEntity) {
+ this.printEntity = printEntity;
+ }
+
+ public void bufferEntity(boolean bufferEntity) {
+ this.bufferEntity = bufferEntity;
+ }
+
+ public List<Object> getProvidersToRegister() {
+ return providersToRegister;
+ }
+
+ public void addProviderToRegister(Object providerToRegister) {
+ this.providersToRegister.add(providerToRegister);
+ }
+
+ public void setPrintClientCall(boolean print) {
+ printClientCall = print;
+ }
+
+ public void setProcessingType(Execution type) {
+ executionType = type;
+ }
+
+ public TextCaser getTextCaser() {
+ return textCaser;
+ }
+
+ public void setTextCaser(TextCaser textCaser) {
+ this.textCaser = textCaser;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java
new file mode 100644
index 0000000..971f9c4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(Integer.MAX_VALUE)
+public class JdkLoggingFilter extends Formatter
+ implements ClientRequestFilter, ClientResponseFilter {
+
+ private static final Logger LOGGER = Logger
+ .getLogger(JdkLoggingFilter.class.getName());
+
+ private static final String REQUEST_PREFIX = ">> ";
+
+ private static final String RESPONSE_PREFIX = "<< ";
+
+ //
+ private final DateFormat df = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
+
+ private final Logger logger;
+
+ private boolean printEntity = true;
+
+ /**
+ * Create a logging filter logging the request and response to a default JDK
+ * logger, named as the fully qualified class name of this class.
+ */
+ public JdkLoggingFilter(boolean printEntity) {
+ this(LOGGER, printEntity);
+ }
+
+ /**
+ * Create a logging filter with custom logger and custom settings of entity
+ * logging.
+ *
+ * @param logger
+ * the logger to log requests and responses.
+ * @param printEntity
+ * if true, entity will be logged as well.
+ */
+ public JdkLoggingFilter(Logger logger, boolean printEntity) {
+ this.logger = logger;
+ this.printEntity = printEntity;
+
+ ConsoleHandler handler = new ConsoleHandler();
+ logger.setUseParentHandlers(false);
+ handler.setFormatter(this);
+
+ // Set handler only once
+ if (logger.getHandlers().length == 0)
+ logger.addHandler(handler);
+ }
+
+ @Override
+ public void filter(ClientRequestContext arg0,
+ ClientResponseContext responseContext) throws IOException {
+ printResponseLine(responseContext.getStatus());
+ printPrefixedHeaders(RESPONSE_PREFIX, responseContext.getHeaders());
+ if (printEntity && responseContext.hasEntity()) {
+ List<String> entity = replaceEntityStream(responseContext);
+ log(RESPONSE_PREFIX, entity);
+ }
+
+ }
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ printRequestLine(requestContext.getMethod(), requestContext.getUri());
+ MultivaluedMap<String, Object> headers = requestContext.getHeaders();
+ StringBuilder sb = new StringBuilder().append(REQUEST_PREFIX);
+ for (String header : JaxrsCommonClient.getMetadata(headers)) {
+ if (sb.length() > REQUEST_PREFIX.length())
+ sb.append(", ");
+ sb.append(header);
+ }
+ log(sb);
+ if (printEntity && requestContext.hasEntity()) {
+ log(new StringBuilder().append(REQUEST_PREFIX)
+ .append(requestContext.getEntity().toString()));
+ }
+ }
+
+ private static List<String> replaceEntityStream(ClientResponseContext ctx)
+ throws IOException {
+ List<String> entity = null;
+ if (ctx.hasEntity()) {
+ InputStream is = ctx.getEntityStream();
+ entity = readEntityFromStream(is);
+ ByteArrayInputStream bais = new ByteArrayInputStream(
+ linesToBytes(entity));
+ ctx.setEntityStream(bais);
+ }
+ return entity;
+ }
+
+ private static byte[] linesToBytes(List<String> lines) {
+ StringBuilder sb = new StringBuilder();
+ for (Iterator<String> i = lines.iterator(); i.hasNext();) {
+ sb.append(i.next());
+ if (i.hasNext())
+ sb.append("\n");
+ }
+ return sb.toString().getBytes();
+ }
+
+ private static List<String> readEntityFromStream(InputStream is)
+ throws IOException {
+ String entity;
+ List<String> lines = new LinkedList<String>();
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ while ((entity = br.readLine()) != null)
+ lines.add(entity);
+ return lines;
+ }
+
+ private void log(StringBuilder b) {
+ if (logger != null)
+ logger.info(b.append("\n").toString());
+ }
+
+ private void log(String prefix, List<String> rows) {
+ if (logger != null && rows != null)
+ for (String row : rows)
+ logger.info(new StringBuilder().append(prefix).append(row).append("\n")
+ .toString());
+ }
+
+ private void printRequestLine(String method, URI uri) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(REQUEST_PREFIX).append(method).append(" ")
+ .append(uri.toASCIIString());
+ log(sb);
+ }
+
+ private void printResponseLine(int status) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(RESPONSE_PREFIX).append(status).append(" ")
+ .append(Response.Status.fromStatusCode(status).name());
+ log(sb);
+ }
+
+ private void printPrefixedHeaders(final String prefix,
+ Map<String, List<String>> headers) {
+ for (Map.Entry<String, List<String>> e : headers.entrySet()) {
+ StringBuilder sb = new StringBuilder();
+ List<String> val = e.getValue();
+ String header = e.getKey();
+
+ if (val.size() == 1) {
+ sb.append(prefix).append(header).append(": ").append(val.get(0));
+ } else {
+ StringBuilder sb2 = new StringBuilder();
+ for (String s : val) {
+ if (sb2.length() != 0)
+ sb2.append(',');
+ sb2.append(s);
+ }
+ sb.append(prefix).append(header).append(": ").append(sb2.toString());
+ }
+ if (sb.length() != 0)
+ log(sb);
+ }
+
+ }
+
+ @Override
+ public String format(LogRecord record) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(df.format(new Date(record.getMillis()))).append(": ")
+ .append("TRACE: [WIRE] - ");
+ sb.append(formatMessage(record));
+ return sb.toString();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java
new file mode 100644
index 0000000..4e454da
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2021 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.client;
+
+/**
+ * Standard WebTestCase can search strings in an order case sensitive, case
+ * insensitive or not in order case sensitive. When there is a need to match not
+ * in order and case insensitive, this class is used.
+ */
+public enum TextCaser {
+ UPPER, NONE, LOWER;
+
+ /**
+ * Get the text upper cased, lower cased, or unchanged, depending on current
+ * TextCaser value
+ */
+ public final String getCasedText(String text) {
+ String ret = null;
+ switch (this) {
+ case UPPER:
+ ret = text.toUpperCase();
+ break;
+ case LOWER:
+ ret = text.toLowerCase();
+ break;
+ case NONE:
+ ret = text;
+ break;
+ }
+ return ret;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java
new file mode 100644
index 0000000..4cd4db4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012, 2021 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.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+
+public class SinglevaluedMap<K, V> implements MultivaluedMap<K, V> {
+
+ Map<K, V> map = new HashMap<K, V>();
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return map.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ @Override
+ public List<V> get(Object key) {
+ return Collections.singletonList(map.get(key));
+ }
+
+ @Override
+ public List<V> put(K key, List<V> value) {
+ V v;
+ if (value == null)
+ v = map.put(key, null);
+ else
+ v = map.put(key, value.iterator().next());
+ return Collections.singletonList(v);
+ }
+
+ @Override
+ public List<V> remove(Object key) {
+ return Collections.singletonList(map.remove(key));
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends List<V>> m) {
+ for (Entry<? extends K, ? extends List<V>> e : m.entrySet())
+ map.put(e.getKey(), e.getValue().iterator().next());
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection<List<V>> values() {
+ Collection<List<V>> col = new ArrayList<List<V>>();
+ for (V v : map.values())
+ col.add(Collections.singletonList(v));
+ return col;
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<K, List<V>>> entrySet() {
+ Map<K, List<V>> adapter = new HashMap<K, List<V>>();
+ for (Entry<K, V> e : map.entrySet())
+ adapter.put(e.getKey(), Collections.singletonList(e.getValue()));
+ return adapter.entrySet();
+ }
+
+ @Override
+ public void add(K key, V value) {
+ map.put(key, value);
+ }
+
+ @Override
+ public V getFirst(K key) {
+ return map.get(key);
+ }
+
+ @Override
+ public void putSingle(K key, V value) {
+ map.put(key, value);
+ }
+
+ @Override
+ public void addAll(K key, V... value) {
+ if (value != null)
+ putSingle(key, value[0]);
+ }
+
+ @Override
+ public void addAll(K arg0, List<V> arg1) {
+ if (arg1.iterator().hasNext())
+ putSingle(arg0, arg1.iterator().next());
+ }
+
+ @Override
+ public void addFirst(K arg0, V arg1) {
+ putSingle(arg0, arg1);
+ }
+
+ @Override
+ public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> arg0) {
+ for (java.util.Map.Entry<K, List<V>> set : arg0.entrySet()) {
+ if (!map.containsKey(set.getKey()))
+ return false;
+ if (!map.containsValue(set.getValue().iterator().next()))
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java
new file mode 100644
index 0000000..8139699
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2021 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.impl;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.HttpMethod;
+
+@HttpMethod("TRACE")
+@Target(value = ElementType.METHOD)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface TRACE {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java
new file mode 100644
index 0000000..6b6a51b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2021 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;
+
+/**
+ * This is the object which standard implementation does not have a provider
+ * for, even though its some simple String holder. It can also be used as
+ * mutable string.
+ */
+public class StringBean {
+ private String header;
+
+ public String get() {
+ return header;
+ }
+
+ public void set(String header) {
+ this.header = header;
+ }
+
+ @Override
+ public String toString() {
+ return "StringBean. To get a value, use rather #get() method.";
+ }
+
+ public StringBean(String header) {
+ super();
+ this.header = header;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java
new file mode 100644
index 0000000..283770c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2021 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.ext.Provider;
+import jakarta.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
+
+@Provider
+public class StringBeanHeaderDelegate implements HeaderDelegate<StringBean> {
+
+ @Override
+ public StringBean fromString(String string) throws IllegalArgumentException {
+ return new StringBean(string);
+ }
+
+ @Override
+ public String toString(StringBean bean) throws IllegalArgumentException {
+ return bean.get();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java
new file mode 100644
index 0000000..309d8cb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012, 2021 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.core.Application;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.Variant.VariantListBuilder;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+import java.util.concurrent.CompletionStage;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Instance;
+
+public class StringBeanRuntimeDelegate extends RuntimeDelegate {
+
+ public StringBeanRuntimeDelegate(RuntimeDelegate orig) {
+ super();
+ this.original = orig;
+ assertNotStringBeanRuntimeDelegate(orig);
+ }
+
+ private RuntimeDelegate original;
+
+ @Override
+ public <T> T createEndpoint(Application arg0, Class<T> arg1)
+ throws IllegalArgumentException, UnsupportedOperationException {
+ return original.createEndpoint(arg0, arg1);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> arg0)
+ throws IllegalArgumentException {
+ if (arg0 == StringBean.class)
+ return (HeaderDelegate<T>) new StringBeanHeaderDelegate();
+ else
+ return original.createHeaderDelegate(arg0);
+ }
+
+ @Override
+ public ResponseBuilder createResponseBuilder() {
+ return original.createResponseBuilder();
+ }
+
+ @Override
+ public UriBuilder createUriBuilder() {
+ return original.createUriBuilder();
+ }
+
+ @Override
+ public VariantListBuilder createVariantListBuilder() {
+ return original.createVariantListBuilder();
+ }
+
+ @Override
+ public EntityPart.Builder createEntityPartBuilder(String partName) {
+ return original.createEntityPartBuilder(partName);
+ }
+
+ @Override
+ public CompletionStage<Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+ return original.bootstrap(application, configuration);
+ }
+
+ @Override
+ public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+ return original.createConfigurationBuilder();
+ }
+
+ public RuntimeDelegate getOriginal() {
+ return original;
+ }
+
+ public static final void assertNotStringBeanRuntimeDelegate() {
+ RuntimeDelegate delegate = RuntimeDelegate.getInstance();
+ assertNotStringBeanRuntimeDelegate(delegate);
+ }
+
+ public static final//
+ void assertNotStringBeanRuntimeDelegate(RuntimeDelegate delegate) {
+ if (delegate instanceof StringBeanRuntimeDelegate) {
+ StringBeanRuntimeDelegate sbrd = (StringBeanRuntimeDelegate) delegate;
+ if (sbrd.getOriginal() != null)
+ RuntimeDelegate.setInstance(sbrd.getOriginal());
+ throw new RuntimeException(
+ "RuntimeDelegate.getInstance() is StringBeanRuntimeDelegate");
+ }
+ }
+
+ @Override
+ public Link.Builder createLinkBuilder() {
+ return original.createLinkBuilder();
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java
new file mode 100644
index 0000000..d433614
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java
@@ -0,0 +1,65 @@
+/*
+*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2018, 2021 Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+* any, must include the following acknowlegement:
+* "This product includes software developed by the
+* Apache Software Foundation (http://www.apache.org/)."
+* Alternately, this acknowlegement may appear in the software itself,
+* if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+* Foundation" must not be used to endorse or promote products derived
+* from this software without prior written permission. For written
+* permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+* nor may "Apache" appear in their names without prior written
+* permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation. For more
+* information on the Apache Software Foundation, please see
+* <http://www.apache.org/>.
+*
+*/
+
+package jakarta.ws.rs.tck.common.util;
+
+public final class Data {
+
+ public static final String PASSED = "Test PASSED";
+
+ public static final String FAILED = "Test FAILED";
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java
new file mode 100644
index 0000000..d5df129
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 2021 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.util;
+
+public class Holder<TYPE> {
+
+ public Holder() {
+ };
+
+ public Holder(TYPE type) {
+ set(type);
+ }
+
+ public TYPE value;
+
+ public void set(TYPE value) {
+ this.value = value;
+ }
+
+ public TYPE get() {
+ return value;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java
new file mode 100644
index 0000000..3663433
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012, 2021 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.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Array;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public abstract class JaxrsUtil {
+
+ public static final//
+ String readFromStream(InputStream stream) throws IOException {
+ InputStreamReader isr = new InputStreamReader(stream);
+ return readFromReader(isr);
+ }
+
+ public static final//
+ String readFromReader(Reader reader) throws IOException {
+ BufferedReader br = new BufferedReader(reader);
+ String entity = br.readLine();
+ br.close();
+ return entity;
+ }
+
+ public static final//
+ String readFromFile(File file) throws IOException {
+ FileReader reader = new FileReader(file);
+ return readFromReader(reader);
+ }
+
+ public static final <T> //
+ String iterableToString(String separator, Iterable<T> collection) {
+ if (collection != null)
+ return iterableToString(separator, collection.iterator());
+ return "";
+ }
+
+ public static final <T> //
+ String iterableToString(String separator, Iterator<T> iterator) {
+ StringBuilder sb = new StringBuilder();
+ while (iterator.hasNext()) {
+ T item = iterator.next();
+ if (item != null) {
+ String appendable = item.toString();
+ sb.append(appendable);
+ if (iterator.hasNext())
+ sb.append(separator);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static final <T> //
+ String enumerationToString(String separator, Enumeration<T> enumeration) {
+ StringBuilder sb = new StringBuilder();
+ if (enumeration != null)
+ while (enumeration.hasMoreElements()) {
+ T item = enumeration.nextElement();
+ if (item != null) {
+ String appendable = item.toString();
+ sb.append(appendable);
+ if (enumeration.hasMoreElements())
+ sb.append(separator);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static final //
+ String iterableToString(String separator, Object... collection) {
+ StringBuilder sb = new StringBuilder();
+ if (collection != null)
+ for (int i = 0; i != collection.length; i++) {
+ Object item = collection[i];
+ if (item != null) {
+ String appendable = item.toString();
+ sb.append(appendable);
+ if (i != collection.length - 1)
+ sb.append(separator);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static final TimeZone findTimeZoneInDate(String date) {
+ StringBuilder sb = new StringBuilder();
+ StringBuilder dateBuilder = new StringBuilder(date.trim()).reverse();
+ int index = 0;
+ char c;
+ while ((c = dateBuilder.charAt(index++)) != ' ') {
+ sb.append(c);
+ }
+ TimeZone timezone = TimeZone.getTimeZone(sb.reverse().toString());
+ return timezone;
+ }
+
+ public static final String mapToString(java.util.Map<?, ?> map) {
+ StringBuilder sb = new StringBuilder();
+ if (map != null)
+ for (Object key : map.keySet()) {
+ sb.append("[").append(key).append(" : ");
+ Object value = map.get(key);
+ sb.append(toString(value)).append("]");
+ }
+ return sb.toString();
+ }
+
+ public static final DateFormat createDateFormat(TimeZone timezone) {
+ SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
+ Locale.US);
+ sdf.setTimeZone(timezone);
+ return sdf;
+ }
+
+ public static String toString(Object object) {
+ String to = null;
+ if (object == null)
+ to = "null";
+ else if (Iterable.class.isInstance(object))
+ to = iterableToString(" ", (Iterable<?>) object);
+ else if (Enumeration.class.isInstance(object))
+ to = enumerationToString(" ", (Enumeration<?>) object);
+ else if (java.util.Map.class.isInstance(object))
+ to = mapToString((java.util.Map<?, ?>) object);
+ else if (Iterator.class.isInstance(object))
+ to = iterableToString(" ", (Iterator<?>) object);
+ else if (Array.class.isInstance(object))
+ to = iterableToString(" ", (Object[]) object);
+ else if (object.getClass().isArray())
+ to = primitiveArrayToString(object);
+ else
+ to = String.valueOf(object);
+ return to;
+ }
+
+ public static String primitiveArrayToString(Object array) {
+ String to = null;
+ if (array == null)
+ to = "null";
+ else if (array.getClass().isArray()) {
+ String sarray = array.toString();
+ if (sarray.startsWith("[I"))
+ to = Arrays.toString((int[]) array);
+ else if (sarray.startsWith("[B"))
+ to = Arrays.toString((byte[]) array);
+ else if (sarray.startsWith("[J"))
+ to = Arrays.toString((long[]) array);
+ else if (sarray.startsWith("[C"))
+ to = Arrays.toString((char[]) array);
+ else if (sarray.startsWith("[S"))
+ to = Arrays.toString((short[]) array);
+ else if (sarray.startsWith("[F"))
+ to = Arrays.toString((float[]) array);
+ else if (sarray.startsWith("[D"))
+ to = Arrays.toString((double[]) array);
+ else if (sarray.startsWith("[Z"))
+ to = Arrays.toString((boolean[]) array);
+ else if (sarray.startsWith("[L"))
+ to = Arrays.toString((Object[]) array);
+ } else
+ to = String.valueOf(array);
+ return to;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java
new file mode 100644
index 0000000..c9c3479
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 2021 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.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * Hold multiple instances of TYPE in a {@link LinkedList} structure, last one
+ * accessible by {@link #get()}.
+ *
+ * @param <TYPE>
+ */
+public class LinkedHolder<TYPE> extends Holder<TYPE> implements Iterable<TYPE> {
+
+ private LinkedList<TYPE> list = new LinkedList<TYPE>();
+
+ public LinkedHolder(TYPE type) {
+ add(type);
+ }
+
+ public LinkedHolder() {
+ }
+
+ public void add(TYPE value) {
+ list.add(value);
+ super.set(value);
+ }
+
+ /**
+ * Replace the last item in the list
+ */
+ @Override
+ public void set(TYPE value) {
+ if (list.size() != 0) {
+ list.set(list.size() - 1, value);
+ super.set(value);
+ }
+ if (value == null) {
+ super.set(null);
+ } else {
+ add(value);
+ }
+ }
+
+ public TYPE get(int index) {
+ if (index >= list.size())
+ return null;
+ return list.get(index);
+ }
+
+ public int size() {
+ return list.size();
+ }
+
+ public void clear() {
+ super.set(null);
+ list.clear();
+ }
+
+ @Override
+ public Iterator<TYPE> iterator() {
+ return list.iterator();
+ }
+
+ public LinkedList<TYPE> asList() {
+ return list;
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java
new file mode 100644
index 0000000..cdd8023
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * A representation of a Goldenfile that may be used by a particular test case.
+ */
+
+public class Goldenfile {
+
+ /*
+ * Message to be returned if the goldenfile cannot be located.
+ */
+ private static final byte[] NOTFOUND = "NO GOLDENFILE FOUND".getBytes();
+
+ /*
+ * Message to be returned if the goldenfile doesn't have read permissions.
+ */
+ private static final byte[] NOPERM = "INSUFFICIENT PERMISSIONS".getBytes();
+
+ /*
+ * Goldenfile represented by this object.
+ */
+ private File _file = null;
+
+ /*
+ * Error message to return by public methods if the file is not found or the
+ * user has insufficient permissions.
+ */
+ private byte[] _errMessage = null;
+
+ /*
+ * Goldenfile length
+ */
+ private long _length = 0L;
+
+ /*
+ * Encoding
+ */
+ private String _encoding = null;
+
+ /**
+ * Creates a new GoldenFile based on the fully qualified filename provided.
+ *
+ * @param path
+ * Fully qualified file name
+ * @param encoding
+ * to use when reading the goldenfile
+ */
+ public Goldenfile(String path, String encoding) {
+ _file = new File(path);
+ if (!_file.exists()) {
+ TestUtil.logTrace("[GoldenFile] Goldenfile: " + path + ", not found!");
+ _errMessage = NOTFOUND;
+ _file = null;
+ } else if (!_file.canRead()) {
+ _errMessage = NOPERM;
+ _file = null;
+ } else {
+ _length = _file.length();
+ _encoding = encoding;
+ }
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns the length of the Goldenfile.
+ *
+ * @return long length
+ */
+ public long getLength() {
+ return _length;
+ }
+
+ /**
+ * Returns the byte content of the specified goldenfile using the charset
+ * encoding specified in the response from the server.
+ *
+ * @return the goldenfile as a byte array
+ * @throws IOException
+ * if an error occurs processing the file.
+ */
+ public byte[] getGoldenFileAsBytes() throws IOException {
+ if (_file != null) {
+ return getGoldenFileAsString().getBytes();
+ } else {
+ return _errMessage;
+ }
+ }
+
+ /**
+ * Retuns a string representation of the specified goldenfile using the
+ * charset encoding specified in the response from the server.
+ *
+ * @return the goldenfile as a String.
+ * @throws IOException
+ * if an error occurs processing the file.
+ */
+ public String getGoldenFileAsString() throws IOException {
+ String gf = null;
+ if (_file != null) {
+ TestUtil.logTrace(
+ "[Goldenfile] Loading goldenfile using " + "encoding: " + _encoding);
+ FileInputStream in = new FileInputStream(_file);
+ gf = Util.getEncodedStringFromStream(in, _encoding);
+ in.close();
+ } else {
+ gf = new String(_errMessage);
+ }
+ return gf;
+ }
+
+ /**
+ * Returns the goldenfile as an InputStream using the charset encoding
+ * specified in the response from the server.
+ *
+ * @return goldenfile as an InputStream
+ * @throws IOException
+ * If an error occurs processing the file.
+ */
+ public InputStream getGoldenFileAsStream() throws IOException {
+ if (_file != null) {
+ return new ByteArrayInputStream(getGoldenFileAsBytes());
+ } else {
+ return new ByteArrayInputStream(_errMessage);
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java
new file mode 100644
index 0000000..45b716e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+/**
+ * This interface defines a base set of methods required used by a TS test case.
+ */
+public interface TestCase {
+
+ /**
+ * Executes the test case.
+ *
+ * @throws TestFailureException
+ * if the test fails for any reason.
+ */
+ public void execute() throws TestFailureException;
+
+ /**
+ * Sets the name of the test case.
+ *
+ * @param name
+ * of the test case
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the name of this test case.
+ *
+ * @return test case name
+ */
+ public String getName();
+
+ /**
+ * Sets the state for this test case. This state will differ from
+ * implementation to implementation.
+ *
+ * @param state
+ * test state
+ */
+ public void setState(Object state);
+
+ /**
+ * Returns the state of the test case. The state returned could possibly
+ * differ depending on when this method is called and when the test case has
+ * been executed.
+ */
+ public Object getState();
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java
new file mode 100644
index 0000000..c71f384
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+/**
+ * Signifies a failure at some point during a test cycle.
+ */
+public class TestFailureException extends java.lang.Exception {
+
+ private static final long serialVersionUID = -4651996590051941456L;
+
+ /**
+ * Creates a new instance of <code>TestFailureException</code> without a
+ * detailed message.
+ */
+ public TestFailureException() {
+ }
+
+ /**
+ * Creates a new instance of <code>TestFailureException</code> containing the
+ * root cause of the test failure.
+ *
+ * @param t
+ * - root cause
+ */
+ public TestFailureException(Throwable t) {
+ super(t);
+ }
+
+ /**
+ * Creates a new instance of <code>TestFailureException</code> with the
+ * specified detail message.
+ *
+ * @param msg
+ * - the detail message.
+ */
+ public TestFailureException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new instance of <code>TestFailureException</code> with the
+ * specified detail message, and the root cause of the test failure
+ *
+ * @param msg
+ * - the detail message
+ * @param t
+ * - root cause
+ */
+ public TestFailureException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+ /**
+ * Returns, if any, the root cause of this Exception.
+ *
+ * @return the root cause of this exception, or null
+ */
+ public Throwable getRootCause() {
+ return getCause();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java
new file mode 100644
index 0000000..604e6cf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java
@@ -0,0 +1,234 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import jakarta.ws.rs.tck.lib.util.BASE64Encoder;
+
+public class Util {
+
+ /**
+ * Zeros
+ */
+ private static final String ZEROS = "00000000";
+
+ /**
+ * short pad size
+ */
+ private static final int SHORTPADSIZE = 4;
+
+ /**
+ * byte pad size
+ */
+ private static final int BYTEPADSIZE = 2;
+
+ /** Creates new Util */
+ private Util() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * BASE64 encodes the provided string.
+ *
+ * @return BASE64 encoded string.
+ */
+ public static String getBase64EncodedString(String value) {
+ BASE64Encoder encoder = new BASE64Encoder();
+ return encoder.encode(value.getBytes());
+ }
+
+ /**
+ * Returns a charset encoded string based on the provided InputStream and
+ * charset encoding.
+ *
+ * @return encoding string
+ */
+ public static String getEncodedStringFromStream(InputStream in, String enc)
+ throws IOException {
+ BufferedReader bin = new BufferedReader(new InputStreamReader(in, enc));
+ StringBuffer sb = new StringBuffer(128);
+ for (int ch = bin.read(); ch != -1; ch = bin.read()) {
+ sb.append((char) ch);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * <code>getHexValue</code> displays a formatted hex representation of the
+ * passed byte array. It also allows for only a specified offset and length of
+ * a particular array to be returned.
+ *
+ * @param bytes
+ * <code>byte[]</code> array to process.
+ * @param pos
+ * <code>int</code> specifies offset to begin processing.
+ * @param len
+ * <code>int</code> specifies the number of bytes to process.
+ * @return <code>String</code> formatted hex representation of processed
+ * array.
+ */
+ public static String getHexValue(byte[] bytes, int pos, int len) {
+ StringBuffer outBuf = new StringBuffer(bytes.length * 2);
+ int bytesPerLine = 36;
+ int cnt = 1;
+ int groups = 4;
+ int curPos = pos;
+ int linePos = 1;
+ boolean displayOffset = true;
+
+ while (len-- > 0) {
+ if (displayOffset) {
+
+ outBuf.append("\n" + paddedHexString(pos, SHORTPADSIZE, true) + ": ");
+ displayOffset = false;
+ }
+
+ outBuf.append(paddedHexString((int) bytes[pos], BYTEPADSIZE, false));
+ linePos += 2; // Byte is padded to 2 characters
+
+ if ((cnt % 4) == 0) {
+ outBuf.append(" ");
+ linePos++;
+ }
+
+ // Now display the characters that are printable
+ if ((cnt % (groups * 4)) == 0) {
+ outBuf.append(" ");
+
+ while (curPos <= pos) {
+ if (!Character.isWhitespace((char) bytes[curPos])) {
+ outBuf.append((char) bytes[curPos]);
+ } else {
+ outBuf.append(".");
+ }
+
+ curPos++;
+ }
+
+ curPos = pos + 1;
+ linePos = 1;
+ displayOffset = true;
+ }
+
+ cnt++;
+ pos++;
+ }
+
+ // pad out the line with spaces
+ while (linePos++ <= bytesPerLine) {
+ outBuf.append(" ");
+ }
+
+ outBuf.append(" ");
+ // Now display the printable characters for the trailing bytes
+ while (curPos < pos) {
+ if (!Character.isWhitespace((char) bytes[curPos])) {
+ outBuf.append((char) bytes[curPos]);
+ } else {
+ outBuf.append(".");
+ }
+
+ curPos++;
+ }
+
+ return outBuf.toString();
+ }
+
+ /*
+ * private methods
+ * ========================================================================
+ */
+
+ /**
+ * <code>paddedHexString</code> pads the passed value based on the specified
+ * wordsize and the value of the prefixFlag.
+ *
+ * @param val
+ * an <code>int</code> value
+ * @param wordsize
+ * an <code>int</code> value
+ * @param prefixFlag
+ * a <code>boolean</code> value
+ * @return a <code>String</code> value
+ */
+ private static String paddedHexString(int val, int wordsize,
+ boolean prefixFlag) {
+
+ String prefix = prefixFlag ? "0x" : "";
+ String hexVal = Integer.toHexString(val);
+
+ if (hexVal.length() > wordsize)
+ hexVal = hexVal.substring(hexVal.length() - wordsize);
+
+ return (prefix + (wordsize > hexVal.length()
+ ? ZEROS.substring(0, wordsize - hexVal.length())
+ : "") + hexVal);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java
new file mode 100644
index 0000000..27c1c3a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpState;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationFactory;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationStrategy;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+
+/**
+ * A TestCase implementation for HTTP-based testing. This allows the user to set
+ * criteria for test success which will be compared against the response from
+ * the server.
+ */
+public class WebTestCase implements TestCase {
+
+ /**
+ * Tokenized response validation strategy
+ */
+ public static final String TOKENIZED_STRATEGY = "jakarta.ws.rs.tck.common.webclient.validation.TokenizedValidator";
+
+ /**
+ * Whitespace response validation strategy
+ */
+ public static final String WHITESPACE_STRATEGY = "jakarta.ws.rs.tck.common.webclient.validation.WhitespaceValidator";
+
+ /**
+ * The request for this case.
+ */
+ private HttpRequest _request = null;
+
+ /**
+ * The server's response.
+ */
+ private HttpResponse _response = null;
+
+ // use HttpMethod instances to store test
+ // case headers that are expected or not
+ // expected.
+
+ /**
+ * Storage for headers that are expected in the response
+ */
+ private Map<String, Header> _expected = null;
+
+ /**
+ * Storage for headers that are not expected in the response
+ */
+ private Map<String, Header> _unexpected = null;
+
+ /**
+ * Expected response status code.
+ */
+ private String _statusCode = null;
+
+ /**
+ * Expected response reason phrase.
+ */
+ private String _reasonPhrase = null;
+
+ /**
+ * Path to goldenfile.
+ */
+ private String _goldenfilePath = null;
+
+ /**
+ * A List of strings that will be searched for in the response in the order
+ * they appear in the list.
+ */
+ private List<String> _searchStrings = null;
+
+ /**
+ * A List of case insensitive strings that will be searched for in the
+ * response in the order they appear in the list.
+ */
+ private List<String> _searchStringsNoCase = null;
+
+ /**
+ * A List of strings that will be search for in the response with no attention
+ * paid to the order they appear.
+ */
+ private List<String> _unorderedSearchStrings = null;
+
+ /**
+ * A List of strings that should not be in the server's response.
+ */
+ private List<String> _uSearchStrings = null;
+
+ /**
+ * Indicates whether a response body should be expected or not.
+ */
+ private boolean _expectResponseBody = true;
+
+ /**
+ * Strategy to use when validating the test case against the server's
+ * response.
+ */
+ private ValidationStrategy _strategy = null;
+
+ /**
+ * Logical name for test case.
+ */
+ private String _name = "Test Case";
+
+ /**
+ * Creates a new instance of WebTestCase By default, a new WebTestCase
+ * instance will use the TokenizedValidator to verify the response with the
+ * configured properties of the test case.
+ */
+ public WebTestCase() {
+ _strategy = ValidationFactory.getInstance(TOKENIZED_STRATEGY);
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+ /**
+ * Executes the test case.
+ *
+ * @throws TestFailureException
+ * if the test fails for any reason.
+ * @throws IllegalStateException
+ * if no request was configured or if no Validator is available at
+ * runtime.
+ */
+ public void execute() throws TestFailureException {
+
+ // If no request was created, we can't run.
+ if (_request == null) {
+ throw new IllegalStateException("[FATAL] HttpRequest is null.");
+ }
+
+ // If no stragey instance is available (strange, but has happened),
+ // fail.
+ if (_strategy == null) {
+ throw new IllegalStateException("[FATAL] No Validator available.");
+ }
+
+ try {
+ _response = _request.execute();
+ } catch (Throwable t) {
+ String message = t.getMessage();
+ throw new TestFailureException("[FATAL] Unexpected failure during "
+ + "test execution." + (message == null ? t.toString() : message), t);
+ }
+
+ // Validate this test case instance
+ if (!_strategy.validate(this)) {
+ throw new TestFailureException("Test FAILED!");
+ }
+
+ }
+
+ /**
+ * Sets the status code to be expected in the response from the server, i.e.
+ * 500 or 404, etc.
+ *
+ * @param statusCode
+ * the expected status code
+ */
+ public void setExpectedStatusCode(String statusCode) {
+ _statusCode = statusCode;
+ }
+
+ /**
+ * Sets the reason phrase to be expected in the response from the server.
+ *
+ * @param reasonPhrase
+ * the expected reason-phrase
+ */
+ public void setExpectedReasonPhrase(String reasonPhrase) {
+ _reasonPhrase = reasonPhrase;
+ }
+
+ /**
+ * Adds a header that is to be expected in the response from the server.
+ *
+ * @param header
+ * in the format of <headername>:<value> (test:foo)
+ */
+ public void addExpectedHeader(String header) {
+ if (_expected == null) {
+ _expected = new HashMap<String, Header>();
+ }
+ addHeader(_expected, header);
+ }
+
+ /**
+ * Sets the path to the goldenfile the test case should use.
+ *
+ * @param gfPath
+ * a fully qualified path including filename.
+ */
+ public void setGoldenFilePath(String gfPath) {
+ _goldenfilePath = gfPath;
+ }
+
+ /**
+ * Sets the request that should be dispatched by this test case.
+ *
+ * @param request
+ * the HTTP request used for this test case
+ */
+ public void setRequest(HttpRequest request) {
+ _request = request;
+ }
+
+ /**
+ * Adds a header that is should not be in the server's response.
+ *
+ * @param header
+ * in the format of <headername>:<value> (test:foo)
+ */
+ public void addUnexpectedHeader(String header) {
+ if (_unexpected == null) {
+ _unexpected = new HashMap<String, Header>();
+ }
+ addHeader(_unexpected, header);
+ }
+
+ /**
+ * Enables/Disables an assertion that a response body is present.
+ *
+ * @param value
+ * a value of true will enable the assertion.
+ */
+ public void setAssertNoResponseBody(boolean value) {
+ }
+
+ /**
+ * Sets a string that will be scanned for and expected in the response body
+ * from the server.
+ *
+ * If multiple search strings are required, one can either call this method
+ * for each string, or pass in one string with pipe <code>|<code> delimiting
+ * the individual search strings within the large string.
+ *
+ * @param searchString
+ * a string expected in the server's response body
+ */
+ public void setResponseSearchString(String searchString) {
+ if (_searchStrings == null) {
+ _searchStrings = new ArrayList<String>();
+ }
+ addSearchStrings(_searchStrings, searchString);
+ }
+
+ /**
+ * Sets a string that will be scanned for and expected in the response body
+ * from the server.
+ *
+ * If multiple search strings are required, one can either call this method
+ * for each string, or pass in one string with pipe <code>|<code> delimiting
+ * the individual search strings within the large string.
+ *
+ * @param searchString
+ * a case insensitive string expected in the server's response body
+ */
+ public void setResponseSearchStringIgnoreCase(String searchString) {
+ if (_searchStringsNoCase == null) {
+ _searchStringsNoCase = new ArrayList<String>();
+ }
+ addSearchStrings(_searchStringsNoCase, searchString);
+ }
+
+ /**
+ * Sets a string that will be scanned for and should not be present in the
+ * response body from the server.
+ *
+ * If multiple search strings are required, one can either call this method
+ * for each string, or pass in one string with pipe <code>|<code> delimiting
+ * the individual search strings within the large string.
+ *
+ * @param searchString
+ * a string that is not expected in the server's response body
+ */
+ public void setUnexpectedResponseSearchString(String searchString) {
+ if (_uSearchStrings == null) {
+ _uSearchStrings = new ArrayList<String>();
+ }
+ addSearchStrings(_uSearchStrings, searchString);
+ }
+
+ /**
+ * Sets a string or series of strings that will be searched for in the
+ * response. If multiple search strings are required, one can either call this
+ * method for each string, or pass in one string with pipe <code>|<code>
+ * delimiting the individual search strings within the large string.
+ *
+ * @param searchString
+ * a string that is not expected in the server's response body
+ */
+ public void setUnorderedSearchString(String searchString) {
+ if (_unorderedSearchStrings == null) {
+ _unorderedSearchStrings = new ArrayList<String>();
+ }
+ addSearchStrings(_unorderedSearchStrings, searchString);
+ }
+
+ /**
+ * Returns the list of search strings.
+ *
+ * @return the list of search strings.
+ */
+ public List<String> getUnorderedSearchStrings() {
+ return _unorderedSearchStrings;
+ }
+
+ /**
+ * Returns the response for this particular test case.
+ *
+ * @return an HttpResponse object
+ */
+ public HttpResponse getResponse() {
+ return _response;
+ }
+
+ /**
+ * Returns an array of Header objects that are expected to be found in the
+ * responst.
+ *
+ * @return an array of headers
+ */
+ public Header[] getExpectedHeaders() {
+ if (_expected == null) {
+ return null;
+ }
+ return _expected.values().toArray(new Header[_expected.size()]);
+ }
+
+ /**
+ * Returns an array of Header objects that are not expected to be found in the
+ * responst.
+ *
+ * @return an array of headers
+ */
+ public Header[] getUnexpectedHeaders() {
+ if (_unexpected == null) {
+ return null;
+ }
+ return _unexpected.values().toArray(new Header[_unexpected.size()]);
+ }
+
+ /**
+ * Returns the status code expected to be found in the server's response
+ *
+ * @return status code
+ */
+ public String getStatusCode() {
+ return _statusCode;
+ }
+
+ /**
+ * Returns the reason phrase that is expected to be found in the server's
+ * response.
+ *
+ * @return reason phrase
+ */
+ public String getReasonPhrase() {
+ return _reasonPhrase;
+ }
+
+ /**
+ * Returns the configured list of strings that will be used when scanning the
+ * server's response.
+ *
+ * @return list of Strings
+ */
+ public List<String> getSearchStrings() {
+ if (_searchStrings == null) {
+ return null;
+ }
+ return _searchStrings;
+ }
+
+ /**
+ * Returns the configured list of strings that will be used when scanning the
+ * server's response.
+ *
+ * @return list of case insensitive Strings
+ */
+ public List<String> getSearchStringsNoCase() {
+ if (_searchStringsNoCase == null) {
+ return null;
+ }
+ return _searchStringsNoCase;
+ }
+
+ /**
+ * Returns the configured list of strings that will be used when scanning the
+ * server's response (these strings are not expected in the response).
+ *
+ * @return list of Strings
+ */
+ public List<String> getUnexpectedSearchStrings() {
+ if (_uSearchStrings == null) {
+ return null;
+ }
+ return _uSearchStrings;
+ }
+
+ /**
+ * Returns an indicator on whether a response body is expected or not.
+ *
+ * @return boolean value
+ */
+ public boolean getExpectResponseBody() {
+ return _expectResponseBody;
+ }
+
+ /**
+ * Returns the HttpRequest for this particular test case.
+ *
+ * @return HttpRequest of this test case
+ */
+ public HttpRequest getRequest() {
+ return _request;
+ }
+
+ /**
+ * Returns the path to the goldenfile.
+ *
+ * @return path to the goldenfile
+ */
+ public String getGoldenfilePath() {
+ return _goldenfilePath;
+ }
+
+ /**
+ * Returns the state for this particular test case.
+ *
+ * @return test state
+ */
+ public Object getState() {
+ if (_response != null) {
+ return _response.getState();
+ } else {
+ // an initial request for state
+ return _request.getState();
+ }
+ }
+
+ /**
+ * Sets the state for this test case.
+ *
+ * @param state
+ * test state
+ */
+ public void setState(Object state) {
+ _request.setState((HttpState) state);
+ }
+
+ /**
+ * Sets a logical name for this test case.
+ *
+ * @param name
+ * the logical name for this test
+ */
+ public void setName(String name) {
+ _name = name;
+ }
+
+ /**
+ * Returns the logical name for this test case.
+ *
+ * @return test name
+ */
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Sets the validation strategy for this test case instance.
+ *
+ * @param validator
+ * - the fully qualified class name of the response validator to use.
+ */
+ public void setStrategy(String validator) {
+ ValidationStrategy strat = ValidationFactory.getInstance(validator);
+ if (strat != null) {
+ _strategy = strat;
+ } else {
+ TestUtil.logMsg("[WebTestCase][WARNING] An attempt was made to use a "
+ + "non-existing validator (" + validator + ")"
+ + ". Falling back to the TokenizedValidator");
+ }
+ }
+
+ /**
+ * Returns the class name of the response validator used.
+ *
+ * @return the fully qualified class of the validator used
+ */
+ public String getStrategy() {
+ return _strategy.getClass().getName();
+ }
+
+ /*
+ * Private Methods
+ * ===========================================================================
+ */
+
+ /**
+ * Utility method to add headers to test case holder objects.
+ *
+ * @param map
+ * the object in which to add header to
+ * @param headerString
+ * String representation of a header in the form of
+ * <headername>:<value>
+ */
+ private void addHeader(Map<String, Header> map, String headerString) {
+ TestUtil.logTrace(
+ "[WebTestCase] addHeader utility method called: " + headerString);
+ StringTokenizer st = new StringTokenizer(headerString, "|");
+ while (st.hasMoreTokens()) {
+ String head = st.nextToken();
+ int colIdx = head.indexOf(':');
+ String name = head.substring(0, colIdx).trim();
+ String value = head.substring(colIdx + 1).trim();
+ TestUtil
+ .logTrace("[WebTestCase] Adding test header: " + name + ", " + value);
+ Header header = map.get(name);
+ if (header != null) {
+ map.put(name, createNewHeader(value, header));
+ } else {
+ map.put(name, new Header(name, value));
+ }
+ }
+ }
+
+ /**
+ * Creates a new header based of the provided header and value.
+ *
+ * @param newValue
+ * - the new value to add to an existing header
+ * @param header
+ * - the original header
+ * @return new Header
+ */
+ private Header createNewHeader(String newValue, Header header) {
+ String oldValue = header.getValue();
+ return new Header(header.getName(), oldValue + ", " + newValue);
+ }
+
+ /**
+ * Adds a search string to the provided list
+ *
+ * @param stringList
+ * - list to add the string to
+ * @param s
+ * - the search string
+ */
+ private void addSearchStrings(List<String> stringList, String s) {
+ StringTokenizer st = new StringTokenizer(s, "|");
+ while (st.hasMoreTokens()) {
+ stringList.add(st.nextToken());
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java
new file mode 100644
index 0000000..5fc2685
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+public class ALLOWHandler implements Handler {
+
+ private static final Handler HANDLER = new ALLOWHandler();
+
+ private static final String DELIM = "##";
+
+ private ALLOWHandler() {
+ }
+
+ public static Handler getInstance() {
+ return HANDLER;
+ }
+
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+ String ALLOWHeader = responseHeader.getValue().toLowerCase();
+ String expectedValues = configuredHeader.getValue().toLowerCase()
+ .replace(" ", "");
+
+ TestUtil.logTrace("[ALLOWHandler] ALLOW header received: " + ALLOWHeader);
+
+ StringTokenizer conf = new StringTokenizer(expectedValues, ",");
+ while (conf.hasMoreTokens()) {
+ String token = conf.nextToken();
+ String token1 = token;
+
+ if ((ALLOWHeader.indexOf(token) < 0)
+ && (ALLOWHeader.indexOf(token1) < 0)) {
+ TestUtil.logErr("[ALLOWHandler] Unable to find '" + token
+ + "' within the ALLOW header returned by the server.");
+ return false;
+ } else {
+ TestUtil.logTrace("[ALLOWHandler] Found expected value, '" + token
+ + "' in ALLOW header returned by server.");
+ }
+ }
+ return true;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java
new file mode 100644
index 0000000..3840a64
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java
@@ -0,0 +1,153 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * When invoked, the content-type header
+ * will be appropriately handled. It allows
+ * flexible checking of control values against
+ * the response which could be in the form of:
+ * content-type; charset
+ * -or-
+ * conent-type
+ * </PRE>
+ */
+public class ContentTypeHandler implements Handler {
+
+ private static Handler handler = new ContentTypeHandler();
+
+ /**
+ * Creates new ContentTypeHandler
+ */
+ private ContentTypeHandler() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns an instance of this handler.
+ */
+ public static Handler getInstance() {
+ return handler;
+ }
+
+ /**
+ * Invokes handler logic.
+ *
+ * @param configuredHeader
+ * the user configured header
+ * @param responseHeader
+ * the response header from the server
+ * @return True if the passed match, otherwise false
+ */
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+ boolean ret = false;
+ TestUtil.logTrace("[ContentTypeHandler] ContentTypeHandler invoked.");
+ String configVal = configuredHeader.getValue().trim();
+ String responseVal = responseHeader.getValue().trim();
+ int colIdx = configVal.indexOf(';');
+ if (colIdx < 0) {
+ // Info we're interested in : type/subtype
+
+ // check response Content-Type header to see what format
+ // it's in.
+ int rColIdx = responseVal.indexOf(';');
+ if (rColIdx < 0) {
+ // Type and subtype, i.e. type/subtype are to be compared
+ // case insensitively.
+ if (configVal.equalsIgnoreCase(responseVal)) {
+ ret = true;
+ }
+ } else {
+ if (configVal.equalsIgnoreCase(responseVal.substring(0, rColIdx))) {
+ ret = true;
+ }
+ }
+ } else {
+ // Info we're interested in : type/subtype; parameter=value
+
+ int rColIdx = responseVal.indexOf(';');
+ if (rColIdx > -1) {
+ String confTypeSubType = configVal.substring(0, colIdx).trim();
+ String responseTypeSubType = responseVal.substring(0, rColIdx).trim();
+ String confParameter = configVal.substring(colIdx + 1).trim();
+ String responseParameter = (responseVal.substring(rColIdx + 1).trim())
+ .replaceAll(" ", "");
+ // compare type/subtype in a case insensitive manner
+ if (confTypeSubType.equalsIgnoreCase(responseTypeSubType)) {
+ // next validate the parameter in a case insensitive manner
+ if (confParameter.equalsIgnoreCase(responseParameter)) {
+ ret = true;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java
new file mode 100644
index 0000000..4ef41af
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java
@@ -0,0 +1,145 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HeaderElement;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * The default handler will handle any
+ * header that doesn't have a configured handler.
+ * </PRE>
+ */
+public class DefaultHandler implements Handler {
+
+ private static Handler handler = new DefaultHandler();
+
+ /**
+ * Creates new DefaultHandler
+ */
+ private DefaultHandler() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns an instance of this handler.
+ */
+ public static Handler getInstance() {
+ return handler;
+ }
+
+ /**
+ * Invokes handler logic.
+ *
+ * @param configuredHeader
+ * the user configured header
+ * @param responseHeader
+ * the response header from the server
+ * @return True if the passed match, otherwise false
+ */
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+ TestUtil.logTrace("[DefaulHandler] DefaultHandler invoked.");
+
+ return areHeadersEqual(configuredHeader, responseHeader);
+ }
+
+ /**
+ * Utility method to determine equality of two Header objects
+ *
+ * @param h1
+ * first header
+ * @param h2
+ * second header
+ * @return true if the headers are equal, otherwise false
+ */
+ protected boolean areHeadersEqual(Header h1, Header h2) {
+
+ HeaderElement[] h1Values = h1.getElements();
+ HeaderElement[] h2Values = h2.getElements();
+
+ if (h1Values.length == h2Values.length) {
+ for (HeaderElement h1Value : h1Values) {
+ String h1Val = h1Value.getName();
+ boolean found = false;
+ for (HeaderElement h2Value : h2Values) {
+ if (h1Val.equals(h2Value.getName())) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java
new file mode 100644
index 0000000..3801d33
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java
@@ -0,0 +1,84 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+/**
+ * Handler interface.
+ */
+public interface Handler {
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Invokes handler logic.
+ *
+ * @param configuredHeader
+ * the user configured header
+ * @param responseHeader
+ * the response header from the server
+ * @return True if the passed match, otherwise false
+ */
+ public boolean invoke(Header configuredHeader, Header responseHeader);
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java
new file mode 100644
index 0000000..6d90810
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java
@@ -0,0 +1,126 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+/**
+ * <PRE>
+ * The HandlerManager is responsible for returning the appropriate handler
+ * instance based on the provided value.
+ */
+public class HandlerFactory {
+
+ /**
+ * Content-Type handler name.
+ */
+ private static final String CONTENT_TYPE = "content-type";
+
+ /**
+ * Location handler name.
+ */
+ private static final String LOCATION = "location";
+
+ /**
+ * Set-Cookie handler name.
+ */
+ private static final String SET_COOKIE = "set-cookie";
+
+ /**
+ * ALLOW handler name.
+ */
+ private static final String ALLOW = "allow";
+
+ /**
+ * www-authenticate handler name.
+ */
+ private static final String WWW_AUTH = "www-authenticate";
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Constructs a new HandlerManager instance
+ */
+ private HandlerFactory() {
+ }
+
+ /**
+ * Returns the appropriate handler instance based on provided discriminate (a
+ * header name).
+ *
+ * @param handlerName
+ * handler instance to obtain.
+ */
+ public static Handler getHandler(String handlerName) {
+ if (CONTENT_TYPE.equals(handlerName.toLowerCase())) {
+ return ContentTypeHandler.getInstance();
+ } else if (LOCATION.equals(handlerName.toLowerCase())) {
+ return LocationHandler.getInstance();
+ } else if (SET_COOKIE.equals(handlerName.toLowerCase())) {
+ return SetCookieHandler.getInstance();
+ } else if (WWW_AUTH.equals(handlerName.toLowerCase())) {
+ return WWWAuthenticateHandler.getInstance();
+ } else if (ALLOW.equals(handlerName.toLowerCase())) {
+ return ALLOWHandler.getInstance();
+ } else {
+ return DefaultHandler.getInstance();
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java
new file mode 100644
index 0000000..835bb73
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java
@@ -0,0 +1,162 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * Will handle headers for the following
+ * cases:
+ * - Server is on port 80 and port value isn't
+ * propagated back to client (assumed)
+ * - Port value is in response
+ * </PRE>
+ */
+public class LocationHandler implements Handler {
+
+ private static Handler handler = new LocationHandler();
+
+ /**
+ * Creates new ContentTypeHandler
+ */
+ private LocationHandler() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns an instance of this handler.
+ */
+ public static Handler getInstance() {
+ return handler;
+ }
+
+ /**
+ * Invokes handler logic.
+ *
+ * @param configuredHeader
+ * the user configured header
+ * @param responseHeader
+ * the response header from the server
+ * @return True if the passed match, otherwise false
+ */
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+ boolean pass = true;
+
+ try {
+ TestUtil.logTrace("[LocationHandler] LocationHandler invoked.");
+
+ URL configURL = new URL(configuredHeader.getValue());
+ URL responseURL = new URL(responseHeader.getValue());
+
+ if (!(configURL.getProtocol().equals(responseURL.getProtocol()))) {
+ pass = false;
+ TestUtil.logErr("[LocationHandler] Mismatch between protocols:");
+ TestUtil.logErr(
+ "[LocationHandler] Configured value: " + configURL.getProtocol());
+ TestUtil.logErr(
+ "[LocationHandler] Response value: " + responseURL.getProtocol());
+ }
+
+ if (!(configURL.getPath().equals(responseURL.getPath()))) {
+ pass = false;
+ TestUtil.logErr("[LocationHandler] Mismatch between paths:");
+ TestUtil.logErr(
+ "[LocationHandler] Configured value: " + configURL.getPath());
+ TestUtil.logErr(
+ "[LocationHandler] Response value: " + responseURL.getPath());
+ }
+
+ if (configURL.getQuery() == null) {
+ if (responseURL.getQuery() != null) {
+ pass = false;
+ TestUtil.logErr("[LocationHandler] Mismatch between querys:");
+ TestUtil.logErr("[LocationHandler] Configured value is null");
+ TestUtil.logErr("[LocationHandler] Response value is non-null");
+ }
+ } else if (!(configURL.getQuery().equals(responseURL.getQuery()))) {
+ pass = false;
+ TestUtil.logErr("[LocationHandler] Mismatch between querys:");
+ TestUtil.logErr(
+ "[LocationHandler] Configured value: " + configURL.getQuery());
+ TestUtil.logErr(
+ "[LocationHandler] Response value: " + responseURL.getQuery());
+ }
+
+ } catch (MalformedURLException mue) {
+ pass = false;
+ TestUtil.logErr("[LocationHandler] MalformedURLException");
+ TestUtil.printStackTrace(mue);
+ }
+
+ return pass;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java
new file mode 100644
index 0000000..bb3b3ec
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+public class SetCookieHandler implements Handler {
+
+ private static final Handler HANDLER = new SetCookieHandler();
+
+ private static final String DELIM = "##";
+
+ private SetCookieHandler() {
+ }
+
+ public static Handler getInstance() {
+ return HANDLER;
+ }
+
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+ String setCookieHeader = responseHeader.getValue().toLowerCase();
+ String expectedValues = configuredHeader.getValue().toLowerCase();
+
+ TestUtil.logTrace(
+ "[SetCookieHandler] Set-Cookie header received: " + setCookieHeader);
+
+ StringTokenizer conf = new StringTokenizer(expectedValues, DELIM);
+ while (conf.hasMoreTokens()) {
+ String token = conf.nextToken();
+ String token1 = token;
+
+ if (token.endsWith("\"") && (token.indexOf("=\"") > 1)) {
+ token1 = token.replace("=\"", "=");
+ token1 = token1.substring(0, token.length() - 2);
+ }
+
+ if (token.startsWith("!")) {
+ String attr = token.substring(1);
+ String attr1 = token1.substring(1);
+ if ((setCookieHeader.indexOf(attr) > -1)
+ || (setCookieHeader.indexOf(attr1) > -1)) {
+ TestUtil.logErr("[SetCookieHandler] Unexpected attribute found "
+ + " Set-Cookie header. Attribute: " + attr
+ + "\nSet-Cookie header: " + setCookieHeader);
+ return false;
+ }
+ } else {
+ if ((setCookieHeader.indexOf(token) < 0)
+ && (setCookieHeader.indexOf(token1) < 0)) {
+ TestUtil.logErr("[SetCookieHandler] Unable to find '" + token
+ + "' within the Set-Cookie header returned by the server.");
+ return false;
+ } else {
+ TestUtil.logTrace("[SetCookieHandler] Found expected value, '" + token
+ + "' in Set-Cookie header returned by server.");
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java
new file mode 100644
index 0000000..898df21
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java
@@ -0,0 +1,113 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * Will handle headers for the following
+ * cases:
+ * - Server is on port 80 and port value isn't
+ * propagated back to client (assumed)
+ * - Port value is in response
+ * </PRE>
+ */
+public class WWWAuthenticateHandler implements Handler {
+
+ private static Handler handler = new WWWAuthenticateHandler();
+
+ /**
+ * Creates new ContentTypeHandler
+ */
+ private WWWAuthenticateHandler() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns an instance of this handler.
+ */
+ public static Handler getInstance() {
+ return handler;
+ }
+
+ /**
+ * Invokes handler logic.
+ *
+ * @param configuredHeader
+ * the user configured header
+ * @param responseHeader
+ * the response header from the server
+ * @return True if the passed match, otherwise false
+ */
+ public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+ TestUtil
+ .logTrace("[WWWAuthenticateHandler] WWAuthenticateHandler invoked.");
+ return true;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java
new file mode 100644
index 0000000..a1aa017
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpConnection;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.Util;
+
+/**
+ * Represents an HTTP client Request
+ */
+
+public class HttpRequest {
+
+ static {
+ // if (TestUtil.traceflag) {
+ // System.setProperty("org.apache.commons.logging.Log",
+ // "jakarta.ws.rs.tck.common.webclient.log.WebLog");
+ // System.setProperty(
+ // "org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
+ // }
+ }
+
+ /**
+ * Default HTTP port.
+ */
+ public static int DEFAULT_HTTP_PORT = 80;
+
+ /**
+ * Default HTTP SSL port.
+ */
+ public static final int DEFAULT_SSL_PORT = 443;
+
+ /**
+ * No authentication
+ */
+ public static final int NO_AUTHENTICATION = 0;
+
+ /**
+ * Basic authentication
+ */
+ public static final int BASIC_AUTHENTICATION = 1;
+
+ /**
+ * Digest authenctication
+ */
+ public static final int DIGEST_AUTHENTICATION = 2;
+
+ /**
+ * Method representation of request.
+ */
+ private HttpMethod _method = null;
+
+ /**
+ * Target web container host
+ */
+ private String _host = null;
+
+ /**
+ * Target web container port
+ */
+ private int _port = DEFAULT_HTTP_PORT;
+
+ /**
+ * Is the request going over SSL
+ */
+ private boolean _isSecure = false;
+
+ /**
+ * HTTP state
+ */
+ private HttpState _state = null;
+
+ /**
+ * Original request line for this request.
+ */
+ private String _requestLine = null;
+
+ /**
+ * Authentication type for current request
+ */
+ private int _authType = NO_AUTHENTICATION;
+
+ /**
+ * Flag to determine if session tracking will be used or not.
+ */
+ private boolean _useCookies = false;
+
+ /**
+ * Content length of request body.
+ */
+ private int _contentLength = 0;
+
+ /**
+ * FollowRedirects
+ */
+ private boolean _redirect = false;
+
+ Header[] _headers = null;
+
+ protected HttpClient client = null;
+
+ /**
+ * Creates new HttpRequest based of the passed request line. The request line
+ * provied must be in the form of:<br>
+ *
+ * <pre>
+ * METHOD PATH HTTP-VERSION
+ * Ex. GET /index.html HTTP/1.0
+ * </pre>
+ */
+ public HttpRequest(String requestLine, String host, int port) {
+ client = new HttpClient();
+ _method = MethodFactory.getInstance(requestLine);
+ _method.setFollowRedirects(false);
+ _host = host;
+ _port = port;
+
+ if (port == DEFAULT_SSL_PORT) {
+ _isSecure = true;
+ }
+
+ // If we got this far, the request line is in the proper
+ // format
+ _requestLine = requestLine;
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * <code>getRequestPath</code> returns the request path for this particular
+ * request.
+ *
+ * @return String request path
+ */
+ public String getRequestPath() {
+ return _method.getPath();
+ }
+
+ /**
+ * <code>getRequestMethod</code> returns the request type, i.e., GET, POST,
+ * etc.
+ *
+ * @return String request type
+ */
+ public String getRequestMethod() {
+ return _method.getName();
+ }
+
+ /**
+ * <code>isSecureConnection()</code> indicates if the Request is secure or
+ * not.
+ *
+ * @return boolean whether Request is using SSL or not.
+ */
+ public boolean isSecureRequest() {
+ return _isSecure;
+ }
+
+ /**
+ * <code>setSecureRequest</code> configures this request to use SSL.
+ *
+ * @param secure
+ * - whether the Request uses SSL or not.
+ */
+ public void setSecureRequest(boolean secure) {
+ _isSecure = secure;
+ }
+
+ /**
+ * <code>setContent</code> will set the body for this request. Note, this is
+ * only valid for POST and PUT operations, however, if called and the request
+ * represents some other HTTP method, it will be no-op'd.
+ *
+ * @param content
+ * request content
+ */
+ public void setContent(String content) {
+ if (_method instanceof EntityEnclosingMethod) {
+ ((EntityEnclosingMethod) _method)
+ .setRequestEntity(new StringRequestEntity(content));
+ }
+ _contentLength = content.length();
+ }
+
+ /**
+ * <code>setAuthenticationCredentials configures the request to
+ * perform authentication.
+ *
+ * <p><code>username</code> and <code>password</code> cannot be null.
+ * </p>
+ *
+ * <p>
+ * It is legal for <code>realm</code> to be null.
+ * </p>
+ *
+ * @param username
+ * the user
+ * @param password
+ * the user's password
+ * @param authType
+ * authentication type
+ * @param realm
+ * authentication realm
+ */
+ public void setAuthenticationCredentials(String username, String password,
+ int authType, String realm) {
+ if (username == null) {
+ throw new IllegalArgumentException("Username cannot be null");
+ }
+
+ if (password == null) {
+ throw new IllegalArgumentException("Password cannot be null");
+ }
+
+ UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username,
+ password);
+ AuthScope scope = new AuthScope(_host, _port, realm);
+ getState().setCredentials(scope, cred);
+ TestUtil.logTrace("[HttpRequest] Added credentials for '" + username
+ + "' with password '" + password + "' in realm '" + realm + "'");
+
+ _authType = authType;
+ }
+
+ /**
+ * <code>addRequestHeader</code> adds a request header to this request. If a
+ * request header of the same name already exists, the new value, will be
+ * added to the set of already existing values.
+ *
+ * <strong>NOTE:</strong> that header names are not case-sensitive.
+ *
+ * @param headerName
+ * request header name
+ * @param headerValue
+ * request header value
+ */
+ public void addRequestHeader(String headerName, String headerValue) {
+ _method.addRequestHeader(headerName, headerValue);
+ TestUtil.logTrace("[HttpRequest] Added request header: "
+ + _method.getRequestHeader(headerName).toExternalForm());
+ }
+
+ public void addRequestHeader(String header) {
+ StringTokenizer st = new StringTokenizer(header, "|");
+ while (st.hasMoreTokens()) {
+ String h = st.nextToken();
+ if (h.toLowerCase().startsWith("cookie")) {
+ createCookie(h);
+ continue;
+ }
+ int col = h.indexOf(':');
+ addRequestHeader(h.substring(0, col).trim(), h.substring(col + 1).trim());
+ }
+ }
+
+ /**
+ * <code>setRequestHeader</code> sets a request header for this request
+ * overwritting any previously existing header/values with the same name.
+ *
+ * <strong>NOTE:</strong> Header names are not case-sensitive.
+ *
+ * @param headerName
+ * request header name
+ * @param headerValue
+ * request header value
+ */
+ public void setRequestHeader(String headerName, String headerValue) {
+ _method.setRequestHeader(headerName, headerValue);
+ TestUtil.logTrace("[HttpRequest] Set request header: "
+ + _method.getRequestHeader(headerName).toExternalForm());
+
+ }
+
+ /**
+ * <code>setFollowRedirects</code> indicates whether HTTP redirects are
+ * followed. By default, redirects are not followed.
+ */
+ public void setFollowRedirects(boolean followRedirects) {
+ _method.setFollowRedirects(followRedirects);
+ }
+
+ /**
+ * <code>getFollowRedirects</code> indicates whether HTTP redirects are
+ * followed.
+ */
+ public boolean getFollowRedirects() {
+ return _method.getFollowRedirects();
+ }
+
+ /**
+ * <code>setState</code> will set the HTTP state for the current request (i.e.
+ * session tracking). This has the side affect
+ */
+ public void setState(HttpState state) {
+ _state = state;
+ _useCookies = true;
+ }
+
+ /**
+ * <code>execute</code> will dispatch the current request to the target
+ * server.
+ *
+ * @return HttpResponse the server's response.
+ * @throws IOException
+ * if an I/O error occurs during dispatch.
+ */
+ public HttpResponse execute() throws IOException, HttpException {
+ String method;
+ int defaultPort;
+ ProtocolSocketFactory factory;
+
+ if (_method.getFollowRedirects()) {
+ client = new HttpClient();
+
+ if (_isSecure) {
+ method = "https";
+ defaultPort = DEFAULT_SSL_PORT;
+ factory = new SSLProtocolSocketFactory();
+ } else {
+ method = "http";
+ defaultPort = DEFAULT_HTTP_PORT;
+ factory = new DefaultProtocolSocketFactory();
+ }
+
+ Protocol protocol = new Protocol(method, factory, defaultPort);
+ HttpConnection conn = new HttpConnection(_host, _port, protocol);
+
+ if (conn.isOpen()) {
+ throw new IllegalStateException("Connection incorrectly opened");
+ }
+
+ conn.open();
+
+ TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine
+ + "' to target server at '" + _host + ":" + _port + "'");
+
+ addSupportHeaders();
+ _headers = _method.getRequestHeaders();
+
+ TestUtil.logTrace(
+ "########## The real value set: " + _method.getFollowRedirects());
+
+ client.getHostConfiguration().setHost(_host, _port, protocol);
+
+ client.executeMethod(_method);
+
+ return new HttpResponse(_host, _port, _isSecure, _method, getState());
+ } else {
+ if (_isSecure) {
+ method = "https";
+ defaultPort = DEFAULT_SSL_PORT;
+ factory = new SSLProtocolSocketFactory();
+ } else {
+ method = "http";
+ defaultPort = DEFAULT_HTTP_PORT;
+ factory = new DefaultProtocolSocketFactory();
+ }
+
+ Protocol protocol = new Protocol(method, factory, defaultPort);
+ HttpConnection conn = new HttpConnection(_host, _port, protocol);
+
+ if (conn.isOpen()) {
+ throw new IllegalStateException("Connection incorrectly opened");
+ }
+
+ conn.open();
+
+ TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine
+ + "' to target server at '" + _host + ":" + _port + "'");
+
+ addSupportHeaders();
+ _headers = _method.getRequestHeaders();
+
+ TestUtil.logTrace(
+ "########## The real value set: " + _method.getFollowRedirects());
+
+ _method.execute(getState(), conn);
+
+ return new HttpResponse(_host, _port, _isSecure, _method, getState());
+ }
+ }
+
+ /**
+ * Returns the current state for this request.
+ *
+ * @return HttpState current state
+ */
+ public HttpState getState() {
+ if (_state == null) {
+ _state = new HttpState();
+ }
+ return _state;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[REQUEST LINE] -> ").append(_requestLine).append('\n');
+
+ if (_headers != null && _headers.length != 0) {
+
+ for (Header _header : _headers) {
+ sb.append(" [REQUEST HEADER] -> ");
+ sb.append(_header.toExternalForm()).append('\n');
+ }
+ }
+
+ if (_contentLength != 0) {
+ sb.append(" [REQUEST BODY LENGTH] -> ").append(_contentLength);
+ sb.append('\n');
+ }
+
+ return sb.toString();
+
+ }
+
+ /*
+ * private methods
+ * ========================================================================
+ */
+
+ private void createCookie(String cookieHeader) {
+ String cookieLine = cookieHeader.substring(cookieHeader.indexOf(':') + 1)
+ .trim();
+ StringTokenizer st = new StringTokenizer(cookieLine, " ;");
+ Cookie cookie = new Cookie();
+ cookie.setVersion(1);
+
+ getState();
+
+ if (cookieLine.indexOf("$Version") == -1) {
+ cookie.setVersion(0);
+ _method.getParams().setCookiePolicy(CookiePolicy.NETSCAPE);
+ }
+
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+
+ if (token.charAt(0) != '$' && !token.startsWith("Domain")
+ && !token.startsWith("Path")) {
+ cookie.setName(token.substring(0, token.indexOf('=')));
+ cookie.setValue(token.substring(token.indexOf('=') + 1));
+ } else if (token.indexOf("Domain") > -1) {
+ cookie.setDomainAttributeSpecified(true);
+ cookie.setDomain(token.substring(token.indexOf('=') + 1));
+ } else if (token.indexOf("Path") > -1) {
+ cookie.setPathAttributeSpecified(true);
+ cookie.setPath(token.substring(token.indexOf('=') + 1));
+ }
+ }
+ _state.addCookie(cookie);
+
+ }
+
+ /**
+ * Adds any support request headers necessary for this request. These headers
+ * will be added based on the state of the request.
+ */
+ private void addSupportHeaders() {
+
+ // Authentication headers
+ // NOTE: Possibly move logic to generic method
+ switch (_authType) {
+ case NO_AUTHENTICATION:
+ break;
+ case BASIC_AUTHENTICATION:
+ setBasicAuthorizationHeader();
+ break;
+ case DIGEST_AUTHENTICATION:
+ throw new UnsupportedOperationException(
+ "Digest Authentication is not currently " + "supported");
+ }
+
+ // A Host header will be added to each request to handle
+ // cases where virtual hosts are used, or there is no DNS
+ // available on the system where the container is running.
+ setHostHeader();
+
+ // Content length header
+ setContentLengthHeader();
+
+ // Cookies
+ setCookieHeader();
+ }
+
+ /**
+ * Sets a basic authentication header in the request is Request is configured
+ * to use basic authentication
+ */
+ private void setBasicAuthorizationHeader() {
+ UsernamePasswordCredentials cred = (UsernamePasswordCredentials) getState()
+ .getCredentials(new AuthScope(_host, _port, null));
+ String authString = null;
+ if (cred != null) {
+ authString = "Basic " + Util.getBase64EncodedString(
+ cred.getUserName() + ":" + cred.getPassword());
+ } else {
+ TestUtil.logTrace("[HttpRequest] NULL CREDENTIALS");
+ }
+ _method.setRequestHeader("Authorization", authString);
+ }
+
+ /**
+ * Sets a Content-Length header in the request if content is present
+ */
+ private void setContentLengthHeader() {
+ if (_contentLength > 0) {
+ _method.setRequestHeader("Content-Length",
+ Integer.toString(_contentLength));
+ }
+ }
+
+ /**
+ * Sets a host header in the request. If the configured host value is an IP
+ * address, the Host header will be sent, but without any value.
+ *
+ * If we adhered to the HTTP/1.1 spec, the Host header must be empty of the
+ * target server is identified via IP address. However, no user agents I've
+ * tested follow this. And if a custom client library does this, it may not
+ * work properly with the target server. For now, the Host request-header will
+ * always have a value.
+ */
+ private void setHostHeader() {
+ if (_port == DEFAULT_HTTP_PORT || _port == DEFAULT_SSL_PORT) {
+ _method.setRequestHeader("Host", _host);
+ } else {
+ _method.setRequestHeader("Host", _host + ":" + _port);
+ }
+ }
+
+ /**
+ * Sets a Cookie header if this request is using cookies.
+ */
+ private void setCookieHeader() {
+ if (_useCookies) {
+ Cookie[] cookies = _state.getCookies();
+ if (cookies != null && cookies.length > 0) {
+ Header cHeader = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109)
+ .formatCookieHeader(_state.getCookies());
+ if (cHeader != null) {
+ _method.setRequestHeader(cHeader);
+ }
+ }
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java
new file mode 100644
index 0000000..177d6df
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2006, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.HttpVersion;
+
+import jakarta.ws.rs.tck.common.webclient.Util;
+
+/**
+ * This class represents an HTTP response from the server.
+ */
+
+public class HttpResponse {
+
+ /**
+ * Default encoding based on Servlet Specification
+ */
+ private static final String DEFAULT_ENCODING = "ISO-8859-1";
+
+ /**
+ * Content-Type header
+ */
+ private static final String CONTENT_TYPE = "Content-Type";
+
+ /**
+ * Wrapped HttpMethod used to pull response info from.
+ */
+ private HttpMethod _method = null;
+
+ /**
+ * HttpState obtained after execution of request
+ */
+ private HttpState _state = null;
+
+ /**
+ * Charset encoding returned in the response
+ */
+ private String _encoding = DEFAULT_ENCODING;
+
+ /**
+ * The response body. Initialized after first call to one of the
+ * getResponseBody methods and cached for subsequent calls.
+ */
+ private String _responseBody = null;
+
+ /**
+ * Host name used for processing request
+ */
+ private String _host = null;
+
+ /**
+ * Port number used for processing request
+ */
+ private int _port;
+
+ /**
+ * Issecure
+ */
+ private boolean _isSecure;
+
+ /** Creates new HttpResponse */
+ public HttpResponse(String host, int port, boolean isSecure,
+ HttpMethod method, HttpState state) {
+
+ _host = host;
+ _port = port;
+ _isSecure = isSecure;
+ _method = method;
+ _state = state;
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns the HTTP status code returned by the server
+ *
+ * @return HTTP status code
+ */
+ public String getStatusCode() {
+ return Integer.toString(_method.getStatusCode());
+ }
+
+ /**
+ * Returns the HTTP reason-phrase returned by the server
+ *
+ * @return HTTP reason-phrase
+ */
+ public String getReasonPhrase() {
+ return _method.getStatusText();
+ }
+
+ /**
+ * Returns the headers received in the response from the server.
+ *
+ * @return response headers
+ */
+ public Header[] getResponseHeaders() {
+ return _method.getResponseHeaders();
+ }
+
+ /**
+ * Returns the headers designated by the name provided.
+ *
+ * @return response headers
+ */
+ public Header[] getResponseHeaders(String headerName) {
+ return _method.getResponseHeaders(headerName);
+ }
+
+ /**
+ * Returns the response header designated by the name provided.
+ *
+ * @return a specfic response header or null if the specified header doesn't
+ * exist.
+ */
+ public Header getResponseHeader(String headerName) {
+ return _method.getResponseHeader(headerName);
+ }
+
+ /**
+ * Returns the response body as a byte array using the charset specified in
+ * the server's response.
+ *
+ * @return response body as an array of bytes.
+ */
+ public byte[] getResponseBodyAsBytes() throws IOException {
+ return getEncodedResponse().getBytes();
+ }
+
+ /**
+ * Returns the response as bytes (no encoding is performed by client.
+ *
+ * @return the raw response bytes
+ * @throws IOException
+ * if an error occurs reading from server
+ */
+ public byte[] getResponseBodyAsRawBytes() throws IOException {
+ return _method.getResponseBody();
+ }
+
+ /**
+ * Returns the response body as a string using the charset specified in the
+ * server's response.
+ *
+ * @return response body as a String
+ */
+ public String getResponseBodyAsString() throws IOException {
+ return getEncodedResponse();
+ }
+
+ /**
+ * Returns the response body of the server without being encoding by the
+ * client.
+ *
+ * @return an unecoded String representation of the response
+ * @throws IOException
+ * if an error occurs reading from the server
+ */
+ public String getResponseBodyAsRawString() throws IOException {
+ return _method.getResponseBodyAsString();
+ }
+
+ /**
+ * Returns the response body as an InputStream using the encoding specified in
+ * the server's response.
+ *
+ * @return response body as an InputStream
+ */
+ public InputStream getResponseBodyAsStream() throws IOException {
+ return new ByteArrayInputStream(getEncodedResponse().getBytes());
+ }
+
+ /**
+ * Returns the response body as an InputStream without any encoding applied by
+ * the client.
+ *
+ * @return an InputStream to read the response
+ * @throws IOException
+ * if an error occurs reading from the server
+ */
+ public InputStream getResponseBodyAsRawStream() throws IOException {
+ return _method.getResponseBodyAsStream();
+ }
+
+ /**
+ * Returns the charset encoding for this response.
+ *
+ * @return charset encoding
+ */
+ public String getResponseEncoding() {
+ Header content = _method.getResponseHeader(CONTENT_TYPE);
+ if (content != null) {
+ String headerVal = content.getValue();
+ int idx = headerVal.indexOf(";charset=");
+ if (idx > -1) {
+ // content encoding included in response
+ _encoding = headerVal.substring(idx + 9);
+ }
+ }
+ return _encoding;
+ }
+
+ /**
+ * Returns the post-request state.
+ *
+ * @return an HttpState object
+ */
+ public HttpState getState() {
+ return _state;
+ }
+
+ /**
+ * Displays a String representation of the response.
+ *
+ * @return string representation of response
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer(255);
+
+ sb.append("[RESPONSE STATUS LINE] -> ");
+ sb.append(((HttpMethodBase) _method).getParams().getVersion()
+ .equals(HttpVersion.HTTP_1_1) ? "HTTP/1.1 " : "HTTP/1.0 ");
+ sb.append(_method.getStatusCode()).append(' ');
+ sb.append(_method.getStatusText()).append('\n');
+ Header[] headers = _method.getResponseHeaders();
+ if (headers != null && headers.length != 0) {
+ for (int i = 0; i < headers.length; i++) {
+ sb.append(" [RESPONSE HEADER] -> ");
+ sb.append(headers[i].toExternalForm()).append('\n');
+ }
+ }
+
+ String resBody;
+ try {
+ resBody = _method.getResponseBodyAsString();
+ } catch (IOException ioe) {
+ resBody = "UNEXECTED EXCEPTION: " + ioe.toString();
+ }
+ if (resBody != null && resBody.length() != 0) {
+ sb.append("------ [RESPONSE BODY] ------\n");
+ sb.append(resBody);
+ sb.append("\n-----------------------------\n\n");
+ }
+ return sb.toString();
+ }
+
+ /*
+ * Eventually they need to come from _method
+ */
+
+ public String getHost() {
+ return _host;
+ }
+
+ public int getPort() {
+ return _port;
+ }
+
+ public String getProtocol() {
+ return _isSecure ? "https" : "http";
+ }
+
+ public String getPath() {
+ return _method.getPath();
+ }
+
+ /*
+ * Private Methods
+ * ==========================================================================
+ */
+
+ /**
+ * Returns the response body using the encoding returned in the response.
+ *
+ * @return encoded response String.
+ */
+ private String getEncodedResponse() throws IOException {
+ if (_responseBody == null) {
+ _responseBody = Util.getEncodedStringFromStream(
+ _method.getResponseBodyAsStream(), getResponseEncoding());
+ }
+ return _responseBody;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java
new file mode 100644
index 0000000..0a03141
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpVersion;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.HeadMethod;
+import org.apache.commons.httpclient.methods.OptionsMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+
+import jakarta.ws.rs.tck.lib.porting.TSURL;
+
+/**
+ * Simple factory class which returns HttpMethod implementations based on a
+ * request line.
+ * <p>
+ * For example, a request line of <tt>GET /index.jsp HTTP/1.0</tt> would return
+ * an HttpMethod implementation that handles GET requests using HTTP/1.0.
+ * </p>
+ */
+
+public class MethodFactory {
+
+ /**
+ * HTTP GET
+ */
+ private static final String GET_METHOD = "GET";
+
+ /**
+ * HTTP POST
+ */
+ private static final String POST_METHOD = "POST";
+
+ /**
+ * HTTP HEAD
+ */
+ private static final String HEAD_METHOD = "HEAD";
+
+ /**
+ * HTTP PUT
+ */
+ private static final String PUT_METHOD = "PUT";
+
+ /**
+ * HTTP DELETE
+ */
+ private static final String DELETE_METHOD = "DELETE";
+
+ /**
+ * HTTP OPTIONS
+ */
+ private static final String OPTIONS_METHOD = "OPTIONS";
+
+ /**
+ * TSURL implementation
+ */
+ private static final TSURL TS_URL = new TSURL();
+
+ /**
+ * Private constructor as all interaction with this class is through the
+ * getInstance() method.
+ */
+ private MethodFactory() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns the approriate request method based on the provided request string.
+ * The request must be in the format of METHOD URI_PATH HTTP_VERSION, i.e. GET
+ * /index.jsp HTTP/1.1.
+ *
+ * @return HttpMethod based in request.
+ */
+ public static HttpMethod getInstance(String request) {
+ StringTokenizer st = new StringTokenizer(request);
+ String method;
+ String query = null;
+ String uri;
+ String version;
+ try {
+ method = st.nextToken();
+ uri = TS_URL.getRequest(st.nextToken());
+ version = st.nextToken();
+ } catch (NoSuchElementException nsee) {
+ throw new IllegalArgumentException(
+ "Request provided: " + request + " is malformed.");
+ }
+
+ // check to see if there is a query string appended
+ // to the URI
+ int queryStart = uri.indexOf('?');
+ if (queryStart != -1) {
+ query = uri.substring(queryStart + 1);
+ uri = uri.substring(0, queryStart);
+ }
+
+ HttpMethodBase req;
+
+ if (method.equals(GET_METHOD)) {
+ req = new GetMethod(uri);
+ } else if (method.equals(POST_METHOD)) {
+ req = new PostMethod(uri);
+ } else if (method.equals(PUT_METHOD)) {
+ req = new PutMethod(uri);
+ } else if (method.equals(DELETE_METHOD)) {
+ req = new DeleteMethod(uri);
+ } else if (method.equals(HEAD_METHOD)) {
+ req = new HeadMethod(uri);
+ } else if (method.equals(OPTIONS_METHOD)) {
+ req = new OptionsMethod(uri);
+ } else {
+ throw new IllegalArgumentException("Invalid method: " + method);
+ }
+
+ setHttpVersion(version, req);
+
+ if (query != null) {
+ req.setQueryString(query);
+ }
+
+ return req;
+ }
+
+ /*
+ * private methods
+ * ========================================================================
+ */
+
+ /**
+ * Sets the HTTP version for the method in question.
+ *
+ * @param version
+ * HTTP version to use for this request
+ * @param method
+ * method to adjust HTTP version
+ */
+ private static void setHttpVersion(String version, HttpMethodBase method) {
+ final String oneOne = "HTTP/1.1";
+ method.getParams().setVersion(
+ (version.equals(oneOne) ? HttpVersion.HTTP_1_1 : HttpVersion.HTTP_1_0));
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java
new file mode 100644
index 0000000..654f181
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2021 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.webclient.validation;
+
+import java.io.IOException;
+
+/**
+ * Sometimes it is not clear what result one should get, there might be more two
+ * or more possibilities. This strategy checks the response contains at least
+ * one of the given statuses.
+ *
+ * The statuses are supposed to be separated by "|" character
+ *
+ * @author Jan Supol
+ */
+public class CheckOneOfStatusesTokenizedValidator extends TokenizedValidator {
+
+ /**
+ * When WebTestCase contains more expected response codes it always means to
+ * check one of them is present; if present, other statuses are dropped. Super
+ * class method is called to get the logging messages
+ */
+ @Override
+ protected boolean checkStatusCode() throws IOException {
+ String responseCode = _res.getStatusCode();
+ String caseCodes = _case.getStatusCode();
+
+ if (caseCodes != null && caseCodes.charAt(0) != '!'
+ && caseCodes.contains("|") && caseCodes.contains(responseCode))
+ _case.setExpectedStatusCode(responseCode);
+ return super.checkStatusCode();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java
new file mode 100644
index 0000000..0237136
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.StringTokenizer;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.Goldenfile;
+
+/**
+ * <pre>
+ * This class provides all of the functionality of the
+ * WebValidatorBase class. Additionally, it will compare
+ * the server's response body with the test case's configured
+ * goldenfile using a StringTokenizer.
+ * </pre>
+ */
+public class TokenizedValidator extends WebValidatorBase {
+
+ /**
+ * System property that will cause the specified goldenfile to be written if
+ * it doesn't already exist.
+ */
+ private static final String RECORD_GF = "ts.record.gf";
+
+ /**
+ * Creates a new instance of TokenizedValidator
+ */
+ public TokenizedValidator() {
+ }
+
+ /*
+ * protected methods
+ * ========================================================================
+ */
+
+ /**
+ * Compare the server response and golenfile using a StringTokenizer.
+ *
+ * @return true if response and goldenfile are the same.
+ * @throws IOException
+ * if an error occurs will processing the Goldenfile
+ */
+ protected boolean checkGoldenfile() throws IOException {
+ String gf;
+ String path = _case.getGoldenfilePath();
+ String enc = _res.getResponseEncoding();
+
+ if (path == null) {
+ return true;
+ }
+
+ Goldenfile file = new Goldenfile(_case.getGoldenfilePath(), enc);
+
+ try {
+ gf = file.getGoldenFileAsString();
+ } catch (IOException ioe) {
+ TestUtil
+ .logErr("[TokenizedValidator] Unexpected exception while accessing "
+ + "goldenfile! " + ioe.toString());
+ return false;
+ }
+
+ String response = _res.getResponseBodyAsString();
+ StringTokenizer gfTokenizer = new StringTokenizer(gf);
+ StringTokenizer resTokenizer = new StringTokenizer(response);
+ int gfCount = gfTokenizer.countTokens();
+ int resCount = resTokenizer.countTokens();
+
+ // Logic to handle the recording of goldenfiles.
+ if (gf.equals("NO GOLDENFILE FOUND") && Boolean.getBoolean(RECORD_GF)) {
+
+ TestUtil
+ .logTrace("[TokenizedValidator][INFO] RECORDING GOLDENFILE: " + path);
+ OutputStreamWriter out = new OutputStreamWriter(
+ new FileOutputStream(path), enc);
+ out.write(response);
+ out.flush();
+ out.close();
+ }
+
+ // If the token counts are the same, continue checking
+ // each individual token, otherwise, immediately fail.
+ if (gfCount == resCount) {
+ while (gfTokenizer.hasMoreTokens()) {
+ String exp = gfTokenizer.nextToken();
+ String res = resTokenizer.nextToken();
+ if (!exp.equals(res)) {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[TokenizedValidator]: Server's response and ");
+ sb.append("goldenfile to not match!\n");
+ sb.append("\n Goldenfile token: ").append(exp);
+ sb.append("\n Response token: ").append(res);
+ TestUtil.logErr(sb.toString());
+ dumpResponseInfo(response, gf);
+ return false;
+ }
+ }
+ } else {
+ TestUtil
+ .logErr("[TokenizedValidator]: Token count between server response "
+ + "and goldenfile do not match.\n Response Token" + "count: "
+ + resCount + "\nGoldenfile Token count: " + gfCount);
+
+ dumpResponseInfo(response, gf);
+ return false;
+ }
+ TestUtil.logTrace("[TokenizedValidator]: Server's response matches the "
+ + "configured goldenfile.");
+ return true;
+ }
+
+ /*
+ * private methods
+ * ========================================================================
+ */
+
+ /**
+ * Dumps the response from the server and the content of the Goldenfile/
+ *
+ * @param serverResponse
+ * the response body from the server.
+ * @param goldenFile
+ * the test goldenfile
+ */
+ private static void dumpResponseInfo(String serverResponse,
+ String goldenFile) {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("\nServer Response (below):\n");
+ sb.append("------------------------------------------\n");
+ sb.append(serverResponse);
+ sb.append("\n------------------------------------------\n");
+ sb.append("\nGoldenfile (below):\n");
+ sb.append("------------------------------------------\n");
+ sb.append(goldenFile);
+ sb.append("\n------------------------------------------\n");
+ TestUtil.logErr(sb.toString());
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java
new file mode 100644
index 0000000..5505d73
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * Returns a ValidationStrategy instance used to validate a response against a
+ * particular WebTestCase
+ *
+ * @author Ryan Lubke
+ * @version %I%
+ */
+public class ValidationFactory {
+
+ /**
+ * Private constructor as all interaction with the class is through the
+ * getInstance() method.
+ */
+ private ValidationFactory() {
+ }
+
+ /*
+ * public methods
+ * ========================================================================
+ */
+
+ /**
+ * Returns a ValidationStrategy instance based on the available factory types.
+ *
+ * @param validator
+ * Validator instance to obtain
+ * @return a ValidationStrategy instance or null if the instance could not be
+ * obtained.
+ */
+ public static ValidationStrategy getInstance(String validator) {
+ try {
+ Object o = Thread.currentThread().getContextClassLoader()
+ .loadClass(validator).newInstance();
+ if (o instanceof ValidationStrategy) {
+ return (ValidationStrategy) o;
+ }
+ } catch (Throwable t) {
+ TestUtil.logMsg("[ValidationFactory] Unable to obtain "
+ + "ValidationStrategy instance: " + validator);
+ }
+ return null;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java
new file mode 100644
index 0000000..f8998d9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+
+/**
+ * A ValidationStrategy is used to compare a server response with a configured
+ * test case. How this validation is performed is up to the concrete
+ * implementation.
+ */
+public interface ValidationStrategy {
+ public boolean validate(WebTestCase testCase);
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java
new file mode 100644
index 0000000..4a0d027
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.handler.Handler;
+import jakarta.ws.rs.tck.common.webclient.handler.HandlerFactory;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+
+/**
+ * Base abstract class for WebTestCase validation.
+ */
+public abstract class WebValidatorBase implements ValidationStrategy {
+
+ /**
+ * Used to detect 4xx class HTTP errors to allow fail fast situations when 4xx
+ * errors are not expected.
+ */
+ protected static final char CLIENT_ERROR = '4';
+
+ /**
+ * Used to detect 5xx class HTTP errors to allows fail fast situations when
+ * 5xx errors are not expected.
+ */
+ protected static final char SERVER_ERROR = '5';
+
+ /**
+ * This test case's HttpResponse
+ */
+ protected HttpResponse _res = null;
+
+ /**
+ * This test case's HttpRequest
+ */
+ protected HttpRequest _req = null;
+
+ /**
+ * The test case being validated
+ */
+ protected WebTestCase _case = null;
+
+ /**
+ * <tt>validate</tt> Will validate the response against the configured
+ * TestCase.
+ *
+ *
+ * <ul>
+ * <li>Check the HTTP status-code</li>
+ * <li>Check the HTTP reason-phrase</li>
+ * <li>Check for expected headers</li>
+ * <li>Check from unexpected headers</li>
+ * <li>Check expected search strings</li>
+ * <li>Check unexpected search strings</li>
+ * <li>Check the goldenfile</li>
+ * </ul>
+ */
+ public boolean validate(WebTestCase testCase) {
+ _res = testCase.getResponse();
+ _req = testCase.getRequest();
+ _case = testCase;
+
+ // begin the check
+ try {
+ if (!checkStatusCode() || !checkReasonPhrase() || !checkExpectedHeaders()
+ || !checkUnexpectedHeaders() || !checkSearchStrings()
+ || !checkSearchStringsNoCase() || !checkUnorderedSearchStrings()
+ || !checkUnexpectedSearchStrings() || !checkGoldenfile()) {
+ return false;
+ }
+ } catch (IOException ioe) {
+ TestUtil
+ .logErr("[WebValidatorBase] Unexpected Exception: " + ioe.toString());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * <code>checkStatusCode</code> will perform status code comparisons based on
+ * the algorithm below
+ * <ul>
+ * <li>Check the HTTP status code</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If status code is -1, then return true
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If test case status code null and response 4xx, return failure, print
+ * error; return false
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If test case status code null and response 5xx, return failure include
+ * response body; return false
+ * <p>
+ * </li>
+ * <li>
+ * <p>
+ * If test case status code null, and response not 4xx or 5xx, return true
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * Test case status code not null, compare it with the response status code;
+ * return true if equal
+ * <p>
+ * <li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected boolean checkStatusCode() throws IOException {
+ String sCode = _case.getStatusCode();
+ String resCode = _res.getStatusCode();
+ if ("-1".equals(sCode))
+ return true;
+
+ if (sCode == null && resCode.charAt(0) == CLIENT_ERROR) {
+ TestUtil
+ .logErr("[WebValidatorBase] Unexpected " + resCode + " received from "
+ + "target server! Request path: " + _req.getRequestPath());
+ return false;
+ }
+
+ if (sCode == null && (resCode.charAt(0) == SERVER_ERROR)) {
+ String resBody = _res.getResponseBodyAsRawString();
+ StringBuffer sb = new StringBuffer(75 + resBody.length());
+ sb.append("[WebValidatorBase] Unexpected '");
+ sb.append(resCode).append("' received from target server!\n");
+ sb.append("Error response recieved from server:\n");
+ sb.append("------------------------------------------------\n");
+ sb.append(resBody != null ? resBody : "NO RESPONSE");
+ TestUtil.logErr(sb.toString());
+ return false;
+ }
+
+ if (sCode == null) {
+ return true;
+ }
+
+ // test status code not null, compare with that of the response
+ if (sCode.charAt(0) != '!') {
+ if (!sCode.equals(resCode)) {
+ TestUtil.logErr("[WebValidatorBase] Unexpected Status Code "
+ + "recieved from server. Expected '" + sCode + "' received '"
+ + resCode + "'");
+ return false;
+ }
+
+ TestUtil.logTrace("[WebValidatorBase] Expected Status Code '" + sCode
+ + "' found in response line!");
+ } else {
+ sCode = sCode.substring(1);
+ if (sCode.equals(resCode)) {
+ TestUtil.logErr("[WebValidatorBase] Unexpected Status Code "
+ + "recieved from server. Expected any value except '" + sCode
+ + "', received '" + resCode + "'");
+ return false;
+ }
+
+ TestUtil.logTrace("[WebValidatorBase] Status Code '" + sCode
+ + "' not found in response line!");
+ }
+
+ return true;
+ }
+
+ /**
+ * <code>checkSearchStrings</code> will scan the response for the configured
+ * strings that are to be expected in the response.
+ * <ul>
+ * <li>Check search strings</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If list of Strings is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If list of Strings is not null, scan response body. If string is found,
+ * return true, otherwise display error and return false.
+ * </p>
+ * </li>
+ * </ul>
+ * </ul>
+ * <em>NOTE:</em> If there are multiple search strings, the search will be
+ * performed as such to preserve the order. For example, if the list of search
+ * strings contains two entities, the search for the second entity will be
+ * started after the index if the first match.
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected boolean checkSearchStrings() throws IOException {
+ List list = _case.getSearchStrings();
+ boolean found = true;
+ if (list != null && !list.isEmpty()) {
+ String responseBody = _res.getResponseBodyAsRawString();
+
+ String search = null;
+
+ for (int i = 0, n = list.size(), startIdx = 0, bodyLength = responseBody
+ .length(); i < n; i++) {
+
+ // set the startIdx to the same value as the body length
+ // and let the test fail (prevents index based runtime
+ // exceptions).
+ if (startIdx >= bodyLength) {
+ startIdx = bodyLength;
+ }
+
+ search = (String) list.get(i);
+ int searchIdx = responseBody.indexOf(search, startIdx);
+
+ TestUtil.logTrace(
+ "[WebValidatorBase] Scanning response for " + "search string: '"
+ + search + "' starting at index " + "location: " + startIdx);
+ if (searchIdx < 0) {
+ found = false;
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Unable to find the following ");
+ sb.append("search string in the server's ");
+ sb.append("response: '").append(search).append("' at index: ");
+ sb.append(startIdx);
+ sb.append("\n[WebValidatorBase] Server's response:\n");
+ sb.append("-------------------------------------------\n");
+ sb.append(responseBody);
+ sb.append("\n-------------------------------------------\n");
+ TestUtil.logErr(sb.toString());
+ break;
+ }
+
+ TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+ + "' at index '" + searchIdx + "' in the server's " + "response");
+ // the new searchIdx is the old index plus the lenght of the
+ // search string.
+ startIdx = searchIdx + search.length();
+ }
+ }
+ return found;
+ }
+
+ /**
+ * <code>checkSearchStringsNoCase</code> will scan the response for the
+ * configured case insensitive strings that are to be expected in the
+ * response.
+ * <ul>
+ * <li>Check search strings</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If list of Strings is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If list of Strings is not null, scan response body. If string is found,
+ * return true, otherwise display error and return false.
+ * </p>
+ * </li>
+ * </ul>
+ * </ul>
+ * <em>NOTE:</em> If there are multiple search strings, the search will be
+ * performed as such to preserve the order. For example, if the list of search
+ * strings contains two entities, the search for the second entity will be
+ * started after the index if the first match.
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected boolean checkSearchStringsNoCase() throws IOException {
+ List list = _case.getSearchStringsNoCase();
+ boolean found = true;
+ if (list != null && !list.isEmpty()) {
+ String responseBody = _res.getResponseBodyAsRawString();
+
+ String search = null;
+
+ for (int i = 0, n = list.size(), startIdx = 0, bodyLength = responseBody
+ .length(); i < n; i++) {
+
+ // set the startIdx to the same value as the body length
+ // and let the test fail (prevents index based runtime
+ // exceptions).
+ if (startIdx >= bodyLength) {
+ startIdx = bodyLength;
+ }
+
+ search = (String) list.get(i);
+ int searchIdx = responseBody.toLowerCase().indexOf(search.toLowerCase(),
+ startIdx);
+
+ TestUtil.logTrace(
+ "[WebValidatorBase] Scanning response for " + "search string: '"
+ + search + "' starting at index " + "location: " + startIdx);
+ if (searchIdx < 0) {
+ found = false;
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Unable to find the following ");
+ sb.append("search string in the server's ");
+ sb.append("response: '").append(search).append("' at index: ");
+ sb.append(startIdx);
+ sb.append("\n[WebValidatorBase] Server's response:\n");
+ sb.append("-------------------------------------------\n");
+ sb.append(responseBody);
+ sb.append("\n-------------------------------------------\n");
+ TestUtil.logErr(sb.toString());
+ break;
+ }
+
+ TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+ + "' at index '" + searchIdx + "' in the server's " + "response");
+ // the new searchIdx is the old index plus the lenght of the
+ // search string.
+ startIdx = searchIdx + search.length();
+ }
+ }
+ return found;
+ }
+
+ /**
+ * <code>checkUnorderedSearchStrings</code> will scan the response for the
+ * configured strings that are to be expected in the response.
+ * <ul>
+ * <li>Check search strings</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If list of Strings is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If list of Strings is not null, scan response body. If string is found,
+ * return true, otherwise display error and return false.
+ * </p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected boolean checkUnorderedSearchStrings() throws IOException {
+ List list = _case.getUnorderedSearchStrings();
+ boolean found = true;
+ if (list != null && !list.isEmpty()) {
+ String responseBody = _res.getResponseBodyAsRawString();
+
+ String search = null;
+
+ for (int i = 0, n = list.size(); i < n; i++) {
+
+ search = (String) list.get(i);
+ int searchIdx = responseBody.indexOf(search);
+
+ TestUtil.logTrace("[WebValidatorBase] Scanning response for "
+ + "search string: '" + search + "'...");
+ if (searchIdx < 0) {
+ found = false;
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Unable to find the following ");
+ sb.append("search string in the server's ");
+ sb.append("response: '").append(search);
+ sb.append("\n[WebValidatorBase] Server's response:\n");
+ sb.append("-------------------------------------------\n");
+ sb.append(responseBody);
+ sb.append("\n-------------------------------------------\n");
+ TestUtil.logErr(sb.toString());
+ break;
+ }
+
+ TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+ + "' at index '" + searchIdx + "' in the server's " + "response");
+ }
+ }
+ return found;
+ }
+
+ /**
+ * <code>checkUnexpectedSearchStrings</code> will scan the response for the
+ * configured strings that are not expected in the response.
+ * <ul>
+ * <li>Check unexpected search strings</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If list of Strings is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If list of Strings is not null, scan response body. If string is not found,
+ * return true, otherwise display error and return false.
+ * <p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected boolean checkUnexpectedSearchStrings() throws IOException {
+ List list = _case.getUnexpectedSearchStrings();
+ if (list != null && !list.isEmpty()) {
+ String responseBody = _res.getResponseBodyAsRawString();
+ Iterator iter = list.iterator();
+ while (iter.hasNext()) {
+ String search = (String) iter.next();
+ TestUtil.logTrace("[WebValidatorBase] Scanning response. The following"
+ + " string should not be present in the response: '" + search
+ + "'");
+ if (responseBody.indexOf(search) > -1) {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Found the following unexpected ");
+ sb.append("search string in the server's ");
+ sb.append("response: '").append(search).append("'");
+ sb.append("\n[WebValidatorBase] Server's response:\n");
+ sb.append("-------------------------------------------\n");
+ sb.append(responseBody);
+ sb.append("\n-------------------------------------------\n");
+ TestUtil.logErr(sb.toString());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * <code>checkGoldenFile</code> compare the server's response with the
+ * configured goldenfile
+ * <ul>
+ * <li>Check the goldenfile</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If goldenfile is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If goldenfile is not null, compare the goldenfile with the response. If
+ * equal, return true, otherwise display error and return false.
+ * <p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ * @throws IOException
+ * if an IO error occurs during validation
+ */
+ protected abstract boolean checkGoldenfile() throws IOException;
+
+ /**
+ * <code>checkReasonPhrase</code> will perform comparisons between the
+ * configued reason-phrase and that of the response.
+ * <ul>
+ * <li>Check reason-phrase</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If configured reason-phrase is null, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If configured reason-phrase is not null, compare the reason-phrases with
+ * the response. If equal, return true, otherwise display error and return
+ * false.
+ * <p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ */
+ protected boolean checkReasonPhrase() {
+ String sReason = _case.getReasonPhrase();
+ String resReason = _res.getReasonPhrase();
+
+ if (sReason == null) {
+ return true;
+ } else if (sReason.equalsIgnoreCase(resReason)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * <code>checkExpectedHeaders</code> will check the response for the
+ * configured expected headers.
+ * <ul>
+ * <li>Check expected headers</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If there are no expected headers, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If there are expected headers, scan the response for the expected headers.
+ * If all expected headers are found, return true, otherwise display an error
+ * and return false.
+ * <p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ */
+ protected boolean checkExpectedHeaders() {
+ Header[] expected = _case.getExpectedHeaders();
+ if (isEmpty(expected)) {
+ return true;
+ } else {
+ boolean found = true;
+ Header currentHeader = null;
+ for (int i = 0; i < expected.length; i++) {
+ currentHeader = expected[i];
+ Header resHeader = _res.getResponseHeader(currentHeader.getName());
+ if (resHeader != null) {
+ Handler handler = HandlerFactory.getHandler(currentHeader.getName());
+ if (!handler.invoke(currentHeader, resHeader)) {
+ found = false;
+ break;
+ }
+ } else {
+ found = false;
+ break;
+ }
+ }
+ if (!found) {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Unable to find the following header");
+ sb.append(" in the server's response: ");
+ sb.append(currentHeader.toExternalForm()).append("\n");
+ sb.append("[WebValidatorBase] Response headers recieved from");
+ sb.append(" server:");
+
+ Header[] resHeaders = _res.getResponseHeaders();
+ for (int i = 0; i < resHeaders.length; i++) {
+ sb.append("\n\tResponseHeader -> ");
+ sb.append(resHeaders[i].toExternalForm());
+ }
+ sb.append("\n");
+ TestUtil.logErr(sb.toString());
+
+ return false;
+ } else {
+ TestUtil.logTrace("[WebValidatorBase] Found expected header: "
+ + currentHeader.toExternalForm());
+ return true;
+ }
+ }
+ }
+
+ /**
+ * <code>checkUnexpectedHeaders</code> will check the response for the
+ * configured unexpected expected headers.
+ * <ul>
+ * <li>Check unexpected headers</li>
+ * <ul>
+ * <li>
+ * <p>
+ * If there are no configured unexpected headers, return true.
+ * </p>
+ * </li>
+ * <li>
+ * <p>
+ * If there are configured unexpected headers, scan the response for the
+ * unexpected headers. If the headers are not found, return true, otherwise
+ * display an error and return false.
+ * <p>
+ * </li>
+ * </ul>
+ * </ul>
+ *
+ * @return boolen result of check
+ */
+ protected boolean checkUnexpectedHeaders() {
+ Header[] unexpected = _case.getUnexpectedHeaders();
+ if (isEmpty(unexpected)) {
+ return true;
+ } else {
+ Header currentHeader = null;
+ for (int i = 0; i < unexpected.length; i++) {
+ currentHeader = unexpected[i];
+ String currName = currentHeader.getName();
+ String currValue = currentHeader.getValue();
+ Header resHeader = _res.getResponseHeader(currName);
+ if (resHeader != null) {
+ if (resHeader.getValue().equals(currValue)) {
+ StringBuffer sb = new StringBuffer(255);
+ sb.append("[WebValidatorBase] Unexpected header found in the ");
+ sb.append("server's response: ");
+ sb.append(currentHeader.toExternalForm()).append("\n");
+ sb.append("[WebValidatorBase] Response headers recieved from");
+ sb.append("server:");
+
+ Header[] resHeaders = _res.getResponseHeaders();
+ for (int j = 0; j < resHeaders.length; j++) {
+ sb.append("\n\tResponseHeader -> ");
+ sb.append(resHeaders[j].toExternalForm());
+ }
+ sb.append("\n");
+ TestUtil.logErr(sb.toString());
+
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Utility method to determine of the expected or unexpected headers are empty
+ * or not.
+ */
+ protected boolean isEmpty(Header[] headers) {
+ if (headers == null || headers.length == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java
new file mode 100644
index 0000000..bedbc29
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java
@@ -0,0 +1,3258 @@
+/*
+ * Copyright (c) 2012, 2021 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.asyncinvoker;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+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 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;
+
+import jakarta.ws.rs.WebApplicationException;
+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.InvocationCallback;
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ * webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+ private static final long serialVersionUID = -696868584437674095L;
+
+ protected long millis;
+
+ protected int callbackResult = 0;
+
+ protected Throwable callbackException = null;
+
+ private final static String NONEXISTING_SITE = "somenonexisting.domain-site";
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("jaxrs_ee_rs_client_asyncinvoker_web/resource");
+ }
+
+ static final String[] METHODS = { "DELETE", "GET", "OPTIONS" };
+
+ static final String[] ENTITY_METHODS = { "PUT", "POST" };
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template");
+ // Replace the servlet_adaptor in web.xml.template with the System variable set as servlet adaptor
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_asyncinvoker_web.war");
+ archive.addClasses(TSAppConfig.class, Resource.class);
+ archive.setWebXML(new StringAsset(webXml));
+ return archive;
+
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+ /* Run test */
+ // --------------------------------------------------------------------
+ // ---------------------- DELETE --------------------------------------
+ // --------------------------------------------------------------------
+ /*
+ * @testName: deleteTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:375;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("delete");
+ Future<Response> future = async.delete();
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:375;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ Future<Response> future = async.delete();
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: deleteThrowsExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:375;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void deleteThrowsExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("delete");
+ Future<Response> future = async.delete();
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:376;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithStringClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ Future<String> future = async.delete(String.class);
+ checkFutureString(future, "delete");
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:376;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ Future<Response> future = async.delete(Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:376;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void deleteWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("delete");
+ Future<String> future = async.delete(String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:376;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ Future<String> future = async.delete(String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:376;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ Future<Response> future = async.delete(Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:377;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.delete(generic);
+ checkFutureString(future, "delete");
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:377;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.delete(generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:377;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void deleteWithGenericTypeThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("delete");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.delete(generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:377;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.delete(generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName:
+ * deleteWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:377;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.delete(generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: deleteWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:378;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithCallbackWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ InvocationCallback<Response> callback = createCallback(true);
+ Future<Response> future = async.delete(callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithCallbackStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:378;
+ *
+ * @test_Strategy: Invoke HTTP DELETE method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void deleteWithCallbackStringWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ InvocationCallback<String> callback = createStringCallback(true);
+ Future<String> future = async.delete(callback);
+ checkFutureString(future, "delete");
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: deleteWithCallbackStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:378;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void deleteWithCallbackStringThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.delete(callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithCallbackStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:378;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithCallbackStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.delete(callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: deleteWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:378;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void deleteWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.delete(callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------GET------------------------------------
+ // ------------------------------------------------------------------
+ /*
+ * @testName: getTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:379;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("get");
+ Future<Response> future = async.get();
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: getWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:379;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ Future<Response> future = async.get();
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: getThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:379;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void getThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("get");
+ Future<Response> future = async.get();
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:380;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithStringClassWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ Future<String> future = async.get(String.class);
+ checkFutureString(future, "get");
+ //return future;
+ }
+
+ /*
+ * @testName: getWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:380;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ Future<Response> future = async.get(Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: getWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:380;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void getWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("get");
+ Future<String> future = async.get(String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:380;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ Future<String> future = async.get(String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:380;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ Future<Response> future = async.get(Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: getWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:381;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.get(generic);
+ checkFutureString(future, "get");
+ //return future;
+ }
+
+ /*
+ * @testName: getWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:381;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.get(generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: getWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:381;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void getWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("get");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.get(generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:381;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.get(generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:381;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.get(generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: getWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:382;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithCallbackWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ InvocationCallback<Response> callback = createCallback(true);
+ Future<Response> future = async.get(callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: getWithCallbackStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:382;
+ *
+ * @test_Strategy: Invoke HTTP GET method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void getWithCallbackStringWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+ InvocationCallback<String> callback = createStringCallback(true);
+ Future<String> future = async.get(callback);
+ checkFutureString(future, "get");
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: getWithCallbackStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:382;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void getWithCallbackStringThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("get");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.get(callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithCallbackStringThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:382;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithCallbackStringThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.get(callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: getWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:382;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void getWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.get(callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------HEAD-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: headTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:383;
+ *
+ * @test_Strategy: Invoke HTTP HEAD method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void headTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("head");
+ Future<Response> future = async.head();
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: headWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:383;
+ *
+ * @test_Strategy: Invoke HTTP HEAD method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void headWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("headandwait");
+ Future<Response> future = async.head();
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: headThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:383;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void headThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("head");
+ Future<Response> future = async.head();
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: headWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:384;
+ *
+ * @test_Strategy: Invoke HTTP HEAD method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void headWithCallbackWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("headandwait");
+ InvocationCallback<Response> callback = createCallback(true);
+ Future<Response> future = async.head(callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: headWithCallbackStringThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:384;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void headWithCallbackStringThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("head");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.head(callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------METHOD-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: methodTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:385;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodTest() throws Fault {
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method);
+ checkFutureOkResponseNoTime(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:385;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWhileServerWaitTest() throws Fault {
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:385;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:386;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithStringClassWhileServerWaitTest()
+ throws Fault {
+ Future<String> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, String.class);
+ checkFutureString(future, method);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:386;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, Response.class);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:386;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<String> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method, String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:386;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ Future<String> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:386;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:387;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, generic);
+ checkFutureString(future, method);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:387;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, generic);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:387;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithGenericTypeThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<Response> future = null;
+ GenericType<Response> generic = createGeneric(Response.class);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method, generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:387;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Future<String> future = null;
+ GenericType<String> generic = createGeneric(String.class);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:387;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ GenericType<Response> generic = createGeneric(Response.class);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:388;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithCallbackWhileServerWaitTest() throws Fault {
+ InvocationCallback<Response> callback = createCallback(true);
+ Future<Response> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithCallbackStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:388;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithCallbackStringWhileServerWaitTest()
+ throws Fault {
+ InvocationCallback<String> callback = createStringCallback(true);
+ Future<String> future = null;
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ future = async.method(method, callback);
+ checkFutureString(future, method);
+ assertCallbackCall();
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithCallbackThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:388;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithCallbackThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<String> future = null;
+ InvocationCallback<String> callback = createStringCallback(false);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method, callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithCallbackThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:388;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithCallbackThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Future<String> future = null;
+ InvocationCallback<String> callback = createStringCallback(false);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:388;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ InvocationCallback<Response> callback = createCallback(false);
+ for (String method : METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ future = async.method(method, callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:389;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithEntityWhileServerWaitTest() throws Fault {
+ Future<Response> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:389;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithEntityThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<Response> future = null;
+ for (String method : ENTITY_METHODS) {
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ future = async.method(method, entity);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithStringClassWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:390;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithStringClassWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<String> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, String.class);
+ checkFutureString(future, method);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithResponseClassWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:390;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithResponseClassWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<Response> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, Response.class);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithClassWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:390;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithClassWithEntityThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Future<String> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithClassWithEntityThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:390;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithClassWithEntityThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Future<String> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithClassWithEntityThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:390;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithClassWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeStringWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:391;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithGenericTypeStringWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<String> future = null;
+ GenericType<String> generic = createGeneric(String.class);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, generic);
+ checkFutureString(future, method);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithGenericTypeResponseWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:391;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithGenericTypeResponseWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<Response> future = null;
+ GenericType<Response> generic = createGeneric(Response.class);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, generic);
+ checkFutureOkResponse(future);
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithGenericTypeWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:391;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithGenericTypeWithEntityThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithGenericTypeWithEntityThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:391;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeWithEntityThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Future<String> future = null;
+ GenericType<String> generic = createGeneric(String.class);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithGenericTypeWithEntityThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:391;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithGenericTypeWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ GenericType<Response> generic = createGeneric(Response.class);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ /*
+ * @testName: methodWithCallbackWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:392;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithCallbackWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<Response> future = null;
+ InvocationCallback<Response> callback = createCallback(true);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithCallbackStringWithEntityWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:392;
+ *
+ * @test_Strategy: Invoke an arbitrary method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void methodWithCallbackStringWithEntityWhileServerWaitTest()
+ throws Fault {
+ Future<String> future = null;
+ InvocationCallback<String> callback = createStringCallback(true);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "andwait");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, callback);
+ checkFutureString(future, method);
+ assertCallbackCall();
+ }
+ //return future;
+ }
+
+ /*
+ * @testName: methodWithCallbackWithEntityThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:392;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void methodWithCallbackWithEntityThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = null;
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName: methodWithCallbackWithEntityThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:392;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithCallbackWithEntityThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Future<String> future = null;
+ InvocationCallback<String> callback = createStringCallback(false);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+ }
+
+ /*
+ * @testName:
+ * methodWithCallbackWithEntityThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:392;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void methodWithCallbackWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Future<Response> future = null;
+ InvocationCallback<Response> callback = createCallback(false);
+ for (String method : ENTITY_METHODS) {
+ AsyncInvoker async = startAsyncInvokerForMethod(
+ method.toLowerCase() + "notok");
+ Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+ future = async.method(method, entity, callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------OPTIONS--------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: optionsTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:393;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("options");
+ Future<Response> future = async.options();
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:393;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ Future<Response> future = async.options();
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: optionsThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:393;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void optionsThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("options");
+ Future<Response> future = async.options();
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: optionsWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:394;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithStringClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ Future<String> future = async.options(String.class);
+ checkFutureString(future, "options");
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:394;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ Future<Response> future = async.options(Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:394;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void optionsWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("options");
+ Future<String> future = async.options(String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: optionsWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:394;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ Future<String> future = async.options(String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: optionsWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:394;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ Future<Response> future = async.options(Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:395;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.options(generic);
+ checkFutureString(future, "options");
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:395;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.options(generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:395;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void optionsWithGenericTypeThrowsProcessingExceptionTest()
+ throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("options");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.options(generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: optionsWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:395;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.options(generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName:
+ * optionsWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:395;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.options(generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: optionsWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:396;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithCallbackWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ InvocationCallback<Response> callback = createCallback(true);
+ Future<Response> future = async.options(callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithStringCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:396;
+ *
+ * @test_Strategy: Invoke HTTP options method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void optionsWithStringCallbackWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+ InvocationCallback<String> callback = createStringCallback(true);
+ Future<String> future = async.options(callback);
+ checkFutureString(future, "options");
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: optionsWithCallbackThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:396;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void optionsWithCallbackThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("options");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.options(callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: optionsWithCallbackThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:396;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithCallbackThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.options(callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName:
+ * optionsWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:396;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void optionsWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.options(callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------POST-----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: postTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:397;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("post");
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity);
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: postWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:397;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: postThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:397;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void postThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("post");
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:398;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWithStringClassWhileServerWaitTest() throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Future<String> future = async.post(entity, String.class);
+ checkFutureString(future, "post");
+ //return future;
+ }
+
+ /*
+ * @testName: postWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:398;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Future<Response> future = async.post(entity, Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: postWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:398;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void postWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("post");
+ Future<String> future = async.post(entity, String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:398;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ Future<String> future = async.post(entity, String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:398;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity, Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: postWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:399;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Future<String> future = async.post(entity, generic);
+ checkFutureString(future, "post");
+ //return future;
+ }
+
+ /*
+ * @testName: postWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:399;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Future<Response> future = async.post(entity, generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: postWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:399;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void postWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ GenericType<String> generic = createGeneric(String.class);
+ AsyncInvoker async = startAsyncInvokerForMethod("post");
+ Future<String> future = async.post(entity, generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:399;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ GenericType<String> generic = createGeneric(String.class);
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ Future<String> future = async.post(entity, generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName:
+ * postWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:399;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity, generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: postWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:400;
+ *
+ * @test_Strategy: Invoke HTTP post method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void postWithCallbackWhileServerWaitTest() throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ InvocationCallback<Response> callback = createCallback(true);
+ AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+ Future<Response> future = async.post(entity, callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: postWithCallbackThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:400;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void postWithCallbackThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ InvocationCallback<String> callback = createStringCallback(false);
+ AsyncInvoker async = startAsyncInvokerForMethod("post");
+ Future<String> future = async.post(entity, callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithCallbackThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:400;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithCallbackThrowsWebApplicationExceptionTest() throws Fault {
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ InvocationCallback<String> callback = createStringCallback(false);
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ Future<String> future = async.post(entity, callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: postWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:400;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void postWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.post(entity, callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------PUT -----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: putTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:401;
+ *
+ * @test_Strategy: Invoke HTTP PUT method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("put");
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.put(entity);
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: putWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:401;
+ *
+ * @test_Strategy: Invoke HTTP PUT method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.put(entity);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: putThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:401;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void putThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("put");
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ Future<Response> future = async.put(entity);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:402;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithStringClassWhileServerWaitTest() throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<String> future = async.put(entity, String.class);
+ checkFutureString(future, "put");
+ //return future;
+ }
+
+ /*
+ * @testName: putWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:402;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<Response> future = async.put(entity, Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: putWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:402;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void putWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("put");
+ Future<String> future = async.put(entity, String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:402;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ Future<String> future = async.put(entity, String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:402;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ Future<Response> future = async.put(entity, Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: putWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:403;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<String> future = async.put(entity, generic);
+ checkFutureString(future, "put");
+ //return future;
+ }
+
+ /*
+ * @testName: putWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:403;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<Response> future = async.put(entity, generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: putWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:403;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void putWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("put");
+ Future<String> future = async.put(entity, generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:403;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ Future<String> future = async.put(entity, generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:403;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.put(entity, generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: putWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:404;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithCallbackWhileServerWaitTest() throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ InvocationCallback<Response> callback = createCallback(true);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<Response> future = async.put(entity, callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: putWithStringCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:404;
+ *
+ * @test_Strategy: Invoke HTTP put method for the current request
+ * asynchronously.
+ */
+ @Test
+ public void putWithStringCallbackWhileServerWaitTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ InvocationCallback<String> callback = createStringCallback(true);
+ AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+ Future<String> future = async.put(entity, callback);
+ checkFutureString(future, "put");
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: putWithCallbackThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:404;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void putWithCallbackThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ InvocationCallback<String> callback = createStringCallback(false);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("put");
+ Future<String> future = async.put(entity, callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithCallbackThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:404;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithCallbackThrowsWebApplicationExceptionTest() throws Fault {
+ InvocationCallback<String> callback = createStringCallback(false);
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ Future<String> future = async.put(entity, callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: putWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:404;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void putWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+ AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.put(entity, callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ------------------------------------------------------------------
+ // ---------------------------TRACE -----------------------------------
+ // ------------------------------------------------------------------
+
+ /*
+ * @testName: traceTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:405;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("trace");
+ Future<Response> future = async.trace();
+ checkFutureOkResponseNoTime(future);
+ //return future;
+ }
+
+ /*
+ * @testName: traceWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:405;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<Response> future = async.trace();
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: traceThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:405;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void traceThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("trace");
+ Future<Response> future = async.trace();
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithStringClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:406;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithStringClassWhileServerWaitTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<String> future = async.trace(String.class);
+ checkFutureString(future, "trace");
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithResponseClassWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:406;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithResponseClassWhileServerWaitTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<Response> future = async.trace(Response.class);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithClassThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:406;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void traceWithClassThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ AsyncInvoker async = startAsyncInvokerForMethod("trace");
+ Future<String> future = async.trace(String.class);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithClassThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:406;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void traceWithClassThrowsWebApplicationExceptionTest() throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ Future<String> future = async.trace(String.class);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithClassThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:406;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ //@Test
+ public void traceWithClassThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ Future<Response> future = async.trace(Response.class);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: traceWithGenericTypeStringWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:407;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithGenericTypeStringWhileServerWaitTest()
+ throws Fault {
+ GenericType<String> generic = createGeneric(String.class);
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<String> future = async.trace(generic);
+ checkFutureString(future, "trace");
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithGenericTypeResponseWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:407;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithGenericTypeResponseWhileServerWaitTest()
+ throws Fault {
+ GenericType<Response> generic = createGeneric(Response.class);
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<Response> future = async.trace(generic);
+ checkFutureOkResponse(future);
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithGenericTypeThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:407;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void traceWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ GenericType<String> generic = createGeneric(String.class);
+ AsyncInvoker async = startAsyncInvokerForMethod("trace");
+ Future<String> future = async.trace(generic);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithGenericTypeThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:407;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void traceWithGenericTypeThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ GenericType<String> generic = createGeneric(String.class);
+ Future<String> future = async.trace(generic);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName:
+ * traceWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:407;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ //@Test
+ public void traceWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ GenericType<Response> generic = createGeneric(Response.class);
+ Future<Response> future = async.trace(generic);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ /*
+ * @testName: traceWithCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:408;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithCallbackWhileServerWaitTest() throws Fault {
+ InvocationCallback<Response> callback = createCallback(true);
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<Response> future = async.trace(callback);
+ checkFutureOkResponse(future);
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithStringCallbackWhileServerWaitTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:408;
+ *
+ * @test_Strategy: Invoke HTTP trace method for the current request
+ * asynchronously.
+ */
+ //@Test
+ public void traceWithStringCallbackWhileServerWaitTest()
+ throws Fault {
+ InvocationCallback<String> callback = createStringCallback(true);
+ AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+ Future<String> future = async.trace(callback);
+ checkFutureString(future, "trace");
+ assertCallbackCall();
+ //return future;
+ }
+
+ /*
+ * @testName: traceWithCallbackThrowsProcessingExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:408;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps an
+ * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+ * failure.
+ */
+ @Test
+ public void traceWithCallbackThrowsProcessingExceptionTest() throws Fault {
+ _hostname = NONEXISTING_SITE;
+ InvocationCallback<String> callback = createStringCallback(false);
+ AsyncInvoker async = startAsyncInvokerForMethod("trace");
+ Future<String> future = async.trace(callback);
+ assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithCallbackThrowsWebApplicationExceptionTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:408;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ @Test
+ public void traceWithCallbackThrowsWebApplicationExceptionTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ InvocationCallback<String> callback = createStringCallback(false);
+ Future<String> future = async.trace(callback);
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+ }
+
+ /*
+ * @testName: traceWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:408;
+ *
+ * @test_Strategy: Note that calling the Future.get() method on the returned
+ * Future instance may throw an ExecutionException that wraps a
+ * WebApplicationException or one of its subclasses thrown in case the
+ * received response status code is not successful and the specified response
+ * type is not Response.
+ */
+ //@Test
+ public void traceWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+ throws Fault {
+ AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+ InvocationCallback<Response> callback = createCallback(false);
+ Future<Response> future = async.trace(callback);
+ checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+ }
+
+ // ///////////////////////////////////////////////////////////////////////
+ // utility methods
+
+ protected String getUrl(String method) {
+ StringBuilder url = new StringBuilder();
+ url.append("http://").append(_hostname).append(":").append(_port);
+ url.append("/").append(getContextRoot()).append("/").append(method);
+ return url.toString();
+ }
+
+ /**
+ * Create AsyncInvoker for given resource method and start time
+ */
+ protected AsyncInvoker startAsyncInvokerForMethod(String methodName) {
+ Client client = ClientBuilder.newClient();
+ client.register(new JdkLoggingFilter(false));
+ WebTarget target = client.target(getUrl(methodName));
+ AsyncInvoker async = target.request().async();
+ setStartTime();
+ return async;
+ }
+
+ protected void assertOkAndLog(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 void checkFutureOkResponseNoTime(Future<Response> future)
+ throws Fault {
+ checkFutureStatusResponseNoTime(future, Status.OK);
+ }
+
+ protected void checkFutureStatusResponseNoTime(Future<Response> future,
+ Status status) throws Fault {
+ Response response = null;
+ try {
+ response = future.get();
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ assertOkAndLog(response, status);
+ }
+
+ protected void checkFutureOkResponse(Future<Response> future) throws Fault {
+ checkMaxEndTime();
+ assertTrue(!future.isDone(), "Future cannot be done, yet!");
+ checkFutureOkResponseNoTime(future);
+ }
+
+ protected void checkFutureString(Future<String> future, String expectedValue)
+ throws Fault {
+ checkMaxEndTime();
+ assertTrue(!future.isDone(), "Future cannot be done, yet!");
+ String value = null;
+ try {
+ value = future.get();
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ assertTrue(expectedValue.equalsIgnoreCase(value), "expected value"+
+ expectedValue+ "differes from acquired value"+ value);
+ }
+
+ protected void //
+ assertExceptionWithWebApplicationExceptionIsThrownAndLog(Future<?> future)
+ throws Fault {
+ try {
+ future.get();
+ throw new Fault("ExecutionException has not been thrown");
+ } catch (ExecutionException e) {
+ assertWebApplicationExceptionIsCauseAndLog(e);
+ } catch (InterruptedException e) {
+ throw new Fault("Unexpected exception thrown", e);
+ }
+ }
+
+ protected void assertExceptionWithProcessingExceptionIsThrownAndLog(
+ Future<?> future) throws Fault {
+ try {
+ future.get();
+ throw new Fault("ExecutionException has not been thrown");
+ } catch (ExecutionException e) {
+ assertProcessingExceptionIsCauseAndLog(e);
+ } catch (InterruptedException e) {
+ throw new Fault("Unexpected exception thrown", e);
+ }
+ }
+
+ protected void //
+ assertProcessingExceptionIsCauseAndLog(ExecutionException e)
+ throws Fault {
+ logMsg("ExecutionException has been thrown as expected", e);
+ assertTrue(hasWrapped(e, jakarta.ws.rs.ProcessingException.class),
+ "ExecutionException wrapped"+ e.getCause()+
+ "rather then ProcessingException");
+ logMsg("ExecutionException.getCause is ProcessingException as expected");
+ }
+
+ protected void //
+ assertWebApplicationExceptionIsCauseAndLog(ExecutionException e)
+ throws Fault {
+ logMsg("ExecutionException has been thrown as expected", e);
+ assertTrue(hasWrapped(e, WebApplicationException.class),
+ "ExecutionException wrapped"+ e.getCause()+
+ "rather then WebApplicationException");
+ logMsg(
+ "ExecutionException.getCause is WebApplicationException as expected");
+ }
+
+ static boolean //
+ hasWrapped(Throwable parent, Class<? extends Throwable> wrapped) {
+ while (parent.getCause() != null) {
+ if (wrapped.isInstance(parent.getCause()))
+ return true;
+ parent = parent.getCause();
+ }
+ return false;
+ }
+
+ protected void sleep(int millis) throws Fault {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ throw new Fault(e);
+ }
+ }
+
+ protected void setStartTime() {
+ millis = System.currentTimeMillis();
+ logMsg("Start time:", millis);
+ }
+
+ protected void checkMaxEndTime() throws Fault {
+ long endMillis = System.currentTimeMillis();
+ long diff = endMillis - millis;
+ logMsg("Client was returned control in", diff, "milliseconds from request");
+ assertTrue(diff <= Resource.SLEEP_TIME,
+ "AsyncInvoker was blocked waiting for a response");
+ }
+
+ protected void checkMinEndTime() throws Fault {
+ long endMillis = System.currentTimeMillis();
+ long diff = endMillis - millis;
+ logMsg("Callback#completed() called in", diff, "milliseconds from request");
+ assertTrue(diff >= Resource.SLEEP_TIME,
+ "AsyncInvoker.completed() was called unexpectedly soon, after"+ diff+
+ "milliseconds");
+ }
+
+ protected void assertCallbackCall() throws Fault {
+ while (callbackResult == 0) {
+ try {
+ Thread.sleep(100L);
+ } catch (InterruptedException e) {
+ throw new Fault(e);
+ }
+ }
+ switch (callbackResult) {
+ case 1:
+ logMsg("Callback completed() call ok");
+ break;
+ case 2:
+ case 3:
+ logMsg("Callback completed() call failed with error");
+ throw new Fault("Callback call failed with error", callbackException);
+ }
+ callbackResult = 0;
+ }
+
+ protected <T> GenericType<T> createGeneric(Class<T> clazz) {
+ return new GenericType<T>(clazz);
+ }
+
+ /**
+ * @param check
+ * defines whether the test actually cares about methods
+ * {@link InvocationCallback#completed(Object)} and
+ * {@link InvocationCallback#failed(Throwable)} being called
+ * @return
+ */
+ protected InvocationCallback<Response> createCallback(boolean check) {
+ InvocationCallback<Response> callback = new Callback<Response>(check) {
+ @Override
+ public void completed(Response response) {
+ checkEndTime();
+ }
+ };
+ return callback;
+ }
+
+ protected InvocationCallback<String> createStringCallback(boolean check) {
+ InvocationCallback<String> callback = new Callback<String>(check) {
+ @Override
+ public void completed(String response) {
+ checkEndTime();
+ }
+ };
+ return callback;
+ }
+
+ abstract class Callback<RESPONSE> implements InvocationCallback<RESPONSE> {
+ protected boolean check;
+
+ public Callback(boolean check) {
+ this.check = check;
+ }
+
+ protected void checkEndTime() {
+ if (check)
+ try {
+ JAXRSClientIT.this.checkMinEndTime();
+ callbackResult = 1;
+ } catch (Fault e) {
+ callbackResult = 2;
+ callbackException = e;
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void failed(Throwable throwable) {
+ if (check) {
+ callbackResult = 3;
+ callbackException = throwable;
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java
new file mode 100644
index 0000000..e761d04
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, 2021 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.asyncinvoker;
+
+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 {
+
+ public static final long SLEEP_TIME = 2000L;
+
+ @GET
+ @Path("get")
+ public String get() {
+ return "get";
+ }
+
+ @GET
+ @Path("getandwait")
+ public String getAndWait() throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return "get";
+ }
+
+ @GET
+ @Path("getnotok")
+ public Response getReturnsStatusNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @HEAD
+ @Path("head")
+ public String head() {
+ return "head";
+ }
+
+ @HEAD
+ @Path("headandwait")
+ public String headAndWait() throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return "head";
+ }
+
+ @HEAD
+ @Path("headnotok")
+ public Response headReturnsStatusNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @PUT
+ @Path("put")
+ public String put(String value) {
+ return value;
+ }
+
+ @PUT
+ @Path("putandwait")
+ public String putAndWait(String value) throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return value;
+ }
+
+ @PUT
+ @Path("putnotok")
+ public Response putReturnsStatusNotOk(String value) {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @POST
+ @Path("post")
+ public String post(String value) {
+ return value;
+ }
+
+ @POST
+ @Path("postandwait")
+ public String postAndWait(String value) throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return value;
+ }
+
+ @POST
+ @Path("postnotok")
+ public Response postReturnsStatusNotOk(String string) {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @DELETE
+ @Path("delete")
+ public String delete() {
+ return "delete";
+ }
+
+ @DELETE
+ @Path("deleteandwait")
+ public String deleteAndWait() throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return "delete";
+ }
+
+ @DELETE
+ @Path("deletenotok")
+ public Response deleteReturnsStatusNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @OPTIONS
+ @Path("options")
+ public String options() {
+ return "options";
+ }
+
+ @OPTIONS
+ @Path("optionsandwait")
+ public String optionsAndWait() throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return "options";
+ }
+
+ @OPTIONS
+ @Path("optionsnotok")
+ public Response optionsReturnsStatusNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @TRACE
+ @Path("trace")
+ public String trace() {
+ return "trace";
+ }
+
+ @TRACE
+ @Path("tracenotok")
+ public Response traceReturnsStatusNotOk() {
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ }
+
+ @TRACE
+ @Path("traceandwait")
+ public String traceAndWait() throws InterruptedException {
+ Thread.sleep(SLEEP_TIME);
+ return trace();
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java
new file mode 100644
index 0000000..9dd436c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2021 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.asyncinvoker;
+
+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/request/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/JAXRSClientIT.java
new file mode 100644
index 0000000..c61353c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/JAXRSClientIT.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2011, 2021 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.request;
+
+import org.apache.commons.httpclient.Header;
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+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;
+
+import jakarta.ws.rs.core.Response.Status;
+
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String IF_MODIFIED_SINCE = "If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT";
+
+ private static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT";
+
+ private static final String IF_NONE_MATCH = "If-None-Match: \"AAA\"";
+
+ public JAXRSClientIT() {
+ setup();
+ setContextRoot("/jaxrs_ee_core_request_web/RequestTest");
+ }
+
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() throws IOException{
+
+ InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template");
+ // Replace the servlet_adaptor in web.xml.template with the System variable set as servlet adaptor
+ String webXml = editWebXmlString(inStream);
+
+ WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_request_web.war");
+ archive.addClasses(TSAppConfig.class, RequestTest.class);
+ archive.setWebXML(new StringAsset(webXml));
+ //archive.addAsWebInfResource(JAXRSClientIT.class.getPackage(), "web.xml.template", "web.xml"); //can use if the web.xml.template doesn't need to be modified.
+ return archive;
+
+ }
+
+ @BeforeEach
+ void logStartTest(TestInfo testInfo) {
+ TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+ }
+
+ @AfterEach
+ void logFinishTest(TestInfo testInfo) {
+ TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+ }
+
+
+ /*
+ * @testName: getMethodGetRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:118; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.getMethod works.
+ */
+ @Test
+ public void getMethodGetRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "GetMethodGetTest"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: getMethodPutRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:118;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.getMethod works.
+ */
+ @Test
+ public void getMethodPutRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("PUT", "GetMethodPutTest"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: getMethodPostRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:118;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.getMethod works.
+ */
+ @Test
+ public void getMethodPostRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("POST", "GetMethodPostTest"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: getMethodDeleteRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:118;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.getMethod works.
+ */
+ @Test
+ public void getMethodDeleteRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("DELETE", "GetMethodDeleteTest"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: getMethodHeadRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:118;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.getMethod works.
+ */
+ @Test
+ public void getMethodHeadRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("HEAD", "GetMethodHeadTest"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: selectVariantGetRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:119;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.selectVariantTest(List vs) works when vs is null.
+ */
+ @Test
+ public void selectVariantGetRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "SelectVariantTestGet"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: selectVariantPutRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:119;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.selectVariantTest(List vs) works when vs is null.
+ */
+ @Test
+ public void selectVariantPutRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("PUT", "SelectVariantTestPut"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: selectVariantPostRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:119;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.selectVariantTest(List vs) works when vs is null.
+ */
+ @Test
+ public void selectVariantPostRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("POST", "SelectVariantTestPost"));
+ setProperty(Property.CONTENT, "POST");
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: selectVariantDeleteRequestTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:119;
+ *
+ * @test_Strategy: Client send request to a resource, verify that
+ * Request.selectVariantTest(List vs) works when vs is null.
+ */
+ @Test
+ public void selectVariantDeleteRequestTest() throws Fault {
+ setProperty(REQUEST, buildRequest("DELETE", "SelectVariantTestDelete"));
+ setProperty(SEARCH_STRING, "PASSED");
+ invoke();
+ }
+
+ /*
+ * @testName: selectVariantResponseVaryTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:119; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Check if the response contains VARY
+ */
+ @Test
+ public void selectVariantResponseVaryTest() throws Fault {
+ setProperty(Property.REQUEST,
+ buildRequest(GET, "SelectVariantTestResponse"));
+ setProperty(Property.REQUEST_HEADERS, "Accept: application/json");
+ setProperty(Property.REQUEST_HEADERS, "Accept-Encoding: *");
+ setProperty(Property.REQUEST_HEADERS, "Accept-Language: *");
+ setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+
+ HttpResponse response = _testCase.getResponse();
+ Header[] headers = response.getResponseHeaders("Vary");
+ assertTrue(headers.length != 0, "Expected at least 1 Vary response header");
+
+ boolean accept = false, lang = false, encoding = false;
+ for (Header header : headers)
+ for (String vary : header.getValue().split(",")) {
+ lang |= vary.contains("Accept-Language");
+ encoding |= vary.contains("Accept-Encoding");
+ accept |= (vary.contains("Accept") && !vary.contains("Accept-"));
+ }
+ assertTrue(lang, "Vary should contain Accept-Language");
+ assertTrue(encoding, "Vary should contain Accept-Encoding");
+ assertTrue(accept, "Vary should contain Accept");
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagNullAndSimpleGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115; JAXRS:SPEC:40;
+ *
+ * @test_Strategy: Verify null and Simple Tag for GET
+ *
+ */
+ @Test
+ public void evaluatePreconditionsTagNullAndSimpleGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsSimpleGet"));
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsEntityTagIfMatchAAAGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Match: AAA Tag for GET
+ */
+ @Test
+ public void evaluatePreconditionsEntityTagIfMatchAAAGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+ setProperty(REQUEST_HEADERS, "If-Match: \"AAA\"");
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsEntityTagIfMatchBBBGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Match: BBB Tag for GET
+ */
+ @Test
+ public void evaluatePreconditionsEntityTagIfMatchBBBGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+ setProperty(REQUEST_HEADERS, "If-Match: \"BBB\"");
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsEntityTagIfMatchAAAPutTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Match: AAA Tag for PUT
+ */
+ @Test
+ public void evaluatePreconditionsEntityTagIfMatchAAAPutTest() throws Fault {
+ setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+ setProperty(REQUEST_HEADERS, "If-Match: \"AAA\"");
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsEntityTagIfMatchBBBPutTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Match: BBB Tag for PUT
+ */
+ @Test
+ public void evaluatePreconditionsEntityTagIfMatchBBBPutTest() throws Fault {
+ setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+ setProperty(REQUEST_HEADERS, "If-Match: \"BBB\"");
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfNonMatchAAAGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+ * GET
+ */
+ @Test
+ public void evaluatePreconditionsTagIfNonMatchAAAGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+ setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfNonMatchAAAPutTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+ * PUT
+ */
+ @Test
+ public void evaluatePreconditionsTagIfNonMatchAAAPutTest() throws Fault {
+ setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+ setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfNonMatchGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:298;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-None-Match No Tag for
+ * GET
+ */
+ @Test
+ public void evaluatePreconditionsTagIfNonMatchGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsGet"));
+ setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfNonMatchAAAHeadTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:115;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+ * HEAD
+ */
+ @Test
+ public void evaluatePreconditionsTagIfNonMatchAAAHeadTest() throws Fault {
+ setProperty(REQUEST, buildRequest("HEAD", "preconditionsAAAHead"));
+ setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsIfNonMatchHeadTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:298;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-None-Match No Tag for
+ * HEAD
+ */
+ @Test
+ public void evaluatePreconditionsIfNonMatchHeadTest() throws Fault {
+ setProperty(REQUEST, buildRequest("HEAD", "preconditionsHead"));
+ setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsIfModSinceAgesAgoGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:116;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since, but was
+ * not modified for GET
+ */
+ @Test
+ public void evaluatePreconditionsIfModSinceAgesAgoGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAgesAgoGet"));
+ setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsIfUnmodSinceAgesAgoGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:116;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Unmodified-Since, but
+ * was not modified for GET
+ */
+ @Test
+ public void evaluatePreconditionsIfUnmodSinceAgesAgoGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAgesAgoGet"));
+ setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsIfModSinceNowGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:116;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+ * was modified
+ */
+ @Test
+ public void evaluatePreconditionsIfModSinceNowGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsNowGet"));
+ setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsIfUnmodSinceNowGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:116;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+ * was modified
+ */
+ @Test
+ public void evaluatePreconditionsIfUnmodSinceNowGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsNowGet"));
+ setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfModAAASinceGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:117;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since, but was
+ * not modified for GET
+ */
+ @Test
+ public void evaluatePreconditionsTagIfModAAASinceGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAAAAgesAgoGet"));
+ setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfUnmodSinceAAAGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:117;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Unmodified-Since, but
+ * was not modified for GET
+ */
+ @Test
+ public void evaluatePreconditionsTagIfUnmodSinceAAAGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsAAAAgesAgoGet"));
+ setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfModSinceNowAAAGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:117;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+ * was modified
+ */
+ @Test
+ public void evaluatePreconditionsTagIfModSinceNowAAAGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsNowAAAGet"));
+ setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.OK));
+ invoke();
+ }
+
+ /*
+ * @testName: evaluatePreconditionsTagIfUnmodSinceNowAAAGetTest
+ *
+ * @assertion_ids: JAXRS:JAVADOC:117;
+ *
+ * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+ * was modified
+ */
+ @Test
+ public void evaluatePreconditionsTagIfUnmodSinceNowAAAGetTest() throws Fault {
+ setProperty(REQUEST, buildRequest(GET, "preconditionsNowAAAGet"));
+ setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+ setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+ invoke();
+ }
+
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java
new file mode 100644
index 0000000..f503c40
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2011, 2021 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.request;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HEAD;
+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.EntityTag;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Variant;
+
+@Path(value = "/RequestTest")
+public class RequestTest {
+
+ // ------------------ GET METHOD ----------------------------
+
+ private static Response assertResponse(String expectedMethod,
+ String actualMethod) {
+ if (actualMethod.equalsIgnoreCase(expectedMethod)) {
+ return Response.ok("Test PASSED").build();
+ } else {
+ return Response.ok("Test FAILED with " + actualMethod).build();
+ }
+ }
+
+ @GET
+ @Path("/GetMethodGetTest")
+ public Response getTest(@Context Request req) {
+ String method = req.getMethod();
+ return assertResponse("GET", method);
+ }
+
+ @PUT
+ @Path("/GetMethodPutTest")
+ public Response putTest(@Context Request req) {
+ String method = req.getMethod();
+ return assertResponse("PUT", method);
+ }
+
+ @POST
+ @Path("/GetMethodPostTest")
+ public Response postTest(@Context Request req) {
+ String method = req.getMethod();
+ return assertResponse("POST", method);
+ }
+
+ @DELETE
+ @Path("/GetMethodDeleteTest")
+ public Response deleteTest(@Context Request req) {
+ String method = req.getMethod();
+ return assertResponse("DELETE", method);
+ }
+
+ @HEAD
+ @Path("/GetMethodHeadTest")
+ public Response headTest(@Context Request req) {
+ String method = req.getMethod();
+
+ if (method.equalsIgnoreCase("HEAD")) {
+ return Response.ok().build();
+ } else {
+ return Response.status(400).build();
+ }
+ }
+
+ // ------------------ SELECT VARIANT ----------------------------
+
+ @GET
+ @Path("/SelectVariantTestGet")
+ public Response selectVariantTestGet(@Context Request req) {
+ List<Variant> vs = null;
+
+ try {
+ req.selectVariant(vs);
+ return Response.ok("Test FAILED - no exception thrown").build();
+ } catch (IllegalArgumentException ile) {
+ return Response.ok("Test PASSED - expected exception thrown").build();
+ } catch (Throwable th) {
+ return Response
+ .ok("Test FAILED - wrong type exception thrown" + th.getMessage())
+ .build();
+ }
+ }
+
+ @PUT
+ @Path("/SelectVariantTestPut")
+ public Response selectVariantTestPut(@Context Request req) {
+ return selectVariantTestGet(req);
+ }
+
+ @POST
+ @Path("/SelectVariantTestPost")
+ public Response selectVariantTestPost(@Context Request req) {
+ return selectVariantTestGet(req);
+ }
+
+ @DELETE
+ @Path("/SelectVariantTestDelete")
+ public Response selectVariantTestDelete(@Context Request req) {
+ return selectVariantTestGet(req);
+ }
+
+ @GET
+ @Path("/SelectVariantTestResponse")
+ public Response selectVariantTestResponse(@Context Request req) {
+ List<Variant> list = Variant.encodings("CP1250", "UTF-8")
+ .languages(Locale.ENGLISH).mediaTypes(MediaType.APPLICATION_JSON_TYPE)
+ .add().build();
+ Variant selectedVariant = req.selectVariant(list);
+ if (null == selectedVariant)
+ return Response.notAcceptable(list).build();
+ return Response.ok("entity").build();
+ }
+
+ // ------------------ EVALUATE PRECONDITIONS ----------------------------
+ private static boolean evaluatePreconditionsEntityTagNull(Request req) {
+ try {
+ req.evaluatePreconditions((EntityTag) null);
+ return false;
+ } catch (IllegalArgumentException iae) {
+ return true;
+ }
+ }
+
+ private static boolean evaluatePreconditionsNowEntityTagNull(Request req) {
+ try {
+ Date now = Calendar.getInstance().getTime();
+ req.evaluatePreconditions(now, (EntityTag) null);
+ return false;
+ } catch (IllegalArgumentException iae) {
+ return true;
+ }
+ }
+
+ private static boolean evaluatePreconditionsDateEntityTag(Request req,
+ Date date, String tag) {
+ ResponseBuilder rb = req.evaluatePreconditions(date, createTag(tag));
+ return rb == null;
+ }
+
+ private static boolean evaluatePreconditionsDate(Request req, Date date) {
+ ResponseBuilder rb = req.evaluatePreconditions(date);
+ return rb == null;
+ }
+
+ private static boolean evaluatePreconditions(Request req) {
+ ResponseBuilder rb = req.evaluatePreconditions();
+ return rb == null;
+ }
+
+ private static EntityTag createTag(String tag) {
+ String xtag = new StringBuilder().append("\"").append(tag).append("\"")
+ .toString();
+ return EntityTag.valueOf(xtag);
+ }
+
+ private static boolean evaluatePreconditionsEntityTag(Request req,
+ String tag) {
+ ResponseBuilder rb = req.evaluatePreconditions(createTag(tag));
+ return rb == null;
+ }
+
+ private static Response createResponse(boolean ok) {
+ Status status = ok ? Status.OK : Status.PRECONDITION_FAILED;
+ return Response.status(status).build();
+ }
+
+ private static Date getYear1900() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.YEAR, 1900);
+ return calendar.getTime();
+ }
+
+ @GET
+ @Path("/preconditionsSimpleGet")
+ public Response evaluatePreconditionsEntityTagGetSimpleTest(
+ @Context Request req) {
+ boolean ok = evaluatePreconditionsEntityTag(req, "AAA");
+ if (!ok)
+ return Response.status(Status.GONE).build();
+ ok &= evaluatePreconditionsNowEntityTagNull(req);
+ if (!ok)
+ return Response.status(Status.NOT_ACCEPTABLE).build();
+ ok &= evaluatePreconditionsEntityTagNull(req);
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsAAAGet")
+ public Response evaluatePreconditionsEntityTagAAAGetTest(
+ @Context Request req) {
+ boolean ok = evaluatePreconditionsEntityTag(req, "AAA");
+ return createResponse(ok);
+ }
+
+ @PUT
+ @Path("/preconditionsAAAPut")
+ public Response evaluatePreconditionsEntityTagAAAPutTest(
+ @Context Request req) {
+ return evaluatePreconditionsEntityTagAAAGetTest(req);
+ }
+
+ @HEAD
+ @Path("/preconditionsAAAHead")
+ public Response evaluatePreconditionsEntityTagAAAHeadTest(
+ @Context Request req) {
+ return evaluatePreconditionsEntityTagAAAGetTest(req);
+ }
+
+ @GET
+ @Path("/preconditionsAAAAgesAgoGet")
+ public Response evaluatePreconditionsAgesAgoEntityTagAAAGetTest(
+ @Context Request req) {
+ Date date = getYear1900();
+ boolean ok = evaluatePreconditionsDateEntityTag(req, date, "AAA");
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsNowAAAGet")
+ public Response evaluatePreconditionsDateEntityTagAAAGetTest(
+ @Context Request req) {
+ Date date = Calendar.getInstance().getTime();
+ boolean ok = evaluatePreconditionsDateEntityTag(req, date, "AAA");
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsNowGet")
+ public Response evaluatePreconditionsDateGetTest(@Context Request req) {
+ Date date = Calendar.getInstance().getTime();
+ boolean ok = evaluatePreconditionsDate(req, date);
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsAgesAgoGet")
+ public Response evaluatePreconditionsAgesAgoGetTest(@Context Request req) {
+ Date date = getYear1900();
+ boolean ok = evaluatePreconditionsDate(req, date);
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsGet")
+ public Response evaluatePreconditionsGetTest(@Context Request req) {
+ boolean ok = evaluatePreconditions(req);
+ return createResponse(ok);
+ }
+
+ @GET
+ @Path("/preconditionsHead")
+ public Response evaluatePreconditionsHeadTest(@Context Request req) {
+ boolean ok = evaluatePreconditions(req);
+ return createResponse(ok);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java
new file mode 100644
index 0000000..a483d2a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, 2021 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.request;
+
+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(RequestTest.class);
+ return resources;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java
new file mode 100644
index 0000000..6d24903
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 2021 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.lib.deliverable;
+
+import java.util.Properties;
+
+/**
+ * This class serves as a well known place for harness, util, and porting
+ * classes to retrieve property values.
+ *
+ * @author Kyle Grucci
+ */
+public interface PropertyManagerInterface {
+
+ /**
+ * This method swaps all of the following interop values in
+ * TSPropertyManager...
+ *
+ */
+ public void swapInteropPropertyValues(String sDirection);
+
+ /**
+ * gets a new properties containing all entries in the property manager. Any
+ * operation on the returned properties will have no effect on property
+ * manager
+ */
+ public Properties getJteProperties();
+
+ /**
+ * gets property value with default
+ *
+ * @param sKey - Property to retrieve
+ * @param default - default value to use
+ * @return String - property value
+ */
+ public String getProperty(String sKey, String def);
+
+ /**
+ * This method is called to get a property value
+ *
+ * @param sKey
+ * - Property to retrieve
+ * @return String - property value
+ */
+ public String getProperty(String sKey) throws PropertyNotSetException;
+
+ /**
+ * This method is called to set a property on the property manager
+ *
+ * @param skey - key to be used
+ * @param sVal - value to use
+ */
+ public void setProperty(String sKey, String sVal);
+
+ /**
+ * This method is called by the test harness to retrieve all properties needed
+ * by a particular test.
+ *
+ * @param sPropKeys - Properties to retrieve
+ * @return Properties - property/value pairs
+ */
+ public Properties getTestSpecificProperties(String[] sPropKeys)
+ throws PropertyNotSetException;
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java
new file mode 100644
index 0000000..2debdde
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2007, 2021 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.lib.deliverable;
+
+public class PropertyNotSetException extends java.lang.Exception {
+ public PropertyNotSetException(String s) {
+ super(s);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java
new file mode 100644
index 0000000..e1956ca
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, 2021 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.lib.implementation.sun.common;
+
+import java.net.*;
+import jakarta.ws.rs.tck.lib.util.*;
+import jakarta.ws.rs.tck.lib.porting.*;
+
+/**
+ * This is a J2EE Reference specific implementation of the TSURLInterface which
+ * is to be used for J2EE-TS testing. TS tests use this interface to obtain the
+ * URL String to use to access a given web component. If a given J2EE Server
+ * implmentation requires that URLs be created in a different manner, then this
+ * implementation can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public class SunRIURL implements TSURLInterface {
+ private URL url = null;
+
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL object.
+ */
+ public URL getURL(String protocol, String host, int port, String file)
+ throws MalformedURLException {
+ try {
+ url = new URL(protocol, host, port, file);
+ } catch (MalformedURLException e) {
+ TestUtil.logErr("Failed during URL creation", e);
+ throw e;
+ }
+ return url;
+ }
+
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL as a String.
+ */
+ public String getURLString(String protocol, String host, int port,
+ String file) {
+ if (file.startsWith("/"))
+ return protocol + "://" + host + ":" + port + file;
+ else
+ return protocol + "://" + host + ":" + port + "/" + file;
+ }
+
+ /**
+ * This method is called by TS tests to get the request string to use to
+ * access a given web component.
+ *
+ * @param request
+ * - the request file.
+ * @return a valid String object.
+ */
+ public String getRequest(String request) {
+ return request;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java
new file mode 100644
index 0000000..2fd13d5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2008, 2021 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.lib.implementation.sun.jersey;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import jakarta.ws.rs.tck.lib.deliverable.PropertyManagerInterface;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * This is a utility class that borrowed from Kyle Grucci's original work in
+ * TSRuntimeConfiguration.java. It is called to replace any configurable
+ * properties in the web xml files with the implementation specific values
+ * specified in ts.jte. A copy is made of each web xml file (with the
+ * substituted values) in the same location with file extension .new.
+ *
+ * @author Dianne Jiao
+ */
+public class TSWebConfiguration {
+
+ // whether running with s1as or j2sdkee RI
+ private static Boolean runningS1AS;
+
+ public final static String WEB_XML = "web.xml.template";
+
+ private File tempFile;
+
+ private PrintWriter log;
+
+ private static Hashtable htReplacementProps = new Hashtable();
+
+ private Hashtable htReplacerTable = new Hashtable();
+
+ private static String sTempDir = "";
+
+ private StringReplacer replacer = new StringReplacer();
+
+ private static File jteFile = new File(System.getProperty("TS_HOME")
+ + File.separator + "bin" + File.separator + "ts.jte");
+
+ private static String servlet_adaptor = "servlet_adaptor";
+
+ private static String implementation_name = "jaxrs_impl_name";
+
+ private PropertyManagerInterface propMgr;
+
+ static Properties props;
+
+ static List<String> props_name = Arrays.asList("servlet_adaptor");
+
+ public TSWebConfiguration() {
+ System.out.println("Dummy TSWebConfiguration Conctructor");
+ }
+
+ public static void main(String[] args) {
+
+ TSWebConfiguration webconfig = new TSWebConfiguration();
+
+ implementation_name = webconfig.findProps(implementation_name);
+ System.out.println("++++++++++++=" + implementation_name);
+
+ servlet_adaptor = webconfig.findProps(servlet_adaptor);
+ servlet_adaptor = servlet_adaptor.replace(".class", "").replace("/", ".");
+ System.out
+ .println("Replacement value for servlet_adaptor =" + servlet_adaptor);
+
+ PrintWriter logOut = new PrintWriter(System.out, true);
+
+ File fileList = new File(System.getProperty("TS_HOME") + File.separator
+ + "bin" + File.separator + "jaxrs_filelist");
+
+ try {
+ BufferedReader input = new BufferedReader(new FileReader(fileList));
+
+ try {
+ String line = null; // not declared within while loop
+ while ((line = input.readLine()) != null) {
+ System.out.println("Processing file " + line);
+ File file = new File(
+ System.getProperty("TS_HOME") + File.separator + line);
+ try {
+ htReplacementProps.put("servlet_adaptor", servlet_adaptor);
+ webconfig.sweepwebFile(file);
+ System.out.println("Done with file " + file.toString());
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out
+ .println("Failed to modify xml files with correct settings. "
+ + "Please check the values of");
+ }
+ }
+ } finally {
+ input.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ System.exit(0);
+ }
+
+ String findProps(String prop) {
+ System.out.println("Processing jte file");
+ String replace = null;
+
+ try {
+ BufferedReader input = new BufferedReader(new FileReader(jteFile));
+
+ try {
+ String line = null;
+ while ((line = input.readLine()) != null) {
+ if (line.startsWith(prop)) {
+ replace = line.split("=")[1];
+ return replace;
+ }
+ }
+ } finally {
+ input.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ /// I am here now
+ public String sweepwebFile(File file)
+ throws FileNotFoundException, IOException {
+ if (htReplacerTable != null && !(htReplacerTable.isEmpty())) {
+ htReplacerTable = replaceOnWebInfoStrings(htReplacerTable);
+ }
+ String dir = file.getParent();
+ File xml = new File(dir + File.separator + file.getName());
+
+ return replacer.replace(file, htReplacementProps, htReplacerTable, dir);
+ }
+
+ final class StringReplacer {
+
+ public String sFindString; // string we are searching for
+
+ public String sReplaceString; // replace sFindString with this
+
+ public String sDirString;
+
+ public String sFileNameStringToReplace;
+
+ public String sNewFileNameString;
+
+ public int iHowMany = -1;
+
+ public String[] sFileList;
+
+ public boolean bNewFile = false;
+
+ private Hashtable htFindAndReplace = null;
+
+ private Hashtable htCustomTable = null;
+
+ private Vector vInfoObjects = new Vector();
+
+ private Vector vMatchingInfoObjects = new Vector();
+
+ private Vector vNonMatchingInfoObjects = new Vector();
+
+ private boolean bSomethingWasReplaced = false;
+
+ public String replace(File file, Hashtable htStrings,
+ Hashtable htReplacerTable, String sTempDir) {
+ String[] sFileList = null;
+ htFindAndReplace = htStrings;
+ htCustomTable = htReplacerTable;
+ String sTemp = "";
+ ReplacementInfo ri = null;
+ String sNewFileName = "";
+ StringBuffer sFoundBuffer = new StringBuffer();
+ char c;
+ bSomethingWasReplaced = false;
+ BufferedReader fReader = null;
+ BufferedWriter fNewWriter = null;
+ try {
+ vInfoObjects = new Vector();
+ String sKey = "";
+ // create ReplacementInfo objects
+ for (Enumeration e = htFindAndReplace.keys(); e.hasMoreElements();) {
+ sKey = (String) e.nextElement();
+ vInfoObjects.addElement(
+ new ReplacementInfo(sKey, (String) htFindAndReplace.get(sKey)));
+ }
+ // add in the table the custom table of replacement strings
+ // if any
+ if (htCustomTable != null) {
+ for (Enumeration e = htCustomTable.keys(); e.hasMoreElements();) {
+ sKey = (String) e.nextElement();
+ vInfoObjects.addElement(
+ new ReplacementInfo(sKey, (String) htCustomTable.get(sKey)));
+
+ }
+ }
+ // reader of the file that we're searching
+ fReader = new BufferedReader(new FileReader(file));
+ System.out.println("File to read: " + file.getAbsolutePath());
+ StringWriter sWriter = new StringWriter();
+ // stores new file contents
+
+ // The following code is here to account for the fact that we
+ // have some properties to replace which are substrings of other
+ // properties. We need to be sure that we will be able to
+ // replace either. Thus, we check the char after certain props
+ // to see if they continue to match another property. If so,
+ // then we will replace with the longer property value
+ boolean bCheckForDot = false;
+ String sHold = "";
+ int iCharRead; // holds each char that we read
+ vMatchingInfoObjects.addAll(vInfoObjects);
+ while ((iCharRead = fReader.read()) != -1) {
+ c = (char) iCharRead;
+
+ if (bCheckForDot) {
+ if (c != '.') {
+ // hold the dot and let the old processing happen
+ sHold = new String((new Character(c)).toString());
+ System.out.println("sHold = " + sHold);
+ } else {
+ sFoundBuffer.append(c);
+ bCheckForDot = false;
+ continue;
+ // since there is no need to just check .
+ }
+ } else {
+ if (sHold != null) {
+ // just write the char that we were holding. This
+ // assumes that this char is not the beginning of a
+ // string we want to replace
+ sWriter.write(sHold);
+ sHold = null;
+ }
+
+ sFoundBuffer.append(c);
+ }
+
+ sTemp = new String(sFoundBuffer);
+
+ // get all ris that still match
+ for (Enumeration e = vMatchingInfoObjects.elements(); e
+ .hasMoreElements();) {
+
+ ri = (ReplacementInfo) e.nextElement();
+ if (ri.sFind.startsWith(sTemp)) {
+ if (ri.sFind.equals(sTemp)) {
+
+ // what if we have a substring of another string that
+ // we are searching for?
+
+ System.out.println(
+ "REPLACER:MATCH found: " + ri.sFind + " matches " + sTemp);
+ ri.foundOccurance();
+ bSomethingWasReplaced = true;
+ sWriter.write(ri.sReplace);
+ // reset sFoundBuffer
+ sFoundBuffer = new StringBuffer();
+ // reset matchers to all again
+ vMatchingInfoObjects.removeAllElements();
+ vMatchingInfoObjects.addAll(vInfoObjects);
+ break;
+ }
+ } else {
+ vNonMatchingInfoObjects.addElement(ri);
+ // the char that we just read causes our string not
+ // to match the string we're looking for. Write the
+ // old string to the new file and reset sFoundBuffer.
+ // this will never happen!!!
+ }
+ }
+ // remove all non-matching ri's
+ vMatchingInfoObjects.removeAll(vNonMatchingInfoObjects);
+ vNonMatchingInfoObjects.removeAllElements();
+ // reset everything if there are none left matching
+ if (vMatchingInfoObjects.isEmpty()) {
+ sWriter.write(sTemp);
+ sFoundBuffer = new StringBuffer();
+ vMatchingInfoObjects.removeAllElements();
+ vMatchingInfoObjects.addAll(vInfoObjects);
+ }
+ }
+ fReader.close();
+ if (bSomethingWasReplaced) {
+ sNewFileName = sTempDir + File.separator + "web.xml."
+ + implementation_name;
+ System.out.println("New filename:" + sNewFileName);
+ fNewWriter = new BufferedWriter(
+ new FileWriter(new File(sNewFileName)));
+ fNewWriter.write(sWriter.toString());
+ fNewWriter.flush();
+ } else {
+ sNewFileName = null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (fNewWriter != null) {
+ try {
+ fNewWriter.close();
+ } catch (IOException exp) {
+ }
+ }
+ }
+ return sNewFileName;
+ }
+
+ class ReplacementInfo {
+
+ private int iFoundOccurances = 0;
+
+ private String sFind = null;
+
+ private String sReplace = null;
+
+ ReplacementInfo(String sFindString, String sReplaceString) {
+ sFind = sFindString;
+ sReplace = sReplaceString;
+ iFoundOccurances = 0;
+ }
+
+ public void foundOccurance() {
+ iFoundOccurances++;
+ if (TestUtil.harnessDebug) {
+ System.out.println("we found an occurance #" + iFoundOccurances
+ + " of '" + sFind + "'");
+ }
+ }
+ }
+ }
+
+ /**
+ * Parse the HashTable which contains strings retrieved via calls into the
+ * porting classes for deployment. We must substitute on these strings prior
+ * to substituting them into the web.xml.
+ */
+ private Hashtable replaceOnWebInfoStrings(Hashtable extras) {
+
+ boolean changeIt = false;
+
+ String searchFor[] = { "servlet_adaptor" };
+
+ for (Enumeration e = extras.keys(); e.hasMoreElements();) {
+ String sKey = (String) e.nextElement();
+ String val = (String) extras.get(sKey);
+ String oldJndi = val;
+ changeIt = false;
+ String buff = null;
+ int startPos = 0;
+ for (int i = 0; i < searchFor.length; i++) {
+ System.out.println("\n###Searching for=" + searchFor[i]);
+ if ((startPos = val.lastIndexOf(searchFor[i])) != -1) {
+ changeIt = true;
+ String startBuff = val.substring(0, startPos);
+ buff = (String) htReplacementProps.get(searchFor[i]);
+ val = startBuff + buff
+ + val.substring(startPos + searchFor[i].length());
+ }
+ }
+ if (changeIt) {
+ extras.put((String) sKey, val);
+ System.out.println(
+ "\n###\nold webInfo Val=" + oldJndi + "\nNew webInfo Val = " + val);
+ }
+ }
+ return extras;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java
new file mode 100644
index 0000000..3c12b5e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.porting;
+
+import java.net.*;
+import java.io.Serializable;
+import jakarta.ws.rs.tck.lib.util.*;
+
+/**
+ * This is a Java EE Reference specific implementation of the TSURLInterface
+ * which is to be used for Java EE TCK testing. TS tests use this interface to
+ * obtain the URL String to use to access a given web component. If a given Java
+ * EE Server implmentation requires that URLs be created in a different manner,
+ * then this implementation can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public class TSURL implements TSURLInterface, Serializable {
+ private TSURLInterface ctsURL = null;
+
+ private String sClass = "porting.ts.url.class.1";
+
+ public TSURL() {
+ // we'll initialize the impl when the individual method is called
+ // this constructor assumes sClass = "porting.ts.url.class.1".
+ }
+
+ public TSURL(String sClassName) {
+ sClass = sClassName;
+ }
+
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL object.
+ */
+ public URL getURL(String protocol, String host, int port, String file)
+ throws MalformedURLException {
+ if (ctsURL == null) {
+ try {
+ // create and initialize a new instance of TSURLInterface
+ Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+ ctsURL = (TSURLInterface) c.newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ return ctsURL.getURL(protocol, host, port, file);
+ }
+
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL as a String.
+ */
+ public String getURLString(String protocol, String host, int port,
+ String file) {
+ if (ctsURL == null) {
+ try {
+ // create and initialize a new instance of TSURLInterface
+ Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+ ctsURL = (TSURLInterface) c.newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return ctsURL.getURLString(protocol, host, port, file);
+ }
+
+ /**
+ * This method is called by TS tests to get the request string to use to
+ * access a given web component.
+ *
+ * @param request
+ * - the request file.
+ * @return a valid String object.
+ */
+ public String getRequest(String request) {
+ if (ctsURL == null) {
+ try {
+ // create and initialize a new instance of TSURLInterface
+ Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+ ctsURL = (TSURLInterface) c.newInstance();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return ctsURL.getRequest(request);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java
new file mode 100644
index 0000000..ee00989
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.porting;
+
+import java.net.*;
+
+/**
+ * An implementation of the TSURLInterface is to be used for Java EE TCK
+ * testing. TS tests use this interface to obtain the URL String to use to
+ * access a given web component. If a given Java EE Server implmentation
+ * requires that URLs be created in a different manner, then this implementation
+ * can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public interface TSURLInterface {
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL object.
+ */
+ public URL getURL(String protocol, String host, int port, String file)
+ throws MalformedURLException;
+
+ /**
+ * This method is called by TS tests to get the URL to use to access a given
+ * web component.
+ *
+ * @param protocol
+ * - the name of the protocol.
+ * @param host
+ * - the name of the host.
+ * @param port
+ * - the port number.
+ * @param file
+ * - the host file.
+ * @return a valid URL as a String.
+ */
+ public String getURLString(String protocol, String host, int port,
+ String file);
+
+ /**
+ * This method is called by TS tests to get the request to use to access a
+ * given web component.
+ *
+ * @param request
+ * - the request file.
+ * @return a valid String object.
+ */
+ public String getRequest(String request);
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java
new file mode 100644
index 0000000..c66eff9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1995, 2021 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.lib.util;
+
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.PrintStream;
+
+/**
+ * This class implements a BASE64 Character decoder as specified in RFC1521.
+ *
+ * This RFC is part of the MIME specification which is published by the Internet
+ * Engineering Task Force (IETF). Unlike some other encoding schemes there is
+ * nothing in this encoding that tells the decoder where a buffer starts or
+ * stops, so to use it you will need to isolate your encoded data into a single
+ * chunk and then feed them this decoder. The simplest way to do that is to read
+ * all of the encoded data into a string and then use:
+ *
+ * <pre>
+ * byte mydata[];
+ * BASE64Decoder base64 = new BASE64Decoder();
+ *
+ * mydata = base64.decodeBuffer(bufferString);
+ * </pre>
+ *
+ * This will decode the String in <i>bufferString</i> and give you an array of
+ * bytes in the array <i>myData</i>.
+ *
+ * On errors, this class throws a CEFormatException with the following detail
+ * strings:
+ *
+ * <pre>
+ * "BASE64Decoder: Not enough bytes for an atom."
+ * </pre>
+ *
+ * @author Chuck McManis
+ * @see CharacterEncoder
+ * @see BASE64Decoder
+ */
+
+public class BASE64Decoder extends CharacterDecoder {
+
+ /** This class has 4 bytes per atom */
+ protected int bytesPerAtom() {
+ return (4);
+ }
+
+ /** Any multiple of 4 will do, 72 might be common */
+ protected int bytesPerLine() {
+ return (72);
+ }
+
+ /**
+ * This character array provides the character to value map based on RFC1521.
+ */
+ private final static char pem_array[] = {
+ // 0 1 2 3 4 5 6 7
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
+ '4', '5', '6', '7', '8', '9', '+', '/' // 7
+ };
+
+ private final static byte pem_convert_array[] = new byte[256];
+
+ static {
+ for (int i = 0; i < 255; i++) {
+ pem_convert_array[i] = -1;
+ }
+ for (int i = 0; i < pem_array.length; i++) {
+ pem_convert_array[pem_array[i]] = (byte) i;
+ }
+ }
+
+ byte decode_buffer[] = new byte[4];
+
+ /**
+ * Decode one BASE64 atom into 1, 2, or 3 bytes of data.
+ */
+ protected void decodeAtom(PushbackInputStream inStream,
+ OutputStream outStream, int rem) throws java.io.IOException {
+ int i;
+ byte a = -1, b = -1, c = -1, d = -1;
+
+ if (rem < 2) {
+ throw new CEFormatException(
+ "BASE64Decoder: Not enough bytes for an atom.");
+ }
+ do {
+ i = inStream.read();
+ if (i == -1) {
+ throw new CEStreamExhausted();
+ }
+ } while (i == '\n' || i == '\r');
+ decode_buffer[0] = (byte) i;
+
+ i = readFully(inStream, decode_buffer, 1, rem - 1);
+ if (i == -1) {
+ throw new CEStreamExhausted();
+ }
+
+ if (rem > 3 && decode_buffer[3] == '=') {
+ rem = 3;
+ }
+ if (rem > 2 && decode_buffer[2] == '=') {
+ rem = 2;
+ }
+ switch (rem) {
+ case 4:
+ d = pem_convert_array[decode_buffer[3] & 0xff];
+ // NOBREAK
+ case 3:
+ c = pem_convert_array[decode_buffer[2] & 0xff];
+ // NOBREAK
+ case 2:
+ b = pem_convert_array[decode_buffer[1] & 0xff];
+ a = pem_convert_array[decode_buffer[0] & 0xff];
+ break;
+ }
+
+ switch (rem) {
+ case 2:
+ outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+ break;
+ case 3:
+ outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+ outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
+ break;
+ case 4:
+ outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+ outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
+ outStream.write((byte) (((c << 6) & 0xc0) | (d & 0x3f)));
+ break;
+ }
+ return;
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java
new file mode 100644
index 0000000..dfd7032
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2006, 2021 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.lib.util;
+
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+
+/**
+ * This class implements a BASE64 Character encoder as specified in RFC1521.
+ * This RFC is part of the MIME specification as published by the Internet
+ * Engineering Task Force (IETF). Unlike some other encoding schemes there is
+ * nothing in this encoding that indicates where a buffer starts or ends.
+ *
+ * This means that the encoded text will simply start with the first line of
+ * encoded text and end with the last line of encoded text.
+ *
+ * @version 1.23, 11/17/05
+ * @author Chuck McManis
+ * @see CharacterEncoder
+ * @see BASE64Decoder
+ */
+
+public class BASE64Encoder extends CharacterEncoder {
+
+ /** this class encodes three bytes per atom. */
+ protected int bytesPerAtom() {
+ return (3);
+ }
+
+ /**
+ * this class encodes 57 bytes per line. This results in a maximum of 57/3 * 4
+ * or 76 characters per output line. Not counting the line termination.
+ */
+ protected int bytesPerLine() {
+ return (57);
+ }
+
+ /** This array maps the characters to their 6 bit values */
+ private final static char pem_array[] = {
+ // 0 1 2 3 4 5 6 7
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
+ '4', '5', '6', '7', '8', '9', '+', '/' // 7
+ };
+
+ /**
+ * encodeAtom - Take three bytes of input and encode it as 4 printable
+ * characters. Note that if the length in len is less than three is encodes
+ * either one or two '=' signs to indicate padding characters.
+ */
+ protected void encodeAtom(OutputStream outStream, byte data[], int offset,
+ int len) throws IOException {
+ byte a, b, c;
+
+ if (len == 1) {
+ a = data[offset];
+ b = 0;
+ c = 0;
+ outStream.write(pem_array[(a >>> 2) & 0x3F]);
+ outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+ outStream.write('=');
+ outStream.write('=');
+ } else if (len == 2) {
+ a = data[offset];
+ b = data[offset + 1];
+ c = 0;
+ outStream.write(pem_array[(a >>> 2) & 0x3F]);
+ outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+ outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
+ outStream.write('=');
+ } else {
+ a = data[offset];
+ b = data[offset + 1];
+ c = data[offset + 2];
+ outStream.write(pem_array[(a >>> 2) & 0x3F]);
+ outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+ outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
+ outStream.write(pem_array[c & 0x3F]);
+ }
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java
new file mode 100644
index 0000000..0b2c0b0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1995, 2021 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.lib.util;
+
+import java.io.IOException;
+
+public class CEFormatException extends IOException {
+ public CEFormatException(String s) {
+ super(s);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java
new file mode 100644
index 0000000..b935609
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 1995, 2021 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.lib.util;
+
+import java.io.IOException;
+
+/** This exception is thrown when EOF is reached */
+public class CEStreamExhausted extends IOException {
+};
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java
new file mode 100644
index 0000000..8143a77
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995, 2021 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.lib.util;
+
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This class defines the decoding half of character encoders. A character
+ * decoder is an algorithim for transforming 8 bit binary data that has been
+ * encoded into text by a character encoder, back into original binary form.
+ *
+ * The character encoders, in general, have been structured around a central
+ * theme that binary data can be encoded into text that has the form:
+ *
+ * <pre>
+ * [Buffer Prefix]
+ * [Line Prefix][encoded data atoms][Line Suffix]
+ * [Buffer Suffix]
+ * </pre>
+ *
+ * Of course in the simplest encoding schemes, the buffer has no distinct prefix
+ * of suffix, however all have some fixed relationship between the text in an
+ * 'atom' and the binary data itself.
+ *
+ * In the CharacterEncoder and CharacterDecoder classes, one complete chunk of
+ * data is referred to as a <i>buffer</i>. Encoded buffers are all text, and
+ * decoded buffers (sometimes just referred to as buffers) are binary octets.
+ *
+ * To create a custom decoder, you must, at a minimum, overide three abstract
+ * methods in this class.
+ * <DL>
+ * <DD>bytesPerAtom which tells the decoder how many bytes to expect from
+ * decodeAtom
+ * <DD>decodeAtom which decodes the bytes sent to it as text.
+ * <DD>bytesPerLine which tells the encoder the maximum number of bytes per
+ * line.
+ * </DL>
+ *
+ * In general, the character decoders return error in the form of a
+ * CEFormatException. The syntax of the detail string is
+ *
+ * <pre>
+ * DecoderClassName: Error message.
+ * </pre>
+ *
+ * Several useful decoders have already been written and are referenced in the
+ * See Also list below.
+ *
+ * @author Chuck McManis
+ * @see CEFormatException
+ * @see CharacterEncoder
+ * @see UCDecoder
+ * @see UUDecoder
+ * @see BASE64Decoder
+ */
+
+public abstract class CharacterDecoder {
+
+ /** Return the number of bytes per atom of decoding */
+ abstract protected int bytesPerAtom();
+
+ /** Return the maximum number of bytes that can be encoded per line */
+ abstract protected int bytesPerLine();
+
+ /** decode the beginning of the buffer, by default this is a NOP. */
+ protected void decodeBufferPrefix(PushbackInputStream aStream,
+ OutputStream bStream) throws IOException {
+ }
+
+ /** decode the buffer suffix, again by default it is a NOP. */
+ protected void decodeBufferSuffix(PushbackInputStream aStream,
+ OutputStream bStream) throws IOException {
+ }
+
+ /**
+ * This method should return, if it knows, the number of bytes that will be
+ * decoded. Many formats such as uuencoding provide this information. By
+ * default we return the maximum bytes that could have been encoded on the
+ * line.
+ */
+ protected int decodeLinePrefix(PushbackInputStream aStream,
+ OutputStream bStream) throws IOException {
+ return (bytesPerLine());
+ }
+
+ /**
+ * This method post processes the line, if there are error detection or
+ * correction codes in a line, they are generally processed by this method.
+ * The simplest version of this method looks for the (newline) character.
+ */
+ protected void decodeLineSuffix(PushbackInputStream aStream,
+ OutputStream bStream) throws IOException {
+ }
+
+ /**
+ * This method does an actual decode. It takes the decoded bytes and writes
+ * them to the OutputStream. The integer <i>l</i> tells the method how many
+ * bytes are required. This is always <= bytesPerAtom().
+ */
+ protected void decodeAtom(PushbackInputStream aStream, OutputStream bStream,
+ int l) throws IOException {
+ throw new CEStreamExhausted();
+ }
+
+ /**
+ * This method works around the bizarre semantics of BufferedInputStream's
+ * read method.
+ */
+ protected int readFully(InputStream in, byte buffer[], int offset, int len)
+ throws java.io.IOException {
+ for (int i = 0; i < len; i++) {
+ int q = in.read();
+ if (q == -1)
+ return ((i == 0) ? -1 : i);
+ buffer[i + offset] = (byte) q;
+ }
+ return len;
+ }
+
+ /**
+ * Decode the text from the InputStream and write the decoded octets to the
+ * OutputStream. This method runs until the stream is exhausted.
+ *
+ * @exception CEFormatException
+ * An error has occured while decoding
+ * @exception CEStreamExhausted
+ * The input stream is unexpectedly out of data
+ */
+ public void decodeBuffer(InputStream aStream, OutputStream bStream)
+ throws IOException {
+ int i;
+ int totalBytes = 0;
+
+ PushbackInputStream ps = new PushbackInputStream(aStream);
+ decodeBufferPrefix(ps, bStream);
+ while (true) {
+ int length;
+
+ try {
+ length = decodeLinePrefix(ps, bStream);
+ for (i = 0; (i + bytesPerAtom()) < length; i += bytesPerAtom()) {
+ decodeAtom(ps, bStream, bytesPerAtom());
+ totalBytes += bytesPerAtom();
+ }
+ if ((i + bytesPerAtom()) == length) {
+ decodeAtom(ps, bStream, bytesPerAtom());
+ totalBytes += bytesPerAtom();
+ } else {
+ decodeAtom(ps, bStream, length - i);
+ totalBytes += (length - i);
+ }
+ decodeLineSuffix(ps, bStream);
+ } catch (CEStreamExhausted e) {
+ break;
+ }
+ }
+ decodeBufferSuffix(ps, bStream);
+ }
+
+ /**
+ * Alternate decode interface that takes a String containing the encoded
+ * buffer and returns a byte array containing the data.
+ *
+ * @exception CEFormatException
+ * An error has occured while decoding
+ */
+ public byte decodeBuffer(String inputString)[] throws IOException {
+ byte inputBuffer[] = new byte[inputString.length()];
+ ByteArrayInputStream inStream;
+ ByteArrayOutputStream outStream;
+
+ inputString.getBytes(0, inputString.length(), inputBuffer, 0);
+ inStream = new ByteArrayInputStream(inputBuffer);
+ outStream = new ByteArrayOutputStream();
+ decodeBuffer(inStream, outStream);
+ return (outStream.toByteArray());
+ }
+
+ /**
+ * Decode the contents of the inputstream into a buffer.
+ */
+ public byte decodeBuffer(InputStream in)[] throws IOException {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ decodeBuffer(in, outStream);
+ return (outStream.toByteArray());
+ }
+
+ /**
+ * Decode the contents of the String into a ByteBuffer.
+ */
+ public ByteBuffer decodeBufferToByteBuffer(String inputString)
+ throws IOException {
+ return ByteBuffer.wrap(decodeBuffer(inputString));
+ }
+
+ /**
+ * Decode the contents of the inputStream into a ByteBuffer.
+ */
+ public ByteBuffer decodeBufferToByteBuffer(InputStream in)
+ throws IOException {
+ return ByteBuffer.wrap(decodeBuffer(in));
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java
new file mode 100644
index 0000000..feb23b3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2006, 2021 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.lib.util;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This class defines the encoding half of character encoders. A character
+ * encoder is an algorithim for transforming 8 bit binary data into text
+ * (generally 7 bit ASCII or 8 bit ISO-Latin-1 text) for transmition over text
+ * channels such as e-mail and network news.
+ *
+ * The character encoders have been structured around a central theme that, in
+ * general, the encoded text has the form:
+ *
+ * <pre>
+ * [Buffer Prefix]
+ * [Line Prefix][encoded data atoms][Line Suffix]
+ * [Buffer Suffix]
+ * </pre>
+ *
+ * In the CharacterEncoder and CharacterDecoder classes, one complete chunk of
+ * data is referred to as a <i>buffer</i>. Encoded buffers are all text, and
+ * decoded buffers (sometimes just referred to as buffers) are binary octets.
+ *
+ * To create a custom encoder, you must, at a minimum, overide three abstract
+ * methods in this class.
+ * <DL>
+ * <DD>bytesPerAtom which tells the encoder how many bytes to send to encodeAtom
+ * <DD>encodeAtom which encodes the bytes sent to it as text.
+ * <DD>bytesPerLine which tells the encoder the maximum number of bytes per
+ * line.
+ * </DL>
+ *
+ * Several useful encoders have already been written and are referenced in the
+ * See Also list below.
+ *
+ * @version 1.38, 11/17/05
+ * @author Chuck McManis
+ * @see CharacterDecoder;
+ * @see UCEncoder
+ * @see UUEncoder
+ * @see BASE64Encoder
+ */
+public abstract class CharacterEncoder {
+
+ /** Stream that understands "printing" */
+ protected PrintStream pStream;
+
+ /** Return the number of bytes per atom of encoding */
+ abstract protected int bytesPerAtom();
+
+ /** Return the number of bytes that can be encoded per line */
+ abstract protected int bytesPerLine();
+
+ /**
+ * Encode the prefix for the entire buffer. By default is simply opens the
+ * PrintStream for use by the other functions.
+ */
+ protected void encodeBufferPrefix(OutputStream aStream) throws IOException {
+ pStream = new PrintStream(aStream);
+ }
+
+ /**
+ * Encode the suffix for the entire buffer.
+ */
+ protected void encodeBufferSuffix(OutputStream aStream) throws IOException {
+ }
+
+ /**
+ * Encode the prefix that starts every output line.
+ */
+ protected void encodeLinePrefix(OutputStream aStream, int aLength)
+ throws IOException {
+ }
+
+ /**
+ * Encode the suffix that ends every output line. By default this method just
+ * prints a <newline> into the output stream.
+ */
+ protected void encodeLineSuffix(OutputStream aStream) throws IOException {
+ pStream.println();
+ }
+
+ /** Encode one "atom" of information into characters. */
+ abstract protected void encodeAtom(OutputStream aStream, byte someBytes[],
+ int anOffset, int aLength) throws IOException;
+
+ /**
+ * This method works around the bizarre semantics of BufferedInputStream's
+ * read method.
+ */
+ protected int readFully(InputStream in, byte buffer[])
+ throws java.io.IOException {
+ for (int i = 0; i < buffer.length; i++) {
+ int q = in.read();
+ if (q == -1)
+ return i;
+ buffer[i] = (byte) q;
+ }
+ return buffer.length;
+ }
+
+ /**
+ * Encode bytes from the input stream, and write them as text characters to
+ * the output stream. This method will run until it exhausts the input stream,
+ * but does not print the line suffix for a final line that is shorter than
+ * bytesPerLine().
+ */
+ public void encode(InputStream inStream, OutputStream outStream)
+ throws IOException {
+ int j;
+ int numBytes;
+ byte tmpbuffer[] = new byte[bytesPerLine()];
+
+ encodeBufferPrefix(outStream);
+
+ while (true) {
+ numBytes = readFully(inStream, tmpbuffer);
+ if (numBytes == 0) {
+ break;
+ }
+ encodeLinePrefix(outStream, numBytes);
+ for (j = 0; j < numBytes; j += bytesPerAtom()) {
+
+ if ((j + bytesPerAtom()) <= numBytes) {
+ encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+ } else {
+ encodeAtom(outStream, tmpbuffer, j, (numBytes) - j);
+ }
+ }
+ if (numBytes < bytesPerLine()) {
+ break;
+ } else {
+ encodeLineSuffix(outStream);
+ }
+ }
+ encodeBufferSuffix(outStream);
+ }
+
+ /**
+ * Encode the buffer in <i>aBuffer</i> and write the encoded result to the
+ * OutputStream <i>aStream</i>.
+ */
+ public void encode(byte aBuffer[], OutputStream aStream) throws IOException {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+ encode(inStream, aStream);
+ }
+
+ /**
+ * A 'streamless' version of encode that simply takes a buffer of bytes and
+ * returns a string containing the encoded buffer.
+ */
+ public String encode(byte aBuffer[]) {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+ String retVal = null;
+ try {
+ encode(inStream, outStream);
+ // explicit ascii->unicode conversion
+ retVal = outStream.toString("8859_1");
+ } catch (Exception IOException) {
+ // This should never happen.
+ throw new Error("CharacterEncoder.encode internal error");
+ }
+ return (retVal);
+ }
+
+ /**
+ * Return a byte array from the remaining bytes in this ByteBuffer.
+ * <P>
+ * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+ * <P>
+ * To avoid an extra copy, the implementation will attempt to return the byte
+ * array backing the ByteBuffer. If this is not possible, a new byte array
+ * will be created.
+ */
+ private byte[] getBytes(ByteBuffer bb) {
+ /*
+ * This should never return a BufferOverflowException, as we're careful to
+ * allocate just the right amount.
+ */
+ byte[] buf = null;
+
+ /*
+ * If it has a usable backing byte buffer, use it. Use only if the array
+ * exactly represents the current ByteBuffer.
+ */
+ if (bb.hasArray()) {
+ byte[] tmp = bb.array();
+ if ((tmp.length == bb.capacity()) && (tmp.length == bb.remaining())) {
+ buf = tmp;
+ bb.position(bb.limit());
+ }
+ }
+
+ if (buf == null) {
+ /*
+ * This class doesn't have a concept of encode(buf, len, off), so if we
+ * have a partial buffer, we must reallocate space.
+ */
+ buf = new byte[bb.remaining()];
+
+ /*
+ * position() automatically updated
+ */
+ bb.get(buf);
+ }
+
+ return buf;
+ }
+
+ /**
+ * Encode the <i>aBuffer</i> ByteBuffer and write the encoded result to the
+ * OutputStream <i>aStream</i>.
+ * <P>
+ * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+ */
+ public void encode(ByteBuffer aBuffer, OutputStream aStream)
+ throws IOException {
+ byte[] buf = getBytes(aBuffer);
+ encode(buf, aStream);
+ }
+
+ /**
+ * A 'streamless' version of encode that simply takes a ByteBuffer and returns
+ * a string containing the encoded buffer.
+ * <P>
+ * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+ */
+ public String encode(ByteBuffer aBuffer) {
+ byte[] buf = getBytes(aBuffer);
+ return encode(buf);
+ }
+
+ /**
+ * Encode bytes from the input stream, and write them as text characters to
+ * the output stream. This method will run until it exhausts the input stream.
+ * It differs from encode in that it will add the line at the end of a final
+ * line that is shorter than bytesPerLine().
+ */
+ public void encodeBuffer(InputStream inStream, OutputStream outStream)
+ throws IOException {
+ int j;
+ int numBytes;
+ byte tmpbuffer[] = new byte[bytesPerLine()];
+
+ encodeBufferPrefix(outStream);
+
+ while (true) {
+ numBytes = readFully(inStream, tmpbuffer);
+ if (numBytes == 0) {
+ break;
+ }
+ encodeLinePrefix(outStream, numBytes);
+ for (j = 0; j < numBytes; j += bytesPerAtom()) {
+ if ((j + bytesPerAtom()) <= numBytes) {
+ encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+ } else {
+ encodeAtom(outStream, tmpbuffer, j, (numBytes) - j);
+ }
+ }
+ encodeLineSuffix(outStream);
+ if (numBytes < bytesPerLine()) {
+ break;
+ }
+ }
+ encodeBufferSuffix(outStream);
+ }
+
+ /**
+ * Encode the buffer in <i>aBuffer</i> and write the encoded result to the
+ * OutputStream <i>aStream</i>.
+ */
+ public void encodeBuffer(byte aBuffer[], OutputStream aStream)
+ throws IOException {
+ ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+ encodeBuffer(inStream, aStream);
+ }
+
+ /**
+ * A 'streamless' version of encode that simply takes a buffer of bytes and
+ * returns a string containing the encoded buffer.
+ */
+ public String encodeBuffer(byte aBuffer[]) {
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+ ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+ try {
+ encodeBuffer(inStream, outStream);
+ } catch (Exception IOException) {
+ // This should never happen.
+ throw new Error("CharacterEncoder.encodeBuffer internal error");
+ }
+ return (outStream.toString());
+ }
+
+ /**
+ * Encode the <i>aBuffer</i> ByteBuffer and write the encoded result to the
+ * OutputStream <i>aStream</i>.
+ * <P>
+ * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+ */
+ public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
+ throws IOException {
+ byte[] buf = getBytes(aBuffer);
+ encodeBuffer(buf, aStream);
+ }
+
+ /**
+ * A 'streamless' version of encode that simply takes a ByteBuffer and returns
+ * a string containing the encoded buffer.
+ * <P>
+ * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+ */
+ public String encodeBuffer(ByteBuffer aBuffer) {
+ byte[] buf = getBytes(aBuffer);
+ return encodeBuffer(buf);
+ }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java
new file mode 100644
index 0000000..89f8a4e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+/**
+ * This exception is thrown by the init method of the TestUtil class, if
+ * anything goes wrong while establishing a socket connection back to the
+ * harness host.
+ *
+ * @author Kyle Grucci
+ */
+public class RemoteLoggingInitException extends java.lang.Exception {
+ /**
+ * creates a RemoteLoggingInitException
+ */
+ public RemoteLoggingInitException() {
+ super();
+ }
+
+ /**
+ * creates a RemoteLoggingInitException with a message
+ *
+ * @param s
+ * the message
+ */
+ public RemoteLoggingInitException(String s) {
+ super(s);
+ }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java
new file mode 100644
index 0000000..fe19465
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java
@@ -0,0 +1,1071 @@
+/*
+ * Copyright (c) 2007, 2021 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
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+
+/**
+ * TestUtil is a final utility class responsible for implementing logging across
+ * multiple VMs. It also contains many convenience methods for logging property
+ * object contents, stacktraces, and header lines.
+ *
+ * @author Kyle Grucci
+ *
+ */
+public final class TestUtil {
+ public static boolean traceflag = Boolean.getBoolean("junit.log.traceflag");
+
+ // this can be set in TestUtil's start logging method!!
+ public static String sTestName;
+
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+ public static final int VM_UNDER_TEST = 0;
+
+ public static final int VM_HARNESS = 1; // this is really the test client VM
+
+ public static final int VM_JAVATEST = 2;
+
+ public static final int DEBUG_OUTPUT_LEVEL = 2;
+
+ public static final int NORMAL_OUTPUT_LEVEL = 3;
+
+ public static final int ERROR_STREAM = 4;
+
+ public static final int OUTPUT_STREAM = 5;
+
+ public static String NEW_LINE = System.getProperty("line.separator", "\n");
+
+ // by default so the testers don't have to do anything
+ public static int iWhereAreWe = VM_UNDER_TEST;
+
+ private static PrintWriter out = null;
+
+ private static PrintWriter err = null;
+
+ private static PrintWriter additionalWriter = null;
+
+ private static ObjectOutputStream objectOutputStream = null;
+
+ private static ObjectOutputStream objectInputStream = null;
+
+ private static Socket socketOnRemoteVM = null;
+
+ private static boolean bAlreadyInitialized = false;
+
+ private static Object socketMutex = new Object();
+
+ private static int portOfHarness = 2000;
+
+ private static String hostOfHarness = "unset host";
+
+ private static Vector vBuffereredOutput = new Vector();
+
+ // Transaction Attribute Value Mapping Table
+ private static final String UNRECOGNIZED_STATUS = "UNRECOGNIZED_STATUS";
+
+ private static final String transactionTable[] = { "STATUS_ACTIVE", // 0
+ "STATUS_MARKED_ROLLBACK", // 1
+ "STATUS_PREPARED", // 2
+ "STATUS_COMMITTED", // 3
+ "STATUS_ROLLEDBACK", // 4
+ "STATUS_UNKNOWN", // 5
+ "STATUS_NO_TRANSACTION", // 6
+ "STATUS_PREPARING", // 7
+ "STATUS_COMMITTING", // 8
+ "STATUS_ROLLING_BACK", // 9
+ };
+
+ // debug flag for printing TS harness debug output
+ public static boolean harnessDebug;
+
+ // hang onto the props that are passed in during logging init calls
+ private static Properties testProps = null;
+
+ private static SimpleDateFormat df = new SimpleDateFormat(
+ "MM-dd-yyyy HH:mm:ss");
+
+ static {
+ harnessDebug = Boolean.getBoolean("cts.harness.debug");
+ }
+
+ /**
+ * used by harness to log debug output to the standard output stream
+ *
+ * @param s
+ * the output string
+ */
+ public static void logHarnessDebug(String s) {
+ if (harnessDebug) {
+ logHarness(s, null);
+ }
+ }
+
+ /**
+ * used by TSTestFinder and TSScript to log output to the standard output
+ * stream
+ *
+ * @param s
+ * the output string
+ * @param t
+ * a Throwable whose stacktrace gets printed
+ */
+ public static void logHarness(String s, Throwable t) {
+ synchronized (System.out) {
+ System.out.println(df.format(new Date()) + ":" + s);
+ //logToAdditionalWriter(s, t);
+ if (t != null) {
+ t.printStackTrace();
+ }
+ }
+ }
+
+ public static void logHarness(String s) {
+ logHarness(s, null);
+ }
+
+ private static void logToAdditionalWriter(String s) {
+ logToAdditionalWriter(s, null);
+ }
+
+ private static void logToAdditionalWriter(String s, Throwable t) {
+ if (additionalWriter != null)
+ additionalWriter.println(s);
+ if (t != null) {
+ t.printStackTrace(additionalWriter);
+ }
+ }
+
+ /**
+ * This method returns the properties object
+ *
+ * @return the properties object
+ */
+ public static Properties getProperties() {
+ if (testProps == null) {
+ testProps = getPropsFromFile();
+ }
+ return testProps;
+ }
+
+ /**
+ * This method returns the property value for the appropriate property key
+ *
+ * @param s
+ * the property name
+ * @return the property value
+ */
+ public static String getProperty(String s) {
+ Properties p = getProperties();
+ return p.getProperty(s);
+ }
+
+ /**
+ * This method returns the property value for the appropriate property key
+ *
+ * @param s
+ * the property name
+ * @return the property value
+ */
+ public static String getProperty(String s, String defaultValue) {
+ Properties p = getProperties();
+ return p.getProperty(s, defaultValue);
+ }
+
+ /**
+ * returns the transaction status value as a String given its integer
+ * representation
+ *
+ * @param status
+ * integer representation of a transaction status
+ * @return string representation of a transaction status
+ */
+ public static String getTransactionStatus(int status) {
+ if (status < 0 || status > transactionTable.length - 1)
+ return UNRECOGNIZED_STATUS;
+ else
+ return transactionTable[status];
+ }
+
+ /**
+ * prints the transaction status value as a String given its integer
+ * representation
+ *
+ * @param status
+ * integer representation of a transaction status
+ */
+ public static void printTransactionStatus(int status) {
+ logMsg("TRANSACTION_STATUS: " + getTransactionStatus(status));
+ }
+
+ // MilliSeconds Multiple
+ public static final int MILLI = 1000;
+
+ /**
+ * pauses the calling thread for the specified number of seconds
+ *
+ * @param s
+ * number of seconds
+ */
+ public static void sleepSec(int s) {
+ logTrace("Sleeping " + s + " seconds");
+ try {
+ Thread.sleep(s * MILLI);
+ } catch (InterruptedException e) {
+ logErr("Exception: " + e);
+ }
+ }
+
+ /**
+ * pauses the calling thread for the specified number of milliseconds
+ *
+ * @param s
+ * number of milliseconds
+ */
+ public static void sleep(int s) {
+ sleepMsec(s);
+ }
+
+ /**
+ * pauses the calling thread for the specified number of milliseconds
+ *
+ * @param s
+ * number of milliseconds
+ */
+ public static void sleepMsec(int s) {
+ logTrace("Sleeping " + s + " milliseconds");
+ try {
+ Thread.sleep(s);
+ } catch (InterruptedException e) {
+ logErr("Exception: " + e);
+ }
+ }
+
+ public static void flushStream() {
+ synchronized (socketMutex) {
+ try {
+ objectOutputStream.flush();
+ } catch (Throwable t) {
+ // Ignore
+ // System.out.println("EXCEPTION WHILE FLUSHING");
+ }
+ }
+ }
+
+ public static void writeObject(TestReportInfo info) {
+ synchronized (socketMutex) {
+ flushStream();
+ try {
+ objectOutputStream.writeObject(info);
+ // System.out.println("WROTE: " + info.sOutput);
+ } catch (Exception e) {
+ // System.out.println("EXCEPTION WHILE WRITING: " + info.sOutput);
+ synchronized (vBuffereredOutput) {
+ vBuffereredOutput.addElement(info);
+ // System.out.println("ADDED THIS STRING TO BUFFERED OUT: " +
+ // info.sOutput);
+ }
+ }
+ flushStream();
+ }
+ }
+
+ private static void sendBufferedData() throws Exception {
+ TestReportInfo tri = null;
+ synchronized (vBuffereredOutput) {
+ try {
+ // logMsg("vBuffereredOutput size = " + vBuffereredOutput.size());
+ synchronized (socketMutex) {
+ for (int ii = 0; ii < vBuffereredOutput.size(); ii++) {
+ tri = (TestReportInfo) vBuffereredOutput.elementAt(ii);
+ writeObject(tri);
+ // System.out.println("WRITING_bufferedoutput: " + tri.sOutput);
+ // objectOutputStream.writeObject(tri);
+ // objectOutputStream.flush();
+ // logMsg("writing: " + ii);
+ // logMsg("writing: " + tri.sOutput);
+ }
+ }
+ // logMsg("wrote buffered output");
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ vBuffereredOutput.removeAllElements();
+ // logMsg("reinititialized buffered output vector");
+ }
+ }
+ }
+
+ private static final String PROPS_FILE_NAME = "-cts-props.txt";
+
+ private static final String PROPS_FILE;
+
+ static {
+ String userName = System.getProperty("user.name");
+ String tmpDir = System.getProperty("java.io.tmpdir",
+ File.separator + "tmp");
+ if (tmpDir.endsWith(File.separator)) {
+ PROPS_FILE = tmpDir + userName + PROPS_FILE_NAME;
+ } else {
+ PROPS_FILE = tmpDir + File.separator + userName + PROPS_FILE_NAME;
+ }
+ System.out.println(
+ "************************************************************");
+ System.out.println("* props file set to \"" + PROPS_FILE + "\"");
+ System.out.println(
+ "************************************************************");
+ }
+
+ private static Properties getPropsFromFile() {
+ FileInputStream in = null;
+ Properties p = new Properties();
+ try {
+ in = new FileInputStream(PROPS_FILE);
+ p.load(in);
+ } catch (Exception e) {
+ logErr("Error reading the Properties object", e);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ return p;
+ }
+
+ private static void savePropsToFile(Properties p) {
+ FileOutputStream out = null;
+ try {
+ out = new FileOutputStream(PROPS_FILE);
+ p.store(out, "CTS Test Properties File");
+ } catch (Exception e) {
+ logErr("Error saving the Properties object", e);
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * This static method must be called once by each new remote VM. Once called,
+ * a socket connection is created back to the host running the test harness.
+ * All calls to logMsg, logErr, and logTrace are immediately sent back to the
+ * harness host.
+ *
+ * @param p
+ * properties containing harness host, port, and trace flag
+ * @exception RemoteLoggingInitException
+ * if an exception occurs while the server side is setting up the
+ * socket connection back to the client host
+ */
+ public static void init(Properties p) throws RemoteLoggingInitException {
+ savePropsToFile(p); // persist properties to a disk file
+ // System.out.println("INIT_CALLED");
+ synchronized (socketMutex) {
+ try {
+ // TSPropertyManager.createTSPropertyManager(p);
+ testProps = p;
+ if (p.isEmpty()) {
+ throw new RemoteLoggingInitException(
+ "Init: Error - Empty properties object passed to TestUtil.init");
+ }
+ NEW_LINE = p.getProperty("line.separator");
+ if (socketOnRemoteVM != null) {
+ socketOnRemoteVM.close();
+ }
+ if (objectOutputStream != null) {
+ objectOutputStream.close();
+ }
+ if (true) {
+ // System.out.println("INIT_CALLED AND SOCKET = NULL");
+ traceflag = Boolean
+ .valueOf(p.getProperty("harness.log.traceflag", "true"))
+ .booleanValue();
+ hostOfHarness = p.getProperty("harness.host");
+ portOfHarness = Integer
+ .parseInt(p.getProperty("harness.log.port", "2000"));
+ if (hostOfHarness == null) {
+ throw new RemoteLoggingInitException(
+ "Init: Error while trying to getProperty(harness.host) - returned null");
+ }
+ socketOnRemoteVM = new Socket(hostOfHarness, portOfHarness);
+ objectOutputStream = new ObjectOutputStream(
+ socketOnRemoteVM.getOutputStream());
+ sendBufferedData();
+ // logMsg("socketOnRemoteVM=null, renewed everything");
+ } else {
+ // we'll never get here now...
+ // call flush to make sure that we still have an open connection.
+ // if the client went away and a new client is being run, we will
+ // get an IOException, in which case we will reconnect.
+ // logMsg("socketOnRemoteVM != null, calling flush");
+ // objectOutputStream.flush();
+ // if this fails, then the connection is gone
+ // this is better than flush, because flush seems to always fail
+ TestReportInfo tri = new TestReportInfo("SVR: " + "Logging check",
+ OUTPUT_STREAM, DEBUG_OUTPUT_LEVEL, null);
+ objectOutputStream.writeObject(tri);
+ // System.out.println("WROTE TEST OBJECT");
+ }
+ } catch (UnknownHostException e) {
+ throw new RemoteLoggingInitException(
+ "You must pass a valid host string to init()");
+ } catch (IOException e) {
+ // System.out.println("EXCEPTION WHILE WRITING TEST OBJECT");
+ // the client VM may have shutdown, so establish a new connection
+ try {
+ // System.out.println("INIT_CALLED AND TRYING TO ESABLISH CONN. AFTER
+ // IOEXCEPTION");
+ traceflag = Boolean
+ .valueOf(p.getProperty("harness.log.traceflag", "true"))
+ .booleanValue();
+ hostOfHarness = p.getProperty("harness.host");
+ portOfHarness = Integer
+ .parseInt(p.getProperty("harness.log.port", "2000"));
+ if (hostOfHarness == null) {
+ throw new RemoteLoggingInitException(
+ "Init: Error while trying to getProperty(harness.host) - returned null");
+ }
+ socketOnRemoteVM.close();
+ socketOnRemoteVM = new Socket(hostOfHarness, portOfHarness);
+ objectOutputStream = new ObjectOutputStream(
+ socketOnRemoteVM.getOutputStream());
+ sendBufferedData();
+ // logMsg("caught IOException from flush(), renewed everything");
+ } catch (IOException e2) {
+ e2.printStackTrace();
+ throw new RemoteLoggingInitException(
+ "IOException in TestUtil.init()");
+ } catch (Exception e2) {
+ e2.printStackTrace();
+ throw new RemoteLoggingInitException(
+ "got a random exception in init()");
+ }
+ } catch (NumberFormatException e) {
+ throw new RemoteLoggingInitException(
+ "You must pass a valid port number string to init()");
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RemoteLoggingInitException(
+ "got a random exception in init()");
+ }
+ }
+ }
+
+ /*
+ * This method is called by our harness code to allow code that is shared
+ * between the harness and the tests and calls TestUtil logMsg and logTrace to
+ * do the right thing inside of the JavaTest VM. These calls will call to our
+ * logHarness methods.
+ */
+ public static void initJavaTest() {
+ iWhereAreWe = VM_JAVATEST;
+ }
+
+ public static void setAdditionalWriter(PrintWriter pw) {
+ iWhereAreWe = VM_JAVATEST;
+ additionalWriter = pw;
+ }
+
+ /**
+ * This static method must be called once by a VM which does not rely upon any
+ * remote logging.
+ *
+ * param p properties containing harness trace flag
+ */
+ public static void initNoLogging(Properties p) {
+ if (bAlreadyInitialized)
+ return;
+
+ testProps = p;
+ NEW_LINE = p.getProperty("line.separator");
+ traceflag = Boolean.valueOf(p.getProperty("harness.log.traceflag", "true"))
+ .booleanValue();
+ iWhereAreWe = VM_HARNESS;
+ bAlreadyInitialized = true;
+ }
+
+ /**
+ * This static method must be called once by the harness VM. Once called, a
+ * serversocket begins listening for Remote VMs to connect on the port
+ * specified by harness.log.port.
+ *
+ * @param p
+ * properties containing harness trace flag
+ */
+ public static void initClient(Properties p) {
+ if (bAlreadyInitialized)
+ return;
+ // start listener thread
+ try {
+ testProps = p;
+ NEW_LINE = p.getProperty("line.separator");
+ traceflag = Boolean
+ .valueOf(p.getProperty("harness.log.traceflag", "true"))
+ .booleanValue();
+ iWhereAreWe = VM_HARNESS;
+ ServerSocket ss = getServerSocket(p);
+ new Acceptor(ss);
+ bAlreadyInitialized = true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static ServerSocket getServerSocket(Properties p) throws IOException {
+ ServerSocket result = null;
+ int port = 2000;
+ int retry = 10;
+ final int delaySeconds = 1;
+ try {
+ port = Integer.parseInt(p.getProperty("harness.log.port", "2000"));
+ } catch (NumberFormatException e1) {
+ e1.printStackTrace();
+ System.err.println("Invalid value for harness.log.port,"
+ + " using default harness.log.port of " + port);
+ }
+ try {
+ retry = Integer
+ .parseInt(p.getProperty("harness.socket.retry.count", "10"));
+ } catch (NumberFormatException e2) {
+ e2.printStackTrace();
+ System.err.println("Invalid value for harness.socket.retry.count,"
+ + " using default harness.socket.retry.count of " + retry);
+ }
+ logTrace(
+ "####### Value of harness.socket.retry.count is \"" + retry + "\"");
+ logTrace("####### Value of harness.log.port is \"" + port + "\"");
+ result = getServerSocket0(port, retry, delaySeconds);
+ while (result == null) {
+ port++;
+ result = getServerSocket0(port, retry, delaySeconds);
+ }
+ p.setProperty("harness.log.port", Integer.toString(port));
+ logTrace(
+ "####### Actual bind value of harness.log.port is \"" + port + "\"");
+ return result;
+ }
+
+ private static ServerSocket getServerSocket0(int port, int retry,
+ int delaySeconds) {
+ ServerSocket result = null;
+ for (int i = 0; i < retry; i++) {
+ try {
+ result = new ServerSocket(port);
+ break;
+ } catch (IOException e3) {
+ try {
+ Thread.sleep(delaySeconds * 1000);
+ } catch (InterruptedException e4) {
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This static method must be called once by the harness VM in order to set
+ * the output and error streams and the name of the current test.
+ *
+ * @param testName
+ * the currently running testname as specified in the source code
+ * tags
+ * @param outStream
+ * stream printed to by the logMsg and logTrace methods
+ * @param errStream
+ * stream printed to by the logErr methods
+ */
+ public static void setCurrentTest(String testName, PrintWriter outStream,
+ PrintWriter errStream) {
+ sTestName = testName;
+ out = outStream;
+ err = outStream;
+ }
+
+ /**
+ * prints a string to the log stream. All tests should use this method for
+ * standard logging messages
+ *
+ * @param s
+ * string to print to the log stream
+ */
+ public static void logMsg(String s) {
+ logHarness(s);
+ }
+
+ /**
+ * prints a string as well as the provided Throwable's stacktrace to the log
+ * stream. All tests should use this method for standard logging messages
+ *
+ * @param s
+ * string to print to the log stream
+ * @param t
+ * - throwable whose stacktrace gets printed*
+ *
+ */
+ public static void logMsg(String s, Throwable t) {
+ logHarnessDebug(s);
+ if (t != null) {
+ t.printStackTrace();
+ }
+ }
+
+ /**
+ * turns on/off debugging. Once on, all calls to the logTrace method result in
+ * messages being printed to the log stream. If off, all logTrace calls are
+ * not printed.
+ *
+ * @param b
+ * If <code>true</code>, debugging is on. If false, debugging is
+ * turned off.
+ */
+ public static void setTrace(boolean b) {
+ traceflag = b;
+ }
+
+ /**
+ * prints a debug string to the log stream. All tests should use this method
+ * for verbose logging messages. Whether or not the string is printed is
+ * determined by the last call to the setTrace method.
+ *
+ * @param s
+ * string to print to the log stream
+ */
+ public static void logTrace(String s) {
+ logTrace(s, null);
+ }
+
+ /**
+ * Prints a debug string as well as the provided Throwable's stacktrace. Use
+ * this if certain exceptions are only desired while tracing.
+ *
+ * @param s
+ * - string to print to the log stream
+ * @param t
+ * - throwable whose stactrace gets printed
+ */
+ public static void logTrace(String s, Throwable t) {
+ if (traceflag) {
+ logHarnessDebug(s);
+ if (t != null) {
+ t.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * prints an error string to the error stream. All tests should use this
+ * method for error messages.
+ *
+ * @param s
+ * string to print to the error stream
+ * @param e
+ * a Throwable whose stacktrace gets printed
+ */
+ public static void logErr(String s, Throwable e) {
+ logHarness(s);
+ if (e != null) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * prints an error string to the error stream. All tests should use this
+ * method for error messages.
+ *
+ * @param s
+ * string to print to the error stream
+ */
+ public static void logErr(String s) {
+ logErr(s, null);
+ }
+
+ /**
+ * prints the contents of a properties object to the logging stream
+ *
+ * @param p
+ * properties to print
+ */
+ public static void list(Properties p) {
+ StringBuffer sb = new StringBuffer();
+ if (p == null)
+ return;
+ sb.append("--- Property Listing ---").append(TestUtil.NEW_LINE);
+ Enumeration e = p.propertyNames();
+ String key = null;
+ while (e.hasMoreElements()) {
+ key = (String) e.nextElement();
+ sb.append(key).append("=").append(p.getProperty(key))
+ .append(TestUtil.NEW_LINE);
+ }
+ sb.append("--- End Property Listing ---").append(TestUtil.NEW_LINE);
+ logTrace(new String(sb));
+ }
+
+ /**
+ * prints the stacktrace of a Throwable to the logging stream
+ *
+ * @param e
+ * exception to print the stacktrace of
+ */
+ public static void printStackTrace(Throwable e) {
+ if (e == null) {
+ return;
+ }
+ try {
+ StringWriter sw = new StringWriter();
+ PrintWriter writer = new PrintWriter(sw);
+ e.printStackTrace(writer);
+ logErr(sw.toString());
+ writer.close();
+ } catch (Exception E) {
+ }
+ }
+
+ /**
+ * prints the stacktrace of a Throwable to a string
+ *
+ * @param e
+ * exception to print the stacktrace of
+ */
+ public static String printStackTraceToString(Throwable e) {
+ String sTrace = "";
+ if (e == null)
+ return "";
+ try {
+ StringWriter sw = new StringWriter();
+ PrintWriter writer = new PrintWriter(sw);
+ e.printStackTrace(writer);
+ sTrace = sw.toString();
+ writer.close();
+ } catch (Exception E) {
+ }
+ return sTrace;
+ }
+
+ /**
+ * prints a line of asterisks to the logging stream
+ */
+ public static void separator2() {
+ logMsg("**************************************************"
+ + "******************************");
+ }
+
+ /**
+ * prints a line of dashes to the logging stream
+ */
+ public static void separator1() {
+ logMsg("--------------------------------------------------"
+ + "------------------------------");
+ }
+
+ /**
+ * Convience method to handle sucking in the data from a connection.
+ */
+ public static String getResponse(URLConnection connection)
+ throws IOException {
+ StringBuffer content;
+ BufferedReader in;
+ // set up the streams / readers
+ InputStream instream = connection.getInputStream();
+ InputStreamReader inreader = new InputStreamReader(instream);
+ in = new BufferedReader(inreader);
+ // data structures
+ content = new StringBuffer(1024);
+ char[] chars = new char[1024];
+ int length = 0;
+ // pull the data into the content buffer
+ while (length != -1) {
+ content.append(chars, 0, length);
+ length = in.read(chars, 0, chars.length);
+ }
+ // return
+ instream.close(); // john feb 16
+ inreader.close(); // john feb 16
+ in.close(); // john feb 16
+ return content.toString();
+ }
+
+ /**
+ * Loads any properties that might be in a given String.
+ */
+ public static Properties getResponseProperties(String string)
+ throws IOException {
+ Properties props;
+ ByteArrayInputStream in;
+ byte[] bytes;
+ props = new Properties();
+ bytes = string.getBytes();
+ in = new ByteArrayInputStream(bytes);
+ props.load(in);
+ in.close();
+ return props;
+ }
+
+ /**
+ * One shot method to get Properties directly from a URLConnection.
+ */
+ public static Properties getResponseProperties(URLConnection connection)
+ throws IOException {
+ Properties props;
+ String input;
+ input = getResponse(connection);
+ props = getResponseProperties(input);
+ return props;
+ }
+
+ public static String toEncodedString(Properties args) {
+ StringBuffer buf = new StringBuffer();
+ Enumeration names = args.propertyNames();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ String value = args.getProperty(name);
+ buf.append(URLEncoder.encode(name)).append("=")
+ .append(URLEncoder.encode(value));
+ if (names.hasMoreElements())
+ buf.append("&");
+ }
+ return buf.toString();
+ }
+
+ public static URLConnection sendPostData(Properties p, URL url)
+ throws IOException {
+ TestUtil.logMsg("Openning url connection to: " + url.toString());
+ URLConnection urlConn = url.openConnection();
+ // Begin POST of properties to SERVLET
+ String argString = TestUtil.toEncodedString(p);
+ urlConn.setDoOutput(true);
+ urlConn.setDoInput(true);
+ urlConn.setUseCaches(false);
+ DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
+ out.writeBytes(argString);
+ out.flush();
+ out.close();
+ // End POST
+ return urlConn;
+ }
+
+ /**
+ * Parse a the table name from the ddl string such as: "create table foo" or
+ * "delete from foo"
+ *
+ * @param value
+ * buffer to parse
+ * @return The name of the table
+ */
+ public static String getTableName(String value) {
+ String tableName = "";
+ if (value != null) {
+ tableName = value.trim();
+ int pos = tableName.lastIndexOf(" ");
+ tableName = tableName.substring(pos + 1);
+ } else {
+ TestUtil.logMsg("Error: Null value passed for table Name");
+ }
+ return (tableName);
+ } // END -- getTableName
+
+ public static String srcToDist(String src) {
+ return replaceLastSrc(src, "dist");
+ }
+
+ public static String replaceLastSrc(String src, String replacement) {
+ // find last index of /src/, remove "src", then replace it with replacement
+ StringBuffer sbToConvert = new StringBuffer(src);
+ int iStart = src.lastIndexOf("src");
+ if (iStart != -1) {
+ if (harnessDebug) {
+ TestUtil.logHarnessDebug("Pre-converted src dir = " + sbToConvert);
+ }
+ sbToConvert.replace(iStart, iStart + 3, replacement);
+
+ if (harnessDebug) {
+ TestUtil.logHarnessDebug(
+ "Converted " + replacement + " dir = " + sbToConvert);
+ }
+ }
+ return sbToConvert.toString();
+ }
+
+ public static String getDistString() {
+ // we may need to default to src until we are ready to convert for good
+ return "dist";
+ }
+
+ public static String getRelativePath(String oldVal) {
+ if (oldVal == null) {
+ return oldVal;
+ }
+ String result = oldVal;
+ oldVal = oldVal.replace('\\', '/');
+ while (oldVal.endsWith("/")) {
+ oldVal = oldVal.substring(0, oldVal.length() - 1);
+ }
+ if (oldVal.endsWith("/src")) {
+ return result;
+ }
+ int pos = oldVal.indexOf("/src/");
+ if (pos == -1) {
+ pos = oldVal.indexOf("/dist/");
+ if (pos == -1) {
+ result = oldVal;
+ } else {
+ result = oldVal.substring(pos + 6); // len of '/dist/'
+ }
+ } else {
+ result = oldVal.substring(pos + 5);
+ }
+ return result;
+ }
+
+ // Convert the given string of key-value-pair into a properties object
+ //
+ // for example :
+ // DatabaseName=derbyDB:user=cts1:password=cts1:serverName=localhost:portNumber=1527
+ //
+ public static Properties strToProps(String strProps) {
+
+ logTrace("Props String = " + strProps);
+ Properties props = new Properties();
+ String strArray[] = strProps.split(":"); // Split the given string into
+ // array of key value pairs
+
+ for (String keyValuePair : strArray) {
+ String strArray2[] = keyValuePair.split("="); // Take the key value pair
+ // and store it into
+ // properties
+ logTrace("Setting property " + strArray2[0] + " = " + strArray2[1]);
+ props.setProperty(strArray2[0], strArray2[1]);
+ }
+
+ return props;
+
+ }
+
+ public static void printProperties(Properties props) {
+ Set<String> propertyNames = props.stringPropertyNames();
+ for (String key : propertyNames) {
+ logTrace(key + " = " + props.getProperty(key));
+ }
+ }
+
+}
+
+// ======================= end of class TestUtil ======================
+
+class Acceptor extends Thread {
+ ServerSocket serverSocket;
+
+ private Socket outputSocket = null;
+
+ public Acceptor(ServerSocket ss) {
+ serverSocket = ss;
+ this.start();
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ outputSocket = serverSocket.accept();
+ new SocketReader(outputSocket);
+ // System.out.println("new connection!!!!!");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+}
+
+class TestReportInfo implements Serializable {
+ public int iDebugLevel = TestUtil.NORMAL_OUTPUT_LEVEL;
+
+ public String sOutput = ""; // Constants.EMPTY_STRING;
+
+ public Throwable exception = null;
+
+ public int iStream = TestUtil.OUTPUT_STREAM;
+
+ public TestReportInfo(String output, int stream, int level, Throwable e) {
+ if (sOutput != null)
+ sOutput = output;
+ iDebugLevel = level;
+ exception = e;
+ iStream = stream;
+ }
+}
+
+class SocketReader extends Thread {
+ private Socket outputSocket = null;
+
+ public SocketReader(Socket s) {
+ outputSocket = s;
+ this.start();
+ }
+
+ public void run() {
+ ObjectInputStream objIn;
+ TestReportInfo tri = null;
+ try {
+ objIn = new ObjectInputStream(outputSocket.getInputStream());
+ // while((tri = (TestReportInfo)objIn.readObject()) != null)
+ while (true) {
+ tri = (TestReportInfo) objIn.readObject();
+ if (tri.iDebugLevel == TestUtil.DEBUG_OUTPUT_LEVEL) {
+ // System.out.println("about to call logTrace");
+ TestUtil.logTrace(tri.sOutput);
+ } else {
+ if (tri.iStream == TestUtil.ERROR_STREAM) {
+ if (tri.exception == null)
+ TestUtil.logErr(tri.sOutput);
+ else
+ TestUtil.logErr(tri.sOutput, tri.exception);
+ // System.out.println("about to call logErr");
+ } else // assume outputstream
+ {
+ // System.out.println("about to call logMsg");
+ TestUtil.logMsg(tri.sOutput);
+ }
+ }
+ }
+ } catch (EOFException e) {
+ // do nothing since the eof broke us out of the loop
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // cleanup socket no matter what happens
+ /*
+ * try { outputSocket.close(); outputSocket = null; } catch(IOException e) {
+ *
+ * }
+ */
+ }
+}
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template
new file mode 100644
index 0000000..5f08e7e
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2012, 2021 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_ASYNC_INVOKER</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.asyncinvoker.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTS_JAXRS_SPEC_CLIENT_ASYNC_INVOKER</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/request/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template
new file mode 100644
index 0000000..1a7f175
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/request/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-RSCOREREQUEST</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.request.TSAppConfig</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>CTSJAX-RSCOREREQUEST</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 1699011..b53bcad 100644
--- a/jersey-tck/pom.xml
+++ b/jersey-tck/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.glassfish.jersey.core</groupId>
@@ -11,16 +12,28 @@
<description>This test verifies the compliance of Eclipse Jersey with Jakarta REST</description>
<properties>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <jersey.version>3.0.0</jersey.version>
+ <glassfish.container.version>6.1.0</glassfish.container.version>
+ <jakarta.platform.version>9.1.0</jakarta.platform.version>
+ <junit.jupiter.version>5.7.2</junit.jupiter.version>
+ <jakarta.rest.version>3.0.0</jakarta.rest.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>junit-bom</artifactId>
+ <version>${junit.jupiter.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
- <version>3.0.0</version>
+ <version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -29,6 +42,18 @@
<dependencies>
<dependency>
+ <groupId>org.glassfish.hk2</groupId>
+ <artifactId>hk2-locator</artifactId>
+ <version>3.0.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-glassfish-managed-6</artifactId>
+ <version>1.0.0.Alpha1</version>
+ </dependency>
+
+ <dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-tck</artifactId>
<version>3.1-SNAPSHOT</version>
@@ -36,24 +61,38 @@
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.inject</groupId>
- <artifactId>jersey-hk2</artifactId>
- <scope>test</scope>
+ <groupId>org.glassfish.main.common</groupId>
+ <artifactId>simple-glassfish-api</artifactId>
+ <version>${glassfish.container.version}</version>
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.core</groupId>
- <artifactId>jersey-server</artifactId>
- <scope>test</scope>
+ <groupId>org.jboss.arquillian.junit5</groupId>
+ <artifactId>arquillian-junit5-container</artifactId>
+ <version>1.7.0.Alpha10</version>
</dependency>
<dependency>
- <groupId>org.glassfish.jersey.containers</groupId>
- <artifactId>jersey-container-grizzly2-http</artifactId>
- <scope>test</scope>
+ <groupId>jakarta.platform</groupId>
+ <artifactId>jakarta.jakartaee-api</artifactId>
+ <version>${jakarta.platform.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
</dependency>
</dependencies>
+
+ <profiles>
+ <profile>
+ <id>arq-glassfish-managed</id>
+ </profile>
+ </profiles>
+
<build>
<plugins>
<plugin>
@@ -67,6 +106,136 @@
</goals>
<configuration>
<dependenciesToScan>jakarta.ws.rs:jakarta.ws.rs-tck</dependenciesToScan>
+ <systemPropertyVariables>
+ <GLASSFISH_HOME>${project.build.directory}/glassfish6</GLASSFISH_HOME>
+ <servlet_adaptor>org.glassfish.jersey.servlet.ServletContainer</servlet_adaptor>
+ <webServerHost>localhost</webServerHost>
+ <webServerPort>8080</webServerPort>
+ <junit.log.traceflag>true</junit.log.traceflag>
+ <porting.ts.url.class.1>jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL</porting.ts.url.class.1>
+ </systemPropertyVariables>
+ <environmentVariables>
+ <GLASSFISH_HOME>${project.build.directory}/glassfish6</GLASSFISH_HOME>
+ </environmentVariables>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>3.2.0</version>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.glassfish.main.distributions</groupId>
+ <artifactId>glassfish</artifactId>
+ <version>${glassfish.container.version}</version>
+ <type>zip</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ <execution>
+ <id>copy</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-client.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-server</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-server.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-common</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-common.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-container-grizzly2-http.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet-core</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-container-servlet-core.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-container-servlet.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-sse</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-media-sse.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-binding</artifactId>
+ <version>${jersey.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jersey-media-json-binding.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ <version>${jakarta.rest.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+ <destFileName>jakarta.ws.rs-api.jar</destFileName>
+ </artifactItem>
+ </artifactItems>
</configuration>
</execution>
</executions>