2020-04-01 18:44:35 +02:00
|
|
|
package eu.dnetlib.dhp.actionmanager.promote;
|
|
|
|
|
2020-04-07 11:56:22 +02:00
|
|
|
import eu.dnetlib.dhp.common.FunctionalInterfaceSupport.SerializableSupplier;
|
2020-04-01 18:44:35 +02:00
|
|
|
import eu.dnetlib.dhp.schema.oaf.Oaf;
|
|
|
|
import eu.dnetlib.dhp.schema.oaf.OafEntity;
|
|
|
|
import eu.dnetlib.dhp.schema.oaf.Relation;
|
|
|
|
|
|
|
|
import java.util.function.BiFunction;
|
|
|
|
|
2020-04-07 11:56:22 +02:00
|
|
|
import static eu.dnetlib.dhp.schema.common.ModelSupport.isSubClass;
|
2020-04-01 18:44:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* OAF model merging support.
|
|
|
|
*/
|
|
|
|
public class MergeAndGet {
|
|
|
|
|
|
|
|
private MergeAndGet() {
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Strategy for merging OAF model objects.
|
|
|
|
* <p>
|
|
|
|
* MERGE_FROM_AND_GET: use OAF 'mergeFrom' method
|
|
|
|
* SELECT_NEWER_AND_GET: use last update timestamp to return newer instance
|
|
|
|
*/
|
|
|
|
public enum Strategy {
|
|
|
|
MERGE_FROM_AND_GET, SELECT_NEWER_AND_GET
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a function for merging OAF model objects.
|
|
|
|
*
|
|
|
|
* @param strategy Strategy to be used to merge objects
|
|
|
|
* @param <G> Graph table type
|
|
|
|
* @param <A> Action payload type
|
|
|
|
* @return BiFunction to be used to merge OAF objects
|
|
|
|
*/
|
|
|
|
public static <G extends Oaf, A extends Oaf> SerializableSupplier<BiFunction<G, A, G>> functionFor(Strategy strategy) {
|
|
|
|
switch (strategy) {
|
|
|
|
case MERGE_FROM_AND_GET:
|
|
|
|
return () -> MergeAndGet::mergeFromAndGet;
|
|
|
|
case SELECT_NEWER_AND_GET:
|
|
|
|
return () -> MergeAndGet::selectNewerAndGet;
|
|
|
|
}
|
|
|
|
throw new RuntimeException();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static <G extends Oaf, A extends Oaf> G mergeFromAndGet(G x, A y) {
|
|
|
|
if (isSubClass(x, Relation.class) && isSubClass(y, Relation.class)) {
|
|
|
|
((Relation) x).mergeFrom((Relation) y);
|
|
|
|
return x;
|
|
|
|
} else if (isSubClass(x, OafEntity.class) && isSubClass(y, OafEntity.class) && isSubClass(x, y)) {
|
|
|
|
((OafEntity) x).mergeFrom((OafEntity) y);
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
throw new RuntimeException(String.format("MERGE_FROM_AND_GET incompatible types: %s, %s",
|
|
|
|
x.getClass().getCanonicalName(), y.getClass().getCanonicalName()));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static <G extends Oaf, A extends Oaf> G selectNewerAndGet(G x, A y) {
|
|
|
|
if (x.getClass().equals(y.getClass()) && x.getLastupdatetimestamp() > y.getLastupdatetimestamp()) {
|
|
|
|
return x;
|
|
|
|
} else if (x.getClass().equals(y.getClass()) && x.getLastupdatetimestamp() < y.getLastupdatetimestamp()) {
|
|
|
|
return (G) y;
|
|
|
|
} else if (isSubClass(x, y) && x.getLastupdatetimestamp() > y.getLastupdatetimestamp()) {
|
|
|
|
return x;
|
|
|
|
} else if (isSubClass(x, y) && x.getLastupdatetimestamp() < y.getLastupdatetimestamp()) {
|
|
|
|
throw new RuntimeException(String.format("SELECT_NEWER_AND_GET cannot return right type when it is not the same as left type: %s, %s",
|
|
|
|
x.getClass().getCanonicalName(), y.getClass().getCanonicalName()));
|
|
|
|
}
|
|
|
|
throw new RuntimeException(String.format("SELECT_NEWER_AND_GET cannot be used when left is not subtype of right: %s, %s",
|
|
|
|
x.getClass().getCanonicalName(), y.getClass().getCanonicalName()));
|
|
|
|
}
|
|
|
|
}
|