Skip to content

Commit

Permalink
code for settings
Browse files Browse the repository at this point in the history
  • Loading branch information
sangupta committed Sep 21, 2022
1 parent 1d5439d commit 7d5a698
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/main/java/com/sangupta/jerry/settings/ConflictResolution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.sangupta.jerry.settings;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ConflictResolution {

public ConflictResolutionPolicy policy();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.sangupta.jerry.settings;

public enum ConflictResolutionPolicy {

BLIND_COPY, // for everything

MIN, // for numbers

MAX, // for numbers

GREATER_THAN, // for comparable

LESS_THAN, // for comparable

NON_ZERO, // for numbers

NON_NULL, // for objects

NON_NEGATIVE, // for numbers

NON_EMPTY, // for strings

UNION, // for collection

INTERSECTION // for collection

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sangupta.jerry.settings;

public interface MergeComparable {

public int compareForMerge(MergeComparable other);

}
94 changes: 94 additions & 0 deletions src/main/java/com/sangupta/jerry/settings/ObjectMerge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.sangupta.jerry.settings;

import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.List;

import com.sangupta.jerry.util.AssertUtils;
import com.sangupta.jerry.util.ReflectionUtils;

public class ObjectMerge {

public static <T> T merge(Class<T> classOfT, T instance, List<T> settings) throws InstantiationException, IllegalAccessException {
if(AssertUtils.isEmpty(settings)) {
return instance;
}

// check if we can sort this list or not
if(MergeComparable.class.isAssignableFrom(classOfT)) {
// sort settings list
settings.sort(new Comparator<T>() {

@Override
public int compare(T o1, T o2) {
MergeComparable p1 = (MergeComparable) o1;
MergeComparable p2 = (MergeComparable) o2;
return p1.compareForMerge(p2);
}

});
}

// now start copying fields
List<Field> fields = ReflectionUtils.getAllFields(classOfT);
for(Field field : fields) {
// for each field, find the value in each object
for(T setting : settings) {
copyFieldIfApplicable(field, instance, setting);
}
}


return instance;
}

private static <T> void copyFieldIfApplicable(Field field, T destination, T source) throws IllegalArgumentException, IllegalAccessException {
Class<?> type = field.getType();

// set accessible so that we can work with private fields
field.setAccessible(true);

// obtain current source value
Object srcValue = field.get(source);

ConflictResolution resolution = field.getAnnotation(ConflictResolution.class);
ConflictResolutionPolicy policy = resolution.policy();

switch (policy) {
case BLIND_COPY:
field.set(destination, srcValue);
return;

case INTERSECTION:
break;

case MAX:
break;

case MIN:
break;

case NON_ZERO:
if(ReflectionUtils.isFieldNumber(type)) {
if(ReflectionUtils.isEqualNumber(srcValue, 0)) {

}
}
break;

case NON_NULL:
if(srcValue != null) {
field.set(destination, srcValue);
}
return;

case UNION:
break;

default:
throw new RuntimeException("Unknown conflict resolution policy");

}
}

}
9 changes: 9 additions & 0 deletions src/main/java/com/sangupta/jerry/util/ReflectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1369,4 +1369,13 @@ public static void populateAllFields(Class<?> clazz, List<Field> fields) {

populateAllFields(clazz.getSuperclass(), fields);
}

public static boolean isFieldNumber(Class<?> type) {
return true;
}

public static boolean isEqualNumber(Object srcValue, int i) {
return false;
}

}
102 changes: 102 additions & 0 deletions src/test/java/com/sangupta/jerry/settings/TestObjectMerge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.sangupta.jerry.settings;

import java.util.ArrayList;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

public class TestObjectMerge {

@Test
public void test() throws InstantiationException, IllegalAccessException {
TestSettingsObject highest = new TestSettingsObject(100);
highest.x1 = 100;
highest.x2 = 100;
highest.x3 = 100;
highest.x4 = 100;
highest.x5 = 100;
highest.x6 = 100;
highest.x7 = true;

TestSettingsObject medium = new TestSettingsObject(50);
medium.x1 = 50;
medium.x2 = 50;
medium.x3 = 50;
medium.x4 = 50;
medium.x5 = 50;
medium.x6 = 50;
medium.x7 = false;

TestSettingsObject lowest = new TestSettingsObject(10);
lowest.x1 = 500;
lowest.x2 = 500;
lowest.x3 = 500;
lowest.x4 = 5;
lowest.x5 = 500;
lowest.x6 = 500;
lowest.x7 = false;

// where everything is copied
TestSettingsObject destination = new TestSettingsObject(0);

List<TestSettingsObject> list = new ArrayList<>();
list.add(lowest);
list.add(highest);
list.add(medium);

ObjectMerge.merge(TestSettingsObject.class, destination, list);

Assert.assertEquals(100, destination.x1);
Assert.assertEquals(100, destination.x2);
Assert.assertEquals(100, destination.x3);
Assert.assertEquals(100, destination.x4);
Assert.assertEquals(100, destination.x5, 0.01f);
Assert.assertEquals(100, destination.x6, 0.01d);
Assert.assertTrue(destination.x7);

}

private static class TestSettingsObject implements MergeComparable {

final int weight;

TestSettingsObject(int weight) {
this.weight = weight;
}

@ConflictResolution(policy = ConflictResolutionPolicy.MIN)
int x1;

@ConflictResolution(policy = ConflictResolutionPolicy.MAX)
long x2;

@ConflictResolution(policy = ConflictResolutionPolicy.BLIND_COPY)
char x3;

@ConflictResolution(policy = ConflictResolutionPolicy.NON_ZERO)
byte x4;

float x5;

double x6;

boolean x7;

@Override
public int compareForMerge(MergeComparable other) {
if (!(other instanceof TestSettingsObject)) {
throw new RuntimeException("Invalid object to compare");
}

TestSettingsObject tso = (TestSettingsObject) other;
return Integer.compare(this.weight, tso.weight);
}

@Override
public String toString() {
return "Priority: " + this.weight;
}

}
}

0 comments on commit 7d5a698

Please sign in to comment.