Skip to content

Commit

Permalink
[RESTEASY-1865] ported proposed code changes to branch (#2625)
Browse files Browse the repository at this point in the history
  • Loading branch information
rsearls committed Dec 7, 2020
1 parent 771f2c6 commit 685132a
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 39 deletions.
Expand Up @@ -281,6 +281,10 @@ protected void register(ResourceFactory rf, String base, ResourceClass resourceC
{
processMethod(rf, base, method);
}

if (rf instanceof SingletonResource) {
providerFactory.registerSingletonResource((SingletonResource) rf);
}
}

/**
Expand Down
Expand Up @@ -36,8 +36,7 @@ public void registered(ResteasyProviderFactory factory)
factory.getInjectorFactory().createPropertyInjector(resourceClass, factory).inject(obj);
}

public Object createResource(HttpRequest request, HttpResponse response, ResteasyProviderFactory factory)
{
public Object createResource(HttpRequest request, HttpResponse response, ResteasyProviderFactory factory) {
return obj;
}

Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.jboss.resteasy.plugins.delegates.NewCookieHeaderDelegate;
import org.jboss.resteasy.plugins.delegates.UriHeaderDelegate;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.plugins.server.resourcefactory.SingletonResource;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.specimpl.LinkBuilderImpl;
Expand Down Expand Up @@ -108,6 +109,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
Expand Down Expand Up @@ -292,6 +294,9 @@ public interface CloseableContext extends AutoCloseable {
private boolean initialized = false;

protected ResourceBuilder resourceBuilder;
// RESTEASY-1865 resource factories for singleton resources
private Map<Class<?>, SingletonResource> singletonResourceFactories;

private StatisticsControllerImpl statisticsController = new StatisticsControllerImpl();

public ResteasyProviderFactory()
Expand Down Expand Up @@ -400,6 +405,7 @@ protected void initialize(ResteasyProviderFactory parent)
builtinsRegistered = false;
registerBuiltins = true;

singletonResourceFactories = new HashMap<>();
injectorFactory = parent == null ? new InjectorFactoryImpl() : parent.getInjectorFactory();
registerDefaultInterceptorPrecedences();
addHeaderDelegateIfAbsent(MediaType.class, new MediaTypeHeaderDelegate());
Expand Down Expand Up @@ -2859,6 +2865,16 @@ public <T> T injectedInstance(Class<? extends T> clazz)
return (T) obj;
}

public void registerSingletonResource(SingletonResource resource)
{
singletonResourceFactories.put(resource.getScannableClass(), resource);
}

private <T> boolean isSingletonResource(Class<T> resourceClass)
{
return singletonResourceFactories.containsKey(resourceClass);
}

/**
* Property and constructor injection using the InjectorFactory.
*
Expand All @@ -2868,68 +2884,55 @@ public <T> T injectedInstance(Class<? extends T> clazz)
* @param <T> type
* @return instance of type T
*/
public <T> T injectedInstance(Class<? extends T> clazz, HttpRequest request, HttpResponse response)
{
Constructor<?> constructor = PickConstructor.pickSingletonConstructor(clazz);
public <T> T injectedInstance(Class<? extends T> clazz, HttpRequest request, HttpResponse response) {
Object obj = null;
if (constructor == null)

if (isSingletonResource(clazz))
{
SingletonResource factory = singletonResourceFactories.get(clazz);
obj = CompletableFuture.completedFuture(factory.createResource(request, response, this)).toCompletableFuture().getNow(null);
}
else
{
Constructor<?> constructor = PickConstructor.pickSingletonConstructor(clazz);

if (constructor == null) {
// TODO this is solely to pass the TCK. This is WRONG WRONG WRONG! I'm challenging.
if (false)//if (clazz.isAnonymousClass())
{
constructor = clazz.getDeclaredConstructors()[0];
constructor.setAccessible(true);
if (!Modifier.isStatic(clazz.getModifiers()))
{
if (!Modifier.isStatic(clazz.getModifiers())) {
Object[] args = {null};
try
{
try {
obj = constructor.newInstance(args);
}
catch (InstantiationException e)
{
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
else
{
try
{
} else {
try {
obj = constructor.newInstance();
}
catch (InstantiationException e)
{
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
else
{
} else {
throw new IllegalArgumentException(Messages.MESSAGES.unableToFindPublicConstructorForClass(clazz.getName()));
}
}
else
{
} else {
ConstructorInjector constructorInjector = getInjectorFactory().createConstructor(constructor, this);
obj = constructorInjector.construct(request, response);

}
}
PropertyInjector propertyInjector = getInjectorFactory().createPropertyInjector(clazz, this);

propertyInjector.inject(request, response, obj);
Expand Down
@@ -0,0 +1,87 @@
package org.jboss.resteasy.test.core;

import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.Date;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.ResourceContext;
import javax.ws.rs.core.Context;

import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class DispatcherTest {

private Dispatcher dispatcher;


@Before
public void before() {
dispatcher = MockDispatcherFactory.createDispatcher();
}

// @see https://issues.jboss.org/browse/RESTEASY-1865
@Test
public void testSingletonResource() throws URISyntaxException, UnsupportedEncodingException {
dispatcher.getRegistry().addSingletonResource(new ParentResource());
dispatcher.getRegistry().addSingletonResource(new ChildResource("I'm singleton child"));

MockHttpRequest request = MockHttpRequest.get("/parent");
MockHttpResponse response = new MockHttpResponse();

dispatcher.invoke(request, response);

assertEquals(200, response.getStatus());
assertEquals("I'm singleton child", response.getContentAsString());
}




@Path("/parent")
public static class ParentResource {

@Context
public ResourceContext resourceCtx;


@GET
public String get() {
ChildResource child = resourceCtx.getResource(ChildResource.class);
return child.get();
}

}

@Path("child")
public static class ChildResource {

private final String name;


@SuppressWarnings("unused") // Not used if RESTEASY-1865 is fixed
public ChildResource() {
this.name = "I'm new child created on " + new Date();
}

public ChildResource(final String name) {
this.name = name;
}


@GET
public String get() {
return name;
}

}

}

0 comments on commit 685132a

Please sign in to comment.