/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*******************************************************************************/
package org.apache.wink.common.internal.providers;
import java.util.Collections;
import java.util.List;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import junit.framework.TestCase;
import org.apache.wink.common.internal.application.ApplicationValidator;
import org.apache.wink.common.internal.lifecycle.LifecycleManagersRegistry;
import org.apache.wink.common.internal.registry.ProvidersRegistry;
public class ProvidersContextResolverTest extends TestCase {
public static class NotAProvider {
}
private static final String STRING = "String";
private static final String STRING2 = "String2";
private static final String STRING3 = "String3";
private static final String STRING4 = "String4";
private static final String STRING5 = "String5";
private static final String STRING6 = "String6";
private static final String STRING7 = "String7";
private static final String ATOM = "Atom";
private static final byte[] BYTE = new byte[0];
private static final Integer _12345 = new Integer(12345);
private static final MyClass MYCLASS = new MyClass();
@Provider
@Produces( {MediaType.TEXT_PLAIN, MediaType.WILDCARD})
public static class StringContextResolver implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING;
}
}
@Provider
@Produces( {MediaType.TEXT_PLAIN})
public static class StringContextResolver2 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING2;
}
}
@Provider
@Produces("text/*")
public static class StringContextResolver3 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING3;
}
}
@Provider
@Produces("*/*")
public static class StringContextResolver4 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING4;
}
}
@Provider
public static class StringContextResolver5 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING5;
}
}
@Provider
public static class StringContextResolver6 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING6;
}
}
@Provider
public static class StringContextResolver7 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING7;
}
}
@Provider
@Produces(MediaType.APPLICATION_FORM_URLENCODED)
// intentionally using a MediaType with a '-' to exercise regex code
public static class MyContextResolver implements ContextResolver<MyClass> {
public MyClass getContext(Class<?> type) {
return MYCLASS;
}
}
public static class MyClass {
}
@Provider
@Produces( {MediaType.APPLICATION_ATOM_XML, MediaType.WILDCARD})
public static class AtomContextResolver implements ContextResolver<String> {
public String getContext(Class<?> type) {
if (type == null) {
return ATOM;
}
return null;
}
}
@Provider
@Produces( {MediaType.TEXT_PLAIN, MediaType.WILDCARD})
public static class ByteContextResolver implements ContextResolver<byte[]> {
public byte[] getContext(Class<?> type) {
return BYTE;
}
}
@Provider
@Produces( {"text/decimal"})
public static class IntegerContextResolver implements ContextResolver<Integer> {
public Integer getContext(Class<?> type) {
return _12345;
}
}
@Provider
public static class ListContextResolver implements ContextResolver<List<byte[]>> {
public List<byte[]> getContext(Class<?> type) {
return Collections.emptyList();
}
}
private ProvidersRegistry createProvidersRegistryImpl() {
ProvidersRegistry providers =
new ProvidersRegistry(new LifecycleManagersRegistry(), new ApplicationValidator());
;
return providers;
}
public void testContextResolvers() {
ProvidersRegistry providers = createProvidersRegistryImpl();
assertTrue(providers.addProvider(new AtomContextResolver()));
assertTrue(providers.addProvider(new StringContextResolver()));
assertTrue(providers.addProvider(new IntegerContextResolver()));
assertTrue(providers.addProvider(new ByteContextResolver()));
assertTrue(providers.addProvider(new ListContextResolver()));
try {
providers.addProvider(new NotAProvider());
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
/*
* String and text/pain, should invoke StringContextResolver
*/
assertEquals(STRING, providers.getContextResolver(String.class,
MediaType.TEXT_PLAIN_TYPE,
null).getContext(null));
/*
* byte[] and text/plain, should invoke ByteContextResolver
*/
assertEquals(BYTE, providers.getContextResolver(byte[].class,
MediaType.TEXT_PLAIN_TYPE,
null).getContext(null));
/*
* There is no context resolver that handlers Integer and /
*/
assertEquals(_12345, providers.getContextResolver(Integer.class,
MediaType.WILDCARD_TYPE,
null).getContext(null));
/*
* StringContextResolver is registered after AtomContextResolver,
* therefore it should be invoked
*/
assertEquals(STRING, providers.getContextResolver(String.class,
MediaType.WILDCARD_TYPE,
null).getContext(null));
/*
* AtomContextResolver returns null, if the parameter is not null,
* therefore StringContextResolver should be invoked
*/
assertEquals(STRING, providers.getContextResolver(String.class,
MediaType.WILDCARD_TYPE,
null).getContext(String.class));
/*
* test ContextResolver with collections
*/
assertEquals(Collections.emptyList(), providers.getContextResolver(List.class,
MediaType.WILDCARD_TYPE,
null).getContext(null));
}
public void testContextResolverWildCards() {
ProvidersRegistry providers = createProvidersRegistryImpl();
assertTrue(providers.addProvider(new MyContextResolver()));
assertTrue(providers.addProvider(new StringContextResolver3()));
/*
* Check various wildcard permutations
*/
assertSame(MYCLASS, providers.getContextResolver(MyClass.class,
MediaType.WILDCARD_TYPE,
null).getContext(MyClass.class));
assertSame(MYCLASS, providers.getContextResolver(MyClass.class,
new MediaType("*", "*"),
null).getContext(MyClass.class));
assertSame(MYCLASS, providers.getContextResolver(MyClass.class,
new MediaType("application", "*"),
null).getContext(MyClass.class));
assertSame(MYCLASS, providers.getContextResolver(MyClass.class,
new MediaType("application",
"x-www-form-urlencoded"),
null).getContext(MyClass.class));
assertSame(MYCLASS, providers
.getContextResolver(MyClass.class, new MediaType("*", "x-www-form-urlencoded"), null)
.getContext(MyClass.class));
// should hit an exact match when search expands out to "text/*"
assertSame(STRING3, providers.getContextResolver(String.class,
new MediaType("text", "blarg"),
null).getContext(String.class));
}
public void testContextResolverSortingAlgorithm() {
ProvidersRegistry providers = createProvidersRegistryImpl();
// note: the order these are added is important to the test
assertTrue(providers.addProvider(new StringContextResolver4()));
assertTrue(providers.addProvider(new StringContextResolver3()));
assertTrue(providers.addProvider(new StringContextResolver2()));
// StringContextResolver2 takes priority over the others due to the
// media type in @Produces
assertSame(STRING2, providers.getContextResolver(String.class,
new MediaType("text", "*"),
null).getContext(String.class));
// StringContextResolver2 takes priority over the others due to the
// media type in @Produces
assertSame(STRING2, providers.getContextResolver(String.class,
new MediaType("*", "*"),
null).getContext(String.class));
// StringContextResolver2 takes priority over the others due to the
// media type in @Produces
assertSame(STRING2, providers.getContextResolver(String.class,
new MediaType("text", "plain"),
null).getContext(String.class));
}
public void testContextResolverNullMediaType() {
ProvidersRegistry providers = createProvidersRegistryImpl();
// note: the order these are added is important to the test
assertTrue(providers.addProvider(new StringContextResolver4()));
assertTrue(providers.addProvider(new StringContextResolver3()));
assertTrue(providers.addProvider(new StringContextResolver2()));
// StringContextResolver2 takes priority over the others due to the
// media type in @Produces
assertSame(STRING2, providers.getContextResolver(String.class, null, null)
.getContext(String.class));
}
public void testContextResolverPrioritySort() {
ProvidersRegistry providers = createProvidersRegistryImpl();
// note: the order these are added is important to the test
assertTrue(providers.addProvider(new StringContextResolver5(), 0.5));
assertTrue(providers.addProvider(new StringContextResolver6(), 0.6));
assertTrue(providers.addProvider(new StringContextResolver7(), 0.4));
// StringContextResolver3 has the highest priority (0.2) even though
// StringContextResolver2
// more closely matches based on the media type in @Produces
assertSame(STRING6, providers.getContextResolver(String.class, null, null)
.getContext(String.class));
}
}