package io.github.ibuildthecloud.gdapi.model.impl;
import io.github.ibuildthecloud.gdapi.context.ApiContext;
import io.github.ibuildthecloud.gdapi.factory.SchemaFactory;
import io.github.ibuildthecloud.gdapi.id.IdFormatter;
import io.github.ibuildthecloud.gdapi.id.IdFormatterUtils;
import io.github.ibuildthecloud.gdapi.model.Field;
import io.github.ibuildthecloud.gdapi.model.FieldType;
import io.github.ibuildthecloud.gdapi.model.Resource;
import io.github.ibuildthecloud.gdapi.model.Schema;
import io.github.ibuildthecloud.gdapi.util.TypeUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.commons.lang3.StringUtils;
public class WrappedResource extends ResourceImpl implements Resource {
Schema schema;
SchemaFactory schemaFactory;
Object obj;
Map<String, Object> priorityFields = new LinkedHashMap<String, Object>();
Map<String, Object> additionalFields;
Map<String, Field> resourceFields;
boolean createTsFields = true;
String method;
Set<String> priorityFieldNames = null;
IdFormatter idFormatter;
public WrappedResource(IdFormatter idFormatter, SchemaFactory schemaFactory,
Schema schema, Object obj, Map<String, Object> additionalFields,
Set<String> priorityFieldNames, String method) {
super();
this.schemaFactory = schemaFactory;
this.schema = schema;
this.resourceFields = schema.getResourceFields();
this.obj = obj;
this.idFormatter = idFormatter;
this.additionalFields = additionalFields;
this.priorityFieldNames = priorityFieldNames;
this.method = method;
init();
}
public WrappedResource(IdFormatter idFormatter, SchemaFactory schemaFactory, Schema schema, Object obj, String method) {
this(idFormatter, schemaFactory, schema, obj, new HashMap<String, Object>(), null, method);
}
protected void addField(String key, Object value) {
if (priorityFieldNames != null && priorityFieldNames.contains(key)) {
priorityFields.put(key, value);
} else {
fields.put(key, value);
}
}
protected void init() {
for (Map.Entry<String, Field> entry : resourceFields.entrySet()) {
String name = entry.getKey();
if (name.equals(TypeUtils.ID_FIELD)) {
continue;
}
Field field = entry.getValue();
if (!field.isIncludeInList()) {
continue;
}
Object value = additionalFields.remove(name);
if (value == null) {
value = field.getValue(obj);
}
if (!Schema.Method.POST.isMethod(method) && field.isReadOnCreateOnly()){
value = null;
}
if (StringUtils.isNotBlank(field.getTransform()) && StringUtils.isNotBlank((String) value)){
String decrypted;
try {
decrypted = ApiContext.getContext().getTransformationService().untransform((String) value);
} catch (UnsupportedOperationException e) {
decrypted = "";
}
if (decrypted != null) {
value = decrypted;
}
}
if (value == null && field.getTypeEnum() == FieldType.BOOLEAN && !field.isNullable()) {
value = field.getDefault();
if (value == null) {
value = false;
}
}
addField(name, IdFormatterUtils.formatReference(field, idFormatter, value, schemaFactory));
if (createTsFields && field.getTypeEnum() == FieldType.DATE && value instanceof Date) {
addField(name + "TS", ((Date)value).getTime());
}
}
for (Map.Entry<String, Object> entry : additionalFields.entrySet()) {
Object value = entry.getValue();
String key = entry.getKey();
Field field = resourceFields.get(key);
if ((field != null && field.isIncludeInList()) || isResource(value)) {
addField(key, value);
}
}
Object id = idFormatter.formatId(getType(), getIdValue());
if (id != null) {
setId(id.toString());
}
if (priorityFields.size() > 0) {
Map<String, Object> sorted = new LinkedHashMap<String, Object>(priorityFields);
sorted.putAll(fields);
fields = sorted;
}
}
protected boolean isResource(Object obj) {
if (obj instanceof Resource) {
return true;
}
if (obj instanceof List<?>) {
List<?> list = (List<?>)obj;
if (list.size() == 0 || isResource(list.get(0))) {
return true;
}
}
return false;
}
protected Object getIdValue() {
Field idField = schema.getResourceFields().get(TypeUtils.ID_FIELD);
return idField == null ? null : idField.getValue(obj);
}
@Override
public String getType() {
String type = super.getType();
return type == null ? schema.getId() : type;
}
@Override
public String getBaseType() {
String parent = schema.getParent();
return parent == null ? getType() : parent;
}
@Override
public Map<String, Object> getFields() {
return fields;
}
@XmlTransient
public boolean isCreateTsFields() {
return createTsFields;
}
public void setCreateTsFields(boolean createTsFields) {
this.createTsFields = createTsFields;
}
public Set<String> getPriorityFieldNames() {
return priorityFieldNames;
}
@XmlTransient
public void setPriorityFieldNames(Set<String> priorityFieldNames) {
this.priorityFieldNames = priorityFieldNames;
}
}