Skip to content

Commit

Permalink
Add nullable and notnull annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
devjeonghwan committed Jul 29, 2022
1 parent 0ff0146 commit 92c10c2
Show file tree
Hide file tree
Showing 38 changed files with 444 additions and 231 deletions.
5 changes: 0 additions & 5 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 68 additions & 39 deletions src/main/java/com/realtimetech/opack/Opacker.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.realtimetech.opack.value.OpackObject;
import com.realtimetech.opack.value.OpackValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -112,10 +113,10 @@ public enum State {

private final @NotNull TypeBaker typeBaker;

private final @NotNull FastStack<Object> objectStack;
private final @NotNull FastStack<BakedType> typeStack;
private final @NotNull FastStack<OpackValue> valueStack;
private final @NotNull HashSet<Object> overlapSet;
private final @NotNull FastStack<@NotNull Object> objectStack;
private final @NotNull FastStack<@NotNull BakedType> typeStack;
private final @NotNull FastStack<@NotNull OpackValue> valueStack;
private final @NotNull HashSet<@NotNull Object> overlapSet;

private final boolean enableConvertEnumToOrdinal;
private final boolean enableConvertRecursiveDependencyToNull;
Expand All @@ -128,7 +129,7 @@ public enum State {
* @param builder the builder of Opacker
* @throws IllegalStateException if the predefined transformer cannot be instanced
*/
private Opacker(Builder builder) {
private Opacker(@NotNull Builder builder) {
this.typeBaker = new TypeBaker(this);

this.objectStack = new FastStack<>(builder.contextStackInitialSize);
Expand Down Expand Up @@ -157,19 +158,23 @@ private Opacker(Builder builder) {
this.enableConvertRecursiveDependencyToNull = builder.enableConvertRecursiveDependencyToNull;
}

public @NotNull TypeBaker getTypeBaker() {
return this.typeBaker;
}

/**
* Serializes the object to {@link OpackValue OpackValue}.
*
* @param object the object to be serialized
* @return opack value
* @throws SerializeException if a problem occurs during serializing; if this opacker is deserializing
*/
public synchronized OpackValue serialize(Object object) throws SerializeException {
public synchronized OpackValue serialize(@NotNull Object object) throws SerializeException {
if (this.state == State.DESERIALIZE)
throw new SerializeException("Opacker is deserializing.");

int separatorStack = this.objectStack.getSize();
OpackValue value = (OpackValue) this.prepareObjectSerialize(object.getClass(), object.getClass(), object);
OpackValue value = (OpackValue) this.prepareObjectSerialize(object.getClass(), object);

State lastState = this.state;
try {
Expand All @@ -189,22 +194,21 @@ public synchronized OpackValue serialize(Object object) throws SerializeExceptio
/**
* Store information needed for serialization in stacks.
*
* @param baseType the class of object to be serialized
* @param originalType the class of original object
* @param object the object to be serialized
* @param baseType the class of object to be serialized
* @param object the object to be serialized
* @return prepared opack value
* @throws SerializeException if a problem occurs during serializing; if the baseType cannot be baked into {@link BakedType BakedType}
*/
private Object prepareObjectSerialize(Class<?> baseType, Class<?> originalType, Object object) throws SerializeException {
if (baseType == null || originalType == null || object == null) {
return null;
}

private @Nullable Object prepareObjectSerialize(@NotNull Class<?> baseType, @NotNull Object object) throws SerializeException {
try {
BakedType bakedType = this.typeBaker.get(baseType);

for (Transformer transformer : bakedType.getTransformers()) {
object = transformer.serialize(this, object);

if (object == null) {
return null;
}
}

Class<?> objectType = object.getClass();
Expand All @@ -216,10 +220,8 @@ private Object prepareObjectSerialize(Class<?> baseType, Class<?> originalType,
/*
If directly pass opack value, deep clone
*/
if (OpackValue.class.isAssignableFrom(originalType)) {
if (object instanceof OpackValue) {
object = ((OpackValue) object).clone();
}
if (object instanceof OpackValue) {
object = ((OpackValue) object).clone();
}

return object;
Expand Down Expand Up @@ -299,28 +301,31 @@ private void executeSerializeStack(int endOfStack) throws SerializeException {

for (int index = 0; index < length; index++) {
Object element = ReflectionUtil.getArrayItem(object, index);
Class<?> elementType = element == null ? null : element.getClass();

Object serializedValue = this.prepareObjectSerialize(elementType, elementType, element);

opackArray.add(serializedValue);
if (element != null) {
opackArray.add(this.prepareObjectSerialize(element.getClass(), element));
} else {
opackArray.add(null);
}
}
} else if (opackValue instanceof OpackObject) {
OpackObject<Object, Object> opackObject = (OpackObject<Object, Object>) opackValue;

for (BakedType.Property property : bakedType.getFields()) {
try {
Object element = property.get(object);
Class<?> fieldType = property.getType();
Class<?> originalType = element == null ? null : element.getClass();

if (property.getTransformer() != null) {
element = property.getTransformer().serialize(this, element);
fieldType = element.getClass();
}

Object serializedValue = this.prepareObjectSerialize(fieldType, originalType, element);
if (element != null) {
opackObject.put(property.getName(), this.prepareObjectSerialize(fieldType, element));
} else {
opackObject.put(property.getName(), null);
}

opackObject.put(property.getName(), serializedValue);
} catch (IllegalAccessException exception) {
throw new SerializeException("Can't get " + property.getName() + " field data in " + bakedType.getType().getSimpleName() + ".", exception);
}
Expand All @@ -337,12 +342,18 @@ private void executeSerializeStack(int endOfStack) throws SerializeException {
* @return deserialized object
* @throws DeserializeException if a problem occurs during deserializing; if this opacker is serializing
*/
public synchronized <T> T deserialize(Class<T> type, OpackValue opackValue) throws DeserializeException {
public synchronized <T> T deserialize(@NotNull Class<T> type, @NotNull OpackValue opackValue) throws DeserializeException {
if (this.state == State.SERIALIZE)
throw new DeserializeException("Opacker is serializing.");

int separatorStack = this.objectStack.getSize();
T value = type.cast(this.prepareObjectDeserialize(type, opackValue));
Object object = this.prepareObjectDeserialize(type, opackValue);

if (object == null) {
return null;
}

T value = type.cast(object);

State lastState = this.state;
try {
Expand All @@ -367,16 +378,16 @@ public synchronized <T> T deserialize(Class<T> type, OpackValue opackValue) thro
* @return prepared object
* @throws DeserializeException if a problem occurs during deserializing
*/
public synchronized Object prepareObjectDeserialize(Class<?> goalType, Object object) throws DeserializeException {
if (goalType == null || object == null) {
return null;
}

private synchronized @Nullable Object prepareObjectDeserialize(@NotNull Class<?> goalType, @NotNull Object object) throws DeserializeException {
try {
BakedType bakedType = this.typeBaker.get(goalType);

for (Transformer transformer : bakedType.getTransformers()) {
object = transformer.deserialize(this, goalType, object);

if (object == null) {
return null;
}
}

/*
Expand Down Expand Up @@ -440,7 +451,8 @@ public synchronized Object prepareObjectDeserialize(Class<?> goalType, Object ob

try {
targetObject = ReflectionUtil.createInstanceUnsafe(goalType);
} catch (InvocationTargetException | IllegalAccessException | InstantiationException exception) {
} catch (InvocationTargetException | IllegalAccessException |
InstantiationException exception) {
throw new DeserializeException("Can't create instance using unsafe method.", exception);
}
} else {
Expand Down Expand Up @@ -481,9 +493,18 @@ private void executeDeserializeStack(int endOfStack) throws DeserializeException

for (int index = 0; index < length; index++) {
Object element = opackArray.get(index);
Object deserializedValue = this.prepareObjectDeserialize(componentType, element);

ReflectionUtil.setArrayItem(object, index, deserializedValue == null ? null : ReflectionUtil.cast(componentType, deserializedValue));
if (element != null) {
Object deserializedValue = this.prepareObjectDeserialize(componentType, element);

if (deserializedValue != null) {
ReflectionUtil.setArrayItem(object, index, ReflectionUtil.cast(componentType, deserializedValue));
} else {
ReflectionUtil.setArrayItem(object, index, null);
}
} else {
ReflectionUtil.setArrayItem(object, index, null);
}
}
} else if (opackValue instanceof OpackObject) {
OpackObject<Object, Object> opackObject = (OpackObject<Object, Object>) opackValue;
Expand All @@ -497,9 +518,17 @@ private void executeDeserializeStack(int endOfStack) throws DeserializeException
element = property.getTransformer().deserialize(this, fieldType, element);
}

Object deserializedValue = this.prepareObjectDeserialize(fieldType, element);
if (element != null) {
Object deserializedValue = this.prepareObjectDeserialize(fieldType, element);

property.set(object, deserializedValue == null ? null : ReflectionUtil.cast(actualFieldType, deserializedValue));
if (deserializedValue != null) {
property.set(object, ReflectionUtil.cast(actualFieldType, deserializedValue));
} else {
property.set(object, null);
}
} else {
property.set(object, null);
}
} catch (IllegalAccessException | IllegalArgumentException exception) {
throw new DeserializeException("Can't set " + property.getName() + " field in " + bakedType.getType().getSimpleName() + ".", exception);
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/realtimetech/opack/annotation/Name.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

package com.realtimetech.opack.annotation;

import org.jetbrains.annotations.NotNull;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand All @@ -38,5 +40,5 @@
/**
* @return returns name to be serialized/deserialized
*/
String value();
@NotNull String value();
}
22 changes: 11 additions & 11 deletions src/main/java/com/realtimetech/opack/bake/BakedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

import java.lang.reflect.Field;

public class BakedType {
public static class Property {
public final class BakedType {
public final static class Property {
private final @NotNull Field field;
private final @NotNull String name;
private final @NotNull Class<?> type;
Expand Down Expand Up @@ -67,7 +67,7 @@ public Property(@NotNull Field field, @Nullable String name, @Nullable Transform
* @param value the new value for the field of object being modified
* @throws IllegalAccessException if this Field object is enforcing Java language access control and the underlying field is either inaccessible or final
*/
public void set(Object object, Object value) throws IllegalAccessException {
public void set(@NotNull Object object, @Nullable Object value) throws IllegalAccessException {
if (!this.field.canAccess(object)) {
this.field.setAccessible(true);
}
Expand All @@ -82,7 +82,7 @@ public void set(Object object, Object value) throws IllegalAccessException {
* @return field value
* @throws IllegalAccessException if this Field object is enforcing Java language access control and the underlying field is inaccessible.
*/
public Object get(Object object) throws IllegalAccessException {
public @Nullable Object get(@NotNull Object object) throws IllegalAccessException {
if (!this.field.canAccess(object)) {
this.field.setAccessible(true);
}
Expand All @@ -91,25 +91,25 @@ public Object get(Object object) throws IllegalAccessException {
}
}

final Class<?> type;
final Transformer[] transformers;
final Property[] fields;
final @NotNull Class<?> type;
final @NotNull Transformer @NotNull [] transformers;
final @NotNull Property @NotNull [] fields;

public BakedType(Class<?> type, Transformer[] transformers, Property[] fields) {
public BakedType(@NotNull Class<?> type, @NotNull Transformer @NotNull [] transformers, @NotNull Property @NotNull [] fields) {
this.type = type;
this.transformers = transformers;
this.fields = fields;
}

public Class<?> getType() {
public @NotNull Class<?> getType() {
return type;
}

public Transformer[] getTransformers() {
public @NotNull Transformer @NotNull [] getTransformers() {
return transformers;
}

public Property[] getFields() {
public @NotNull Property @NotNull [] getFields() {
return fields;
}
}
Loading

0 comments on commit 92c10c2

Please sign in to comment.