Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.67 KB | None | 0 0
  1. package com.appypie.snappy.appsheet.asformula
  2.  
  3. import android.text.TextUtils.split
  4. import android.util.Log
  5. import android.util.SparseArray
  6. import com.appypie.snappy.appsheet.extensions.isDigitsOnly
  7. import com.appypie.snappy.appsheet.pagedata.model.FieldItem
  8. import com.facebook.internal.Mutable
  9. import java.util.*
  10. import kotlin.collections.ArrayList
  11.  
  12. object FormulaUtil {
  13. var squareBracesRegex = "\\[[^\\[]*\\]"
  14. var stackTokenArr: MutableList<String>? = null
  15. var strTst = "CONCATENATE(UPPER([FName]),[LName],LOWER([FName]))" //"CONCATENATE(UPPER([FName]),[LName],LOWER([FName]),UPPER([FName]))"
  16. var txtFunctionArr = arrayOf("LEN", "LEFT", "RIGHT", "TRIM", "CONCATENATE", "FIND", "UPPER", "LOWER")
  17. var operatorArr = arrayOf("+", "-", "/", "%", "*")
  18. var mathFunOpArr = arrayOf("SQRT", "DISTANCE", "POWER", "MAX", "MIN", "AVERAGE", "COUNT", "ROUND", "NUMBER", "DECIMAL", "SUM", "LIST","ABS")
  19. var dateTimeOpArr = arrayOf("NOW", "TODAY", "TIMENOW", "DATETIME", "TIME", "DATE", "WEEKNUM", "WEEKDAY", "YEAR", "MONTH", "SECOND", "MINUTE", "HOUR",
  20. "TIMENUMBER", "TIMEDURATION", "DATEDURATION", "DATENUMBER", "DATETIMENUMBER", "DATETIMEDURATION", "DURATIONNUMBER", "DURATIONDURATION")
  21. var functionArr = arrayOf(
  22. "UPPER", "LOWER", "CONCATENATE", "SQRT",
  23. "DISTANCE", "POWER", "ABS", "MAX", "MIN", "AVERAGE", "COUNT", "ROUND",
  24. "STDEVP", "FLOOR", "CEILING", "NUMBER", "DECIMAL", "SUM", "LIST", "LEFT"
  25. )
  26.  
  27.  
  28. fun getStackTokenArr(str: String): ArrayList<String> {
  29. var stackArr: ArrayList<String> = arrayListOf<String>()
  30. var getVal: String = ""
  31. var breakExpressions = "(,)"
  32. str.forEachIndexed { index, charData ->
  33. if (charData != null && breakExpressions.contains(charData)) {
  34. stackArr.add(getVal)
  35. stackArr.add(charData.toString())
  36. getVal = ""
  37. } else {
  38. getVal = "${getVal}${charData}"
  39. }
  40. }
  41. stackArr.add(getVal)
  42. return stackArr
  43. }
  44.  
  45. //Function To Get Type Of Variables in Operator Operand Stack
  46. fun checkVariableType(position: Int, fieldsList: ArrayList<FieldItem>?): VARIABLE_TYPE {
  47. var checkVar = stackTokenArr?.get(position)
  48. if (functionArr.any { it == checkVar }) {
  49. return VARIABLE_TYPE.FUNCTION
  50. } else if (operatorArr.any { it == checkVar }) {
  51. return VARIABLE_TYPE.OPERATOR
  52. } else if ((checkVar ?: "").contains("[") && (checkVar ?: "").contains("]")) {
  53. fieldsList?.forEachIndexed { index, fieldItem ->
  54. var regex = fieldItem.fieldTitle?.toRegex()
  55. if (regex?.containsMatchIn((checkVar ?: "")) ?: false) {
  56. stackTokenArr?.get(position)?.replace(checkVar ?: "", fieldItem.fieldValue
  57. ?: "")
  58. }
  59. }
  60. return VARIABLE_TYPE.COLOUM_VALUE
  61. } else if (checkVar.equals("(")) {
  62. return VARIABLE_TYPE.START_BRACKET
  63. } else if (checkVar.equals(")")) {
  64. return VARIABLE_TYPE.POP_TO_EVALUATE
  65. } else if ((checkVar ?: "").isDigitsOnly()) {
  66. return VARIABLE_TYPE.CONSTANT
  67. }
  68. return VARIABLE_TYPE.IGNORE
  69. }
  70.  
  71. fun checkVariableType(position: Int): VARIABLE_TYPE {
  72. var checkVar = stackTokenArr?.get(position)
  73. if (functionArr.any { it == checkVar }) {
  74. return VARIABLE_TYPE.FUNCTION
  75. } else if (operatorArr.any { it == checkVar }) {
  76. return VARIABLE_TYPE.OPERATOR
  77. } else if ((checkVar ?: "").contains("[") && (checkVar ?: "").contains("]")) {
  78. return VARIABLE_TYPE.COLOUM_VALUE
  79. } else if (checkVar.equals("(")) {
  80. return VARIABLE_TYPE.START_BRACKET
  81. } else if (checkVar.equals(")")) {
  82. return VARIABLE_TYPE.POP_TO_EVALUATE
  83. } /*else if ((checkVar?:"").isDigitsOnly()) {
  84. return VARIABLE_TYPE.CONSTANT
  85. }*/
  86. return VARIABLE_TYPE.IGNORE
  87. }
  88.  
  89.  
  90. /**
  91. * replace column name with column value
  92. */
  93. fun checkReplace(stackToken: String?, fieldsList: ArrayList<FieldItem>?): SparseArray<FieldItem> {
  94. var isColumnContains = SparseArray<FieldItem>()
  95. fieldsList?.forEachIndexed { index, fieldItem ->
  96. var regex = fieldItem.fieldTitle?.toRegex()
  97. if (regex?.containsMatchIn((stackToken ?: "")) ?: false) {
  98. isColumnContains.put(index, fieldItem)
  99. }
  100. }
  101. return isColumnContains
  102. }
  103.  
  104. /**
  105. * handle to manage all kind of formula
  106. */
  107. @JvmStatic
  108. fun manageFormulaStack(formula: String, fieldsList: ArrayList<FieldItem>?): String {
  109. stackTokenArr = getStackTokenArr(formula)
  110. var ops = Stack<String>()
  111. var vals = Stack<String>()
  112. stackTokenArr?.forEachIndexed { index, strData ->
  113. var args = checkVariableType(index)
  114. if (args.equals(VARIABLE_TYPE.COLOUM_VALUE)) {
  115. var data = checkReplace(strData, fieldsList)
  116. if (data.size() > 0) {
  117. stackTokenArr?.set(index, data.valueAt(0).fieldValue ?: "")
  118. println("replacedData:${stackTokenArr?.get(index)}")
  119. }
  120. }
  121. if (args.equals(VARIABLE_TYPE.IGNORE))
  122. else if (args.equals(VARIABLE_TYPE.START_BRACKET))
  123. else if (args.equals(VARIABLE_TYPE.FUNCTION)) {
  124. ops.push(strData)
  125. } else if (args.equals(VARIABLE_TYPE.POP_TO_EVALUATE)) {
  126. var op = ops.pop()
  127. if (txtFunctionArr.any { it == op }) {
  128. var opData = ArrayList<String>()
  129. for (index in 0 until vals.size) {
  130. opData.add(vals.pop())
  131. }
  132. var result = handleTxtFunArr(op,opData)
  133. vals.push("${result}")
  134. }
  135. else if (mathFunOpArr.any { it == op }) {
  136. var opData = ArrayList<String>()
  137. for (index in 0 until vals.size) {
  138. opData.add(vals.pop())
  139. }
  140. var result = handleMathFunOpArr(op,opData)
  141. vals.push("${result}")
  142. }/*("DISTANCE", "NUMBER", "DECIMAL","LIST")*/
  143. else if (operatorArr.any { it == op }) {
  144. var opData = ArrayList<String>()
  145. for (index in 0 until vals.size) {
  146. opData.add(vals.pop())
  147. }
  148. var result = handleOperatorArr(op,opData)
  149. vals.push("${result}")
  150. }
  151. else if (dateTimeOpArr.any { it == op }) {
  152. var opData = ArrayList<String>()
  153. for (index in 0 until vals.size) {
  154. opData.add(vals.pop())
  155. }
  156. var result = handleDateTimeFunArr(op,opData)
  157. vals.push("${result}")
  158. }
  159. } else {
  160. vals.push(stackTokenArr?.get(index))
  161. }
  162. }
  163. var resultPoped = ""
  164. if(vals.size>0){
  165. resultPoped = vals.pop()
  166. println("Final print values:${resultPoped}")
  167. }
  168. return "${resultPoped}"
  169. }
  170.  
  171. /**
  172. * handle to perform text formula
  173. */
  174. fun handleTxtFunArr(op:String,opData:ArrayList<String>):String{
  175. var finalResult = ""
  176. when (op) {
  177. "UPPER" -> {
  178. try {
  179. var finalData = opData?.get(0)?.toUpperCase()?:""
  180. finalResult = "${finalData}"
  181. } catch (e: Exception) {
  182.  
  183. }
  184.  
  185. }
  186. "LOWER" -> {
  187. try {
  188. var finalData = opData?.get(0)?.toLowerCase()?:""
  189. finalResult = "${finalData}"
  190. } catch (e: Exception) {
  191.  
  192. }
  193.  
  194. }
  195. "LEN" -> {
  196. try {
  197. var finalData = opData.get(0).length?:0
  198. finalResult = "${finalData}"
  199. } catch (e: Exception) {
  200.  
  201. }
  202.  
  203. }
  204. "LEFT" -> {
  205. try {
  206. var strData = opData?.get(0)?:""
  207. var range = opData.get(1).toInt()?:0
  208. var finalData = ASStringUtils.findLeftString(strData,range )
  209. finalResult = "${finalData}"
  210. } catch (e: Exception) {
  211.  
  212. }
  213. }
  214. "RIGHT" -> {
  215. try {
  216. var strData = opData?.get(0)?:""
  217. var range = opData.get(1).toInt()?:0
  218. var finalData = ASStringUtils.findRightString(strData,range )
  219. finalResult = "${finalData}"
  220. } catch (e: Exception) {
  221.  
  222. }
  223. }
  224. "TRIM" -> {
  225. var finalData = opData.get(0).trim()?:""
  226. finalResult = "${finalData}"
  227. }
  228. "FIND" -> {
  229. try {
  230. var searchContain = opData?.get(0)?:""
  231. var searchTxt = opData?.get(1)?:""
  232. finalResult = "${searchContain.split(searchTxt.toRegex(),1)?.get(0)?.length?:0}"
  233. } catch (e: Exception) {
  234.  
  235. }
  236.  
  237. }
  238. "CONCATENATE" -> {
  239. try {
  240. var finalData:StringBuffer = StringBuffer()
  241. for (index in 0 until opData.size) {
  242. finalData = finalData.append(Regex("[,]").replace(opData.get(index), ""))
  243. }
  244. finalResult = "${finalData}"
  245. } catch (e: Exception) {
  246.  
  247. }
  248.  
  249. }
  250. }
  251. return finalResult
  252. }
  253. /**
  254. * handle to perform operator{like +,-,*,/,%} formula
  255. */
  256. fun handleOperatorArr(op:String,opData:ArrayList<String>):String{
  257. var value = opData.get(0).toDouble()?:0.0
  258. var value1 = opData.get(1).toDouble()?:0.0
  259. when (op) {
  260. "/" -> {
  261. value /= value1
  262. }
  263. "*" -> {
  264. value *= value1
  265. }
  266. "+" -> {
  267. value += value1
  268. }
  269. "-" -> {
  270. value -= value1
  271. }
  272. "%" -> {
  273. value %= value1
  274. }
  275. }
  276. return "${value}"
  277. }
  278. /**
  279. * handle to perform math like{MAX,MIN,AVG,SUM,LIST,ROUND,COUNT.. etc} formula
  280. */
  281. fun handleMathFunOpArr(op:String,opData:ArrayList<String>):String{
  282. var finalResult = ""
  283. when (op) {
  284. "MAX" -> {
  285. var maxData: DoubleArray = DoubleArray(opData.size)
  286. for (index in 0 until opData.size) {
  287. maxData[index] = opData.get(index).toDouble()?:0.0
  288. }
  289. var finalMaxData = ASMath.max(maxData)?:0.0
  290. finalResult = "${finalMaxData}"
  291. }
  292. "MIN" -> {
  293. var minData: DoubleArray = DoubleArray(opData.size)
  294. for (index in 0 until opData.size) {
  295. minData[index] = opData.get(index).toDouble()?:0.0
  296. }
  297. var finalMinData = ASMath.min(minData)?:0.0
  298. finalResult = "${finalMinData}"
  299. }
  300. "AVERAGE" -> {
  301. var avgData: DoubleArray = DoubleArray(opData.size)
  302. for (index in 0 until opData.size) {
  303. avgData[index] = opData.get(index).toDouble()?:0.0
  304. }
  305. var finalAvgData = ASMath.average(avgData)?:0.0
  306. finalResult = "${finalAvgData}"
  307. }
  308. "SUM" -> {
  309. var sumData: DoubleArray = DoubleArray(opData.size)
  310. for (index in 0 until opData.size) {
  311. sumData[index] = opData.get(index).toDouble()?:0.0
  312. }
  313. var finalSumData = ASMath.sum(sumData)?:0.0
  314. finalResult = "${finalSumData}"
  315. }
  316. "LIST" -> {
  317. /* var listData:DoubleArray= DoubleArray(vals.size)
  318. for (index in 0 until vals.size) {
  319. listData[index] = vals.pop().toDouble()
  320. }
  321. vals.push("${listData}")*/
  322. }
  323. "ROUND" -> {
  324. try {
  325. var p = opData.get(0).toInt()?:0
  326. var n = opData.get(0).toDouble()?:0.0
  327. var value = ASMath.round(n, p)?:0.0
  328. finalResult = "${value}"
  329. } catch (e: Exception) {
  330.  
  331. }
  332. }
  333. "COUNT" -> {
  334. finalResult = "${opData.size ?: 0}"
  335. }
  336. "SQRT" -> {
  337. finalResult = "${Math.sqrt(opData.get(0).toDouble()?: 0.0)}"
  338. }
  339. "POWER" -> {
  340. var value = opData.get(0)?.toDouble()?:0.0
  341. var powerValue = opData.get(1)?.toDouble()?:0.0
  342. finalResult = "${Math.pow(value,powerValue)}"
  343. }
  344. "ABS" -> {
  345. var value = opData.get(0)?.toDouble()?:0.0
  346. finalResult = "${Math.abs(value)}"
  347. }
  348. }
  349. return finalResult
  350. }
  351. /**
  352. * handle to perform date,time and datetime formula
  353. */
  354. fun handleDateTimeFunArr(op:String,opData:ArrayList<String>):String{
  355. var finalResult = ""
  356. when (op) {
  357. "NOW" -> {
  358.  
  359. }
  360. "TODAY" -> {
  361.  
  362. }
  363. "TIMENOW" -> {
  364.  
  365. }
  366. "DATETIME" -> {
  367.  
  368. }
  369. "TIME" -> {
  370.  
  371. }
  372. "DATE" -> {
  373.  
  374. }
  375. "WEEKNUM" -> {
  376.  
  377. }
  378. "WEEKDAY" -> {
  379.  
  380. }
  381. "YEAR" -> {
  382.  
  383. }
  384. "MONTH" -> {
  385.  
  386. }
  387. "SECOND" -> {
  388.  
  389. }
  390. "MINUTE" -> {
  391.  
  392. }
  393. "HOUR" -> {
  394.  
  395. }
  396. "TIMENUMBER" -> {
  397.  
  398. }
  399. "TIMEDURATION" -> {
  400.  
  401. }
  402. "DATEDURATION" -> {
  403.  
  404. }
  405. "DATENUMBER" -> {
  406.  
  407. }
  408. "DATETIMENUMBER" -> {
  409.  
  410. }
  411. "DATETIMEDURATION" -> {
  412.  
  413. }
  414. "DURATIONNUMBER" -> {
  415.  
  416. }
  417. "DURATIONDURATION" -> {
  418.  
  419. }
  420. }
  421. return finalResult
  422. }
  423. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement