Skip to content

Commit

Permalink
Allow to use HeaderDelegateProvider to parse the response MediaType
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Supol <[email protected]>
  • Loading branch information
jansupol committed Mar 27, 2020
1 parent 5b611fc commit 351a578
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.PropertiesDelegate;
import org.glassfish.jersey.internal.RuntimeDelegateDecorator;
import org.glassfish.jersey.message.MessageBodyWorkers;

/**
Expand Down Expand Up @@ -331,7 +332,7 @@ private <T> T singleHeader(String name, Function<String, T> converter, boolean c
}

try {
return converter.apply(HeaderUtils.asString(value, null));
return converter.apply(HeaderUtils.asString(value, configuration));
} catch (ProcessingException ex) {
throw exception(name, value, ex);
}
Expand Down Expand Up @@ -450,7 +451,9 @@ public MediaType getMediaType() {
@Override
public MediaType apply(String input) {
try {
return MediaType.valueOf(input);
return RuntimeDelegateDecorator.configured(configuration)
.createHeaderDelegate(MediaType.class)
.fromString(input);
} catch (IllegalArgumentException iae) {
throw new ProcessingException(iae);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ public Locale getLanguage() {
* message entity).
*/
public MediaType getMediaType() {
return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, MediaType::valueOf, false);
return singleHeader(HttpHeaders.CONTENT_TYPE, MediaType.class, RuntimeDelegateDecorator.configured(configuration)
.createHeaderDelegate(MediaType.class)::fromString, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
Expand All @@ -17,8 +17,12 @@
package org.glassfish.jersey.tests.e2e.header;

import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.message.internal.HeaderUtils;
import org.glassfish.jersey.message.internal.HeaderValueException;
import org.glassfish.jersey.message.internal.InboundMessageContext;
import org.glassfish.jersey.message.internal.OutboundMessageContext;
import org.glassfish.jersey.spi.HeaderDelegateProvider;
import org.junit.Assert;
import org.junit.Test;
Expand All @@ -34,14 +38,18 @@
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ReaderInterceptor;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.fail;

public class HeaderDelegateProviderTest {
static final String HEADER_NAME = "BEAN_HEADER";
static final String DISABLED_VALUE = new BeanForHeaderDelegateProviderTest().toString();
Expand All @@ -64,6 +72,23 @@ public String toString(BeanForHeaderDelegateProviderTest value) {
}
}

public static class EmptyContentTypeHandler implements HeaderDelegateProvider<MediaType> {
@Override
public boolean supports(Class<?> type) {
return MediaType.class == type;
}

@Override
public MediaType fromString(String value) {
return value.isEmpty() ? MediaType.APPLICATION_OCTET_STREAM_TYPE : MediaType.valueOf(value);
}

@Override
public String toString(MediaType value) {
return value.toString();
}
};

public static class BeanForHeaderDelegateProviderTest {
public static String getValue() {
return "CORRECT_VALUE";
Expand Down Expand Up @@ -116,13 +141,18 @@ public void filter(ClientRequestContext requestContext) throws IOException {

@Test
public void testTheProviderIsFound() {
int found = 0;
for (HeaderDelegateProvider provider : ServiceFinder.find(HeaderDelegateProvider.class, true)) {
Assert.assertEquals(provider.getClass(), BeanHeaderDelegateProvider.class);
if (provider.getClass() == BeanHeaderDelegateProvider.class
|| provider.getClass() == EmptyContentTypeHandler.class) {
found++;
}
}
Assert.assertEquals(2, found);
}

@Test
public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
public void testHeaderDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
MultivaluedHashMap headers = new MultivaluedHashMap();
headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest()));
MultivaluedMap<String, String> converted = HeaderUtils.asStringHeaders(headers, null);
Expand All @@ -134,7 +164,7 @@ public void headerDelegateIsUsedWhenRuntimeDelegateDecoratorIsUsed() {
}

@Test
public void headerDelegateIsNotUsed() {
public void testHeaderDelegateIsNotUsed() {
MultivaluedHashMap headers = new MultivaluedHashMap();
headers.put(HEADER_NAME, Arrays.asList(new BeanForHeaderDelegateProviderTest()));

Expand All @@ -147,6 +177,54 @@ public void headerDelegateIsNotUsed() {
testMap(converted, DISABLED_VALUE);
}

@Test
public void testGetMediaTypeInInboundMessageContext() {
ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
InboundMessageContext inboundMessageContext = new InboundMessageContext(config.getConfiguration()) {
@Override
protected Iterable<ReaderInterceptor> getReaderInterceptors() {
return null;
}
};
inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, "");
try {
inboundMessageContext.getMediaType();
fail("Expected HeaderValueException has not been thrown");
} catch (HeaderValueException ex) {
// expected
}

config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false);
inboundMessageContext = new InboundMessageContext(config.getConfiguration()) {
@Override
protected Iterable<ReaderInterceptor> getReaderInterceptors() {
return null;
}
};
inboundMessageContext.header(HttpHeaders.CONTENT_TYPE, "");
MediaType mediaType = inboundMessageContext.getMediaType();
Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType);
}

@Test
public void testGetMediaTypeInOutboundMessageContext() {
ClientConfig config = new ClientConfig().property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
OutboundMessageContext outboundMessageContext = new OutboundMessageContext(config.getConfiguration());
outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, "");
try {
outboundMessageContext.getMediaType();
fail("Expected HeaderValueException has not been thrown");
} catch (IllegalArgumentException ex) {
// expected
}

config.property(CommonProperties.METAINF_SERVICES_LOOKUP_DISABLE, false);
outboundMessageContext = new OutboundMessageContext(config.getConfiguration());
outboundMessageContext.getHeaders().add(HttpHeaders.CONTENT_TYPE, "");
MediaType mediaType = outboundMessageContext.getMediaType();
Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, mediaType);
}

private void testMap(MultivaluedMap<String, String> map, String expectedValue) {
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
Assert.assertEquals(HEADER_NAME, entry.getKey());
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$BeanHeaderDelegateProvider
org.glassfish.jersey.tests.e2e.header.HeaderDelegateProviderTest$EmptyContentTypeHandler

0 comments on commit 351a578

Please sign in to comment.