Skip to content

Commit

Permalink
Enhancement: added CompositeKey to implement composite/synthetic prim…
Browse files Browse the repository at this point in the history
…ary keys
  • Loading branch information
TikhomirovSergey committed Sep 6, 2018
1 parent 7cf1d40 commit 9e6e6c2
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 61 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ subprojects {
apply plugin: 'maven-publish'

group 'ru.tinkoff.qa.neptune'
version '0.1.8-ALPHA'
version '0.1.9-ALPHA'

sourceCompatibility = 1.9
targetCompatibility = 1.9
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package ru.tinkoff.qa.neptune.data.base.api;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.reflect.Modifier.isStatic;
import static java.util.Arrays.stream;

/**
* This class is designed to implement classes of composite key objects.
* It is supposed to be used at the case below
* {@code @PersistenceCapable(table = "TABLE_NAME", objectIdClass = CompositeKeySubclass.class)}
*
* WARNING: it is necessary to override following methods:
* <p>{@link #hashCode()}</p>
* <p>{@link #equals(Object)}</p>
* <p>{@link #toString()}</p>
*
* It is enough
* <p>
* {@code 'public int hashCode() {
* return super.hashCode();
* }'}
* </p>
*/
public abstract class CompositeKey extends OrmObject implements Serializable {

@Override
public int hashCode() {
int result = 0;
Class<?> clazz = this.getClass();
while (!clazz.equals(Object.class)) {
List<Field> fields = stream(clazz.getDeclaredFields()).filter(field -> !isStatic(field.getModifiers()))
.collect(Collectors.toList());
for (Field f : fields) {
f.setAccessible(true);
try {
Object v = f.get(this);
if (v == null) {
continue;
}
result = result ^ v.hashCode();
}
catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
clazz = clazz.getSuperclass();
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package ru.tinkoff.qa.neptune.data.base.api;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.reflect.Modifier.isStatic;
import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable;

class OrmObject {

private boolean equalsByFields(Object obj) {
Class<?> clazz = this.getClass();
while (!clazz.equals(Object.class)) {
List<Field> fields = stream(clazz.getDeclaredFields()).filter(field -> !isStatic(field.getModifiers()))
.collect(Collectors.toList());
for (Field f: fields) {
f.setAccessible(true);
try {
Object v1 = f.get(this);
Object v2 = f.get(obj);

if (v1 == null && v2 == null) {
continue;
}

if ((v1 != null && v2 == null) || (v1 == null && v2 != null)) {
return false;
}

if (v1.equals(v2)) {
continue;
}

return false;
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
clazz = clazz.getSuperclass();
}

return true;
}

@Override
public boolean equals(Object obj) {
OrmObject toCheck = this;
return ofNullable(obj)
.map(o -> {
if (toCheck == o) {
return true;
}
return toCheck.getClass().equals(obj.getClass()) &&
toCheck.equalsByFields(obj);
})
.orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,10 @@

import com.google.gson.Gson;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

import static java.lang.reflect.Modifier.isStatic;
import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable;

/**
* This abstract class is designed to mark persistable classes.
*/
public abstract class PersistableObject implements Cloneable {

private boolean equalsByFields(Object obj) {
Class<?> clazz = this.getClass();
while (!clazz.equals(PersistableObject.class)) {
List<Field> fields = stream(clazz.getDeclaredFields()).filter(field -> !isStatic(field.getModifiers()))
.collect(Collectors.toList());
for (Field f: fields) {
f.setAccessible(true);
try {
Object v1 = f.get(this);
Object v2 = f.get(obj);

if (v1 == null && v2 == null) {
continue;
}

if ((v1 != null && v2 == null) || (v1 == null && v2 != null)) {
return false;
}

if (v1.equals(v2)) {
continue;
}

return false;
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
clazz = clazz.getSuperclass();
}

return true;
}

@Override
public boolean equals(Object obj) {
PersistableObject toCheck = this;
return ofNullable(obj)
.map(o -> {
if (toCheck == o) {
return true;
}
else if (!PersistableObject.class.isAssignableFrom(obj.getClass())) {
return false;
}
return toCheck.getClass().equals(obj.getClass()) &&
toCheck.equalsByFields(obj);
})
.orElse(false);
}
public abstract class PersistableObject extends OrmObject implements Cloneable {

@Override
public String toString() {
Expand Down

0 comments on commit 9e6e6c2

Please sign in to comment.