Skip to content
This repository has been archived by the owner on Oct 12, 2021. It is now read-only.

Commit

Permalink
Allow setters to have a different collection raw type (#33)
Browse files Browse the repository at this point in the history
* Allow setters to have a different collection raw type

Change-Id: I403febc863bb145b3ee71b5032889f3aded47504
Signed-off-by: Andrew Berezovskyi <andriib@kth.se>
  • Loading branch information
berezovskyi authored and jadelkhoury committed Sep 5, 2018
1 parent b22a910 commit 517e22c
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 7 deletions.
5 changes: 5 additions & 0 deletions org.eclipse.lyo.oslc4j.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.ws.rs.core.UriBuilder;
import org.eclipse.lyo.oslc4j.core.annotation.OslcAllowedValue;
import org.eclipse.lyo.oslc4j.core.annotation.OslcAllowedValues;
Expand Down Expand Up @@ -60,6 +62,7 @@
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreInvalidValueTypeException;
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreMissingAnnotationException;
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreMissingSetMethodException;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class ResourceShapeFactory {
protected static final String METHOD_NAME_START_GET = "get";
Expand Down Expand Up @@ -362,7 +365,7 @@ protected static Class<?> getComponentType(final Class<?> resourceClass, final M
}
}

protected static void validateSetMethodExists(final Class<?> resourceClass, final Method getMethod) throws OslcCoreMissingSetMethodException {
static void validateSetMethodExists(final Class<?> resourceClass, final Method getMethod) throws OslcCoreMissingSetMethodException {
final String getMethodName = getMethod.getName();

final String setMethodName;
Expand All @@ -372,14 +375,50 @@ protected static void validateSetMethodExists(final Class<?> resourceClass, fina
setMethodName = METHOD_NAME_START_SET + getMethodName.substring(METHOD_NAME_START_IS_LENGTH);
}

try {
resourceClass.getMethod(setMethodName, getMethod.getReturnType());
} catch (final NoSuchMethodException exception) {
throw new OslcCoreMissingSetMethodException(resourceClass, getMethod, exception);
}
final Class<?> returnType = getMethod.getReturnType();
if(!isCollectionType(returnType)) {
try {
resourceClass.getMethod(setMethodName, returnType);
} catch (final NoSuchMethodException exception) {
throw new OslcCoreMissingSetMethodException(resourceClass, getMethod, exception);
}
} else {
final List<Method> methods = Arrays.stream(resourceClass.getMethods())
.filter(m -> m.getName().equals(setMethodName))
.collect(Collectors.toList());
if (methods.size() == 0) {
throw new OslcCoreMissingSetMethodException(resourceClass, getMethod, null);
}

if (methods.size() > 1) {
throw new IllegalArgumentException(
"Multiple setters on the same RDF property are not yet supported");
}

final Method method = methods.get(0);

final Type[] parameterTypes = method.getGenericParameterTypes();
if (parameterTypes == null || parameterTypes.length == 0 || parameterTypes.length > 1) {
throw new IllegalArgumentException(
String.format("Method '%s' shall have exactly one argument",
method.getName()
));
}

final ParameterizedType setterArgumentType = (ParameterizedType) parameterTypes[0];
final ParameterizedType genericReturnType = (ParameterizedType) getMethod.getGenericReturnType();
if (!genericReturnType.getActualTypeArguments()[0].equals(setterArgumentType.getActualTypeArguments()[0])) {
// if a getter returns HashSet<T>, we want the same t in the setter Set<T>
throw new OslcCoreMissingSetMethodException(resourceClass, getMethod, null);
}
}
}

private static void validateUserSpecifiedOccurs(final Class<?> resourceClass, final Method method, final OslcOccurs occursAnnotation) throws OslcCoreInvalidOccursException {
static boolean isCollectionType(final Class<?> returnType) {
return Collection.class.isAssignableFrom(returnType);
}

private static void validateUserSpecifiedOccurs(final Class<?> resourceClass, final Method method, final OslcOccurs occursAnnotation) throws OslcCoreInvalidOccursException {
final Class<?> returnType = method.getReturnType();
final Occurs occurs = occursAnnotation.value();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.eclipse.lyo.oslc4j.core.model;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreMissingSetMethodException;
import org.junit.Test;

import static org.junit.Assert.*;
import static org.assertj.core.api.Assertions.*;

/**
* @version $version-stub$
* @since 2.4.0
*/
public class ResourceShapeFactoryTest {

@Test
public void detectCollectionType() throws NoSuchMethodException {
final boolean isCollectionType = ResourceShapeFactory.isCollectionType(
Dummy.class.getMethod("getValue").getReturnType());

assertThat(isCollectionType).isTrue();
}

@Test
public void detectNonCollectionType() throws NoSuchMethodException {
final boolean isCollectionType = ResourceShapeFactory.isCollectionType(
Dummy.class.getMethod("getValue2").getReturnType());

assertThat(isCollectionType).isFalse();
}

@Test
public void findSetterNonCollection()
throws NoSuchMethodException, OslcCoreMissingSetMethodException {
ResourceShapeFactory.validateSetMethodExists(Dummy.class, Dummy.class.getMethod("getValue2"));
}

@Test
public void findSetterCollection()
throws NoSuchMethodException, OslcCoreMissingSetMethodException {
ResourceShapeFactory.validateSetMethodExists(Dummy.class, Dummy.class.getMethod("getValue"));
}

@Test(expected = OslcCoreMissingSetMethodException.class)
public void findSetterCollectionMismachGenType()
throws NoSuchMethodException, OslcCoreMissingSetMethodException {
ResourceShapeFactory.validateSetMethodExists(Dummy.class, Dummy.class.getMethod("getValueDifferent"));
}

interface Dummy {
public ArrayList<BigDecimal> getValue();

public void setValue(HashSet<BigDecimal> ds);

public ArrayList<BigDecimal> getValueDifferent();

public void setValueDifferent(HashSet<Integer> ds);

public BigDecimal getValue2();

public void setValue2(BigDecimal d);
}
}

0 comments on commit 517e22c

Please sign in to comment.