ExpressUtil.java
8.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
package com.skua.common.util;
import io.netty.util.internal.StringUtil;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
* ExpressUtil(表达式判断工具类)
*/
public class ExpressUtil {
/**
* 根据逻辑表达式推送结果 增加的复杂的取位运算
* @param express
* @param dataMap
* @return
* @throws ScriptException
*/
public static String getValueByExpress(String express, Map<String, Object> dataMap) throws ScriptException {
if (dataMap == null)
return "";
if (StringUtil.isNullOrEmpty(express))
return "";
String result = "";
int index = express.indexOf("=");// 表达式中有等式的
int hideIndex = express.indexOf("@hide"); // 表达式中有@hide字符串的,表示有隐藏属性
// 优先判断是否有隐藏属性
if (hideIndex > 0) {
result = "3";
return result;
}
int stringIndex = express.indexOf("@word");// 表达式中有@word字符串的,表示有>=3种以上文字属性进行切换的
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
engine.put(entry.getKey(), entry.getValue()); // 设置变量名称与采集数据的映射关系
}
/** start 增加等式逻辑判断功能,判断等式类型表达式是否成立 修改人:HQW 2016-11-10 */
// 优先判断带文字属性的点
if (stringIndex > 0) {
String tempStr = express.substring(0, index);// 表达式等式中的变量名称
result = "word" + (String) engine.eval(tempStr); // 获取表达式中的变量名称被设置的具体数值
return result;
}
// 逻辑位判断处理
int bitIndex = express.indexOf("^");// 判断表达式中是否有^符号,进行二进制转换处理
if (bitIndex > 0) {
String tempbit = express.substring(bitIndex + 1);
int bitNumber = Integer.parseInt(tempbit.split("\\.")[0]) + 1;// 获取表达式中的位数,组态中从0开始为第一位
String expStr = express.substring(0, bitIndex);
String decimalSource = (String) engine.eval(expStr);
result = decimalToBinary(Integer.parseInt(decimalSource.split("\\.")[0]), bitNumber);
return result;
}
// 恒等式逻辑部分进行赋值
if (index > 0) {
String tempStr = express.substring(0, index);// 表达式等式中的变量名称
String valueStr = express.substring(index + 1);// 表达式等式中的数值
result = engine.eval(tempStr).toString(); // 获取表达式中的变量名称被设置的具体数值
if (valueStr.equals(result)) {
result = "1";
} else {
result = "0";
}
} else {
result = engine.eval(express).toString();
}
// 显示隐藏逻辑部分进行赋值
/** end */
result = subZeroAndDot(result);
return result;
}
/**
* 根据表达式计算结果,满足复杂逻辑表达式
* @Title: getValueByExpress2
* @Description: TODO
* @param express
* @param dataMap
* @return
* @throws ScriptException
* @return: String
*/
public static String getValueByExpress2(String express,Map<String,Object> dataMap) throws ScriptException{
if(dataMap == null) return "";
if(StringUtil.isNullOrEmpty(express)) return "";
String result = "";
//去除首尾的"#"
if(express.startsWith("#")){
express = express.substring(1);
}
if(express.endsWith("#")){
express = express.substring(0, express.length()-1);
}
//优先判断是否有隐藏属性
int hideIndex = express.indexOf("@hide"); //表达式中有@hide字符串的,表示有隐藏属性
if(hideIndex>0){
result="3";
return result;
}
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
String parameters = "";
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
//设置变量名称与采集数据的映射关系,value转换成double便于后续计算
engine.put(entry.getKey(), Double.parseDouble(entry.getValue().toString()));
//以字段为参数进行参数拼接
parameters = parameters + "," + entry.getKey() ;
}
//去掉首位的","
if(parameters.length() > 0){
parameters = parameters.substring(1);
}
//定义函数并调用,将拼接好的参数带入
String script = "function add("+parameters+"){return "+express+"} add("+parameters+")";
Object object = engine.eval(script);
if(object!=null){
result = object.toString();
//去掉模拟量中小数点后可能存在的多余0
result = subZeroAndDot(result);
}else{
return "";
}
//判断返回是否为真假并赋予对应的值
if("true".equals(result)){
result = "1";
}else if("false".equals(result)){
result = "0";
}
return result;
}
/**
* 去掉数字字符串中小数点后多余的0
* @param s
* @return
*/
public static String subZeroAndDot(String s){
if(s.indexOf(".") > 0){
//去掉多余的0
s = s.replaceAll("0+?$", "");
//如最后一位是.则去掉
s = s.replaceAll("[.]$", "");
}
return s;
}
/**
* @Title: decimalToBinary
* @Description: 进行十进制和2进行数据转换,并获取指定位数数据 获取2进制的位运算方法
* @param decimalSource
* 待转换10进制数据
* @param bitNumber
* 需要获取第几位数据
* @return
* @return: String 返回值非0即1,只有两种状态
*/
public static String decimalToBinary(int decimalSource, int bitNumber) {
BigInteger bi = new BigInteger(String.valueOf(decimalSource)); // 转换成BigInteger类型
String bitValueS = bi.toString(2);// 参数2指定的是转化成X进制,默认10进制
int bitLength = bitValueS.length(); // 转换后二进制数据长度
String bitValue = "0"; // 默认值
/* 逻辑处理 */
if (bitLength < bitNumber) {
bitValue = "0";
} else {
int leftIndex = bitLength - bitNumber;
bitValue = bitValueS.substring(leftIndex, leftIndex + 1);// 获取指定位数,取其中一位
}
return bitValue;
}
private Map<String,String> getExpressMapByExpressStr2(Map<String, String> mapResult, String express, Map<String, String> dataResult){
if(dataResult == null){
dataResult = new HashMap<String,String>();
}
if(StringUtil.isNullOrEmpty(express)){
return null;
}
for (Map.Entry<String, String> entry : mapResult.entrySet()) {
String field = entry.getKey();
if(express.contains(field)){
dataResult.put(field, mapResult.get(field));
}
}
return dataResult;
}
/**
* 通过计算表达式得到数据
* @param mapResult 已知的结果集
* @param express 表达式
* @return 转换后的结果
*/
private Map<String,String> getExpressMapByExpressStr(Map<String,String> mapResult , String express,Map<String,String> dataResult){
if(dataResult == null){
dataResult = new HashMap<String,String>();
}
if(StringUtil.isNullOrEmpty(express)){
return null;
}
Pattern p = Pattern.compile("^*\\|\\||\\||&|&&*$");
Matcher m = p.matcher(express);
if (m.find()) {
//按照特殊字符进行切割
int index = getIndexBySymbol(express);
if(index < 1){
//针对特殊字符重复的时候,需要优先进行2次处理
return getExpressMapByExpressStr(mapResult , express.substring(1) , dataResult);
}
String fieldName = express.substring(0,index);
fieldName = cleanFieldName(fieldName , "()()");
dataResult.put(fieldName , mapResult.get(fieldName));
return getExpressMapByExpressStr(mapResult , express.substring(index) , dataResult);
}else{
//清洗字符串中不含有括号时
String fieldName = cleanFieldName(express , "()()");
dataResult.put(fieldName , mapResult.get(fieldName));
return dataResult;
}
}
/**
* 根据&或者|进行
* @param express
* @return
*/
private int getIndexBySymbol(String express){
int index = express.indexOf("&");
int otherIndex = express.indexOf("|");
if(index > otherIndex){
return otherIndex;
}
return index;
}
/**
* 清洗字段名称-将左右括号进行清洗掉
* @param fieldName 字段名称
* @return 已清洗后的字段名称
*/
private String cleanFieldName(String fieldName , String replaceStr){
if(StringUtil.isNullOrEmpty(fieldName)){
return "";
}else{
fieldName = fieldName.replaceAll("["+replaceStr+"]", "");
/**satar 增加等式类型表达式处理逻辑,取出等式中的字段名称 修改人:HQW 2016-11-10*/
int index = fieldName.indexOf("=");
if(index>0){
fieldName = fieldName.substring(0, index);
}
if(fieldName.contains("^")) {
fieldName=fieldName.substring(0, fieldName.indexOf("^"));
}
/**end */
return fieldName;
}
}
}