package io.github.ibuildthecloud.gdapi.model.impl;
import io.github.ibuildthecloud.gdapi.model.Field;
import io.github.ibuildthecloud.gdapi.model.FieldType;
import io.github.ibuildthecloud.gdapi.model.FieldType.TypeAndName;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlTransient;
public class FieldImpl implements Field, Serializable {
private static final long serialVersionUID = -2165031896296545902L;
String name, type, validChars, invalidChars, transform, description;
Integer displayIndex;
boolean create, update, includeInList = true, nullable, unique, required, defaultIsNull, readOnCreateOnly = false;
FieldType typeEnum;
List<FieldType> subTypeEnums;
List<String> subTypes;
Long min, max, minLength, maxLength;
Object defaultValue;
List<String> options;
transient Method readMethod;
Map<String, Object> attributes = new HashMap<String, Object>();
public FieldImpl() {
}
public FieldImpl(Field field) {
this.name = field.getName();
this.description = field.getDescription();
this.validChars = field.getValidChars();
this.invalidChars = field.getInvalidChars();
this.create = field.isCreate();
this.readOnCreateOnly = field.isReadOnCreateOnly();
this.transform = field.getTransform();
this.update = field.isUpdate();
this.includeInList = field.isIncludeInList();
this.nullable = field.isNullable();
this.unique = field.isUnique();
this.required = field.isRequired();
this.min = field.getMin();
this.max = field.getMax();
this.minLength = field.getMinLength();
this.maxLength = field.getMaxLength();
this.defaultValue = field.getDefault();
this.options = field.getOptions() == null ? null : new ArrayList<String>(field.getOptions());
this.displayIndex = field.getDisplayIndex();
this.attributes = new HashMap<String, Object>(field.getAttributes());
if (field instanceof FieldImpl) {
this.readMethod = ((FieldImpl)field).getReadMethod();
this.defaultIsNull = ((FieldImpl)field).isDefaultIsNull();
}
setType(field.getType());
}
@Override
public Object getValue(Object object) {
if (readMethod == null || object == null)
return null;
try {
return readMethod.invoke(object);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (IllegalArgumentException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw new IllegalStateException(e);
}
}
@Override
@XmlTransient
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean isCreate() {
return create;
}
public void setCreate(boolean create) {
this.create = create;
}
@Override
public boolean isReadOnCreateOnly() {
return readOnCreateOnly;
}
public void setReadOnCreateOnly(boolean readOnCreateOnly) {
this.readOnCreateOnly = readOnCreateOnly;
}
@Override
public boolean isUpdate() {
return update;
}
public void setUpdate(boolean update) {
this.update = update;
}
@Override
public boolean isIncludeInList() {
return includeInList;
}
public void setIncludeInList(boolean includeInList) {
this.includeInList = includeInList;
}
@Override
public String getType() {
if (type == null && typeEnum != null) {
type = FieldType.toString(type, typeEnum, subTypes);
}
return type;
}
public void setType(String typeName) {
if (typeName == null) {
type = null;
} else {
List<TypeAndName> parts = FieldType.parse(typeName);
if (parts.size() == 0) {
throw new IllegalArgumentException("Failed to parse type [" + typeName + "]");
}
TypeAndName part = parts.get(0);
this.type = part.getName();
this.typeEnum = part.getType();
parts.remove(0);
setSubTypesList(parts);
}
}
@Override
public boolean isNullable() {
return nullable;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
@Override
public FieldType getTypeEnum() {
return typeEnum;
}
public void setTypeEnum(FieldType typeEnum) {
this.typeEnum = typeEnum;
this.type = null;
this.subTypeEnums = Collections.emptyList();
this.subTypes = Collections.emptyList();
}
@Override
public Long getMin() {
return min;
}
public void setMin(Long min) {
this.min = min;
}
@Override
public Long getMax() {
return max;
}
public void setMax(Long max) {
this.max = max;
}
@Override
public Long getMinLength() {
return minLength;
}
public void setMinLength(Long minLength) {
this.minLength = minLength;
}
@Override
public Long getMaxLength() {
return maxLength;
}
public void setMaxLength(Long maxLength) {
this.maxLength = maxLength;
}
@Override
public Object getDefault() {
if (defaultValue == null || this.typeEnum == null) {
return defaultValue;
}
switch (this.typeEnum) {
case BOOLEAN:
return Boolean.parseBoolean(defaultValue.toString());
case INT:
try {
return Long.parseLong(defaultValue.toString());
} catch (NumberFormatException nfe) {
break;
}
default:
}
return defaultValue;
}
public void setDefault(Object defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public List<String> getOptions() {
return options;
}
public void setOptions(List<String> options) {
this.options = options;
}
@XmlTransient
public Method getReadMethod() {
return readMethod;
}
public void setReadMethod(Method readMethod) {
this.readMethod = readMethod;
}
@Override
public boolean isUnique() {
return unique;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
@Override
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
@Override
public String getValidChars() {
return validChars;
}
public void setValidChars(String validChars) {
this.validChars = validChars;
}
@Override
public String getInvalidChars() {
return invalidChars;
}
public void setInvalidChars(String invalidChars) {
this.invalidChars = invalidChars;
}
@Override
public String toString() {
return "FieldImpl [name=" + name + ", type=" + type + ", validChars=" + validChars + ", invalidChars=" + invalidChars + ", displayIndex="
+ displayIndex + ", create=" + create + ", update=" + update + ", includeInList=" + includeInList + ", nullable=" + nullable + ", unique="
+ unique + ", required=" + required + ", defaultIsNull=" + defaultIsNull + ", typeEnum=" + typeEnum + ", subTypeEnums=" + subTypeEnums
+ ", subTypes=" + subTypes + ", min=" + min + ", max=" + max + ", minLength=" + minLength + ", maxLength=" + maxLength + ", defaultValue="
+ defaultValue + ", options=" + options + ", readMethod=" + readMethod + "description=" + description + "]";
}
public void setSubTypesList(List<TypeAndName> subTypes) {
this.subTypes = new ArrayList<String>(subTypes.size());
this.subTypeEnums = new ArrayList<FieldType>(subTypes.size());
for (TypeAndName typeAndName : subTypes) {
this.subTypes.add(typeAndName.getName());
this.subTypeEnums.add(typeAndName.getType());
}
this.type = FieldType.toString(type, typeEnum, this.subTypes);
}
@Override
public List<FieldType> getSubTypeEnums() {
return subTypeEnums;
}
@Override
public List<String> getSubTypes() {
return subTypes;
}
@Override
@XmlTransient
public Integer getDisplayIndex() {
return displayIndex;
}
public void setDisplayIndex(Integer displayIndex) {
this.displayIndex = displayIndex;
}
@XmlTransient
public boolean isDefaultIsNull() {
return defaultIsNull;
}
public void setDefaultIsNull(boolean defaultIsNull) {
this.defaultIsNull = defaultIsNull;
}
@Override
public boolean hasDefault() {
return defaultValue != null || defaultIsNull;
}
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@XmlTransient
public void setAttributes(Map<String, Object> attributes) {
this.attributes = attributes;
}
public void setTransform(String transform) {
this.transform = transform;
}
public String getTransform() {
return transform;
}
}