1717 */
1818package com .dtstack .flinkx .restapi .common ;
1919
20- import java .util .List ;
21- import java .util .Objects ;
20+ import com .github .pfmiles .dropincc .*;
21+ import org .apache .commons .collections .CollectionUtils ;
22+ import org .apache .commons .lang3 .StringUtils ;
23+ import org .apache .commons .lang3 .math .NumberUtils ;
24+
25+ import java .math .BigDecimal ;
26+ import java .sql .Timestamp ;
27+ import java .util .*;
28+ import java .util .concurrent .atomic .AtomicReference ;
2229
2330/**
2431 * DymaticParam
2532 *
26332734 * @Date 2020/9/26
2835 */
29- public class DymaticParam extends ConstantParam implements ParamDefinitionNextAble , lifecycle {
36+ public class DymaticParam extends ConstantParam implements ParamDefinitionNextAble {
3037
3138 private RestContext restContext ;
32- private ParamItemContext valueDymaticParam ;
33- private ParamItemContext nextvalueDymaticParam ;
3439
35- public DymaticParam (String name , ParamType paramType , Class valueClass , String description , String format , RestContext context ) {
40+ private final List <Paramitem > dymaticNowString ;
41+ private final List <Paramitem > dymaticNextString ;
42+
43+
44+ private final String initValueExpression ;
45+ private final String nextValueExpression ;
46+
47+ private Exe exe = getExe ();
48+
49+
50+ public DymaticParam (String name , ParamType paramType , Class valueClass , String nowValue , String nextValue , String description , String format , RestContext context ) {
3651 super (name , paramType , valueClass , null , description , format );
52+ // nowvalue一定是存在的
53+ initValueExpression = nowValue ;
54+
55+ dymaticNowString = ParamFactory .getVarible (nowValue );
56+
57+ if (StringUtils .isBlank (nextValue )) {
58+ dymaticNextString = dymaticNowString ;
59+ nextValueExpression = initValueExpression ;
60+ } else {
61+ dymaticNextString = ParamFactory .getVarible (nextValue );
62+ nextValueExpression = nextValue ;
63+ }
3764 this .restContext = context ;
3865 }
3966
4067 @ Override
4168 public Object getValue () {
42- Object data ;
43- if (restContext .getTime () > 0 && Objects .nonNull (nextvalueDymaticParam )) {
44- data = nextvalueDymaticParam .getValue ();
45- } else {
46- data = nextvalueDymaticParam .getValue ();
47- }
48- data = format (data );
49- return objectConvent (getValueType (), data );
69+ return getDymaticValue (dymaticNowString , initValueExpression );
5070 }
5171
5272 /**
@@ -59,8 +79,7 @@ public Object getValue() {
5979 */
6080 @ Override
6181 public Object getNextValue () {
62- // restContext.calcute();
63- return getValue ();
82+ return getDymaticValue (dymaticNextString , nextValueExpression );
6483 }
6584
6685 //判断是否是运算符
@@ -103,20 +122,134 @@ public int operationLv(char operation) {//给运算符设置优先级
103122
104123 @ Override
105124 public void init () {
106- if (Objects .nonNull (valueDymaticParam )){
107- valueDymaticParam .init ();
108- }
109125
110- if (Objects .nonNull (nextvalueDymaticParam )){
111- nextvalueDymaticParam .init ();
112- }
113126 }
114127
115- public void setValueDymaticParam (ParamItemContext valueDymaticParam ) {
116- this .valueDymaticParam = valueDymaticParam ;
128+ public Exe getExe () {
129+ Lang c = new Lang ("Calculator" );
130+ Grule expr = c .newGrule ();
131+ c .defineGrule (expr , CC .EOF ).action (new Action () {
132+ public BigDecimal act (Object matched ) {
133+ return new BigDecimal (((Object []) matched )[0 ].toString ());
134+ }
135+ });
136+ TokenDef a = c .newToken ("\\ +" );
137+ Grule addend = c .newGrule ();
138+ expr .define (addend , CC .ks (a .or ("\\ -" ), addend )).action (new Action () {
139+ public BigDecimal act (Object matched ) {
140+ Object [] ms = (Object []) matched ;
141+ BigDecimal a0 = (BigDecimal ) ms [0 ];
142+ Object [] aPairs = (Object []) ms [1 ];
143+ for (Object p : aPairs ) {
144+ String op = (String ) ((Object []) p )[0 ];
145+ BigDecimal a = (BigDecimal ) ((Object []) p )[1 ];
146+ if ("+" .equals (op )) {
147+ a0 = a .add (a0 );
148+ } else {
149+ a0 = a0 .subtract (a );
150+ }
151+ }
152+ return a0 ;
153+ }
154+ });
155+ TokenDef m = c .newToken ("\\ *" );
156+ Grule factor = c .newGrule ();
157+ addend .define (factor , CC .ks (m .or ("/" ), factor )).action (new Action () {
158+ public BigDecimal act (Object matched ) {
159+ Object [] ms = (Object []) matched ;
160+ BigDecimal f0 = (BigDecimal ) ms [0 ];
161+ Object [] fPairs = (Object []) ms [1 ];
162+ for (Object p : fPairs ) {
163+ String op = (String ) ((Object []) p )[0 ];
164+ BigDecimal f = (BigDecimal ) ((Object []) p )[1 ];
165+ if ("*" .equals (op )) {
166+ f0 = f0 .multiply (f );
167+ } else {
168+ f0 = f0 .divide (f , BigDecimal .ROUND_HALF_UP , 3 );
169+ }
170+ }
171+ return f0 ;
172+ }
173+ });
174+ factor .define ("\\ (" , expr , "\\ )" ).action (new Action () {
175+ public BigDecimal act (Object matched ) {
176+ return (BigDecimal ) ((Object []) matched )[1 ];
177+ }
178+ }).alt ("\\ -\\ d+(\\ .\\ d+)?|\\ d+(\\ .\\ d+)?" ).action (new Action () {
179+ public BigDecimal act (Object matched ) {
180+ return new BigDecimal (matched .toString ());
181+ }
182+ });
183+ Exe exe = c .compile ();
184+ return exe ;
117185 }
118186
119- public void setNextvalueDymaticParam (ParamItemContext nextvalueDymaticParam ) {
120- this .nextvalueDymaticParam = nextvalueDymaticParam ;
187+ private Object getDymaticValue (List <Paramitem > dymaticString , String expression ) {
188+ if (CollectionUtils .isEmpty (dymaticString )) {
189+ return expression ;
190+ }
191+ Map <String , Object > tempReplaceValue = new HashMap <>(16 );
192+ AtomicReference <String > tempExpression = new AtomicReference <>(expression );
193+ Object tempValue ;
194+ dymaticString .forEach (k -> {
195+ Object value = k .getValue (restContext );
196+ tempReplaceValue .put (escapeExprSpecialWord ("${" + k .getName () + "}" ), value );
197+ });
198+ tempReplaceValue .forEach ((k , v ) -> {
199+ if (Objects .isNull (v )){
200+ tempExpression .set (tempExpression .get ().replaceFirst (k , 0 +"" ));
201+ }else if (NumberUtils .isNumber (v .toString ())) {
202+ tempExpression .set (tempExpression .get ().replaceFirst (k , v .toString ()));
203+ } else if (v instanceof Date ) {
204+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((Date ) v ).getTime () + "" ));
205+ }
206+ if (v instanceof java .sql .Date ) {
207+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((java .sql .Date ) v ).getTime () + "" ));
208+ }
209+ if (v instanceof Timestamp ) {
210+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((Timestamp ) v ).getTime () + "" ));
211+ }
212+ });
213+
214+
215+ try {
216+ tempValue = exe .eval (tempExpression .get ());
217+ } catch (Exception e ) {
218+ tempReplaceValue .forEach ((k , v ) -> {
219+ if (Objects .isNull (v )){
220+ tempExpression .set (tempExpression .get ().replaceFirst (k , "" ));
221+ }else if (NumberUtils .isNumber (v .toString ())) {
222+ tempExpression .set (tempExpression .get ().replaceFirst (k , v .toString ()));
223+ } else if (v instanceof Date ) {
224+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((Date ) v ).toString () + "" ));
225+ }
226+ if (v instanceof java .sql .Date ) {
227+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((java .sql .Date ) v ).toString () + "" ));
228+ }
229+ if (v instanceof Timestamp ) {
230+ tempExpression .set (tempExpression .get ().replaceFirst (k , ((Timestamp ) v ).toString () + "" ));
231+ }
232+ });
233+ tempValue = initValueExpression ;
234+ }
235+ restContext .updateValue (getType ().name ().toLowerCase (Locale .ENGLISH ) + "." + getName (), tempValue );
236+ return tempValue ;
237+ }
238+ /**
239+ * 转义正则特殊字符 ($()*+.[]?\^{},|)
240+ *
241+ * @param keyword
242+ * @return
243+ */
244+ public static String escapeExprSpecialWord (String keyword ) {
245+ if (StringUtils .isNotBlank (keyword )) {
246+ String [] fbsArr = { "\\ " , "$" , "(" , ")" , "*" , "+" , "." , "[" , "]" , "?" , "^" , "{" , "}" , "|" };
247+ for (String key : fbsArr ) {
248+ if (keyword .contains (key )) {
249+ keyword = keyword .replace (key , "\\ " + key );
250+ }
251+ }
252+ }
253+ return keyword ;
121254 }
122255}
0 commit comments