package foundation.dao;
|
|
import java.io.IOException;
|
import java.math.BigDecimal;
|
import java.net.URLDecoder;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import foundation.dao.version.VersionRequest;
|
import foundation.data.meta.field.FieldsRuntime;
|
import foundation.data.meta.property.MetaType;
|
import foundation.data.object.DataJoin;
|
import foundation.data.object.DataJoins;
|
import foundation.data.object.DataObject;
|
import foundation.data.object.IParamProvider;
|
import foundation.handler.DataPool;
|
import foundation.handler.DataPoolType;
|
import foundation.json.JArrayReader;
|
import foundation.json.JObjectReader;
|
import foundation.json.JSONReader;
|
import foundation.json.JType;
|
import foundation.route.Operation;
|
import foundation.server.config.DBaseType;
|
import foundation.token.IOnlineUser;
|
import foundation.translator.ITranslator;
|
import foundation.translator.Translator;
|
import foundation.util.MapList;
|
import foundation.util.Util;
|
import foundation.variant.provider.DataEvent;
|
import foundation.variant.provider.IVariantsProvider;
|
import foundation.variant.provider.VariantProviderType;
|
|
public class DataReader extends JObjectReader implements IVariantsProvider, IParamProvider {
|
|
private static Set<String> excludeNames;
|
private static Set<Character> stopChars;
|
private Operation operation;
|
private DataPool dataPool;
|
private Domain domain;
|
private MapList<String, String> params;
|
|
|
static {
|
excludeNames = new HashSet<String>();
|
excludeNames.add("dataname");
|
excludeNames.add("filter");
|
excludeNames.add("orderby");
|
excludeNames.add("page");
|
|
stopChars = new HashSet<Character>();
|
stopChars.add(' ');
|
stopChars.add('\r');
|
stopChars.add('\n');
|
}
|
|
public DataReader(Operation operation, DataPool dataPool) throws Exception {
|
super();
|
|
//1.
|
this.operation = operation;
|
this.dataPool = dataPool;
|
|
DataPoolType type = dataPool.getType();
|
|
if (DataPoolType.Get == type) {
|
loadGetRequestData(dataPool);
|
}
|
else if (DataPoolType.Post == type) {
|
loadPostRequestData(dataPool);
|
}
|
else if (DataPoolType.MultiPart == type) {
|
loadMultiPartParams();
|
}
|
}
|
|
private void loadGetRequestData(DataPool dataPool) throws Exception {
|
params = dataPool.getParams();
|
|
domain = new Domain(this, operation);
|
domain.setEmpty(true);
|
|
loadDomain(domain);
|
}
|
|
private void loadPostRequestData(DataPool dataPool) throws Exception {
|
//1. read JSON body
|
JObjectReader jObjectReader = dataPool.getJObjectReader();
|
this.items = jObjectReader.getItems();
|
|
//2. read parameters
|
params = dataPool.getParams();
|
|
//3. read domain
|
domain = new Domain(this, operation);
|
loadDomain(domain);
|
}
|
|
private void loadMultiPartParams() {
|
params = dataPool.getParams();
|
}
|
|
public synchronized Domain getDomain() throws Exception {
|
return domain;
|
}
|
|
public void loadDomain(Domain domain) throws Exception {
|
//1. empty
|
boolean empty = isEmpty();
|
domain.setEmpty(empty);
|
|
//2. token
|
String token = getString(IDataLetter.Token);
|
domain.setToken(token);
|
|
//3. data name and partial name
|
String dataName = getString(IDataLetter.DataName);
|
|
if (!Util.isEmpty(dataName)) {
|
int pos = dataName.indexOf(".");
|
|
if (pos > 0) {
|
String partialName = dataName.substring(pos + 1);
|
dataName = dataName.substring(0, pos);
|
|
domain.setPartialName(partialName);
|
}
|
|
domain.setDataName(dataName);
|
}
|
|
//4. parent id and id
|
String parentId = getString(IDataLetter.ParentID);
|
domain.setParentId(parentId);
|
|
String id = getString(IDataLetter.ID);
|
domain.setId(id);
|
|
//5.
|
String operator = getString(IDataLetter.Operator);
|
if (Util.isEmpty(operator)) {
|
operator = operation.getOperator();
|
}
|
|
domain.setOperator(operator);
|
|
OperatorCode operatorCode = OperatorCode.parse(operator);
|
domain.setOperatorCode(operatorCode);
|
|
//6. meta code
|
boolean attachMeta = getBoolean(IDataLetter.AttachMeta, false);
|
MetaType metaType = attachMeta ? MetaType.Unknow : MetaType.None;
|
if (MetaType.Unknow == metaType && OperatorCode.GetBatch.equals(operatorCode)) {
|
metaType = MetaType.List;
|
}
|
|
domain.setMetaType(metaType);
|
|
String scene = getString(IDataLetter.Scene);
|
domain.setScene(scene);
|
|
//7. host
|
String hostId = getString(IDataLetter.HostID);
|
domain.setHostId(hostId);
|
|
if (has(IDataLetter.HostItems)) {
|
Set<String> hostItems = new HashSet<String>();
|
JArrayReader array = getReader(IDataLetter.HostItems, JType.Array);
|
|
for (JSONReader value: array) {
|
String itemName = value.getString(null);
|
if (itemName == null) {
|
continue;
|
}
|
|
itemName = itemName.toLowerCase();
|
hostItems.add(itemName);
|
}
|
|
domain.setHostItems(hostItems);
|
}
|
}
|
|
public VersionRequest loadVersionRequest() {
|
if (!has(IDataLetter.Version)) {
|
return null;
|
}
|
|
VersionRequest versionRequest = domain.getVersionRequest();
|
|
if (versionRequest == null) {
|
versionRequest = new VersionRequest();
|
domain.setVersionRequest(versionRequest);
|
}
|
|
JObjectReader versionReader = getReader(IDataLetter.Version, JType.Object);
|
|
String get = versionReader.getString("get");
|
String compare = versionReader.getString("compare");
|
versionRequest.set(get, compare);
|
|
return versionRequest;
|
}
|
|
public void loadFilterFromJSON(DataObject dataObject, Filter filter) throws Exception {
|
FieldsRuntime meta = dataObject.getTableFieldMetas();
|
DBaseType dbaseType = dataObject.getDbaseType();
|
String tableName = dataObject.getTableOrViewName();
|
DataJoins dataJoins = dataObject.getDataJoins();
|
|
//1. 如果直接指定ID,读取ID
|
String id = domain.getId();
|
if (!Util.isEmpty(id)) {
|
filter.add(getFullFieldName(tableName, "id"), id);
|
}
|
|
//2. 如果指定了MasterID, 读取MasterID
|
String masterId = domain.getParentId();
|
if (!Util.isEmpty(masterId)) {
|
filter.add(getFullFieldName(tableName, "parent_id"), masterId);
|
}
|
|
//3. 从过滤条件中读取
|
if (!has(IDataLetter.Filter)) {
|
return;
|
}
|
|
JType dataType = getType(IDataLetter.Filter);
|
|
//3.1 read string
|
if (JType.String == dataType) {
|
String value = getString(IDataLetter.Filter);
|
value = decodeString(value);
|
doReadOneFilerLineFromJSON(dbaseType, tableName, dataJoins, value, filter);
|
}
|
//3.2 read array
|
else if (JType.Array == dataType) {
|
JArrayReader array = getReader(IDataLetter.Filter, JType.Array);
|
|
for (JSONReader line: array) {
|
doReadOneFilerLineFromJSON(dbaseType, tableName, dataJoins, meta, line, filter);
|
}
|
}
|
//3.3 read object
|
else if (JType.Object == dataType) {
|
JSONReader line = getReader(IDataLetter.Filter, JType.Object);
|
doReadOneFilerLineFromJSON(dbaseType, tableName, dataJoins, meta, line, filter);
|
}
|
}
|
|
private void doReadOneFilerLineFromJSON(DBaseType dbaseType, String tableName, DataJoins dataJoins, String value, Filter filter) {
|
int pos = value.indexOf(DataJoin.TableJoinConnector);
|
|
if (pos >= 0) {
|
value = value.replace(DataJoin.TableJoinConnector, ".");
|
}
|
|
filter.add(value);
|
}
|
|
private void doReadOneFilerLineFromJSON(DBaseType dbaseType, String tableName, DataJoins dataJoins, FieldsRuntime meta, JSONReader line, Filter filter) throws Exception {
|
String fieldName = line.getString(IDataLetter.Filter_Field);
|
String value = line.getString(IDataLetter.Filter_Value);
|
String operator = line.getString(IDataLetter.Filter_Operator);
|
|
if (Util.isEmpty(fieldName) || Util.isEmpty(value)) {
|
return;
|
}
|
|
int pos = 0;
|
|
//1. 如果表中包含该字段,直接加入
|
if (meta.contains(fieldName)) {
|
ITranslator translator = meta.getValueTranslator(fieldName);
|
JType valueType = line.getType(IDataLetter.Filter_Value);
|
|
//1.1 如果是 2023-08-20 >= date <= 2023-08-25 这种类型
|
if (JType.Array == valueType) {
|
List<String> list = line.getStringList(IDataLetter.Filter_Value);
|
|
if (list.size() != 2) {
|
return;
|
}
|
|
String left = getFullFieldName(tableName, fieldName) + ">=" + translator.toSqlString(dbaseType, list.get(0));
|
String right = getFullFieldName(tableName, fieldName) + "<=" + translator.toSqlString(dbaseType, list.get(1));
|
filter.add("(" + left + " and " + right + ")");
|
return;
|
}
|
|
//1.2 如果是 code = 00001 这种类型
|
value = URLDecoder.decode(value, "UTF-8");
|
value = translator.toSqlString(dbaseType, value);
|
filter.add(getFullFieldName(tableName, fieldName), operator, value);
|
return;
|
}
|
//2. 检查 Join 表
|
else if ((pos = fieldName.indexOf(DataJoin.TableJoinConnector)) > 0) {
|
tableName = fieldName.substring(0, pos);
|
fieldName = fieldName.substring(pos + 2);
|
|
meta = dataJoins.getJoinFieldsMeta(tableName);
|
if (meta == null) {
|
return;
|
}
|
|
ITranslator translator = meta.getValueTranslator(fieldName);
|
if (translator == null) {
|
return;
|
}
|
|
value = URLDecoder.decode(value, "UTF-8");
|
value = translator.toSqlString(dbaseType, value);
|
|
filter.add(getFullFieldName(tableName, fieldName), operator, value);
|
}
|
//3. 自定义SQL中的字段,有可能存在.的情况
|
else if (fieldName.indexOf(".") > 0) {
|
tableName = fieldName.substring(pos);
|
value = URLDecoder.decode(value, "UTF-8");
|
|
filter.add(fieldName, operator, Translator.toSqlString(dbaseType, value));
|
}
|
}
|
|
public static String getFullFieldName(String tableName, String fieldName) {
|
if (Util.isEmpty(tableName)) {
|
return fieldName;
|
}
|
|
return tableName + "." + fieldName;
|
}
|
|
public void loadPageOrderByFromJSON(DataObject dataObject, Page page, OrderBy orderBy) throws Exception {
|
//1. read page
|
if (has(IDataLetter.Page)) {
|
JObjectReader pageReader = getReader("page", JType.Object);
|
|
//1.1 如果请求分页参数为空,不需要加上分页
|
if (pageReader != null) {
|
Integer pageSize = pageReader.getInteger(IDataLetter.Page_Size, null);
|
page.setPageSize(pageSize);
|
|
Integer pageNo = pageReader.getInteger(IDataLetter.Page_No, null);
|
page.setPageNo(pageNo);
|
}
|
}
|
else {
|
//2. 如果不传分页参数,不需要加上分页
|
page.setEmpty(true);
|
}
|
|
//2. read order by
|
if (has(IDataLetter.OrderBy)) {
|
String value = getString(IDataLetter.OrderBy);
|
|
if (!Util.isEmpty(value)) {
|
orderBy.add(value);
|
}
|
else {
|
OrderBy defaultOrderBy = dataObject.getDefaultOrderBy();
|
orderBy.addAll(defaultOrderBy);
|
}
|
}
|
|
//3 add page order by
|
if ((!page.isEmpty()) && (orderBy.isEmpty())) {
|
FieldsRuntime meta = dataObject.getBatchBrowseFieldMetas();
|
|
if (meta.contains(OrderBy.PageOrderByField)) {
|
String tableName = dataObject.getTableOrViewName();
|
if (!Util.isEmpty(tableName)) {
|
orderBy.add(tableName + "." + OrderBy.PageOrderByField);
|
}
|
}
|
}
|
}
|
|
public void loadOrderByFromJSON(DataObject dataObject, OrderBy orderBy) throws Exception {
|
if (has(IDataLetter.OrderBy)) {
|
String value = getString(IDataLetter.OrderBy);
|
|
if (!Util.isEmpty(value)) {
|
orderBy.add(value);
|
}
|
else {
|
OrderBy defaultOrderBy = dataObject.getDefaultOrderBy();
|
orderBy.addAll(defaultOrderBy);
|
}
|
}
|
}
|
|
public Domain loadFilterPageOrderByFromJSON(DataObject dataObject, Filter filter, Page page, OrderBy orderBy) throws Exception {
|
//1. load filter
|
loadFilterFromJSON(dataObject, filter);
|
|
//2. load page and order by
|
loadPageOrderByFromJSON(dataObject, page, orderBy);
|
|
//3. return
|
return domain;
|
}
|
|
private String decodeString(String value) {
|
try {
|
value = URLDecoder.decode(value, "UTF-8");
|
return value;
|
}
|
catch (Exception e) {
|
return value;
|
}
|
}
|
|
public DataPackage getDataPackage() throws Exception {
|
return domain.getDataPackage();
|
}
|
|
public VersionRequest getVersionRequest() {
|
return domain.getVersionRequest();
|
}
|
|
public Operation getOperation() {
|
return operation;
|
}
|
|
public String getOperator() {
|
if (operation == null) {
|
return null;
|
}
|
|
return operation.getOperator();
|
}
|
|
public void loadOneParameter(String name, String value) {
|
params.add(name, value);
|
}
|
|
@Override
|
public boolean has(String name) {
|
boolean result = super.has(name);
|
|
if (result) {
|
return result;
|
}
|
|
if (params == null) {
|
return result;
|
}
|
|
result = params.contains(name);
|
return result;
|
}
|
|
@Override
|
public JType getType(String name) {
|
JType result = super.getType(name);
|
|
if (JType.Empty != result) {
|
return result;
|
}
|
|
result = params.contains(name) ? JType.String : JType.Empty;
|
return result;
|
}
|
|
@Override
|
public String getString(String name) {
|
String result = super.getString(name);
|
|
if ((result == null) && (params != null)) {
|
result = params.get(name);
|
}
|
|
return result;
|
}
|
public BigDecimal getBigDecimal(String name, BigDecimal defaultValue) {
|
String result = super.getString(name);
|
|
if ((Util.isEmpty(result)) && (params != null)) {
|
return defaultValue;
|
}
|
|
return new BigDecimal(result);
|
}
|
|
public String getRequestBody() throws IOException {
|
if (dataPool == null) {
|
return null;
|
}
|
|
return dataPool.getBody();
|
}
|
|
@Override
|
public String getProviderName() {
|
return this.getClass().getSimpleName();
|
}
|
|
@Override
|
public VariantProviderType getProviderType() {
|
return VariantProviderType.Transiant;
|
}
|
|
@Override
|
public boolean containsVariant(String name) {
|
if (name == null) {
|
return false;
|
}
|
|
if (excludeNames.contains(name.toLowerCase())) {
|
return false;
|
}
|
|
return has(name);
|
}
|
|
@Override
|
public Object getVariantValue(DataEvent dataEvent, String name) {
|
return getString(name);
|
}
|
|
@Override
|
public Set<String> getVariantNames() {
|
Set<String> result = new HashSet<String>();
|
|
Set<String> keys = items.getKeySet();
|
|
for (String name: keys) {
|
if (excludeNames.contains(name.toLowerCase())) {
|
continue;
|
}
|
|
result.add(name);
|
}
|
|
return result;
|
}
|
|
public DataPool getDataPool() {
|
return dataPool;
|
}
|
|
public void setDataPool(DataPool dataPool) {
|
this.dataPool = dataPool;
|
}
|
|
public String getBody() throws IOException {
|
return dataPool.getBody();
|
}
|
|
public HttpServletRequest getRequest() {
|
return dataPool.getRequest();
|
}
|
|
public IOnlineUser getUser() {
|
return dataPool.getUser();
|
}
|
|
}
|