Skip to content

Commit

Permalink
Rewrite interface reducer method
Browse files Browse the repository at this point in the history
  • Loading branch information
gaborflorian committed Nov 8, 2023
1 parent 12a034c commit 48f4d8b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import java.util.List;
import java.util.stream.Collectors;

import static hu.blackbelt.structured.map.proxy.util.MapBuilderProxyUtil.getNoDescendantInterfaces;
import static hu.blackbelt.structured.map.proxy.util.MapBuilderProxyUtil.getInterfacesWithNoDescendants;

public final class MapBuilderProxy<B, T> implements InvocationHandler {

Expand All @@ -51,11 +51,11 @@ public static <B, T> Builder<B, T> builder(Class<B> builderClass, Class<T> targe
public static <B, T> Builder<B, T> builder(Class<B> builderClass, T targetInstance) {
if (targetInstance instanceof Proxy) {
List interfacesList = new ArrayList(Arrays.stream(targetInstance.getClass().getInterfaces()).collect(Collectors.toSet()));
getNoDescendantInterfaces(interfacesList, List.of(MapHolder.class, InvocationHandler.class));
if (interfacesList.size() != 1) {
List<Class<?>> interfacesWithNoDescendants = getInterfacesWithNoDescendants(interfacesList, List.of(MapHolder.class, InvocationHandler.class));
if (interfacesWithNoDescendants.size() != 1) {
throw new RuntimeException("Proxy contains more than one interfaces");
}
return new MapBuilderProxy.Builder<B, T>(builderClass, (Class<T>) interfacesList.get(0)).withTargetInstance(targetInstance);
return new MapBuilderProxy.Builder<B, T>(builderClass, (Class<T>) interfacesWithNoDescendants.get(0)).withTargetInstance(targetInstance);
}
return new MapBuilderProxy.Builder<B, T>(builderClass, (Class<T>) targetInstance.getClass()).withTargetInstance(targetInstance);
}
Expand Down Expand Up @@ -136,7 +136,7 @@ private MapBuilderProxy(Object target, String builderMethodPrefix, MapProxyParam
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
if (m.getName().startsWith("build")) {
return internal;
return MapProxy.builder(targetClass).withMap(((MapHolder) internal).$internalMap()).withParams(params).newInstance();
} else {
T newInstance = MapProxy.builder(targetClass).withMap(((MapHolder) internal).$internalMap()).withParams(params).newInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,25 @@ public final class MapBuilderProxyUtil {


// This method removes the interfaces that have a descendant or the excludeInterfaces contains it.
public static void getNoDescendantInterfaces(List<Class<?>> interfacesList, List<Class<?>> excludedInterfaces) {
public static List<Class<?>> getInterfacesWithNoDescendants(List<Class<?>> clazzInterfaces, List<Class<?>> excludedInterfaces) {
List<Class<?>> interfacesWithNoDescendants = new ArrayList<>();
for (Class<?> inter : clazzInterfaces) {
if (!hasDescendants(inter, clazzInterfaces)) {
interfacesWithNoDescendants.add(inter);
}
}
if(excludedInterfaces != null) {
interfacesList.removeAll(excludedInterfaces);
interfacesWithNoDescendants.removeAll(excludedInterfaces);
}
getNoDescendantInterfacesRec(interfacesList);
return interfacesWithNoDescendants;
}

private static void getNoDescendantInterfacesRec(List<Class<?>> interfacesList) {
if (interfacesList.size() >= 2) {
Class<?> aClass = interfacesList.get(0);
Set<Class<?>> removeSet = new HashSet<>();
for (Class<?> inter : interfacesList) {
if (!aClass.equals(inter) && aClass.isAssignableFrom(inter)) {
removeSet.add(aClass);
} else if (!aClass.equals(inter) && inter.isAssignableFrom(aClass)) {
removeSet.add(inter);
}
}
if (!removeSet.isEmpty()) {
interfacesList.removeAll(removeSet);
getNoDescendantInterfacesRec(interfacesList);
private static boolean hasDescendants(Class<?> inter, List<Class<?>> clazzInterfaces) {
for (Class<?> interOther : clazzInterfaces) {
if (!inter.equals(interOther) && inter.isAssignableFrom(interOther)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
import java.util.ArrayList;
import java.util.List;


import static hu.blackbelt.structured.map.proxy.util.MapBuilderProxyUtil.getNoDescendantInterfaces;
import static hu.blackbelt.structured.map.proxy.util.MapBuilderProxyUtil.getInterfacesWithNoDescendants;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand Down Expand Up @@ -64,25 +63,25 @@ public void testInterfaceReducer() {

//Diamond
List<Class<?>> diamondList = new ArrayList<>(List.of(C.class, B.class, D.class, A.class));
getNoDescendantInterfaces(diamondList, null);
List<Class<?>> interfacesWithNoDescendants = getInterfacesWithNoDescendants(diamondList, null);

assertEquals(1, diamondList.size());
assertEquals(D.class, diamondList.get(0));
assertEquals(1, interfacesWithNoDescendants.size());
assertEquals(D.class, interfacesWithNoDescendants.get(0));

// Multi Interfaces
List<Class<?>> multiList = new ArrayList<>(List.of(F.class, B.class, E.class, A.class));
getNoDescendantInterfaces(multiList, null);
assertEquals(1, multiList.size());
assertEquals(F.class, multiList.get(0));
interfacesWithNoDescendants = getInterfacesWithNoDescendants(multiList, null);
assertEquals(1, interfacesWithNoDescendants.size());
assertEquals(F.class, interfacesWithNoDescendants.get(0));

List<Class<?>> interfacesWithNoRelation = new ArrayList<>(List.of(A.class, F.class, B.class, E.class, H.class, G.class));
getNoDescendantInterfaces(interfacesWithNoRelation, null);
assertTrue(1 < interfacesWithNoRelation.size());
interfacesWithNoDescendants = getInterfacesWithNoDescendants(interfacesWithNoRelation, null);
assertTrue(1 < interfacesWithNoDescendants.size());

List<Class<?>> interfacesWithExclude = new ArrayList<>(List.of(F.class, B.class, E.class, A.class, G.class));
getNoDescendantInterfaces(interfacesWithExclude, List.of(G.class));
assertEquals(1, interfacesWithExclude.size());
assertEquals(F.class, multiList.get(0));
interfacesWithNoDescendants = getInterfacesWithNoDescendants(interfacesWithExclude, List.of(G.class));
assertEquals(1, interfacesWithNoDescendants.size());
assertEquals(F.class, interfacesWithNoDescendants.get(0));

}
}

0 comments on commit 48f4d8b

Please sign in to comment.