package com.brightgenerous.orm.mapper;
import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import com.brightgenerous.commons.EqualsUtils;
import com.brightgenerous.commons.HashCodeUtils;
import com.brightgenerous.commons.StringUtils;
import com.brightgenerous.commons.ToStringUtils;
import com.brightgenerous.lang.Args;
public class TableMapper implements Serializable {
private static final long serialVersionUID = -8599881819890993547L;
public static enum Flag {
ALL, SELECT, INSERT, UPDATE
}
private final Class<?> clazz;
private final boolean alias;
private final String table;
private final String property;
private final LinkedHashMap<String, ColumnDefine> primarys;
private final LinkedHashMap<String, ColumnDefine> fieldColumns;
public TableMapper(Class<?> clazz, boolean alias, String table,
LinkedHashMap<String, ColumnDefine> primarys,
LinkedHashMap<String, ColumnDefine> fieldColumns) {
this(clazz, alias, table, null, primarys, fieldColumns);
}
protected TableMapper(Class<?> clazz, boolean alias, String table, String property,
LinkedHashMap<String, ColumnDefine> primarys,
LinkedHashMap<String, ColumnDefine> fieldColumns) {
Args.notNull(clazz, "clazz");
Args.notEmpty(table, "table");
this.clazz = clazz;
this.alias = alias;
this.table = table;
this.property = property;
this.primarys = new LinkedHashMap<>((primarys == null) ? Collections.EMPTY_MAP : primarys);
this.fieldColumns = new LinkedHashMap<>((fieldColumns == null) ? Collections.EMPTY_MAP
: fieldColumns);
}
public Class<?> getBeanClass() {
return clazz;
}
public boolean isAlias() {
return alias;
}
public String getTable() {
return table;
}
public String getProperty() {
return property;
}
public LinkedHashMap<String, ColumnDefine> getPrimarys() {
return primarys;
}
public LinkedHashMap<String, ColumnDefine> getFieldColumns() {
return fieldColumns;
}
private static final String[] excludeFields = new String[] { "flagFieldColumns",
"flagStripFieldFullColumns", "flagFieldFullColumns", "flagPropertyFieldFullColumns" };
private transient volatile Map<Flag, LinkedHashMap<String, ColumnDefine>> flagFieldColumns;
private transient volatile Map<Flag, LinkedHashMap<String, String>> flagStripFieldFullColumns;
private transient volatile Map<Flag, LinkedHashMap<String, String>> flagFieldFullColumns;
private transient volatile Map<Flag, LinkedHashMap<String, String>> flagPropertyFieldFullColumns;
public LinkedHashMap<String, ColumnDefine> getFieldColumns(Flag flag) {
Args.notNull(flag, "flag");
if (flagFieldColumns == null) {
synchronized (this) {
if (flagFieldColumns == null) {
flagFieldColumns = new ConcurrentHashMap<>();
}
}
}
LinkedHashMap<String, ColumnDefine> ret = flagFieldColumns.get(flag);
if (ret == null) {
synchronized (flagFieldColumns) {
ret = flagFieldColumns.get(flag);
if (ret == null) {
ret = new LinkedHashMap<>();
for (Entry<String, ColumnDefine> e : fieldColumns.entrySet()) {
ColumnDefine cd = e.getValue();
if (!checkFlag(cd, flag)) {
continue;
}
ret.put(e.getKey(), cd);
}
flagFieldColumns.put(flag, ret);
}
}
}
return ret;
}
public LinkedHashMap<String, String> getStripFieldFullColumns(Flag flag) {
Args.notNull(flag, "flag");
if (flagStripFieldFullColumns == null) {
synchronized (this) {
if (flagStripFieldFullColumns == null) {
flagStripFieldFullColumns = new ConcurrentHashMap<>();
}
}
}
LinkedHashMap<String, String> ret = flagStripFieldFullColumns.get(flag);
if (ret == null) {
synchronized (flagStripFieldFullColumns) {
ret = flagStripFieldFullColumns.get(flag);
if (ret == null) {
ret = new LinkedHashMap<>();
LinkedHashMap<String, String> ffcs = getFieldFullColumns(flag);
for (Entry<String, String> e : ffcs.entrySet()) {
String k = MapperUtils.spritField(e.getKey());
if (!ret.containsKey(k)) {
ret.put(k, e.getValue());
}
}
flagStripFieldFullColumns.put(flag, ret);
}
}
}
return ret;
}
public LinkedHashMap<String, String> getFieldFullColumns(Flag flag) {
Args.notNull(flag, "flag");
if (flagFieldFullColumns == null) {
synchronized (this) {
if (flagFieldFullColumns == null) {
flagFieldFullColumns = new ConcurrentHashMap<>();
}
}
}
LinkedHashMap<String, String> ret = flagFieldFullColumns.get(flag);
if (ret == null) {
synchronized (flagFieldFullColumns) {
ret = flagFieldFullColumns.get(flag);
if (ret == null) {
ret = new LinkedHashMap<>();
for (Entry<String, ColumnDefine> e : fieldColumns.entrySet()) {
ColumnDefine cd = e.getValue();
if (!checkFlag(cd, flag)) {
continue;
}
String f = e.getKey();
String c = MapperUtils.joinTableColumn(table, cd.getName());
if (!ret.containsKey(f)) {
ret.put(f, c);
}
}
flagFieldFullColumns.put(flag, ret);
}
}
}
return ret;
}
public LinkedHashMap<String, String> getPropertyFieldFullColumns(Flag flag) {
Args.notNull(flag, "flag");
if (flagPropertyFieldFullColumns == null) {
synchronized (this) {
if (flagPropertyFieldFullColumns == null) {
flagPropertyFieldFullColumns = new ConcurrentHashMap<>();
}
}
}
LinkedHashMap<String, String> ret = flagPropertyFieldFullColumns.get(flag);
if (ret == null) {
synchronized (flagPropertyFieldFullColumns) {
ret = flagPropertyFieldFullColumns.get(flag);
if (ret == null) {
LinkedHashMap<String, String> ffcs = getFieldFullColumns(flag);
if (StringUtils.isEmpty(property)) {
ret = ffcs;
} else {
ret = new LinkedHashMap<>();
for (Entry<String, String> e : ffcs.entrySet()) {
String pf = MapperUtils.joinPropertyField(property, e.getKey());
if (!ret.containsKey(pf)) {
ret.put(pf, e.getValue());
}
}
flagPropertyFieldFullColumns.put(flag, ret);
}
}
}
}
return ret;
}
protected boolean checkFlag(ColumnDefine columnDefine, Flag flag) {
switch (flag) {
case ALL:
return true;
case SELECT:
return columnDefine.isEnableSelect();
case INSERT:
return columnDefine.isEnableInsert();
case UPDATE:
return columnDefine.isEnableUpdate();
default:
throw new IllegalStateException();
}
}
public static TableMapper createAlt(TableMapper tableMapper, String property) {
Args.notNull(tableMapper, "tableMapper");
return new TableMapper(tableMapper.clazz, tableMapper.alias, tableMapper.table, property,
tableMapper.primarys, tableMapper.fieldColumns);
}
@Override
public int hashCode() {
if (HashCodeUtils.resolved()) {
return HashCodeUtils.hashCodeAlt(null, this, excludeFields);
}
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
if (EqualsUtils.resolved()) {
return EqualsUtils.equalsAlt(null, this, obj, excludeFields);
}
return super.equals(obj);
}
@Override
public String toString() {
if (ToStringUtils.resolved()) {
return ToStringUtils.toStringAlt(this);
}
return super.toString();
}
}