Skip to content

Commit

Permalink
Merge 726286b into ccc3a06
Browse files Browse the repository at this point in the history
  • Loading branch information
remmeier committed Mar 13, 2019
2 parents ccc3a06 + 726286b commit 59da9c9
Show file tree
Hide file tree
Showing 21 changed files with 610 additions and 51 deletions.
47 changes: 31 additions & 16 deletions crnk-client/src/main/java/io/crnk/client/CrnkClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package io.crnk.client;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import io.crnk.client.action.ActionStubFactory;
Expand Down Expand Up @@ -79,16 +89,6 @@
import io.crnk.legacy.registry.RepositoryInstanceBuilder;
import io.crnk.legacy.repository.RelationshipRepository;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
* Client implementation giving access to JSON API repositories using stubs.
*/
Expand Down Expand Up @@ -361,9 +361,24 @@ private void initExceptionMapperRegistry() {
exceptionMapperRegistry = new ExceptionMapperRegistryBuilder().build(exceptionMapperLookup);
}

@SuppressWarnings({"rawtypes", "unchecked"})
@SuppressWarnings({ "rawtypes", "unchecked" })
private <T, I extends Serializable> RegistryEntry allocateRepository(Class<T> resourceClass, RegistryEntry parentEntry) {
RegistryEntry entry = resourceRegistry.getEntry(resourceClass);
if (entry != null) {
return entry;
}

// allocate super types first
ResourceInformationProvider resourceInformationProvider = moduleRegistry.getResourceInformationBuilder();
Class<? super T> superclass = resourceClass.getSuperclass();
if (parentEntry == null && superclass != null && superclass != Object.class && resourceInformationProvider.accept(superclass)) {
parentEntry = allocateRepository(superclass, null);
}

entry = resourceRegistry.getEntry(resourceClass);
if (entry != null) {
return entry;
}

ResourceInformation resourceInformation = resourceInformationProvider.build(resourceClass);
final ClientStubBase repositoryStub = new ResourceRepositoryStubImpl<T, I>(this, resourceClass, resourceInformation, urlBuilder);
Expand Down Expand Up @@ -398,7 +413,7 @@ public Object buildRepository() {
return registryEntry;
}

@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
private void allocateRepositoryRelations(RegistryEntry registryEntry) {
ResourceInformation resourceInformation = registryEntry.getResourceInformation();
List<ResourceField> relationshipFields = resourceInformation.getRelationshipFields();
Expand Down Expand Up @@ -471,15 +486,15 @@ public String getTargetResourceType() {
ClassLoader classLoader = repositoryInterfaceClass.getClassLoader();
InvocationHandler invocationHandler =
new ClientStubInvocationHandler(repositoryInterfaceClass, repositoryStub, actionStub);
return (R) Proxy.newProxyInstance(classLoader, new Class[]{repositoryInterfaceClass, ResourceRepositoryV2.class},
return (R) Proxy.newProxyInstance(classLoader, new Class[] { repositoryInterfaceClass, ResourceRepositoryV2.class },
invocationHandler);
}

/**
* @param resourceClass repository class
* @return stub for the given resourceClass
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T, I extends Serializable> ResourceRepositoryV2<T, I> getRepositoryForType(Class<T> resourceClass) {
init();

Expand Down Expand Up @@ -511,7 +526,7 @@ public ResourceRepositoryV2<Resource, String> getRepositoryForPath(String resour
* Generic access using {@link Resource} class without type mapping.
*/
public RelationshipRepositoryV2<Resource, String, Resource, String> getRepositoryForPath(String sourceResourceType,
String targetResourceType) {
String targetResourceType) {
init();

ResourceInformation sourceResourceInformation =
Expand All @@ -526,7 +541,7 @@ public RelationshipRepositoryV2<Resource, String, Resource, String> getRepositor
* @return stub for the relationship between the given source and target
* class
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T, I extends Serializable, D, J extends Serializable> RelationshipRepositoryV2<T, I, D, J> getRepositoryForType(
Class<T> sourceClass, Class<D> targetClass) {
init();
Expand Down
11 changes: 5 additions & 6 deletions crnk-client/src/test/java/io/crnk/client/AbstractClientTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.crnk.client;

import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.MultivaluedMap;

import io.crnk.client.action.JerseyActionStubFactory;
import io.crnk.core.boot.CrnkProperties;
import io.crnk.rs.CrnkFeature;
Expand All @@ -17,11 +22,6 @@
import org.junit.Assert;
import org.junit.Before;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.MultivaluedMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

public abstract class AbstractClientTest extends JerseyTestBase {

public CrnkClient client;
Expand Down Expand Up @@ -65,7 +65,6 @@ protected TestApplication configure() {
if (testApplication == null) {
testApplication = new TestApplication();
}

return testApplication;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.crnk.client.inheritance;

import io.crnk.client.AbstractClientTest;
import io.crnk.client.inheritance.repositories.cyclic.CyclicResourceARepository;
import io.crnk.client.inheritance.repositories.cyclic.CyclicResourceBRespository;
import io.crnk.client.inheritance.repositories.cyclic.CyclicResourceCRepository;
import io.crnk.client.inheritance.repositories.related.RelatedResourceARepository;
import io.crnk.client.inheritance.repositories.related.RelatedResourceBRepository;
import io.crnk.client.inheritance.resources.cyclic.CyclicResourceA;
import io.crnk.client.inheritance.resources.related.RelatedResourceA;
import io.crnk.client.inheritance.resources.related.RelatedResourceAsub1;
import io.crnk.core.module.SimpleModule;
import io.crnk.core.queryspec.QuerySpec;
import org.junit.Assert;
import org.junit.Test;

/**
* Examples makes use of Inheritance of resources that share a common resource path. Make sure it correctly handles
* multiple resources with same path and able to find fields on subtypes.
*
* @author syri.
*/
public class SamePathInheritanceClientTest extends AbstractClientTest {


@Override
protected TestApplication configure() {
TestApplication app = super.configure();
SimpleModule cyclicModule = new SimpleModule("crnk-test");
cyclicModule.addRepository(new CyclicResourceARepository());
cyclicModule.addRepository(new CyclicResourceBRespository());
cyclicModule.addRepository(new CyclicResourceCRepository());
cyclicModule.addRepository(new RelatedResourceARepository());
cyclicModule.addRepository(new RelatedResourceBRepository());
app.getFeature().addModule(cyclicModule);
return app;
}

@Test
public void testInheritedRelation() {
QuerySpec querySpec = new QuerySpec(RelatedResourceA.class);
RelatedResourceA resource = client.getRepositoryForType(RelatedResourceA.class).findOne(1L, querySpec);
RelatedResourceAsub1 subResource = (RelatedResourceAsub1) resource;
Assert.assertEquals(1, subResource.getRelatedResourceBS().size());
}

@Test
public void testCyclicRelationsRepository() {
// Crash
client.getRepositoryForType(CyclicResourceA.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.crnk.client.inheritance.repositories;

import java.util.Collections;
import java.util.List;

import io.crnk.client.inheritance.resources.related.RelatedResourceA;
import io.crnk.client.inheritance.resources.related.RelatedResourceAsub1;
import io.crnk.client.inheritance.resources.related.RelatedResourceB;

/*
* @author syri.
*/
public class RepositoryData {

public static final List<RelatedResourceA> RESOURCE_A_LIST;

public static final List<RelatedResourceB> RESOURCE_B_LIST;

static {
RelatedResourceAsub1 relatedResourceAsub1 = new RelatedResourceAsub1();
relatedResourceAsub1.setId(1L);

RelatedResourceB relatedResourceB = new RelatedResourceB();
relatedResourceB.setId(10L);

relatedResourceAsub1.setRelatedResourceBS(Collections.singletonList(relatedResourceB));
relatedResourceB.setRelatedResourceAsub1(relatedResourceAsub1);

RESOURCE_A_LIST = Collections.singletonList(relatedResourceAsub1);
RESOURCE_B_LIST = Collections.singletonList(relatedResourceB);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.crnk.client.inheritance.repositories.cyclic;

import java.util.Collections;

import io.crnk.client.inheritance.resources.cyclic.CyclicResourceA;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;

/*
* @author syri.
*/
public class CyclicResourceARepository extends ResourceRepositoryBase<CyclicResourceA, Long> {

public CyclicResourceARepository() {
super(CyclicResourceA.class);
}

@Override
public ResourceList<CyclicResourceA> findAll(QuerySpec querySpec) {
return querySpec.apply(Collections.emptyList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.crnk.client.inheritance.repositories.cyclic;

import java.util.Collections;

import io.crnk.client.inheritance.resources.cyclic.CyclicResourceB;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;

/*
* @author syri.
*/
public class CyclicResourceBRespository extends ResourceRepositoryBase<CyclicResourceB, Long> {

public CyclicResourceBRespository() {
super(CyclicResourceB.class);
}

@Override
public ResourceList<CyclicResourceB> findAll(QuerySpec querySpec) {
return querySpec.apply(Collections.emptyList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.crnk.client.inheritance.repositories.cyclic;

import java.util.Collections;

import io.crnk.client.inheritance.resources.cyclic.CyclicResourceC;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;

/*
* @author syri.
*/
public class CyclicResourceCRepository extends ResourceRepositoryBase<CyclicResourceC, Long> {

public CyclicResourceCRepository() {
super(CyclicResourceC.class);
}

@Override
public ResourceList<CyclicResourceC> findAll(QuerySpec querySpec) {
return querySpec.apply(Collections.emptyList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.crnk.client.inheritance.repositories.related;

import io.crnk.client.inheritance.repositories.RepositoryData;
import io.crnk.client.inheritance.resources.related.RelatedResourceA;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;

/*
* @author syri.
*/
public class RelatedResourceARepository extends ResourceRepositoryBase<RelatedResourceA, Long> {

public RelatedResourceARepository() {
super(RelatedResourceA.class);
}

@Override
public ResourceList<RelatedResourceA> findAll(QuerySpec querySpec) {
return querySpec.apply(RepositoryData.RESOURCE_A_LIST);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.crnk.client.inheritance.repositories.related;

import io.crnk.client.inheritance.repositories.RepositoryData;
import io.crnk.client.inheritance.resources.related.RelatedResourceB;
import io.crnk.core.queryspec.QuerySpec;
import io.crnk.core.repository.ResourceRepositoryBase;
import io.crnk.core.resource.list.ResourceList;

/*
* @author syri.
*/
public class RelatedResourceBRepository extends ResourceRepositoryBase<RelatedResourceB, Long> {

public RelatedResourceBRepository() {
super(RelatedResourceB.class);
}

@Override
public ResourceList<RelatedResourceB> findAll(QuerySpec querySpec) {
return querySpec.apply(RepositoryData.RESOURCE_B_LIST);
}
}

0 comments on commit 59da9c9

Please sign in to comment.