diff --git a/jar-enginex-runner/.gitignore b/jar-enginex-runner/.gitignore new file mode 100644 index 0000000..cf60db2 --- /dev/null +++ b/jar-enginex-runner/.gitignore @@ -0,0 +1,34 @@ +HELP.md +target/ +logs/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/jar-enginex-runner/README.md b/jar-enginex-runner/README.md new file mode 100644 index 0000000..68556ce --- /dev/null +++ b/jar-enginex-runner/README.md @@ -0,0 +1,3 @@ +# jar-enginex-runner + +enginex后端执行器 \ No newline at end of file diff --git a/jar-enginex-runner/lib/javax.ejb.jar b/jar-enginex-runner/lib/javax.ejb.jar new file mode 100644 index 0000000..4ebf5ec Binary files /dev/null and b/jar-enginex-runner/lib/javax.ejb.jar differ diff --git a/jar-enginex-runner/lib/javax.jms.jar b/jar-enginex-runner/lib/javax.jms.jar new file mode 100644 index 0000000..d31451a Binary files /dev/null and b/jar-enginex-runner/lib/javax.jms.jar differ diff --git a/jar-enginex-runner/lib/javax.persistence.jar b/jar-enginex-runner/lib/javax.persistence.jar new file mode 100644 index 0000000..21d80e0 Binary files /dev/null and b/jar-enginex-runner/lib/javax.persistence.jar differ diff --git a/jar-enginex-runner/lib/javax.resource.jar b/jar-enginex-runner/lib/javax.resource.jar new file mode 100644 index 0000000..696a234 Binary files /dev/null and b/jar-enginex-runner/lib/javax.resource.jar differ diff --git a/jar-enginex-runner/lib/javax.servlet.jsp.jar b/jar-enginex-runner/lib/javax.servlet.jsp.jar new file mode 100644 index 0000000..9c0631c Binary files /dev/null and b/jar-enginex-runner/lib/javax.servlet.jsp.jar differ diff --git a/jar-enginex-runner/lib/javax.servlet.jsp.jstl.jar b/jar-enginex-runner/lib/javax.servlet.jsp.jstl.jar new file mode 100644 index 0000000..7be17cc Binary files /dev/null and b/jar-enginex-runner/lib/javax.servlet.jsp.jstl.jar differ diff --git a/jar-enginex-runner/lib/javax.transaction.jar b/jar-enginex-runner/lib/javax.transaction.jar new file mode 100644 index 0000000..729c695 Binary files /dev/null and b/jar-enginex-runner/lib/javax.transaction.jar differ diff --git a/jar-enginex-runner/mvnw b/jar-enginex-runner/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/jar-enginex-runner/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/jar-enginex-runner/mvnw.cmd b/jar-enginex-runner/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/jar-enginex-runner/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/jar-enginex-runner/pom.xml b/jar-enginex-runner/pom.xml new file mode 100644 index 0000000..0e7e184 --- /dev/null +++ b/jar-enginex-runner/pom.xml @@ -0,0 +1,311 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + + com.baoying + enginex-runner + 0.0.1-SNAPSHOT + jar-enginex-runner + Demo project for Spring Boot + + 1.8 + 1.2.12 + 6.4.0.Final + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + junit + junit + test + + + + + + com.baomidou + mybatis-plus-boot-starter + 3.3.2 + + + + mysql + mysql-connector-java + + + + com.alibaba + druid-spring-boot-starter + 1.1.21 + + + + org.codehaus.jackson + jackson-mapper-lgpl + 1.7.4 + + + + org.apache.commons + commons-lang3 + 3.1 + + + + com.alibaba + fastjson + 1.2.58 + + + + org.projectlombok + lombok + 1.18.0 + + + + + org.drools + drools-core + ${drools.version} + + + org.kie + kie-spring + ${drools.version} + + + org.drools + drools-compiler + ${drools.version} + + + org.kie + kie-api + ${drools.version} + + + org.kie + kie-ci + ${drools.version} + + + org.drools + knowledge-api + 6.4.0.Final + + + com.itextpdf + itextpdf + 5.4.3 + + + com.itextpdf + itext-asian + 5.2.0 + + + + + + com.github.ben-manes.caffeine + caffeine + 2.8.4 + + + + + org.apache.commons + commons-pool2 + 2.0 + + + + + redis.clients + jedis + 2.4.2 + + + + + + commons-httpclient + commons-httpclient + 3.1 + + + + + org.codehaus.groovy + groovy-all + 2.4.15 + + + + org.python + jython-standalone + 2.7.0 + + + + org.jpmml + pmml-evaluator + 1.4.1 + + + org.jpmml + pmml-evaluator-extension + 1.4.1 + + + + + org.springframework.boot + spring-boot-starter-mail + + + + com.alibaba + transmittable-thread-local + 2.2.0 + + + + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.3 + compile + + + + + + com.spring4all + spring-boot-starter-hbase + 1.0.0.RELEASE + + + + org.apache.hbase + hbase-client + + + + + + + + org.apache.hbase + hbase-shaded-client + 1.3.1 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + 1.2.3 + + + org.mybatis + mybatis + + + org.mybatis + mybatis-spring + + + + + + + com.alibaba.otter + canal.client + 1.1.4 + + + ch.qos.logback + logback-core + + + ch.qos.logback + logback-classic + + + + + com.google.protobuf + protobuf-java + 3.5.1 + + + + cn.hutool + hutool-all + 5.5.2 + + + + + + + src/main/java + + + **/*.xml + + + + + src/main/resources + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/JarEnginexRunnerApplication.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/JarEnginexRunnerApplication.java new file mode 100644 index 0000000..75a7d47 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/JarEnginexRunnerApplication.java @@ -0,0 +1,19 @@ +package com.baoying.enginex.executor; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableTransactionManagement +@MapperScan("com.baoying.enginex.executor.*.mapper") +@ComponentScan(basePackages = "com.baoying.enginex.executor.**") +public class JarEnginexRunnerApplication { + + public static void main(String[] args) { + SpringApplication.run(JarEnginexRunnerApplication.class, args); + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CacheController.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CacheController.java new file mode 100644 index 0000000..4da7c78 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CacheController.java @@ -0,0 +1,119 @@ +package com.baoying.enginex.executor.canal; + +import com.baoying.enginex.executor.datamanage.mapper.SimpleMapper; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/cache") +public class CacheController { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Resource + private SimpleMapper simpleMapper; + @Autowired + private RedisManager redisManager; + + @RequestMapping(value = "initCache", method = RequestMethod.GET) + public void initCache() { + logger.info("===================== 缓存初始化开始 ====================="); + long start = System.currentTimeMillis(); + // 遍历表 + for (TableEnum tableEnum : TableEnum.values()) { + String tableName = tableEnum.getTableName(); + logger.info("===================== 开始初始化缓存表[{}] =====================", tableName); + + String sqlStr = "select * from " + tableName; + Map parameterMap = new HashMap<>(); + parameterMap.put("sqlStr", sqlStr); + List> result = simpleMapper.customSelect(parameterMap); + // 遍历行 + for (LinkedHashMap map : result) { + row(tableEnum, map); + } + logger.info("===================== 结束初始化缓存表[{}],共[{}]条数据 =====================", tableName, result.size()); + } + long end = System.currentTimeMillis(); + logger.info("===================== 缓存初始化成功!!耗时:{}ms =====================", (end - start)); + } + + private void row(TableEnum tableEnum, LinkedHashMap map) { + String tableName = tableEnum.getTableName(); + String primaryKey = null; + String foreignKey = null; + + if (StringUtils.isNotBlank(tableEnum.getPrimaryId())) { + String primaryId = map.get(tableEnum.getPrimaryId()).toString(); + primaryKey = RedisUtils.getPrimaryKey(tableName, primaryId); + } + + if (StringUtils.isNotBlank(tableEnum.getForeignId())) { + Object obj = map.get(tableEnum.getForeignId()); + if (obj != null && !"".equals(obj.toString())) { + String foreignId = obj.toString(); + foreignKey = RedisUtils.getForeignKey(tableName, foreignId); + } + } + + if (StringUtils.isNotBlank(primaryKey)) { + // 遍历列 + for (String field : map.keySet()) { + String value = map.get(field) == null ? null : map.get(field).toString(); + setColumnCache(primaryKey, field, value); + } + } + + if (StringUtils.isNotBlank(foreignKey)) { + setForeignKeyCache(primaryKey, foreignKey); + } + + // 指标表特殊处理 + dealSpecialTable(tableName, map); + } + + private void setColumnCache(String primaryKey, String field, String value) { + logger.info("开始主键缓存设置, primaryKey:{}, field:{}, value:{}", primaryKey, field, value); + + redisManager.hset(primaryKey, field, value); + + logger.info("结束主键缓存设置, primaryKey:{}, field:{}, value:{}", primaryKey, field, value); + } + + private void setForeignKeyCache(String primaryKey, String foreignKey) { + logger.info("开始外键缓存设置, primaryKey:{}, foreignKey:{}", primaryKey, foreignKey); + + redisManager.sadd(foreignKey, primaryKey); + + logger.info("结束外键缓存设置, primaryKey:{}, foreignKey:{}", primaryKey, foreignKey); + } + + private void dealSpecialTable(String tableName, LinkedHashMap map) { + if(tableName.equals(TableEnum.T_FIELD.getTableName())){ + String fieldEn = "field_en:" + map.get("organ_id") + ":" + map.get("field_en"); + String fieldEnKey = RedisUtils.getPrimaryKey(tableName, fieldEn); + + String fieldCn = "field_cn:" + map.get("organ_id") + ":" + map.get("field_cn"); + String fieldCnKey = RedisUtils.getPrimaryKey(tableName, fieldCn); + + for (String field : map.keySet()) { + String value = map.get(field) == null ? null : map.get(field).toString(); + setColumnCache(fieldEnKey, field, value); + setColumnCache(fieldCnKey, field, value); + } + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CanalClient.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CanalClient.java new file mode 100644 index 0000000..cdbb23d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/CanalClient.java @@ -0,0 +1,246 @@ +package com.baoying.enginex.executor.canal; + +import com.alibaba.otter.canal.client.CanalConnector; +import com.alibaba.otter.canal.client.CanalConnectors; +import com.alibaba.otter.canal.protocol.CanalEntry; +import com.alibaba.otter.canal.protocol.Message; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Optional; + +/** + * Canal数据同步 + * 实现ApplicationRunner接口,springboot启动成功后会执行run方法 + */ +@Component +public class CanalClient implements ApplicationRunner { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final static int BATCH_SIZE = 1000; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public void run(ApplicationArguments args) throws Exception { + if(Constants.switchFlag.OFF.equals(configHolder.getCanalCacheSwitch())){ + return; + } + + // 创建链接 + CanalConnector connector = CanalConnectors.newSingleConnector( + new InetSocketAddress(configHolder.getCanalHostName(), configHolder.getCanalPort()), + "example", "", ""); + try { + //打开连接 + connector.connect(); + //订阅数据库表,全部表 + connector.subscribe(".*\\..*"); + //回滚到未进行ack的地方,下次fetch的时候,可以从最后一个没有ack的地方开始拿 + connector.rollback(); + while (true) { + logger.info("canal数据同步监听中..."); + // 获取指定数量的数据 + Message message = connector.getWithoutAck(BATCH_SIZE); + //获取批量ID + long batchId = message.getId(); + //获取批量的数量 + int size = message.getEntries().size(); + //如果没有数据 + if (batchId == -1 || size == 0) { + try { + //线程休眠2秒 + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + //如果有数据,处理数据 + printEntry(message.getEntries()); + } + //进行 batch id 的确认。确认之后,小于等于此 batchId 的 Message 都会被确认。 + connector.ack(batchId); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + connector.disconnect(); + } + } + + /** + * 解析binlog获得的实体类信息 + */ + private void printEntry(List entrys) { + for (CanalEntry.Entry entry : entrys) { + if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) { + //开启/关闭事务的实体类型,跳过 + continue; + } + + String tableName = entry.getHeader().getTableName(); + TableEnum tableEnum = TableEnum.getByTableName(tableName); + if(tableEnum == null){ + // 没有在枚举中定义的表,跳过 + continue; + } + + //RowChange对象,包含了一行数据变化的所有特征 + //比如isDdl 是否是ddl变更操作 sql 具体的ddl sql beforeColumns afterColumns 变更前后的数据字段等等 + CanalEntry.RowChange rowChage; + try { + rowChage = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); + } catch (Exception e) { + throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(), e); + } + + //获取操作类型:insert/update/delete类型 + CanalEntry.EventType eventType = rowChage.getEventType(); + //打印Header信息 + logger.info(String.format("============= binlog[%s:%s] , name[%s,%s] , eventType : %s =============", + entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(), + entry.getHeader().getSchemaName(), entry.getHeader().getTableName(), + eventType)); + + //判断是否是DDL语句 + if (rowChage.getIsDdl()) { + logger.info("============= isDdl: true,sql:" + rowChage.getSql()); + } + + //获取RowChange对象里的每一行数据 + for (CanalEntry.RowData rowData : rowChage.getRowDatasList()) { + //如果是删除语句 + if (eventType == CanalEntry.EventType.DELETE) { + row(rowData.getBeforeColumnsList(), tableName); + //如果是新增语句 + } else if (eventType == CanalEntry.EventType.INSERT) { + row(rowData.getAfterColumnsList(), tableName); + //如果是更新的语句 + } else { + //变更前的数据 +// printColumn(rowData.getBeforeColumnsList(), tableName); + //变更后的数据 + row(rowData.getAfterColumnsList(), tableName); + } + } + } + } + + private void row(List columns, String tableName) { + Optional keyColumn = columns.stream().filter(item -> item.getIsKey()).findFirst(); + if(keyColumn.isPresent()){ + // 获取主键id + String id = keyColumn.get().getValue(); + // 拼接主键key + String key = RedisUtils.getPrimaryKey(tableName, id); + // 拼接外键key + String foreignKey = null; + // 子表的redis key需要拼接上主表的id + TableEnum tableEnum = TableEnum.getByTableName(tableName); + if(tableEnum != null){ + Optional foreignKeyColumn = columns.stream().filter(item -> item.getName().equals(tableEnum.getForeignId())).findFirst(); + if(foreignKeyColumn.isPresent()){ + String foreignKeyValue = foreignKeyColumn.get().getValue(); + foreignKey = RedisUtils.getForeignKey(tableName, foreignKeyValue); + } + } + + for (CanalEntry.Column column : columns) { + // 更新发生改变的字段缓存 + setUpdatedColumnCache(column, key, foreignKey); + } + + // 指标表特殊处理 + dealSpecialTable(columns, tableName); + } + } + + private void setUpdatedColumnCache(CanalEntry.Column column, String key, String foreignKey){ + if(column.getUpdated()) { + logger.info("开始主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue()); + + redisManager.hset(key, column.getName(), column.getValue()); + + logger.info("结束主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue()); + + if(foreignKey != null){ + logger.info("开始外键缓存更新, {}, {}", key, foreignKey); + + redisManager.sadd(foreignKey, key); + + logger.info("结束外键缓存更新, {}, {}", key, foreignKey); + } + } + } + + private void setAllColumnCache(CanalEntry.Column column, String key){ + logger.info("开始主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue()); + + redisManager.hset(key, column.getName(), column.getValue()); + + logger.info("结束主键缓存更新, {}, {}, {}", key, column.getName(), column.getValue()); + } + + private void dealSpecialTable(List columns, String tableName){ + if(tableName.equals(TableEnum.T_FIELD.getTableName())){ + String organ_id = null; + String field_en = null; + String field_cn = null; + for (CanalEntry.Column column : columns) { + String name = column.getName(); + switch (name) { + case "organ_id": + organ_id = column.getValue(); + break; + case "field_en": + field_en = column.getValue(); + break; + case "field_cn": + field_cn = column.getValue(); + break; + default: + break; + } + } + + String fieldEn = "field_en:" + organ_id + ":" + field_en; + String fieldEnKey = RedisUtils.getPrimaryKey(tableName, fieldEn); + + String fieldCn = "field_cn:" + organ_id + ":" + field_cn; + String fieldCnKey = RedisUtils.getPrimaryKey(tableName, fieldCn); + + // 如果field_en或field_cn发生变化,则对应的key为新生成的,需要保存所有字段缓存 + Optional fieldEnOptional = columns.stream().filter(item -> item.getName().equals("field_en") && item.getUpdated()).findFirst(); + Optional fieldCnOptional = columns.stream().filter(item -> item.getName().equals("field_cn") && item.getUpdated()).findFirst(); + for (CanalEntry.Column column : columns) { + if(fieldEnOptional.isPresent()){ + // 更新所有字段缓存 + setAllColumnCache(column, fieldEnKey); + } else { + // 更新发生改变的字段缓存 + setUpdatedColumnCache(column, fieldEnKey, null); + } + + if(fieldCnOptional.isPresent()){ + setAllColumnCache(column, fieldCnKey); + } else { + setUpdatedColumnCache(column, fieldCnKey, null); + } + } + } + } + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/TableEnum.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/TableEnum.java new file mode 100644 index 0000000..ba4b0be --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/canal/TableEnum.java @@ -0,0 +1,77 @@ +package com.baoying.enginex.executor.canal; + +/** + * 缓存数据同步表 + */ +public enum TableEnum { + + /** + * 引擎 + */ + T_ENGINE("t_engine", "id", ""), + T_ENGINE_VERSION("t_engine_version", "version_id", "engine_id"), + T_ENGINE_NODE("t_engine_node", "node_id", "version_id"), + + /** + * 指标 + */ + T_FIELD("t_field", "id", ""), + T_FIELD_INTERFACE("t_field_interface", "id", ""), + T_FIELD_DATA_SOURCE("t_field_data_source", "id", ""), + + /** + * 规则 + */ + T_RULE("t_rule", "id", ""), + T_RULE_VERSION("t_rule_version", "id", "rule_id"), + T_RULE_CONDITION("t_rule_condition", "id", "version_id"), + T_RULE_LOOP_GROUP_ACTION("t_rule_loop_group_action", "id", "condition_for_id"), + T_RULE_FIELD("t_rule_field", "id", "rule_id"), + /** + * 策略输出 + */ + T_TACTICS_OUTPUT("t_tactics_output", "id", "tactics_id"); + + private String tableName; + private String primaryId; + private String foreignId; + + TableEnum(String tableName, String primaryId, String foreignId) { + this.tableName = tableName; + this.primaryId = primaryId; + this.foreignId = foreignId; + } + + public static TableEnum getByTableName(String tableName) { + for (TableEnum tableEnum : TableEnum.values()) { + if (tableName.equals(tableEnum.getTableName())) { + return tableEnum; + } + } + return null; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public String getPrimaryId() { + return primaryId; + } + + public void setPrimaryId(String primaryId) { + this.primaryId = primaryId; + } + + public String getForeignId() { + return foreignId; + } + + public void setForeignId(String foreignId) { + this.foreignId = foreignId; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/basefactory/CustomBeanFactory.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/basefactory/CustomBeanFactory.java new file mode 100644 index 0000000..b2caba1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/basefactory/CustomBeanFactory.java @@ -0,0 +1,17 @@ +package com.baoying.enginex.executor.common.basefactory; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public final class CustomBeanFactory { + public static ApplicationContext getContext() { + final String[] applicationXML = { "applicationContext.xml"}; + ApplicationContext context = getSpringContext(applicationXML); + return context; + } + + public static ApplicationContext getSpringContext(String[] paths) { + return new ClassPathXmlApplicationContext(paths); + + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/CommonConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/CommonConst.java new file mode 100644 index 0000000..f34a03d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/CommonConst.java @@ -0,0 +1,31 @@ +package com.baoying.enginex.executor.common.constants; + +public class CommonConst { + + /** + * 逗号 + */ + public static final String SYMBOL_COMMA = ","; + + /** + * 单引号 + */ + public static final String SYMBOL_SINGLE_QUOTA = "\'"; + + /** + * 空格 + */ + public static final String SYMBOL_BLANK = " "; + + /** + * 空字符串 + */ + public static final String STRING_EMPTY = ""; + + /** + * 30分钟(s) + * */ + public static final long MINUTE_30 = 1800000; + + public static String DROOLS_KSESSION_KEY_PREFIX = "DROOLS_KSESSION#"; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/Constants.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/Constants.java new file mode 100644 index 0000000..9fdc18c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/Constants.java @@ -0,0 +1,30 @@ +package com.baoying.enginex.executor.common.constants; + +/** + * 公共变量约定 + */ +public class Constants { + + // 规则集节点相关常量 + public interface ruleNode { + // 互斥组(串行) + int MUTEXGROUP = 1; + // 执行组(并行) + int EXECUTEGROUP = 2; + } + + public interface switchFlag { + // 开关打开 + String ON = "on"; + // 开关关闭 + String OFF = "off"; + } + + public interface fieldName { + // 字段英文名 + String fieldEn = "field_en"; + //字段中文名 + String fieldCn = "field_cn"; + } + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/ParamTypeConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/ParamTypeConst.java new file mode 100644 index 0000000..9ce45b6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/constants/ParamTypeConst.java @@ -0,0 +1,10 @@ +package com.baoying.enginex.executor.common.constants; + +public class ParamTypeConst { + public static final int CONSTANT = 1; + public static final int VARIABLE = 2; + public static final int CUSTOM = 3; + public static final int REGEX = 4; + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionFactory.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionFactory.java new file mode 100644 index 0000000..6b4e3f5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionFactory.java @@ -0,0 +1,60 @@ +package com.baoying.enginex.executor.common.ksession; + +import com.baoying.enginex.executor.redis.RedisManager; +import org.apache.commons.pool2.BaseKeyedPooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; +import org.drools.KnowledgeBase; +import org.drools.KnowledgeBaseFactory; +import org.drools.builder.*; +import org.drools.io.ResourceFactory; +import org.drools.runtime.StatefulKnowledgeSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * kSession工厂类 + */ +@Component +public class KSessionFactory extends BaseKeyedPooledObjectFactory { + + @Autowired + private RedisManager redisManager; + + @Override + public StatefulKnowledgeSession create(String key) throws Exception { + StatefulKnowledgeSession kSession = null; + try { + String ruleString = redisManager.get(key); + if(ruleString == null){ + throw new Exception("create kSession fail, key is "+ key + ", ruleString is null!"); + } + + long start = System.currentTimeMillis(); + KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder(); + kb.add(ResourceFactory.newByteArrayResource(ruleString.getBytes("utf-8")), ResourceType.DRL); + KnowledgeBuilderErrors errors = kb.getErrors(); + for (KnowledgeBuilderError error : errors) { + System.out.println(error); + } + KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase(); + kBase.addKnowledgePackages(kb.getKnowledgePackages()); + kSession = kBase.newStatefulKnowledgeSession(); + long end = System.currentTimeMillis(); + System.out.println("------------------drools kSession创建耗时:" + (end - start) + " ----------------------"); + } catch (Exception e) { + throw e; + } + + return kSession; + } + + @Override + public PooledObject wrap(StatefulKnowledgeSession kSession) { + return new DefaultPooledObject(kSession); + } + + public void setRedisManager(RedisManager redisManager) { + this.redisManager = redisManager; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionPool.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionPool.java new file mode 100644 index 0000000..6951d13 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/ksession/KSessionPool.java @@ -0,0 +1,67 @@ +package com.baoying.enginex.executor.common.ksession; + +import org.apache.commons.pool2.impl.GenericKeyedObjectPool; +import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig; +import org.drools.runtime.StatefulKnowledgeSession; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * kSession连接池 + */ +@Component +public class KSessionPool implements InitializingBean { + + private GenericKeyedObjectPool pool; + + @Autowired + private KSessionFactory kSessionFactory; + + /** + * 初始化方法 + * @throws Exception + */ + @Override + public void afterPropertiesSet() throws Exception { + initPool(); + } + + /** + * 初始化连接池 + * @return + * @throws Exception + */ + public void initPool() throws Exception { + GenericKeyedObjectPoolConfig poolConfig = new GenericKeyedObjectPoolConfig(); + poolConfig.setMaxTotalPerKey(200); + poolConfig.setMaxIdlePerKey(50); + poolConfig.setMinIdlePerKey(5); + poolConfig.setMaxTotal(2000); + this.pool = new GenericKeyedObjectPool(kSessionFactory, poolConfig); + } + + /** + * 获取一个连接对象 + * @return + * @throws Exception + */ + public StatefulKnowledgeSession borrowObject(String key) throws Exception { + return pool.borrowObject(key); + } + + /** + * 归还一个连接对象 + * @param ftpClient + */ + public void returnObject(String key, StatefulKnowledgeSession kSession) { + if(kSession != null){ + pool.returnObject(key, kSession); + } + } + + public void setkSessionFactory(KSessionFactory kSessionFactory) { + this.kSessionFactory = kSessionFactory; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/BaseMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/BaseMapper.java new file mode 100644 index 0000000..f70a40b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/BaseMapper.java @@ -0,0 +1,55 @@ +package com.baoying.enginex.executor.common.mapper; + +import java.util.List; + +public abstract interface BaseMapper { + + /** + * @Description: 根据对象删除数据 + * @param entity 对象 + * @return 是否删除成功 + */ + int deleteByExample(IdEntity entity); + + /** + * @Description: 根据对象主键ID删除数据 + * @param id 对象id编号 + * @return 是否删除成功 + */ + int deleteByPrimaryKey(Long id); + + /** + * @Description: 插入一条新的数据 + * @param entity 对象 + * @return 是否插入成功 + */ + int insertSelective(IdEntity entity); + + /** + * @Description: 根据对象主键更新对象信息 + * @param entity 对象 + * @return 是否修改成功标志 + */ + int updateByPrimaryKeySelective(IdEntity entity); + + /** + * @Description: 根据对象获取数据条数 + * @param entity 对象 + * @return 返回行数 + */ + int countByExample(IdEntity entity); + + /** + * @Description: 根据对象主键ID获取指定数据(多个) + * @param entity 对象 + * @return 对象列表 + */ + List selectByExample(IdEntity entity); + + /** + * @Description: 根据对象主键ID获取指定数据(单个) + * @param id id编号 + * @return 返回单个对象 + */ + IdEntity selectByPrimaryKey(Long id); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.java new file mode 100644 index 0000000..e990cb6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.java @@ -0,0 +1,39 @@ +package com.baoying.enginex.executor.common.mapper; + +import com.baoying.enginex.executor.common.model.EmailTemplate; +import com.baoying.enginex.executor.common.model.EmailTemplateExample; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface EmailTemplateMapper { + long countByExample(EmailTemplateExample example); + + int deleteByExample(EmailTemplateExample example); + + int deleteByPrimaryKey(Integer templateId); + + int insert(EmailTemplate record); + + int insertSelective(EmailTemplate record); + + List selectByExampleWithBLOBs(EmailTemplateExample example); + + List selectByExample(EmailTemplateExample example); + + EmailTemplate selectByPrimaryKey(Integer templateId); + + int updateByExampleSelective(@Param("record") EmailTemplate record, @Param("example") EmailTemplateExample example); + + int updateByExampleWithBLOBs(@Param("record") EmailTemplate record, @Param("example") EmailTemplateExample example); + + int updateByExample(@Param("record") EmailTemplate record, @Param("example") EmailTemplateExample example); + + int updateByPrimaryKeySelective(EmailTemplate record); + + int updateByPrimaryKeyWithBLOBs(EmailTemplate record); + + int updateByPrimaryKey(EmailTemplate record); + + EmailTemplate selectTemplateByNid(String nid); +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.xml new file mode 100644 index 0000000..5f092f0 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/mapper/EmailTemplateMapper.xml @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + template_id, subject, nid, status, address, use_type, create_time, update_time + + + content + + + + + + delete from t_email_template + where template_id = #{templateId,jdbcType=INTEGER} + + + delete from t_email_template + + + + + + insert into t_email_template (template_id, subject, nid, + status, address, use_type, + create_time, update_time, content + ) + values (#{templateId,jdbcType=INTEGER}, #{subject,jdbcType=VARCHAR}, #{nid,jdbcType=VARCHAR}, + #{status,jdbcType=TINYINT}, #{address,jdbcType=VARCHAR}, #{useType,jdbcType=TINYINT}, + #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, #{content,jdbcType=LONGVARCHAR} + ) + + + insert into t_email_template + + + template_id, + + + subject, + + + nid, + + + status, + + + address, + + + use_type, + + + create_time, + + + update_time, + + + content, + + + + + #{templateId,jdbcType=INTEGER}, + + + #{subject,jdbcType=VARCHAR}, + + + #{nid,jdbcType=VARCHAR}, + + + #{status,jdbcType=TINYINT}, + + + #{address,jdbcType=VARCHAR}, + + + #{useType,jdbcType=TINYINT}, + + + #{createTime,jdbcType=TIMESTAMP}, + + + #{updateTime,jdbcType=TIMESTAMP}, + + + #{content,jdbcType=LONGVARCHAR}, + + + + + + update t_email_template + + + template_id = #{record.templateId,jdbcType=INTEGER}, + + + subject = #{record.subject,jdbcType=VARCHAR}, + + + nid = #{record.nid,jdbcType=VARCHAR}, + + + status = #{record.status,jdbcType=TINYINT}, + + + address = #{record.address,jdbcType=VARCHAR}, + + + use_type = #{record.useType,jdbcType=TINYINT}, + + + create_time = #{record.createTime,jdbcType=TIMESTAMP}, + + + update_time = #{record.updateTime,jdbcType=TIMESTAMP}, + + + content = #{record.content,jdbcType=LONGVARCHAR}, + + + + + + + + update t_email_template + set template_id = #{record.templateId,jdbcType=INTEGER}, + subject = #{record.subject,jdbcType=VARCHAR}, + nid = #{record.nid,jdbcType=VARCHAR}, + status = #{record.status,jdbcType=TINYINT}, + address = #{record.address,jdbcType=VARCHAR}, + use_type = #{record.useType,jdbcType=TINYINT}, + create_time = #{record.createTime,jdbcType=TIMESTAMP}, + update_time = #{record.updateTime,jdbcType=TIMESTAMP}, + content = #{record.content,jdbcType=LONGVARCHAR} + + + + + + update t_email_template + set template_id = #{record.templateId,jdbcType=INTEGER}, + subject = #{record.subject,jdbcType=VARCHAR}, + nid = #{record.nid,jdbcType=VARCHAR}, + status = #{record.status,jdbcType=TINYINT}, + address = #{record.address,jdbcType=VARCHAR}, + use_type = #{record.useType,jdbcType=TINYINT}, + create_time = #{record.createTime,jdbcType=TIMESTAMP}, + update_time = #{record.updateTime,jdbcType=TIMESTAMP} + + + + + + update t_email_template + + + subject = #{subject,jdbcType=VARCHAR}, + + + nid = #{nid,jdbcType=VARCHAR}, + + + status = #{status,jdbcType=TINYINT}, + + + address = #{address,jdbcType=VARCHAR}, + + + use_type = #{useType,jdbcType=TINYINT}, + + + create_time = #{createTime,jdbcType=TIMESTAMP}, + + + update_time = #{updateTime,jdbcType=TIMESTAMP}, + + + content = #{content,jdbcType=LONGVARCHAR}, + + + where template_id = #{templateId,jdbcType=INTEGER} + + + update t_email_template + set subject = #{subject,jdbcType=VARCHAR}, + nid = #{nid,jdbcType=VARCHAR}, + status = #{status,jdbcType=TINYINT}, + address = #{address,jdbcType=VARCHAR}, + use_type = #{useType,jdbcType=TINYINT}, + create_time = #{createTime,jdbcType=TIMESTAMP}, + update_time = #{updateTime,jdbcType=TIMESTAMP}, + content = #{content,jdbcType=LONGVARCHAR} + where template_id = #{templateId,jdbcType=INTEGER} + + + update t_email_template + set subject = #{subject,jdbcType=VARCHAR}, + nid = #{nid,jdbcType=VARCHAR}, + status = #{status,jdbcType=TINYINT}, + address = #{address,jdbcType=VARCHAR}, + use_type = #{useType,jdbcType=TINYINT}, + create_time = #{createTime,jdbcType=TIMESTAMP}, + update_time = #{updateTime,jdbcType=TIMESTAMP} + where template_id = #{templateId,jdbcType=INTEGER} + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/BasePage.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/BasePage.java new file mode 100644 index 0000000..d2a2e1c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/BasePage.java @@ -0,0 +1,81 @@ +package com.baoying.enginex.executor.common.model; + + +public class BasePage { + + /** + * 当前页数 + */ + private int page; + + /** + * 每页显示的行数 + */ + private int rows; + + /** + * 开始行数 + */ + private Integer curRow; + + /** + * 结束行数 + */ + private Integer endRow; + + /** + * 总行数 + */ + private Integer total; + + public BasePage() { + + } + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + /** + * setPagination:(设置当前页面和每页显示行数).
+ * @author wz + * @param page 当前页数 + * @param rows 每页显示的行数 + */ + public void setPagination(int page,int rows){ + this.page = page; + this.rows = rows; + this.curRow = (page-1)*rows; + this.endRow = (page)*rows; + } + + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getRows() { + return rows; + } + + public void setRows(int rows) { + this.rows = rows; + } + + public void setCurRow(Integer curRow) { + this.curRow = curRow; + } + + public void setEndRow(Integer endRow) { + this.endRow = endRow; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplate.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplate.java new file mode 100644 index 0000000..c7cefad --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplate.java @@ -0,0 +1,122 @@ +package com.baoying.enginex.executor.common.model; + +import java.util.Date; + +public class EmailTemplate { + private Integer templateId; + + private String subject; + + private String nid; + + private Byte status; + + private String address; + + private Byte useType; + + private Date createTime; + + private Date updateTime; + + private String content; + + public EmailTemplate(Integer templateId, String subject, String nid, Byte status, String address, Byte useType, Date createTime, Date updateTime) { + this.templateId = templateId; + this.subject = subject; + this.nid = nid; + this.status = status; + this.address = address; + this.useType = useType; + this.createTime = createTime; + this.updateTime = updateTime; + } + + public EmailTemplate(Integer templateId, String subject, String nid, Byte status, String address, Byte useType, Date createTime, Date updateTime, String content) { + this.templateId = templateId; + this.subject = subject; + this.nid = nid; + this.status = status; + this.address = address; + this.useType = useType; + this.createTime = createTime; + this.updateTime = updateTime; + this.content = content; + } + + public EmailTemplate() { + super(); + } + + public Integer getTemplateId() { + return templateId; + } + + public void setTemplateId(Integer templateId) { + this.templateId = templateId; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject == null ? null : subject.trim(); + } + + public String getNid() { + return nid; + } + + public void setNid(String nid) { + this.nid = nid == null ? null : nid.trim(); + } + + public Byte getStatus() { + return status; + } + + public void setStatus(Byte status) { + this.status = status; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address == null ? null : address.trim(); + } + + public Byte getUseType() { + return useType; + } + + public void setUseType(Byte useType) { + this.useType = useType; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content == null ? null : content.trim(); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplateExample.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplateExample.java new file mode 100644 index 0000000..6ae7b1d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/EmailTemplateExample.java @@ -0,0 +1,711 @@ +package com.baoying.enginex.executor.common.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class EmailTemplateExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public EmailTemplateExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andTemplateIdIsNull() { + addCriterion("template_id is null"); + return (Criteria) this; + } + + public Criteria andTemplateIdIsNotNull() { + addCriterion("template_id is not null"); + return (Criteria) this; + } + + public Criteria andTemplateIdEqualTo(Integer value) { + addCriterion("template_id =", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdNotEqualTo(Integer value) { + addCriterion("template_id <>", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdGreaterThan(Integer value) { + addCriterion("template_id >", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdGreaterThanOrEqualTo(Integer value) { + addCriterion("template_id >=", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdLessThan(Integer value) { + addCriterion("template_id <", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdLessThanOrEqualTo(Integer value) { + addCriterion("template_id <=", value, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdIn(List values) { + addCriterion("template_id in", values, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdNotIn(List values) { + addCriterion("template_id not in", values, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdBetween(Integer value1, Integer value2) { + addCriterion("template_id between", value1, value2, "templateId"); + return (Criteria) this; + } + + public Criteria andTemplateIdNotBetween(Integer value1, Integer value2) { + addCriterion("template_id not between", value1, value2, "templateId"); + return (Criteria) this; + } + + public Criteria andSubjectIsNull() { + addCriterion("subject is null"); + return (Criteria) this; + } + + public Criteria andSubjectIsNotNull() { + addCriterion("subject is not null"); + return (Criteria) this; + } + + public Criteria andSubjectEqualTo(String value) { + addCriterion("subject =", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectNotEqualTo(String value) { + addCriterion("subject <>", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectGreaterThan(String value) { + addCriterion("subject >", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectGreaterThanOrEqualTo(String value) { + addCriterion("subject >=", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectLessThan(String value) { + addCriterion("subject <", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectLessThanOrEqualTo(String value) { + addCriterion("subject <=", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectLike(String value) { + addCriterion("subject like", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectNotLike(String value) { + addCriterion("subject not like", value, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectIn(List values) { + addCriterion("subject in", values, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectNotIn(List values) { + addCriterion("subject not in", values, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectBetween(String value1, String value2) { + addCriterion("subject between", value1, value2, "subject"); + return (Criteria) this; + } + + public Criteria andSubjectNotBetween(String value1, String value2) { + addCriterion("subject not between", value1, value2, "subject"); + return (Criteria) this; + } + + public Criteria andNidIsNull() { + addCriterion("nid is null"); + return (Criteria) this; + } + + public Criteria andNidIsNotNull() { + addCriterion("nid is not null"); + return (Criteria) this; + } + + public Criteria andNidEqualTo(String value) { + addCriterion("nid =", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidNotEqualTo(String value) { + addCriterion("nid <>", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidGreaterThan(String value) { + addCriterion("nid >", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidGreaterThanOrEqualTo(String value) { + addCriterion("nid >=", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidLessThan(String value) { + addCriterion("nid <", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidLessThanOrEqualTo(String value) { + addCriterion("nid <=", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidLike(String value) { + addCriterion("nid like", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidNotLike(String value) { + addCriterion("nid not like", value, "nid"); + return (Criteria) this; + } + + public Criteria andNidIn(List values) { + addCriterion("nid in", values, "nid"); + return (Criteria) this; + } + + public Criteria andNidNotIn(List values) { + addCriterion("nid not in", values, "nid"); + return (Criteria) this; + } + + public Criteria andNidBetween(String value1, String value2) { + addCriterion("nid between", value1, value2, "nid"); + return (Criteria) this; + } + + public Criteria andNidNotBetween(String value1, String value2) { + addCriterion("nid not between", value1, value2, "nid"); + return (Criteria) this; + } + + public Criteria andStatusIsNull() { + addCriterion("status is null"); + return (Criteria) this; + } + + public Criteria andStatusIsNotNull() { + addCriterion("status is not null"); + return (Criteria) this; + } + + public Criteria andStatusEqualTo(Byte value) { + addCriterion("status =", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotEqualTo(Byte value) { + addCriterion("status <>", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThan(Byte value) { + addCriterion("status >", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThanOrEqualTo(Byte value) { + addCriterion("status >=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThan(Byte value) { + addCriterion("status <", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThanOrEqualTo(Byte value) { + addCriterion("status <=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusIn(List values) { + addCriterion("status in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotIn(List values) { + addCriterion("status not in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusBetween(Byte value1, Byte value2) { + addCriterion("status between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotBetween(Byte value1, Byte value2) { + addCriterion("status not between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andAddressIsNull() { + addCriterion("address is null"); + return (Criteria) this; + } + + public Criteria andAddressIsNotNull() { + addCriterion("address is not null"); + return (Criteria) this; + } + + public Criteria andAddressEqualTo(String value) { + addCriterion("address =", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressNotEqualTo(String value) { + addCriterion("address <>", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressGreaterThan(String value) { + addCriterion("address >", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressGreaterThanOrEqualTo(String value) { + addCriterion("address >=", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressLessThan(String value) { + addCriterion("address <", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressLessThanOrEqualTo(String value) { + addCriterion("address <=", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressLike(String value) { + addCriterion("address like", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressNotLike(String value) { + addCriterion("address not like", value, "address"); + return (Criteria) this; + } + + public Criteria andAddressIn(List values) { + addCriterion("address in", values, "address"); + return (Criteria) this; + } + + public Criteria andAddressNotIn(List values) { + addCriterion("address not in", values, "address"); + return (Criteria) this; + } + + public Criteria andAddressBetween(String value1, String value2) { + addCriterion("address between", value1, value2, "address"); + return (Criteria) this; + } + + public Criteria andAddressNotBetween(String value1, String value2) { + addCriterion("address not between", value1, value2, "address"); + return (Criteria) this; + } + + public Criteria andUseTypeIsNull() { + addCriterion("use_type is null"); + return (Criteria) this; + } + + public Criteria andUseTypeIsNotNull() { + addCriterion("use_type is not null"); + return (Criteria) this; + } + + public Criteria andUseTypeEqualTo(Byte value) { + addCriterion("use_type =", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeNotEqualTo(Byte value) { + addCriterion("use_type <>", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeGreaterThan(Byte value) { + addCriterion("use_type >", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeGreaterThanOrEqualTo(Byte value) { + addCriterion("use_type >=", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeLessThan(Byte value) { + addCriterion("use_type <", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeLessThanOrEqualTo(Byte value) { + addCriterion("use_type <=", value, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeIn(List values) { + addCriterion("use_type in", values, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeNotIn(List values) { + addCriterion("use_type not in", values, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeBetween(Byte value1, Byte value2) { + addCriterion("use_type between", value1, value2, "useType"); + return (Criteria) this; + } + + public Criteria andUseTypeNotBetween(Byte value1, Byte value2) { + addCriterion("use_type not between", value1, value2, "useType"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNull() { + addCriterion("create_time is null"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNotNull() { + addCriterion("create_time is not null"); + return (Criteria) this; + } + + public Criteria andCreateTimeEqualTo(Date value) { + addCriterion("create_time =", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotEqualTo(Date value) { + addCriterion("create_time <>", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThan(Date value) { + addCriterion("create_time >", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThanOrEqualTo(Date value) { + addCriterion("create_time >=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThan(Date value) { + addCriterion("create_time <", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThanOrEqualTo(Date value) { + addCriterion("create_time <=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeIn(List values) { + addCriterion("create_time in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotIn(List values) { + addCriterion("create_time not in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeBetween(Date value1, Date value2) { + addCriterion("create_time between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotBetween(Date value1, Date value2) { + addCriterion("create_time not between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNull() { + addCriterion("update_time is null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNotNull() { + addCriterion("update_time is not null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeEqualTo(Date value) { + addCriterion("update_time =", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotEqualTo(Date value) { + addCriterion("update_time <>", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThan(Date value) { + addCriterion("update_time >", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThanOrEqualTo(Date value) { + addCriterion("update_time >=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThan(Date value) { + addCriterion("update_time <", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThanOrEqualTo(Date value) { + addCriterion("update_time <=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIn(List values) { + addCriterion("update_time in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotIn(List values) { + addCriterion("update_time not in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeBetween(Date value1, Date value2) { + addCriterion("update_time between", value1, value2, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotBetween(Date value1, Date value2) { + addCriterion("update_time not between", value1, value2, "updateTime"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/ExpressionParam.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/ExpressionParam.java new file mode 100644 index 0000000..3c20f2a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/model/ExpressionParam.java @@ -0,0 +1,18 @@ +package com.baoying.enginex.executor.common.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +//表达式的参数实体类 +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ExpressionParam { + private String fieldEn;//表达式中key字段en + private String operator;//表达式的操作符 + private Integer variableType;//表达式中value类型,1常量 2变量,3自定义 + private String fieldValue;//表达式中对应常量value值或者变量key + private String executionLogic;//执行逻辑 + private Integer conditionType;//规则节点的类型:1-关系节点,2-表达式节点 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionData.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionData.java new file mode 100644 index 0000000..89163d5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionData.java @@ -0,0 +1,15 @@ +package com.baoying.enginex.executor.common.session; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = false) +public class SessionData { + + private Long organId; // 组织id + private Long engineId; // 引擎id + private Integer reqType;//请求类型 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionManager.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionManager.java new file mode 100644 index 0000000..5040ea1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/common/session/SessionManager.java @@ -0,0 +1,20 @@ +package com.baoying.enginex.executor.common.session; + +import com.alibaba.ttl.TransmittableThreadLocal; + +/** + * session管理类 + */ +public class SessionManager { + private static TransmittableThreadLocal session = new TransmittableThreadLocal() { + + }; + + public static SessionData getSession() { + return session.get(); + } + + public static void setSession(SessionData conn) { + session.set(conn); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigHolder.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigHolder.java new file mode 100644 index 0000000..1e482d2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigHolder.java @@ -0,0 +1,72 @@ +package com.baoying.enginex.executor.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Data +public class ConfigHolder { + + //redisConfig + @Value("${redis.host}") + private String redisHost; + @Value("${redis.port}") + private int redisPort; + @Value("${redis.db}") + private int redisDb; + @Value("${redis.password}") + private String redisPwd; + @Value("${redis.pool.maxTotal}") + private int redisMaxTotal; + @Value("${redis.pool.maxIdle}") + private int redisMaxIdle; + @Value("${redis.pool.maxWait}") + private int redisMaxWait; + @Value("${redis.pool.timeout}") + private int redisTimeout; + + // 业务逻辑是否使用缓存 + @Value("${switch.use.cache}") + private String cacheSwitch; + // canal缓存同步是否开启 + @Value("${switch.canal.cache}") + private String canalCacheSwitch; + // canal主机地址 + @Value("${canal.hostname}") + private String canalHostName; + // canal端口 + @Value("${canal.port}") + private int canalPort; + + //jdbcConfig + /*@Value("${jdbc.url}") + private String jdbcUrl; + @Value("${jdbc.driver}") + private String DriverName; + @Value("${pool.maxPoolSize}") + private int maxPoolSize; + @Value("${jdbc.username}") + private String jdbcUserName; + @Value("${jdbc.password}") + private String jdbcPwd; + @Value("${pool.maxWait}") + private int jdbcMaxWait; + @Value("${pool.timeBetweenEvictionRunsMillis}") + private int timeBetweenEvictionRunsMillis; + @Value("${pool.minEvictableIdleTimeMillis}") + private int minEvictableIdleTimeMillis; + @Value("${pool.validationQuery}") + private String validationQuery; + + //rabbitconfig + @Value("${rabbitMQ.host}") + private String rabbitHost; + @Value("${rabbitMQ.port}") + private int rabbitPort; + @Value("${rabbitMQ.username}") + private String rabbitUsername; + @Value("${rabbitMQ.password}") + private String rabbitPassword;*/ + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigurationContainor.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigurationContainor.java new file mode 100644 index 0000000..54c1e29 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/ConfigurationContainor.java @@ -0,0 +1,46 @@ +package com.baoying.enginex.executor.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +import javax.annotation.Resource; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ConfigurationContainor { + + @Resource + private ConfigHolder configHolder; + + @Bean(name = "threadPoolTaskExecutor") + ThreadPoolTaskExecutor threadPoolTaskExecutor(){ + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2000); + executor.setMaxPoolSize(10000); + executor.setQueueCapacity(100000); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); + return executor; + } + + @Bean(name = "jedisPool") + public JedisPool jedisPool(){ + JedisPoolConfig config = new JedisPoolConfig(); + config.setMaxTotal(configHolder.getRedisMaxTotal()); + config.setMaxIdle(configHolder.getRedisMaxIdle()); + config.setMaxWaitMillis(configHolder.getRedisMaxWait()); + config.setTestOnBorrow(true); +// config.setTestOnReturn(true); + + JedisPool pool = new JedisPool(config, + configHolder.getRedisHost(), + configHolder.getRedisPort(), + configHolder.getRedisTimeout(), + configHolder.getRedisPwd(), + configHolder.getRedisDb()); + return pool; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/DataSourceConfig.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/DataSourceConfig.java new file mode 100644 index 0000000..af53c49 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/DataSourceConfig.java @@ -0,0 +1,61 @@ +package com.baoying.enginex.executor.config; + +import com.alibaba.druid.pool.DruidDataSource; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; + +import javax.sql.DataSource; + + +@Configuration +public class DataSourceConfig { + @Value("${spring.datasource.default.url}") + private String defaultDBUrl; + @Value("${spring.datasource.default.username}") + private String defaultDBUser; + @Value("${spring.datasource.default.password}") + private String defaultDBPassword; + @Value("${spring.datasource.default.driver-class-name}") + private String defaultDBDreiverName; + + @Bean + public DruidDataSource druidDataSource(){ + DruidDataSource defaultDataSource = new DruidDataSource(); + defaultDataSource.setUrl(defaultDBUrl); + defaultDataSource.setUsername(defaultDBUser); + defaultDataSource.setPassword(defaultDBPassword); + defaultDataSource.setDriverClassName(defaultDBDreiverName); + + return defaultDataSource; + } + + @Bean + public SqlSessionFactory sqlSessionFactory( + @Qualifier("druidDataSource") DataSource druidDataSource) + throws Exception { + MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); + ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] mapperXmlResource = resolver.getResources("classpath*:com/baoying/enginex/executor/*/mapper/*Mapper.xml"); + bean.setDataSource(druidDataSource); + bean.setMapperLocations(mapperXmlResource); + bean.setTypeAliasesPackage("com.baoying.enginex.executor.**.model"); + bean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true); + bean.getObject().getConfiguration().setCacheEnabled(false); + return bean.getObject(); + } + + @Bean(name = "sqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate( + @Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) + throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/RestTemplateConfig.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/RestTemplateConfig.java new file mode 100644 index 0000000..00dfa2a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/config/RestTemplateConfig.java @@ -0,0 +1,52 @@ +package com.baoying.enginex.executor.config; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.http.client.AsyncClientHttpRequestFactory; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.AsyncRestTemplate; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplate配置 + */ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(@Qualifier("clientHttpRequestFactory") ClientHttpRequestFactory factory){ + return new RestTemplate(factory); + } + + @Bean + public AsyncRestTemplate asyncRestTemplate(@Qualifier("asyncClientHttpRequestFactory") AsyncClientHttpRequestFactory factory){ + return new AsyncRestTemplate(factory); + } + + @Bean + public ClientHttpRequestFactory clientHttpRequestFactory(){ + // 创建一个 httpCilent 简单工厂 + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + // 设置连接超时 + factory.setConnectTimeout(15000); + // 设置读取超时 + factory.setReadTimeout(5000); + return factory; + } + + @Bean + public AsyncClientHttpRequestFactory asyncClientHttpRequestFactory(){ + // 创建一个 httpCilent 简单工厂 + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + // 设置连接超时 +// factory.setConnectTimeout(15000); + // 设置读取超时 +// factory.setReadTimeout(5000); + //设置异步任务(线程不会重用,每次调用时都会重新启动一个新的线程) + factory.setTaskExecutor(new SimpleAsyncTaskExecutor()); + return factory; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.java new file mode 100644 index 0000000..26afa10 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.java @@ -0,0 +1,57 @@ +package com.baoying.enginex.executor.datamanage.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.datamanage.model.Field; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface FieldMapper extends BaseMapper { + + /** + * findFieldByIds:(找出一批字段id对应的字段列表).
+ * @author caowenyu + * @param paramMap 参数集合 + * @return 字段列表 + */ + public List findFieldByIdsbyorganId(Map paramMap); + + /** + * findByFieldEn:(根据引擎和字段英文名找出引擎所用字段对象).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段对象 + */ + public Field findByFieldEnbyorganId(Map paramMap); + + /** + * findByFieldCn:(根据字段中文名找出字段对象).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段对象 + */ + public Field findByFieldCnbyorganId(Map paramMap); + + /** + * findByFieldCn:(按中文名查找通用字段).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段对象 + */ + public Field findByFieldCnNoEngineIdbyorganId(Map paramMap); + + /** + * findByFieldId:(根据字段Id查找字段对象).
+ * @author caowenyu + * @param paramMap 参数集合 + * @return 字段对象 + */ + public Field findByFieldIdbyorganId(Map paramMap); + + List selectFieldListByIds(@Param("ids") List ids); + + List selectFieldListByEns(@Param("ens")List ens); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.xml new file mode 100644 index 0000000..c3007df --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldMapper.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.java new file mode 100644 index 0000000..c944126 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.java @@ -0,0 +1,128 @@ + + +package com.baoying.enginex.executor.datamanage.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.datamanage.model.FieldType; + +import java.util.List; +import java.util.Map; + +public interface FieldTypeMapper extends BaseMapper { + + /** + * getFieldTypeList:(查找用户的字段类型列表).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段类型列表 + */ + public List getFieldTypeList(Map paramMap); + + /** + * getSubFieldTypeList:(根据传入的字段父类型查找子类型列表).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段类型列表 + */ + public List getSubFieldTypeList(Map paramMap); + + /** + * findFieldTypeById:(根据传入的字段类型ID查找字段类型名).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段类型列表 + */ + public FieldType findFieldTypeById(Map paramMap); + + /** + * findTypeIdByParentId:(根据传入的字段类型父ID查找子类型ID).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 子字段类型ID + */ + public String findTypeIdByParentId(Map paramMap); + + /** + * findTypeIdByParentId:(根据传入的字段类型类型ID查找父ID).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 子字段类型ID + */ + public String findParentIdByTypeId(Map paramMap); + + /** + * findFieldType:(查找用户可用的字段类型列表,通用组织所有,引擎只有自定义).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 字段类型列表 + */ + public List findFieldType(Map paramMap); + + /** + * createFieldType:(新增字段类型).
+ * @author yuanlinfeng + * @param fieldTypeVo 字段类型实体类 + * @return 插入成功 + */ + public boolean createFieldType(FieldType fieldTypeVo); + + /** + * findIdByFieldType:(新增字段类型).
+ * @author yuanlinfeng + * @param paramMap paramMap + * @return 字段类型编号 + */ + public long findIdByFieldType(Map paramMap); + + /** + * updateFieldType:(更新字段类型名).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + */ + public boolean updateFieldType(Map paramMap); + + /** + * updateFieldTypeByTypeIds:(更新字段类型为删除状态(-1)).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + */ + public boolean updateFieldTypeByTypeIds(Map paramMap); + + /** + * deleteFieldTypeByTypeIds:(删除字段类型下没有字段的空节点)).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + */ + public boolean deleteFieldTypeByTypeIds(Map paramMap); + + /** + * backFieldTypeByTypeIds:(更新字段类型状态为启用状态(1)).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + */ + public boolean backFieldTypeByTypeIds(Map paramMap); + + /** + * isExists:(查找字段名是否存在).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 存在的记录条数 + */ + public int isExists(Map paramMap); + + + /** + * isExistsDefaultTreeName:(查找默认节点名是否存在).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 存在的记录条数 + */ + public int isExistsDefaultTreeName(Map paramMap); + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.xml new file mode 100644 index 0000000..ca38dc0 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeMapper.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + insert into t_field_type ( field_type, parent_id, is_common ) + values ( #{fieldType}, #{parentId}, #{isCommon} ) + + + + update t_field_type + set field_type = #{fieldType} + where id = (select field_typeid + from t_field_type_user_rel + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + + and engine_id = #{engineId} + + + and engine_id is null + + and field_typeid = #{id} + ) + + + + update t_field_type_user_rel + set status = -1 + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and engine_id = #{engineId} + and field_typeid in + + #{item} + + and status = 1 + + + + delete from t_field_type_user_rel + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and engine_id = #{engineId} + and field_typeid in + + #{item} + + and field_typeid not in + ( select field_typeid + from t_field f,t_field_user_rel r + where f.id = r.field_id + and f.field_typeid in + + #{item} + + ) + + + + update t_field_type_user_rel + set status = 1 + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and engine_id = #{engineId} + and field_typeid in + + #{item} + + and status = -1 + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.java new file mode 100644 index 0000000..3487ced --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.java @@ -0,0 +1,54 @@ + + +package com.baoying.enginex.executor.datamanage.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.datamanage.model.FieldTypeUser; + +import java.util.Map; + +public interface FieldTypeUserMapper extends BaseMapper { + + /** + * createFieldTypeUserRel:(新增字段类型).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 插入成功 + */ + public boolean createFieldTypeUserRel(Map paramMap); + + /** + * batchBindEngineFieldTypeUserRel:(把一批通用字段类型id中不存在的类型id批量绑定到引擎).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 插入成功 + */ + public boolean batchBindEngineFieldTypeUserRel(Map paramMap); + + /** + * deleteFieldTypeUserRel:(取消字段类型).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 删除成功 + */ + public boolean deleteFieldTypeUserRel(Map paramMap); + + /** + * updateFieldTypeUserRel:(更新字段类型名).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + */ + public boolean updateFieldTypeUserRel(Map paramMap); + + /** + * findNodeIds:(查找引擎在用的节点集合).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return + */ + public String findNodeIds(Map paramMap); + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.xml new file mode 100644 index 0000000..d37e5d7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldTypeUserMapper.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + insert into t_field_type_user_rel ( field_typeid, organ_id, engine_id, user_id, created ) + values ( #{fieldTypeId}, #{organId}, #{engineId}, #{userId}, now() ) + + + + insert into t_field_type_user_rel ( field_typeid, organ_id, engine_id, user_id, created ) + select field_typeid, organ_id, #{engineId}, #{userId}, now() + from t_field_type_user_rel r + where r.field_typeid in + + #{item} + + and field_typeid not in ( select field_typeid from t_field_type_user_rel where engine_id = #{engineId}) + and engine_id is null + + + + + + delete from t_field_type_user_rel + where + organ_id = ( select organ_id from t_user where user_id = #{userId} ) + + and engine_id = #{engineId} + + + and engine_id is null + + and field_typeid = #{fieldTypeId} + + + + update t_field_type_user_rel + set user_id = #{userId}, created = now() + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + + and engine_id = #{engineId} + + + and engine_id is null + + and field_typeid = #{id} + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.java new file mode 100644 index 0000000..b95260b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.java @@ -0,0 +1,77 @@ + + +package com.baoying.enginex.executor.datamanage.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.datamanage.model.FieldUser; + +import java.util.Map; + +public interface FieldUserMapper extends BaseMapper { + + /** + * createFieldUserRel:(绑定字段和用户关系).
+ * @author yuanlinfeng + * @param fieldUser 用户字段实体类 + * @return 插入成功 + * */ + public boolean createFieldUserRel(FieldUser fieldUserVo); + + /** + * batchCreateFieldUserRel:(批量导入字段信息后批量绑定字段和用户关系).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 插入成功 + * */ + public boolean batchCreateFieldUserRel(Map paramMap); + + /** + * batchBindEngineFieldUserRel:(把一批通用字段id中未绑定的字段id批量绑定到引擎).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 插入成功 + * */ + public boolean batchBindEngineFieldUserRel(Map paramMap); + + /** + * batchCreateEngineFieldUserRel:(把id、英文名、中文名不重复的组织字段批量绑定到引擎).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 插入成功 + * */ + public boolean batchCreateEngineFieldUserRel(Map paramMap); + + /** + * updateFieldUserRel:(更新字段).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + * */ + public boolean updateFieldUserRel(Map paramMap); + + /** + * updateStatus:(单个或批量更新用户字段关系).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新成功 + * */ + public boolean updateStatus(Map paramMap); + + /** + * deleteFieldByIds:(批量修改字段启用状态为删除状态(-1)).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新是否成功 + */ + public boolean deleteFieldByIds(Map paramMap); + + /** + * deleteFieldByIds:(批量修改字段删除状态为启用状态(1)).
+ * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 更新是否成功 + */ + public boolean backFieldByIds(Map paramMap); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.xml new file mode 100644 index 0000000..0a982d9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/FieldUserMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + insert into t_field_user_rel (field_id, organ_id, engine_id, user_id, status, created, updated) + values (#{fieldId}, #{organId}, #{engineId}, #{userId}, #{status}, now(), now()) + + + + insert into t_field_user_rel (field_id, organ_id, engine_id, user_id, status, created, updated) + select id, #{organId}, #{engineId}, #{userId}, #{status}, now(), now() + from t_field t + where t.author = #{author} + and not exists ( select r.field_id from t_field_user_rel r where t.id = r.field_id ) + + + + insert into t_field_user_rel (field_id, organ_id, engine_id, user_id, status, created, updated) + select id, #{organId}, #{engineId}, #{userId}, #{status}, now(), now() + from t_field f + where f.field_typeid in + + #{item} + + and not exists ( select 1 + from ( select f.id,f.field_en,f.field_cn + from t_field f,t_field_user_rel fu + where f.id = fu.field_id + and fu.organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and fu.engine_id = ${engineId} )y + where f.field_en = y.field_en or f.field_cn = y.field_cn or f.id = y.id + ) + + + + insert into t_field_user_rel (field_id, organ_id, engine_id, user_id, status, created, updated) + select id, #{organId}, #{engineId}, #{userId}, 1, now(), now() + from t_field f + where f.id in + + #{item} + + and not exists ( select 1 + from ( select f.id,f.field_en,f.field_cn + from t_field f,t_field_user_rel fu + where f.id = fu.field_id + and fu.organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and fu.engine_id = ${engineId} )y + where f.field_en = y.field_en or f.field_cn = y.field_cn or f.id = y.id + ) + + + + update t_field_user_rel + set user_id = #{userId} , updated = now() + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + + and engine_id = #{engineId} + + + and engine_id is null + + and field_id = #{Id} + + + + update t_field_user_rel + set status=#{status} + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + + and engine_id = #{engineId} + + + and engine_id is null + + and field_id in + + #{item} + + + + + update t_field_user_rel + set status = -1 + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and engine_id = #{engineId} + and field_id in + + #{item} + + and status = 1 + + + + update t_field_user_rel + set status = 1 + where organ_id = ( select organ_id from t_user where user_id = #{userId} ) + and engine_id = #{engineId} + and field_id in + + #{item} + + and status = -1 + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.java new file mode 100644 index 0000000..a168cfe --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.java @@ -0,0 +1,11 @@ +package com.baoying.enginex.executor.datamanage.mapper; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public interface SimpleMapper { + + List> customSelect(Map paramsMap); + List> test(Map paramsMap); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.xml new file mode 100644 index 0000000..9882a70 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/mapper/SimpleMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/CustList.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/CustList.java new file mode 100644 index 0000000..d70b691 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/CustList.java @@ -0,0 +1,236 @@ +package com.baoying.enginex.executor.datamanage.model; + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; +import java.util.Date; + +public class CustList extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 以下20个t开头为匿名字段 + * */ + private String t0; + private String t1; + private String t2; + private String t3; + private String t4; + private String t5; + private String t6; + private String t7; + private String t8; + private String t9; + private String t10; + private String t11; + private String t12; + private String t13; + private String t14; + private String t15; + private String t16; + private String t17; + private String t18; + private String t19; + + /** + * 创建人编号 + * */ + private Long userId; + + /** + * 创建人昵称 + * */ + private String nickName; + + /** + * 创建时间 + * */ + private Date created; + + /** + * 检索客户信息是否存在的定制条件 + */ + private String checkCol; + + /** + * 检索名单库的表名称 + */ + private String tableName; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getT0() { + return t0; + } + public void setT0(String t0) { + this.t0 = t0; + } + public String getT1() { + return t1; + } + public void setT1(String t1) { + this.t1 = t1; + } + public String getT2() { + return t2; + } + public void setT2(String t2) { + this.t2 = t2; + } + public String getT3() { + return t3; + } + public void setT3(String t3) { + this.t3 = t3; + } + public String getT4() { + return t4; + } + public void setT4(String t4) { + this.t4 = t4; + } + public String getT5() { + return t5; + } + public void setT5(String t5) { + this.t5 = t5; + } + public String getT6() { + return t6; + } + public void setT6(String t6) { + this.t6 = t6; + } + public String getT7() { + return t7; + } + public void setT7(String t7) { + this.t7 = t7; + } + public String getT8() { + return t8; + } + public void setT8(String t8) { + this.t8 = t8; + } + public String getT9() { + return t9; + } + public void setT9(String t9) { + this.t9 = t9; + } + public String getT10() { + return t10; + } + public void setT10(String t10) { + this.t10 = t10; + } + public String getT11() { + return t11; + } + public void setT11(String t11) { + this.t11 = t11; + } + public String getT12() { + return t12; + } + public void setT12(String t12) { + this.t12 = t12; + } + public String getT13() { + return t13; + } + public void setT13(String t13) { + this.t13 = t13; + } + public String getT14() { + return t14; + } + public void setT14(String t14) { + this.t14 = t14; + } + public String getT15() { + return t15; + } + public void setT15(String t15) { + this.t15 = t15; + } + public String getT16() { + return t16; + } + public void setT16(String t16) { + this.t16 = t16; + } + public String getT17() { + return t17; + } + public void setT17(String t17) { + this.t17 = t17; + } + public String getT18() { + return t18; + } + public void setT18(String t18) { + this.t18 = t18; + } + public String getT19() { + return t19; + } + public void setT19(String t19) { + this.t19 = t19; + } + public Long getUserId() { + return userId; + } + public void setUserId(Long userId) { + this.userId = userId; + } + public Date getCreated() { + return created; + } + public void setCreated(Date created) { + this.created = created; + } + public String getNickName() { + return nickName; + } + public void setNickName(String nickName) { + this.nickName = nickName; + } + public String getCheckCol() { + return checkCol; + } + public void setCheckCol(String checkCol) { + this.checkCol = checkCol; + } + public String getTableName() { + return tableName; + } + public void setTableName(String tableName) { + this.tableName = tableName; + } + @Override + public String toString() { + return "CustList [id=" + id + ", t0=" + t0 + ", t1=" + t1 + ", t2=" + t2 + + ", t3=" + t3 + ", t4=" + t4 + ", t5=" + t5 + ", t6=" + t6 + + ", t7=" + t7 + ", t8=" + t8 + ", t9=" + t9 + ", t10=" + t10 + + ", t11=" + t11 + ", t12=" + t12 + ", t13=" + t13 + ", t14=" + + t14 + ", t15=" + t15 + ", t16=" + t16 + ", t17=" + t17 + + ", t18=" + t18 + ", t19=" + t19 + ", userId=" + userId + + ", nickName=" + nickName + ", created=" + created + + ", checkCol=" + checkCol + ", tableName=" + tableName + "]"; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/Field.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/Field.java new file mode 100644 index 0000000..bf68b24 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/Field.java @@ -0,0 +1,203 @@ +package com.baoying.enginex.executor.datamanage.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +@TableName("t_field") +public class Field implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 字段英文名 + * */ + private String fieldEn; + + /** + * 字段中文名 + * */ + private String fieldCn; + + /** + * 字段类型编号 + * */ + @TableField("field_typeid") + private Long fieldTypeId; + + /** + * 字段类型名 + * */ + @TableField(exist = false) + private String fieldType; + + /** + * 字段存值类型 + * */ + private Integer valueType; + + /** + * 字段存值类型中文 + * */ + @TableField(exist = false) + private String valueTypeName; + + /** + * 字段约束范围 + * */ + private String valueScope; + + /** + * 是否衍生字段 + * */ + private Integer isDerivative; + + /** + * 是否衍生字段 + * */ + @TableField(exist = false) + private String isDerivativeName; + + /** + * 是否输出字段 + * */ + private Integer isOutput; + + /** + * 是否输出字段 + * */ + @TableField(exist = false) + private String isOutputName; + + /** + * 是否组织定义的通用字段 + * */ + private Integer isCommon; + + /** + * 衍生字段公式 + * */ + private String formula; + + /** + * 衍生字段公式回显信息 + * */ + private String formulaShow; + + /** + * 衍生字段引用的字段id + * */ + @TableField("used_fieldid") + private String usedFieldId; + + /** + * 衍生字段引用的原生字段id + * */ + @TableField("orig_fieldid") + private String origFieldId; + + /** + * 创建人 + * */ + private Long author; + + /** + * 创建人昵称 + * */ + @TableField(exist = false) + private String nickName; + + /** + * 创建时间 + * */ + private Date created; + + /** + * 归属的引擎ID + * */ + @TableField(exist = false) + private Long engineId; + + /** + * 归属的引擎名称 + * */ + @TableField(exist = false) + private String engineName; + + /** + * 字段状态(启用、停用、删除、未知) + * */ + @TableField(exist = false) + private String status; + + /** + * 字段条件设置集合 + * */ + @TableField(exist = false) + private List fieldCondList; + + /** + * 字段用户关系编号 + * */ + @TableField(exist = false) + private Long fieldRelId; + + /** + * 是否使用sql获取指标 + */ + private Boolean isUseSql; + + /** + * 使用sql获取指标时对应的数据源 + */ + private Integer dataSourceId; + + /** + * 使用sql获取指标时对应的sql语句 + */ + private String sqlStatement; + + /** + * sql变量配置 + */ + private String sqlVariable; + + /** + * 是否使用接口 + */ + private Boolean isInterface; + + /** + * 接口id + */ + private Integer interfaceId; + + /** + * 接口解析指标 + */ + private String interfaceParseField; + + /** + * json类型对应的json值 + */ + private String jsonValue; + /** + * 字典变量例如 日期:date + */ + private String dictVariable; + + /** + * 该字段归属的组织编号 + * */ + private Long organId; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldCond.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldCond.java new file mode 100644 index 0000000..ba07b14 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldCond.java @@ -0,0 +1,142 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; +import com.baoying.enginex.executor.datamanage.vo.FieldSubCondVo; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +public class FieldCond extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 条件编号 + * */ + private Long id; + + /** + * 字段编号 + * */ + private Long fieldId; + + /** + * 字段条件值 + * */ + private String conditionValue; + + /** + * 字段条件区域设置json格式 + * */ + private String content; + + /** + * 条件字段编号 + * */ + private Long condFieldId; + + /** + * 条件字段的运算符 + * */ + private String condFieldOperator; + + /** + * 条件字段的条件设置值 + * */ + private String condFieldValue; + + /** + * 条件字段间的逻辑符 + * */ + private String condFieldLogical; + + /** + * 创建时间 + * */ + private Date created; + + private List fieldSubCond; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getFieldId() { + return fieldId; + } + + public void setFieldId(Long fieldId) { + this.fieldId = fieldId; + } + + public String getConditionValue() { + return conditionValue; + } + + public void setConditionValue(String conditionValue) { + this.conditionValue = conditionValue; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Long getCondFieldId() { + return condFieldId; + } + + public void setCondFieldId(Long condFieldId) { + this.condFieldId = condFieldId; + } + + public String getCondFieldOperator() { + return condFieldOperator; + } + + public void setCondFieldOperator(String condFieldOperator) { + this.condFieldOperator = condFieldOperator; + } + + public String getCondFieldValue() { + return condFieldValue; + } + + public void setCondFieldValue(String condFieldValue) { + this.condFieldValue = condFieldValue; + } + + public String getCondFieldLogical() { + return condFieldLogical; + } + + public void setCondFieldLogical(String condFieldLogical) { + this.condFieldLogical = condFieldLogical; + } + + public List getFieldSubCond() { + return fieldSubCond; + } + + public void setFieldSubCond(List fieldSubCond) { + this.fieldSubCond = fieldSubCond; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldInter.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldInter.java new file mode 100644 index 0000000..2ce413c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldInter.java @@ -0,0 +1,104 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + +public class FieldInter extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Integer id; + + /** + * 衍生字段编号 + * */ + private Integer fieldRelId; + + /** + * 公式引用的字段编号 + * */ + private Integer interFieldId; + + /** + * 公式引用的字段用户关系编号 + * */ + private Integer interFieldRelId; + + /** + * 同名字段的顺序 + * */ + private Integer seq; + + /** + * 字段值区间划分 + * */ + private String interval; + + /** + * 对应区间的值定义 + * */ + private String value; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getFieldRelId() { + return fieldRelId; + } + + public void setFieldRelId(Integer fieldRelId) { + this.fieldRelId = fieldRelId; + } + + public Integer getInterFieldId() { + return interFieldId; + } + + public void setInterFieldId(Integer interFieldId) { + this.interFieldId = interFieldId; + } + + public Integer getInterFieldRelId() { + return interFieldRelId; + } + + public void setInterFieldRelId(Integer interFieldRelId) { + this.interFieldRelId = interFieldRelId; + } + + public Integer getSeq() { + return seq; + } + + public void setSeq(Integer seq) { + this.seq = seq; + } + + public String getInterval() { + return interval; + } + + public void setInterval(String interval) { + this.interval = interval; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldType.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldType.java new file mode 100644 index 0000000..1b62fd5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldType.java @@ -0,0 +1,106 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + +public class FieldType extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Integer id; + + /** + * 字段类型名 + * */ + private String fieldType; + + /** + * 父节点编号 + * */ + private Integer parentId; + + /** + * 是否组织定义的通用字段类型 + * */ + private Integer isCommon; + + /** + * 字段类型的子类集合 + * */ + private FieldType[] children; + + /** + * 是否为父类 + * */ + private String isParent = "true"; + + /** + * 引擎编号 + * */ + private Integer engineId; + + /** + *文件夹图片路径 + * */ + private String icon; + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getFieldType() { + return fieldType; + } + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + public Integer getParentId() { + return parentId; + } + public void setParentId(Integer parentId) { + this.parentId = parentId; + } + public Integer getIsCommon() { + return isCommon; + } + public void setIsCommon(Integer isCommon) { + this.isCommon = isCommon; + } + public FieldType[] getChildren() { + return children; + } + public void setChildren(FieldType[] children) { + this.children = children; + } + public String getIsParent() { + return isParent; + } + public void setIsParent(String isParent) { + this.isParent = isParent; + } + public Integer getEngineId() { + return engineId; + } + public void setEngineId(Integer engineId) { + this.engineId = engineId; + } + public String getIcon() { +// if(engineId!=null) +// icon = "../../resource/images/authority/folder.png"; +// else + icon = "../resource/images/authority/folder.png"; + return icon; + } + public void setIcon(String icon) { + this.icon = icon; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldTypeUser.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldTypeUser.java new file mode 100644 index 0000000..db8b115 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldTypeUser.java @@ -0,0 +1,80 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; +import java.util.Date; + +public class FieldTypeUser extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Integer id; + + /** + * 字段类型编号(表主键) + * */ + private Integer fieldTypeId; + + /** + * 该字段类型归属的组织编号 + * */ + private Long organId; + + /** + * 该字段类型归属的引擎id(表主键) + * */ + private Integer engineId; + + /** + * 创建或修改该字段的用户编号 + * */ + private Long userId; + + /** + * 创建时间 + * */ + private Date created; + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public Integer getFieldTypeId() { + return fieldTypeId; + } + public void setFieldTypeId(Integer fieldTypeId) { + this.fieldTypeId = fieldTypeId; + } + public Long getOrganId() { + return organId; + } + public void setOrganId(Long organId) { + this.organId = organId; + } + public Integer getEngineId() { + return engineId; + } + public void setEngineId(Integer engineId) { + this.engineId = engineId; + } + public Long getUserId() { + return userId; + } + public void setUserId(Long userId) { + this.userId = userId; + } + public Date getCreated() { + return created; + } + public void setCreated(Date created) { + this.created = created; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldUser.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldUser.java new file mode 100644 index 0000000..c887839 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FieldUser.java @@ -0,0 +1,102 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; +import java.util.Date; + +public class FieldUser extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 字段编号(表主键) + * */ + private Long fieldId; + + /** + * 该字段归属的组织编号 + * */ + private Long organId; + + /** + * 该字段归属的引擎id(表主键) + * */ + private Long engineId; + + /** + * 创建或修改该字段的用户编号 + * */ + private Long userId; + + /** + * 启用停用删除标志 + * */ + private int status; + + /** + * 创建时间 + * */ + private Date created; + + /** + * 更新时间 + * */ + private Date updated; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public Long getFieldId() { + return fieldId; + } + public void setFieldId(Long fieldId) { + this.fieldId = fieldId; + } + public Long getOrganId() { + return organId; + } + public void setOrganId(Long organId) { + this.organId = organId; + } + public Long getEngineId() { + return engineId; + } + public void setEngineId(Long engineId) { + this.engineId = engineId; + } + public Long getUserId() { + return userId; + } + public void setUserId(Long userId) { + this.userId = userId; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + public Date getCreated() { + return created; + } + public void setCreated(Date created) { + this.created = created; + } + public Date getUpdated() { + return updated; + } + public void setUpdated(Date updated) { + this.updated = updated; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FormulaField.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FormulaField.java new file mode 100644 index 0000000..b655d49 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/model/FormulaField.java @@ -0,0 +1,45 @@ +package com.baoying.enginex.executor.datamanage.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + +public class FormulaField extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 字段编号(表主键) + * */ + private Long fieldId; + /** + * 公式用到的字段编号(表主键) + * */ + private Long formulaFieldId; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public Long getFieldId() { + return fieldId; + } + public void setFieldId(Long fieldId) { + this.fieldId = fieldId; + } + public Long getFormulaFieldId() { + return formulaFieldId; + } + public void setFormulaFieldId(Long formulaFieldId) { + this.formulaFieldId = formulaFieldId; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/FieldService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/FieldService.java new file mode 100644 index 0000000..f7e08e6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/FieldService.java @@ -0,0 +1,19 @@ +package com.baoying.enginex.executor.datamanage.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.datamanage.model.Field; + +import java.util.List; + +public interface FieldService extends IService { + + Field queryById(Long id); + + List findFieldByIdsbyorganId(Long organId, List ids); + + List selectFieldListByEns(List fieldEnList); + + Field findByFieldEnbyorganId(Long organId, String fieldEn); + + Field findByFieldCnbyorganId(Long organId, String fieldCn); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/impl/FieldServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/impl/FieldServiceImpl.java new file mode 100644 index 0000000..cfeb580 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/service/impl/FieldServiceImpl.java @@ -0,0 +1,112 @@ +package com.baoying.enginex.executor.datamanage.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.common.session.SessionManager; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.datamanage.mapper.FieldMapper; +import com.baoying.enginex.executor.datamanage.model.Field; +import com.baoying.enginex.executor.datamanage.service.FieldService; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class FieldServiceImpl extends ServiceImpl implements FieldService { + + @Autowired + public FieldMapper fieldMapper; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public Field queryById(Long id) { + Field field = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getPrimaryKey(TableEnum.T_FIELD, id); + field = redisManager.getByPrimaryKey(key, Field.class); + } else { + field = fieldMapper.selectById(id); + } + + return field; + } + + @Override + public List findFieldByIdsbyorganId(Long organId, List ids) { + List fieldList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + List keys = RedisUtils.getPrimaryKey(TableEnum.T_FIELD, ids); + fieldList = redisManager.hgetAllBatchByPrimaryKeys(keys, Field.class); + } else { + Map paramMap = new HashMap<>(); + paramMap.put("organId", organId); + paramMap.put("Ids", ids); + fieldList = fieldMapper.findFieldByIdsbyorganId(paramMap); + } + return fieldList; + } + + @Override + public List selectFieldListByEns(List fieldEnList) { + List fieldList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + Long organId = SessionManager.getSession().getOrganId(); + List keys = fieldEnList.stream().map(item -> { + String fieldEnStr = Constants.fieldName.fieldEn + ":" + organId + ":" + item; + String fieldEnKey = RedisUtils.getPrimaryKey(TableEnum.T_FIELD, fieldEnStr); + return fieldEnKey; + }).collect(Collectors.toList()); + + fieldList = redisManager.hgetAllBatchByPrimaryKeys(keys, Field.class); + + } else { + fieldList = fieldMapper.selectFieldListByEns(fieldEnList); + } + return fieldList; + } + + @Override + public Field findByFieldEnbyorganId(Long organId, String fieldEn) { + Field field = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String fieldEnStr = Constants.fieldName.fieldEn + ":" + organId + ":" + fieldEn; + String fieldEnKey = RedisUtils.getPrimaryKey(TableEnum.T_FIELD, fieldEnStr); + field = redisManager.getByPrimaryKey(fieldEnKey, Field.class); + // todo 是否需要status = 1判断 + } else { + Map paramMap = new HashMap(); + paramMap.put("organId", organId); + paramMap.put("fieldEn", fieldEn); + field = fieldMapper.findByFieldEnbyorganId(paramMap); + } + return field; + } + + @Override + public Field findByFieldCnbyorganId(Long organId, String fieldCn) { + Field field = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String fieldCnStr = Constants.fieldName.fieldCn + ":" + organId + ":" + fieldCn; + String fieldCnKey = RedisUtils.getPrimaryKey(TableEnum.T_FIELD, fieldCnStr); + field = redisManager.getByPrimaryKey(fieldCnKey, Field.class); + // todo 是否需要status = 1判断 + } else { + Map paramMap = new HashMap(); + paramMap.put("organId", organId); + paramMap.put("fieldCn", fieldCn); + field = fieldMapper.findByFieldCnbyorganId(paramMap); + } + return field; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldEnumVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldEnumVo.java new file mode 100644 index 0000000..dcab312 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldEnumVo.java @@ -0,0 +1,29 @@ +package com.baoying.enginex.executor.datamanage.vo; + +import com.baoying.enginex.executor.datamanage.model.Field; + +import java.util.List; + + +public class FieldEnumVo { + + private Field field; + + private List enums; + + public Field getField() { + return field; + } + + public void setField(Field field) { + this.field = field; + } + + public List getEnums() { + return enums; + } + + public void setEnums(List enums) { + this.enums = enums; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldExcelVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldExcelVo.java new file mode 100644 index 0000000..be106f7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldExcelVo.java @@ -0,0 +1,150 @@ +package com.baoying.enginex.executor.datamanage.vo; + +import java.util.Date; + +public class FieldExcelVo { + + /** + * 主键 + * */ + private Integer id; + + /** + * 字段英文名 + * */ + private String fieldEn; + + /** + * 字段中文名 + * */ + private String fieldCn; + + /** + * 字段类型名称 + * */ + private String fieldType; + + /** + * 字段存值类型 + * */ + private String valueType; + + /** + * 字段约束范围 + * */ + private String valueScope; + + /** + * 是否衍生字段 + * */ + private String isDerivative; + + /** + * 是否输出字段 + * */ + private String isOutput; + + /** + * 衍生字段公式 + * */ + private String formula; + + /** + * 创建人 + * */ + private String author; + + /** + * 创建时间 + * */ + private Date created; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getFieldEn() { + return fieldEn; + } + + public void setFieldEn(String fieldEn) { + this.fieldEn = fieldEn; + } + + public String getFieldCn() { + return fieldCn; + } + + public void setFieldCn(String fieldCn) { + this.fieldCn = fieldCn; + } + + public String getFieldType() { + return fieldType; + } + + public void setFieldType(String fieldType) { + this.fieldType = fieldType; + } + + public String getValueType() { + return valueType; + } + + public void setValueType(String valueType) { + this.valueType = valueType; + } + + public String getValueScope() { + return valueScope; + } + + public void setValueScope(String valueScope) { + this.valueScope = valueScope; + } + + public String getIsDerivative() { + return isDerivative; + } + + public void setIsDerivative(String isDerivative) { + this.isDerivative = isDerivative; + } + + public String getIsOutput() { + return isOutput; + } + + public void setIsOutput(String isOutput) { + this.isOutput = isOutput; + } + + public String getFormula() { + return formula; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldFormulaVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldFormulaVo.java new file mode 100644 index 0000000..1a58aff --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldFormulaVo.java @@ -0,0 +1,89 @@ +package com.baoying.enginex.executor.datamanage.vo; + +import java.io.Serializable; + +public class FieldFormulaVo implements Serializable { + + private static final long serialVersionUID = 1L; + + // [{fvalue: "0",formula: "a",farr: [{fieldCN:"引擎字段1-1",fieldCond:[{"inputOne":"c","inputThree":"5"},{"inputOne":"b","inputThree":"12"}]},{fieldCN:"通用字段2贷前",fieldCond:[{"inputOne":"(30,40]","inputThree":"5"},{"inputOne":"[45,51)","inputThree":"12"}]}]}]; + + /** + * 衍生字段公式设置对应的值 + * */ + private String fvalue; + + /** + * 衍生字段公式 + * */ + private String formula; + + /** + * 衍生字段公式里字段的条件区域设置 + * */ + private Integer idx; + + /** + * 衍生字段公式里字段的条件区域设置 + * */ + private String farr; + + /** + * 衍生字段公式里条件区域设置的某个字段中文名 + * */ + private String fieldCN; + + /** + * 衍生字段公式里条件区域设置的某个字段的具体设置 + * */ + private String fieldCond; + + public String getFvalue() { + return fvalue; + } + + public void setFvalue(String fvalue) { + this.fvalue = fvalue; + } + + public String getFormula() { + return formula; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + public Integer getIdx() { + return idx; + } + + public void setIdx(Integer idx) { + this.idx = idx; + } + + public String getFarr() { + return farr; + } + + public void setFarr(String farr) { + this.farr = farr; + } + + public String getFieldCN() { + return fieldCN; + } + + public void setFieldCN(String fieldCN) { + this.fieldCN = fieldCN; + } + + public String getFieldCond() { + return fieldCond; + } + + public void setFieldCond(String fieldCond) { + this.fieldCond = fieldCond; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldSubCondVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldSubCondVo.java new file mode 100644 index 0000000..12955c3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/datamanage/vo/FieldSubCondVo.java @@ -0,0 +1,108 @@ +package com.baoying.enginex.executor.datamanage.vo; + +import java.io.Serializable; + +public class FieldSubCondVo implements Serializable{ + + private static final long serialVersionUID = 1L; + + //[{"fieldId":"43","operator":"in","fieldValue":"b","logical":"and"}] + + /** + * 条件字段编号 + * */ + private Integer fieldId; + + /** + * 条件字段的运算符 + * */ + private String operator; + + /** + * 条件字段的条件设置值 + * */ + private String fieldValue; + + /** + * 条件字段间的逻辑符 + * */ + private String logical; + + /** + * 条件字段的值类型 + * */ + private Integer valueType; + + /** + * 条件字段的取值范围 + * */ + private String valueScope; + + /** + * 条件字段的取值范围拆解后的数组 + * */ + private String[] values; + + /** + * 条件字段的字段名 + */ + private String fieldCn; + + + public Integer getFieldId() { + return fieldId; + } + public void setFieldId(Integer fieldId) { + this.fieldId = fieldId; + } + public String getOperator() { + return operator; + } + public void setOperator(String operator) { + this.operator = operator; + } + public String getFieldValue() { + return fieldValue; + } + public void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + public String getLogical() { + return logical; + } + public void setLogical(String logical) { + this.logical = logical; + } + public Integer getValueType() { + return valueType; + } + public void setValueType(Integer valueType) { + this.valueType = valueType; + } + public String getValueScope() { + return valueScope; + } + public void setValueScope(String valueScope) { + this.valueScope = valueScope; + } + public String[] getValues() { + if(valueType == 3){ + values = valueScope.split(","); + }else{ + values = new String[]{valueScope}; + } + return values; + } + public void setValues(String[] values) { + this.values = values; + } + public String getFieldCn() { + return fieldCn; + } + public void setFieldCn(String fieldCn) { + this.fieldCn = fieldCn; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineConst.java new file mode 100644 index 0000000..d94a29f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineConst.java @@ -0,0 +1,20 @@ +package com.baoying.enginex.executor.engine.consts; + + +public class EngineConst { + + /** + * 版本部署状态 + */ + public static final int BOOT_STATE_DEPLOY = 1; + + /** + * 版本未部署状态 + */ + public static final int BOOT_STATE_UNDEPLOY = 0; + + /** + * 决策选项结果集key + */ + public static final String DECISION_COLLECTION_KEY = "formulaList"; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineMsg.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineMsg.java new file mode 100644 index 0000000..564e1cb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineMsg.java @@ -0,0 +1,29 @@ +package com.baoying.enginex.executor.engine.consts; + +public class EngineMsg { + + /** + * 部署成功 + */ + public static final int STATUS_SUCCESS = 1; + + public static final String DEPLOY_SUCCESS = "部署成功!"; + + public static final String UNDEPLOY_SUCCESS = "当前版本已停用!"; + + /** + * 部署失败 + */ + public static final int STATUS_FAILED = 0; + + public static final String DEPLOY_FAILED = "部署失败!"; + + public static final String UNDEPLOY_FAILED = "停用当前版本失败!"; + + public static final String DELETE_RUNNING_FAILED = "当前版本正在运行,不能删除!"; + + public static final String DELETE_VERSION_SUCCESS = "当前版本删除成功!"; + + public static final String DELETE_VERSION_FAILED = "未知异常,当前版本删除失败!"; + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineOperator.java new file mode 100644 index 0000000..7f9bbc3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EngineOperator.java @@ -0,0 +1,151 @@ +package com.baoying.enginex.executor.engine.consts; + + +public class EngineOperator { + + /*---------------------------- 关系运算符 ----------------------------*/ + + public static final String OPERATOR_AND_RELATION = "&&"; + + public static final String OPERATOR_OR_RELATION = "||"; + + public static final String OPERATOR_NOT_RELATION = "!"; + + public static final String OPERATOR_EQUALS_RELATION = "=="; + + public static final String OPERATOR_GREATER_RELATION = ">"; + + public static final String OPERATOR_GREATER_EQUALS_RELATION = ">="; + + public static final String OPERATOR_LESS_RELATION = "<"; + + public static final String OPERATOR_LESS_EQUALS_RELATION = "<="; + + public static final String OPERATOR_NOT_EQUALS_RELATION = "!="; + + public static final String OPERATOR_AND_STRING_RELATION = "AND"; + + public static final String OPERATOR_OR_STRING_RELATION = "OR"; + + /*---------------------------- 数学运算符 ----------------------------*/ + + public static final String OPERATOR_ADD_MATH = "+"; + + public static final String OPERATOR_MINUS_MATH = "-"; + + public static final String OPERATOR_MULITI_MATH = "*"; + + public static final String OPERATOR_DIVIDE_MATH = "/"; + + public static final String OPERATOR_MODULU_MATH = "%"; + + public static final String OPERATOR_ABS_MATH = "abs"; + + public static final String OPERATOR_ACOS_MATH = "acos"; + + public static final String OPERATOR_ASIN_MATH = "asin"; + + public static final String OPERATOR_ATAN_MATH = "atan"; + + public static final String OPERATOR_ATAN2_MATH = "atan2"; + + public static final String OPERATOR_AVERAGE_MATH = "avg"; + + public static final String OPERATOR_CEIL_MATH = "ceil"; + + public static final String OPERATOR_COS_MATH = "cos"; + + public static final String OPERATOR_EXP_MATH = "exp"; + + public static final String OPERATOR_FLOOR_MATH = "floor"; + + public static final String OPERATOR_IEEE_MATH = "IEEEremainder"; + + public static final String OPERATOR_LN_MATH = "ln"; + + public static final String OPERATOR_LOG_MATH = "log"; + + public static final String OPERATOR_MAX_MATH = "max"; + + public static final String OPERATOR_MIN_MATH = "min"; + + public static final String OPERATOR_POW_MATH = "pow"; + + public static final String OPERATOR_RANDOM_MATH = "random"; + + public static final String OPERATOR_RINT_MATH = "rint"; + + public static final String OPERATOR_ROUND_MATH = "round"; + + public static final String OPERATOR_SIN_MATH = "sin"; + + public static final String OPERATOR_SQRT_MATH = "sqrt"; + + public static final String OPERATOR_SUM_MATH = "sum"; + + public static final String OPERATOR_TAN_MATH = "tan"; + + public static final String OPERATOR_TODEGREES_MATH = "toDegrees"; + + public static final String OPERATOR_TORADIANS_MATH = "toRadians"; + + /*---------------------------- 字符串运算符 ----------------------------*/ + + public static final String OPERATOR_CHARAT_STRING = "charAt"; + + public static final String OPERATOR_COMPARE_STRING = "compareTo"; + + public static final String OPERATOR_CTIC_STRING = "compareToIgnoreCase"; + + public static final String OPERATOR_CONCAT_STRING = "concat"; + + public static final String OPERATOR_ENDSWITH_STRING = "endsWith"; + + public static final String OPERATOR_EIC_STRING = "equalsIgnoreCase"; + + public static final String OPERATOR_EVAL_STRING = "eval"; + + public static final String OPERATOR_INDEXOF_STRING = "indexOf"; + + public static final String OPERATOR_LASTINDEXOF_STRING = "lastIndexOf"; + + public static final String OPERATOR_LENGTH_STRING = "length"; + + public static final String OPERATOR_REPLACE_STRING = "replace"; + + public static final String OPERATOR_STARTSWITH_STRING = "startsWith"; + + public static final String OPERATOR_SUB_STRING = "substring"; + + public static final String OPERATOR_TLC_STRING = "toLowerCase"; + + public static final String OPERATOR_TUC_STRING = "toUpperCase"; + + public static final String OPERATOR_TRIM_STRING = "trim"; + + public static final String OPERATOR_CONTAINS_STRING = "contains"; + + public static final String OPERATOR_UNCONTAINS_STRING = "notContains"; + + public static final String OPERATOR_EQUALS_STRING = "equals"; + + public static final String OPERATOR_UNEQUALS_STRING = "notEquals"; + + /*---------------------------- 符号 ----------------------------*/ + + public static final String OPERATOR_LEFT_BRACE = "{"; + + public static final String OPERATOR_RIGHT_BRACE = "}"; + + public static final String OPERATOR_VARIABLE_LEFT = "#"+OPERATOR_LEFT_BRACE; + + public static final String OPERATOR_VARIABLE_RIGHT = "}"; + + public static final String OPERATOR_LEFT_PARENTHESES = "("; + + public static final String OPERATOR_RIGHT_PARENTHESES = ")"; + + public static final String OPERATOR_LEFT_BRACKET = "["; + + public static final String OPERATOR_RIGHT_BRACKET = "]"; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EnumConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EnumConst.java new file mode 100644 index 0000000..d57c954 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/consts/EnumConst.java @@ -0,0 +1,47 @@ +package com.baoying.enginex.executor.engine.consts; + + +public class EnumConst { + + public static final String NODE_START = "开始"; + + public static final String NODE_POLICY = "政策规则"; + + public static final String NODE_CLASSIFY = "客户分群"; + + public static final String NODE_SCORECARD = "评分卡"; + + public static final String NODE_BLACK = "黑名单"; + + public static final String NODE_WHITE = "白名单"; + + public static final String NODE_SANDBOX = "沙盒比例"; + + public static final String NODE_CREDIT_LEVEL = "信用评级"; + + public static final String NODE_DECISION = "决策选项"; + + public static final String NODE_QUOTA_CALC = "额度计算"; + + public static final String NODE_REPORT = "报表分析"; + + public static final String NODE_CUSTOMIZE = "自定义按钮"; + + public static final String NODE_COMPLEXRULE = "复杂规则"; + + public static final String NODE_CHILD_ENGINE = "子引擎"; + + public static final String NODE_MODEL = "模型"; + + public static final String DECISION_TABLES = "决策表"; + + public static final String DECISION_TREE = "决策树"; + + public static final String NODE_RPC = "远程调用"; + + public static final String NODE_PARALLEL = "并行"; + + public static final String NODE_AGGREGATION = "聚合"; + + public static final String NODE_CHAMPION_CHALLENGE= "冠军挑战"; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/ApiController.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/ApiController.java new file mode 100644 index 0000000..fb2a01b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/ApiController.java @@ -0,0 +1,119 @@ +package com.baoying.enginex.executor.engine.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.engine.model.DecisionReqModel; +import com.baoying.enginex.executor.engine.service.EngineApiService; +import com.baoying.enginex.executor.engine.thread.EngineCallable; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +@Controller +@RequestMapping("/QueryString") +public class ApiController { + + private static final Logger logger = LoggerFactory.getLogger(ApiController.class); + + @Autowired + public EngineApiService engineApiService; + + @RequestMapping(value = "/decision", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json;charset=UTF-8") + @ResponseBody + public String decision(String ts, String nonce, String act, String pid, String uid, String sign, String token, String paramJson, String fields) { + logger.info("请求参数--" + "ts:" + ts + ",nonce:" + nonce + ",act:" + act + ",pid:" + pid + ",uid:" + uid + ", sign:" + sign + ",token:" + token + ",paramJson" + paramJson); + Map map = new HashMap<>(); + map.put("ts", ts); + map.put("nonce", nonce); + map.put("act", act); + map.put("pid", pid); + map.put("uid", uid); + map.put("token", token); + JSONObject jsonObject = JSONObject.parseObject(paramJson); + if (jsonObject.getInteger("reqType") == 2) { + map.put("version", jsonObject.getInteger("version")); + map.put("subversion", jsonObject.getInteger("subversion")); + } + map.put("reqType", jsonObject.getInteger("reqType")); + map.put("engineId", jsonObject.getLong("engineId")); + map.put("organId", jsonObject.getLong("organId")); + map.put("sign", jsonObject.getString("sign")); + + Map requestFields = new HashMap<>(); + if(StringUtils.isNotBlank(fields)){ + requestFields = JSONObject.parseObject(fields, Map.class); + } + map.put("fields", requestFields); + String result = engineApiService.engineApi(map); + logger.info("uid:" + uid + " 响应参数--" + "result:" + result); + return result; + } + + @RequestMapping(value = "/batchDecision", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json;charset=UTF-8") + @ResponseBody + public String batchDecision(HttpServletResponse response, String ts, String nonce, String act, String sign, String token, int reqType, Long engineId, Long organId, String paramJson) { + List resultList = new ArrayList<>(); + Map resultMap = new HashMap<>(); + + List> list = new ArrayList<>(); + List reqModelList = JSONObject.parseArray(paramJson, DecisionReqModel.class); + for (DecisionReqModel reqModel : reqModelList) { + Map map = new HashMap<>(); + map.put("ts", ts); + map.put("nonce", nonce); + map.put("act", act); + map.put("token", token); + map.put("reqType", reqType); + map.put("engineId", engineId); + map.put("organId", organId); + map.put("sign", sign); + map.put("pid", reqModel.getPid()); + map.put("uid", reqModel.getUid()); + + Map requestFields = new HashMap<>(); + if(reqModel.getFields() != null){ + requestFields = JSONObject.parseObject(JSONObject.toJSONString(reqModel.getFields()), Map.class); + } + map.put("fields", requestFields); + list.add(map); + } + + List> futureList = new ArrayList<>(); + ExecutorService executorService = Executors.newFixedThreadPool(10); + for(Map paramMap : list){ + futureList.add(executorService.submit(new EngineCallable(paramMap))); + } + + // 获取线程执行结果 + for (final Future future : futureList) { + try { + final String str = future.get(5, TimeUnit.MINUTES); + resultList.add(JSONObject.parseObject(str)); + } catch (Exception e) { + boolean cancelResult = future.cancel(true); + logger.error("取消结果(" + cancelResult + ")" + e.getMessage(), e); + } + } + + String result = JSONObject.toJSONString(resultList); + resultMap.put("result", resultList); + logger.info(" 响应参数--" + "result:" + result); + + return result; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/DecisionController.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/DecisionController.java new file mode 100644 index 0000000..7a6d70a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/controller/DecisionController.java @@ -0,0 +1,70 @@ +package com.baoying.enginex.executor.engine.controller; + +import com.baoying.enginex.executor.common.session.SessionData; +import com.baoying.enginex.executor.common.session.SessionManager; +import com.baoying.enginex.executor.engine.model.request.DecisionApiBizData; +import com.baoying.enginex.executor.engine.model.request.DecisionApiRequest; +import com.baoying.enginex.executor.engine.service.EngineApiService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Controller +@RequestMapping("/runner") +public class DecisionController { + + private static final Logger logger = LoggerFactory.getLogger(DecisionController.class); + + @Autowired + public EngineApiService engineApiService; + + @RequestMapping(value = "/decision", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public String decision(@RequestBody DecisionApiRequest apiRequest) { + long start = System.currentTimeMillis(); + DecisionApiBizData bizData = apiRequest.getBiz_data(); + Map map = new HashMap<>(); + map.put("pid", bizData.getBusinessId()); + map.put("uid", ""); + map.put("reqType", 1); + map.put("engineId", bizData.getEngineId()); + map.put("organId", bizData.getOrganId()); + + SessionData sessionData = new SessionData(); + sessionData.setOrganId(bizData.getOrganId()); + sessionData.setEngineId(bizData.getEngineId()); + sessionData.setReqType(1); + SessionManager.setSession(sessionData); + + if(bizData.getFields() != null){ + map.put("fields", bizData.getFields()); + } else { + map.put("fields", new HashMap<>()); + } + String result = engineApiService.engineApi(map); + long end = System.currentTimeMillis(); + logger.info("============ 接口调用耗时:{}ms ============", (end -start)); + return result; + } + + @RequestMapping(value = "/batchExecute", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public List batchExecute(@RequestBody List requestList){ + List list = new ArrayList<>(); + for (DecisionApiRequest apiRequest : requestList) { + String decision = this.decision(apiRequest); + list.add(decision); + } + return list; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/CallBackTypeEnum.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/CallBackTypeEnum.java new file mode 100644 index 0000000..8478cc4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/CallBackTypeEnum.java @@ -0,0 +1,23 @@ +package com.baoying.enginex.executor.engine.enums; + +public enum CallBackTypeEnum { + + SYNC(1,"同步"), + ASYNC(2,"异步"); + + private int code; + private String message; + + CallBackTypeEnum(int code, String message) { + this.code = code; + this.message = message; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/NodeTypeEnum.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/NodeTypeEnum.java new file mode 100644 index 0000000..545e33b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/enums/NodeTypeEnum.java @@ -0,0 +1,125 @@ +package com.baoying.enginex.executor.engine.enums; + +import com.baoying.enginex.executor.engine.consts.EnumConst; + +public enum NodeTypeEnum { + /** + * 开始节点 + */ + START(1, EnumConst.NODE_START), + /** + * 规则节点 + */ + POLICY(2,EnumConst.NODE_POLICY), + /** + * 分组节点 + */ + CLASSIFY(3, EnumConst.NODE_CLASSIFY), + /** + * 评分卡节点 + */ + SCORECARD(4,EnumConst.NODE_SCORECARD), + /** + * 黑名单节点 + */ + BLACKLIST(5,EnumConst.NODE_BLACK), + /** + * 白名单节点 + */ + WHITELIST(6,EnumConst.NODE_WHITE), + /** + * 沙盒节点 + */ + SANDBOX(7,EnumConst.NODE_SANDBOX), + /** + * 信用评级节点 + */ + CREDITLEVEL(8,EnumConst.NODE_CREDIT_LEVEL), + /** + * 决策选项节点 + */ + DECISION(9,EnumConst.NODE_DECISION), + /** + * 额度计算节点 + */ + QUOTACALC(10,EnumConst.NODE_QUOTA_CALC), + /** + * 报表分析节点 + */ + REPORT(11,EnumConst.NODE_REPORT), + /** + * 自定义节点 + */ + CUSTOMIZE(12,EnumConst.NODE_CUSTOMIZE), + /** + * 复杂规则 + */ + NODE_COMPLEXRULE(13,EnumConst.NODE_COMPLEXRULE), + /** + * 子引擎 + */ + CHILD_ENGINE(14,EnumConst.NODE_CHILD_ENGINE), + /** + * 模型 + */ + MODEL(15,EnumConst.NODE_MODEL), + /** + * 决策表 + */ + DECISION_TABLES(16,EnumConst.DECISION_TABLES), + /** + * 决策树 + */ + DECISION_TREE(17,EnumConst.DECISION_TREE), + /** + * 远程调用 + */ + RPC(18, EnumConst.NODE_RPC), + /** + * 并行节点 + */ + PARALLEL(19, EnumConst.NODE_PARALLEL), + /** + * 聚合节点 + */ + AGGREGATION(20, EnumConst.NODE_AGGREGATION), + /** + * 冠军挑战节点 + */ + CHAMPION_CHALLENGE(21, EnumConst.NODE_CHAMPION_CHALLENGE); + + private int value; + + private String type; + + private NodeTypeEnum(int value, String type) + { + this.value = value; + this.type = type; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public static NodeTypeEnum adapad(int value) { + for (NodeTypeEnum nodeTypeEnum : NodeTypeEnum.values()) { + if (nodeTypeEnum.getValue() == value) { + return nodeTypeEnum; + } + } + return null; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineMapper.java new file mode 100644 index 0000000..08717b6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineMapper.java @@ -0,0 +1,9 @@ +package com.baoying.enginex.executor.engine.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.engine.model.Engine; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EngineMapper extends BaseMapper { +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.java new file mode 100644 index 0000000..2a3012e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.java @@ -0,0 +1,18 @@ +package com.baoying.enginex.executor.engine.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.engine.model.EngineNode; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface EngineNodeMapper extends BaseMapper { + + /** + * 根据版本id获取版本下的所有节点 + * @param engineVersionId + * @return + */ + List getEngineNodeListByVersionId(@Param("engineVersionId") Long engineVersionId); + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.xml new file mode 100644 index 0000000..ce6e7f1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineNodeMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + node_id, parent_id, version_id, node_name, node_code, node_order, node_type, node_x, node_y,node_json,node_script,next_nodes,params,snapshot + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.java new file mode 100644 index 0000000..d75f9c6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.java @@ -0,0 +1,72 @@ + + +package com.baoying.enginex.executor.engine.mapper; + + +import com.baoying.enginex.executor.engine.model.EngineResultSet; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + + +public interface EngineResultSetMapper { + /** + * + * 增加结果集 + * @param resultSet 结果集对象 + * @return 返回结果 + * @see + */ + int insertResultSet(EngineResultSet resultSet); + /** + * + * 查询结果集列表 + * @param resultSet 查询对象 + * @return 返回结果集 + * @see + */ + List getResultSetByList(EngineResultSet resultSet); + + /** + * 根据引擎编号和时间段获取结果集数据 + * @param map + * @return + */ + List getEngineResultSetBySegment(Map map); + + /** + * + * 通过主键编号得到 + * @param resultSet 对象 + * @return 返回对象 + * @see + */ + EngineResultSet getResultSetById(EngineResultSet resultSet); + + List getResultSetDetailsById(long resultSetId); + + /** + * 查找引擎id的批量测试结果 + * yuanlinfeng + * @param resultSetId + * @return + */ + List getBatchTestResultSetByEngineId(Map paramMap); + + /** + * 查找引擎批量测试批次号的所有测试结果 + * yuanlinfeng + * @param resultSetId + * @return + */ + List getBatchTestResultSetByBatchNo(Map paramMap); + + /** + * 更新结果出参 + * @param resultSet + */ + void updateResultOutput(EngineResultSet resultSet); + void updateResultById(@Param("resultId") Integer resultId, @Param("rowKeyStr") String rowKeyStr); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.xml new file mode 100644 index 0000000..758e1a4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineResultSetMapper.xml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO + t_resultset + + + uid, + + + pid, + + + input, + + + output, + + + result, + + + engine_id, + + + uuid, + + + engine_version, + + + engine_name, + + + engine_code, + + + type, + + + sub_version, + + + scorecardscore, + + + batch_no, + + + datilResult, + + + values + + + #{uid}, + + + #{pid}, + + + #{input}, + + + #{output}, + + + #{result}, + + + #{engine_id}, + + + #{uuid}, + + + #{engine_version}, + + + #{engine_name}, + + + #{engine_code}, + + + #{type}, + + + #{subVersion}, + + + #{scorecardscore}, + + + #{batchNo}, + + + #{datilResult}, + + + + + + + + + + + + + + + update t_resultset t set t.`output` = #{output} where t.`id` = #{id} + + + + UPDATE t_resultset + set hbase_row_key = #{rowKeyStr} + where id = #{resultId} + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.java new file mode 100644 index 0000000..b8acde4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.java @@ -0,0 +1,27 @@ +package com.baoying.enginex.executor.engine.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.engine.model.EngineVersion; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Map; + +@Mapper +public interface EngineVersionMapper extends BaseMapper { + + /** + * 获取引擎正在运行中的版本 + * @param engineId + * @return + */ + EngineVersion getRunningVersion(@Param("engineId") Long engineId); + + /** + * 获取指定版本信息 + * @param paramMap + * @return + */ + EngineVersion getTargetEngineVersion(Map paramMap); + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.xml new file mode 100644 index 0000000..b207c87 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/mapper/EngineVersionMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + version_id, engine_id, version, boot_state, status, layout, user_id, create_time, + latest_user, latest_time, sub_version + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ComplexRule.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ComplexRule.java new file mode 100644 index 0000000..89791a2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ComplexRule.java @@ -0,0 +1,42 @@ +package com.baoying.enginex.executor.engine.model; + +import java.util.Map; + +public class ComplexRule { + + private Map result; + + private String out; + + private Map returnResult; + + + + public Map getReturnResult() { + return returnResult; + } + + public void setReturnResult(Map returnResult) { + this.returnResult = returnResult; + } + + public Map getResult() { + return result; + } + + public void setResult(Map result) { + this.result = result; + } + + public String getOut() { + return out; + } + + public void setOut(String out) { + this.out = out; + } + + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionOptions.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionOptions.java new file mode 100644 index 0000000..9a36d3b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionOptions.java @@ -0,0 +1,62 @@ + +package com.baoying.enginex.executor.engine.model; + +import java.util.Map; + +public class DecisionOptions { + private String code;//决策选项code + private String name;//决策选项名称 + private Map inFields;//输入字段 + private Map outFields;//输出字段 + private Integer fType;//输出字段类型 + private Long nodId;//节点id + private String fieldScope; + + + + public String getFieldScope() { + return fieldScope; + } + public void setFieldScope(String fieldScope) { + this.fieldScope = fieldScope; + } + public Long getNodId() { + return nodId; + } + public void setNodId(Long nodId) { + this.nodId = nodId; + } + public Integer getfType() { + return fType; + } + public void setfType(Integer fType) { + this.fType = fType; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Map getInFields() { + return inFields; + } + public void setInFields(Map inFields) { + this.inFields = inFields; + } + public Map getOutFields() { + return outFields; + } + public void setOutFields(Map outFields) { + this.outFields = outFields; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionReqModel.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionReqModel.java new file mode 100644 index 0000000..6666277 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/DecisionReqModel.java @@ -0,0 +1,16 @@ +package com.baoying.enginex.executor.engine.model; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class DecisionReqModel implements Serializable { + private static final long serialVersionUID = 1743177499998353115L; + + private String pid; + private String uid; + private JSONObject fields; + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Engine.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Engine.java new file mode 100644 index 0000000..a3d0cd8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Engine.java @@ -0,0 +1,90 @@ +package com.baoying.enginex.executor.engine.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +@TableName("t_engine") +public class Engine implements Serializable { + private static final long serialVersionUID = -6611916471057697499L; + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 引擎编号 + */ + private String code; + + /** + * 引擎名称 + */ + private String name; + + /** + * 引擎描述 + */ + private String description; + + /** + * 引擎状态 + */ + private Integer status; + + /** + * 创建时间 + */ + private Date createDatetime; + + /** + * 修改时间 + */ + private Date updateDatetime; + + /** + * 创建人 + */ + private Long creator; + + /** + * 修改人 + */ + private Long userId; + + /** + * 公司编号 + */ + private Long organId; + + /** + * 调用方式 1:同步,2:异步 + */ + private Integer callbackType; + + /** + * 回调地址 + */ + private String callbackUrl; + + /** + * 异常回调地址 + */ + private String exceptionCallbackUrl; + + /** + * 引擎版本集合 + */ + @TableField(exist = false) + private List engineVersionList; + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineNode.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineNode.java new file mode 100644 index 0000000..ae8026a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineNode.java @@ -0,0 +1,85 @@ +package com.baoying.enginex.executor.engine.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +@Data +@TableName("t_engine_node") +public class EngineNode implements Serializable{ + private static final long serialVersionUID = -1867357850853531748L; + + /** + * 节点编号 + */ + @TableId(type = IdType.AUTO) + private Long nodeId; + + /** + * 版本编号 + */ + private Long versionId; + + /** + * 节点名称 + */ + private String nodeName; + + /** + * 节点code + */ + private String nodeCode; + + /** + * 节点顺序 + */ + private Integer nodeOrder; + + /** + * 节点类型 + */ + private Integer nodeType; + + /** + * 节点json + */ + private String nodeJson; + + /** + * 节点X轴 + */ + private double nodeX; + + /** + * 节点Y轴 + */ + private double nodeY; + + /** + * 节点脚本 + */ + private String nodeScript; + + /** + * 下一节点 + */ + private String nextNodes; + + /** + * 节点类型,图标等信息 + */ + private String params; + + /** + * 父节点编号 + */ + private String parentId; + + /** + * 节点配置快照 + */ + private String snapshot; +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineResultSet.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineResultSet.java new file mode 100644 index 0000000..cd21487 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineResultSet.java @@ -0,0 +1,252 @@ + + +package com.baoying.enginex.executor.engine.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.util.Date; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Accessors +public class EngineResultSet { + private Integer id; + private String uid; + private String pid; + private String input; + private String output; + private Date create_datetime; + + private String result; + + private Long engine_id; + + private Integer engine_version; + + private String uuid; + + private String engine_name; + + private String engine_code; + + private Date startDate; + + private Date endDate; + + private Integer type; + + private Integer subVersion; + + private String scorecardscore; + + private String datilResult; + /** + *决策表结果 + */ + private String decisionTablesResult; + + /** + *决策树结果 + */ + private String decisionTreeResult; + + /** + * 批量测试批次号 + */ + private String batchNo; + + /** + * 批量测试每批测试开始时间 + */ + private Date startTime; + + /** + * 批量测试每批次花费时间 + */ + private String costTime; + + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getScorecardscore() { + return scorecardscore; + } + + public void setScorecardscore(String scorecardscore) { + this.scorecardscore = scorecardscore; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getSubVersion() { + return subVersion; + } + + public void setSubVersion(Integer subVersion) { + this.subVersion = subVersion; + } + + private List resultSetList; + + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public String getEngine_name() { + return engine_name; + } + + public void setEngine_name(String engine_name) { + this.engine_name = engine_name; + } + + public String getEngine_code() { + return engine_code; + } + + public void setEngine_code(String engine_code) { + this.engine_code = engine_code; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public Date getCreate_datetime() { + return create_datetime; + } + + public void setCreate_datetime(Date create_datetime) { + this.create_datetime = create_datetime; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public Long getEngine_id() { + return engine_id; + } + + public void setEngine_id(Long engine_id) { + this.engine_id = engine_id; + } + + public Integer getEngine_version() { + return engine_version; + } + + public void setEngine_version(Integer engine_version) { + this.engine_version = engine_version; + } + + public List getResultSetList() { + return resultSetList; + } + + public void setResultSetList(List resultSetList) { + this.resultSetList = resultSetList; + } + + public String getBatchNo() { + return batchNo; + } + + public void setBatchNo(String batchNo) { + this.batchNo = batchNo; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public String getCostTime() { + return costTime; + } + + public void setCostTime(String costTime) { + this.costTime = costTime; + } + + public String getDatilResult() { + return datilResult; + } + + public void setDatilResult(String datilResult) { + this.datilResult = datilResult; + } + + public String getOutput() { + return output; + } + + public void setOutput(String output) { + this.output = output; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineRule.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineRule.java new file mode 100644 index 0000000..9c840fe --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineRule.java @@ -0,0 +1,74 @@ + +package com.baoying.enginex.executor.engine.model; + +import java.util.Map; + +public class EngineRule { + + private String refused; + + private String code ; + + private String policyName; + + private String desc; + + private String Strtus; + + + private Mapfields; + + + public String getStrtus() { + return Strtus; + } + + public void setStrtus(String strtus) { + Strtus = strtus; + } + + public String getRefused() { + return refused; + } + + public void setRefused(String refused) { + this.refused = refused; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getPolicyName() { + return policyName; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public Map getFields() { + return fields; + } + + public void setFields(Map fields) { + this.fields = fields; + } + + + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineVersion.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineVersion.java new file mode 100644 index 0000000..8820695 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/EngineVersion.java @@ -0,0 +1,79 @@ +package com.baoying.enginex.executor.engine.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +@TableName("t_engine_version") +public class EngineVersion implements Serializable { + private static final long serialVersionUID = 2923432053414979455L; + + /** + * 版本编号 + */ + @TableId(type = IdType.AUTO) + private Long versionId; + + /** + * 引擎编号 + */ + private Long engineId; + + /** + * 版本号 + */ + private Integer version; + + /** + * 子版本 + */ + private Integer subVersion; + + /** + * 部署状态 + */ + private Integer bootState; + + /** + * 版本状态 + */ + private Integer status; + + /** + * 布局方式 + */ + private Integer layout; + + /** + * 创建者 + */ + private Long userId; + + /** + * 创建时间 + */ + private String createTime; + + /** + * 修改人 + */ + private Long latestUser; + + /** + * 最后修改时间 + */ + private String latestTime; + + /** + * 节点集合 + * */ + @TableField(exist = false) + private List engineNodeList; + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/IndexEngineReportVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/IndexEngineReportVo.java new file mode 100644 index 0000000..db1cad3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/IndexEngineReportVo.java @@ -0,0 +1,53 @@ +package com.baoying.enginex.executor.engine.model; + +import java.io.Serializable; + +public class IndexEngineReportVo implements Serializable { + + private static final long serialVersionUID = -1274492726714567316L; + private String dayTime; + private String monthTime; + private Integer engineId; + private String engineName; + private Integer useNum; + + public String getDayTime() { + return dayTime; + } + + public void setDayTime(String dayTime) { + this.dayTime = dayTime; + } + + public String getMonthTime() { + return monthTime; + } + + public void setMonthTime(String monthTime) { + this.monthTime = monthTime; + } + + public Integer getEngineId() { + return engineId; + } + + public void setEngineId(Integer engineId) { + this.engineId = engineId; + } + + public String getEngineName() { + return engineName; + } + + public void setEngineName(String engineName) { + this.engineName = engineName; + } + + public Integer getUseNum() { + return useNum; + } + + public void setUseNum(Integer useNum) { + this.useNum = useNum; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/InputParam.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/InputParam.java new file mode 100644 index 0000000..eabdde6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/InputParam.java @@ -0,0 +1,36 @@ +package com.baoying.enginex.executor.engine.model; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class InputParam { + private Map inputParam; + private List result; + // 数组中 符合条件的对象属性 + private Map> outputParam; + + public Map getInputParam() { + return inputParam; + } + + public void setInputParam(Map inputParam) { + this.inputParam = inputParam; + } + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } + + public Map> getOutputParam() { + return outputParam; + } + + public void setOutputParam(Map> outputParam) { + this.outputParam = outputParam; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/NodeKnowledge.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/NodeKnowledge.java new file mode 100644 index 0000000..3ea8595 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/NodeKnowledge.java @@ -0,0 +1,63 @@ +package com.baoying.enginex.executor.engine.model; + +import java.io.Serializable; + +/** + * 节点与知识库映射关系模型 + * @author sunyk + * + */ +public class NodeKnowledge implements Serializable { + private static final long serialVersionUID = -55965399064577379L; + /** + * 主键编号 + */ + private Long relId; + + /** + * 节点编号 + */ + private Long nodeId; + + /** + * 知识库信息编号 + */ + private Long knowledgeId; + + /** + * 知识库类型1规则2评分卡 + */ + private Integer knowledgeType; + + public Long getRelId() { + return relId; + } + + public void setRelId(Long relId) { + this.relId = relId; + } + + public Long getNodeId() { + return nodeId; + } + + public void setNodeId(Long nodeId) { + this.nodeId = nodeId; + } + + public Long getKnowledgeId() { + return knowledgeId; + } + + public void setKnowledgeId(Long knowledgeId) { + this.knowledgeId = knowledgeId; + } + + public Integer getKnowledgeType() { + return knowledgeType; + } + + public void setKnowledgeType(Integer knowledgeType) { + this.knowledgeType = knowledgeType; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Result.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Result.java new file mode 100644 index 0000000..21f19a5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Result.java @@ -0,0 +1,63 @@ + + +package com.baoying.enginex.executor.engine.model; + +import java.util.List; +import java.util.Map; + +public class Result { + private String resultType;//规则1代表加减法,2拒绝规则 + private Integer id;//规则编号 + private String code;//规则code + private String name; + private String value; + private Map map;//评分 + private List list; + + + public Map getMap() { + return map; + } + public void setMap(Map map) { + this.map = map; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getResultType() { + return resultType; + } + public void setResultType(String resultType) { + this.resultType = resultType; + } + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public List getList() { + return list; + } + public void setList(List list) { + this.list = list; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ResultSetList.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ResultSetList.java new file mode 100644 index 0000000..af50abb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ResultSetList.java @@ -0,0 +1,76 @@ + + +package com.baoying.enginex.executor.engine.model; + +import java.util.Date; + +public class ResultSetList { + private Long id; + private Integer type;//1.黑名单。2.白名单。3.拒绝规则。4.加减分规则 + private String code; + private String name; + private String description; + private String resultsetId; + private String expression; + private Date startDate; + private Date endDate; + + +public Date getStartDate() { + return startDate; +} +public void setStartDate(Date startDate) { + this.startDate = startDate; +} +public Date getEndDate() { + return endDate; +} +public void setEndDate(Date endDate) { + this.endDate = endDate; +} +public Long getId() { + return id; +} +public void setId(Long id) { + this.id = id; +} +public Integer getType() { + return type; +} +public void setType(Integer type) { + this.type = type; +} +public String getCode() { + return code; +} +public void setCode(String code) { + this.code = code; +} +public String getName() { + return name; +} +public void setName(String name) { + this.name = name; +} +public String getDescription() { + return description; +} +public void setDescription(String description) { + this.description = description; +} +public String getResultsetId() { + return resultsetId; +} +public void setResultsetId(String resultsetId) { + this.resultsetId = resultsetId; +} +public String getExpression() { + return expression; +} +public void setExpression(String expression) { + this.expression = expression; +} + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Sandbox.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Sandbox.java new file mode 100644 index 0000000..cc06839 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/Sandbox.java @@ -0,0 +1,53 @@ + + +package com.baoying.enginex.executor.engine.model; + +public class Sandbox { + private Integer sandbox;//沙盒组编号 + private Integer proportion;//沙盒占用比例 + private String nextNode;//下个节点序号 + private Integer sum;//分母 + private Integer startNumber;//起始值 + private Integer endNumberl;//终止值 + + + + public Integer getSum() { + return sum; + } + public void setSum(Integer sum) { + this.sum = sum; + } + public Integer getStartNumber() { + return startNumber; + } + public void setStartNumber(Integer startNumber) { + this.startNumber = startNumber; + } + public Integer getEndNumberl() { + return endNumberl; + } + public void setEndNumberl(Integer endNumberl) { + this.endNumberl = endNumberl; + } + public Integer getSandbox() { + return sandbox; + } + public void setSandbox(Integer sandbox) { + this.sandbox = sandbox; + } + public Integer getProportion() { + return proportion; + } + public void setProportion(Integer proportion) { + this.proportion = proportion; + } + public String getNextNode() { + return nextNode; + } + public void setNextNode(String nextNode) { + this.nextNode = nextNode; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ScoreCardEngine.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ScoreCardEngine.java new file mode 100644 index 0000000..1890952 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/ScoreCardEngine.java @@ -0,0 +1,49 @@ + + +package com.baoying.enginex.executor.engine.model; + +import java.util.Map; + +public class ScoreCardEngine { + private String code;//评分卡编号 + private String name;//评分卡名称 + private String scoreCardName;//评分卡名称 + private Map inFields;//评分可用到的字段 + private Map outFields;//评分卡 + + + public String getScoreCardName() { + return scoreCardName; + } + public void setScoreCardName(String scoreCardName) { + this.scoreCardName = scoreCardName; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Map getInFields() { + return inFields; + } + public void setInFields(Map inFields) { + this.inFields = inFields; + } + public Map getOutFields() { + return outFields; + } + public void setOutFields(Map outFields) { + this.outFields = outFields; + } + + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/TestRule.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/TestRule.java new file mode 100644 index 0000000..c1478ba --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/TestRule.java @@ -0,0 +1,37 @@ + + +package com.baoying.enginex.executor.engine.model; + +public class TestRule { + private String id; + + private String ruleid; + + private String param; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getRuleid() { + return ruleid; + } + + public void setRuleid(String ruleid) { + this.ruleid = ruleid; + } + + public String getParam() { + return param; + } + + public void setParam(String param) { + this.param = param; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiBizData.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiBizData.java new file mode 100644 index 0000000..28a0abb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiBizData.java @@ -0,0 +1,18 @@ +package com.baoying.enginex.executor.engine.model.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Map; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = false) +public class DecisionApiBizData { + + private String businessId; // 业务id + private Long organId; // 组织id + private Long engineId; // 引擎id + private Map fields; // 指标字段键值对 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiRequest.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiRequest.java new file mode 100644 index 0000000..df0e1f8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/model/request/DecisionApiRequest.java @@ -0,0 +1,17 @@ +package com.baoying.enginex.executor.engine.model.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = false) +public class DecisionApiRequest { + + private String tp_code; // 调用方编码 + private String timestamp; // 精确到毫秒 + private String sign; // 签名 + private String biz_enc; // biz_data加密方式(0不加密,1加密) + private DecisionApiBizData biz_data; // 请求的业务数据,json格式的字符串 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineApiService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineApiService.java new file mode 100644 index 0000000..80b2034 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineApiService.java @@ -0,0 +1,8 @@ +package com.baoying.enginex.executor.engine.service; + +import java.util.Map; + +public interface EngineApiService { + + String engineApi(Map paramJson); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineNodeService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineNodeService.java new file mode 100644 index 0000000..0dfd038 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineNodeService.java @@ -0,0 +1,16 @@ +package com.baoying.enginex.executor.engine.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.engine.model.EngineNode; + +import java.util.List; + +public interface EngineNodeService extends IService { + + /** + * 根据版本id获取版本下的所有节点 + * @param versionId + * @return + */ + List getEngineNodeListByVersionId(Long versionId); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineService.java new file mode 100644 index 0000000..163aecf --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineService.java @@ -0,0 +1,14 @@ +package com.baoying.enginex.executor.engine.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.engine.model.Engine; + +public interface EngineService extends IService { + + /** + * 根据id查询引擎 + * @param id + * @return + */ + Engine getEngineById(Long id); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineVersionService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineVersionService.java new file mode 100644 index 0000000..3a16c19 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/EngineVersionService.java @@ -0,0 +1,17 @@ +package com.baoying.enginex.executor.engine.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.engine.model.EngineVersion; + +public interface EngineVersionService extends IService { + + EngineVersion getEngineVersionById(Long versionId); + + /** + * 获取引擎正在运行中的版本 + * @param engineId + * @return + */ + EngineVersion getRunningVersion(Long engineId); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineApiServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineApiServiceImpl.java new file mode 100644 index 0000000..215cd62 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineApiServiceImpl.java @@ -0,0 +1,400 @@ +package com.baoying.enginex.executor.engine.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.engine.enums.NodeTypeEnum; +import com.baoying.enginex.executor.engine.mapper.EngineResultSetMapper; +import com.baoying.enginex.executor.engine.model.Engine; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.engine.model.EngineResultSet; +import com.baoying.enginex.executor.engine.model.EngineVersion; +import com.baoying.enginex.executor.engine.service.EngineApiService; +import com.baoying.enginex.executor.engine.service.EngineNodeService; +import com.baoying.enginex.executor.engine.service.EngineService; +import com.baoying.enginex.executor.engine.service.EngineVersionService; +import com.baoying.enginex.executor.node.service.impl.*; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; +import org.springframework.web.client.AsyncRestTemplate; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class EngineApiServiceImpl implements EngineApiService { + + private static final Logger logger = LoggerFactory.getLogger(EngineApiServiceImpl.class); + + @Autowired + public EngineService engineService; + + @Resource + public EngineVersionService engineVersionService; + + @Resource + public EngineNodeService engineNodeService; + + @Resource + public EngineResultSetMapper resultSetMapper; + + @Autowired + private DecisionOptionsNode decisionOptionsNode; + + @Autowired + private RuleSetNode ruleSetNode; + + @Autowired + private GroupNode groupNode; + + @Autowired + private SandboxProportionNode sandboxProportionNode; + + @Autowired + private AsyncRestTemplate asyncRestTemplate; + + @Override + public String engineApi(Map paramJson) { + logger.info("请求参数,paramJson: {}", JSONObject.toJSONString(paramJson)); + JSONObject jsonObject = new JSONObject(); + JSONArray resultJson = new JSONArray(); + Map> featureMaps = new ConcurrentHashMap<>(); + //时间差小于等于30分钟并且鉴权成功 + if (true){ + Long organId = Long.valueOf(paramJson.get("organId").toString()); + Long engineId = Long.valueOf(paramJson.get("engineId").toString()); + //获取引擎信息 + Engine engine = engineService.getEngineById(engineId); + if(engine != null && !engine.getOrganId().equals(organId)){ + // todo 校验引擎是否为该组织所属 + } + //获取引擎正在运行中的版本 + EngineVersion engineVersion = engineVersionService.getRunningVersion(engineId); + if (engineVersion != null) { + //返回引擎下的所有节点集合 + List engineNodeList = engineNodeService.getEngineNodeListByVersionId(engineVersion.getVersionId()); + Map engineNodeMap = getEngineNodeListByMap(engineNodeList); + try { + //变量池 + Map inputParam = new ConcurrentHashMap<>(); + inputParam.putAll(JSONObject.parseObject(JSONObject.toJSONString(paramJson.get("fields")), Map.class)); + EngineNode engineNode = engineNodeMap.get("ND_START"); + if (null != engineNode && null != engineNode.getNextNodes()) { + //返回输出结果 + Map outMap = new ConcurrentHashMap<>(); + // 记录执行前全量指标 + featureMaps.put("before",inputParam); + //节点执行方法 + recursionEngineNode(inputParam, engineNodeMap.get(engineNode.getNextNodes()), engineNodeMap, outMap); + jsonObject.put("status", "0x0000"); + jsonObject.put("msg", "执行成功"); + if (outMap.containsKey("centens") && outMap.get("centens").equals("true")) { + jsonObject.put("status", "0x0006"); + jsonObject.put("msg", "获取数据失败"); + jsonObject.put("data", ""); + return jsonObject.toString(); + } + //记录执行后的全量指标 + featureMaps.put("after",inputParam); + paramJson.put("versionId",engineNode.getVersionId()); + String json = JSONObject.toJSONString(inputParam); + jsonObject.put("input", JSONObject.parseObject(json)); + + EngineResultSet resultSet = new EngineResultSet(); + resultSet.setEngine_code(engine.getCode()); + resultSet.setInput(json); + resultSet.setEngine_id(engine.getId()); + resultSet.setEngine_name(engine.getName()); + resultSet.setType(2); + resultSet.setSubVersion(engineVersion.getSubVersion()); + resultSet.setUid(String.valueOf(paramJson.get("uid"))); + resultSet.setPid(String.valueOf(paramJson.get("pid"))); + + //决策表最终结果 + if (outMap.containsKey("decisionTables")){ + jsonObject.put("decisionTablesResult", outMap.get("decisionTables").toString()); + resultSet.setDecisionTablesResult(outMap.get("decisionTables").toString()); + } + //决策树最终结果 + if (outMap.containsKey("decisionTree")){ + jsonObject.put("decisionTreeResult", outMap.get("decisionTree").toString()); + resultSet.setDecisionTreeResult(outMap.get("decisionTree").toString()); + } + // 节点终止输出 + if (outMap.containsKey("result")) { + resultSet.setResult(outMap.get("result").toString()); + //决策选项最终结果 + jsonObject.put("result", outMap.get("result").toString()); + } + + if (outMap.containsKey("blackJson")) { + resultJson.add(new JSONObject().parse(outMap.get("blackJson").toString())); + } + + if (outMap.containsKey("whiteJson")) { + resultJson.add(new JSONObject().parse(outMap.get("whiteJson").toString())); + } + + if (outMap.containsKey("ruleJson")) { + //规则集节点输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 2); + ruleJson.put("resultJson", outMap.get("ruleJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("scoreJson")) { + //评分卡输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 4); + ruleJson.put("resultJson", outMap.get("scoreJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("decisionJson")) { + //决策选项输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 9); + ruleJson.put("resultJson", outMap.get("decisionJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("childEngineJson")) { + //子引擎节点输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 14); + ruleJson.put("resultJson", outMap.get("childEngineJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("modelJson")) { + //模型节点输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 15); + ruleJson.put("resultJson", outMap.get("modelJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("decisionTablesJson")) { + //决策表输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 16); + ruleJson.put("resultJson", outMap.get("decisionTablesJson")); + resultJson.add(ruleJson); + } + + if (outMap.containsKey("decisionTreeJson")) { + //决策树输出 + JSONObject ruleJson = new JSONObject(); + ruleJson.put("resultType", 17); + ruleJson.put("resultJson", outMap.get("decisionTreeJson")); + resultJson.add(ruleJson); + } + + jsonObject.put("data", resultJson); + String result = JSONObject.toJSONString(jsonObject); + + JSONObject tmpJsonObject = JSONObject.parseObject(result); + tmpJsonObject.remove("input"); + resultSet.setOutput(JSONObject.toJSONString(tmpJsonObject)); + resultSetMapper.insertResultSet(resultSet); + Integer resultId = resultSet.getId(); + // 正常返回结果回调 + decisionCallback(engine.getCallbackUrl(), paramJson, result); + } + } catch (Exception e) { + logger.error("接口请求异常", e); + jsonObject.put("status", "0x0005"); + jsonObject.put("msg", "执行失败"); + jsonObject.put("data", ""); + // 异常回调 + decisionCallback(engine.getCallbackUrl(), paramJson, "执行失败"); + } + } else { + jsonObject.put("status", "0x0004"); + jsonObject.put("msg", "请求引擎不存在或尚未部署运行"); + jsonObject.put("data", ""); + } + } else { + jsonObject.put("status", "0x0001"); + jsonObject.put("msg", "鉴权失败,非法调用"); + jsonObject.put("data", ""); + } + + return jsonObject.toString(); + } + + + /** + * 递归执行节点 + * @param inputParam + * @param engineNode + * @param engineNodeMap + * @param outMap + */ + private EngineNode recursionEngineNode(Map inputParam, EngineNode engineNode, Map engineNodeMap, Map outMap) { + logger.info("请求参数--" + "inputParam:" + JSONObject.toJSONString(inputParam)); + + EngineNode resultNode = null; // 结束时返回节点: 串行流程返回null、并行流程返回聚合节点 + + if(engineNode == null){ + return null; + } + + // 获取节点所需的指标 + getNodeField(engineNode, inputParam); + // 执行节点逻辑 + runNode(engineNode, inputParam, outMap); + + //用于存储执行过的节点 + List executedNodeList = new ArrayList<>(); + if(outMap.containsKey("executedNodes")){ + executedNodeList =(List) outMap.get("executedNodes"); + } + executedNodeList.add(engineNode.getNodeId()+""); + // 更新执行过节点数组 + outMap.put("executedNodes",executedNodeList); + // 递归执行下一个节点 + if (StringUtils.isNotBlank(engineNode.getNextNodes())) { + // 串行节点执行 + EngineNode nextEngineNode = engineNodeMap.get(engineNode.getNextNodes()); + //如果输出的map里面有nextNode,则说明有分组,需要走分组下面的节点 + if (outMap.containsKey("nextNode")) { + nextEngineNode = engineNodeMap.get(outMap.get("nextNode")); + outMap.remove("nextNode"); + } + + if(nextEngineNode!=null&&nextEngineNode.getNodeType() == NodeTypeEnum.AGGREGATION.getValue()){ + // 并行节点后面的分支为多线程执行,执行到聚合节点则结束 + resultNode = nextEngineNode; + } else { + resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap); + } + } + + return resultNode; + } + + + + /** + * 获取节点所需的指标 + * @param engineNode + * @param inputParam + */ + private void getNodeField(EngineNode engineNode, Map inputParam) { + switch (engineNode.getNodeType()) { + case 2: + //规则 + ruleSetNode.getNodeField(engineNode, inputParam); + break; + case 3: + //分组 + groupNode.getNodeField(engineNode, inputParam); + break; + case 9: + //决策选项 + decisionOptionsNode.getNodeField(engineNode, inputParam); + break; + default: + break; + } + } + + /** + * 执行节点逻辑 + * @param engineNode + * @param inputParam + * @param outMap + */ + private void runNode(EngineNode engineNode, Map inputParam, Map outMap) { + switch (engineNode.getNodeType()) { + case 2: + //规则 + ruleSetNode.runNode(engineNode, inputParam, outMap); + break; + case 3: + //分组 + groupNode.runNode(engineNode, inputParam, outMap); + break; + case 7: + //沙盒比例 + sandboxProportionNode.runNode(engineNode, inputParam, outMap); + break; + case 9: + //决策选项 + decisionOptionsNode.runNode(engineNode, inputParam, outMap); + break; + default: + break; + } + } + + /** + * 把引擎节点,以序号为key放入map + * + * @param nodelist 引擎节点 + * @return map + * @see + */ + private Map getEngineNodeListByMap(List nodelist) { + Map map = new HashMap<>(); + for (int i = 0; i < nodelist.size(); i++) { + map.put(nodelist.get(i).getNodeCode(), nodelist.get(i)); + } + return map; + } + + /** + * 决策流执行完回调(包括决策流正常返回结果回调、以及异常回调) + * @param url + * @param paramJson + * @param result + */ + private void decisionCallback(String url, Map paramJson, String result){ + if(StringUtils.isBlank(url)){ + return; + } + Map paramMap = new HashMap<>(); + paramMap.put("paramJson", JSONObject.toJSONString(paramJson)); + paramMap.put("result", result); + // 设置请求头 + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + // 封装请求体 + JSONObject body = JSONObject.parseObject(JSONObject.toJSONString(paramMap)); + // 封装参数和头信息 + HttpEntity httpEntity = new HttpEntity(body, httpHeaders); + ListenableFuture> future = asyncRestTemplate.postForEntity(url, httpEntity, String.class); + if(future != null){ + future.addCallback(new ListenableFutureCallback>() { + @Override + public void onFailure(Throwable throwable) { + logger.info("引擎回调异步调用失败", throwable); + } + + @Override + public void onSuccess(ResponseEntity stringResponseEntity) { + String result = stringResponseEntity.getBody(); + logger.info("引擎回调异步调用成功,result:{}", result); + } + }); + } + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineNodeServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineNodeServiceImpl.java new file mode 100644 index 0000000..9c83b83 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineNodeServiceImpl.java @@ -0,0 +1,45 @@ +package com.baoying.enginex.executor.engine.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.engine.mapper.EngineNodeMapper; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.engine.service.EngineNodeService; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class EngineNodeServiceImpl extends ServiceImpl implements EngineNodeService { + + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + @Autowired + private EngineNodeMapper engineNodeMapper; + + @Override + public List getEngineNodeListByVersionId(Long versionId) { + List engineNodeList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getForeignKey(TableEnum.T_ENGINE_NODE, versionId); + engineNodeList = redisManager.getByForeignKey(key, EngineNode.class); + if(engineNodeList != null){ + // 按node_order升序排序 + engineNodeList = engineNodeList.stream().sorted(Comparator.comparing(EngineNode::getNodeOrder)).collect(Collectors.toList()); + } + } else { + engineNodeList = engineNodeMapper.getEngineNodeListByVersionId(versionId); + } + + return engineNodeList; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineServiceImpl.java new file mode 100644 index 0000000..c895603 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineServiceImpl.java @@ -0,0 +1,37 @@ +package com.baoying.enginex.executor.engine.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.engine.mapper.EngineMapper; +import com.baoying.enginex.executor.engine.model.Engine; +import com.baoying.enginex.executor.engine.service.EngineService; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class EngineServiceImpl extends ServiceImpl implements EngineService { + + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + @Autowired + private EngineMapper engineMapper; + + @Override + public Engine getEngineById(Long id) { + Engine engine = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getPrimaryKey(TableEnum.T_ENGINE, id); + engine = redisManager.getByPrimaryKey(key, Engine.class); + } else { + engine = engineMapper.selectById(id); + } + + return engine; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineVersionServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineVersionServiceImpl.java new file mode 100644 index 0000000..f5397c8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/service/impl/EngineVersionServiceImpl.java @@ -0,0 +1,56 @@ +package com.baoying.enginex.executor.engine.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.engine.mapper.EngineVersionMapper; +import com.baoying.enginex.executor.engine.model.EngineVersion; +import com.baoying.enginex.executor.engine.service.EngineVersionService; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class EngineVersionServiceImpl extends ServiceImpl implements EngineVersionService { + + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + @Autowired + private EngineVersionMapper engineVersionMapper; + + @Override + public EngineVersion getEngineVersionById(Long versionId) { + EngineVersion engineVersion = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getPrimaryKey(TableEnum.T_ENGINE_VERSION, versionId); + engineVersion = redisManager.getByPrimaryKey(key, EngineVersion.class); + } else { + engineVersion = engineVersionMapper.selectById(versionId); + } + return engineVersion; + } + + @Override + public EngineVersion getRunningVersion(Long engineId) { + EngineVersion engineVersion = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getForeignKey(TableEnum.T_ENGINE_VERSION, engineId); + List list = redisManager.getByForeignKey(key, EngineVersion.class); + Optional optional = list.stream().filter(item -> item.getBootState() == 1).findFirst(); + if(optional.isPresent()){ + engineVersion = optional.get(); + } + } else { + engineVersion = engineVersionMapper.getRunningVersion(engineId); + } + + return engineVersion; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/thread/EngineCallable.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/thread/EngineCallable.java new file mode 100644 index 0000000..57b75ba --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/engine/thread/EngineCallable.java @@ -0,0 +1,25 @@ +package com.baoying.enginex.executor.engine.thread; + +import com.baoying.enginex.executor.common.basefactory.CustomBeanFactory; +import com.baoying.enginex.executor.engine.service.EngineApiService; +import org.springframework.context.ApplicationContext; + +import java.util.Map; +import java.util.concurrent.Callable; + +public class EngineCallable implements Callable { + + private Map paramJson; + + public EngineCallable(Map paramJson){ + this.paramJson = paramJson; + } + + @Override + public String call() { + ApplicationContext context = CustomBeanFactory.getContext(); + EngineApiService engineApiService = (EngineApiService) context.getBean("engineApiServiceImpl"); + String result = engineApiService.engineApi(paramJson); + return result; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.java new file mode 100644 index 0000000..96ba08b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.java @@ -0,0 +1,36 @@ +package com.baoying.enginex.executor.knowledge.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.knowledge.model.KnowledgeTree; + +import java.util.List; +import java.util.Map; + + +public interface KnowledgeTreeMapper extends BaseMapper { + + /** + * getTreeList:(根据父节点id和组织id,查询其下的所有子节点) + * @author keke + * @param paramMap 参数集合 + * @return 父节点下的所有子节点 + * */ + public List getTreeList(Map paramMap); + + /** + * batchInsert:(批量新增节点) + * @author keke + * @param k 节点信息集合 + * @return + * */ + public int batchInsert(List k); + + /** + * getTreeList:(根据父节点id和组织id,查询其下的所有子节点,若节点下规则,则过滤掉) + * @author keke + * @param paramMap 参数集合 + * @return 父节点下的所有子节点 + * */ + public List getTreeDataForEngine(Map paramMap); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.xml new file mode 100644 index 0000000..6ce10bb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/KnowledgeTreeMapper.xml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + id, + name, + parent_id, + user_id, + organ_id, + engine_id, + status, + type, + tree_type, + created, + updated + + + + k.id, + k.name, + k.parent_id, + k.user_id, + k.organ_id, + k.engine_id, + k.status, + k.type, + k.tree_type, + k.created, + k.updated + + + + + + + + + insert into t_knowledge_tree (name,parent_id,user_id, + + organ_id, + + + engine_id, + + status,type,tree_type,created,updated) + values(#{name},#{parentId},#{userId}, + + #{organId}, + + + #{engineId}, + + #{status},#{type},#{treeType},now(), now()) + + + + + insert into t_knowledge_tree (name,parent_id,user_id, + + organ_id, + + + engine_id, + + status,type,tree_type,created,updated) + values(#{item.name},#{item.parentId},#{item.userId}, + + #{item.organId}, + + + #{item.engineId}, + + #{item.status},#{item.type},#{item.treeType},now(), now()) + + + + + + update t_knowledge_tree set + + name = #{name}, + + + status = #{status}, + + + type = #{type}, + + + parent_id = #{parentId}, + + updated = now() where id = #{id} + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.java new file mode 100644 index 0000000..8e2921a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.java @@ -0,0 +1,74 @@ +package com.baoying.enginex.executor.knowledge.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.engine.model.NodeKnowledge; +import com.baoying.enginex.executor.knowledge.model.Rule; +import com.baoying.enginex.executor.knowledge.model.RuleField; + +import java.util.List; +import java.util.Map; + + +public interface RuleFieldMapper extends BaseMapper { + + /** + * getFieldList : (根据规则id,,获取规则下的所有字段) + * @author keke + * @param ruleId 规则id + * @return 规则下的所有字段 + * */ + public List getFieldList(Long ruleId); + + /** + * insertField : (批量新增字段记录) + * @author keke + * @param rlist 字段信息集合 + * @return + * */ + public int insertField(List ruleFieldlist); + + /** + * updateField : (批量修改字段记录) + * @author keke + * @param rlist 字段信息集合 + * @return + * */ + public boolean updateField(List rlist); + + /** + * deleteField : (批量删除字段记录) + * @author keke + * @param rlist 字段信息集合 + * @return + * */ + public boolean deleteField(List rlist); + + + /** + * getNodeByList : (根据引擎节点得到所用字段) + * @author wenyu.cao + * @param nodeid 节点编号 + * @return 返回字段list + * */ + public List getNodeByList(NodeKnowledge knowledge); + public List getNodeByListNew(NodeKnowledge knowledge); + /** + * + * 根据规则得到规则引用字段 + * @param nodeKnowledge + * @return + * @see + */ + public List selectNodeByRuleList(NodeKnowledge nodeKnowledge); + public List selectNodeByRuleListNew(NodeKnowledge nodeKnowledge); + /** + * + * 根据规则id得到规则引用字段 + * @param paramMap 规则id集合 + * @return + * @see + */ + public List selectByRuleList(Map paramMap); + public List selectByRuleListNew(Map paramMap); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.xml new file mode 100644 index 0000000..c54c5bb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleFieldMapper.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + r.id , + r.logical, + r.operator, + t.field_cn as field, + r.field_value as fieldValue, + r.rule_id as ruleId, + r.field_id as fieldId, + t.field_en as fieldEn, + t.value_type as valueType, + t.value_scope as valueScope + + + + + + insert into t_rule_field + (logical,operator,field_value,rule_id,field_id) + values + + ( + #{item.logical}, + #{item.operator}, + #{item.fieldValue}, + #{item.ruleId}, + TRIM(#{item.fieldId}) + ) + + + + + + + + update t_rule_field set + + logical = #{item.logical} + + + ,operator = #{item.operator} + + + ,field_value = #{item.fieldValue} + + + ,field_id = TRIM(#{item.fieldId}) + + where id = #{item.id} + + + + + + delete from t_rule_field where id = #{item.id} + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.java new file mode 100644 index 0000000..4dafceb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.java @@ -0,0 +1,90 @@ +package com.baoying.enginex.executor.knowledge.mapper; + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.engine.model.NodeKnowledge; +import com.baoying.enginex.executor.knowledge.model.Rule; + +import java.util.List; +import java.util.Map; + + +public interface RuleMapper extends BaseMapper { + + /** + * getRuleList:(获取规则集合) + * @author keke + * @param paramMap 参数集合 + * @return 规则集合 + * */ + public List getRuleList(Map paramMap); + + /** + * updateRuleStatus:(批量修改规则状态记录) + * @author keke + * @param paramMap 参数集合 + * @return + * */ + public int updateRuleStatus(Map paramMap); + /** + * getNodeByRuleList : (根据引擎节点得到所用规则) + * @author wenyu.cao + * @param nodeid 节点编号 + * @return 返回字段list + * */ + public List getNodeByRuleList(NodeKnowledge knowledge); + + /** + * 根据规则类型查询规则 + * @param list 规则编号 + * @return + * @see + */ + public List selectnodeByInRoleid(List list); + + /** + * 根据父节点id查找,节点下所有规则id的集合 + * @param list 规则编号 + * @return + * @see + */ + public List getRuleIdsByParentId(Map param); + + /** + * getRuleList:(查找引用了某些字段的规则集合) + * @author yuanlinfeng + * @param paramMap 参数集合 + * @return 规则集合 + * */ + public List checkByField(Map paramMap); + + /** + * 效验规则名称唯一性 + * @param param 参数集合 + * @return + * @see + */ + public int countOnlyRuleName(Map param); + + /** + * 效验规则代码唯一性 + * @param param 参数集合 + * @return + * @see + */ + public int countOnlyRuleCode(Map param); + + /** + * getFieldIdsByRuleId:(根据规则id,获取规则所用字段id和Key) + * @author keke + * @param idList 规则id集合 + * @return + * */ + public List getFieldIdsByRuleId(List idList); + + public List getRuleListByType(Map paramMap); + + public List getNodeAddOrSubRulesByNodeId(Long nodeId); + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.xml new file mode 100644 index 0000000..240dda7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/mapper/RuleMapper.xml @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + r.id, + r.name, + r.code, + r.description, + r.priority, + r.parent_id as parentId, + r.user_id as userId, + r.author, + u.nick_name as authorName, + r.organ_id as organId, + r.engine_id as engineId, + r.status, + r.rule_audit as ruleAudit, + r.type, + r.score, + r.last_logical as lastLogical, + r.is_non as isNon, + r.created, + r.updated, + r.rule_type, + r.result_field_en, + r.hit_field_en + + + + r.id, + r.name, + r.code, + r.description, + r.priority, + r.parent_id as parentId, + r.user_id as userId, + r.author, + u.nick_name as authorName, + r.organ_id as organId, + r.engine_id as engineId, + (CASE r. STATUS + WHEN r.id IN ( + SELECT + rule_id + FROM + t_engine_rule_rel td + WHERE + engine_id =#{engineId} + ) THEN + 1 + ELSE + 0 + END) AS status, + r.rule_audit as ruleAudit, + r.type, + r.score, + r.last_logical as lastLogical, + r.is_non as isNon, + r.created, + r.updated, + r.rule_type + + + + r.id, + r.name, + r.code, + r.description, + r.engine_id, + r.priority, + r.parent_id, + r.user_id, + r.author, + r.organ_id, + r.engine_id, + r.status, + r.type, + r.is_non, + r.rule_audit, + r.score, + r.last_logical, + r.created, + r.updated, + r.rule_type + + + + + + + + + insert into t_rule ( + name, + code, + description, + priority, + parent_id, + user_id, + author, + + content, + + + organ_id, + + + engine_id, + + + rule_audit, + + + score, + + + last_logical, + + status,type,is_non,created,updated,rule_type) + values( + #{name}, + #{code}, + #{description}, + #{priority}, + #{parentId}, + #{userId}, + #{author}, + + #{content}, + + + #{organId}, + + + #{engineId}, + + + #{ruleAudit}, + + + #{score}, + + + #{lastLogical}, + + #{status},#{type},#{isNon},now(), now(),#{ruleType} + ) + + + + update t_rule set + + name = #{name}, + + + code = #{code}, + + + content = #{content}, + + + description = #{description}, + + + priority = #{priority}, + + + status = #{status}, + + + type = #{type}, + + + is_non = #{isNon}, + + + rule_type = #{ruleType}, + + + rule_audit = #{ruleAudit}, + + + last_logical = #{lastLogical}, + + score = #{score}, + updated = now() where id = #{id} + + + + update t_rule set status = #{status} where id in + + #{item} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/EngineRuleRel.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/EngineRuleRel.java new file mode 100644 index 0000000..d269eeb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/EngineRuleRel.java @@ -0,0 +1,41 @@ +package com.baoying.enginex.executor.knowledge.model; + +import java.io.Serializable; + + +public class EngineRuleRel implements Serializable{ + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 引擎id + * */ + private Long engineId; + + /** + * 树形目录id + * */ + private Long ruleId; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getEngineId() { + return engineId; + } + + public void setEngineId(Long engineId) { + this.engineId = engineId; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTree.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTree.java new file mode 100644 index 0000000..1c33108 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTree.java @@ -0,0 +1,227 @@ +package com.baoying.enginex.executor.knowledge.model; + +import org.codehaus.jackson.annotate.JsonIgnore; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Date; + + +public class KnowledgeTree implements Serializable{ + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 目录名称 + * */ + private String name; + + /** + * 父节点id + * */ + private Long parentId; + + /** + * 创建人id + * */ + private Long userId; + + /** + * 组织id + * */ + private Long organId; + + + /** + * 引擎id + * */ + private Long engineId; + + /** + * 创建日期 + * */ + private Date created; + + /** + * 目录类型 0 : 系统的目录 1:组织的目录 2: 引擎的目录 + * */ + private Integer type; + + /** + * 树形分类:0:规则树 1:评分卡的树 2:回收站的树 + * */ + private Integer treeType; + + /** + * 状态 0 :停用 ,1 : 启用,-1:删除 + * */ + private Integer status; + + /** + * 修改日期 + * */ + private Date updated; + + /** + * 子类集合 + * */ + private KnowledgeTree[] children; + + /** + * 是否为父类 + * */ + private String isParent = "true"; + + /** + *文件夹图片路径 + * */ + private String icon=""; + + private String isLastNode=""; + + private Integer directoryType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getOrganId() { + return organId; + } + + public void setOrganId(Long organId) { + this.organId = organId; + } + + public Long getEngineId() { + return engineId; + } + + public void setEngineId(Long engineId) { + this.engineId = engineId; + } + + @JsonIgnore + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + @JsonIgnore + public Date getUpdated() { + return updated; + } + + public void setUpdated(Date updated) { + this.updated = updated; + } + + public KnowledgeTree[] getChildren() { + return children; + } + + public void setChildren(KnowledgeTree[] children) { + this.children = children; + } + + public String getIsParent() { + return isParent; + } + + public void setIsParent(String isParent) { + this.isParent = isParent; + } + + public Integer getTreeType() { + return treeType; + } + + public void setTreeType(Integer treeType) { + this.treeType = treeType; + } + + public String getIcon() { + if((int)treeType == 2 || (int)treeType == 3){ + icon = "../resource/images/datamanage/cabage.png"; + isLastNode ="true"; + }else{ + icon = "../resource/images/authority/folder.png"; + } + return icon; + } + + public Integer getDirectoryType() { + return directoryType = type ; + } + + public String getIsLastNode() { + if((int)treeType == 2 || (int)treeType == 3){ + isLastNode ="true"; + } + return isLastNode; + } + + @Override + public String toString() { + return "KnowledgeTree [id=" + id + ", name=" + name + ", parentId=" + + parentId + ", userId=" + userId + ", organId=" + organId + + ", engineId=" + engineId + ", created=" + created + ", type=" + + type + ", treeType=" + treeType + ", status=" + status + + ", updated=" + updated + ", children=" + + Arrays.toString(children) + ", isParent=" + isParent + + ", icon=" + icon + ", isLastNode=" + isLastNode + + ", directoryType=" + directoryType + "]"; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTreeRel.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTreeRel.java new file mode 100644 index 0000000..272dd88 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/KnowledgeTreeRel.java @@ -0,0 +1,48 @@ +package com.baoying.enginex.executor.knowledge.model; + +import java.io.Serializable; + + +public class KnowledgeTreeRel implements Serializable{ + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 引擎id + * */ + private Long engineId; + + /** + * 树形目录id + * */ + private Long treeId; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getEngineId() { + return engineId; + } + + public void setEngineId(Long engineId) { + this.engineId = engineId; + } + + public Long getTreeId() { + return treeId; + } + + public void setTreeId(Long treeId) { + this.treeId = treeId; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/Rule.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/Rule.java new file mode 100644 index 0000000..594772c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/Rule.java @@ -0,0 +1,411 @@ +package com.baoying.enginex.executor.knowledge.model; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + +public class Rule implements Serializable,Cloneable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 名称 + * */ + private String name; + + /** + * 代码 + * */ + private String code; + + /** + * 描述 + * */ + private String description; + + /** + * 优先级 + * */ + private Integer priority; + + /** + * 父节点id + * */ + private Long parentId; + + /** + *修改人id + * */ + private Long userId; + + /** + *创建人id + * */ + private Long author; + + /** + *创建人名称 + * */ + private String authorName; + + /** + * 组织id + * */ + private Long organId; + + /** + * 引擎id + * */ + private Long engineId; + + /** + * 规则类型 0 : 系统的规则 1:组织的规则 2: 引擎的规则 + * */ + private Integer type; + + /** + * 逻辑关系"非" 0:不是非 1:是非 + * */ + private Integer isNon; + + /** + * 状态 0 :停用 ,1 : 启用,-1:删除 + * */ + private Integer status; + /** + * 审批规则 5 :通过 ,2 : 拒绝,3:人工审批 4:简化流程 + */ + public int ruleAudit; + /** + * 规则字段集合 + * */ + private List ruleFieldList; + + /** + * 规则内容集合 + * */ + private List ruleContentList; + + /** + * 创建日期 + * */ + private Date created; + + /** + * 修改日期 + * */ + private Date updated; + + /** + * 规则具体内容 + * */ + public String content; + + /** + * 0硬性拒绝规则1加减分规则 + */ + private Integer ruleType; + + /** + *得分 + */ + private Integer score; + + /** + *逻辑关系符,存储条件区域最后一个逻辑符号,值有')'、'))'、'-1' + */ + private String lastLogical; + + /** + * 引擎名 + * */ + private String engineName; + + /** + * 规则节点名称 + * */ + private String engineNodeName; + + /** + * 规则节点名称 + * */ + private Long engineNodeId; + + /** + * 区分规则集和规则 + * */ + private int showType = 0; + + public String getScoreFieldEn() { + return scoreFieldEn; + } + + public void setScoreFieldEn(String scoreFieldEn) { + this.scoreFieldEn = scoreFieldEn; + } + + private String resultFieldEn;//存放结果的字段en + + private String scoreFieldEn;//存放是否命中的字段 + + public String getResultFieldEn() { + return resultFieldEn; + } + + public void setResultFieldEn(String resultFieldEn) { + this.resultFieldEn = resultFieldEn; + } + + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public int getRuleAudit() { + return ruleAudit; + } + + public void setRuleAudit(int ruleAudit) { + this.ruleAudit = ruleAudit; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getAuthor() { + return author; + } + + public void setAuthor(Long author) { + this.author = author; + } + + public String getAuthorName() { + return authorName; + } + + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + public Long getOrganId() { + return organId; + } + + public void setOrganId(Long organId) { + this.organId = organId; + } + + public Long getEngineId() { + return engineId; + } + + public void setEngineId(Long engineId) { + this.engineId = engineId; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public List getRuleFieldList() { + return ruleFieldList; + } + + public void setRuleFieldList(List ruleFieldList) { + this.ruleFieldList = ruleFieldList; + } + + public List getRuleContentList() { + return ruleContentList; + } + + public void setRuleContentList(List ruleContentList) { + this.ruleContentList = ruleContentList; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getUpdated() { + return updated; + } + + public void setUpdated(Date updated) { + this.updated = updated; + } + + public Integer getIsNon() { + return isNon; + } + + public void setIsNon(Integer isNon) { + this.isNon = isNon; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Integer getRuleType() { + if(ruleAudit == 2) { + ruleType = 0; + }else{ + ruleType = 1; + } + return ruleType; + } + + public void setRuleType(Integer ruleType) { + this.ruleType = ruleType; + } + + public Integer getScore() { + return score; + } + + public void setScore(Integer score) { + this.score = score; + } + + public String getLastLogical() { + return lastLogical; + } + + public void setLastLogical(String lastLogical) { + this.lastLogical = lastLogical; + } + + public String getEngineName() { + return engineName; + } + + public void setEngineName(String engineName) { + this.engineName = engineName; + } + + + + public String getEngineNodeName() { + return engineNodeName; + } + + public void setEngineNodeName(String engineNodeName) { + this.engineNodeName = engineNodeName; + } + + public Long getEngineNodeId() { + return engineNodeId; + } + + public void setEngineNodeId(Long engineNodeId) { + this.engineNodeId = engineNodeId; + } + + public int getShowType() { + return showType; + } + + public void setShowType(int showType) { + this.showType = showType; + } + + @Override + public Object clone() throws CloneNotSupportedException { + // TODO Auto-generated method stub + return super.clone(); + } + + @Override + public String toString() { + return "Rule [id=" + id + ", name=" + name + ", versionCode=" + code + ", description=" + description + ", priority=" + + priority + ", parentId=" + parentId + ", userId=" + userId + ", author=" + author + ", authorName=" + + authorName + ", organId=" + organId + ", engineId=" + engineId + ", type=" + type + ", isNon=" + isNon + + ", status=" + status + ", ruleAudit=" + ruleAudit + ", ruleFieldList=" + ruleFieldList + + ", ruleContentList=" + ruleContentList + ", created=" + created + ", updated=" + updated + + ", content=" + content + ", ruleType=" + ruleType + ", score=" + score + ", lastLogical=" + + lastLogical + ", engineName=" + engineName + ", engineNodeName=" + engineNodeName + ", engineNodeId=" + + engineNodeId + ", showType=" + showType + "]"; + } + + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleContent.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleContent.java new file mode 100644 index 0000000..5b9ebd2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleContent.java @@ -0,0 +1,149 @@ +package com.baoying.enginex.executor.knowledge.model; + + +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; + + +public class RuleContent implements Serializable{ + + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 字段名 + * */ + private String field; + + /** + * 字段值 + * */ + private String fieldValue; + + /** + * 字段id + * */ + private String fieldId; + + /** + * 规则Id + * */ + private Long ruleId; + + + /** + * 关联的字段的英文名称 + * */ + private String fieldEn; + + /** + * 关联的字段的值类型 + * */ + private Integer valueType; + + /** + * 关联的字段的取值范围 + * */ + private String valueScope; + + /** + * 关联的字段的值拆解后的数组 + * */ + private String[] values; + + /** + * 类型:1 常量、2 变量 + */ + private Integer variableType; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getFieldValue() { + return fieldValue; + } + + public void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + + public String getFieldId() { + return fieldId; + } + + public void setFieldId(String fieldId) { + this.fieldId = fieldId; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public Integer getValueType() { + return valueType; + } + + public void setValueType(Integer valueType) { + this.valueType = valueType; + } + + public String getValueScope() { + return valueScope; + } + + public void setValueScope(String valueScope) { + this.valueScope = valueScope; + } + + public String[] getValues() { + if(!StringUtils.isBlank(valueScope)){ + if(valueType == 3){ + values = valueScope.split(","); + }else{ + values = new String[]{valueScope}; + } + }else{ + values = null; + } + return values; + } + + public String getFieldEn() { + return fieldEn; + } + + public void setFieldEn(String fieldEn) { + this.fieldEn = fieldEn; + } + + public Integer getVariableType() { + return variableType; + } + + public void setVariableType(Integer variableType) { + this.variableType = variableType; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleExcel.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleExcel.java new file mode 100644 index 0000000..db444b2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleExcel.java @@ -0,0 +1,74 @@ +package com.baoying.enginex.executor.knowledge.model; + +public class RuleExcel { + + /** + * 规则名称 + * */ + private String name; + + /** + * 规则代码 + * */ + private String code; + + /** + * 规则描述 + * */ + private String description; + + /** + * 优先级 + * */ + private Integer priority; + + /** + * 规则字段内容 + * */ + private String fieldContent; + + /** + * 规则内容 + * */ + private String content; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public Integer getPriority() { + return priority; + } + public void setPriority(Integer priority) { + this.priority = priority; + } + public String getFieldContent() { + return fieldContent; + } + public void setFieldContent(String fieldContent) { + this.fieldContent = fieldContent; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleField.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleField.java new file mode 100644 index 0000000..600a143 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/RuleField.java @@ -0,0 +1,164 @@ +package com.baoying.enginex.executor.knowledge.model; + + +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; + + +public class RuleField implements Serializable{ + + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 逻辑运算符 + * */ + private String logical; + + /** + * 字段内容 + * */ + private String field; + + /** + * 运算符 + * */ + private String operator; + + /** + * 字段值 + * */ + private String fieldValue; + + /** + * 关联的规则的id + * */ + private Long ruleId; + + /** + * 关联的字段的id + * */ + private String fieldId; + + /** + * 关联的字段的英文名称 + * */ + private String fieldEn; + + /** + * 关联的字段的值类型 + * */ + private Integer valueType; + + /** + * 关联的字段的取值范围 + * */ + private String valueScope; + + /** + * 关联的字段的值拆解后的数组 + * */ + private String[] values; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLogical() { + return logical; + } + + public void setLogical(String logical) { + this.logical = logical; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getFieldValue() { + return fieldValue; + } + + public void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + + public Long getRuleId() { + return ruleId; + } + + public void setRuleId(Long ruleId) { + this.ruleId = ruleId; + } + + public String getFieldId() { + return fieldId; + } + + public void setFieldId(String fieldId) { + this.fieldId = fieldId; + } + + public Integer getValueType() { + return valueType; + } + + public void setValueType(Integer valueType) { + this.valueType = valueType; + } + + public String getValueScope() { + return valueScope; + } + + public void setValueScope(String valueScope) { + this.valueScope = valueScope; + } + + public String[] getValues() { + if(!StringUtils.isBlank(valueScope)){ + if(valueType == 3){ + values = valueScope.split(","); + }else{ + values = new String[]{valueScope}; + } + }else{ + values = null; + } + return values; + } + + public String getFieldEn() { + return fieldEn; + } + + public void setFieldEn(String fieldEn) { + this.fieldEn = fieldEn; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScoreCardJson.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScoreCardJson.java new file mode 100644 index 0000000..072e1a1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScoreCardJson.java @@ -0,0 +1,44 @@ +package com.baoying.enginex.executor.knowledge.model; + +public class ScoreCardJson { + + private String ouput; + private Integer index; + private String formula; + private String formula_show; + private String fields; + + public String getOuput() { + return ouput; + } + public void setOuput(String ouput) { + this.ouput = ouput; + } + public Integer getIndex() { + return index; + } + public void setIndex(Integer index) { + this.index = index; + } + public String getFormula() { + return formula; + } + public void setFormula(String formula) { + this.formula = formula; + } + public String getFormula_show() { + return formula_show; + } + public void setFormula_show(String formula_show) { + this.formula_show = formula_show; + } + public String getFields() { + if(fields!=null){ + fields = fields.substring(1,fields.length()-1).trim(); + } + return fields; + } + public void setFields(String fields) { + this.fields = fields; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardExcel.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardExcel.java new file mode 100644 index 0000000..27cca47 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardExcel.java @@ -0,0 +1,71 @@ +package com.baoying.enginex.executor.knowledge.model; + +public class ScorecardExcel { + + /** + * 评分卡名称 + * */ + private String name; + + /** + * 评分卡代码 + * */ + private String code; + + /** + * 评分卡描述 + * */ + private String description; + + /** + * 版本号 + * */ + private String version; + + /** + * 评分卡字段内容 + * */ + private String fieldContent; + + /** + * 评分卡内容 + * */ + private String content; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getFieldContent() { + return fieldContent; + } + public void setFieldContent(String fieldContent) { + this.fieldContent = fieldContent; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardField.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardField.java new file mode 100644 index 0000000..9c331e2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardField.java @@ -0,0 +1,50 @@ +package com.baoying.enginex.executor.knowledge.model; + +import java.io.Serializable; + + +public class ScorecardField implements Serializable{ + + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 关联的评分卡的id + * */ + private Long scorecardId; + + /** + * 关联的字段id + * */ + private Long fieldId; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getScorecardId() { + return scorecardId; + } + + public void setScorecardId(Long scorecardId) { + this.scorecardId = scorecardId; + } + + public Long getFieldId() { + return fieldId; + } + + public void setFieldId(Long fieldId) { + this.fieldId = fieldId; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardRuleContent.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardRuleContent.java new file mode 100644 index 0000000..257f76e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/knowledge/model/ScorecardRuleContent.java @@ -0,0 +1,140 @@ +package com.baoying.enginex.executor.knowledge.model; + + +import com.alibaba.fastjson.JSONObject; + +import java.io.Serializable; + + +public class ScorecardRuleContent implements Serializable{ + + + private static final long serialVersionUID = 1L; + + /** + * 主键 + * */ + private Long id; + + /** + * 评分卡Id + * */ + private Long scorecardId; + + /** + * 字段 + * */ + private String field; + + /** + * 字段英文名称 + * */ + private String fieldEn; + + /** + * 字段值 + * */ + private String fieldValue; + + /** + * 字段id + * */ + private Long fieldId; + + /** + * 关联的字段的值类型 + * */ + private Integer valueType; + + /** + * 关联的字段的取值范围 + * */ + private String valueScope; + + /** + * 关联的字段的值拆解后的数组 + * */ + private String[] values; + + private ScoreCardJson sCardJson; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getScorecardId() { + return scorecardId; + } + + public void setScorecardId(Long scorecardId) { + this.scorecardId = scorecardId; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getFieldValue() { + return fieldValue; + } + + public void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + + public Long getFieldId() { + return fieldId; + } + + public void setFieldId(Long fieldId) { + this.fieldId = fieldId; + } + + public Integer getValueType() { + return valueType; + } + + public void setValueType(Integer valueType) { + this.valueType = valueType; + } + + public String getValueScope() { + return valueScope; + } + + public void setValueScope(String valueScope) { + this.valueScope = valueScope; + } + + public String[] getValues() { + if(valueType == 3){ + values = valueScope.split(","); + }else{ + values = new String[]{valueScope}; + } + return values; + } + + public ScoreCardJson getsCardJson() { + sCardJson = JSONObject.parseObject(fieldValue, ScoreCardJson.class); + return sCardJson; + } + + public String getFieldEn() { + return fieldEn; + } + + public void setFieldEn(String fieldEn) { + this.fieldEn = fieldEn; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/EmailService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/EmailService.java new file mode 100644 index 0000000..a26e901 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/EmailService.java @@ -0,0 +1,21 @@ +package com.baoying.enginex.executor.message.email.service; + +public interface EmailService { + /** + * 发送邮件方法 + * @param to 收件人邮件地址 + * @param subject 主题 + * @param content 邮件内容 + */ + public void sendHtmlMail(String to, String subject, String content); + + /** + * 发送模板邮件方法 + * @param to 收件人邮件地址 + * @param subject 主题 + * @param templateName 模板名称 + * @param context 追加参数集合 + */ +// public void sendTemplateMail(String to, String subject, String templateName, Context context); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/impl/EmailServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/impl/EmailServiceImpl.java new file mode 100644 index 0000000..06f3ba1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/message/email/service/impl/EmailServiceImpl.java @@ -0,0 +1,49 @@ +package com.baoying.enginex.executor.message.email.service.impl; + +import com.baoying.enginex.executor.message.email.service.EmailService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.mail.internet.MimeMessage; + +@Service("emailService") +@Slf4j +public class EmailServiceImpl implements EmailService { + + @Resource + private JavaMailSender mailSender; + + @Value("${spring.mail.username}") + private String fromAddr; + + @Override + public void sendHtmlMail(String to, String subject, String content) { + log.info("开始发送邮件,to:{}, subject:{}, content:{}", to, subject, content); + MimeMessage message = mailSender.createMimeMessage(); + try { + //true表示需要创建一个multipart message + MimeMessageHelper helper = new MimeMessageHelper(message,true, "utf-8"); + helper.setFrom(fromAddr); + String[] split = to.split(","); + helper.setTo(split); + helper.setSubject(subject); + helper.setText(content,true); + mailSender.send(message); + log.info("邮件发送成功"); + }catch (Exception e){ + log.error("邮件发送失败",e); + } + } + + public String getFromAddr() { + return fromAddr; + } + + public void setFromAddr(String fromAddr) { + this.fromAddr = fromAddr; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/CommonService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/CommonService.java new file mode 100644 index 0000000..086d78c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/CommonService.java @@ -0,0 +1,26 @@ +package com.baoying.enginex.executor.node.service; + +import com.baoying.enginex.executor.datamanage.model.Field; + +import java.util.List; +import java.util.Map; + +public interface CommonService { + + boolean getFieldByIds(List ids, Map inputParam); + + /** + * 获取引擎节点所需的指标 + * @param fields + * @param engineNode + * @param inputParam + * @return + */ + boolean getEngineField(List fields, Map inputParam); + + /** + * 获取衍生指标 + * @param inputParam + */ + void getFieldResult (Map inputParam); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/EngineNodeService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/EngineNodeService.java new file mode 100644 index 0000000..4dba3b1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/EngineNodeService.java @@ -0,0 +1,26 @@ +package com.baoying.enginex.executor.node.service; + +import com.baoying.enginex.executor.engine.model.EngineNode; + +import java.util.Map; + +/** + * 引擎节点执行 + */ +public interface EngineNodeService { + + /** + * 获取节点所需的指标 + * @param engineNode + * @param inputParam + */ + void getNodeField(EngineNode engineNode, Map inputParam); + + /** + * 执行节点逻辑 + * @param engineNode + * @param inputParam + * @param outMap + */ + void runNode(EngineNode engineNode, Map inputParam, Map outMap); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/CommonServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..083a9e7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/CommonServiceImpl.java @@ -0,0 +1,789 @@ +package com.baoying.enginex.executor.node.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.common.session.SessionData; +import com.baoying.enginex.executor.common.session.SessionManager; +import com.baoying.enginex.executor.datamanage.mapper.SimpleMapper; +import com.baoying.enginex.executor.datamanage.model.Field; +import com.baoying.enginex.executor.datamanage.model.FieldCond; +import com.baoying.enginex.executor.datamanage.service.FieldService; +import com.baoying.enginex.executor.engine.model.ComplexRule; +import com.baoying.enginex.executor.node.service.CommonService; +import com.baoying.enginex.executor.util.DictVariableUtils; +import com.baoying.enginex.executor.util.ExecuteUtils; +import com.baoying.enginex.executor.util.StringUtil; +import com.baoying.enginex.executor.util.https.HttpClient; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.math.Groovy; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.InputStream; +import java.math.BigDecimal; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Service +public class CommonServiceImpl implements CommonService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Resource + private SimpleMapper simpleMapper; + + @Autowired + public FieldService fieldService; + + @Autowired + private Groovy groovy; + + @Override + public boolean getFieldByIds(List ids, Map inputParam) { + if (ids == null || ids.size() == 0) { + return true; + } + SessionData sessionData = SessionManager.getSession(); +// Long organId = sessionData.getOrganId(); + Long organId = 46L; + List fieldList = fieldService.findFieldByIdsbyorganId(organId, ids); + List list = new ArrayList<>(); + ids = new ArrayList<>(); + for (int i = 0; i < fieldList.size(); i++) { + if (fieldList.get(i).getIsDerivative() == 1) { + ids.addAll(StringUtil.toLongList(fieldList.get(i).getOrigFieldId())); + } else + list.add(fieldList.get(i)); + } + if (ids.size() > 0) { + List lists = fieldService.findFieldByIdsbyorganId(organId, ids); + list.addAll(lists); + } + + List fields = new ArrayList<>(); + fields.addAll(list); + + this.getEngineField(fields, inputParam); + + for (Field field : fieldList) { + if (field.getIsDerivative() == 1) { + inputParam.put(field.getFieldEn(), ""); + this.getFieldResult(inputParam); + } + } + return false; + } + + /** + * 调用http请求得到引擎节点所需要的字段 + * + * @return 引擎所需字段 + * @see + */ + @Override + public boolean getEngineField(List fields, Map inputParam) { + logger.info("start getEngineField, fields:{},inputParam:{}", JSONObject.toJSONString(fields), JSONObject.toJSONString(inputParam)); + + int type = 1; + + if (null != fields && fields.size() < 1) { + return true; + } + + // 循环规则特殊处理 + List tempFields = new ArrayList<>(fields); + for (Field field : fields) { + if (field.getFieldEn().contains("[") && field.getFieldEn().contains("]")) { + String fieldEn = field.getFieldEn().substring(0, field.getFieldEn().indexOf("[")); + Field nField = new Field(); + nField.setFieldEn(fieldEn); + tempFields.add(nField); + tempFields.remove(field); + } + } + fields = new ArrayList<>(tempFields); + + // 需要调用指标系统的字段集合 + List remainFields = new ArrayList<>(fields); + + for (Field field : fields) { + if (inputParam.containsKey(field.getFieldEn())) { + // 优先从入参中获取指标 + remainFields.remove(field); + } + } + + if (null != remainFields && remainFields.size() < 1) { + return true; + } + + Properties p = new Properties(); + try { + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("datacenter.properties"); + p.load(inputStream); + } catch (Exception e1) { + e1.printStackTrace(); + logger.error("remainFields:{},请求异常", JSONObject.toJSONString(remainFields), e1); + } + String act = p.getProperty("act"); + //随机数 + String nonce = UUID.randomUUID().toString(); + String token = p.getProperty("token"); + Date date = new Date(); + long ts = date.getTime(); +// String sign = MD5.GetMD5Code(act.trim() + "," + date.getTime() + "," + nonce.trim() + "," + pid.trim() + "," + uid.trim() + "," + token.trim()); + HttpClient httpClient = new HttpClient(); + String url = p.getProperty("url") + "?token=" + token.trim() + "&ts=" + ts + "&act=" + act.trim() + "&nonce=" + nonce.trim(); + Map pam = new HashMap<>(); + pam.put("fields", getListFieldByString(remainFields)); +// pam.put("sign", sign); + pam.put("type", String.valueOf(type)); + try { + String result = httpClient.post(url, pam); + JSONObject jsonObject = JSONObject.parseObject(result); + //返回成功状态下解析返回的字段 + if (jsonObject.getString("status").equals("0x0000")) { + JSONArray array = jsonObject.getJSONArray("data"); + + if (type == 1) { //普通规则 + for (int i = 0; i < array.size(); i++) { + JSONObject object = array.getJSONObject(i); + for (Map.Entry entry : object.entrySet()) { + inputParam.put(entry.getKey(), entry.getValue()); + } + } + return true; + } else { //复杂规则 + List list = new ArrayList(); + return true; + } + } else { + //返回状态不成功,直接返回null + return false; + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("remainFields:{},请求异常", JSONObject.toJSONString(remainFields), e); + } + return false; + } + + /** + * 把list对象转换为以,号隔开的string字符串 + * + * @param list + * @return + * @see + */ + private String getListFieldByString(List list) { + String fields = ""; + for (int i = 0; i < list.size(); i++) { + fields = fields + list.get(i).getFieldEn() + ","; + } + return fields; + + } + + /** + * 根据输入字段参数返回衍生字段的结果 + * 输入:引擎id及参数列表(原生字段英文字段名和值、待计算的衍生字段只有英文字段名) + * 输出:待计算衍生字段的计算结果值 + */ + @Override + public void getFieldResult(Map paramMap) { + //参数传递中间临时Map + Map paramMap2 = new HashMap(); + for (Map.Entry entry : paramMap.entrySet()) { + if (null != entry.getValue()) + paramMap2.put(entry.getKey(), entry.getValue()); + else + paramMap2.put(entry.getKey(), ""); + } + + SessionData sessionData = SessionManager.getSession(); + Long organId = sessionData.getOrganId(); + paramMap2.put("organId", organId); + + for (Map.Entry entry : paramMap.entrySet()) { + String fieldEn = entry.getKey(); + String fieldValue = ""; + if (null != entry.getValue()) + fieldValue = String.valueOf(entry.getValue()); + + if (null == fieldValue || fieldValue.equals("")) { + + paramMap2.put("fieldEn", fieldEn); + Field field = fieldService.findByFieldEnbyorganId(organId, fieldEn); + + if (field != null) { + if (field.getIsDerivative() == 1) { + String result = ""; + paramMap2.put("fieldCn", field.getFieldCn()); + result = getExpAll(field.getFieldCn(), "", paramMap); + //单独返回数值结果会带上(),做处理去掉 + result = result.replace("(", ""); + result = result.replace(")", ""); + paramMap.put(fieldEn, result); + } + } + } + } + } + + /** + * 递归生成衍生字段嵌套的逻辑表达式或公式计算的结果 + */ + private String getExpAll(String fieldCn, String exp, Map param) { + + String result = ""; + Map param2 = new HashMap(); + for (Map.Entry entry : param.entrySet()) { + if (null != entry.getValue()) + param2.put(entry.getKey(), entry.getValue()); + else + param2.put(entry.getKey(), ""); + } + + SessionData sessionData = SessionManager.getSession(); + Long organId = sessionData.getOrganId(); + + Map paramMap = new HashMap(); + + paramMap.put("organId", organId); + paramMap.put("engineId", param.get("engineId")); + paramMap.put("fieldCn", fieldCn); + + //放大从组织通用字段拷贝生成的引擎字段里字段的获取范围,优先取引擎,没有再取组织里的(因为中文名在组织通用字段和引擎字段里有重复) + String arrFormula = ""; + Field engField = fieldService.findByFieldCnbyorganId(organId, fieldCn); + String engFormula = engField.getFormula(); + if (!engFormula.equals("") && engFormula != null) { + arrFormula = engFormula; + } + + if (arrFormula.equals("") || arrFormula == null) { //衍生字段只有条件区域 + + List fieldCondList = new ArrayList(); + List engfieldCondList = fieldService.findByFieldCnbyorganId(organId, fieldCn).getFieldCondList(); + if (engfieldCondList.size() > 0) { + fieldCondList = engfieldCondList; + } + + if (fieldCondList.size() > 0) {//需要进行条件区域逻辑运算 + for (FieldCond fieldCond : fieldCondList) {//这里的fieldCond是字段设置的逻辑运算符 + String condValue = fieldCond.getConditionValue(); + List condList = new ArrayList<>(); + condList = JSONObject.parseArray(fieldCond.getContent()); + exp = ""; + for (int j = 0; j < condList.size(); j++) { + JSONObject cond = ((JSONArray) condList).getJSONObject(j); + //[{\"fieldId\":\"31\",\"operator\":\">\",\"fieldValue\":\"1000\",\"logical\":\"&&\"},{\"fieldId\":\"31\",\"operator\":\">=\",\"fieldValue\":\"7000\"}] + paramMap.put("id", cond.getString("fieldId")); + + Field condfield = fieldService.queryById(Long.valueOf(cond.getString("fieldId"))); + if (condfield == null) { + condfield = fieldService.findByFieldCnbyorganId(organId, fieldCn); + } + + String condFieldEn = condfield.getFieldEn();//yqshouru 月收入 + String condFieldCn = condfield.getFieldCn(); + Integer condValueType = condfield.getValueType(); //1数值型 + String condFieldValue = cond.getString("fieldValue"); //1000 + String operator = cond.getString("operator"); //>大于号 + String fieldValue = param2.get(condFieldEn).toString(); //取输入变量的值 + + String logical = ""; + + if (condfield.getIsDerivative() == 0) { + if (cond.containsKey("logical")) + logical = " " + cond.getString("logical") + " "; + if (operator.equals("in")) { + //exp += "(indexOf(#{"+fieldValue+"},'"+condFieldValue+"')>0"+logical; + exp += "(indexOf('" + condFieldValue + "','" + fieldValue + "',0) >= 0)" + logical; + } else if (operator.equals("not in")) { + //exp += "(indexOf(#{"+fieldValue+"},'"+condFieldValue+"')=0"+logical; + exp += "(indexOf('" + condFieldValue + "','" + fieldValue + "',0) = -1)" + logical; + } else if (operator.equals("like")) { //交换位置 (indexOf('abc','c',0) >= 0) + exp += "(indexOf('" + fieldValue + "','" + condFieldValue + "',0) >= 0)" + logical; + } else if (operator.equals("not like")) { //(indexOf('abc','x',0) = -1) + exp += "(indexOf('" + fieldValue + "','" + condFieldValue + "',0) = -1)" + logical; + } else { + if (condValueType == 1 || condValueType == 4) { + exp += " (" + fieldValue + "" + operator + "" + condFieldValue + ") " + logical; + } else + exp += " ('" + fieldValue + "'" + operator + "'" + condFieldValue + "') " + logical; + } + } else {//衍生字段 + if (cond.containsKey("logical")) + logical = " " + cond.getString("logical") + " "; + if (operator.equals("in")) { + //exp += "(indexOf(#{"+getExpAll(condFieldCn,"",param2)+"},'"+condFieldValue+"')>0"+logical; + //(indexOf('abc','c',0) >= 0) && (indexOf('abc','x',0) = -1) + exp += "(indexOf('" + condFieldValue + "','" + getExpAll(condFieldCn, "", param2) + "',0) >= 0)" + logical; + } else if (operator.equals("not in")) { + exp += "(indexOf('" + condFieldValue + "','" + getExpAll(condFieldCn, "", param2) + "',0) = -1)" + logical; + } else if (operator.equals("like")) { //交换位置 (indexOf('abc','c',0) >= 0) + exp += "(indexOf('" + getExpAll(condFieldCn, "", param2) + "','" + condFieldValue + "',0) >= 0)" + logical; + } else if (operator.equals("not like")) { //(indexOf('abc','x',0) = -1) + exp += "(indexOf('" + getExpAll(condFieldCn, "", param2) + "','" + condFieldValue + "',0) = -1)" + logical; + } else { + if (condValueType == 1 || condValueType == 4) { + exp += " (" + getExpAll(condFieldCn, "", param2) + "" + operator + "" + condFieldValue + ") " + logical; + } else + exp += " ('" + getExpAll(condFieldCn, "", param2) + "'" + operator + "'" + condFieldValue + "') " + logical; + } + } + } + Evaluator evaluator = new Evaluator(); + String b = ""; + try { + System.out.println("========字段区域设置的的表达式输出:" + exp); + b = evaluator.evaluate(exp); + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + if (b.equals("1.0")) { + result = condValue; + break; //遇到一个满足条件的则跳出循环 + } + } + } + } else { //衍生字段只有公式 + List formulaList = new ArrayList<>(); + formulaList = JSONObject.parseArray(arrFormula); + for (int i = 0; i < formulaList.size(); i++) { + JSONObject formulaJson = ((JSONArray) formulaList).getJSONObject(i); + + String formula = (String) formulaJson.get("formula"); + formula = formula.replace(">", ">"); //3>=6 && 3< 12 + formula = formula.replace("<", "<"); + Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()()-]+@"); + Matcher matcher = pattern.matcher(formula); + String subexp = formula; + int j = 0; + exp = ""; + // 存放groovy脚本入参 + Map data = new HashMap<>(); + //System.out.println("待替换的字段串:"+formula); + while (matcher.find()) { + String fieldCN = matcher.group(0).replace("@", ""); + Map fieldMap = new HashMap(); + paramMap.put("organId", organId); + fieldMap.put("engineId", paramMap.get("engineId")); + fieldMap.put("fieldCn", fieldCN); + fieldMap.put("organId", organId); + Field subField = fieldService.findByFieldCnbyorganId(organId, fieldCN); + + //构造字段条件区间计算输入参数 + Map paramCond = new HashMap(); + paramCond.put("fieldValue", param2.get(subField.getFieldEn())); + paramCond.put("fieldEn", subField.getFieldEn()); + paramCond.put("fieldValueType", subField.getValueType()); + + //字段条件转换 + JSONArray fieldCond = new JSONArray(); + if (formulaJson.get("farr") != null && !"".equals(formulaJson.get("farr"))) { + JSONArray jsonArr = (JSONArray) formulaJson.get("farr"); + for (Iterator iterator = jsonArr.iterator(); iterator.hasNext(); ) { + JSONObject job = (JSONObject) iterator.next(); + if (job.get("fieldCN").equals(fieldCN) && !job.get("fieldCond").equals("")) { + fieldCond = (JSONArray) job.get("fieldCond"); + break; + } + } + } + + paramCond.put("fieldCond", fieldCond); + String v = ""; + if (fieldCond.size() > 0) { + v = calcFieldCond(paramCond); + } else { + v = "" + param2.get(subField.getFieldEn()); + } + data.put(subField.getFieldEn(), param2.get(subField.getFieldEn())); + + if (subField.getIsDerivative() == 0) { +// if(subexp.indexOf("substring")>=0||subexp.indexOf("equals")>=0){ //substring(@字段A@,3,6) +// exp += subexp.substring(j, matcher.end()).replace("@"+fieldCN+"@", "'"+v+"'"); +// }else{ +// exp += subexp.substring(j, matcher.end()).replace("@"+fieldCN+"@", v); +// } + + if (subexp.contains("def main")) { + // groovy脚本替换为动态参数 + v = "_['" + subField.getFieldEn() + "']"; + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); + } else { + if (subField.getValueType() == 1 || subField.getValueType() == 4) { + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); + } else { + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", "'" + v + "'"); + } + } + + } else { + + v = getExpAll(fieldCN, exp, param2); + // 存衍生字段 + if (subField.getValueType() == 1 || subField.getValueType() == 4) { + data.put(subField.getFieldEn(), Integer.valueOf(v)); + } else { + data.put(subField.getFieldEn(), v); + } + + if (subexp.contains("def main")) { + // groovy脚本替换为动态参数 + v = "_['" + subField.getFieldEn() + "']"; + } + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); + } + j = matcher.end(); + } + exp += formula.substring(j, formula.length()); + Evaluator evaluator = new Evaluator(); + String b = ""; + try { +// System.out.println("========字段公式编辑设置的表达式输出:" + exp); + + if (exp.contains("def main")) { + // 执行groovy脚本 + b = groovy.execute(exp, data); +// b = String.valueOf(groovy.execute(exp, data)); + } else { + b = evaluator.evaluate(exp); + } + + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + + // + if (engField.getValueType().intValue() == 1 || engField.getValueType().intValue() == 2) { //数值型或者字符型字段的衍生表达式b的结果返回值0.0代表计算结果 + if (!b.equals("")) { + result = b; + if (StringUtil.isValidStr(result) && result.startsWith("'") && result.endsWith("'")) { + result = result.substring(1, result.length() - 1); + } + } + } else if (engField.getValueType().intValue() == 3) { //枚举型字段的衍生表达式b的结果返回值0.0代表false即逻辑表达式无效 + if (!b.equals("1.0") && !b.equals("0.0") && !b.equals("")) { + result = b; + if (StringUtil.isValidStr(result) && result.startsWith("'") && result.endsWith("'")) { + result = result.substring(1, result.length() - 1); + } + } + if (b.equals("1.0")) { + result = (String) formulaJson.get("fvalue"); + //result = result.substring(result.indexOf(":")+1,result.length());// a:2 取2返回 + if (isNumeric(result)) { + result = "(" + result + ")"; + } else { + result = "'" + result + "'"; + } + break; //遇到一个满足条件的则跳出循环 + } + } + + } + } + + return result; + + } + + /** + * 公式编辑里设置字段条件区域转换的通用方法 + * 输入:待转换字段的输入参数、值类型 + * 输出:输入参数所在区间对应的结果值 + */ + private String calcFieldCond(Map paramMap) { + + String fieldValue = (String) paramMap.get("fieldValue"); + Integer fieldValueType = (Integer) paramMap.get("fieldValueType"); + + String result = ""; + //[{"fieldCN":"引擎字段1-1","fieldCond":[{"inputOne":"a","inputThree":"33"},{"inputOne":"b","inputThree":"490"},{"inputOne":"c","inputThree":"50"}]}] + //[{"fieldCN":"引擎字段1-1","fieldCond":[{"inputOne":"(3,19]","inputThree":"1"},{"inputOne":"(19,200]","inputThree":"2"}]},{"fieldCN":"通用字段2贷前","fieldCond":""}] + JSONArray jsonArr = (JSONArray) paramMap.get("fieldCond"); + for (Iterator iterator = jsonArr.iterator(); iterator.hasNext(); ) { + JSONObject job = (JSONObject) iterator.next(); + String inputOne = (String) job.get("inputOne"); + String inputThree = (String) job.get("inputThree"); + + if (fieldValueType == 3) { + if (fieldValue.equals(inputOne)) { + result = inputThree; + break; + } + } else if (fieldValueType == 1 || fieldValueType == 4) { + //(40,50] + Double lv = Double.parseDouble(inputOne.substring(1, inputOne.indexOf(","))); + Double rv = Double.parseDouble(inputOne.substring(inputOne.indexOf(",") + 1, inputOne.length() - 1)); + + String exp = ""; + if (inputOne.startsWith("(") && !lv.equals("")) { + exp = fieldValue + ">" + lv; + } + if (inputOne.startsWith("[") && !lv.equals("")) { + exp = fieldValue + ">=" + lv; + } + if (inputOne.endsWith(")") && !rv.equals("")) { + if (exp.equals("")) + exp += fieldValue + "<" + rv; + else + exp += "&&" + fieldValue + "<" + rv; + } + if (inputOne.endsWith("]") && !rv.equals("")) { + if (exp.equals("")) + exp += fieldValue + "<=" + rv; + else + exp += "&&" + fieldValue + "<=" + rv; + } + + Evaluator evaluator = new Evaluator(); + String b = ""; + try { + b = evaluator.evaluate(exp); + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + if (b.equals("1.0")) { + result = inputThree; + break; //遇到一个满足条件的则跳出循环 + } + } + } + return result; + } + + /** + * 判断表达式的运算结果是否数值型的公共方法 + */ + public boolean isNumeric(String str) { + Pattern pattern = Pattern.compile("^(-|\\+)?\\d+(\\.\\d+)?$"); + Matcher isNum = pattern.matcher(str); + if (!isNum.matches()) { + return false; + } + return true; + } + + private Map getSqlFieldParam(Field field, Map inputParam, Map parameterMap) { + String sqlStr = field.getSqlStatement(); + // 添加动态参数 + //处理in方法中的遍历 + Pattern sqlInPattern = Pattern.compile("[\\s]*in[\\s]*\\([\\s]*#\\{([a-zA-Z0-9_\u4e00-\u9fa5()()-]+)\\}[\\s]*\\)"); + Matcher sqlInMatcher = sqlInPattern.matcher(sqlStr); + while (sqlInMatcher.find()) { + String replaceOld = sqlInMatcher.group(0); + String sqlField = sqlInMatcher.group(1); + String sqlVariable = field.getSqlVariable(); + String fieldEn = sqlField.split("\\.")[0]; + String convertStr = ""; + Object value = null; + if (StringUtils.isNotBlank(sqlVariable)) { + JSONArray sqlVariableArr = JSONArray.parseArray(sqlVariable); + for (int i = 0; i < sqlVariableArr.size(); i++) { + JSONObject sqlVariableObj = sqlVariableArr.getJSONObject(i); + if (sqlField.equals(sqlVariableObj.getString("key"))) { + value = sqlVariableObj.getJSONArray("value"); + } + } + } + if (value == null) { + if (!inputParam.containsKey(fieldEn)) { + //不存再需要重新获取 + List fieldEns = new ArrayList<>(); + fieldEns.add(fieldEn); + //查询未入参的en是否是指标库中的指标,如果是则u需要继续查找 + List fieldList = fieldService.selectFieldListByEns(fieldEns); + if (fieldList != null && !fieldList.isEmpty()) { + //查询引用到的指标 + getEngineField(fieldList, inputParam); + } + + } +// value = inputParam.get(sqlField); + value = ExecuteUtils.getObjFromMap(inputParam, sqlField); + } + if (StringUtils.isBlank(convertStr) && value != null) { + if (value instanceof String) { + convertStr = value.toString(); + } else if (value instanceof List) { + List collection = (List) value; + int size = collection.size(); + + for (int i = 0; i < size; i++) { + convertStr += ("'" + String.valueOf(collection.get(i)) + "'"); + if (i < size - 1) { + convertStr += ","; + } + } + } + } + sqlStr = sqlStr.replace(replaceOld, " in (" + convertStr + ") "); + } + Pattern pattern = Pattern.compile("#\\{[a-zA-Z0-9_\u4e00-\u9fa5()()-]+\\}"); + Matcher matcher = pattern.matcher(sqlStr); + while (matcher.find()) { + String sqlField = matcher.group(0).replace("#{", "").replace("}", ""); + String fieldEn = sqlField.split("\\.")[0]; + // sql动态参数从页面配置获取 + String sqlVariable = field.getSqlVariable(); + if (StringUtils.isNotBlank(sqlVariable)) { + JSONArray sqlVariableArr = JSONArray.parseArray(sqlVariable); + for (int i = 0; i < sqlVariableArr.size(); i++) { + JSONObject sqlVariableObj = sqlVariableArr.getJSONObject(i); + if (sqlField.equals(sqlVariableObj.getString("key"))) { + parameterMap.put(sqlField, sqlVariableObj.get("value")); + } + } + } + + // sql动态参数从变量池获取 + if (!parameterMap.containsKey(fieldEn)) { + if (!inputParam.containsKey(fieldEn)) { + //不存再需要重新获取 + List fieldEns = new ArrayList<>(); + fieldEns.add(fieldEn); + //查询未入参的en是否是指标库中的指标,如果是则u需要继续查找 + List fieldList = fieldService.selectFieldListByEns(fieldEns); + if (fieldList != null && !fieldList.isEmpty()) { + //查询引用到的指标 + getEngineField(fieldList, inputParam); + } + + } + parameterMap.put(sqlField, ExecuteUtils.getObjFromMap(inputParam, sqlField)); + } + } + Pattern pattern$ = Pattern.compile("\\$\\{[a-zA-Z0-9_\u4e00-\u9fa5()()-]+\\}"); + Matcher matcher$ = pattern$.matcher(sqlStr); + while (matcher$.find()) { + String sqlField = matcher$.group(0).replace("${", "").replace("}", ""); + String fieldEn = sqlField.split("\\.")[0]; + // sql绑定参数从页面配置获取 + String sqlVariable = field.getSqlVariable(); + String dictVariable = field.getDictVariable(); + String replaceStr = ""; + if (StringUtils.isNotBlank(sqlVariable)) { + JSONArray sqlVariableArr = JSONArray.parseArray(sqlVariable); + for (int i = 0; i < sqlVariableArr.size(); i++) { + JSONObject sqlVariableObj = sqlVariableArr.getJSONObject(i); + + if (!sqlField.equals(sqlVariableObj.getString("key"))) { + continue; + } + if (inputParam.containsKey(fieldEn)) { + replaceStr = ExecuteUtils.getObjFromMap(inputParam, sqlField).toString(); + } else if (sqlVariableObj.get("value") != null) { + replaceStr = String.valueOf(sqlVariableObj.get("value")); + } + if (StringUtils.isNotBlank(replaceStr)) { + break; + } + + } + } + if (StringUtils.isNotBlank(dictVariable)){ + JSONArray jsonArray = JSONArray.parseArray(dictVariable); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (!sqlField.equals(jsonObject.getString("key"))) { + continue; + } +// if (inputParam.containsKey(fieldEn)) { +// replaceStr = ExecuteUtils.getObjFromMap(inputParam, sqlField).toString(); +// } else +// if (jsonObject.get("value") != null) { +// switch (jsonObject.getString("type")){ +// case "date": +// try { +// replaceStr = DateUtil.format(new Date(),jsonObject.getString("value")); +// }catch (Exception e){ +// e.printStackTrace(); +// replaceStr = DateUtil.format(new Date(),"yyyyMMdd"); +// } +// break; +// default: +// replaceStr = String.valueOf(jsonObject.get("value")); +// } +// } + replaceStr = DictVariableUtils.getValueFromJsonObject(jsonObject).toString(); + if (StringUtils.isNotBlank(replaceStr)) { + break; + } + } + } + if (StringUtils.isNotBlank(replaceStr)) { + //已经取出则直接跳过 + sqlStr = sqlStr.replace("${" + sqlField + "}", replaceStr); + continue; + } + // sql动态参数从变量池获取 + if (!parameterMap.containsKey(fieldEn)) { + if (!inputParam.containsKey(fieldEn)) { + //不存再需要重新获取 + //查询未入参的en是否是指标库中的指标,如果是则u需要继续查找 + List fieldList = fieldService.selectFieldListByEns(Arrays.asList(fieldEn)); + if (fieldList != null && !fieldList.isEmpty()) { + //查询引用到的指标 + getEngineField(fieldList, inputParam); + } + } + replaceStr = ExecuteUtils.getObjFromMap(inputParam, sqlField).toString(); + } + if (StringUtils.isNotBlank(replaceStr)) { + sqlStr = sqlStr.replace("${" + sqlField + "}", replaceStr); + break; + } + } + parameterMap.put("sqlStr", sqlStr); + return parameterMap; + } + + private Object handlerSqlFieldResult(Field field, Map parameterMap) { + List> result = simpleMapper.customSelect(parameterMap); + Object resultValue = null; + if (result == null || result.size() == 0) { + resultValue = null; + } else { + //json类型的数据 + if (field.getValueType() == 6) { + String json = field.getJsonValue(); + //示例数据为数组 + if (StringUtils.isNotBlank(json) && json.startsWith("[") && json.endsWith("]")) { + resultValue = result; + } else { + resultValue = result.get(0); + } + } else if (result.size() == 1) {// 基本指标只能是一个值。所以只能取sql查出来的第一个值。否则抛出异常 + LinkedHashMap resultMap = result.get(0); + if (resultMap.size() == 1) { + for (Map.Entry entry : resultMap.entrySet()) { + Object value = entry.getValue(); + + // 防止double表示为科学计数法 + if (value instanceof Double) { + value = BigDecimal.valueOf((Double) value); + } + resultValue = value.toString(); + } + } else { + throw new RuntimeException("sql库指标计算异常,sql字段个数超出预期。查询结果resultMap:" + resultMap.toString()); + } + } else { + throw new RuntimeException("sql库指标计算异常,sql结果个数超出预期。查询结果result:" + result.toString()); + } + } + return resultValue; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/DecisionOptionsNode.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/DecisionOptionsNode.java new file mode 100644 index 0000000..6958bd6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/DecisionOptionsNode.java @@ -0,0 +1,144 @@ +package com.baoying.enginex.executor.node.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.node.service.CommonService; +import com.baoying.enginex.executor.node.service.EngineNodeService; +import com.baoying.enginex.executor.util.JevalUtil; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 决策选项节点 + */ +@Service +public class DecisionOptionsNode implements EngineNodeService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private CommonService commonService; + + @Override + public void getNodeField(EngineNode engineNode, Map inputParam) { + logger.info("start【获取决策选项节点指标】DecisionOptionsNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam)); + JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript()); + JSONArray array = jsonObject.getJSONArray("input"); + List ids = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + JSONObject input = array.getJSONObject(i); + Object fieldId = input.get("field_id"); + if(fieldId != null && !"".equals(fieldId.toString())){ + ids.add(Long.valueOf(fieldId.toString())); + } + } + commonService.getFieldByIds(ids, inputParam); + } + + @Override + public void runNode(EngineNode engineNode, Map inputParam, Map outMap) { + //监控信息--节点信息记录(不需要策略层面的监控) + outMap.put("nodeSnapshot",JSON.parseObject(engineNode.getNodeJson())); + JSONObject nodeInfo = new JSONObject(); + nodeInfo.put("engineNode",engineNode); + nodeInfo.put("nodeId",engineNode.getNodeId()); + nodeInfo.put("nodeName",engineNode.getNodeName()); + nodeInfo.put("nodeType",engineNode.getNodeType()); + outMap.put("nodeInfo",nodeInfo); + JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript()); + JSONArray inputArray = jsonObject.getJSONArray("input"); + List inputList = JSONObject.parseArray(JSONObject.toJSONString(jsonObject.getJSONArray("input")), JSONObject.class); + JSONArray conditionArray = jsonObject.getJSONArray("conditions"); + JSONObject outputJson = jsonObject.getJSONObject("output"); + + // 变量值转义 + Map variablesMap = new HashMap<>(); + for (int i = 0; i < inputArray.size(); i++) { + String input = inputArray.get(i).toString(); + JSONObject inputField = JSONObject.parseObject(input); + String field_code = inputField.getString("field_code"); + Map fieldsMap = new HashMap<>(); + fieldsMap.put(field_code, inputField.getInteger("valueType")); + variablesMap.put(field_code, inputParam.get(field_code)); + variablesMap = JevalUtil.convertVariables(fieldsMap, variablesMap); + } + + // 默认值处理 + String dicisionResult =""; + String defaultValue = outputJson.getString("defaultValue"); + if (StringUtils.isNotBlank(defaultValue)){ + dicisionResult = defaultValue; + } + // 决策条件判断 + if(conditionArray != null && conditionArray.size() > 0){ + for (int i = 0; i < conditionArray.size(); i++) { + JSONObject formulaJson = JSONObject.parseObject(conditionArray.getString(i)); + try { + boolean outfieldvalue = JevalUtil.evaluateBoolean(formulaJson.getString("formula"), variablesMap); + if (outfieldvalue) { + dicisionResult = formulaJson.getString("result"); + // 输出结果计算 + String result = formulaJson.getString("result"); + if(result.contains("{") && result.contains("}")){ + String expression = result; + Pattern pattern = Pattern.compile("\\{[a-zA-Z0-9_\u4e00-\u9fa5()()-]+\\}"); + Matcher matcher = pattern.matcher(expression); + while (matcher.find()) { + String asName = matcher.group(0).replace("{", "").replace("}", ""); + Optional inputObj = inputList.stream().filter(item -> asName.equals(item.getString("asName"))).findFirst(); + if(inputObj.isPresent()){ + String field_code = inputObj.get().getString("field_code"); + expression = expression.replaceAll(asName, field_code); + } + } + expression = expression.replaceAll("\\{", "#{"); + Double calResult = JevalUtil.evaluateNumric(expression, variablesMap); + dicisionResult = calResult.toString(); + } + + break; + } + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + } + } + + Map outFields = new HashMap<>(); + String outputFieldCode = outputJson.getString("field_code"); + outFields.put("fieldId", outputJson.getIntValue("field_id")); + outFields.put("fieldName", outputJson.getString("field_name")); + outFields.put("fieldCode", outputFieldCode); + outFields.put("outValue", dicisionResult); + outMap.put("result", dicisionResult); + String key = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_result"; + inputParam.put(key, dicisionResult); + inputParam.put(outputFieldCode, dicisionResult); + + JSONObject json = new JSONObject(); + json.put("nodeId", engineNode.getNodeId()); + json.put("nodeName", engineNode.getNodeName()); + json.put("outFields", JSONObject.parseObject(JSON.toJSONString(outFields))); + //监控中心===》hbase中写入结果信息 + outMap.put("nodeResult",json); + if (outMap.containsKey("decisionJson")) { + JSONArray resultJson = (JSONArray) outMap.get("decisionJson"); + resultJson.add(json); + } else { + JSONArray resultJson = new JSONArray(); + resultJson.add(json); + outMap.put("decisionJson", resultJson); + } + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/GroupNode.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/GroupNode.java new file mode 100644 index 0000000..ff0abd6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/GroupNode.java @@ -0,0 +1,107 @@ +package com.baoying.enginex.executor.node.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.common.constants.CommonConst; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.node.service.CommonService; +import com.baoying.enginex.executor.node.service.EngineNodeService; +import com.baoying.enginex.executor.util.JevalUtil; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class GroupNode implements EngineNodeService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private CommonService commonService; + + @Override + public void getNodeField(EngineNode engineNode, Map inputParam) { + logger.info("start【获取分组节点指标】GroupNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam)); + JSONObject jsonObject = JSONObject.parseObject(engineNode.getNodeScript()); + JSONArray array = jsonObject.getJSONArray("fields"); + List ids = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + JSONObject input = array.getJSONObject(i); + Object fieldId = input.get("fieldId"); + if(fieldId != null && !"".equals(fieldId.toString())){ + ids.add(Long.valueOf(fieldId.toString())); + } + } + commonService.getFieldByIds(ids, inputParam); + } + + @Override + public void runNode(EngineNode engineNode, Map inputParam, Map outMap) { + JSONObject jsonScript = JSONObject.parseObject(engineNode.getNodeScript()); + //监控中心--节点信息记录(不需要策略层面的监控) + outMap.put("nodeSnapshot",JSONObject.parse(engineNode.getNodeJson())); + JSONObject nodeInfo = new JSONObject(); + nodeInfo.put("engineNode",engineNode); + nodeInfo.put("nodeId",engineNode.getNodeId()); + nodeInfo.put("nodeName",engineNode.getNodeName()); + nodeInfo.put("nodeType",engineNode.getNodeType()); + outMap.put("nodeInfo",nodeInfo); + try { + String nextNode = handleClassify(jsonScript, inputParam); + outMap.put("nextNode", nextNode); + JSONObject result = new JSONObject(); + result.put("nodeResult",nextNode); + outMap.put("nodeResult",result); + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + } + + private static String handleClassify(JSONObject jsonScript, Map inputParam) throws EvaluationException { + JSONArray conditions = jsonScript.getJSONArray("conditions"); + JSONArray fields = jsonScript.getJSONArray("fields"); + Map variablesMap = new HashMap<>(); + variablesMap.putAll(inputParam); + Map fieldsMap = new HashMap<>(); + for(int i = 0; i < fields.size(); i++){ + JSONObject jsonObject = fields.getJSONObject(i); + fieldsMap.put(jsonObject.getString("fieldCode"), jsonObject.getIntValue("valueType")); + } + JevalUtil.convertVariables(fieldsMap, variablesMap); + + String nextNode = ""; + if (conditions == null || conditions.isEmpty()) { + //TODO 如果为空,如何处理 + return nextNode; + } else { + int size = conditions.size(); + boolean flag = false; + JSONObject formula = null; + for (int i = 0; i < size; i++) { + formula = conditions.getJSONObject(i); + //公式为空,则为else条件分支 + if (CommonConst.STRING_EMPTY.equals(formula.getString("formula"))) { + //else条件 + if (nextNode.equals(CommonConst.STRING_EMPTY)) { + nextNode = formula.getString("nextNode"); + } + } else { + //正常条件分支 + flag = JevalUtil.evaluateBoolean(formula.getString("formula"), variablesMap); + if (flag) { + nextNode = formula.getString("nextNode"); + break; + } + } + } + return nextNode; + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/RuleSetNode.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/RuleSetNode.java new file mode 100644 index 0000000..971aacf --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/RuleSetNode.java @@ -0,0 +1,866 @@ +package com.baoying.enginex.executor.node.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.common.constants.CommonConst; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.common.ksession.KSessionPool; +import com.baoying.enginex.executor.common.model.ExpressionParam; +import com.baoying.enginex.executor.datamanage.model.Field; +import com.baoying.enginex.executor.datamanage.service.FieldService; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.engine.model.InputParam; +import com.baoying.enginex.executor.engine.model.Result; +import com.baoying.enginex.executor.node.service.CommonService; +import com.baoying.enginex.executor.node.service.EngineNodeService; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.rule.consts.RuleConst; +import com.baoying.enginex.executor.rule.model.RuleInfo; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; +import com.baoying.enginex.executor.rule.model.vo.RuleConditionVo; +import com.baoying.enginex.executor.rule.model.vo.RuleVersionVo; +import com.baoying.enginex.executor.rule.service.*; +import com.baoying.enginex.executor.tactics.consts.TacticsType; +import com.baoying.enginex.executor.util.ExecuteUtils; +import com.baoying.enginex.executor.util.JevalUtil; +import com.baoying.enginex.executor.util.MD5; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import org.apache.commons.lang3.StringUtils; +import org.drools.runtime.StatefulKnowledgeSession; +import org.drools.runtime.rule.FactHandle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + +@Service +public class RuleSetNode implements EngineNodeService { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private CommonService commonService; + @Autowired + private RuleFieldInfoService ruleFieldInfoService; + @Resource + private RuleService ruleService; + @Autowired + private RuleConditionService conditionService; + @Resource + private RuleScriptVersionService ruleScriptVersionService; + @Resource + private FieldService fieldService; + @Autowired + private RuleVersionService versionService; + @Autowired + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + @Autowired + private KSessionPool kSessionPool; + @Autowired + private RedisManager redisManager; + + @Override + public void getNodeField(EngineNode engineNode, Map inputParam) { + logger.info("start【获取规则集节点指标】RuleSetNode.getNodeField engineNode:{},inputParam:{}", JSONObject.toJSONString(engineNode), JSONObject.toJSONString(inputParam)); + JSONObject nodeJson = JSONObject.parseObject(engineNode.getNodeJson()); + List ids = new ArrayList<>(); + List ruleIds = new ArrayList<>(); // 基础规则集 + List versionIds = new ArrayList<>(); // 复杂规则集 + List scriptVersionIds = new ArrayList<>(); // 脚本规则集 + + JSONArray jsonArray = null; + int groupType = nodeJson.getInteger("groupType"); + if (groupType == Constants.ruleNode.MUTEXGROUP) { + jsonArray = nodeJson.getJSONObject("mutexGroup").getJSONArray("rules"); + } else { + jsonArray = nodeJson.getJSONObject("executeGroup").getJSONArray("rules"); + } + + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject ruleObj = jsonArray.getJSONObject(i); + Long versionId = ruleObj.getLong("ruleVersionId"); + Long ruleId = ruleObj.getLong("id"); + Long difficulty = ruleObj.getLong("difficulty"); + if (difficulty != null && difficulty == 3) { + scriptVersionIds.add(versionId); // 脚本式规则 + } else if (versionId != null) { + versionIds.add(versionId); // 复杂规则 + } else if (ruleId != null) { + ruleIds.add(ruleId); // 简单规则 + } + } + + //获取字段en + List fieldEnList = new ArrayList<>(); + if (!ruleIds.isEmpty()) { + fieldEnList.addAll(ruleFieldInfoService.getFieldEnList(ruleIds)); + } + if (!versionIds.isEmpty()) { + fieldEnList.addAll(conditionService.queryFieldEnByVersionIds(versionIds)); + } + if (!scriptVersionIds.isEmpty()) { + fieldEnList.addAll(ruleScriptVersionService.queryFieldEnByVersionIds(scriptVersionIds)); + } + + //筛选调那些循环或者嵌套中的字段 + fieldEnList = fieldEnList.stream().distinct().filter(f -> f != null && !f.contains(".") && !f.contains("%")).collect(Collectors.toList()); + if (fieldEnList != null && !fieldEnList.isEmpty()) { + List fieldList = fieldService.selectFieldListByEns(fieldEnList); + for (Field field : fieldList) { + ids.add(field.getId()); + } + } + + if (!ids.isEmpty()) { + commonService.getFieldByIds(ids, inputParam); + } + } + + @Override + public void runNode(EngineNode engineNode, Map inputParam, Map outMap) { + JSONObject nodeJson = JSONObject.parseObject(engineNode.getNodeJson()); + //监控中心--记录节点快照信息 + if (engineNode != null && engineNode.getSnapshot() != null) { + outMap.put("nodeSnapshot", engineNode.getSnapshot()); + } + JSONObject nodeInfo = new JSONObject(); + nodeInfo.put("engineNode", engineNode); + nodeInfo.put("nodeId", engineNode.getNodeId()); + nodeInfo.put("nodeName", engineNode.getNodeName()); + nodeInfo.put("nodeType", engineNode.getNodeType()); + outMap.put("nodeInfo", nodeInfo); + int groupType = nodeJson.getInteger("groupType") == null ? Constants.ruleNode.EXECUTEGROUP : nodeJson.getInteger("groupType"); + CopyOnWriteArrayList ruleResultList = new CopyOnWriteArrayList<>();// 规则执行结果集合 + List ruleHitList = new ArrayList<>(); // 命中的规则集合 + + // 互斥组(串行) + if (groupType == Constants.ruleNode.MUTEXGROUP) { + JSONArray jsonArray = nodeJson.getJSONObject("mutexGroup").getJSONArray("rules"); + List ruleInfoList = getRuleFromJsonArray(jsonArray); + //监控中心--循环获取策略层面的快照信息 + recordStrategySnopshot(ruleInfoList, outMap); + ruleHitList = serialRule(inputParam, outMap, ruleInfoList, ruleResultList); + } + // 执行组(并行) + else if (groupType == Constants.ruleNode.EXECUTEGROUP) { + JSONArray jsonArray = nodeJson.getJSONObject("executeGroup").getJSONArray("rules"); + List ruleInfoList = getRuleFromJsonArray(jsonArray); + //监控中心--循环获取策略层面的快照信息 + recordStrategySnopshot(ruleInfoList, outMap); + ruleHitList = parallelRule(inputParam, outMap, ruleInfoList, ruleResultList); + } + + // 终止条件处理 + terminalCondition(engineNode, nodeJson, outMap, ruleHitList); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("nodeId", engineNode.getNodeId()); + jsonObject.put("nodeName", engineNode.getNodeName()); + jsonObject.put("ruleResultList", ruleResultList); + + if (outMap.containsKey("ruleJson")) { + JSONArray resultJson = (JSONArray) outMap.get("ruleJson"); + resultJson.add(jsonObject); + } else { + JSONArray resultJson = new JSONArray(); + resultJson.add(jsonObject); + outMap.put("ruleJson", resultJson); + } + int hitSize = 0; + double scoreSum = 0d; + for (Map map : ruleResultList) { + Object ruleScore = map.get("ruleScore"); + Object ruleResult = map.get("ruleResult"); + if (null != ruleResult && "命中".equals(ruleResult)) { + hitSize++; + if (null != ruleScore) { + try { + scoreSum += Double.valueOf(ruleScore.toString()); + } catch (Exception e) { + continue; + } + } + } + } + String hitKey = "" + engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_size"; + String scoreKey = "" + engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_score"; + inputParam.put(hitKey, hitSize); + inputParam.put(scoreKey, scoreSum); + //监控中心==》记录节点输出结果 + //记录整个规则集中的所有规则的命中情况,以及总的统计次数 放到输出变量池 + JSONObject nodeResult = new JSONObject(); + nodeResult.put("ruleResultList", ruleResultList); + nodeResult.put("hitNum", hitSize); + nodeResult.put("scoreTotal", scoreSum); + outMap.put("nodeResult", nodeResult); + } + + /** + * 监控中心--获取策略层面快照信息 + * + * @param ruleInfoList + * @param outMap + */ + private void recordStrategySnopshot(List ruleInfoList, Map outMap) { + JSONArray jsonObject = new JSONArray(); + ruleInfoList.stream().forEach(ruleInfo -> { + if (ruleInfo.getVersion().getSnapshot() != null) { + jsonObject.add(ruleInfo.getVersion().getSnapshot()); + + } + }); + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("snopshot", jsonObject); + outMap.put("strategySnopshot", jsonObject1); + } + + /** + * 串行执行规则 + * + * @param inputParam + * @param outMap + * @param ruleInfoList + * @param ruleResultList + * @return + */ + private List serialRule(Map inputParam, Map outMap, List ruleInfoList, CopyOnWriteArrayList ruleResultList) { + logger.info("请求参数--串行执行规则" + "map:" + JSONObject.toJSONString(inputParam)); + List resultList = new ArrayList<>(); + for (int i = 0; i < ruleInfoList.size(); i++) { + RuleInfo rule = ruleInfoList.get(i); + boolean hitFlag = executeByDifficulty(inputParam, outMap, rule, ruleResultList); + if (hitFlag) { + resultList.add(rule); + break; + } + } + return resultList; + } + + + /** + * 并行执行规则 + * + * @param inputParam + * @param outMap + * @param ruleInfoList + * @param ruleResultList + * @return + */ + private List parallelRule(Map inputParam, Map outMap, List ruleInfoList, CopyOnWriteArrayList ruleResultList) { + logger.info("请求参数--并行执行规则" + "map:" + JSONObject.toJSONString(inputParam)); + List resultList = new ArrayList<>(); + List> futureList = new ArrayList<>(); + for (int i = 0; i < ruleInfoList.size(); i++) { + final int index = i; + CompletableFuture future = CompletableFuture.supplyAsync(() -> { + RuleInfo rule = ruleInfoList.get(index); + boolean hitFlag = executeByDifficulty(inputParam, outMap, rule, ruleResultList); + if (hitFlag) { + return rule; + } else { + return null; + } + }, threadPoolTaskExecutor); + + futureList.add(future); + } + + for (CompletableFuture future : futureList) { + try { + RuleInfo rule = future.get(); + if (rule != null) { + resultList.add(rule); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + return resultList; + } + + /** + * 根究规则类型选择执行 + * + * @param inputParam + * @param outMap + * @param rule + * @param ruleResultList + * @return + */ + private boolean executeByDifficulty(Map inputParam, Map outMap, RuleInfo rule, CopyOnWriteArrayList ruleResultList) { + boolean hitFlag = false; + if (rule.getDifficulty() == 1) { + hitFlag = executeBasicRule(inputParam, outMap, rule, ruleResultList); + } else if (rule.getDifficulty() == 2) { + hitFlag = executeComplexRule(inputParam, outMap, rule, ruleResultList); + } else if (rule.getDifficulty() == 3) { + hitFlag = executeScriptRule(inputParam, outMap, rule, ruleResultList); + } + return hitFlag; + } + + /** + * 执行复杂规则 + * + * @param input + * @param output + * @param rule + * @param ruleResultList + * @return + */ + public boolean executeComplexRule(Map input, Map output, RuleInfo rule, CopyOnWriteArrayList ruleResultList) { + boolean hitFlag = false; + //获取需要执行的整个规则。 +// RuleVo rule = ruleService.queryByVersionId(ruleId); +// Long versionId = rule.getVersionId(); +// if (versionId==null){ +// return false; +// } +// RuleVersionVo ruleVersion = versionService.queryByVersionId(versionId); + RuleVersionVo ruleVersion = rule.getVersion(); + if (ruleVersion == null) { + return false; + } + + //取出本规则的条件列表 + Map ruleMap = new HashMap<>(); + ruleMap.put("ruleId", rule.getId()); + ruleMap.put("ruleVersionId",ruleVersion.getId()); + ruleMap.put("ruleCode", rule.getCode()); + ruleMap.put("ruleName", rule.getName()); + ruleMap.put("versionCode", ruleVersion.getVersionCode()); + ruleMap.put("versionDesc", ruleVersion.getDescription()); + ruleMap.put("desc", rule.getDescription()); + ruleMap.put("ruleResult", "未命中"); + + //获取规则需要执行的condition逻辑。 + RuleConditionVo ruleCondition = ruleVersion.getRuleConditionVo(); + //传入输入参数、中间变量、输出参数和需要执行的condition逻辑获取执行结果 + Map temp = JSON.parseObject(JSON.toJSONString(input), Map.class); + boolean result = this.executeRuleCondition(temp, output, ruleCondition); + String resultFieldEn = ruleVersion.getResultFieldEn(); + if (resultFieldEn == null || "".equals(resultFieldEn)) { + resultFieldEn = "rule_2_"+rule.getId()+"_"+ruleVersion.getId()+"_hitResult"; + } + String scoreFieldEn = ruleVersion.getScoreFieldEn(); + if (StringUtils.isNotBlank(scoreFieldEn)){ + scoreFieldEn = "rule_2_"+rule.getId()+"_"+ruleVersion.getId()+"_score"; + } + input.put(resultFieldEn, "未命中"); + //根据执行的最终结果处理此规则输出内容 + List fieldList = new ArrayList<>(); + JSONObject resultJson = new JSONObject(); + if (result) { + ruleMap.put("ruleResult", "命中"); + ruleMap.put("ruleScore", rule.getScore()); + JSONObject scoreJson = new JSONObject(); + resultJson.put(resultFieldEn, "命中"); + fieldList.add(resultJson); +// if (StringUtils.isNotBlank(ruleVersion.getScoreFieldEn())) { + scoreJson.put(scoreFieldEn, ruleVersion.getScore()); + fieldList.add(scoreJson); + input.put(scoreFieldEn, ruleVersion.getScore()); +// } + input.put(resultFieldEn, "命中"); + //处理此规则需要输出的内容 + fieldList.addAll(ruleService.setComplexRuleOutput(ruleVersion.getId(), temp, input, TacticsType.OutType.SUCCESS_OUT)); + ruleMap.put("fieldList", fieldList); + hitFlag = true; + } else { + resultJson.put(resultFieldEn, "未命中"); + ruleMap.put("ruleScore", 0); + input.put(scoreFieldEn,0); + fieldList.add(resultJson); + fieldList.addAll(ruleService.setComplexRuleOutput(ruleVersion.getId(), temp, input, TacticsType.OutType.FAIL_OUT)); + ruleMap.put("fieldList", fieldList); + } + ruleResultList.add(ruleMap); + return hitFlag; + } + + //执行规则的条件 + private boolean executeRuleCondition(Map input, Map output, RuleConditionVo ruleCondition) { + Integer conditionType = ruleCondition.getConditionType(); + boolean result = false; + switch (conditionType) { + //关系条件节点 &&和|| + case RuleConst.RELATION_CONDITION: + //循环结果的条件 + case RuleConst.LOOP_RESULT_CONDITION: + case RuleConst.CONDITION_RESULT_CONDITION: + result = executeRelation(input, output, ruleCondition); + break; + //表达式条件节点 + case RuleConst.EXPRESSION_CONDITION: + result = executeExpression(input, output, ruleCondition); + break; + //循环条件根节点 + case RuleConst.LOOP_CONDITION: + result = executeLoop(input, output, ruleCondition); + break; + //条件组根节点 + case RuleConst.CONDITION_GROUP_CONDITION: + result = executeCondGroup(input, output, ruleCondition); + break; + } + return result; + } + + //执行条件组 + private boolean executeCondGroup(Map input, Map output, RuleConditionVo ruleCondition) { + //取出子条件 + List children = ruleCondition.getChildren(); + //存储命中条数 + int hitNum = 0; + if (children == null) { + return false; + } + //执行条件组中条件列表,命中则添加命中条数 + for (RuleConditionVo child : children) { + boolean childResult = executeRuleCondition(input, output, child); + if (childResult) { + hitNum++; + } + } + //获取条件组命中条件,为null直接不命中 + RuleConditionVo condGroup = ruleCondition.getCondGroupResultCondition(); + if (condGroup == null) { + return false; + } + //传入命中条件和组内命中条数执行并返回 + Map map = new HashMap<>(); + //将命中条数存入map然后判断执行结果 + map.put("hitNum", hitNum); + return executeRuleCondition(map, output, condGroup); + } + + //关系条件节点 &&和|| + private boolean executeRelation(Map input, Map output, RuleConditionVo ruleCondition) { + //获取关系逻辑 + String logical = ruleCondition.getLogical(); + //处理子逻辑 + List children = ruleCondition.getChildren(); + + boolean result = false; + switch (logical) { + case "||": + result = false; + for (RuleConditionVo child : children) { + boolean childResult = executeRuleCondition(input, output, child); + if (childResult) { + return true; + } + } + break; + case "&&": + result = true; + for (RuleConditionVo child : children) { + boolean childResult = executeRuleCondition(input, output, child); + if (!childResult) { + return false; + } + } + break; + } + return result; + } + + //表达式条件节点 + private boolean executeExpression(Map input, Map output, RuleConditionVo ruleCondition) { + String executionLogic = ruleCondition.getExecutionLogic(); + boolean result = false; + ExpressionParam expressionParam = new ExpressionParam(); + //复制执行的关键参数到统一入参 + BeanUtils.copyProperties(ruleCondition, expressionParam); + result = ExecuteUtils.getExpressionResult(expressionParam, input); + return result; + } + + //循环条件根节点 + private boolean executeLoop(Map input, Map output, RuleConditionVo ruleCondition) { + List children = ruleCondition.getChildren(); + String fieldEn = ruleCondition.getFieldEn(); + + //对循环中每个条件进行处理 + String[] split = fieldEn.split("\\."); + //从map中取元素返回最终取到的对象 + Object obj = ExecuteUtils.getObjFromMap(input, fieldEn); + List arrayList = new ArrayList(); + if (obj != null) { + arrayList.addAll(JSON.parseObject(JSON.toJSONString(obj), ArrayList.class)); + } + //取不到这个数组 + if (arrayList.isEmpty()) { + return false; + } + //拼接当前对象的key + String currentKey = "%" + split[split.length - 1] + "%"; + for (RuleConditionVo child : children) { + List loopGroupActions = child.getLoopGroupActions(); + // 调用for循环条件下的操作,并且将其存入input中 + for (RuleLoopGroupAction loopGroupAction : loopGroupActions) { + this.initLoopGroupAction(loopGroupAction, input); + } + } + for (Object currentObj : arrayList) { + //将循环时的当前对象存入input + input.put(currentKey, currentObj); + //循环执行当前for中的每个判断单元 + for (RuleConditionVo child : children) { + if (executeRuleCondition(input, output, child)) { + List loopGroupActions = child.getLoopGroupActions(); + // 调用for循环条件下的操作,并且将其存入input中 + for (RuleLoopGroupAction loopGroupAction : loopGroupActions) { + this.saveLoopGroupAction(loopGroupAction, input); + } + } + } + } + //计算for的返回结果 + RuleConditionVo loopResultCondition = ruleCondition.getLoopResultCondition(); + boolean result = executeRuleCondition(input, output, loopResultCondition); + return result; + } + + //保存循环规则的动作 + private void saveLoopGroupAction(RuleLoopGroupAction loopGroupAction, Map input) { + Integer actionType = loopGroupAction.getActionType(); + String actionKey = loopGroupAction.getActionKey(); + String actionValue = loopGroupAction.getActionValue(); + if (actionType == null) { + return; + } + switch (actionType) { + case RuleConst.LOOP_GROUP_ACTION_TYPE_SUM: + Integer count = 1; + if (input.containsKey(actionKey) && StringUtils.isNumeric(ExecuteUtils.getObjFromMap(input, actionKey).toString())) { + count = count + Integer.parseInt(ExecuteUtils.getObjFromMap(input, actionKey).toString()); + } + input.put(actionKey, count); + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_ASSIGNMENT: + //赋值待添加 + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_CONST: + input.put(actionKey, actionValue); + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_VARIABLE: + input.put(actionKey, ExecuteUtils.getObjFromMap(input, actionValue)); + break; + } + } + + + private void initLoopGroupAction(RuleLoopGroupAction loopGroupAction, Map input){ + Integer actionType = loopGroupAction.getActionType(); + String actionKey = loopGroupAction.getActionKey(); + String actionValue = loopGroupAction.getActionValue(); + if (actionType == null) { + return; + } + switch (actionType) { + case RuleConst.LOOP_GROUP_ACTION_TYPE_SUM: + input.put(actionKey, 0); + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_ASSIGNMENT: + //赋值待添加 + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_CONST: + input.put(actionKey, ""); + break; + case RuleConst.LOOP_GROUP_ACTION_TYPE_OUT_VARIABLE: + input.put(actionKey,new HashSet<>()); + break; + } + } + /** + * 执行基础规则(drools) + * + * @param map + * @param outMap + * @param rule + * @param ruleResultList + * @return + */ + private boolean executeBasicRule(Map map, Map outMap, RuleInfo rule, CopyOnWriteArrayList ruleResultList) { + boolean hitFlag = false; + StatefulKnowledgeSession kSession = null; + String keyMd5 = null; + try { + String ruleString = rule.getContent().replace("\\r\\n", "\r\n"); + ruleString = ruleString.replace("\\t", "\t"); + keyMd5 = CommonConst.DROOLS_KSESSION_KEY_PREFIX + MD5.GetMD5Code(ruleString); + redisManager.set(keyMd5, ruleString, 120); + kSession = kSessionPool.borrowObject(keyMd5); + + List resultList = new ArrayList<>(); + InputParam inputParam = new InputParam(); + inputParam.setInputParam(map); + inputParam.setResult(resultList); + FactHandle fact = kSession.insert(inputParam); + kSession.fireAllRules(); + kSession.retract(fact); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("ruleId", rule.getId()); + jsonObject.put("ruleCode", rule.getCode()); + jsonObject.put("ruleName", rule.getName()); + jsonObject.put("desc", rule.getDescription()); + String resultEn = rule.getResultFieldEn(); + if (StringUtils.isBlank(resultEn)){ + resultEn = "rule_1_"+rule.getId()+"_hitResult"; + } + String scoreEn = rule.getScoreFieldEn(); + if (StringUtils.isBlank(resultEn)){ + scoreEn = "rule_1_"+rule.getId()+"_score"; + } + if (resultList.size() > 0) { + jsonObject.put("ruleResult", "命中"); + jsonObject.put("ruleScore", rule.getScore()); + map.put(scoreEn, rule.getScore()); + map.put(resultEn, "命中"); + + List fieldList = new ArrayList<>(); + JSONObject resultJson = new JSONObject(); + JSONObject scoreJson = new JSONObject(); + resultJson.put(rule.getResultFieldEn(), "命中"); + scoreJson.put(rule.getScoreFieldEn(), rule.getScore()); + fieldList.add(resultJson); + fieldList.add(scoreJson); + if (null != rule && null != rule.getId()) { + fieldList.addAll(ruleService.setBaseRuleOutput(rule.getId(), map)); + jsonObject.put("fieldList", fieldList); + } + ruleResultList.add(jsonObject); + hitFlag = true; + + } else { + // 未命中返回信息 + jsonObject.put("ruleResult", "未命中"); + map.put(resultEn, "未命中"); + map.put(scoreEn, 0); + ruleResultList.add(jsonObject); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("请求异常", e); + } finally { + if (keyMd5 != null && kSession != null) { + kSessionPool.returnObject(keyMd5, kSession); + } + } + return hitFlag; + } + + /** + * 终止条件判断 + * + * @param engineNode + * @param inputParam + * @param outMap + * @param ruleHitList + */ + private void terminalCondition(EngineNode engineNode, Map inputParam, Map outMap, List ruleHitList) { + if (StringUtils.isBlank(engineNode.getNodeScript())) { + return; + } + JSONObject nodeScript = JSONObject.parseObject(engineNode.getNodeScript()); + JSONObject terminationInfo = nodeScript.getJSONObject("terminationInfo"); + JSONArray selectedRule = terminationInfo.getJSONArray("selectedRule"); + String conditions = terminationInfo.getString("conditions"); + if (!selectedRule.isEmpty()) { + if (!selectedRule.isEmpty()) { + List selectedRuleList = JSONObject.parseArray(JSONObject.toJSONString(selectedRule), JSONObject.class); + // 查找已选规则中命名的规则集合 + List selectedHitRules = new ArrayList<>(); + for (JSONObject jsonObject : selectedRuleList) { + Optional rule = ruleHitList.stream().filter(item -> item.getId().equals(jsonObject.getLong("id"))).findFirst(); + if (rule.isPresent()) { + selectedHitRules.add(rule.get()); + } + } + + int totalSize = selectedHitRules.size(); // 规则命名个数 + double totalScore = selectedHitRules.stream().mapToDouble(RuleInfo::getScore).sum(); // 规则总得分 + String sizeKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_size"; + String scoreKey = engineNode.getNodeType() + "_" + engineNode.getNodeId() + "_terminal_score"; + Map variablesMap = new HashMap<>(); + variablesMap.put(sizeKey, totalSize); + variablesMap.put(scoreKey, totalScore); + + ExecuteUtils.terminalCondition(engineNode,inputParam,outMap,variablesMap); + } + } + } + + private List getRuleFromJsonArray(JSONArray jsonArray) { + List ruleIds = new ArrayList<>(); + Map map = new HashMap<>(); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject ruleObj = jsonArray.getJSONObject(i); + Long versionId = ruleObj.getLong("ruleVersionId"); + Long ruleId = ruleObj.getLong("id"); + if (ruleId != null) { + ruleIds.add(ruleId); + if (versionId != null) { + map.put(ruleId, versionId); + } + } + } + + List ruleInfoList = ruleService.getRuleList(ruleIds); + for (RuleInfo ruleInfo : ruleInfoList) { + if (ruleInfo.getDifficulty() == 2 || ruleInfo.getDifficulty() == 3) { + Long versionId = map.get(ruleInfo.getId()); + ruleInfo.setVersionId(versionId); + if (versionId != null) { + switch (ruleInfo.getDifficulty()) { + case 2: + RuleVersionVo ruleVersionVo = versionService.queryById(versionId); + ruleInfo.setVersion(ruleVersionVo); + ruleInfo.setScore(ruleVersionVo.getScore()); + break; + case 3: + RuleScriptVersion ruleScriptVersion = ruleScriptVersionService.queryById(versionId); + ruleInfo.setScriptVersion(ruleScriptVersion); + ruleInfo.setVersion(JSON.parseObject(JSON.toJSONString(ruleScriptVersion), RuleVersionVo.class)); + ruleInfo.setScore(0); + break; + } + } else { + ruleInfo.setScore(0); + } + } + } + + return ruleInfoList; + } + + /** + * 执行脚本规则 + * + * @param inputParam + * @param outMap + * @param rule + * @param ruleResultList + * @return + */ + private boolean executeScriptRule(Map inputParam, Map outMap, RuleInfo rule, CopyOnWriteArrayList ruleResultList) { + boolean hitFlag = false; + RuleScriptVersion scriptVersion = rule.getScriptVersion(); + if (RuleConst.ScriptType.GROOVY.equals(rule.getScriptType())&&RuleConst.ScriptType.GROOVY.equals( scriptVersion.getScriptType())) { + //groovy脚本执行 + //取出需要执行的版本 + if (scriptVersion == null || StringUtils.isBlank(scriptVersion.getScriptContent())) { + return false; + } + //取出脚本内容 + String scriptContent = scriptVersion.getScriptContent(); + //取出本规则集的规则列表 + Map ruleMap = new HashMap<>(); + ruleMap.put("ruleId", rule.getId()); + ruleMap.put("ruleCode", rule.getCode()); + ruleMap.put("ruleName", rule.getName()); + ruleMap.put("versionCode", scriptVersion.getVersionCode()); + ruleMap.put("versionDesc", scriptVersion.getDescription()); + ruleMap.put("desc", rule.getDescription()); + ruleMap.put("ruleResult", "未命中"); + + + String resultFieldEn = "hitResult"; + String resultEn = "rule_"+rule.getDifficulty()+"_"+rule.getId()+"_"+scriptVersion.getId()+"_hitResult"; + String scoreEn = "rule_"+rule.getDifficulty()+"_"+rule.getId()+"_"+scriptVersion.getId()+"_score"; + inputParam.put(resultEn, "未命中"); + inputParam.put(scoreEn,0); + //根据执行的最终结果处理此规则输出内容 + List fieldList = new ArrayList<>(); + JSONObject resultJson = new JSONObject(); + try { + Object resp = ExecuteUtils.getObjFromScript(inputParam, scriptContent); + String result = "未命中"; + JSONObject executeResult = null; + int ruleScore = 0; + if (resp instanceof HashMap) { + Map resultMap = (HashMap) resp; + executeResult = JSON.parseObject(JSON.toJSONString(resultMap)); + ruleScore = executeResult.getIntValue("ruleScore"); + result = executeResult.getString(resultFieldEn); + JSONArray fieldListJson = executeResult.getJSONArray("fieldList"); + JSONObject updateInputMap = executeResult.getJSONObject("updateInputMap"); + if (fieldListJson != null) { + fieldList = fieldListJson.toJavaList(Object.class); + List list = new ArrayList(); + for (Object o : fieldList) { + if (o!=null&& o instanceof Map){ + Map map = ExecuteUtils.handleGroovyResult((Map) o); + list.add(map); + } + } + fieldList = list; + } + + if (executeResult != null) { + ruleMap.put("ruleResult", result); + ruleMap.put("ruleScore", ruleScore); + resultJson.put(resultFieldEn, result); + fieldList.add(resultJson); + inputParam.put(resultFieldEn, result); + //处理此规则需要输出的内容 + ruleMap.put("fieldList", fieldList); + } + if ("命中".equals(result)) { + hitFlag = true; + inputParam.put(resultEn,"命中"); + inputParam.put(scoreEn,ruleScore); + } + //更新入参 + if (updateInputMap!=null&&!updateInputMap.isEmpty()){ + Set> entries = ExecuteUtils.handleGroovyResult(updateInputMap).entrySet(); + for (Map.Entry entry : entries) { + inputParam.put(entry.getKey(),entry.getValue()); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("脚本规则集执行错误:{}" + e); + } + ruleResultList.add(ruleMap); + } + return hitFlag; + } + +// public static void main(String[] args) { +//// HashMap result = new HashMap<>(); //规则执行的返回值 +//// int ruleScore = 0; //规则命中时得分 +//// String hitResult = "未命中"; //命中结果,可选类型为:命中、未命中 +//// HashMap updateInputMap = new HashMap<>(); //用于更新入参的map,此map中的所有内容将被更新到入参中,key重复的将被覆盖。 +//// ArrayList> fieldList = new ArrayList<>(); //用于存放输出字段的值 +//// //自定义代码区域,根据需要书写逻辑代码 +//// +//// +//// +//// //返回固定格式的结果用于后续执行 +//// result.put("hitResult",hitResult); +//// result.put("ruleScore",ruleScore); +//// result.put("fieldList",fieldList); +//// result.put("updateInputMap",updateInputMap); +//// return result; +// } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/SandboxProportionNode.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/SandboxProportionNode.java new file mode 100644 index 0000000..3a10a88 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/node/service/impl/SandboxProportionNode.java @@ -0,0 +1,114 @@ +package com.baoying.enginex.executor.node.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.engine.model.Sandbox; +import com.baoying.enginex.executor.node.service.EngineNodeService; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +@Service +public class SandboxProportionNode implements EngineNodeService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Override + public void getNodeField(EngineNode engineNode, Map inputParam) { + + } + + @Override + public void runNode(EngineNode engineNode, Map inputParam, Map outMap) { + if (null != engineNode.getNodeScript()) { + List list = JSON.parseArray(engineNode.getNodeScript(), Sandbox.class); + //监控中心-- 节点配置信息记录(不需要策略层面的监控) + JSONObject nodeSnapshot = new JSONObject(); + nodeSnapshot.put("nodeSnapshot",JSON.parseArray(engineNode.getNodeJson())); + outMap.put("nodeSnapshot",nodeSnapshot); + JSONObject nodeInfo = new JSONObject(); + nodeInfo.put("engineNode",engineNode); + nodeInfo.put("nodeId",engineNode.getNodeId()); + nodeInfo.put("nodeName",engineNode.getNodeName()); + nodeInfo.put("nodeType",engineNode.getNodeType()); + outMap.put("nodeInfo",nodeInfo); + int num = 0;//随机生成的数 + int startNum = 0; + int endNum = 0; + for (int i = 0; i < list.size(); i++) { + Sandbox sandbox = list.get(i); + endNum = startNum + sandbox.getProportion(); + if (num == 0) + num = getRandoms(0, sandbox.getSum(), 1)[0]; + int[] range = getRandoms(startNum, endNum, sandbox.getProportion()); + for (int j = 0; j < range.length; j++) { + if (range[j] == num) { + if (StringUtils.isBlank(sandbox.getNextNode())) { + List sblist = JSON.parseArray(engineNode.getNodeJson(), Sandbox.class); + for (Sandbox sb : sblist) { + if (sb.getSandbox() == sandbox.getSandbox()) { + sandbox.setNextNode(sb.getNextNode()); + break; + } + } + } + + outMap.put("nextNode", sandbox.getNextNode()); + JSONObject nodeResult = new JSONObject(); + nodeResult.put("nodeResult",sandbox.getNextNode()); + outMap.put("nodeResult",nodeResult); + break; + } + } + startNum = endNum; + } + } + } + + /** + * 根据min和max随机生成count个不重复的随机数组 + * + * @param min + * @param max + * @param count + * @return int[] + */ + public int[] getRandoms(int min, int max, int count) { + int[] randoms = new int[count]; + List listRandom = new ArrayList(); + + if (count > (max - min + 1)) { + return null; + } + // 将所有的可能出现的数字放进候选list + for (int i = min; i < max; i++) { + listRandom.add(i); + } + // 从候选list中取出放入数组,已经被选中的就从这个list中移除 + for (int i = 0; i < count; i++) { + int index = getRandom(0, listRandom.size() - 1); + randoms[i] = listRandom.get(index); + listRandom.remove(index); + } + + return randoms; + } + + /** + * 根据min和max随机生成一个范围在[min,max]的随机数,包括min和max + * + * @param min + * @param max + * @return int + */ + public int getRandom(int min, int max) { + Random random = new Random(); + return random.nextInt(max - min + 1) + min; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisManager.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisManager.java new file mode 100644 index 0000000..f7dc255 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisManager.java @@ -0,0 +1,683 @@ +package com.baoying.enginex.executor.redis; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.PropertyNamingStrategy; +import com.alibaba.fastjson.parser.ParserConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import redis.clients.jedis.*; + +import java.util.*; + +@Component +public class RedisManager { + // 0-表示永远不过期 + private int expire = 0; + + @Autowired + private JedisPool jedisPool; + + public RedisManager() {} + + /** + * @Title: init + * @Description: 初始化方法,用来初始化 + * @param 设定文件 + * @return void 返回类型 + * @throws + */ + public void init() { + } + + /** + * @Title: get + * @Description: 根据key来获得一条特定的缓存数据 + * @param @param key 序列化后的key + * @param @return 设定文件 + * @return byte[] 返回类型 + * @throws + */ + public byte[] get(byte[] key) { + byte[] value = null; + Jedis jedis =null; + try { + jedis = jedisPool.getResource(); + value = jedis.get(key); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + jedis.close(); + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + + /** + * @Title: get + * @Description: 根据key来获得一条特定的缓存数据 + * @param @param key string类型的key + * @param @return 设定文件 + * @return String 返回类型 + * @throws + */ + public String get(String key) { + String value = null; + Jedis jedis = jedisPool.getResource(); + try { + value = jedis.get(key); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + /** + * @Title: set + * @Description: 向redis数据库中缓存数据,key,value都为byte[](已经序列化) + * @param @param key + * @param @param value + * @param @return 设定文件 + * @return byte[] 返回类型 + * @throws + */ + public byte[] set(byte[] key, byte[] value) { + Jedis jedis = jedisPool.getResource(); + try { + jedis.set(key, value); + if (this.expire != 0) { + jedis.expire(key, this.expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + /** + * @Title: set + * @Description: 向redis数据库中缓存数据,key,value为字符串类型,缓存时间为永不过期 + * @param @param key + * @param @param value + * @param @return 设定文件 + * @return String 返回类型 + * @throws + */ + public String set(String key, String value) { + Jedis jedis = jedisPool.getResource(); + try { + jedis.set(key, value); + if (this.expire != 0) { + jedis.expire(key, this.expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + /** + * @Title: set + * @Description: 向redis数据库中缓存数据,key,value都为byte[](已经序列化) + * @param @param key + * @param @param value + * @param @param expire 0为永不过期,其他时间则会设置对应的过期时间 + * @param @return 设定文件 + * @return byte[] 返回类型 + * @throws + */ + public byte[] set(byte[] key, byte[] value, int expire) { + Jedis jedis = null; + try { + jedis = jedisPool.getResource(); + jedis.set(key, value); + if (expire != 0) { + jedis.expire(key, expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + /** + * @Title: set + * @Description: 向redis数据库中缓存数据,key,value都为字符串的类型 + * @param @param key + * @param @param value + * @param @param expire 0为永不过期,其他时间则会设置对应的过期时间 + * @param @return 设定文件 + * @return String 返回类型 + * @throws + */ + public String set(String key, String value, int expire) { + Jedis jedis = jedisPool.getResource(); + try { + jedis.set(key, value); + if (expire != 0) { + jedis.expire(key, expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + /** + * @Title: del + * @Description: 根据byte数组(已经序列化的key)来删除redis数据库中缓存的数据 + * @param @param key 设定文件 + * @return void 返回类型 + * @throws + */ + public void del(byte[] key) { + Jedis jedis = jedisPool.getResource(); + try { + jedis.del(key); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + } + + /** + * @Title: del + * @Description: 根据特定的string类型的key来删除redis数据库中的缓存数据 + * @param @param key 设定文件 + * @return void 返回类型 + * @throws + */ + public void del(String key) { + Jedis jedis = jedisPool.getResource(); + try { + jedis.del(key); + } finally { + if (jedis != null) { + jedis.close(); + } + } + } + + /** + * @Title: flushDB + * @Description: 清除指定redis数据库中的数据 + * @param 设定文件 + * @return void 返回类型 + * @throws + */ + public void flushDB() { + Jedis jedis = jedisPool.getResource(); + try { + jedis.flushDB(); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + } + + /** + * @Title: dbSize + * @Description: 获得redis缓存数据的大小 + * @param @return 设定文件 + * @return Long 返回类型 + * @throws + */ + public Long dbSize() { + Long dbSize = 0L; + Jedis jedis = jedisPool.getResource(); + try { + dbSize = jedis.dbSize(); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return dbSize; + } + + /** + * @Title: keys + * @Description: 根据泛型来查询所有符合泛型的缓存数据 + * @param @param pattern + * @param @return 设定文件 + * @return Set 返回类型 + * @throws + */ + public Set keys(String pattern) { + Set keys = null; + Jedis jedis = jedisPool.getResource(); + try { + keys = jedis.keys(pattern.getBytes()); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return keys; + } + + /** + * @Title: dels + * @Description: 根据提供的泛型来删除reids中缓存的数据 + * @param @param pattern 设定文件 + * @return void 返回类型 + * @throws + */ + public void dels(String pattern) { + Set keys = null; + Jedis jedis = jedisPool.getResource(); + try { + keys = jedis.keys(pattern.getBytes()); + Iterator ito = keys.iterator(); + while (ito.hasNext()) { + jedis.del(ito.next()); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + } + + + + // ------------------------------------ 缓存改造 ----------------------------------- + + /** + * hash类型 添加键值对 + * + * @param key + * @param field + * @param value + * @return + */ + public Long hset(String key, String field, String value) { + Jedis jedis = jedisPool.getResource(); + Long result = null; + try { + result = jedis.hset(key, field, value); + if (this.expire != 0) { + jedis.expire(key, this.expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return result; + } + + /** + * hash类型 获取所有键值对 + * + * @param key + * @return + */ + public Map hgetAll(String key) { + Map value = null; + Jedis jedis = jedisPool.getResource(); + try { + value = jedis.hgetAll(key); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + public ScanResult scan(String cursor, ScanParams params) { + ScanResult value = null; + Jedis jedis = jedisPool.getResource(); + try { + value = jedis.scan(cursor, params); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return value; + } + + public List scan(String key) { + List result = null; + // 游标初始值为0 + String cursor = ScanParams.SCAN_POINTER_START; + ScanParams scanParams = new ScanParams(); + scanParams.match(key);// pattern + scanParams.count(1000); + while (true) { + //使用scan命令获取数据,使用cursor游标记录位置,下次循环使用 + ScanResult scanResult = scan(cursor, scanParams); + cursor = scanResult.getStringCursor();// 返回0 说明遍历完成 + List list = scanResult.getResult(); + if (result == null) { + result = new ArrayList<>(); + } + result.addAll(list); + if ("0".equals(cursor)) { + break; + } + } + return result; + } + + /** + * hash类型 模糊查询 + * + * @param keyPattern + * @param clazz + * @param + * @return + */ + public List scanHash(String keyPattern, Class clazz) { + List result = null; + List keys = scan(keyPattern); + for (String key : keys) { + Map map = hgetAll(key); + if (result == null) { + result = new ArrayList<>(); + } + result.add(JSONObject.parseObject(JSONObject.toJSONString(map), clazz)); + } + return result; + } + + /** + * list类型 从尾部添加元素 + * + * @param key + * @param strings + * @return + */ + public Long rpush(String key, String... strings) { + Jedis jedis = jedisPool.getResource(); + Long result = null; + try { + result = jedis.rpush(key, strings); + if (this.expire != 0) { + jedis.expire(key, this.expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return result; + } + + /** + * list类型 获取链表中从start到end的元素的值 + * (start、end可为负数,若为-1则表示链表尾部的元素) + * + * @param key + * @param start + * @param end + * @return + */ + public List lrange(String key, long start, long end) { + Jedis jedis = jedisPool.getResource(); + List result = null; + try { + result = jedis.lrange(key, 0, -1); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return result; + } + + /** + * set类型 添加成员 + * + * @param key + * @param members + * @return + */ + public Long sadd(String key, String... members) { + Jedis jedis = jedisPool.getResource(); + Long result = null; + try { + result = jedis.sadd(key, members); + if (this.expire != 0) { + jedis.expire(key, this.expire); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return result; + } + + /** + * set类型 获取所有的成员 + * + * @param key + * @return + */ + public Set smembers(String key) { + Jedis jedis = jedisPool.getResource(); + Set result = null; + try { + result = jedis.smembers(key); + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + return result; + } + + /** + * 根据主键查询对象 + * + * @param key + * @param clazz + * @param + * @return + */ + public T getByPrimaryKey(String key, Class clazz) { + long start = System.currentTimeMillis(); + ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; + T result = null; + Map map = hgetAll(key); + if (map != null) { + result = JSONObject.parseObject(JSONObject.toJSONString(map), clazz); + } + long end = System.currentTimeMillis(); + System.out.println("============= getByPrimaryKey ======== 耗时:" + (end -start)); + return result; + } + + /** + * 根据外键查询对应的集合 + * + * @param key + * @param clazz + * @param + * @return + */ + public List getByForeignKey(String key, Class clazz) { + long start = System.currentTimeMillis(); + ParserConfig.getGlobalInstance().propertyNamingStrategy = PropertyNamingStrategy.SnakeCase; + List result = null; + Set members = smembers(key); + if (members != null) { + result = hgetAllBatchByPrimaryKeys(new ArrayList<>(members), clazz); + } + long end = System.currentTimeMillis(); + System.out.println("============= getByForeignKey ======== 耗时:" + (end -start)); + return result; + } + + /** + * pipeline批量获取hash数据 + * + * @param keys 主键列表 + * @param clazz + * @param + * @return + */ + public List hgetAllBatchByPrimaryKeys(List keys, Class clazz) { + long start = System.currentTimeMillis(); + Jedis jedis = jedisPool.getResource(); + List result = null; + try { + Pipeline pipelined = jedis.pipelined(); + for (String key : keys) { + pipelined.hgetAll(key); + } + // 阻塞拿到所有返回信息 + List objectList = pipelined.syncAndReturnAll(); + + for (Object object : objectList) { + if (result == null) { + result = new ArrayList<>(); + } + result.add(JSONObject.parseObject(JSONObject.toJSONString(object), clazz)); + } + } catch (Exception e) { + //释放redis对象 + jedisPool.returnBrokenResource(jedis); + e.printStackTrace(); + } finally { + //返还到连接池 + if (jedis != null) { + jedisPool.returnResource(jedis); + } + } + long end = System.currentTimeMillis(); + System.out.println("============= hgetAllBatchByPrimaryKeys ======== 耗时:" + (end -start)); + return result; + } + + /** + * pipeline批量获取hash数据 + * @param keys 外键列表 + * @param clazz + * @param + * @return + */ + public List hgetAllBatchByForeignKeys(List keys, Class clazz) { + long start = System.currentTimeMillis(); + List result = null; + for (String key : keys) { + List keyResult = getByForeignKey(key, clazz); + if(keyResult == null){ + continue; + } + if (result == null) { + result = new ArrayList<>(); + } + result.addAll(keyResult); + } + long end = System.currentTimeMillis(); + System.out.println("============= hgetAllBatchByForeignKeys ======== 耗时:" + (end -start)); + return result; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisPipeline.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisPipeline.java new file mode 100644 index 0000000..3bf52b3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisPipeline.java @@ -0,0 +1,46 @@ +//package com.baoying.enginex.executor.redis; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.dao.DataAccessException; +//import org.springframework.data.redis.connection.RedisConnection; +//import org.springframework.data.redis.core.RedisCallback; +//import org.springframework.data.redis.core.RedisOperations; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.data.redis.core.SessionCallback; +//import org.springframework.stereotype.Component; +// +//import java.util.List; +// +//@Component +//public class RedisPipeline { +// +// @Autowired +// private RedisTemplate redisTemplate; +// +// public List hGetAllBatch(List keys) { +// List list = redisTemplate.executePipelined(new RedisCallback() { +// @Override +// public Object doInRedis(RedisConnection redisConnection) throws DataAccessException { +// for(String key : keys){ +// redisConnection.hGetAll(key.getBytes()); +// } +// return null; +// } +// }); +// return list; +// } +// +// public List usePipeline(List keys) { +// List list = redisTemplate.executePipelined(new SessionCallback() { +// @Override +// public Object execute(RedisOperations redisOperations) throws DataAccessException { +// for(String key : keys){ +// redisOperations.opsForHash().entries(null); +// } +// return null; +// } +// }); +// return list; +// } +// +//} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisUtils.java new file mode 100644 index 0000000..0354020 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/redis/RedisUtils.java @@ -0,0 +1,49 @@ +package com.baoying.enginex.executor.redis; + +import com.baoying.enginex.executor.canal.TableEnum; + +import java.util.List; +import java.util.stream.Collectors; + +public class RedisUtils { + + /** + * 获取主键redis key + * @param tableName + * @param primaryId + * @return + */ + public static String getPrimaryKey(String tableName, Object primaryId){ + String key = "primary_key" + ":" + tableName + ":" + primaryId; + return key; + } + + public static String getPrimaryKey(TableEnum tableEnum, Object primaryId){ + return getPrimaryKey(tableEnum.getTableName(), primaryId); + } + + public static List getPrimaryKey(TableEnum tableEnum, List primaryIds){ + List keys = primaryIds.stream().map(item -> getPrimaryKey(tableEnum, item)).collect(Collectors.toList()); + return keys; + } + + /** + * 获取外键redis key + * @param tableName + * @param foreignId + * @return + */ + public static String getForeignKey(String tableName, Object foreignId){ + String key = "foreign_key" + ":" + tableName + ":" + foreignId; + return key; + } + + public static String getForeignKey(TableEnum tableEnum, Object foreignId){ + return getForeignKey(tableEnum.getTableName(), foreignId); + } + + public static List getForeignKey(TableEnum tableEnum, List foreignIds){ + List keys = foreignIds.stream().map(item -> getForeignKey(tableEnum, item)).collect(Collectors.toList()); + return keys; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConditionConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConditionConst.java new file mode 100644 index 0000000..7960f1e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConditionConst.java @@ -0,0 +1,12 @@ +package com.baoying.enginex.executor.rule.consts; + +public class RuleConditionConst { + + public static final long DEFAULT_CONDITION_PARENT_ID = 0;//根节点父ID + + public static final String LOOP_RULE_LOGICAL = "for";//循环规则的逻辑符号 + public static final int LOOP_RULE_RESULT_CONDITION = 4;//循环规则的结果条件 + + public static final String CONDITION_GROUP_LOGICAL = "condGroup";//条件组的逻辑符号 + public static final int CONDITION_GROUP_RESULT_CONDITION = 6;//条件组的结果条件 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConst.java new file mode 100644 index 0000000..177144a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleConst.java @@ -0,0 +1,28 @@ +package com.baoying.enginex.executor.rule.consts; + +public class RuleConst { + + public static final int CONST_TYPE = 1;//常量 + public static final int VARIABLE_TYPE = 2;//变量 + + public static final int RELATION_CONDITION = 1;//关系节点表示&&或者|| + public static final int EXPRESSION_CONDITION = 2;//表达式条件 + public static final int LOOP_CONDITION = 3;//循环条件 + public static final int LOOP_RESULT_CONDITION = 4;//循环规则条件 + public static final int CONDITION_GROUP_CONDITION = 5;//条件组节点 + public static final int CONDITION_RESULT_CONDITION = 6;//条件组节点 + + + public static final int LOOP_GROUP_ACTION_TYPE_SUM = 1;//循环中求和 + public static final int LOOP_GROUP_ACTION_TYPE_ASSIGNMENT = 2;//赋值 + + public static final int LOOP_GROUP_ACTION_TYPE_OUT_VARIABLE = 3;//输出变量 + public static final int LOOP_GROUP_ACTION_TYPE_OUT_CONST = 4;//输出常量 + + public static class ScriptType { + public static final String GROOVY = "groovy"; + public static final String PYTHON = "python"; + public static final String JAVASCRIPT = "js"; + + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleRunnerConst.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleRunnerConst.java new file mode 100644 index 0000000..89f54f5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/consts/RuleRunnerConst.java @@ -0,0 +1,86 @@ +package com.baoying.enginex.executor.rule.consts; + +import java.util.Map; + +public class RuleRunnerConst { + public static final String RULE_FILE_HEAD = " package com.baoying.enginex.executor.drools \\r\\n" + + " import java.util.Map;\\r\\n" + + " import java.util.List;\\r\\n" + + " import java.util.ArrayList;\\r\\n" + + " import java.util.HashMap;\\r\\n" + + " import com.baoying.enginex.executor.engine.model.InputParam;\\r\\n" + + " import com.baoying.enginex.executor.engine.model.Result;\\r\\n" + + " import com.baoying.enginex.executor.engine.model.EngineRule;\\r\\n"; + public static final String RULE_NAME_PREFIX = " rule \t"; + public static final String RULE_SALIENCE_PREFIX = "\\r\\n salience\\t "; + public static final String RULE_CONDITION_PREFIX = "\\r\\n when \\r\\n"; + public static final String CONDITION_DETAIL_PREFIX = "\\t $inputParam : InputParam();\\r\\n Map"; + public static final String CONDITION_DETAIL_SUFFIX = " \t from $inputParam.inputParam;\\r\\n"; + public static final String RULE_DISPOSE_PREFIX = "\\t then \\r\\n"; + public static final String DISPOSE_PREFIX = + "\\t List resultList =$inputParam.getResult();\\r\\n" + + "\\t Result result =new Result(); \\r\\n" + + "\\t result.setResultType(\""; + public static final String DISPOSE_INFIX = "\"); \\r\\n" + + "\\t result.setVersionCode(\""; + public static final String DISPOSE_SUFFIX = "\"); \\r\\n" + + "\\t Map map =new HashMap<>(); \\r\\n"; + + public static final String SCORE_PREFIX = "\\t map.put(\"score\","; + public static final String SCORE_SUFFIX = "); \\r\\n"; + + public static final String RULE_END = "\\t result.setMap(map); \\r\\n" + + " resultList.add(result); \\r\\n" + + "\\t $inputParam.setResult(resultList); \\r\\n" + + " end\\r\\n"; + + public static final int DEFAULT_TYPE = 1; + + //拼装规则执行的content + public static String fitRuleContent(String code, Integer salience, String rule, Integer type, Integer score, Map contentMap) { + String content = ""; + if (salience == null || salience < 0) { + salience = 0; + } + if (type == null) { + type = DEFAULT_TYPE; + } + content += RULE_FILE_HEAD + + RULE_NAME_PREFIX + code + + RULE_SALIENCE_PREFIX + salience + + RULE_CONDITION_PREFIX + + CONDITION_DETAIL_PREFIX + rule + + CONDITION_DETAIL_SUFFIX + + RULE_DISPOSE_PREFIX + + DISPOSE_PREFIX + type + + DISPOSE_INFIX + code+ + DISPOSE_SUFFIX; + if (score!=null){ + content += SCORE_PREFIX+score+SCORE_SUFFIX; + } + + if (contentMap!=null&&!contentMap.isEmpty()){ + for (String s : contentMap.keySet()) { + content+="\\t\\t map.put(\""+s+"\",\""+contentMap.get(s)+"\");\\n"; + } + + } + content += RULE_END; + + return content; + } + +// public static void main(String[] args) { +// String versionCode = "rule1"; +// Integer salience = null; +// String rule = "age>10"; +// Integer type = null; +// Integer score = 10; +// Map contentMap = new HashMap<>(); +// contentMap.put("a","a"); +// contentMap.put("b","b"); +// contentMap.put("c","c"); +// String s = fitContent(versionCode, salience, rule, type, score,contentMap); +// System.out.println(s); +// } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleConditionInfoMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleConditionInfoMapper.java new file mode 100644 index 0000000..3504c81 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleConditionInfoMapper.java @@ -0,0 +1,14 @@ +package com.baoying.enginex.executor.rule.mapper; + + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleConditionInfo; +import org.apache.ibatis.annotations.Mapper; + + +@Mapper +public interface RuleConditionInfoMapper extends BaseMapper { + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.java new file mode 100644 index 0000000..fe19561 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.java @@ -0,0 +1,14 @@ +package com.baoying.enginex.executor.rule.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleFieldInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface RuleFieldInfoMapper extends BaseMapper { + + List getFieldEnList(@Param("ruleIds") List ruleIds); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.xml new file mode 100644 index 0000000..2f96e06 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleFieldInfoMapper.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.java new file mode 100644 index 0000000..ad4ffbe --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.java @@ -0,0 +1,16 @@ +package com.baoying.enginex.executor.rule.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + +@Mapper +public interface RuleInfoMapper extends BaseMapper { + + List getRuleList(@Param("ruleIds")List ruleIds); +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.xml new file mode 100644 index 0000000..2ad03d9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleInfoMapper.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, name, code, description, priority, parent_id, author, user_id, organ_id, engine_id, status, type, is_non, content, created, updated, rule_type, rule_audit, score, score_field_en, last_logical,difficulty,script_type,result_field_en + + + + + + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleLoopGroupActionMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleLoopGroupActionMapper.java new file mode 100644 index 0000000..411fcda --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleLoopGroupActionMapper.java @@ -0,0 +1,9 @@ +package com.baoying.enginex.executor.rule.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; + +public interface RuleLoopGroupActionMapper extends BaseMapper { + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleScriptVersionMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleScriptVersionMapper.java new file mode 100644 index 0000000..e6fdaa9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleScriptVersionMapper.java @@ -0,0 +1,15 @@ +package com.baoying.enginex.executor.rule.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; +import org.apache.ibatis.annotations.Mapper; + + +@Mapper +public interface RuleScriptVersionMapper extends BaseMapper { + + + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleVersionMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleVersionMapper.java new file mode 100644 index 0000000..a77463b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/mapper/RuleVersionMapper.java @@ -0,0 +1,9 @@ +package com.baoying.enginex.executor.rule.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.rule.model.RuleVersion; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface RuleVersionMapper extends BaseMapper { +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleConditionInfo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleConditionInfo.java new file mode 100644 index 0000000..5796e03 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleConditionInfo.java @@ -0,0 +1,66 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baoying.enginex.executor.rule.model.vo.RuleConditionVo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors +@TableName("`t_rule_condition`") +public class RuleConditionInfo + implements Serializable { + private static final long serialVersionUID = -55937038829167862L; + + @TableId(type = IdType.AUTO) + private Long id;//主键ID + + private String logical;//关系节点的逻辑符号:&&(并关系),||(或关系) + + private Long fieldId;//表达式节点对应的字段id + private String fieldEn;//字段en + private String fieldType;//字段的类型:1中间变量 2 入参 + private String operator;//表达式节点的操作符 + private Integer variableType;//变量类型,1常量 2变量 + private String fieldValue;//表达式节点对应字段的限定值 + private String executionLogic;//执行逻辑 + private Long ruleId;//规则表的id + private Long versionId;//规则版本id + private Long parentId;//父节点的id + + private Integer conditionType;//规则节点的类型:1-关系节点,2-表达式节点 + + private Date createTime;//创建时间 + + private Date updateTime;//修改时间 + + @TableField(exist = false) + private String insertTempId;//插入时临时id + + @TableField(exist = false) + private String TempParentId;//插入时临时父id + + @TableField(exist = false) + private Integer valueType;//字段值类型 + + @TableField(exist = false) + private List loopGroupActions = new ArrayList<>();//循环组对应的条件 + + @TableField(exist = false) + private RuleConditionVo loopResultCondition;//for对应的结果条件的计算条件树 + @TableField(exist = false) + private RuleConditionVo condGroupResultCondition;//条件组对应的结果计算条件树 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleFieldInfo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleFieldInfo.java new file mode 100644 index 0000000..f98a773 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleFieldInfo.java @@ -0,0 +1,38 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_rule_field") +public class RuleFieldInfo implements Serializable { + private static final long serialVersionUID = -132321133324148507L; + @TableId(type = IdType.AUTO) + private Long id; + + private String logical;//逻辑运算符 + + private String operator;//运算符 + + private String fieldValue;//字段值 + + private Long ruleId;//关联的规则的id + + private String fieldId;//关联的字段的id + @TableField(exist = false) + private String fieldEn;//关联的字段的英文名称 + @TableField(exist = false) + private String field;//字段内容 + @TableField(exist = false) + private Integer valueType;//关联的字段的值类型 + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleInfo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleInfo.java new file mode 100644 index 0000000..a6a9923 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleInfo.java @@ -0,0 +1,86 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baoying.enginex.executor.rule.model.vo.RuleVersionVo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors +@TableName("t_rule") +public class RuleInfo implements Serializable { + private static final long serialVersionUID = -13354133324148507L; + @TableId(type = IdType.AUTO) + private Long id;//主键 + + private String name;//规则名称 + + private String code;//规则代码 + + private String description;//规则描述 + + private Integer priority;//规则优先级 + + private Long parentId;//父节点id + + private Long author;//创建人id + + private Long userId;//修改人id + + private Long organId;//组织id + + private Integer engineId; + + private Integer status;//状态 0 :停用 ,1 : 启用,-1:删除 + + private Integer type;//规则类型 0 : 系统的规则 1:组织的规则 2: 引擎的规则 + + private Integer isNon;//逻辑关系“非”,0:否 ,1:是 + + private String content;//规则具体内容 + + private Date created; + + private Date updated; + + private Integer ruleType;//0硬性拒绝规则1加减分规则 + + private Integer ruleAudit; + + private Integer score;//得分 + + private String lastLogical;//逻辑关系符 + + private Integer difficulty;//规则难度:1-简单规则,2复杂规则 + + private String scriptType; + + private String resultFieldEn;//存放结果的字段en + + private String scoreFieldEn;//存放是否命中的字段 + + @TableField(exist = false) + private String authorName;//创建人名称,需要去其他表查询 + @TableField(exist = false) + private List parentIds; + @TableField(exist = false) + private Long versionId;//执行版本的id + @TableField(exist = false) + private RuleVersionVo version; + @TableField(exist = false) + private List ruleScriptVersionList; + @TableField(exist = false) + private RuleScriptVersion scriptVersion; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleLoopGroupAction.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleLoopGroupAction.java new file mode 100644 index 0000000..0136dc6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleLoopGroupAction.java @@ -0,0 +1,55 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_rule_loop_group_action") +public class RuleLoopGroupAction implements Serializable { + private static final long serialVersionUID = -47370055295043749L; + /** + * 循环组动作表主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 对应条件表中for的id + */ + private Long conditionForId; + /** + * 对应条件表中条件id + */ + private Long conditionGroupId; + /** + * 动作类型 1-求和,2-赋值,3-输出输出变量,4-输出常量 + */ + private Integer actionType; + /** + * 动作的key + */ + private String actionKey; + /** + * 动作的value + */ + private String actionValue; + /** + * 创建时间 + */ + private Date createTime; + /** + * 修改时间 + */ + private Date updateTime; + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleScriptVersion.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleScriptVersion.java new file mode 100644 index 0000000..f0e9393 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleScriptVersion.java @@ -0,0 +1,74 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("`t_rule_script_version`") +public class RuleScriptVersion implements Serializable { + private static final long serialVersionUID = -78864192587533951L; + /** + * 主键:规则版本id + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 规则id + */ + private Long ruleId; + /** + * 版本号 + */ + private String versionCode; + /** + * 版本描述 + */ + private String description; + /** + * 状态:-1删除 ,1启用,0停用 + */ + private Integer status; + /** + * 脚本类型:groovy,python,js + */ + private String scriptType; + /** + * 脚本规则集内容json,包含脚本内容和脚本所用字段两个值 + */ + private String scriptContent; + /** + * 组织id + */ + private Long organId; + /** + * 创建者id + */ + private Long createUserId; + /** + * 修改者id + */ + private Long updateUserId; + /** + * 创建时间 + */ + private Date createTime; + /** + * 修改时间 + */ + private Date updateTime; + /** + * 规则版本配置快照 + */ + private String snapshot; + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleVersion.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleVersion.java new file mode 100644 index 0000000..50651a0 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/RuleVersion.java @@ -0,0 +1,76 @@ +package com.baoying.enginex.executor.rule.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("`t_rule_version`") +public class RuleVersion implements Serializable { + private static final long serialVersionUID = -1850194333747447612L; + /** + * 规则版本主键id + */ + @TableId( type = IdType.AUTO) + private Long id; + /** + * 规则id + */ + private Long ruleId; + /** + * 规则版本号 + */ + private String versionCode; + /** + * 描述信息 + */ + private String description; + /** + * 状态:-1 删除 0停用 1启用 + */ + private Integer status; + /** + * 规则结果en(命中情况) + */ + private String resultFieldEn; + /** + * 规则得分 + */ + private Integer score; + /** + * 规则得分的en + */ + private String scoreFieldEn; + /** + * 组织id + */ + private Long organId; + /** + * 创建者id + */ + private Long createUserId; + /** + * 修改者id + */ + private Long updateUserId; + /** + * 创建时间 + */ + private Date createTime; + /** + * 修改时间 + */ + private Date updateTime; + /** + * 规则版本快照 + */ + private String snapshot; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleConditionVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleConditionVo.java new file mode 100644 index 0000000..ebcde12 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleConditionVo.java @@ -0,0 +1,56 @@ +package com.baoying.enginex.executor.rule.model.vo; + + +import com.baoying.enginex.executor.rule.model.RuleConditionInfo; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors +public class RuleConditionVo extends RuleConditionInfo { + +// private Long id;//主键ID +// +// private String logical;//关系节点的逻辑符号:&&(并关系),||(或关系) +// +// private Long fieldId;//表达式节点对应的字段id +// +// private String fieldEn;//字段en +// private String fieldType;//字段的类型:1中间变量 2 入参 +// private String operator;//表达式节点的操作符 +// private Integer variableType;//变量类型,1常量 2变量 +// private String fieldValue;//表达式节点对应字段的限定值 +// private String executionLogic;//执行逻辑 +// private Long ruleId;//规则表的id +// +// private Long parentId;//父节点的id +// +// private Integer conditionType;//规则节点的类型:1-关系节点,2-表达式节点 +// +// private Date createTime;//创建时间 +// +// private Date updateTime;//修改时间 +// +// private String insertTempId;//插入时临时id +// +// private String TempParentId;//插入时临时父id + + private List children;//规则子节点 + +// private Integer valueType;//字段类型 +// +// private List loopGroupActions = new ArrayList<>();//循环组对应的条件,循环内的组条件下的操作列表 +// +// private RuleConditionVo loopResultCondition;//for对应的结果条件的计算条件树 +// +// private RuleConditionVo condGroupResultCondition;//条件组对应的结果计算条件树 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVersionVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVersionVo.java new file mode 100644 index 0000000..8661bec --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVersionVo.java @@ -0,0 +1,19 @@ +package com.baoying.enginex.executor.rule.model.vo; + + +import com.baoying.enginex.executor.rule.model.RuleVersion; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class RuleVersionVo extends RuleVersion { + private RuleConditionVo ruleConditionVo;//规则对应的结点树 + + private List tacticsOutputList;//成功输出字段 + private List failOutputList;//失败输出字段 +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVo.java new file mode 100644 index 0000000..85805a4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/model/vo/RuleVo.java @@ -0,0 +1,29 @@ +package com.baoying.enginex.executor.rule.model.vo; + + +import com.baoying.enginex.executor.rule.model.RuleFieldInfo; +import com.baoying.enginex.executor.rule.model.RuleInfo; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors +public class RuleVo extends RuleInfo { + + private RuleConditionVo ruleConditionVo;//规则对应的结点树 + + + private List ruleFieldList;//简单规则条件列表 + + private List tacticsOutputList;//输出字段 + + private List ruleVersionList;//版本列表 + private List ruleScriptVersionList; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleConditionService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleConditionService.java new file mode 100644 index 0000000..0bc281d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleConditionService.java @@ -0,0 +1,15 @@ +package com.baoying.enginex.executor.rule.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleConditionInfo; +import com.baoying.enginex.executor.rule.model.vo.RuleConditionVo; + +import java.util.List; + + +public interface RuleConditionService extends IService { + + RuleConditionVo queryByVersionId(Long versionId); + + List queryFieldEnByVersionIds(List versionIds); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleFieldInfoService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleFieldInfoService.java new file mode 100644 index 0000000..014a3b8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleFieldInfoService.java @@ -0,0 +1,13 @@ +package com.baoying.enginex.executor.rule.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleFieldInfo; + +import java.util.List; + +public interface RuleFieldInfoService extends IService { + + List queryByRuleId(Long ruleId); + + List getFieldEnList(List ruleIds); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleLoopGroupActionService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleLoopGroupActionService.java new file mode 100644 index 0000000..cd94ef0 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleLoopGroupActionService.java @@ -0,0 +1,14 @@ +package com.baoying.enginex.executor.rule.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; + +import java.util.List; + + +public interface RuleLoopGroupActionService extends IService { + + List getRuleLoopList(Long forId, Long conditionId); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleScriptVersionService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleScriptVersionService.java new file mode 100644 index 0000000..3012fc8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleScriptVersionService.java @@ -0,0 +1,19 @@ +package com.baoying.enginex.executor.rule.service; + + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; + +import java.util.List; + + +public interface RuleScriptVersionService extends IService { + RuleScriptVersion queryById(Long id); + + List queryVersionListByRuleId(Long ruleId); + + List queryFieldEnByVersionId(Long versionId); + List queryFieldEnByVersionIds(List versionId); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleService.java new file mode 100644 index 0000000..6a75acd --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleService.java @@ -0,0 +1,28 @@ +package com.baoying.enginex.executor.rule.service; + + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleInfo; +import com.baoying.enginex.executor.rule.model.vo.RuleVo; + + +import java.util.List; +import java.util.Map; + +public interface RuleService extends IService { + + /** + * 通过ID查询单条数据 + * @param id 主键 + * @return 实例对象 + */ + RuleVo queryById(Long id); + + List setComplexRuleOutput(Long versionId, Map temp, Map input, String outType); + + List setBaseRuleOutput(Long ruleId, Map input); + + List getRuleList(List ruleIds); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleVersionService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleVersionService.java new file mode 100644 index 0000000..be7aacc --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/RuleVersionService.java @@ -0,0 +1,14 @@ +package com.baoying.enginex.executor.rule.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.rule.model.RuleVersion; +import com.baoying.enginex.executor.rule.model.vo.RuleVersionVo; + +import java.util.List; + +public interface RuleVersionService extends IService { + + RuleVersionVo queryById(Long id); + + List queryVersionListByRuleId(Long ruleId); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleConditionServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleConditionServiceImpl.java new file mode 100644 index 0000000..7104395 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleConditionServiceImpl.java @@ -0,0 +1,158 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.rule.consts.RuleConditionConst; +import com.baoying.enginex.executor.rule.mapper.RuleConditionInfoMapper; +import com.baoying.enginex.executor.rule.model.RuleConditionInfo; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; +import com.baoying.enginex.executor.rule.model.vo.RuleConditionVo; +import com.baoying.enginex.executor.rule.service.RuleConditionService; +import com.baoying.enginex.executor.rule.service.RuleLoopGroupActionService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + + +@Service("ruleConditionService2") +public class RuleConditionServiceImpl extends ServiceImpl implements RuleConditionService { + + @Resource + private RuleConditionInfoMapper ruleConditionInfoMapper; + @Resource + private RuleLoopGroupActionService loopGroupActionService; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public RuleConditionVo queryByVersionId(Long versionId) { + if (versionId == null) { + return null; + } + //构造查询条件,查询条件列表 + RuleConditionVo result = null; + + List ruleConditionInfoList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getForeignKey(TableEnum.T_RULE_CONDITION, versionId); + ruleConditionInfoList = redisManager.getByForeignKey(key, RuleConditionInfo.class); + } else { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(RuleConditionInfo::getVersionId, versionId); + ruleConditionInfoList = ruleConditionInfoMapper.selectList(queryWrapper); + } + + //组装为需要的树形结构 + if (ruleConditionInfoList != null) { + result = this.assemble(ruleConditionInfoList); + } + return result; + } + + @Override + public List queryFieldEnByVersionIds(List versionIds) { + List ruleConditions = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + List keys = RedisUtils.getForeignKey(TableEnum.T_RULE_CONDITION, versionIds); + ruleConditions = redisManager.hgetAllBatchByForeignKeys(keys, RuleConditionInfo.class); + + ruleConditions = ruleConditions.stream() + .filter(item -> StringUtils.isNotBlank(item.getFieldEn()) && !"1".equals(item.getFieldType())) + .collect(Collectors.toList()); + + } else { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(RuleConditionInfo::getVersionId,versionIds); + queryWrapper.isNotNull(RuleConditionInfo::getFieldEn); + queryWrapper.ne(RuleConditionInfo::getFieldType,1); + queryWrapper.select(RuleConditionInfo::getFieldEn); + ruleConditions = ruleConditionInfoMapper.selectList(queryWrapper); + } + + List result = new ArrayList<>(); + if (ruleConditions != null){ + for (RuleConditionInfo condition : ruleConditions) { + result.add(condition.getFieldEn()); + } + } + return result; + } + + //装配方法,将规则条件List装配成一个规则树并返回 + public RuleConditionVo assemble(List list) { + RuleConditionVo root = null; + //转换为Vo + List rcVoList = transferToVoList(list); + //获取根节点,根节点只有一个的时候进行操作,并且返回拼装好的规则树,否则返回null + List collect = rcVoList.stream().filter(rc -> { + return rc.getParentId() == RuleConditionConst.DEFAULT_CONDITION_PARENT_ID; + }).collect(Collectors.toList()); + if (collect.size() == 1) { + root = collect.get(0); + RuleConditionVo ruleTree = coupling(rcVoList, root); + return ruleTree; + } + return null; + } + + //耦合方法:将规则节点列表耦合规则树(),循环规则的子节点需要去查循环表获取 + private RuleConditionVo coupling(List list, RuleConditionVo root) { + List children = new ArrayList<>(); + for (RuleConditionVo rc : list) { + //处理root的子节点 + if (root.getId().equals(rc.getParentId())) { + RuleConditionVo rcVo = coupling(list, rc); + String logical = root.getLogical(); + + if (logical!=null&&!"".equals(logical)){ + switch (logical){ + //当root为for节点,则此子节点需要拼上循环动作 + case RuleConditionConst.LOOP_RULE_LOGICAL: + List loopList = loopGroupActionService.getRuleLoopList(root.getId(),rc.getId()); + rcVo.setLoopGroupActions(loopList); + if (rc.getConditionType()==RuleConditionConst.LOOP_RULE_RESULT_CONDITION){ + root.setLoopResultCondition(rcVo); + continue; + } + break; + //当root为条件组节点,则此子节点需要拼上条件组结果 + case RuleConditionConst.CONDITION_GROUP_LOGICAL: + if (rc.getConditionType()==RuleConditionConst.CONDITION_GROUP_RESULT_CONDITION){ + root.setCondGroupResultCondition(rcVo); + continue; + } + break; + } + + } + children.add(rcVo); + } + } + root.setChildren(children); + return root; + } + + //List转换为List + private List transferToVoList(List list) { + List rcVoList = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + RuleConditionVo rcVo = new RuleConditionVo(); + BeanUtils.copyProperties(list.get(i), rcVo); + rcVoList.add(rcVo); + } + return rcVoList; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleFieldInfoServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleFieldInfoServiceImpl.java new file mode 100644 index 0000000..2ee9479 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleFieldInfoServiceImpl.java @@ -0,0 +1,58 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.rule.mapper.RuleFieldInfoMapper; +import com.baoying.enginex.executor.rule.model.RuleFieldInfo; +import com.baoying.enginex.executor.rule.service.RuleFieldInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class RuleFieldInfoServiceImpl extends ServiceImpl implements RuleFieldInfoService { + + @Resource + private RuleFieldInfoMapper ruleFieldInfoMapper; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public List queryByRuleId(Long ruleId) { + RuleFieldInfo ruleFieldInfo = new RuleFieldInfo(); + ruleFieldInfo.setRuleId(ruleId); + List ruleFieldInfoList = ruleFieldInfoMapper.selectList(new QueryWrapper<>(ruleFieldInfo)); + return ruleFieldInfoList; + } + + @Override + public List getFieldEnList(List ruleIds) { + List list = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + List keys = RedisUtils.getForeignKey(TableEnum.T_RULE_FIELD, ruleIds); + List ruleFieldInfos = redisManager.hgetAllBatchByForeignKeys(keys, RuleFieldInfo.class); + Set set = ruleFieldInfos.stream().map(item -> { + String[] fieldIdArr = item.getFieldId().split("\\|"); // 587|f_hr_age + return fieldIdArr[1]; + }).collect(Collectors.toSet()); + + list = new ArrayList<>(set); + } else { + list = ruleFieldInfoMapper.getFieldEnList(ruleIds); + } + return list; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleLoopGroupActionServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleLoopGroupActionServiceImpl.java new file mode 100644 index 0000000..da28c09 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleLoopGroupActionServiceImpl.java @@ -0,0 +1,50 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.rule.mapper.RuleLoopGroupActionMapper; +import com.baoying.enginex.executor.rule.model.RuleLoopGroupAction; +import com.baoying.enginex.executor.rule.service.RuleLoopGroupActionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + + +@Service("ruleLoopGroupActionService") +public class RuleLoopGroupActionServiceImpl extends ServiceImpl implements RuleLoopGroupActionService { + @Resource + private RuleLoopGroupActionMapper ruleLoopGroupActionMapper; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public List getRuleLoopList(Long forId, Long conditionId) { + List loopList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getForeignKey(TableEnum.T_RULE_LOOP_GROUP_ACTION, forId); + loopList = redisManager.getByForeignKey(key, RuleLoopGroupAction.class); + loopList = loopList.stream().filter(item -> item.getConditionGroupId().equals(conditionId)).collect(Collectors.toList()); + } else { + RuleLoopGroupAction ruleLoopGroupAction = new RuleLoopGroupAction(); + ruleLoopGroupAction.setConditionForId(forId); + ruleLoopGroupAction.setConditionGroupId(conditionId); + loopList = ruleLoopGroupActionMapper.selectList(new QueryWrapper<>(ruleLoopGroupAction)); + } + + if (loopList==null){ + loopList = new ArrayList<>(); + } + return loopList; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleScriptVersionServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleScriptVersionServiceImpl.java new file mode 100644 index 0000000..bca56a4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleScriptVersionServiceImpl.java @@ -0,0 +1,90 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.baoying.enginex.executor.datamanage.model.Field; +import com.baoying.enginex.executor.rule.mapper.RuleScriptVersionMapper; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; +import com.baoying.enginex.executor.rule.service.RuleScriptVersionService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + + +@Service("ruleScriptVersionService") +public class RuleScriptVersionServiceImpl extends ServiceImpl implements RuleScriptVersionService { + @Resource + private RuleScriptVersionMapper ruleScriptVersionMapper; + @Autowired + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + @Override + public RuleScriptVersion queryById(Long id) { + if (id!=null){ + return this.getById(id); + } + return null; + } + + @Override + public List queryVersionListByRuleId(Long ruleId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(RuleScriptVersion::getRuleId,ruleId); + wrapper.eq(RuleScriptVersion::getStatus,1); + wrapper.orderByDesc(RuleScriptVersion::getId); + List list = this.list(wrapper); + return list; + } + + @Override + public List queryFieldEnByVersionId(Long versionId) { + + RuleScriptVersion ruleScriptVersion = this.queryById(versionId); + Set fieldEnSet = new HashSet<>(); + if (ruleScriptVersion==null){ + return new ArrayList<>(); + } + collectFieldEn(ruleScriptVersion,fieldEnSet); + return new ArrayList<>(fieldEnSet); + } + + @Override + public List queryFieldEnByVersionIds(List versionIds) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(RuleScriptVersion::getId,versionIds); + List list = this.list(wrapper); + Set fieldEnSet = new HashSet<>(); + if (list!=null&&!list.isEmpty()){ + for (RuleScriptVersion ruleScriptVersion : list) { + collectFieldEn(ruleScriptVersion,fieldEnSet); + } + } + return new ArrayList<>(fieldEnSet); + } + private void collectFieldEn(RuleScriptVersion ruleScriptVersion,Set fieldEnSet){ + String scriptContent = ruleScriptVersion.getScriptContent(); + if (StringUtils.isNotBlank(scriptContent)){ + JSONObject jsonObject = JSON.parseObject(scriptContent); + Object farr = jsonObject.get("farr"); + if (farr!=null&&!"".equals(farr)){ + List fieldList = JSONArray.parseArray(JSON.toJSONString(farr), Field.class); + fieldEnSet.addAll(fieldList.stream().map(item->{return item.getFieldEn();}).collect(Collectors.toSet())); + } + } + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleServiceImpl.java new file mode 100644 index 0000000..911e78d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleServiceImpl.java @@ -0,0 +1,107 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.rule.mapper.RuleInfoMapper; + +import com.baoying.enginex.executor.rule.model.RuleFieldInfo; +import com.baoying.enginex.executor.rule.model.RuleInfo; +import com.baoying.enginex.executor.rule.model.RuleScriptVersion; +import com.baoying.enginex.executor.rule.model.vo.RuleVersionVo; +import com.baoying.enginex.executor.rule.model.vo.RuleVo; +import com.baoying.enginex.executor.rule.service.RuleFieldInfoService; +import com.baoying.enginex.executor.rule.service.RuleScriptVersionService; +import com.baoying.enginex.executor.rule.service.RuleService; +import com.baoying.enginex.executor.rule.service.RuleVersionService; +import com.baoying.enginex.executor.tactics.consts.TacticsType; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import com.baoying.enginex.executor.tactics.service.TacticsOutputService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; + + +@Service("ruleService2") +public class RuleServiceImpl extends ServiceImpl implements RuleService { + @Resource + private RuleInfoMapper ruleInfoMapper; + @Autowired + private RuleVersionService versionService; + @Resource + private RuleFieldInfoService ruleFieldInfoService; + @Resource + private TacticsOutputService outputService; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + @Resource + private RuleScriptVersionService ruleScriptVersionService; + + @Override + public RuleVo queryById(Long id) { + //查询规则 + RuleInfo ruleInfo = ruleInfoMapper.selectById(id); + if (ruleInfo==null){ + return null; + } + RuleVo ruleVo = new RuleVo(); + BeanUtils.copyProperties(ruleInfo, ruleVo); + Integer difficulty = ruleInfo.getDifficulty(); + switch (difficulty) { + case 1: + List list = ruleFieldInfoService.queryByRuleId(id); + List tacticsOutputList = outputService.queryByTactics(new TacticsOutput(id, TacticsType.BASE_RULE)); + ruleVo.setTacticsOutputList(tacticsOutputList); + ruleVo.setRuleFieldList(list); + break; + case 2: + //查询版本 + List ruleVersionList = versionService.queryVersionListByRuleId(id); + ruleVo.setRuleVersionList(ruleVersionList); + break; + case 3: + //脚本规则集 + List ruleScriptVersionList = ruleScriptVersionService.queryVersionListByRuleId(id); + ruleVo.setRuleScriptVersionList(ruleScriptVersionList); + break; + } + return ruleVo; + } + + @Override + public List setComplexRuleOutput(Long versionId, Map temp, Map input, String outType) { + List jsonObjectList = outputService.setOutput(new TacticsOutput(versionId, TacticsType.COMPLEX_RULE,outType), temp); + for (JSONObject jsonObject : jsonObjectList) { + input.putAll(jsonObject); + } + return jsonObjectList; + } + + @Override + public List setBaseRuleOutput(Long ruleId, Map input) { + List jsonObjectList = outputService.setOutput(new TacticsOutput(ruleId, TacticsType.BASE_RULE), input); + return jsonObjectList; + } + + @Override + public List getRuleList(List ruleIds) { + List ruleInfoList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + List keys = RedisUtils.getPrimaryKey(TableEnum.T_RULE, ruleIds); + ruleInfoList = redisManager.hgetAllBatchByPrimaryKeys(keys, RuleInfo.class); + } else { + ruleInfoList = ruleInfoMapper.getRuleList(ruleIds); + } + return ruleInfoList; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleVersionServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleVersionServiceImpl.java new file mode 100644 index 0000000..a6f65f5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/rule/service/impl/RuleVersionServiceImpl.java @@ -0,0 +1,84 @@ +package com.baoying.enginex.executor.rule.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.rule.mapper.RuleVersionMapper; +import com.baoying.enginex.executor.rule.model.RuleVersion; +import com.baoying.enginex.executor.rule.model.vo.RuleConditionVo; +import com.baoying.enginex.executor.rule.model.vo.RuleVersionVo; +import com.baoying.enginex.executor.rule.service.RuleConditionService; +import com.baoying.enginex.executor.rule.service.RuleVersionService; +import com.baoying.enginex.executor.tactics.consts.TacticsType; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import com.baoying.enginex.executor.tactics.service.TacticsOutputService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class RuleVersionServiceImpl extends ServiceImpl implements RuleVersionService { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + @Autowired + private RuleVersionMapper versionMapper; + @Autowired + private RuleConditionService conditionService; + @Autowired + private TacticsOutputService outputService; + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public RuleVersionVo queryById(Long id) { + RuleVersion ruleVersion = null; + if (Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())) { + String key = RedisUtils.getPrimaryKey(TableEnum.T_RULE_VERSION, id); + ruleVersion = redisManager.getByPrimaryKey(key, RuleVersion.class); + } else { + ruleVersion = versionMapper.selectById(id); + } + + RuleVersionVo result = new RuleVersionVo(); + if (ruleVersion == null) { + return result; + } + BeanUtils.copyProperties(ruleVersion, result); + //查询ruleCondition组装成树形结构 + RuleConditionVo ruleConditionVo = conditionService.queryByVersionId(id); + List tacticsOutputList = outputService.queryByTactics(new TacticsOutput(id, TacticsType.COMPLEX_RULE,TacticsType.OutType.SUCCESS_OUT)); + List failOutputList = outputService.queryByTactics(new TacticsOutput(id, TacticsType.COMPLEX_RULE,TacticsType.OutType.FAIL_OUT)); + result.setRuleConditionVo(ruleConditionVo); + result.setTacticsOutputList(tacticsOutputList); + result.setFailOutputList(failOutputList); + return result; + } + + @Override + public List queryVersionListByRuleId(Long ruleId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(RuleVersion::getRuleId,ruleId); + queryWrapper.eq(RuleVersion::getStatus,1); + queryWrapper.orderByDesc(RuleVersion::getUpdateTime); + List ruleVersionList = versionMapper.selectList(queryWrapper); + List ruleVersionVoList = new ArrayList<>(); + for (RuleVersion ruleVersion : ruleVersionList) { + RuleVersionVo versionVo = new RuleVersionVo(); + BeanUtils.copyProperties(ruleVersion,versionVo); + ruleVersionVoList.add(versionVo); + } + return ruleVersionVoList; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.java new file mode 100644 index 0000000..cadfb7c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.java @@ -0,0 +1,26 @@ + +package com.baoying.enginex.executor.system.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.system.model.Department; + + +public interface DepartmentMapper extends BaseMapper { + + /** + * isExist:(根据相应的条件判断是否存在重复值).
+ * @author wz + * @param departmentVo 部门实体类 + * @return 返回行数 + */ + Integer isExist(Department department); + + /** + * deleteDept:(根据部门ids删除部门信息).
+ * @author wz + * @param deletIds 部门ids + */ + void deleteDept(Long[] deletIds); +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.xml new file mode 100644 index 0000000..2199b8d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/DepartmentMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + INSERT INTO + manager_organization + + + org_name, + + + org_code, + + status, + updateTime + + values + + + #{deptName}, + + + #{deptCode}, + + 1, + now() + + + + + + + UPDATE manager_organization SET + + org_name = #{deptName} + + + ,org_code = #{deptCode} + + ,updateTime = now() + WHERE + status=1 + + and id = #{id} + + + + + UPDATE manager_organization SET + status=-1 + WHERE + id + IN + + #{deletIds} + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.java new file mode 100644 index 0000000..a2fa119 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.java @@ -0,0 +1,57 @@ + +package com.baoying.enginex.executor.system.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.system.model.Menu; + +import java.util.List; + + +public interface MenuMapper extends BaseMapper { + /** + * isExist:(根据相应的条件判断是否存在重复值).
+ * @author wz + * @param menu 菜单实体类 + * @return 返回行数 + */ + Integer isExist(Menu menu); + + /** + * deleteRole:(根据菜单ids删除菜单信息).
+ * @author wz + * @param deletIds 菜单ids + */ + void deleteMenu(Long[] deletIds); + + /** + * selectByRole:(根据角色查询).
+ * @author wz + * @param menu + * @return 查询的菜单类 + */ + List selectByRole(Menu menu); + + /** + * deleteMenuRole:(删除菜单角色关联表).
+ * @author wz + * @param menu 菜单实体类 + */ + void deleteMenuRole(Menu menu); + + /** + * insertMenuRole:(添加菜单角色关联表).
+ * @author wz + * @param menu 菜单实体类 + */ + void insertMenuRole(Menu menu); + + /** + * findUserMenuByUser:(根据登录用户名查询相应授权菜单列表).
+ * @author wz + * @param loginName + * @return 根据登录用户名查询相应授权菜单列表 + */ + List findUserMenuByUser(String loginName); +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.xml new file mode 100644 index 0000000..bf94775 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/MenuMapper.xml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO + manager_menu + + + pid, + + + name, + + + menu_code, + + + type, + + + url, + + + icon, + + status, + updateTime + + values + + + #{pid}, + + + #{name}, + + + #{menuCode}, + + + #{type}, + + + #{url}, + + + #{icon}, + + 1, + now() + + + + + + + UPDATE manager_menu SET + + pid = #{pid}, + + + name = #{name}, + + + type = #{type}, + + + url = #{url}, + + + icon = #{icon}, + + + name = #{name} + + + ,menu_code = #{menuCode} + + ,updateTime = now() + WHERE + status=1 + + and id = #{id} + + + + + UPDATE manager_menu SET + status=-1 + WHERE + id + IN + + #{deletIds} + + + + + DELETE FROM + manager_menu_role + WHERE + 1=1 + + and role_code = #{roleCode} + + + + + INSERT INTO + manager_menu_role + + + menu_id, + + + role_code + + + values + + + #{id}, + + + #{roleCode} + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.java new file mode 100644 index 0000000..9e07db8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.java @@ -0,0 +1,26 @@ + +package com.baoying.enginex.executor.system.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.system.model.Role; + + +public interface RoleMapper extends BaseMapper { + + /** + * isExist:(根据相应的条件判断是否存在重复值).
+ * @author wz + * @param role 角色实体类 + * @return 返回行数 + */ + Integer isExist(Role role); + + /** + * deleteRole:(根据角色ids删除角色信息).
+ * @author wz + * @param deletIds 角色ids + */ + void deleteRole(Long[] deletIds); +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.xml new file mode 100644 index 0000000..6452fb1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/RoleMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + INSERT INTO + manager_role + + + name, + + + role_code, + + status, + updateTime + + values + + + #{name}, + + + #{roleCode}, + + 1, + now() + + + + + + + UPDATE manager_role SET + + name = #{name} + + + ,role_code = #{roleCode} + + ,updateTime = now() + WHERE + status=1 + + and id = #{id} + + + + + UPDATE manager_role SET + status=-1 + WHERE + id + IN + + #{deletIds} + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.java new file mode 100644 index 0000000..5b78b9d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.java @@ -0,0 +1,111 @@ + +package com.baoying.enginex.executor.system.mapper; + +import com.baoying.enginex.executor.system.model.SysMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + + +public interface SysMenuMapper { + + /** + * 查询所有资源 + * @return + */ + public List getAllSysMenu(); + /** + * 查询单条资源 + * @param id + * @return + */ + public SysMenu findById(long id); + /** + * 新增资源 + * @param sysMenu + * @return + */ + public int createSysMenu(SysMenu sysMenu); + /** + * 修改资源 + * @param sysMenu + * @return + */ + public int updateSysMenu(SysMenu sysMenu); + /** + * 删除资源 + * @param id + * @return + */ + public int deleteSysMenu(long id); + + /** + * 修改资源状态 + * @param id + * @param idList + * @return + */ + public int updateStatus(@Param("status") int status, @Param("list") List list); + + /** + * 通过父节点查询子菜单 + * @param id + * @return + */ + public List findChildByParent(long parentId); + + /** + * 通过角色菜单关系表及父节点查询菜单 + */ + public List findRoleMenuByParent(@Param("parentId") long parentId, @Param("roleId") long roleId); + + /** + * 保存角色菜单关系 + */ + public int insertRoleMenu(@Param("roleId") long roleId, @Param("list") List list); + + /** + * 删除角色菜单关系(实现修改) + */ + public int deleteRoleMenu(long roleId); + /** + * 分配资源树 + * @param roleId + * @return + */ + public List findTreeList(long roleId); + /** + * 获取所有启用资源 + * @return + */ + public List getAllValidMenu(); + + /** + * 获取引擎资源树 + */ + public List> getEngineTree(long roleId); + + /** + * 保存引擎树 + */ + public int insertRoleEngine(@Param("roleId") long roleId, @Param("list") List list); + /** + * 删除引擎树(实现修改) + */ + public int deleteRoleEngine(long roleId); + + /** + * 验证唯一性 + */ + public List validateMenuOnly(SysMenu sysMenu); + /** + * 验证是否有查看菜单的权限 + */ + public List validatePermission(@Param("roleId") long roleId, @Param("url") String url); + /** + * 验证是否有该引擎的权限 + */ + public List> validateEnginePermission(@Param("roleId") long roleId, @Param("id_e") String id_e); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.xml new file mode 100644 index 0000000..71ae388 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysMenuMapper.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + resource_id, user_id, name, code, url, parent_id, des, birth, icon, status + + + + + + + + + + + + + + + + + + + + + + + + + + insert into t_resource (user_id, name, code, url, parent_id, des, birth, icon) + values (#{userId}, #{name}, #{code}, #{url}, #{parentId}, #{des}, now(), #{icon}) + + + + + insert into t_role_resource_rel (role_id, resource_id) + values + + (#{roleId}, #{ids}) + + + + + + insert into t_role_engine (role_id, id_str) + values + + (#{roleId}, #{ids}) + + + + + update t_resource set name=#{name}, + url=#{url}, + + des=#{des}, + + + icon=#{icon}, + + + user_id=#{userId}, + + + parent_id=#{parentId}, + + code=#{code} + where resource_id = #{id} + + + + update t_resource set status = -1 where resource_id = #{id} + + + + + delete from t_role_resource_rel where role_id = #{roleId} + + + + + delete from t_role_engine where role_id = #{roleId} + + + + update t_resource set status=#{status} + + + resource_id in + #{ids} + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.java new file mode 100644 index 0000000..c6bd78b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.java @@ -0,0 +1,57 @@ + +package com.baoying.enginex.executor.system.mapper; + +import com.baoying.enginex.executor.system.model.SysOrganization; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + +public interface SysOrganizationMapper { + /** + * 查询所有公司 + * @return + */ + public List getAllSysOrganization(); + /** + * 获取所有启用公司 + * @return + */ + public List getAllValidOrgan(); + /** + * 查询单个公司 + * @param id + * @return + */ + public SysOrganization findById(long id); + /** + * 创建公司 + * @param SysOrganization + * @return + */ + public int createSysOrganization(SysOrganization SysOrganization); + /** + * 修改组织 + * @param SysOrganization + * @return + */ + public int updateSysOrganization(SysOrganization SysOrganization); + /** + * 删除组织 + * @param id + * @return + */ + public int deleteSysOrganization(long id); + + /** + * 修改公司状态(停用/启用、删除) + * @param states + * @return + */ + public int updateStatus(@Param("status") int status, @Param("list") List list); + /** + * 验证唯一性 + */ + public List validateOrganOnly(SysOrganization SysOrganization); + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.xml new file mode 100644 index 0000000..4c9805d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysOrganizationMapper.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + organ_id, name, code, email, telephone, status, birth, author,token + + + + + + + + + + + + + insert into t_organization (name, code, email, telephone, status, author, birth, token) + values (#{name}, #{code}, #{email}, #{telephone}, 1, #{author}, now(), #{token}) + + + + update t_organization set name=#{name}, + + email=#{email}, + + + telephone=#{telephone}, + + + author=#{author}, + + code=#{code} + where organ_id=#{id} + + + + update t_organization set status = -1 where organ_id=#{id} + + + + update t_organization set status=#{status} + + + organ_id in + #{ids} + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..1dd6763 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.java @@ -0,0 +1,90 @@ + +package com.baoying.enginex.executor.system.mapper; + +import com.baoying.enginex.executor.system.model.SysRole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + + +public interface SysRoleMapper { + /** + * 获取本组织所有角色 + * @return + */ + public List getAllSysRole(long organId); + /** + * 获取所有角色 + */ + public List getAllRoles(); + /** + * 获取本组织启用的角色 + * @param organId + * @return + */ + public List getAllValidRole(@Param("organId") long organId, @Param("author") String author); + /** + * 查询本组织的单个角色 + * @param id + * @return + */ + public SysRole findById(@Param("id") long id, @Param("organId") long organId); + /** + * 查询单个角色 + * @param id + * @return + */ + public SysRole findByAId(long id); + + /** + * 创建本组织角色 + * @param sysRole + * @return + */ + public int createSysRole(SysRole sysRole); + /** + * 修改本公司角色 + * @param sysRole + * @return + */ + public int updateSysRole(SysRole sysRole); + /** + * 删除本公司角色 + * @param id + * @return + */ + public int deleteSysRole(long id); + /** + * 创建公司管理员角色 + */ + public int createOrganRole(SysRole sysRole); + /** + * 修改角色状态(停用、启用、删除) + * @param id + * @param idList + * @return + */ + public int updateStatus(@Param("status") int status, @Param("list") List list); + /** + * 根据角色查询角色所在公司 + */ + public long getOrganByRoleId(long roleId); + + /** + * 验证角色唯一性 + */ + public List validateRoleOnly(SysRole sysRole); + /** + * 查询公司管理员角色id + */ + public List getOrganRoleByAuthor(SysRole sysRole); + /** + * 删除本公司所有角色 + */ + public int deleteAllRoles(long organId); + /** + * 删除多个公司的所有角色 + */ + public int deleteRolesByOrgans(@Param("status") Integer status, @Param("list") List list); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.xml new file mode 100644 index 0000000..abddcb6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysRoleMapper.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + role_id, organ_id, role_name, role_code, role_desc, author, birth, status + + + + + + + + + + + + + + + + + + + + + + insert into t_role (role_id, organ_id, role_name, role_code, role_desc, author, birth, status) + values (#{id}, #{organId}, #{roleName}, #{roleCode}, #{roleDesc}, #{author}, now(), 1) + + + + insert into t_role (role_id, organ_id, role_name, role_code, role_desc, author, birth, status) + values (#{id}, #{organId}, #{roleName}, #{roleCode}, #{roleDesc}, #{author}, now(), 1) + + + + update t_role set + + role_desc=#{roleDesc}, + + + role_code=#{roleCode}, + + role_name=#{roleName} + where role_id = #{id} and organ_id = #{organId} + + + + update t_role set status = -1 where role_id = #{id} + + + + update t_role set status=#{status} + + + role_id in + #{ids} + + + + + + + update t_role set status = -1 where organ_id = #{organId} + + + + update t_role set status = #{status} + + + organ_id in + #{ids} + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..bf99eda --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.java @@ -0,0 +1,120 @@ + +package com.baoying.enginex.executor.system.mapper; + +import com.baoying.enginex.executor.system.model.SysUser; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + + +public interface SysUserMapper { + /** + * 查询搜索用户 + */ + public List getAllUsers(SysUser sysUser); + /** + * 查询本组织单个用户 + * @param id + * @return + */ + public SysUser findById(SysUser sysUser); + /** + * 创建本公司用户 + * @param sysUser + * @return + */ + public long createSysUser(SysUser sysUser); + /** + * 添加用户角色关系 + * @param userId + * @param roleId + * @return + */ + public int insertUserRole(@Param("userId") long userId, + @Param("roleId") long roleId, + @Param("organId") long organId); + /** + * 修改本公司用户 + * @param sysUser + * @return + */ + public int updateSysUser(SysUser sysUser); + /** + * 修改用户角色关系 + * @param sysUser + * @return + */ + public int updateUserRole(SysUser sysUser); + /** + * 删除本公司用户 + * @param id + * @return + */ + public int deleteSysUser(long id); + /** + * 修改用户状态(停用/启用/删除) + * @param states + * @return + */ + public int updateStates(@Param("status") int status, @Param("list") List list); + /** + * 通过用户id查询角色 + * @param userId + * @return + */ + public SysUser findRoleByUserId(long userId); + + /** + * 重置密码 + */ + public int resetPassword(SysUser sysUser); + + /** + * 修改密码 + */ + public int updatePassword(SysUser sysUser); + + /** + * 本公司账号员工编号唯一性 + */ + public List validateUserOnly(SysUser sysUser); + + /** + * 删除本公司的所有账号 + */ + public int deleteAllUser(long organId); + /** + * 删除本公司的用户角色关系 + */ + public int deleteAllUserRole(long organId); + /** + * 删除多个公司的所有账号 + */ + public int deleteUsersByOrgans(@Param("status") Integer status, @Param("list") List list); + /** + * 删除多个公司的用户角色关系 + */ + public int deleteUserRoleByOrgan(@Param("status") Integer status, @Param("list") List list); + /** + * 删除角色账号关联关系 + */ + public int deleteUserRoleById(long RoleId); + /** + * 查询本角色下的所有账号 + */ + public List getUserIdsByRoleId(long roleId); + /** + * 删除角色关联的所有账号 + */ + public int deleteUsersByIds(@Param("status") Integer status, @Param("list") List list); + + /** + * 批量删除角色账号关系 + */ + public int deleteBatchUserRole(@Param("status") Integer status, @Param("list") List list); + /** + * 批量查询角色关联的账号 + */ + public List getBatchUserIdsByRoleId(List list); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.xml new file mode 100644 index 0000000..99059a2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/SysUserMapper.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_id, organ_id, employee_id, account, password, nick_name, email, cellphone, qq, latest_time, latest_ip, status, birth, author + + + + + + + + + + + + + + + + + + + + + + + insert into t_user (organ_id, employee_id, account, password, nick_name, email, cellphone, qq, latest_time, latest_ip, status, birth, author) + values (#{organId}, #{employeeId}, #{account}, #{password}, #{nickName}, #{email}, #{cellphone}, #{qq}, #{latestTime}, #{latestIp}, 1, now(), #{author}) + + + + + insert into t_user_role_rel (user_id, role_id,organ_id) + values (#{userId}, #{roleId},#{organId}) + + + + + update t_user set account=#{account}, + + password = #{password} + + + employee_id=#{employeeId}, + + + email=#{email}, + + + cellphone=#{cellphone}, + + + qq=#{qq}, + + + latest_time=#{latestTime}, + + + latest_ip=#{latestIp}, + + + birth=#{birth}, + + + author=#{author}, + + nick_name=#{nickName} + where user_id=#{id} + + + + + update t_user_role_rel set user_id=#{id}, role_id=#{sysRole.id} + where user_id=#{id} + + + + + update t_user set status=-1 + where user_id=#{id} + + + + + update t_user set status=#{status} + + + user_id in + #{ids} + + + + + + + + update t_user set password = #{password} where user_id=#{id} + + + + + update t_user set password = #{password} where user_id=#{id} + + + + + update t_user set status = -1 where organ_id=#{organId} + + + + + update t_user_role_rel set status = -1 where organ_id = #{organId} + + + + update t_user set status = #{status} + + + organ_id in + #{ids} + + + + + + + update t_user_role_rel set status = #{status} + + + organ_id in + #{ids} + + + + + + + + update t_user_role_rel set status = -1 where role_id = #{roleId} + + + + + update t_user set status = #{status} + + + user_id in + #{ids} + + + + + + + + update t_user_role_rel set status = #{status} + + + role_id in + #{ids} + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.java new file mode 100644 index 0000000..90e262f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.java @@ -0,0 +1,57 @@ +package com.baoying.enginex.executor.system.mapper; + + +import com.baoying.enginex.executor.common.mapper.BaseMapper; +import com.baoying.enginex.executor.system.model.User; +import com.baoying.enginex.executor.system.model.UserRole; + +import java.util.List; +import java.util.Set; + + +public interface UserMapper extends BaseMapper { + /** + * isExist:(根据相应的条件判断是否存在重复值).
+ * @author wz + * @param user 用户实体类 + * @return 返回行数 + */ + Integer isExist(User user); + + /** + * selectLoginInfo:(用户登录判断).
+ * @author wz + * @param user 用户实体类 + * @return User + */ + User selectLoginInfo(User user); + + /** + * deleteDept:(根据用户ids删除用户信息).
+ * @author wz + * @param user 用户id + */ + void deleteUser(User user); + + /** + * insertUserRole:(增加记录到用户角色关系表).
+ * @author wz + * @param userRolelist 用户角色关系list + */ + void insertUserRole(List userRolelist); + + /** + * deleteUserRole:(根据用户ids删除用户角色关联表信息).
+ * @author wz + * @param deletIds 用户ids + */ + void deleteUserRole(Long[] deletIds); + + /** + * findUserMenuSet:(根据用户名获取所授权的菜单).
+ * @author wz + * @param loginName + * @return 根据用户名获取所授权的菜单 + */ + Set findUserMenuSet(String loginName); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.xml b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.xml new file mode 100644 index 0000000..027cfe8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/mapper/UserMapper.xml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO + manager_user + + + login_name, + + + name, + + + password, + + + email, + + + phone, + + + dept_code, + + status, + updateTime + + values + + + #{loginName}, + + + #{name}, + + + #{password}, + + + #{email}, + + + #{phone}, + + + #{deptCode}, + + 0, + now() + + + + + UPDATE manager_user SET + + login_name = #{loginName}, + + + name = #{name}, + + + password = #{password}, + + + email = #{email}, + + + phone = #{phone}, + + + dept_code = #{deptCode}, + + updateTime = now() + WHERE + status !=-1 + + and id = #{id} + + + + + INSERT INTO manager_user_role + (user_id,role_code) + values + + (#{item.userId},#{item.roleCode}) + + + + + + + + + DELETE FROM + manager_user_role + WHERE + user_id + IN + + #{deletIds} + + + + + UPDATE manager_user SET + status=#{status} + WHERE + id + IN + + #{item} + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Department.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Department.java new file mode 100644 index 0000000..52a60c4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Department.java @@ -0,0 +1,119 @@ +package com.baoying.enginex.executor.system.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + +public class Department extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + /** + * 部门id + */ + private Long id; + /** + * 部门名称 + */ + private String deptName; + /** + * 部门编号 + */ + private String deptCode; + /** + * 部门排序 + */ + private Integer deptOrder; + /** + * 状态 + */ + private Integer status; + /** + * 创建人 + */ + private String creator; + /** + * 创建时间 + */ + private String createTime; + /** + * 最后修改人 + */ + private String updater; + /** + * 最后修改时间 + */ + private String updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeptCode() { + return deptCode; + } + + public void setDeptCode(String deptCode) { + this.deptCode = deptCode; + } + + public Integer getDeptOrder() { + return deptOrder; + } + + public void setDeptOrder(Integer deptOrder) { + this.deptOrder = deptOrder; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdater() { + return updater; + } + + public void setUpdater(String updater) { + this.updater = updater; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Menu.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Menu.java new file mode 100644 index 0000000..37bb55b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Menu.java @@ -0,0 +1,247 @@ +package com.baoying.enginex.executor.system.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; +import java.util.Arrays; + + +public class Menu extends BasePage implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 菜单主键id + */ + private Long id; + /** + * 父id + */ + private Long pid; + /** + * 菜单名称 + */ + private String name; + /** + * 菜单类型 + */ + private Integer type; + /** + * 菜单顺序 + */ + private Integer muneOrder; + /** + * easyui展开 + */ + private String state; + /** + * 菜单链接 + */ + private String url; + /** + * 菜单编号 + */ + private String menuCode; + /** + * 菜单图标 + */ + private String icon; + /** + * 菜单描述 + */ + private String description; + /** + * 菜单状态 + */ + private Integer status; + /** + * 创建人 + */ + private String creator; + /** + * 创建时间 + */ + private String createTime; + /** + * 最后修改人 + */ + private String updater; + /** + * 最后修改时间 + */ + private String updateTime; + + /** + * 父类 + */ + private Long _parentId; + + /** + * 角色编码 + */ + private String roleCode; + + /** + * 删除ids数组 + */ + private Long []deletIds; + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Long[] getDeletIds() { + return deletIds; + } + + public void setDeletIds(Long[] deletIds) { + this.deletIds = deletIds; + } + + public String getRoleCode() { + return roleCode; + } + + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } + + public Long get_parentId() { + return _parentId; + } + + public void set_parentId(Long _parentId) { + this._parentId = _parentId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getPid() { + return pid; + } + + public void setPid(Long pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getMuneOrder() { + return muneOrder; + } + + public void setMuneOrder(Integer muneOrder) { + this.muneOrder = muneOrder; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getMenuCode() { + return menuCode; + } + + public void setMenuCode(String menuCode) { + this.menuCode = menuCode; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdater() { + return updater; + } + + public void setUpdater(String updater) { + this.updater = updater; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "Menu [id=" + id + ", pid=" + pid + ", name=" + name + ", type=" + + type + ", muneOrder=" + muneOrder + ", state=" + state + + ", url=" + url + ", menuCode=" + menuCode + ", icon=" + icon + + ", description=" + description + ", status=" + status + + ", creator=" + creator + ", createTime=" + createTime + + ", updater=" + updater + ", updateTime=" + updateTime + + ", _parentId=" + _parentId + ", roleCode=" + roleCode + + ", deletIds=" + Arrays.toString(deletIds) + "]"; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/MenuJson.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/MenuJson.java new file mode 100644 index 0000000..a197ed6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/MenuJson.java @@ -0,0 +1,54 @@ +package com.baoying.enginex.executor.system.model; + +import java.util.List; + + +public class MenuJson { + + private String menuid; + private String icon; + private String menuname; + private String url; + private List menus; + + public String getMenuid() { + return menuid; + } + + public void setMenuid(String menuid) { + this.menuid = menuid; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getMenuname() { + return menuname; + } + + public void setMenuname(String menuname) { + this.menuname = menuname; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public List getMenus() { + return menus; + } + + public void setMenus(List menus) { + this.menus = menus; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Pager.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Pager.java new file mode 100644 index 0000000..387d61e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Pager.java @@ -0,0 +1,78 @@ +package com.baoying.enginex.executor.system.model; + +public class Pager { + + private int rows = 10; + private int totalResult; + private int page; + + private String sortField; + private String order; + + public Pager() { + } + + public Pager(int totalResult) { + this.totalResult = totalResult; + } + + public int getRows() { + return rows; + } + + public void setRows(int rows) { + this.rows = rows; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getTotalPage() { + return (totalResult + rows - 1) / rows; + } + + public int getTotalResult() { + return totalResult; + } + + public void setTotalResult(int totalResult) { + this.totalResult = totalResult; + } + + public int getCurrentResult() { + if (page == 0) return 0; + else return (page - 1) * rows; + } + + public String getSortField() { + return sortField; + } + + public void setSortField(String sortField) { + this.sortField = sortField; + } + + public String getOrder() { + return order; + } + + public void setOrder(String order) { + this.order = order; + } + + public int getPageCount() { + int pagecount = 0; + if (totalResult % rows == 0) { + pagecount = totalResult / rows; + } else { + pagecount = totalResult / rows + 1; + } + return pagecount; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Role.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Role.java new file mode 100644 index 0000000..8d4b8c2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/Role.java @@ -0,0 +1,130 @@ +package com.baoying.enginex.executor.system.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + + +public class Role extends BasePage implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + /** + * 角色名称 + */ + private String name; + /** + * 角色编码 + */ + private String roleCode; + /** + * 角色描述 + */ + private String descripttion; + /** + * 状态 + */ + private Integer status; + /** + * 创建人 + */ + private String creator; + /** + * 创建时间 + */ + private String createTime; + /** + * 最后修改人 + */ + private String updater; + /** + * 最后修改时间 + */ + private String updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRoleCode() { + return roleCode; + } + + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } + + public String getDescripttion() { + return descripttion; + } + + public void setDescripttion(String descripttion) { + this.descripttion = descripttion; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getUpdater() { + return updater; + } + + public void setUpdater(String updater) { + this.updater = updater; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "Role [id=" + id + ", name=" + name + ", roleCode=" + roleCode + + ", descripttion=" + descripttion + ", status=" + status + + ", creator=" + creator + ", createTime=" + createTime + + ", updater=" + updater + ", updateTime=" + updateTime + "]"; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysMenu.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysMenu.java new file mode 100644 index 0000000..7bcb694 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysMenu.java @@ -0,0 +1,127 @@ + +package com.baoying.enginex.executor.system.model; + +import java.io.Serializable; +import java.util.Date; + + + +public class SysMenu implements Serializable { + + private static final long serialVersionUID = -1L; + + private long id; + private long userId;//分配者 + private String name; //资源名称 + private String code;//资源代号 + private String url;//路径 + private long parentId;//父节点 + private String des; + private Date birth;//创建时间 + private String icon;//图标 + private int status;//状态 + private long roleId;//角色id + private boolean checked;//菜单默认选中 + private boolean chkDisabled;//节点是否禁用 + private boolean isHidden;//节点是否隐藏 + + + + + public boolean isisHidden() { + return isHidden; + } + public void setisHidden(boolean isHidden) { + this.isHidden = isHidden; + } + public boolean isChkDisabled() { + return chkDisabled; + } + public void setChkDisabled(boolean chkDisabled) { + this.chkDisabled = chkDisabled; + } + public boolean isChecked() { + return checked; + } + public void setChecked(boolean checked) { + this.checked = checked; + } + public long getRoleId() { + return roleId; + } + public void setRoleId(long roleId) { + this.roleId = roleId; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + public String getDes() { + return des; + } + public void setDes(String des) { + this.des = des; + } + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public long getUserId() { + return userId; + } + public void setUserId(long userId) { + this.userId = userId; + } + public long getParentId() { + return parentId; + } + public void setParentId(long parentId) { + this.parentId = parentId; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public String getIcon() { + return icon; + } + public void setIcon(String icon) { + this.icon = icon; + } + public Date getBirth() { + return birth; + } + public void setBirth(Date birth) { + this.birth = birth; + } + @Override + public String toString() { + return "SysMenu [id=" + id + ", userId=" + userId + ", name=" + name + + ", versionCode=" + code + ", url=" + url + ", parentId=" + parentId + + ", des=" + des + ", birth=" + birth + ", icon=" + icon + + ", status=" + status + ", roleId=" + roleId + ", checked=" + + checked + ", chkDisabled=" + chkDisabled + ", isHidden=" + + isHidden + "]"; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysOrganization.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysOrganization.java new file mode 100644 index 0000000..8bfb985 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysOrganization.java @@ -0,0 +1,89 @@ + +package com.baoying.enginex.executor.system.model; + +import java.io.Serializable; +import java.util.Date; + + + +public class SysOrganization implements Serializable { + + private static final long serialVersionUID = -1L; + + private long id;//组织编号 + private String name;//组织名称 + private String code;//组织代号 + private String email; + private String telephone; + private int status;//0禁用1启用 + private String author;//创建者 + private Date birth;//创建时间 + private String token;//唯一标识 + + + + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + public String getAuthor() { + return author; + } + public void setAuthor(String author) { + this.author = author; + } + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getTelephone() { + return telephone; + } + public void setTelephone(String telephone) { + this.telephone = telephone; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + public Date getBirth() { + return birth; + } + public void setBirth(Date birth) { + this.birth = birth; + } + @Override + public String toString() { + return "SysOrganization [id=" + id + ", name=" + name + ", versionCode=" + code + + ", email=" + email + ", telephone=" + telephone + ", status=" + + status + ", author=" + author + ", birth=" + birth + + ", token=" + token + "]"; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysRole.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysRole.java new file mode 100644 index 0000000..cfb9aa7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysRole.java @@ -0,0 +1,83 @@ + +package com.baoying.enginex.executor.system.model; + +import java.io.Serializable; +import java.util.Date; + + + +public class SysRole implements Serializable { + + private static final long serialVersionUID = -1L; + + private long id; + private long organId; + private String roleName; + private String roleCode;//角色代号 + private String roleDesc; + private String author;//创建者 + private Date birth;//创建时间 + private int status; //状态0禁用1启用 + + + + + public String getAuthor() { + return author; + } + public void setAuthor(String author) { + this.author = author; + } + public Date getBirth() { + return birth; + } + public void setBirth(Date birth) { + this.birth = birth; + } + public long getOrganId() { + return organId; + } + public void setOrganId(long organId) { + this.organId = organId; + } + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public String getRoleName() { + return roleName; + } + public void setRoleName(String roleName) { + this.roleName = roleName; + } + public String getRoleCode() { + return roleCode; + } + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } + public String getRoleDesc() { + return roleDesc; + } + public void setRoleDesc(String roleDesc) { + this.roleDesc = roleDesc; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + @Override + public String toString() { + return "SysRole [id=" + id + ", organId=" + organId + ", roleName=" + + roleName + ", roleCode=" + roleCode + ", roleDesc=" + roleDesc + + ", author=" + author + ", birth=" + birth + ", status=" + + status + "]"; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysSuccess.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysSuccess.java new file mode 100644 index 0000000..ed50b75 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysSuccess.java @@ -0,0 +1,40 @@ +package com.baoying.enginex.executor.system.model; + +public class SysSuccess { + + private boolean success; + private String msg; + + public SysSuccess() { + } + + public SysSuccess(boolean value, String msg) { + super(); + this.success = value; + this.msg = msg; + } + + public boolean getSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + @Override + public String toString() { + return "SysSuccess [success=" + success + ", msg=" + msg + "]"; + } + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysUser.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysUser.java new file mode 100644 index 0000000..143255a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/SysUser.java @@ -0,0 +1,141 @@ + +package com.baoying.enginex.executor.system.model; + +import java.io.Serializable; +import java.util.Date; + + + +public class SysUser implements Serializable { + + private static final long serialVersionUID = -1L; + + private long id;//用户(主键) + private long organId;//组织编号 + private String employeeId;//员工编号 + private String account;//账户 + private String password; + private String nickName;//昵称 + private String email; + private String cellphone; + private String qq; + private String latestTime; + private String latestIp; + private int status; + private Date birth;//创建时间 + private String author;//创建人 + private SysRole sysRole;//角色对象 + private SysOrganization sysOrgan;//公司对象 + + + + + + public SysOrganization getSysOrgan() { + return sysOrgan; + } + public void setSysOrgan(SysOrganization sysOrgan) { + this.sysOrgan = sysOrgan; + } + public String getAuthor() { + return author; + } + public void setAuthor(String author) { + this.author = author; + } + public String getEmployeeId() { + return employeeId; + } + public void setEmployeeId(String employeeId) { + this.employeeId = employeeId; + } + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public long getOrganId() { + return organId; + } + public void setOrganId(long organId) { + this.organId = organId; + } + public String getAccount() { + return account; + } + public void setAccount(String account) { + this.account = account; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getNickName() { + return nickName; + } + public void setNickName(String nickName) { + this.nickName = nickName; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getCellphone() { + return cellphone; + } + public void setCellphone(String cellphone) { + this.cellphone = cellphone; + } + public String getQq() { + return qq; + } + public void setQq(String qq) { + this.qq = qq; + } + public String getLatestTime() { + return latestTime; + } + public void setLatestTime(String latestTime) { + this.latestTime = latestTime; + } + public String getLatestIp() { + return latestIp; + } + public void setLatestIp(String latestIp) { + this.latestIp = latestIp; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + public SysRole getSysRole() { + return sysRole; + } + public void setSysRole(SysRole sysRole) { + this.sysRole = sysRole; + } + public Date getBirth() { + return birth; + } + public void setBirth(Date birth) { + this.birth = birth; + } + @Override + public String toString() { + return "SysUser [id=" + id + ", organId=" + organId + ", employeeId=" + + employeeId + ", account=" + account + ", password=" + password + + ", nickName=" + nickName + ", email=" + email + ", cellphone=" + + cellphone + ", qq=" + qq + ", latestTime=" + latestTime + + ", latestIp=" + latestIp + ", status=" + status + ", birth=" + + birth + ", author=" + author + ", sysOrgan="+sysOrgan+", sysRole=" + sysRole + "]"; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/User.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/User.java new file mode 100644 index 0000000..28d66d1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/User.java @@ -0,0 +1,203 @@ +package com.baoying.enginex.executor.system.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Date; + + +public class User extends BasePage implements Serializable { + + /** + * serialVersionUID:TODO(序列化对象使用) + */ + private static final long serialVersionUID = 1L; + + /** + * 关系id + */ + private Long userId; + /** + * 企业id + */ + private Long organId; + /** + * 用户id + */ + private String account; + /** + * 用户密码 + */ + private String password; + + /** + * 昵称 + */ + private String nickName; + /** + * 邮箱 + */ + private String email; + /** + * 电话 + */ + private String cellphone; + /** + * qq + */ + private String qq; + /** + * + */ + private String latestTime; + /** + * 最后一次登录IP + */ + private String latestIp; + /** + * 状态 + */ + private Integer status; + /** + * 创建时间 + */ + private Date birth; + /** + * 创建时间 + */ + private Long parentId; + /** + * 删除ids数组 + */ + private Long []deletIds; + + public Long[] getDeletIds() { + return deletIds; + } + + public void setDeletIds(Long[] deletIds) { + this.deletIds = deletIds; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getOrganId() { + return organId; + } + + public void setOrganId(Long organId) { + this.organId = organId; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getCellphone() { + return cellphone; + } + + public void setCellphone(String cellphone) { + this.cellphone = cellphone; + } + + public String getQq() { + return qq; + } + + public void setQq(String qq) { + this.qq = qq; + } + + + + public String getLatestTime() { + return latestTime; + } + + public void setLatestTime(String latestTime) { + this.latestTime = latestTime; + } + + public String getLatestIp() { + return latestIp; + } + + public void setLatestIp(String latestIp) { + this.latestIp = latestIp; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Date getBirth() { + return birth; + } + + public void setBirth(Date birth) { + this.birth = birth; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + @Override + public String toString() { + return "User [userId=" + userId + ", organId=" + organId + ", account=" + + account + ", password=" + password + ", nickName=" + nickName + + ", email=" + email + ", cellphone=" + cellphone + ", qq=" + qq + + ", latestTime=" + latestTime + ", latestIp=" + latestIp + + ", status=" + status + ", birth=" + birth + ", parentId=" + + parentId + ", deletIds=" + Arrays.toString(deletIds) + "]"; + } + + + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/UserRole.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/UserRole.java new file mode 100644 index 0000000..802fa8f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/system/model/UserRole.java @@ -0,0 +1,52 @@ + +package com.baoying.enginex.executor.system.model; + + +import com.baoying.enginex.executor.common.model.BasePage; + +import java.io.Serializable; + + +public class UserRole extends BasePage implements Serializable{ + + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + private Long id; + /** + * 用户id + */ + private Long userId; + /** + * 角色编码 + */ + private String roleCode; + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public Long getUserId() { + return userId; + } + public void setUserId(Long userId) { + this.userId = userId; + } + public String getRoleCode() { + return roleCode; + } + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } + @Override + public String toString() { + return "UserRole [id=" + id + ", userId=" + userId + ", roleCode=" + + roleCode + "]"; + } + + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/consts/TacticsType.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/consts/TacticsType.java new file mode 100644 index 0000000..8d31c97 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/consts/TacticsType.java @@ -0,0 +1,16 @@ +package com.baoying.enginex.executor.tactics.consts; + +public class TacticsType { + public static final String DECISION_TABLES = "decision_tables";//决策表 + public static final String SCORECARD = "scorecard";//评分卡 + public static final String LIST_DB = "list_db";//名单库 + public static final String MODELS = "models"; + public static final String COMPLEX_RULE = "complex_rule"; + public static final String BASE_RULE = "base_rule"; + public static final String DECISION_TREE = "decision_tree";//决策树 + + public static class OutType{ + public static final String SUCCESS_OUT = "success";//成功时输出 + public static final String FAIL_OUT = "fail";//失败时输出 + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/mapper/TacticsOutputMapper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/mapper/TacticsOutputMapper.java new file mode 100644 index 0000000..5d4d08b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/mapper/TacticsOutputMapper.java @@ -0,0 +1,10 @@ +package com.baoying.enginex.executor.tactics.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TacticsOutputMapper extends BaseMapper { +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/OutCondition.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/OutCondition.java new file mode 100644 index 0000000..7d60b50 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/OutCondition.java @@ -0,0 +1,18 @@ +package com.baoying.enginex.executor.tactics.model; + + +import com.baoying.enginex.executor.common.model.ExpressionParam; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OutCondition { + private String logical; + private List conditionList; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/TacticsOutput.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/TacticsOutput.java new file mode 100644 index 0000000..0ba6040 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/model/TacticsOutput.java @@ -0,0 +1,78 @@ +package com.baoying.enginex.executor.tactics.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_tactics_output") +public class TacticsOutput implements Serializable { + @TableField(exist = false) + private static final long serialVersionUID = 699491471584300246L; + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 字段id + */ + private Long fieldId; + /** + * 字段的en + */ + private String fieldEn; + /** + * 字段值 + */ + private String fieldValue; + /** + *字段值的类型:1 常量、2 变量,3.自定义 + */ + private Integer variableType; + /** + * 关联的策略id + */ + private Long tacticsId; + /** + * 关联的策略类型 base_rule.基础规则 scorecard.评分卡 decision_tables.决策表 decision_tree.决策树 complex_rule.复杂规则 list_db.名单库 models.机器学习模型 + */ + private String tacticsType; + /** + * 输出条件 + */ + private String outCondition; + /** + * 输出类型 success成功输出, fail失败输出 + */ + private String outType; + /** + * 创建时间 + */ + private Date createTime; + /** + * 修改时间 + */ + private Date updateTime; + + public TacticsOutput(Long tacticsId, String tacticsType) { + this.tacticsId = tacticsId; + this.tacticsType = tacticsType; + } + + public TacticsOutput(Long tacticsId, String tacticsType, String outType) { + this.tacticsId = tacticsId; + this.tacticsType = tacticsType; + this.outType = outType; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/TacticsOutputService.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/TacticsOutputService.java new file mode 100644 index 0000000..8cd1636 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/TacticsOutputService.java @@ -0,0 +1,18 @@ +package com.baoying.enginex.executor.tactics.service; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; + +import java.util.List; +import java.util.Map; + + +public interface TacticsOutputService extends IService { + + List queryByTactics(TacticsOutput entity); + + List setOutput(TacticsOutput entity,Map input); + + boolean judgeOutCondition(String condition,Map input); +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/impl/TacticsOutputServiceImpl.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/impl/TacticsOutputServiceImpl.java new file mode 100644 index 0000000..9c111c5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/tactics/service/impl/TacticsOutputServiceImpl.java @@ -0,0 +1,141 @@ +package com.baoying.enginex.executor.tactics.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baoying.enginex.executor.canal.TableEnum; +import com.baoying.enginex.executor.common.constants.Constants; +import com.baoying.enginex.executor.common.model.ExpressionParam; +import com.baoying.enginex.executor.config.ConfigHolder; +import com.baoying.enginex.executor.redis.RedisManager; +import com.baoying.enginex.executor.redis.RedisUtils; +import com.baoying.enginex.executor.tactics.consts.TacticsType; +import com.baoying.enginex.executor.tactics.mapper.TacticsOutputMapper; +import com.baoying.enginex.executor.tactics.model.OutCondition; +import com.baoying.enginex.executor.tactics.model.TacticsOutput; +import com.baoying.enginex.executor.tactics.service.TacticsOutputService; + +import com.baoying.enginex.executor.util.ExecuteUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class TacticsOutputServiceImpl extends ServiceImpl implements TacticsOutputService { + + @Autowired + private ConfigHolder configHolder; + @Autowired + private RedisManager redisManager; + + @Override + public List queryByTactics(TacticsOutput entity) { + List tacticsOutputList = null; + if(Constants.switchFlag.ON.equals(configHolder.getCacheSwitch())){ + String key = RedisUtils.getForeignKey(TableEnum.T_TACTICS_OUTPUT, entity.getTacticsId()); + tacticsOutputList = redisManager.getByForeignKey(key, TacticsOutput.class); + if(tacticsOutputList != null){ + tacticsOutputList = tacticsOutputList.stream().filter(item -> item.getTacticsType().equals(entity.getTacticsType())) + .collect(Collectors.toList()); + } + if (tacticsOutputList!=null&&!tacticsOutputList.isEmpty()&& TacticsType.COMPLEX_RULE.equals(entity.getVariableType())&&entity.getOutType()!=null){ + //复杂规则需要过滤出类型 + tacticsOutputList = tacticsOutputList.stream().filter(item ->entity.getOutType().equals( item.getOutType())).collect(Collectors.toList()); + } + } else { + tacticsOutputList = this.list(new QueryWrapper<>(entity)); + } + + return tacticsOutputList; + } + + @Transactional + + //设置输出,传入map向map中放入输出并且返回输出列表 + @Override + public List setOutput(TacticsOutput entity, Map input) { + List tacticsOutputList = this.queryByTactics(entity); + List jsonList = new ArrayList<>(); + if (tacticsOutputList != null && tacticsOutputList.size() > 0) { + for (TacticsOutput tacticsOutput : tacticsOutputList) { + if (!this.judgeOutCondition(tacticsOutput.getOutCondition(),input)){ + continue; + } + JSONObject json = new JSONObject(); + String fieldEn = tacticsOutput.getFieldEn(); + String fieldValue = tacticsOutput.getFieldValue(); + Object value = fieldValue; + Integer variableType = tacticsOutput.getVariableType(); + if (variableType != null) { + switch (variableType) { + case 2: + value = ExecuteUtils.getObjFromMap(input, fieldValue); + break; + case 3: + value = ExecuteUtils.getObjFromScript(input,fieldValue); + break; + } + } + if (value != null ) { + if (!"".equals(value)&&!"'".equals(value)&&value.toString().startsWith("'")&&value.toString().endsWith("'")){ + value = value.toString().substring(1,value.toString().length()-1); + } + json.put(fieldEn, value); + input.put(fieldEn, value); + jsonList.add(json); + } + } + } + return jsonList; + } + + //判断是否符合输出条件 + @Override + public boolean judgeOutCondition(String condition, Map input) { + //条件为空则符合输出 + if (null == condition || "".equals(condition)) { + return true; + } + OutCondition outCondition; + try { + outCondition = JSON.parseObject(condition, OutCondition.class); + }catch (Exception e){ + //字符串转json失败 + return true; + } + String logical = outCondition.getLogical(); + List conditionList = outCondition.getConditionList(); + if (null == logical || null == conditionList||conditionList.size()<1){ + return true; + } + boolean result=false; + switch (logical) { + case "||": + result = false; + for (ExpressionParam expression : conditionList) { + if (ExecuteUtils.getExpressionResult(expression, input)){ + return true; + } + } + break; + case "&&": + result = true; + for (ExpressionParam expression : conditionList) { + if (!ExecuteUtils.getExpressionResult(expression, input)){ + return false; + } + } + break; + } + return result; + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CollectionUtil.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CollectionUtil.java new file mode 100644 index 0000000..724f049 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CollectionUtil.java @@ -0,0 +1,104 @@ +package com.baoying.enginex.executor.util; + +import java.util.*; + +public class CollectionUtil { + + /** + * 集合判非空 + * + * @param collection + * @return + */ + public static boolean isNotNullOrEmpty(Collection collection) { + if (null == collection || collection.isEmpty()){ + return false; + } + return true; + } + + /** + * map判非空 + * + * @param map + * @return + */ + public static boolean isNotNullOrEmpty(Map map) { + if (null == map || map.isEmpty()){ + return false; + } + return true; + } + + /** + * 获取多个集合并集 + * @param list + * @return + */ + public static Set getUnion(List> list) { + Set set = new HashSet(); + if (list == null) { + list = new ArrayList>(); + } + int size = list.size(); + if (size > 1) { + for (int i = 0; i < size; i++) { + int j = i + 1; + if (j < size) { + list.get(0).removeAll(list.get(j)); + list.get(0).addAll(list.get(j)); + if (i == size - 2) { + List resultList = list.get(0); + for (Object result : resultList) { + set.add(result); + } + } + } + } + } else { + // 只有一个集合则直接插入结果 + for (List subList : list) { + for (Object result : subList) { + set.add(result); + } + } + } + return set; + + } + + /** + * 获取多个集合交集 + * @param list + * @return + */ + public static Set getIntersection(List> list) { + Set set = new HashSet(); + int size = list.size(); + if (size > 1) { + // 集合个数大于1,取交集 + for (int i = 0; i < size; i++) { + int j = i + 1; + if (j < size) { + list.get(0).retainAll(list.get(j)); + if (i == size - 2) { + List resultList = list.get(0); + for (Object result : resultList) { + set.add(result); + } + } + } + } + } else { + // 只有一个集合则不取交集 + for (List subList : list) { + for (Object result : subList) { + set.add(result); + } + } + } + + return set; + + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CustomValueUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CustomValueUtils.java new file mode 100644 index 0000000..4590857 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/CustomValueUtils.java @@ -0,0 +1,32 @@ +package com.baoying.enginex.executor.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.util.HashSet; +import java.util.Set; + +public class CustomValueUtils { + + public static final Set getFieldEnSet(String custom) { + Set fieldEns = new HashSet<>(); + if (custom != null && !"".equals(custom)) { + JSONObject jsonObject = JSON.parseObject(custom); + Object farr = jsonObject.get("farr"); + if (farr != null) { + JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(farr)); + if (jsonArray != null && jsonArray.size() > 0) { + for (Object o : jsonArray) { + JSONObject field = JSON.parseObject(JSON.toJSONString(o)); + Object fieldEn = field.get("fieldEn"); + if (fieldEn != null && !"".equals(fieldEn)) { + fieldEns.add(fieldEn.toString()); + } + } + } + } + } + return fieldEns; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DataHelp.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DataHelp.java new file mode 100644 index 0000000..4f5c854 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DataHelp.java @@ -0,0 +1,40 @@ +package com.baoying.enginex.executor.util; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DataHelp { + public static int day=0; + public static String getNowDate(){ + Date date = new Date(); + SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String s = simple.format(date); + return s; + } + public static String getEndDate(){ + SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Calendar c = Calendar.getInstance(); + c.add(Calendar.DATE, + DataHelp.day); + Date monday = c.getTime(); + String s = simple.format(monday); + return s; + } + public static String getNowDateString(){ + Date date = new Date(); + SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss"); + String s = simple.format(date); + return s; + } + public static String getDay(){ + Date date = new Date(); + SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd"); + String s = simple.format(date); + return s; + } + public static void main(String[] args) { + System.out.println(getNowDate()); + System.out.println(getNowDateString()); + + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DictVariableUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DictVariableUtils.java new file mode 100644 index 0000000..bafc7c1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/DictVariableUtils.java @@ -0,0 +1,29 @@ +package com.baoying.enginex.executor.util; + +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONObject; + +import java.util.Date; + +public class DictVariableUtils { + + public static Object getValueFromJsonObject(JSONObject jsonObject){ + Object result = ""; + if (jsonObject.get("value") != null) { + switch (jsonObject.getString("type")){ + case "date": + try { + result = DateUtil.format(new Date(),jsonObject.getString("value")); + }catch (Exception e){ + e.printStackTrace(); + result = DateUtil.format(new Date(),"yyyyMMdd"); + } + break; + default: + result = jsonObject.get("value"); + } + } + return result; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ExecuteUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ExecuteUtils.java new file mode 100644 index 0000000..66fa29b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ExecuteUtils.java @@ -0,0 +1,674 @@ +package com.baoying.enginex.executor.util; + + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.common.constants.ParamTypeConst; +import com.baoying.enginex.executor.common.model.ExpressionParam; +import com.baoying.enginex.executor.datamanage.model.Field; +import com.baoying.enginex.executor.datamanage.service.FieldService; +import com.baoying.enginex.executor.engine.model.EngineNode; +import com.baoying.enginex.executor.node.service.CommonService; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.math.Groovy; +import org.apache.commons.lang.StringUtils; +import com.baoying.enginex.executor.util.jeval.function.math.Python; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +//底层执行的工具类 +@Component +public class ExecuteUtils { + private static final Logger logger = LoggerFactory.getLogger(ExecuteUtils.class); + private static Groovy groovy; + private static CommonService commonService; + private static Python python; + private static FieldService fieldService; + + @Autowired + public ExecuteUtils(Groovy groovy, CommonService commonService, Python python, FieldService fieldService) { + ExecuteUtils.groovy = groovy; + ExecuteUtils.commonService = commonService; + ExecuteUtils.python = python; + ExecuteUtils.fieldService = fieldService; + } + + //获取基本单元的执行结果 + public final static boolean getExpressionResult(ExpressionParam expressionParam, Map params) { + //如果是规则的条件的话,判断是否为叶子节点,如果不是则直接返回false + if (expressionParam.getConditionType() != null && expressionParam.getConditionType() != 2) { + return false; + } + String operator = expressionParam.getOperator(); +// //获取第一个参数的key +// String paramOneKey = expressionParam.getFieldEn(); +// //获取第二个参数的key或者常量值 +// String paramTwoKey = expressionParam.getFieldValue(); + //获取第二个参数的类型 + Integer variableType = expressionParam.getVariableType(); + //给每个参数取值 + Object paramOne = getValueByKey(2, params, expressionParam.getFieldEn(),null); + //默认为常量 + Object paramTwo = getValueByKey(variableType, params, expressionParam.getFieldValue(),null); + //如果第二个参数类型为变量则取出参数,为自定义则计算出值返回 +// if (variableType != null) { +// switch (variableType) { +// case 1: +// //常量类型 +// break; +// case 2: +// //变量类型 +// paramTwo = getObjFromMap(params, paramTwoKey); +// break; +// case 3: +// //自定义脚本类型 +// paramTwo = getObjFromScript(params, expressionParam.getFieldValue()); +// break; +// case 4: +// //正则表达式类型 +// paramTwo = getObjFromRegex(params, expressionParam.getFieldValue()); +// } +// } + //如果两个参数有没取到的则直接返回false + if (paramOne == null || "".equals(paramOne) || paramTwo == null || "".equals(paramTwo)) { + return false; + } + return getCondResult(operator, paramOne, paramTwo); +// //协商获取操作类型 +// boolean result = false; +// //预处理:如果是数字类型的话提前取出数值 +// Double numOne = StrUtils.strToDouble(paramOne.toString()); +// Double numTwo = StrUtils.strToDouble(paramTwo.toString()); +// switch (operator) { +// //数值之间的比较 +// case "==": +// if (numOne != null && numTwo != null) { +// result = numOne.equals(numTwo); +// } else if (paramOne != null && paramTwo != null) { +// result = paramOne.toString().equals(paramTwo.toString()); +// } +// break; +// case "!=": +// if (numOne != null && numTwo != null) { +// result = !numOne.equals(numTwo); +// } else if (paramOne != null && paramTwo != null) { +// result = !paramOne.toString().equals(paramTwo.toString()); +// } +// break; +// case ">": +// if (numOne != null && numTwo != null) { +// result = numOne > numTwo; +// } +// break; +// case "<": +// if (numOne != null && numTwo != null) { +// result = numOne < numTwo; +// } +// break; +// case ">=": +// if (numOne != null && numTwo != null) { +// result = numOne >= numTwo; +// } +// break; +// case "<=": +// if (numOne != null && numTwo != null) { +// result = numOne <= numTwo; +// } +// break; +// //字符串之间的比较 +// case "equals": +// result = paramOne.toString().equals(paramTwo.toString()); +// break; +// case "not equals": +// result = !paramOne.toString().equals(paramTwo.toString()); +// break; +// case "contains": +// result = paramOne.toString().contains(paramTwo.toString()); +// break; +// case "not contains": +// result = !paramOne.toString().contains(paramTwo.toString()); +// break; +// case "regex": +// Pattern pattern = Pattern.compile(paramTwo.toString()); +// Matcher matcher = pattern.matcher(paramOne.toString()); +// result = matcher.find(); +// break; +// } +// return result; + } + + + //传入两个参数和一个操作符进行比对获取结果 + public final static boolean getCondResult(String operator, Object paramOne, Object paramTwo) { + boolean result = false; + Double numOne = StrUtils.strToDouble(paramOne.toString()); + Double numTwo = StrUtils.strToDouble(paramTwo.toString()); + switch (operator) { + //数值之间的比较 + case "==": + if (numOne != null && numTwo != null) { + result = numOne.equals(numTwo); + } else if (paramOne != null && paramTwo != null) { + result = paramOne.toString().equals(paramTwo.toString()); + } + break; + case "!=": + if (numOne != null && numTwo != null) { + result = !numOne.equals(numTwo); + } else if (paramOne != null && paramTwo != null) { + result = !paramOne.toString().equals(paramTwo.toString()); + } + break; + case ">": + if (numOne != null && numTwo != null) { + result = numOne > numTwo; + } + break; + case "<": + if (numOne != null && numTwo != null) { + result = numOne < numTwo; + } + break; + case ">=": + if (numOne != null && numTwo != null) { + result = numOne >= numTwo; + } + break; + case "<=": + if (numOne != null && numTwo != null) { + result = numOne <= numTwo; + } + break; + //字符串之间的比较 + case "equals": + result = paramOne.toString().equals(paramTwo.toString()); + break; + case "not equals": + result = !paramOne.toString().equals(paramTwo.toString()); + break; + case "contains": + result = paramOne.toString().contains(paramTwo.toString()); + break; + case "not contains": + result = !paramOne.toString().contains(paramTwo.toString()); + break; + case "regex": + Pattern pattern = Pattern.compile(paramTwo.toString()); + Matcher matcher = pattern.matcher(paramOne.toString()); + result = matcher.find(); + break; + case "in": + if (paramTwo instanceof List){ + List list = (List) paramTwo; + result = list.contains(paramOne); + }else if (paramTwo instanceof Map){ + Map map= (Map)paramTwo; + result = map.containsKey(paramOne); + } + break; + case "not in": + if (paramTwo instanceof List){ + List list = (List) paramTwo; + result = !list.contains(paramOne); + }else if (paramTwo instanceof Map){ + Map map= (Map)paramTwo; + result = !map.containsKey(paramOne); + } + break; + } + return result; + } + + //根据key,分不同类型取出值 + public final static Object getValueByKey(Integer variableType, Map params, String paramKey,List list) { + Object result = paramKey; + if (variableType != null) { + switch (variableType) { + case ParamTypeConst + .CONSTANT: + //常量类型 + result = paramKey; + break; + case ParamTypeConst + .VARIABLE: + //变量类型 + result = getObjFromMap(params, paramKey); + break; + case ParamTypeConst + .CUSTOM: + //自定义脚本类型 + if (list==null || list.isEmpty()){ + result = getObjFromScript(params, paramKey); + }else { + result = getObjFromScript(params,paramKey,list); + } + break; + case ParamTypeConst + .REGEX: + //正则表达式类型 + result = getObjFromRegex(params, paramKey); + } + } + return result; + } + + + //从map中取值 + public final static Object getObjFromMap(Map input, String key) { + if (StringUtils.isBlank(key)) { + return ""; + } + if (input == null) { + input = new ConcurrentHashMap<>(); + } + String[] array = key.split("\\."); + //如果当前变量池中未找到此变量则需要获取 + if (input.get(array[0]) == null && !array[0].startsWith("%")) { + List strings = new ArrayList(); + strings.add(array[0]); + boolean result = getFieldToInputByEns(strings,input); + if (!result) { + return ""; + } + } + return getObjFromMap(input, array); + } + + //从map中找到需要的对象并返回 + public final static Object getObjFromMap(Map input, String[] array) { + if (array.length == 1) { + Object o = input.get(array[0]); + if (o == null) { + return ""; + } + return o; + } + Map map = input; + for (int i = 0; i < array.length; i++) { + String childKey = array[i]; + //判断是否能找到key + if (map.containsKey(childKey)) { + Object o = map.get(childKey); + if (i == array.length - 1) { + return map.get(childKey); + } + //如果是数组取length + if (i == array.length - 2) { + if ("length()".equals(array[array.length - 1])) { + return JSON.toJavaObject(JSON.parseObject(JSON.toJSONString(o)), ArrayList.class).size(); + } + } + //未找到最后一个数组元素则将其识别为map + map = JSON.toJavaObject(JSON.parseObject(JSON.toJSONString(o)), Map.class); + } + } + return ""; + } + + //根据入参map,通过公式和groovy计算出返回结果 + public final static Object getObjFromScript(Map input, String fieldValue) { + JSONObject formulaJson = JSON.parseObject(fieldValue); + //找到脚本中引用的字段,放入data中 + Map data = new HashMap<>(); + Object farr = formulaJson.get("farr"); + List fieldIds = new ArrayList<>(); + //字段cn为key,字段en为value + Map fieldMap = new HashMap<>(); + if (farr != null && !"".equals(farr)) { + List fieldList = JSONArray.parseArray(JSON.toJSONString(farr), Field.class); + for (Field field : fieldList) { + String fieldCn = field.getFieldCn(); + String fieldEn = field.getFieldEn(); + if (fieldCn != null && fieldEn != null && !"".equals(fieldCn) && !"".equals(fieldEn)) { + fieldMap.put(fieldCn, field); + } + fieldIds.add(field.getId()); + } + } + if (fieldIds.size() > 0) { + getFieldToInputByIds(fieldIds,input); + } + Object result = executeScript(formulaJson, fieldMap, input); + //取出groovy脚本 +// String formula = (String) formulaJson.get("formula"); +// //替换掉特殊的字符 +// formula = formula.replace(">", ">"); //3>=6 && 3< 12 +// formula = formula.replace("<", "<"); +// //正则匹配自定义中用到的变量对其进行替换 +// Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()()-]+@"); +// Matcher matcher = pattern.matcher(formula); +// String subexp = formula; +// String exp = ""; +// int j = 0; +// while (matcher.find()) { +// String fieldCN = matcher.group(0).replace("@", ""); +// Field subField = fieldMap.get(fieldCN); +// if (subField == null) { +// return ""; +// } +// String fieldEn = subField.getFieldEn(); +// String v = ""; +// v = "" + input.get(fieldEn); +// data.put(fieldEn, input.get(fieldEn)); +// if (subexp.contains("def main")) { +// // groovy脚本替换为动态参数 +// v = "_['" + fieldEn + "']"; +// exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); +// } else { +// if (subField.getValueType() == 1 || subField.getValueType() == 4) { +// exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); +// } else { +// exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", "'" + v + "'"); +// } +// } +// j = matcher.end(); +// } +// exp += formula.substring(j, formula.length()); +// Evaluator evaluator = new Evaluator(); +// Object result = ""; +// try { +// if (exp.contains("def main")) { +// // 执行groovy脚本 +// +// logger.warn("groovy:{},{}", exp, data); +// result = groovy.executeForObject(exp, data); +// } else if (exp.contains("def python_main(_):")) { +// //执行python脚本 +// result = python.executeForObject(exp, data); +// } else { +// //执行公式 +// result = evaluator.evaluate(exp); +// } +// } catch (EvaluationException e) { +// e.printStackTrace(); +// logger.error("请求异常", e); +// } + return result; + } + + //处理集合中的特殊自定义 + public final static Object getObjFromScript(Map input, String fieldValue, List current) { + JSONObject formulaJson = JSON.parseObject(fieldValue); + //找到脚本中引用的字段,放入data中 + Object farr = formulaJson.get("farr"); + List fieldIds = new ArrayList<>(); + //字段cn为key,字段en为value + Map fieldMap = new HashMap<>(); + if (farr != null && !"".equals(farr)) { + List fieldList = JSONArray.parseArray(JSON.toJSONString(farr), JSONObject.class); + String inputParamStr = JSON.toJSONString(input); + for (JSONObject jsonObject : fieldList) { + String fieldCn = jsonObject.getString("fieldCn"); + String fieldEn = jsonObject.getString("fieldEn"); + Field field = new Field(); + field.setFieldEn(fieldEn); + field.setFieldCn(fieldCn); + field.setValueType(jsonObject.getInteger("valueType")); + Long id = jsonObject.getLong("id"); + if (fieldCn != null && fieldEn != null && !"".equals(fieldCn) && !"".equals(fieldEn)) { + fieldMap.put(fieldCn, field); + } + if (!jsonObject.containsKey("paramList")) { + fieldIds.add(id); + continue; + } + Map temp = JSON.parseObject(inputParamStr, Map.class); + //存在paramList需要单个字段取出 + JSONArray paramList = jsonObject.getJSONArray("paramList"); + for (int i = 0; i < paramList.size(); i++) { + JSONObject param = paramList.getJSONObject(i); + String en = param.getString("en"); + String value = param.getString("value"); + switch (param.getIntValue("type")) { + case ParamTypeConst.CONSTANT: + temp.put(en,value ); + break; + case ParamTypeConst.VARIABLE: + temp.put(en, ListOpUtils.getObjByKeyAndJson(current.get(0), value)); + break; + } + } + getFieldToInputByIds(Arrays.asList(id), temp); + input.put(fieldEn,temp.get(fieldEn)); + } + } + + if (fieldIds.size() > 0) { + getFieldToInputByIds(fieldIds, input); + } + //取出groovy脚本 + Object result = executeScript(formulaJson, fieldMap, input); + return result; + } + + //对正则取值 + public final static Object getObjFromRegex(Map input, String fieldValue) { + String result = fieldValue; + //校验是否使用了字段如果使用了则需要替换为值 + Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()()-]+@"); + Matcher matcher = pattern.matcher(fieldValue); + while (matcher.find()) { + String fieldEn = matcher.group().replace("@", ""); + Object value = ExecuteUtils.getObjFromMap(input, fieldEn); + String valueStr = ""; + if (value != null) { + valueStr = value.toString(); + } + result = result.replace("@" + fieldEn + "@", valueStr); + } + return result; + } + + //执行自定义脚本 + public final static Object executeScript(JSONObject formulaJson, Map fieldMap, Map input) { + String formula = formulaJson.getString("formula"); + //替换掉特殊的字符 + formula = formula.replace(">", ">"); //3>=6 && 3< 12 + formula = formula.replace("<", "<"); + //正则匹配自定义中用到的变量对其进行替换 + Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()()-]+@"); + Matcher matcher = pattern.matcher(formula); + String subexp = formula; + String exp = ""; + int j = 0; + Map data = new HashMap<>(); + while (matcher.find()) { + String fieldCN = matcher.group(0).replace("@", ""); + Field subField = fieldMap.get(fieldCN); + if (subField == null) { + return ""; + } + String fieldEn = subField.getFieldEn(); + String v = ""; + v = "" + input.get(fieldEn); + data.put(fieldEn, input.get(fieldEn)); + if (subexp.contains("def main")) { + // groovy脚本替换为动态参数 + v = "_['" + fieldEn + "']"; + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); + } else { + if (subField.getValueType() == 1 || subField.getValueType() == 4) { + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", v); + } else { + exp += subexp.substring(j, matcher.end()).replace("@" + fieldCN + "@", "'" + v + "'"); + } + } + j = matcher.end(); + } + + + exp += formula.substring(j, formula.length()); + Evaluator evaluator = new Evaluator(); + Object result = ""; + try { + if (exp.contains("def main")) { + // 执行groovy脚本 + + logger.warn("groovy:{},{}", exp, data); + result = groovy.executeForObject(exp, data); + } else if (exp.contains("def python_main(_):")) { + //执行python脚本 + result = python.executeForObject(exp, data); + } else { + //执行公式 + result = evaluator.evaluate(exp); + } + if (result.toString().startsWith("'")){ + //字符串 + result = result.toString().replace("'",""); + }else { + //数值 + if (StrUtils.isNum(result.toString())){ + String[] split = result.toString().split("\\."); + if (split.length>1&&StrUtils.strToLong(split[1])>0){ + result = StrUtils.strToDouble(result.toString()); + }else { + result = StrUtils.strToLong(split[0]); + } + } + } + } catch (EvaluationException e) { + e.printStackTrace(); + logger.error("请求异常", e); + } + + return result; + } + + //对groovy脚本执行结果进一步处理 + public static Map handleGroovyResult(Map map) { + + Iterator> iterator = map.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + if (entry.getKey().startsWith("_['") && entry.getKey().endsWith("']")) { + map.remove(entry.getKey()); + String key = entry.getKey().replace("_['", "").replace("']", ""); + map.put(key, entry.getValue()); + } + } + return map; + } + + //调用commonService根据ens取参数 + public static boolean getFieldToInputByEns(List fieldEns, Map input ){ + boolean result = commonService.getEngineField(fieldService.selectFieldListByEns(fieldEns), input); + return result; + } + //调用commonService根据ids取参数 + public static boolean getFieldToInputByIds(List ids, Map input ){ + boolean result = commonService.getFieldByIds(ids, input); + return result; + } + + // 解析nodeJson + public final static List getExecuteListFromNodeJson(EngineNode engineNode) { + JSONObject nodeJson = JSON.parseObject(engineNode.getNodeJson()); + String strategyStr = null; + switch (engineNode.getNodeType()) { + case 2://规则集 + strategyStr = JSON.toJSONString(nodeJson.getJSONObject("executeGroup").get("strategyList")); + break; + case 4://评分卡 + strategyStr = JSON.toJSONString(nodeJson.getJSONArray("scorecardList")); + break; + case 5://名单库 + strategyStr = JSON.toJSONString(nodeJson.getJSONArray("listDbList")); + break; + case 15://模型 + strategyStr = JSON.toJSONString(nodeJson.getJSONArray("modelList")); + break; + case 16://决策表 + strategyStr = JSON.toJSONString(nodeJson.getJSONArray("decisionTableList")); + break; + case 17://决策树 + strategyStr = JSON.toJSONString(nodeJson.getJSONArray("decisionTreeList")); + break; + + } + List maps = JSON.parseArray(strategyStr, Map.class); + return maps; + } + + //获取执行用的id列表 + public final static List getExecuteIdList(EngineNode engineNode, String idKey) { + List maps = ExecuteUtils.getExecuteListFromNodeJson(engineNode); + List executeIdList = new ArrayList<>(); + if (maps != null && maps.size() > 0) { + for (Map map : maps) { + if (map.containsKey(idKey)) { + Object o = map.get(idKey); + if (o != null) { + Long id = StrUtils.strToLong(String.valueOf(o)); + if (id != null) { + executeIdList.add(id); + } + } + + } + } + } + return executeIdList; + } + + //判断终止条件是否满足,满足则结束 + public final static void terminalCondition(EngineNode engineNode, Map inputParam, Map outMap, Map variablesMap) { + if (StringUtils.isBlank(engineNode.getNodeScript())) { + return; + } + JSONObject nodeScript = JSONObject.parseObject(engineNode.getNodeScript()); + JSONObject terminationInfo = nodeScript.getJSONObject("terminationInfo"); + String conditions = terminationInfo.getString("conditions"); + Map fieldTypeMap = terminationInfo.getObject("fieldTypeMap", Map.class); + JevalUtil.convertVariables(fieldTypeMap, variablesMap); + // 判断终止条件 + boolean result = false; + try { + result = JevalUtil.evaluateBoolean(conditions, variablesMap); + } catch (EvaluationException e) { + logger.error("终止条件执行异常,执行内容:{},参数:{}", conditions, variablesMap); + e.printStackTrace(); + } + + if (result) { + Object outValue = ""; + JSONObject output = terminationInfo.getJSONObject("output"); + String fieldValue = output.getString("fieldValue"); + String fieldCode = output.getString("fieldCode"); + int variableType = output.getInteger("variableType"); + switch (variableType) { + case 1: + outValue = fieldValue; + break; + case 2: + outValue = ExecuteUtils.getObjFromMap(inputParam, fieldValue); + break; + case 3: + outValue = ExecuteUtils.getObjFromScript(inputParam, fieldValue); + break; + } + // 输出终止结果 + if (outValue == null) { + outValue = ""; + } + if (outValue instanceof String) { + outMap.put("result", outValue); + } else { + outMap.put("result", JSONObject.toJSON(outValue)); + } + if (StringUtils.isNotBlank(fieldCode)) { + inputParam.put(fieldCode, outValue); + } + engineNode.setNextNodes(null); + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/JevalUtil.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/JevalUtil.java new file mode 100644 index 0000000..4662733 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/JevalUtil.java @@ -0,0 +1,168 @@ +package com.baoying.enginex.executor.util; + +import com.baoying.enginex.executor.common.constants.CommonConst; +import com.baoying.enginex.executor.engine.consts.EngineOperator; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; + +import java.util.Map; + +/** + * 表达式解析器入口 + * @author sunyk + * + */ +public class JevalUtil { + + /** + * 获取执行布尔值结果 + * @param expression + * @param params + * @return + * @throws EvaluationException + */ + public static Boolean evaluateBoolean(String expression,Map params) throws EvaluationException { + Evaluator evaluator = getEvaluator(params); + return evaluator.getBooleanResult(expression); + } + + /** + * 获取执行数字结果 + * @param expression + * @param params + * @return + * @throws EvaluationException + */ + public static Double evaluateNumric(String expression,Map params) throws EvaluationException{ + Evaluator evaluator = getEvaluator(params); + return evaluator.getNumberResult(expression); + } + + /** + * 获取执行String结果 + * @param expression + * @param params + * @return + * @throws EvaluationException + */ + public static String evaluateString(String expression,Map params) throws EvaluationException{ + Evaluator evaluator = getEvaluator(params); + return evaluator.evaluate(expression,false,true); + } + + /** + * 获取绑定参数的Evaluator + * @param params + * @return + * @throws EvaluationException + */ + private static Evaluator getEvaluator(Map params){ + Evaluator evaluator = new Evaluator(); + if(params != null && !params.isEmpty()){ + for (Map.Entry entry : params.entrySet()) { + if(null!=entry.getValue()){ + evaluator.putVariable(entry.getKey(), entry.getValue().toString()); + } + } + } + return evaluator; + } + + /** + * 根据区间表达式解析区间 + * @param expression,eg:[3,5],param:字段code + * @return + */ + public static String getNumericInterval(String expression,String param){ + StringBuffer result = new StringBuffer(); + //先把变量进行加工#{param} + param = EngineOperator.OPERATOR_VARIABLE_LEFT+param+EngineOperator.OPERATOR_VARIABLE_RIGHT; + //如果是纯数字,代表==,直接拼接 + if(!expression.startsWith(EngineOperator.OPERATOR_LEFT_PARENTHESES) && !expression.startsWith(EngineOperator.OPERATOR_LEFT_BRACKET) + && !expression.endsWith(EngineOperator.OPERATOR_RIGHT_PARENTHESES) && !expression.endsWith(EngineOperator.OPERATOR_RIGHT_BRACKET)){ + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_EQUALS_RELATION).append(CommonConst.SYMBOL_BLANK).append(expression); + return result.toString(); + } + //获取到取值区间 + String exp = expression.substring(1, expression.length()-1); + String[] segments = null; + if(exp.startsWith(CommonConst.SYMBOL_COMMA)){ + segments = new String[1]; + segments[0] = exp.substring(1); + }else{ + segments = exp.split(CommonConst.SYMBOL_COMMA); + } + //判断取值范围(,3)(4,) + if(segments.length == 1){ + //说明是(,3),(4,) + if(expression.substring(1, expression.length()-1).startsWith(CommonConst.SYMBOL_COMMA)){ + //以逗号开始(,3) + if(expression.endsWith(EngineOperator.OPERATOR_RIGHT_PARENTHESES)){ + //小括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_LESS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + }else if(expression.endsWith(EngineOperator.OPERATOR_RIGHT_BRACKET)){ + //大括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_LESS_EQUALS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + } + }else{ + //以逗号结尾(4,) + if(expression.startsWith(EngineOperator.OPERATOR_LEFT_PARENTHESES)){ + //小括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_GREATER_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + }else if(expression.startsWith(EngineOperator.OPERATOR_LEFT_BRACKET)){ + //大括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_GREATER_EQUALS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + } + } + }else if(segments.length == 2){ + //开始符号 + if(expression.startsWith(EngineOperator.OPERATOR_LEFT_PARENTHESES)){ + //小括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_GREATER_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + }else if(expression.startsWith(EngineOperator.OPERATOR_LEFT_BRACKET)){ + //大括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_GREATER_EQUALS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[0]); + } + //都是&&关系 + result.append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_AND_RELATION).append(CommonConst.SYMBOL_BLANK); + //结束符号 + if(expression.endsWith(EngineOperator.OPERATOR_RIGHT_PARENTHESES)){ + //小括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_LESS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[1]); + }else if(expression.endsWith(EngineOperator.OPERATOR_RIGHT_BRACKET)){ + //大括号 + result.append(param).append(CommonConst.SYMBOL_BLANK).append(EngineOperator.OPERATOR_LESS_EQUALS_RELATION).append(CommonConst.SYMBOL_BLANK).append(segments[1]); + } + } + return result.toString(); + } + + /** + * 变量值转义 + * @param fieldsMap + * @param variablesMap + * @return + */ + public static Map convertVariables(Map fieldsMap,Map variablesMap){ + if(CollectionUtil.isNotNullOrEmpty(variablesMap)){ + if(!CollectionUtil.isNotNullOrEmpty(fieldsMap)){ + return variablesMap; + } + String key = ""; + Integer value = null; + for (Map.Entry entry : variablesMap.entrySet()) { + key = entry.getKey(); + value = fieldsMap.get(key); + if(value == null){ + continue; + } + //2代表字符串 + if(value == 2){ + String variableValue = CommonConst.SYMBOL_SINGLE_QUOTA+String.valueOf(variablesMap.get(key))+CommonConst.SYMBOL_SINGLE_QUOTA; + variablesMap.put(key, variableValue); + } + } + } + return variablesMap; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ListOpUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ListOpUtils.java new file mode 100644 index 0000000..4857a7f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/ListOpUtils.java @@ -0,0 +1,106 @@ +package com.baoying.enginex.executor.util; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class ListOpUtils { + public static Map> recursionGroup(List param, List keys){ + return param.stream().collect(Collectors.groupingBy(item->{ + String cond = ""; + for (String key : keys) { + if (StringUtils.isNotBlank(cond)){ + cond+="_"; + } + cond += getObjByKeyAndJson(item,key); +// String[] split = key.split("\\."); +// if (split.length>1){ +// JSONObject jsonObject = item; +// for (int i = 0; i < split.length; i++) { +// if (i + * Description: md5加密工具类.
+ * Date: 2015年6月30日 上午10:30:23
+ * @since JDK 1.7 + * @see + */ +public class MD5 { + /** + * 全局数组 + */ + private static final String[] DIGITS = { "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "H", "i", + "j", "k", "l", "m", "n", "~", "$", "@", "%", "*", "#", "&", "!" }; + + public MD5() { + } + + /** + * byteToArrayString:(返回形式为数字跟字符串).
+ * @author wz + * @param bByte byte + * @return 返回形式为数字跟字符串 + */ + private static String byteToArrayString(byte bByte) { + int iRet = bByte; + if (iRet < 0) { + iRet += 256; + } + int iD1 = iRet / 32; + int iD2 = iRet % 32; + return DIGITS[iD1] + DIGITS[iD2]; + } + + /** + * byteToNum:(返回形式只为数字).
+ * @param bByte byte + * @return 返回形式只为数字 + */ + private static String byteToNum(byte bByte) { + int iRet = bByte; + System.out.println("iRet1=" + iRet); + if (iRet < 0) { + iRet += 256; + } + return String.valueOf(iRet); + } + + /** + * byteToString:(转换字节数组为16进制字串).
+ * @param bByte byte数组 + * @return 返回转换字节数组为16进制字串 + */ + private static String byteToString(byte[] bByte) { + StringBuffer sBuffer = new StringBuffer(); + for (int i = 0; i < bByte.length; i++) { + sBuffer.append(byteToArrayString(bByte[i])); + } + return sBuffer.toString(); + } + + /** + * GetMD5Code:(md5加密).
+ * @author wz + * @param param 需要加密的字段 + * @return 加密后的字段 + */ + public static String GetMD5Code(String param) { + String resultString = null; + try { + resultString = new String(param); + MessageDigest md = MessageDigest.getInstance("MD5"); + // md.digest() 该函数返回值为存放哈希值结果的byte数组 + resultString = byteToString(md.digest(param.getBytes())); + } catch (NoSuchAlgorithmException ex) { + ex.printStackTrace(); + } + return resultString; + } + + +// public static void main(String[] args) { +// MD5 getMD5 = new MD5(); +// System.out.println(getMD5.GetMD5Code("123456")); +// } + +} + diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/NumUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/NumUtils.java new file mode 100644 index 0000000..39b9f4f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/NumUtils.java @@ -0,0 +1,24 @@ +package com.baoying.enginex.executor.util; + + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NumUtils { + + public static double toDouble(Object o){ + double d = 0D; + if (o==null){ + return d; + } + try { + d = Double.valueOf(o.toString()).doubleValue(); + + }catch (Exception e){ + log.error("转换为double失败,原值:{}",o); + e.printStackTrace(); + } + return d; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StrUtils.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StrUtils.java new file mode 100644 index 0000000..a402980 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StrUtils.java @@ -0,0 +1,32 @@ +package com.baoying.enginex.executor.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StrUtils { + //判断是否为一个数字 + public static boolean isNum(String str){ + if (str==null||"".equals(str)){ + return false; + } + Pattern pattern = Pattern.compile("^(-|\\+)?\\d+(\\.\\d+)?$"); + Matcher isNum = pattern.matcher(str); + if (!isNum.matches()) { + return false; + } + return true; + } + //将字符串转为Long类型 + public static Long strToLong(String str){ + if (isNum(str)){ + return Long.valueOf(str); + } + return null; + } + public static Double strToDouble(String str){ + if (isNum(str)){ + return Double.valueOf(str); + } + return null; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StringUtil.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StringUtil.java new file mode 100644 index 0000000..95dc1d2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/StringUtil.java @@ -0,0 +1,465 @@ +package com.baoying.enginex.executor.util; + +import java.math.BigDecimal; +import java.util.*; + +/** + * @ClassName: StringUtil + * @Description: String 工具类 + * @author Bai_Keyang + * @date 2015-06-24 16:00:16 + */ +public class StringUtil { + + /** + *

判断是否是有效的字符串,空字符串为无效字符串

+ * + * @param str + * @return boolean + */ + public static boolean isValidStr(String str) { + return str != null && str.trim().length() > 0; + } + + /** + *

判断是字符串否是为空,字符串为空,返回 "",反之返回其字符串本身.

+ * + *

if str is null then convret str to "".

+ * + * @param str + * @return String + */ + public static String convertStrIfNull(String str) { + return str == null ? SysConstant.EMPTY_STRING : str; + } + + /** + *

根据字符串转换为布尔值.

+ * + * @param str + * @return boolean + */ + public static boolean getStrToBoolean(String str) { + return isValidStr(str) ? str.toLowerCase().trim().equals(SysConstant.TRUE) : false; + } + + /** + *

根据字符串转换为 整型(int)并返回;转换失败,则返回0.

+ * + *

convert str value to int. if fail,then return 0.

+ * + * @param str + * @return int + */ + public static int getStrToInt(String str) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException e) { + return 0; + } + } + + /** + *

根据字符串转换为 整型(int)并返回;转换失败,则返回 指定的值.

+ * + *

convert str value to int. if fail,then return defaultvalue.

+ * + * @param str + * @param defaultValue + * @return int + */ + public static int getStrToInt(String str, int defaultValue) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + /** + *

根据字符串转换为long.

+ * + * @param str + * @return long + */ + public static long getStrTolong(String str) { + long result = 0; + if (!isValidStr(str)) { + return result; + } + try { + result = Long.parseLong(str); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据字符串转换为double.

+ * + *

convert String to double

+ * + * @param str + * @return double + */ + public static double getStrTodouble(String str) { + double result = 0; + if (!isValidStr(str)) { + return result; + } + try { + result = Double.parseDouble(str); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据字符串转换为BigDecimal.

+ * + *

convert String object to BigDecimal

+ * + * @param str + * @return BigDecimal + */ + public static BigDecimal getStrToBigDecimal(String str) { + BigDecimal result = new BigDecimal(0); + if (!isValidStr(str)) { + return result; + } + try { + result = new BigDecimal(str); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据字符串转换为Integer.

+ * + *

convert String to Integer.

+ * + * @param str + * @return Integer + */ + public static Integer getStrToInteger(String str) { + Integer result = new Integer(0); + if (!isValidStr(str)) { + return result; + } + try { + result = Integer.valueOf(str); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据字符串转换为Long.

+ * + *

convert String to Long.

+ * + * @param str + * @return Long + */ + public static Long getStrToLong(String str) { + Long result = new Long(0); + if (!isValidStr(str)) { + return result; + } + try { + result = Long.valueOf(str.trim()); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据字符串转换为Double.

+ * + *

convert String to Double

+ * + * @param str + * @return Double + */ + public static Double getStrToDouble(String str) { + Double result = new Double(0); + if (!isValidStr(str)) { + return result; + } + try { + result = Double.valueOf(str); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return result; + } + + /** + *

根据数组转换为字符串,用","拼接.

+ *

例:

+ *

    String[] strArray = new String[]{"How","do","you","do"};

+ *

    拼接后字符串样例:How,do,you,do

+ * + *

convert Object array to String use ",".

+ * + * @param Object[] + * @return String + */ + public static String getArrToStr(Object[] obj) { + if (obj == null) { + return null; + } + + StringBuffer buffer = new StringBuffer(); + if (obj.length > 0) { + buffer.append(obj[0]); + } + + for (int m = 1; m < obj.length; m++) { + buffer.append(SysConstant.COMMA).append(obj[m]); + } + + return buffer.toString(); + } + + /** + *

去掉重复数据(1,2,3,2,4 => 1,2,3,4)

+ * + * @param metadata + * @param tagStr + * @return String + */ + public static String removeEqualStr(String metadata, String tagStr) { + if (!StringUtil.isValidStr(metadata)) { + return SysConstant.EMPTY_STRING; + } + Set set = new HashSet(); + String[] arr = metadata.split(tagStr); + for (String temp : arr) { + if (StringUtil.isValidStr(temp)) { + set.add(temp); + } + } + Iterator it = set.iterator(); + StringBuffer returnMetadata = new StringBuffer(); + while (it.hasNext()) { + returnMetadata.append(it.next() + tagStr); + } + return returnMetadata.toString().substring(0,returnMetadata.length() - 1); + } + + /** + *

查询是否有重复数据

+ * + * @param strArr + * @param str + * @param tagStr + * @return boolean + */ + public static boolean hasEqualStr(String strArr, String str, String tagStr) { + boolean bool = false; + if (StringUtil.isValidStr(strArr)) { + String[] arr = strArr.split(tagStr); + for (String temp : arr) { + if (temp.equals(str)) { + bool = true; + break; + } + } + } + return bool; + } + + /** + *

根据字符串将其转换编码为UTF-8的字符串.

+ * + *

convert type to utf-8

+ * + * @param str + * @return utf-8 string + */ + public static String toUtf8String(String str) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c >= 0 && c <= 255) { + sb.append(c); + } else { + byte[] b; + try { + b = Character.toString(c).getBytes("utf-8"); + } catch (Exception ex) { + b = new byte[0]; + } + for (int j = 0; j < b.length; j++) { + int k = b[j]; + if (k < 0) + k += 256; + sb.append("%" + Integer.toHexString(k).toUpperCase()); + } + } + } + return sb.toString(); + } + + /** + *

根据字符串指定的位置更新字符串内容

+ * + * @param formString 被更新字符串 + * @param updateIndex 选择更新位数 + * @param updateValue 更新为值 + * + * @return String + */ + public static String formatIntegrity(String formatString, int updateIndex, char updateValue) { + if (!isValidStr(formatString)) { + return formatString; + } + if (updateIndex < 1) { + return formatString; + } + if (updateIndex > formatString.length()) { + return formatString; + } + char[] formatStringChar = formatString.toCharArray(); + formatStringChar[updateIndex] = updateValue; + + return String.valueOf(formatStringChar); + } + + /** + *

转换特殊字符

+ * + * @param str 含有特殊字符的字符串 + * + * @return String + */ + public static String converSpecialChar(String str) { + if (!isValidStr(str)) { + return str; + } + str = str.trim(); + if (str.indexOf("\\") >= 0) { + str = str.replaceAll("\\\\", "\\\\\\\\\\\\\\\\"); + } + if (str.indexOf("'") >= 0) { + str = str.replaceAll("'", "\\\\'"); + } + if (str.indexOf("\"") >= 0) { + str = str.replaceAll("\"", "\\\\\""); + } + if (str.indexOf("%") >= 0) { + str = str.replaceAll("%", "\\\\%"); + } + return str; + } + + /** + *

获取字符串字节长度(包含中文和中文符号)

+ * + * @param str 含有中文和中文符号的字符串 + * + * @return int + */ + public static int getLength(String str){ + return str.replaceAll("[\u4E00-\u9FA5\u3000-\u303F\uFF00-\uFFEF]", "rr").length(); + } + + /** + *

此排序方法仅应用于数字类型的string数字排序

+ * + * @param arrays 有long类型的数字组成的String 数组 + * @return 排序后的数组 + */ + public static String[] sortArrays(String[] arrays){ + for(int i = 0; i < arrays.length - 1; i++) { + String temp =""; + for(int j = 0; j < arrays.length - i - 1; j++) { + if(StringUtil.getStrTolong(arrays[j]) >StringUtil.getStrTolong(arrays[j +1])) { + temp = arrays[j + 1]; + arrays[j + 1] = arrays[j]; + arrays[j] = temp; + } + } + } + return arrays; + } + + /** + *

此排序方法仅应用于浮点类型的string数字排序

+ * + * @param arrays 有浮点类型的数字组成的String 数组 + * @return 排序后的数组 + */ + public static String[] sortArraystoBigDecimal(String[] arrays) { + for (int i = 0; i < arrays.length - 1; i++) { + String temp = ""; + for (int j = 0; j < arrays.length - i - 1; j++) { + if (StringUtil.getStrToBigDecimal(arrays[j]).compareTo( + StringUtil.getStrToBigDecimal(arrays[j + 1])) == 1) { + temp = arrays[j + 1]; + arrays[j + 1] = arrays[j]; + arrays[j] = temp; + } + } + } + return arrays; + } + + /** + *

判断字符串是否为NUll,或者为空字符

+ * @param str 字符串 + * @return boolean + * */ + public static boolean isBlank(String str){ + if(str == null || str.equals("")){ + return true; + } + return false; + } + + + /** + *

将字符拆分,并放入list集合

+ * @param str 字符串 + * @return list + * */ + public static List toLongList(String str){ + List idList = new ArrayList(); + if(!isBlank(str)){ + String[] idsArray = str.split(","); + for (int i = 0; i < idsArray.length; i++) { + idList.add(Long.parseLong(idsArray[i])); + } + } + return idList; + } + + + public static String listToString(List list, char separator) { + return org.apache.commons.lang.StringUtils.join(list.toArray(),separator); + } + + public static void main(String[] args) { + //String result = "aaaa ,,aaa"; + //System.out.println(getLength(result)); + + String[] strArray = new String[]{"How","d$o","you","do"}; + strArray = new String[]{"5.36","5.003","1.36","9.87","3.33333379"}; + //strArray = StringUtil.sortArrays(strArray); + strArray = StringUtil.sortArraystoBigDecimal(strArray); + String str = StringUtil.getArrToStr(strArray); + System.out.println(str); + + //System.out.println(StringUtil.formatIntegrity("dkkemnkn", 2, '6')); + + } + + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/SysConstant.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/SysConstant.java new file mode 100644 index 0000000..3b63848 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/SysConstant.java @@ -0,0 +1,96 @@ +package com.baoying.enginex.executor.util; + +/** + * @ClassName: SysConstant + * @Description: 系统常量类 + * @author Bai_Keyang + * @date 2015-06-24 16:00:16 + */ +public final class SysConstant { + + public static final String EMPTY_STRING =""; + + public static final String SPACE =" "; + + public static final String COMMA =","; + + public static final String SEMICOLON =";"; + + public static final String MINUS ="-"; + + public static final String UNDERLINE ="_"; + + public static final String DATA_POINT ="."; + + public static final String POINT ="\\."; + + public static final String COLON =":"; + + public static final String WN ="// "; + + public static final String AT ="@"; + + public static final String SLASH ="/"; + + public static final String BACKSLASH ="\\\\"; + + public static final String YES ="Y"; + + public static final String NO ="N"; + + public static final String TRUE ="true"; + + public static final String FALSE ="false"; + + public static final String LEFT_BRACKET ="("; + + public static final String RIGHT_BRACKET =")"; + + public static final String ELLIPSIS ="..."; + + public static final String ESCAPE ="\\"; + + public static final String EXCLAMATION ="!"; + + public static final String INFINITY ="∞"; + + /** + * 系统统一操作成功码 + */ + public static final String SUCCESS_CODE = "200"; + + /** + * 系统统一操作成功提示信息 + */ + public static final String SUCCESS_MESSAGE = "操作成功"; + + /** + * 系统统一操作失败码 + */ + public static final String FAIL_CODE = "500"; + + /** + * 系统统一操作失败提示信息 + */ + public static final String FAIL_MESSAGE = "操作失败"; + + /** + * 系统统一操作失败码 + */ + public static final String UNUSE_CODE = "300"; + + /** + * 系统统一操作失败提示信息 + */ + public static final String UNUSE_MESSAGE = "已停用"; + + /** + * 系统统一操作失败码 + */ + public static final String DEL_CODE = "400"; + + /** + * 系统统一操作失败提示信息 + */ + public static final String DEL_MESSAGE = "已删除"; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpClient.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpClient.java new file mode 100644 index 0000000..f9d8b54 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpClient.java @@ -0,0 +1,320 @@ +package com.baoying.enginex.executor.util.https; + +import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.cookie.CookiePolicy; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.multipart.PartBase; +import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.commons.httpclient.params.HttpConnectionManagerParams; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +/** + * @author sinaWeibo + * + */ +public class HttpClient implements java.io.Serializable { + + static Logger log=LoggerFactory.getLogger(HttpClient.class); + + private static final long serialVersionUID = -176092625883595547L; + private static final int OK = 200; // OK: Success! + private static final int NOT_MODIFIED = 304; // Not Modified: There was no new data to return. + private static final int BAD_REQUEST = 400; // Bad Request: The request was invalid. An accompanying error message will explain why. This is the status versionCode will be returned during rate limiting. + private static final int NOT_AUTHORIZED = 401; // Not Authorized: Authentication credentials were missing or incorrect. + private static final int FORBIDDEN = 403; // Forbidden: The request is understood, but it has been refused. An accompanying error message will explain why. + private static final int NOT_FOUND = 404; // Not Found: The URI requested is invalid or the resource requested, such as a user, does not exists. + private static final int NOT_ACCEPTABLE = 406; // Not Acceptable: Returned by the Search API when an invalid format is specified in the request. + private static final int INTERNAL_SERVER_ERROR = 500;// Internal Server Error: Something is broken. Please post to the group so the Weibo team can investigate. + private static final int BAD_GATEWAY = 502;// Bad Gateway: Weibo is down or being upgraded. + private static final int SERVICE_UNAVAILABLE = 503;// Service Unavailable: The Weibo servers are up, but overloaded with requests. Try again later. The search and trend methods use this to indicate when you are being rate limited. + + private final static boolean DEBUG = true; + org.apache.commons.httpclient.HttpClient client = null; + + private MultiThreadedHttpConnectionManager connectionManager; + private int maxSize; + + public HttpClient() { + this(150, 30000, 30000, 1024 * 1024); + } + + public HttpClient(int maxConPerHost, int conTimeOutMs, int soTimeOutMs, + int maxSize) { + connectionManager = new MultiThreadedHttpConnectionManager(); + HttpConnectionManagerParams params = connectionManager.getParams(); + params.setDefaultMaxConnectionsPerHost(maxConPerHost); + params.setConnectionTimeout(conTimeOutMs); + params.setSoTimeout(soTimeOutMs); + + HttpClientParams clientParams = new HttpClientParams(); + // 忽略cookie 避免 Cookie rejected 警告 + clientParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES); + client = new org.apache.commons.httpclient.HttpClient(clientParams, + connectionManager); + Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443); + Protocol.registerProtocol("https", myhttps); + this.maxSize = maxSize; + } + + /** + * log调试 + * + */ + private static void log(String message) { + if (DEBUG) { + log.debug(message); + } + } + + /** + * 处理http getmethod 请求 + * + */ + public int getHttps(String url){ + log.debug(" in getHttps,url="+url); + GetMethod method = new GetMethod(url); + int responseCode = -1; + try { + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, + new DefaultHttpMethodRetryHandler(3, false)); + client.executeMethod(method); + responseCode = method.getStatusCode(); + log.info("https StatusCode:" + responseCode); + } catch (IOException ioe) { + ioe.printStackTrace(); + } finally { + method.releaseConnection(); + return responseCode; + } + } + public String get(String url) throws Exception { + return get(url, new PostParameter[0]).asString(); + } + + public Response get(String url, PostParameter[] params) + throws Exception { + log("Request:"); + log("GET:" + url); + if (null != params && params.length > 0) { + String encodedParams = HttpClient.encodeParameters(params); + if (-1 == url.indexOf("?")) { + url += "?" + encodedParams; + } else { + url += "&" + encodedParams; + } + } + GetMethod getmethod = new GetMethod(url); + return httpRequest(getmethod); + + } + + /** + * 处理http post请求 + * + */ + + public Response post(String url, PostParameter[] params) + throws Exception { + return post(url, params, true); + + } + + public Response post(String url, PostParameter[] params, + Boolean WithTokenHeader) throws HttpsException { + log("Request:"); + log("POST" + url); + PostMethod postMethod = new PostMethod(url); + for (int i = 0; i < params.length; i++) { + postMethod.addParameter(params[i].getName(), params[i].getValue()); + } + HttpMethodParams param = postMethod.getParams(); + param.setContentCharset("UTF-8"); + if (WithTokenHeader) { + return httpRequest(postMethod); + } else { + return httpRequest(postMethod, WithTokenHeader); + } + } + + /** + * 处理http post请求 + * + */ + + public String post(String url, Map params) + throws Exception { + String strResult = null; + + Response response= post(url, params, true); + if (response !=null) { + // 取出回应字串 + strResult = response.getResponseAsString(); + } + return strResult; + } + + public Response post(String url, Map params, + Boolean WithTokenHeader) throws HttpsException { + log("Request:"); + log("POST" + url); + PostMethod postMethod = new PostMethod(url); + postMethod.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8"); + + for (Map.Entry entry : params.entrySet()) { + postMethod.addParameter(entry.getKey(), entry + .getValue()); + } + + HttpMethodParams param = postMethod.getParams(); + param.setContentCharset("UTF-8"); + if (WithTokenHeader) { + return httpRequest(postMethod); + } else { + return httpRequest(postMethod, WithTokenHeader); + } + } + public Response httpRequest(HttpMethod method) throws HttpsException { + return httpRequest(method, true); + } + + public Response httpRequest(HttpMethod method, Boolean WithTokenHeader) + throws HttpsException { + InetAddress ipaddr; + int responseCode = -1; + try { + ipaddr = InetAddress.getLocalHost(); + List
headers = new ArrayList
(); + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, + new DefaultHttpMethodRetryHandler(3, false)); + client.executeMethod(method); + Header[] resHeader = method.getResponseHeaders(); + responseCode = method.getStatusCode(); + log("Response:"); + log("https StatusCode:" + String.valueOf(responseCode)); + + for (Header header : resHeader) { + log(header.getName() + ":" + header.getValue()); + } + Response response = new Response(); + response.setResponseAsString(method.getResponseBodyAsString()); + log(response.toString() + "\n"); + + if (responseCode != OK) + + { + try { + throw new HttpsException(getCause(responseCode)); + } catch (Exception e) { + e.printStackTrace(); + } + } + return response; + + } catch (IOException ioe) { + throw new HttpsException(ioe.getMessage(), ioe, responseCode); + } finally { + method.releaseConnection(); + } + + } + + /* + * 对parameters进行encode处理 + */ + public static String encodeParameters(PostParameter[] postParams) { + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < postParams.length; j++) { + if (j != 0) { + buf.append("&"); + } + try { + buf.append(URLEncoder.encode(postParams[j].getName(), "UTF-8")) + .append("=") + .append(URLEncoder.encode(postParams[j].getValue(), + "UTF-8")); + } catch (java.io.UnsupportedEncodingException neverHappen) { + } + } + return buf.toString(); + } + + private static class ByteArrayPart extends PartBase { + private byte[] mData; + private String mName; + + public ByteArrayPart(byte[] data, String name, String type) + throws IOException { + super(name, type, "UTF-8", "binary"); + mName = name; + mData = data; + } + + protected void sendData(OutputStream out) throws IOException { + out.write(mData); + } + + protected long lengthOfData() throws IOException { + return mData.length; + } + + protected void sendDispositionHeader(OutputStream out) + throws IOException { + super.sendDispositionHeader(out); + StringBuilder buf = new StringBuilder(); + buf.append("; filename=\"").append(mName).append("\""); + out.write(buf.toString().getBytes()); + } + } + + private static String getCause(int statusCode) { + String cause = null; + switch (statusCode) { + case NOT_MODIFIED: + break; + case BAD_REQUEST: + cause = "The request was invalid. An accompanying error message will explain why. This is the status versionCode will be returned during rate limiting."; + break; + case NOT_AUTHORIZED: + cause = "Authentication credentials were missing or incorrect."; + break; + case FORBIDDEN: + cause = "The request is understood, but it has been refused. An accompanying error message will explain why."; + break; + case NOT_FOUND: + cause = "The URI requested is invalid or the resource requested, such as a user, does not exists."; + break; + case NOT_ACCEPTABLE: + cause = "Returned by the Search API when an invalid format is specified in the request."; + break; + case INTERNAL_SERVER_ERROR: + cause = "Something is broken. Please post to the group so the Weibo team can investigate."; + break; + case BAD_GATEWAY: + cause = "Weibo is down or being upgraded."; + break; + case SERVICE_UNAVAILABLE: + cause = "Service Unavailable: The Weibo servers are up, but overloaded with requests. Try again later. The search and trend methods use this to indicate when you are being rate limited."; + break; + default: + cause = ""; + } + return statusCode + ":" + cause; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpsException.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpsException.java new file mode 100644 index 0000000..b28487f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/HttpsException.java @@ -0,0 +1,49 @@ +package com.baoying.enginex.executor.util.https; + +/** + * An exception class that will be thrown when WeiboAPI calls are failed.
+ * In case the Weibo server returned HTTP error versionCode, you can get the HTTP status versionCode using getStatusCode() method. + * @author Yusuke Yamamoto - yusuke at mac.com + */ +public class HttpsException extends Exception { + private int statusCode = -1; + private int errorCode = -1; + private String request; + private String error; + private static final long serialVersionUID = -2623309261327598087L; + + public HttpsException(String msg) { + super(msg); + } + + public HttpsException(Exception cause) { + super(cause); + } + + public HttpsException(String msg, Exception cause) { + super(msg, cause); + } + + public HttpsException(String msg, Exception cause, int statusCode) { + super(msg, cause); + this.statusCode = statusCode; + + } + + public int getStatusCode() { + return this.statusCode; + } + + public int getErrorCode() { + return errorCode; + } + + public String getRequest() { + return request; + } + + public String getError() { + return error; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/MySSLSocketFactory.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/MySSLSocketFactory.java new file mode 100644 index 0000000..f415676 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/MySSLSocketFactory.java @@ -0,0 +1,101 @@ +package com.baoying.enginex.executor.util.https; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.net.*; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** +Provide a custom socket factory that implements org.apache.commons.httpclient.protocol.ProtocolSocketFactory interface. +The socket factory is responsible for opening a socket to the target server using either the standard or a third party +SSL library and performing any required initialization such as performing the connection handshake. Generally the initialization +is performed automatically when the socket is created. +@author sinaWeibo +*/ +public class MySSLSocketFactory implements ProtocolSocketFactory { + private SSLContext sslcontext = null; + private SSLContext createSSLContext() { + SSLContext sslcontext = null; + try { + sslcontext = SSLContext.getInstance("SSL"); + sslcontext.init(null, + new TrustManager[] { new TrustAnyTrustManager() }, + new java.security.SecureRandom()); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } + return sslcontext; + } + + private SSLContext getSSLContext() { + if (this.sslcontext == null) { + this.sslcontext = createSSLContext(); + } + return this.sslcontext; + } + + public Socket createSocket(Socket socket, String host, int port, + boolean autoClose) throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket(socket, host, + port, autoClose); + } + + public Socket createSocket(String host, int port) throws IOException, + UnknownHostException { + return getSSLContext().getSocketFactory().createSocket(host, port); + } + + public Socket createSocket(String host, int port, InetAddress clientHost, + int clientPort) throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket(host, port, + clientHost, clientPort); + } + + public Socket createSocket(String host, int port, InetAddress localAddress, + int localPort, HttpConnectionParams params) throws IOException, + UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = getSSLContext().getSocketFactory(); + if (timeout == 0) { + return socketfactory.createSocket(host, port, localAddress, + localPort); + } else { + Socket socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, + localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + return socket; + } + } + + private static class TrustAnyTrustManager implements X509TrustManager { + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[] {}; + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/PostParameter.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/PostParameter.java new file mode 100644 index 0000000..699056d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/PostParameter.java @@ -0,0 +1,208 @@ +package com.baoying.enginex.executor.util.https; + +import java.io.File; +import java.net.URLEncoder; +import java.util.List; + + +/** + * A data class representing HTTP Post parameter + * @author Yusuke Yamamoto - yusuke at mac.com + */ +public class PostParameter implements java.io.Serializable{ + String name; + String value; + private File file = null; + + private static final long serialVersionUID = -8708108746980739212L; + + public PostParameter(String name, String value) { + this.name = name; + this.value = value; + } + + public PostParameter(String name, double value) { + this.name = name; + this.value = String.valueOf(value); + } + + public PostParameter(String name, int value) { + this.name = name; + this.value = String.valueOf(value); + } + + public PostParameter(String name, File file) { + this.name = name; + this.file = file; + } + + public String getName(){ + return name; + } + public String getValue(){ + return value; + } + + public File getFile() { + return file; + } + + public boolean isFile(){ + return null != file; + } + + private static final String JPEG = "image/jpeg"; + private static final String GIF = "image/gif"; + private static final String PNG = "image/png"; + private static final String OCTET = "application/octet-stream"; + + /** + * + * @return content-type + */ + public String getContentType() { + if (!isFile()) { + throw new IllegalStateException("not a file"); + } + String contentType; + String extensions = file.getName(); + int index = extensions.lastIndexOf("."); + if (-1 == index) { + // no extension + contentType = OCTET; + } else { + extensions = extensions.substring(extensions.lastIndexOf(".") + 1).toLowerCase(); + if (extensions.length() == 3) { + if ("gif".equals(extensions)) { + contentType = GIF; + } else if ("png".equals(extensions)) { + contentType = PNG; + } else if ("jpg".equals(extensions)) { + contentType = JPEG; + } else { + contentType = OCTET; + } + } else if (extensions.length() == 4) { + if ("jpeg".equals(extensions)) { + contentType = JPEG; + } else { + contentType = OCTET; + } + } else { + contentType = OCTET; + } + } + return contentType; + } + + + public static boolean containsFile(PostParameter[] params) { + boolean containsFile = false; + if(null == params){ + return false; + } + for (PostParameter param : params) { + if (param.isFile()) { + containsFile = true; + break; + } + } + return containsFile; + } + /*package*/ static boolean containsFile(List params) { + boolean containsFile = false; + for (PostParameter param : params) { + if (param.isFile()) { + containsFile = true; + break; + } + } + return containsFile; + } + + public static PostParameter[] getParameterArray(String name, String value) { + return new PostParameter[]{new PostParameter(name,value)}; + } + public static PostParameter[] getParameterArray(String name, int value) { + return getParameterArray(name,String.valueOf(value)); + } + + public static PostParameter[] getParameterArray(String name1, String value1 + , String name2, String value2) { + return new PostParameter[]{new PostParameter(name1, value1) + , new PostParameter(name2, value2)}; + } + public static PostParameter[] getParameterArray(String name1, int value1 + , String name2, int value2) { + return getParameterArray(name1,String.valueOf(value1),name2,String.valueOf(value2)); + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + value.hashCode(); + result = 31 * result + (file != null ? file.hashCode() : 0); + return result; + } + + @Override public boolean equals(Object obj) { + if (null == obj) { + return false; + } + if (this == obj) { + return true; + } + if (obj instanceof PostParameter) { + PostParameter that = (PostParameter) obj; + + if (file != null ? !file.equals(that.file) : that.file != null) + return false; + + return this.name.equals(that.name) && + this.value.equals(that.value); + } + return false; + } + + @Override + public String toString() { + return "PostParameter{" + + "name='" + name + '\'' + + ", value='" + value + '\'' + + ", file=" + file + + '}'; + } + + public int compareTo(Object o) { + int compared; + PostParameter that = (PostParameter) o; + compared = name.compareTo(that.name); + if (0 == compared) { + compared = value.compareTo(that.value); + } + return compared; + } + + public static String encodeParameters(PostParameter[] httpParams) { + if (null == httpParams) { + return ""; + } + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < httpParams.length; j++) { + if (httpParams[j].isFile()) { + throw new IllegalArgumentException("parameter [" + httpParams[j].name + "]should be text"); + } + if (j != 0) { + buf.append("&"); + } + try { + buf.append(URLEncoder.encode(httpParams[j].name, "UTF-8")) + .append("=").append(URLEncoder.encode(httpParams[j].value, "UTF-8")); + } catch (java.io.UnsupportedEncodingException neverHappen) { + } + } + return buf.toString(); + + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/Response.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/Response.java new file mode 100644 index 0000000..9d60b9a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/https/Response.java @@ -0,0 +1,225 @@ +package com.baoying.enginex.executor.util.https; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.*; +import java.net.HttpURLConnection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.GZIPInputStream; + +/** + * A data class representing HTTP Response + * + * @author Yusuke Yamamoto - yusuke at mac.com + */ +public class Response { + private final static boolean DEBUG = true; + static Logger log = LoggerFactory.getLogger(Response.class.getName()); + + + private static ThreadLocal builders = + new ThreadLocal() { + @Override + protected DocumentBuilder initialValue() { + try { + return + DocumentBuilderFactory.newInstance() + .newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new ExceptionInInitializerError(ex); + } + } + }; + + private int statusCode; + private Document responseAsDocument = null; + private String responseAsString = null; + private InputStream is; + private HttpURLConnection con; + private boolean streamConsumed = false; + + public Response() { + + } + public Response(HttpURLConnection con) throws IOException { + this.con = con; + this.statusCode = con.getResponseCode(); + if(null == (is = con.getErrorStream())){ + is = con.getInputStream(); + } + if (null != is && "gzip".equals(con.getContentEncoding())) { + // the response is gzipped + is = new GZIPInputStream(is); + } + } + + // for test purpose + /*package*/ Response(String content) { + this.responseAsString = content; + } + + public int getStatusCode() { + return statusCode; + } + + public String getResponseHeader(String name) { + if (con != null) + return con.getHeaderField(name); + else + return null; + } + + /** + * Returns the response stream.
+ * This method cannot be called after calling asString() or asDcoument()
+ * It is suggested to call disconnect() after consuming the stream. + * + * Disconnects the internal HttpURLConnection silently. + * @return response body stream + * @throws HttpsException + * @see #disconnect() + */ + public InputStream asStream() { + if(streamConsumed){ + throw new IllegalStateException("Stream has already been consumed."); + } + return is; + } + + /** + * Returns the response body as string.
+ * Disconnects the internal HttpURLConnection silently. + * @return response body + * @throws HttpsException + */ + public String asString() throws HttpsException{ + if(null == responseAsString){ + BufferedReader br; + try { + InputStream stream = asStream(); + if (null == stream) { + return null; + } + br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + StringBuffer buf = new StringBuffer(); + String line; + while (null != (line = br.readLine())) { + buf.append(line).append("\n"); + } + this.responseAsString = buf.toString(); + /* if(Configuration.isDalvik()){ + this.responseAsString = unescape(responseAsString); + }*/ + log(responseAsString); + stream.close(); + con.disconnect(); + streamConsumed = true; + } catch (NullPointerException npe) { + // don't remember in which case npe can be thrown + throw new HttpsException(npe.getMessage(), npe); + } catch (IOException ioe) { + throw new HttpsException(ioe.getMessage(), ioe); + } + } + return responseAsString; + } + + /** + * Returns the response body as org.w3c.dom.Document.
+ * Disconnects the internal HttpURLConnection silently. + * @return response body as org.w3c.dom.Document + * @throws HttpsException + */ + public Document asDocument() throws HttpsException { + if (null == responseAsDocument) { + try { + // it should be faster to read the inputstream directly. + // but makes it difficult to troubleshoot + this.responseAsDocument = builders.get().parse(new ByteArrayInputStream(asString().getBytes("UTF-8"))); + } catch (SAXException saxe) { + throw new HttpsException("The response body was not well-formed:\n" + responseAsString, saxe); + } catch (IOException ioe) { + throw new HttpsException("There's something with the connection.", ioe); + } + } + return responseAsDocument; + } + + public InputStreamReader asReader() { + try { + return new InputStreamReader(is, "UTF-8"); + } catch (java.io.UnsupportedEncodingException uee) { + return new InputStreamReader(is); + } + } + + public void disconnect(){ + con.disconnect(); + } + + private static Pattern escaped = Pattern.compile("&#([0-9]{3,5});"); + + /** + * Unescape UTF-8 escaped characters to string. + * @author pengjianq...@gmail.com + * + * @param original The string to be unescaped. + * @return The unescaped string + */ + public static String unescape(String original) { + Matcher mm = escaped.matcher(original); + StringBuffer unescaped = new StringBuffer(); + while (mm.find()) { + mm.appendReplacement(unescaped, Character.toString( + (char) Integer.parseInt(mm.group(1), 10))); + } + mm.appendTail(unescaped); + return unescaped.toString(); + } + + @Override + public String toString() { + if(null != responseAsString){ + return responseAsString; + } + return "Response{" + + "statusCode=" + statusCode + + ", response=" + responseAsDocument + + ", responseString='" + responseAsString + '\'' + + ", is=" + is + + ", con=" + con + + '}'; + } + + private void log(String message) { + if (DEBUG) { + log.debug("[" + new java.util.Date() + "]" + message); + } + } + + private void log(String message, String message2) { + if (DEBUG) { + log(message + message2); + } + } + + public String getResponseAsString() { + return responseAsString; + } + + public void setResponseAsString(String responseAsString) { + this.responseAsString = responseAsString; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ArgumentTokenizer.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ArgumentTokenizer.java new file mode 100644 index 0000000..5b9597f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ArgumentTokenizer.java @@ -0,0 +1,119 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import java.util.Enumeration; + +/** + * This class allow for tokenizer methods to be called on a String of arguments. + */ +public class ArgumentTokenizer implements Enumeration { + + /** + * The default delimitor. + */ + public final char defaultDelimiter = + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR; + + // The arguments to be tokenized. This is updated every time the nextToken + // method is called. + private String arguments = null; + + // The separator between the arguments. + private char delimiter = defaultDelimiter; + + /** + * Constructor that takes a String of arguments and a delimitoer. + * + * @param arguments + * The String of srguments to be tokenized. + * @param delimiter + * The argument tokenizer. + */ + public ArgumentTokenizer(final String arguments, final char delimiter) { + this.arguments = arguments; + this.delimiter = delimiter; + } + + /** + * Indicates if there are more elements. + * + * @return True if there are more elements and false if not. + */ + public boolean hasMoreElements() { + return hasMoreTokens(); + } + + /** + * Indicates if there are more tokens. + * + * @return True if there are more tokens and false if not. + */ + public boolean hasMoreTokens() { + + if (arguments.length() > 0) { + return true; + } + + return false; + } + + /** + * Returns the next element. + * + * @return The next element. + */ + public Object nextElement() { + return nextToken(); + } + + /** + * Returns the next token. + * + * @return The next element. + */ + public String nextToken() { + int charCtr = 0; + int size = arguments.length(); + int parenthesesCtr = 0; + String returnArgument = null; + + // Loop until we hit the end of the arguments String. + while (charCtr < size) { + if (arguments.charAt(charCtr) == '(') { + parenthesesCtr++; + } else if (arguments.charAt(charCtr) == ')') { + parenthesesCtr--; + } else if (arguments.charAt(charCtr) == delimiter + && parenthesesCtr == 0) { + + returnArgument = arguments.substring(0, charCtr); + arguments = arguments.substring(charCtr + 1); + break; + } + + charCtr++; + } + + if (returnArgument == null) { + returnArgument = arguments; + arguments = ""; + } + + return returnArgument; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationConstants.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationConstants.java new file mode 100644 index 0000000..877eb1a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationConstants.java @@ -0,0 +1,63 @@ +package com.baoying.enginex.executor.util.jeval; + +/** + * Contains constants used by classes in this package. + */ +public class EvaluationConstants { + + /** + * The single quote character. + */ + public static final char SINGLE_QUOTE = '\''; + + /** + * The double quote character. + */ + public static final char DOUBLE_QUOTE = '"'; + + /** + * The open brace character. + */ + public static final char OPEN_BRACE = '{'; + + /** + * The closed brace character. + */ + public static final char CLOSED_BRACE = '}'; + + /** + * The pound sign character. + */ + public static final char POUND_SIGN = '#'; + + /** + * The open variable string. + */ + public static final String OPEN_VARIABLE = String.valueOf(POUND_SIGN) + + String.valueOf(OPEN_BRACE); + + /** + * The closed brace string. + */ + public static final String CLOSED_VARIABLE = String.valueOf(CLOSED_BRACE); + + /** + * The true value for a Boolean string. + */ + public static final String BOOLEAN_STRING_TRUE = "1.0"; + + /** + * The false value for a Boolean string. + */ + public static final String BOOLEAN_STRING_FALSE = "0.0"; + + /** + * The comma character. + */ + public static final char COMMA = ','; + + /** + * The function argument separator. + */ + public static final char FUNCTION_ARGUMENT_SEPARATOR = COMMA; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationException.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationException.java new file mode 100644 index 0000000..548a14f --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationException.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +/** + * This exception is thrown when an error occurs during the evaluation process. + */ +public class EvaluationException extends Exception { + + private static final long serialVersionUID = -3010333364122748053L; + + /** + * This constructor takes a custom message as input. + * + * @param message + * A custom message for the exception to display. + */ + public EvaluationException(String message) { + super(message); + } + + /** + * This constructor takes an exception as input. + * + * @param exception + * An exception. + */ + public EvaluationException(Exception exception) { + super(exception); + } + + /** + * This constructor takes an exception as input. + * + * @param message + * A custom message for the exception to display. + * @param exception + * An exception. + */ + public EvaluationException(String message, Exception exception) { + super(message, exception); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationHelper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationHelper.java new file mode 100644 index 0000000..3a94b9e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationHelper.java @@ -0,0 +1,87 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +public class EvaluationHelper { + + /** + * Replaces all old string within the expression with new strings. + * + * @param expression + * The string being processed. + * @param oldString + * The string to replace. + * @param newString + * The string to replace the old string with. + * + * @return The new expression with all of the old strings replaced with new + * strings. + */ + public static String replaceAll(final String expression, + final String oldString, final String newString) { + + String replacedExpression = expression; + + if (replacedExpression != null) { + int charCtr = 0; + int oldStringIndex = replacedExpression.indexOf(oldString, charCtr); + + while (oldStringIndex > -1) { + // Remove the old string from the expression. + final StringBuffer buffer = new StringBuffer(replacedExpression + .substring(0, oldStringIndex) + + replacedExpression.substring(oldStringIndex + + oldString.length())); + + // Insert the new string into the expression. + buffer.insert(oldStringIndex, newString); + + replacedExpression = buffer.toString(); + + charCtr = oldStringIndex + newString.length(); + + // Determine if we need to continue to search. + if (charCtr < replacedExpression.length()) { + oldStringIndex = replacedExpression.indexOf(oldString, + charCtr); + } else { + oldStringIndex = -1; + } + } + } + + return replacedExpression; + } + + /** + * Determines if a character is a space or white space. + * + * @param character + * The character being evaluated. + * + * @return True if the character is a space or white space and false if not. + */ + public static boolean isSpace(final char character) { + + if (character == ' ' || character == '\t' || character == '\n' + || character == '\r' || character == '\f') { + return true; + } + + return false; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationResult.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationResult.java new file mode 100644 index 0000000..59e820c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/EvaluationResult.java @@ -0,0 +1,177 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +/** + * This class can be used to wrap the result of an expression evaluation. It + * contains useful methods for evaluating the contents of the result. + */ +public class EvaluationResult { + + // The value returned from the evaluation of an expression. + private String result; + + // The quote character specified in the evaluation of the expression. + private char quoteCharacter; + + /** + * Constructor. + * + * @param result + * The value returned from the evaluation of an expression. + * @param quoteCharacter + * The quote character specified in the evaluation of the + * expression. + */ + public EvaluationResult(String result, char quoteCharacter) { + + this.result = result; + this.quoteCharacter = quoteCharacter; + } + + /** + * Returns the quote character. + * + * @return The quote character. + */ + public char getQuoteCharacter() { + return quoteCharacter; + } + + /** + * Sets the quote character. + * + * @param quoteCharacter + * The quoteCharacter to set. + */ + public void setQuoteCharacter(char quoteCharacter) { + this.quoteCharacter = quoteCharacter; + } + + /** + * Returns the result value. + * + * @return The result value. + */ + public String getResult() { + return result; + } + + /** + * Sets the result value. + * + * @param result + * The result to set. + */ + public void setResult(String result) { + this.result = result; + } + + /** + * Returns true if the result value is equal to the value of a Boolean true + * string (1.0). + * + * @return True if the result value is equal to the value of a Boolean true + * string (1.0). + */ + public boolean isBooleanTrue() { + + if (result != null + && EvaluationConstants.BOOLEAN_STRING_TRUE.equals(result)) { + + return true; + } + + return false; + } + + /** + * Returns true if the result value is equal to the value of a Boolean false + * string (0.0). + * + * @return True if the result value is equal to the value of a Boolean false + * string (0.0). + */ + public boolean isBooleanFalse() { + + if (result != null + && EvaluationConstants.BOOLEAN_STRING_FALSE.equals(result)) { + + return true; + } + + return false; + } + + /** + * Returns true if the result value starts with a quote character and ends + * with a quote character. + * + * @return True if the result value starts with a quote character and ends + * with a quote character. + */ + public boolean isString() { + + if (result != null && result.length() >= 2) { + + if (result.charAt(0) == quoteCharacter + && result.charAt(result.length() - 1) == quoteCharacter) { + + return true; + } + } + + return false; + } + + /** + * Returns a Double for the result value. + * + * @return A Double for the result value. + * + * @throws NumberFormatException + * Thrown if the result value is not a double. + */ + public Double getDouble() throws NumberFormatException { + + return new Double(result); + } + + /** + * Returns the unwrapped string for the result value. An unwrapped string is + * a string value without the quote characters that wrap the result value. + * For a string to be returned, then the first character must be a quote + * character and the last character must be a quote character. Otherwise, a + * null value is returned. + * + * @return The normal string for the result value. Null will be returned if + * the result value is not of a string type. + */ + public String getUnwrappedString() { + + if (result != null && result.length() >= 2) { + + if (result.charAt(0) == quoteCharacter + && result.charAt(result.length() - 1) == quoteCharacter) { + + return result.substring(1, result.length() - 1); + } + } + + return null; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/Evaluator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/Evaluator.java new file mode 100644 index 0000000..9c6fc7b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/Evaluator.java @@ -0,0 +1,1703 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.function.*; +import com.baoying.enginex.executor.util.jeval.function.math.MathFunctions; +import com.baoying.enginex.executor.util.jeval.function.string.StringFunctions; +import com.baoying.enginex.executor.util.jeval.operator.*; + +import java.util.*; + +/** + * This class is used to evaluate mathematical, string, Boolean and functional + * expressions. It is the main entry point into the JEval API.
+ *
+ * The following types of expressions are supported:
+ *
    + *
  • mathematical Expression involving numbers. Numbers are treated + * as doubles, so resulting numbers will contain at least one decimal place.
  • + *
  • string String can also be added together, compared, etc...
  • + *
  • Boolean Expression that evaluate to true (1.0) and false (0.0).
  • + *
  • functional Custom functions can be created or there are many + * Math and String functions that JEval supplies with this class.
  • + *
+ * The following operators are supported:
+ *
    + *
  • ( open parentheses
  • + *
  • ) closed parentheses
  • + *
  • + addition (for numbers and strings)
  • + *
  • - subtraction
  • + *
  • * multiplication
  • + *
  • / division
  • + *
  • % modulus
  • + *
  • + unary plus
  • + *
  • - unary minus
  • + *
  • = equal (for numbers and strings)
  • + *
  • != not equal (for numbers and strings)
  • + *
  • < less than (for numbers and strings)
  • + *
  • <= less than or equal (for numbers and strings)
  • + *
  • > greater than (for numbers and strings)
  • + *
  • >= greater than or equal (for numbers and strings)
  • + *
  • && boolean and
  • + *
  • || boolean or
  • + *
  • ! boolean not
  • + *
+ * Allows for prebuilt and custom functions.
+ *
    + *
  • JEval already comes with many functions which represent most of the + * methods in the Math and String classes in the standard JDK.
  • + *
  • Thirty-nine math and string functions come built in. See the + * net.sourceforge.jeval.functions.math and + * net.sourceforge.jeval.functions.string packages for details on these ready to + * use functions. You can choose to not load these functions if we you want to + * gain a small improvement in performance.
  • + *
  • Functions must be followed by an open parentheses and a closed + * parentheses which contain any required parameters.
  • + *
  • For more details on functions, see the Function class and the test + * classes.
  • + *
+ * Allows for variables.
+ *
    + *
  • Variable must be enclosed by a pound sign and open brace #{ and a closed + * brace }. i.e. expression = "#{a} + #{b}"
  • + *
  • Two math variables come built in. The E and PI variables represent the + * same value as the Math.E and Math.PI constants in the standard Java SDK. You + * can choose not to load these variables.
  • + *
+ * Notes on expression parsing: + *
    + *
  • Spaces are ignored when parsing expressions.
  • + *
  • The order of precedence used by this class is as follows from highest to + * lowest.
  • + *
  • The expression is evaluated as one or more subexpressions. + * Subexpressions within open parentheses and closed parentheses are evaluated + * before other parts of the expression.
  • + *
  • Inner most subexpression are evaluated first working outward.
  • + *
  • Subexpressions at the same level are evaluated from left to right.
  • + *
  • When evaluating expressions and subexpressions, operators are evaluated + * with the following precedence listed below.
  • + *
  • Operators with with the same precedence are evaluated from left to + * right.
  • + *
  • Once the expression is parsed, Variables are replaced with their values. + * The evaluator has its own internal variable map that it used to resolve + * variable values. All of the variable related methods on the evaluator refer + * to this internal map. You can choose to set you own variable resolver on your + * evaluator instance. If you do this, then variables resolved by your resolver + * will override any variables in the evaluator's internal variable map.
  • + *
  • Functions are then executed and replaced with their results. Function + * arguments are each individually evaluated as subexpressions that are comma + * separated. This gives you the ability to use nested functions in your + * expressions. You can choose not to evaluate function arguments as expressions + * and instead let the functions handle the arguments themselves. This in effect + * turns off nested expressions, unless you versionCode nested expression support into + * your own custom functions.
  • + *
  • Once all variables and functions are resolved, then the parsed + * expression and subexpressions are evaluated according to operator precedence.
  • + *
+ * Operator precedence: + *
    + *
  • + unary plus, - unary minus, ! boolean not
  • + *
  • * multiplication, / division, % modulus
  • + *
  • + addition, - subtraction
  • + *
  • < less than, <= less than or equal, > greater than, >= greater than or + * equal
  • + *
  • = equal, != not equal
  • + *
  • && boolean and
  • + *
  • || boolean or
  • + *
+ * Function and variable names can not break any of the following rules:
+ *
    + *
  • can not start with a number
  • + *
  • can not contain an operator (see the above list of operators)/li> + *
  • can not contain a quote character - single or double/li> + *
  • can not contain a brace character - open or closed/li> + *
  • can not contain one of the following special characters: #, ~ , ^ !
  • + *
+ * Other Notes: + *
    + *
  • This class is not thread safe.
  • + *
  • Allows for the quote character (single or double) to be specified at run + * time. Quote characters are required for specifying string values.
  • + *
  • Expressions can contain different types of expressions within the same + * expression. However, Numeric and string types can not be mixed in a left / + * right operand pair.
  • + *
  • An expression can be parsed before being evaluated by calling the parse() + * method. This may save on response time if parsing takes more than a few + * seconds. However, parsing is usually very fast, so this is probably not + * needed.
  • + *
  • If an expression does not change, it will not be parsed each + * time the expression is evaluated. Therefore, variables values can change and + * the expression can be evaluated again without having to re-parse the + * expression.
  • + *
  • Nested functions calls are supported. Nested function support can be + * turned off to improve performance. Custom functions can be coded to handle + * nested calls instead if desired.
  • + *
  • The string used to start variables, "#{", can not appear in an + * expression. + *
  • See the evaluate methods in this class, JUnit tests and samples for more + * details.
  • + *
+ */ +public class Evaluator { + + // Contains all of the operators. + private List operators = new ArrayList(); + + // Contains all of the functions in use. + private Map functions = new HashMap(); + + // Contains all of the variables in use. + private Map variables = new HashMap(); + + // The quote character in use. + private char quoteCharacter = EvaluationConstants.SINGLE_QUOTE; + + // The open parentheses operator. + private Operator openParenthesesOperator = new OpenParenthesesOperator(); + + // The closed parentheses operator. + private Operator closedParenthesesOperator = new ClosedParenthesesOperator(); + + // Indicates if the user wants to load the system math variables. + private boolean loadMathVariables; + + // Indicates if the user wants to load the system math functions. + private boolean loadMathFunctions; + + // Indicates if the user wants to load the system string functions. + private boolean loadStringFunctions; + + // Indicates if the user wants to process nested function calls. + private boolean processNestedFunctions; + + // Saves the previous expression, because we do not want to parse it, if + // it did not change. + private String previousExpression = null; + + // The previous stack of parsed operators + private Stack previousOperatorStack = null; + + // The previous stack of parsed operands. + private Stack previousOperandStack = null; + + // The stack of parsed operators + private Stack operatorStack = null; + + // The stack of parsed operands. + private Stack operandStack = null; + + // Allows for user to set their own variable resolver. + private VariableResolver variableResolver = null; + + /** + * The default constructor. This constructor calls the five parameter + * Evaluator constructor and passes in the following default values: + * SINGLE_QUOTE, true, true, true and true. + */ + public Evaluator() { + this(EvaluationConstants.SINGLE_QUOTE, true, true, true, true); + } + + /** + * The main constructor for Evaluator. + * + * @param quoteCharacter + * The quote character to use when evaluating expression. + * @param loadMathVariables + * Indicates if the standard Math variables should be loaded or + * not. + * @param loadMathFunctions + * Indicates if the standard Math functions should be loaded or + * not. + * @param loadStringFunctions + * Indicates if the standard String functions should be loaded or + * not. + * @param processNestedFunctions + * Indicates if nested function calls should be processed or not. + * + * @exception IllegalArgumentException + * Thrown when the quote character is not a valid quote + * character. + */ + public Evaluator(final char quoteCharacter, + final boolean loadMathVariables, final boolean loadMathFunctions, + final boolean loadStringFunctions, + final boolean processNestedFunctions) { + + // Install the operators used by Evaluator. + installOperators(); + + // Install the system variables. + this.loadMathVariables = loadMathVariables; + loadSystemVariables(); + + // Install the system functions. + this.loadMathFunctions = loadMathFunctions; + this.loadStringFunctions = loadStringFunctions; + loadSystemFunctions(); + + // Set the default quote character. + setQuoteCharacter(quoteCharacter); + + // Process nested function calls. + this.processNestedFunctions = processNestedFunctions; + } + + /** + * Returns the current quote character in use. + * + * @return The quote character in use. + */ + public char getQuoteCharacter() { + return quoteCharacter; + } + + /** + * Sets the quote character to use when evaluating expressions. + * + * @param quoteCharacter + * The quote character to use when evaluating expressions. + * + * @exception IllegalArgumentException + * Thrown when the quote character is not a valid quote + * character. + */ + public void setQuoteCharacter(final char quoteCharacter) { + if (quoteCharacter == EvaluationConstants.SINGLE_QUOTE + || quoteCharacter == EvaluationConstants.DOUBLE_QUOTE) { + this.quoteCharacter = quoteCharacter; + } else { + throw new IllegalArgumentException("Invalid quote character."); + } + } + + /** + * Adds a function to the list of functions to use when evaluating + * expressions. + * + * @param function + * The function being added. + * + * @exception IllegalArgumentException + * Thrown when the function name is not valid or the function + * name is already in use. + */ + public void putFunction(final Function function) { + // Make sure the function name is valid. + isValidName(function.getName()); + + // Make sure the function name isn't already in use. + final Function existingFunction = (Function) functions.get(function + .getName()); + + if (existingFunction == null) { + functions.put(function.getName(), function); + } else { + throw new IllegalArgumentException("A function with the same name " + + "already exists."); + } + } + + /** + * Returns a funtion from the list of functions. If the function can not be + * found in the list of functions, then null will be returned. + * + * @param functionName + * The name of the function to retrieve the value for. + * + * @return The value for a function in the list of function. + */ + public Function getFunction(final String functionName) { + return (Function) functions.get(functionName); + } + + /** + * Removes the function from the list of functions to use when evaluating + * expressions. + * + * @param functionName + * The name of the function to remove. + */ + public void removeFunction(final String functionName) { + if (functions.containsKey(functionName)) { + functions.remove(functionName); + } else { + throw new IllegalArgumentException("The function does not exist."); + } + } + + /** + * Removes all of the functions at one time. + */ + public void clearFunctions() { + // Remove all functions. + functions.clear(); + + // Reload the system functions if necessary. + loadSystemFunctions(); + } + + /** + * Rturns the map of functions currently set on this object. + * + * @return the map of functions currently set on this object. + */ + public Map getFunctions() { + return functions; + } + + /** + * Sets the map of functions for this object. + * + * @param functions The map of functions for this object. + */ + public void setFunctions(Map functions) { + this.functions = functions; + } + + /** + * Adds or replaces a variable to the list of variables to use when + * evaluating expressions. If the variable already exists, then its value + * will be overlaid. + * + * @param variableName + * The name of the variable being set. + * @param variableValue + * The value for the variable being set. + */ + public void putVariable(final String variableName, + final String variableValue) { + // Make sure the variable name is valid. + isValidName(variableName); + + variables.put(variableName, variableValue); + } + + /** + * Returns the value for a variable in the list of variables. If the + * variable can not be found in the list of variables, then null will be + * returned. + * + * @param variableName + * The name of the variable to retrieve the value for. + * + * @return The value for a variable in the list of variables. + * + * @throws Throws + * an EvaluatorException if the variable name can not be + * resolved. + */ + public String getVariableValue(final String variableName) + throws EvaluationException { + + String variableValue = null; + + /* + * If the user has implemented a variable resolver and set it onto this + * object, then use it before looking in the variable map. + */ + if (variableResolver != null) { + + try { + variableValue = variableResolver.resolveVariable(variableName); + } catch (FunctionException fe) { + throw new EvaluationException(fe.getMessage(), fe); + } + } + + /* + * If no variable value at this point, then go to the internal variable + * map to resolve the variable. + */ + if (variableValue == null) { + + variableValue = (String) variables.get(variableName); + } + + if (variableValue == null) { + + throw new EvaluationException( + "Can not resolve variable with name equal to \"" + + variableName + "\"."); + } + + return variableValue; + } + + /** + * Removes the variable from the list of variables to use when evaluating + * expressions. + * + * @param variableName + * The name of the variable to remove. + */ + public void removeVaraible(final String variableName) { + if (variables.containsKey(variableName)) { + variables.remove(variableName); + } else { + throw new IllegalArgumentException("The variable does not exist."); + } + } + + /** + * Removes all of the variables at one time. + */ + public void clearVariables() { + // Remove all functions. + variables.clear(); + + // Reload the system variables if necessary. + loadSystemVariables(); + } + + /** + * Rturns the map of variables currently set on this object. + * + * @return the map of variables currently set on this object. + */ + public Map getVariables() { + return variables; + } + + /** + * Sets the map of variables for this object. + * + * @param variables The map of variables for this object. + */ + public void setVariables(Map variables) { + this.variables = variables; + } + + /** + * Returns the variable resolver. The variable resolver can be used by + * the user to resolve their own variables. Variables in the variable + * resolver override any variables that are in this classes internal + * variable map. + * + * @return The variable resolver. + */ + public VariableResolver getVariableResolver() { + return variableResolver; + } + + /** + * Sets the variable resolver for this class. Varaibles resolved by the + * variable resolver will override any variables in this class's internal + * variable map. + * + * @param variableResolver The variable resolver for this class. + */ + public void setVariableResolver(VariableResolver variableResolver) { + this.variableResolver = variableResolver; + } + + /** + * This method evaluates mathematical, boolean or functional expressions. + * See the class description and test classes for more information on how to + * write an expression. If quotes exist around a string expression, then + * they will be left in the result string. Function will also have their + * results wrapped with the appripriate quote characters. + * + * @param expression + * The expression to evaluate. + * + * @return The result of the evaluated. expression. Numbers are treated as + * doubles, so resulting numbers will contain at least one decimal + * place. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public String evaluate(final String expression) throws EvaluationException { + return evaluate(expression, true, true); + } + + /** + * This method evaluates mathematical, boolean or functional expressions. + * See the class description and test classes for more information on how to + * write an expression. The expression used will be the one previously + * specified when using the parse method. If the parse method has not been + * called before calling this method, then an exception will be thrown. If + * quotes exist around a string expression, then they will be left in the + * result string. Function will also have their results wrapped with the + * appropriate quote characters. + * + * @return The result of the evaluated. expression. Numbers are treated as + * doubles, so resulting numbers will contain at least one decimal + * place. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public String evaluate() throws EvaluationException { + // Get the previously parsed expression. + final String expression = previousExpression; + + if (expression == null || expression.length() == 0) { + throw new EvaluationException("No expression has been specified."); + } + + return evaluate(expression, true, true); + } + + /** + * This method evaluates mathematical, boolean or functional expressions. + * See the class description and test classes for more information on how to + * write an expression. + * + * @param expression + * The expression to evaluate. + * @param keepQuotes + * Indicates if the the quotes should be kept in the result or + * not. This is only for string expression that are enclosed in + * quotes prior to being evaluated. + * @param wrapStringFunctionResults + * Indicates if the results from functions that return strings + * should be wrapped in quotes. The quote character used will be + * whatever is the current quote character for this object. + * + * @return The result of the evaluated expression. Numbers are treated as + * doubles, so resulting numbers will contain at least one decimal + * place. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public String evaluate(final String expression, final boolean keepQuotes, + final boolean wrapStringFunctionResults) throws EvaluationException { + + // Parse the expression. + parse(expression); + + String result = getResult(operatorStack, operandStack, + wrapStringFunctionResults); + + // Remove the quotes if necessary. + if (isExpressionString(result) && !keepQuotes) { + result = result.substring(1, result.length() - 1); + } + + return result; + } + + /** + * This method evaluates mathematical, boolean or functional expressions. + * The expression used will be the one previously specified when using the + * parse method. If the parse method has not been called before calling this + * method, then an exception will be thrown. See the class description and + * test classes for more information on how to write an expression. + * + * @param keepQuotes + * Indicates if the the quotes should be kept in the result or + * not. This is only for string expressions that are enclosed in + * quotes prior to being evaluated. + * @param wrapStringFunctionResults + * Indicates if the results from functions that return strings + * should be wrapped in quotes. The quote character used will be + * whatever is the current quote character for this object. + * + * @return The result of the evaluated expression. Numbers are treated as + * doubles, so resulting numbers will contain at least one decimal + * place. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public String evaluate(final boolean keepQuotes, + final boolean wrapStringFunctionResults) throws EvaluationException { + + // Get the previously parsed expression. + final String expression = previousExpression; + + if (expression == null || expression.length() == 0) { + throw new EvaluationException("No expression has been specified."); + } + + return evaluate(expression, keepQuotes, wrapStringFunctionResults); + } + + /** + * This method is a simple wrapper around the evaluate(String) method. Its + * purpose is to return a more friendly boolean return value instead of the + * string "1.0" (for true) and "0.0" (for false) that is normally returned. + * + * @param expression + * The expression to evaluate. + * + * @return A boolean value that represents the result of the evaluated + * expression. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. It is also thrown if the result is not able to + * be converted to a boolean value. + */ + public boolean getBooleanResult(final String expression) + throws EvaluationException { + + final String result = evaluate(expression); + + try { + Double doubleResult = new Double(result); + + if (doubleResult.doubleValue() == 1.0) { + return true; + } + } catch (NumberFormatException exception) { + return false; + } + + return false; + } + + /** + * This method is a simple wrapper around the evaluate(String) method. Its + * purpose is to return a more friendly double return value instead of the + * string number that is normally returned. + * + * @param expression + * The expression to evaluate. + * + * @return A double value that represents the result of the evaluated + * expression. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. It is also thrown if the result is not able to + * be converted to a double value. + */ + public double getNumberResult(final String expression) + throws EvaluationException { + + final String result = evaluate(expression); + Double doubleResult = null; + + try { + doubleResult = new Double(result); + } catch (NumberFormatException nfe) { + throw new EvaluationException( + "Expression does not produce a number.", nfe); + } + + return doubleResult.doubleValue(); + } + + /** + * This method parses a mathematical, boolean or functional expressions. + * When the expression is eventually evaluated, as long as the expression + * has not changed, it will not have to be reparsed. See the class + * description and test classes for more information on how to write an + * expression. + * + * @param expression + * The expression to evaluate. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public void parse(final String expression) throws EvaluationException { + + // Save the expression. + boolean parse = true; + if (!expression.equals(previousExpression)) { + previousExpression = expression; + } else { + parse = false; + operatorStack = (Stack) previousOperatorStack.clone(); + operandStack = (Stack) previousOperandStack.clone(); + } + + try { + if (parse) { + // These stacks will keep track of the operands and operators. + operandStack = new Stack(); + operatorStack = new Stack(); + + // Flags to help us keep track of what we are processing. + boolean haveOperand = false; + boolean haveOperator = false; + Operator unaryOperator = null; + + // We are going to process until we get to the end, so get the + // length. + int numChars = expression.length(); + int charCtr = 0; + + // Process until the counter exceeds the length. The goal is to + // get + // all of the operands and operators. + while (charCtr < numChars) { + Operator operator = null; + int operatorIndex = -1; + + // Skip any white space. + if (EvaluationHelper.isSpace(expression.charAt(charCtr))) { + charCtr++; + continue; + } + + // Get the next operator. + NextOperator nextOperator = getNextOperator(expression, + charCtr, null); + + if (nextOperator != null) { + operator = nextOperator.getOperator(); + operatorIndex = nextOperator.getIndex(); + } + + // Check if it is time to process an operand. + if (operatorIndex > charCtr || operatorIndex == -1) { + charCtr = processOperand(expression, charCtr, + operatorIndex, operandStack, unaryOperator); + + haveOperand = true; + haveOperator = false; + unaryOperator = null; + } + + // Check if it is time to process an operator. + if (operatorIndex == charCtr) { + if (nextOperator.getOperator().isUnary() + && (haveOperator || charCtr == 0)) { + charCtr = processUnaryOperator(operatorIndex, + nextOperator.getOperator()); + + if (unaryOperator == null) { + // We have an unary operator. + unaryOperator = nextOperator.getOperator(); + } else { + throw new EvaluationException( + "Consecutive unary " + + "operators are not allowed (index=" + + charCtr + ")."); + } + } else { + charCtr = processOperator(expression, + operatorIndex, operator, operatorStack, + operandStack, haveOperand, unaryOperator); + + unaryOperator = null; + } + + if (!(nextOperator.getOperator() instanceof ClosedParenthesesOperator)) { + haveOperand = false; + haveOperator = true; + } + } + } + + // Save the parsed operators and operands. + previousOperatorStack = (Stack) operatorStack.clone(); + previousOperandStack = (Stack) operandStack.clone(); + } + } catch (Exception e) { + // Clear the previous expression, because it is invalid. + previousExpression = ""; + + throw new EvaluationException(e.getMessage(), e); + } + } + + /** + * Install all of the operators into the list of operators to use when + * evaluating expressions. + */ + private void installOperators() { + // Install the most used operators first. + operators.add(openParenthesesOperator); + operators.add(closedParenthesesOperator); + operators.add(new AdditionOperator()); + operators.add(new SubtractionOperator()); + operators.add(new MultiplicationOperator()); + operators.add(new DivisionOperator()); + operators.add(new EqualOperator()); + operators.add(new NotEqualOperator()); + + // If there is a first character conflict between two operators, + // then install the operator with the greatest length first. + operators.add(new LessThanOrEqualOperator()); // Length of 2. + operators.add(new LessThanOperator()); // Length of 1. + operators.add(new GreaterThanOrEqualOperator()); // Length of 2. + operators.add(new GreaterThanOperator()); // Length of 1. + + // Install the least used operators last. + operators.add(new BooleanAndOperator()); + operators.add(new BooleanOrOperator()); + operators.add(new BooleanNotOperator()); + operators.add(new ModulusOperator()); + } + + /** + * Processes the operand that has been found in the expression. + * + * @param expression + * The expression being evaluated. + * @param operatorIndex + * The position in the expression where the current operator + * being processed is located. + * @param operandStack + * The stack of operands. + * @param unaryOperator + * The unary operator if we are working with one. + * + * @return The new position in the expression where processing should + * continue. + * + * @exception EvaluateException + * Thrown is an error is encoutnered while processing the + * expression. + */ + private int processOperand(final String expression, final int charCtr, + final int operatorIndex, final Stack operandStack, + final Operator unaryOperator) throws EvaluationException { + + String operandString = null; + int rtnCtr = -1; + + // Get the operand to process. + if (operatorIndex == -1) { + operandString = expression.substring(charCtr).trim(); + rtnCtr = expression.length(); + } else { + operandString = expression.substring(charCtr, operatorIndex).trim(); + rtnCtr = operatorIndex; + } + + if (operandString.length() == 0) { + throw new EvaluationException("Expression is invalid."); + } + + final ExpressionOperand operand = new ExpressionOperand(operandString, + unaryOperator); + operandStack.push(operand); + + return rtnCtr; + } + + /** + * Processes the operator that has been found in the expression. + * + * @param expression + * The expression being evaluated. + * @param operatorIndex + * The position in the expression where the current operator + * being processed is located. + * @param operator + * The operator being processed. + * @param operatorStack + * The stack of operators. + * @param operandStack + * The stack of operands. + * @param haveOperand + * Indicates if have an operand to process. + * @param unaryOperator + * The unary operand associated with thi operator. This may be + * null. + * + * @return The new position in the expression where processing should + * continue. + * + * @exception EvaluateException + * Thrown is an error is encoutnered while processing the + * expression. + */ + private int processOperator(final String expression, + final int originalOperatorIndex, final Operator originalOperator, + final Stack operatorStack, final Stack operandStack, + final boolean haveOperand, final Operator unaryOperator) + throws EvaluationException { + + int operatorIndex = originalOperatorIndex; + Operator operator = originalOperator; + + // If we have and operand and the current operator is an instance + // of OpenParenthesesOperator, then we are ready to process a function. + if (haveOperand && operator instanceof OpenParenthesesOperator) { + NextOperator nextOperator = processFunction(expression, + operatorIndex, operandStack); + + operator = nextOperator.getOperator(); + operatorIndex = nextOperator.getIndex() + operator.getLength(); + + nextOperator = getNextOperator(expression, operatorIndex, null); + + // Look to see if there is another operator. + // If there is, the process it, else get out of this routine. + if (nextOperator != null) { + operator = nextOperator.getOperator(); + operatorIndex = nextOperator.getIndex(); + } else { + return operatorIndex; + } + } + + // Determine what type of operator we are left with and process + // accordingly. + if (operator instanceof OpenParenthesesOperator) { + final ExpressionOperator expressionOperator = new ExpressionOperator( + operator, unaryOperator); + operatorStack.push(expressionOperator); + } else if (operator instanceof ClosedParenthesesOperator) { + ExpressionOperator stackOperator = null; + + if (operatorStack.size() > 0) { + stackOperator = (ExpressionOperator) operatorStack.peek(); + } + + // Process until we reach an open parentheses. + while (stackOperator != null + && !(stackOperator.getOperator() instanceof OpenParenthesesOperator)) { + processTree(operandStack, operatorStack); + + if (operatorStack.size() > 0) { + stackOperator = (ExpressionOperator) operatorStack.peek(); + } else { + stackOperator = null; + } + } + + if (operatorStack.isEmpty()) { + throw new EvaluationException("Expression is invalid."); + } + + // Pop the open parameter from the stack. + final ExpressionOperator expressionOperator = (ExpressionOperator) operatorStack + .pop(); + + if (!(expressionOperator.getOperator() instanceof OpenParenthesesOperator)) { + throw new EvaluationException("Expression is invalid."); + } + + // Process the unary operator if we have one. + if (expressionOperator.getUnaryOperator() != null) { + Object operand = operandStack.pop(); + + ExpressionTree tree = new ExpressionTree(this, operand, null, + null, expressionOperator.getUnaryOperator()); + + operandStack.push(tree); + } + } else { + // Process non-param operator. + if (operatorStack.size() > 0) { + ExpressionOperator stackOperator = (ExpressionOperator) operatorStack + .peek(); + + while (stackOperator != null + && stackOperator.getOperator().getPrecedence() >= operator + .getPrecedence()) { + processTree(operandStack, operatorStack); + + if (operatorStack.size() > 0) { + stackOperator = (ExpressionOperator) operatorStack + .peek(); + } else { + stackOperator = null; + } + } + } + + ExpressionOperator expressionOperator = new ExpressionOperator( + operator, unaryOperator); + + operatorStack.push(expressionOperator); + } + + final int rtnCtr = operatorIndex + operator.getLength(); + + return rtnCtr; + } + + /** + * Processes the unary operator that has been found in the expression. + * + * @param operatorIndex + * The position in the expression where the current operator + * being processed is located. + * @param operator + * The operator being processed. + * + * @return The new position in the expression where processing should + * continue. + */ + private int processUnaryOperator(final int operatorIndex, + final Operator operator) { + + final int rtnCtr = operatorIndex + operator.getSymbol().length(); + + return rtnCtr; + } + + /** + * Processes the function that has been found in the expression. + * + * @param expression + * The expression being evaluated. + * @param operatorIndex + * The position in the expression where the current operator + * being processed is located. + * @param operandStack + * The stack of operands. + * @param operatorStack + * The stack of operators. + * @param operator + * The current operator being processed. + * @param unaryOperator + * The unary operator associated with this function. This can be + * null. + * + * @return The next operator in the expression. This should be the closed + * parentheses operator. + * + * @exception EvaluateException + * Thrown is an error is encoutnered while processing the + * expression. + */ + private NextOperator processFunction(final String expression, + final int operatorIndex, final Stack operandStack) + throws EvaluationException { + + int parenthesisCount = 1; + NextOperator nextOperator = null; + int nextOperatorIndex = operatorIndex; + + // Loop until we find the function's closing parentheses. + while (parenthesisCount > 0) { + nextOperator = getNextOperator(expression, nextOperatorIndex + 1, + null); + + if (nextOperator == null) { + throw new EvaluationException("Function is not closed."); + } else if (nextOperator.getOperator() instanceof OpenParenthesesOperator) { + parenthesisCount++; + } else if (nextOperator.getOperator() instanceof ClosedParenthesesOperator) { + parenthesisCount--; + } + + // Get the next operator index. + nextOperatorIndex = nextOperator.getIndex(); + } + + // Get the function argument. + String arguments = expression.substring(operatorIndex + 1, + nextOperatorIndex); + + // Pop the function name from the stack. + final ExpressionOperand operand = (ExpressionOperand) operandStack + .pop(); + final Operator unaryOperator = operand.getUnaryOperator(); + final String functionName = operand.getValue(); + + // Validate that the function name is valid. + try { + isValidName(functionName); + } catch (IllegalArgumentException iae) { + throw new EvaluationException("Invalid function name of \"" + + functionName + "\".", iae); + } + + // Get the function object. + final Function function = (Function) functions.get(functionName); + + if (function == null) { + throw new EvaluationException("A function is not defined (index=" + + operatorIndex + ")."); + } + + final ParsedFunction parsedFunction = new ParsedFunction(function, + arguments, unaryOperator); + operandStack.push(parsedFunction); + + return nextOperator; + } + + /** + * Processes an expresssion tree that has been parsed into an operand stack + * and oeprator stack. + * + * @param operandStack + * The stack of operands. + * @param operatorStack + * The stack of operators. + */ + private void processTree(final Stack operandStack, final Stack operatorStack) { + + Object rightOperand = null; + Object leftOperand = null; + Operator operator = null; + + // Get the right operand node from the tree. + if (operandStack.size() > 0) { + rightOperand = operandStack.pop(); + } + + // Get the left operand node from the tree. + if (operandStack.size() > 0) { + leftOperand = operandStack.pop(); + } + + // Get the operator node from the tree. + operator = ((ExpressionOperator) operatorStack.pop()).getOperator(); + + // Build an expressin tree from the nodes. + final ExpressionTree tree = new ExpressionTree(this, leftOperand, + rightOperand, operator, null); + + // Push the tree onto the stack. + operandStack.push(tree); + } + + /** + * Returns the final result of the evaluated expression. + * + * @param operatorStack + * The stack of operators. + * @param operandStack + * The stack of operands. + * @param wrapStringFunctionResults + * Indicates if the results from functions that return strings + * should be wrapped in quotes. The quote character used will be + * whatever is the current quote character for this object. + * + * @return The final result of the evaluated expression. + * + * @exception EvaluateException + * Thrown is an error is encoutnered while processing the + * expression. + */ + private String getResult(final Stack operatorStack, + final Stack operandStack, final boolean wrapStringFunctionResults) + throws EvaluationException { + + // The result to return. + String resultString = null; + + // Process the rest of the operators left on the stack. + while (operatorStack.size() > 0) { + processTree(operandStack, operatorStack); + } + + // At this point only one operand should be left on the tree. + // It may be a tree operand that contains other tree and/or + // other operands. + if (operandStack.size() != 1) { + throw new EvaluationException("Expression is invalid."); + } + + final Object finalOperand = operandStack.pop(); + + // Check if the final operand is a tree. + if (finalOperand instanceof ExpressionTree) { + // Get the final result. + resultString = ((ExpressionTree) finalOperand) + .evaluate(wrapStringFunctionResults); + } + // Check if the final operand is an operand. + else if (finalOperand instanceof ExpressionOperand) { + ExpressionOperand resultExpressionOperand = (ExpressionOperand) finalOperand; + + resultString = ((ExpressionOperand) finalOperand).getValue(); + resultString = replaceVariables(resultString); + + // Check if the operand is a string or not. If it not a string, + // then it must be a number. + if (!isExpressionString(resultString)) { + Double resultDouble = null; + try { + resultDouble = new Double(resultString); + } catch (Exception e) { + throw new EvaluationException("Expression is invalid.", e); + } + + // Process a unary operator if one exists. + if (resultExpressionOperand.getUnaryOperator() != null) { + resultDouble = new Double(resultExpressionOperand + .getUnaryOperator().evaluate( + resultDouble.doubleValue())); + } + + // Get the final result. + resultString = resultDouble.toString(); + } else { + if (resultExpressionOperand.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } else if (finalOperand instanceof ParsedFunction) { + final ParsedFunction parsedFunction = (ParsedFunction) finalOperand; + final Function function = parsedFunction.getFunction(); + String arguments = parsedFunction.getArguments(); + + if (processNestedFunctions) { + arguments = processNestedFunctions(arguments); + } + + arguments = replaceVariables(arguments); + + // Get the final result. + try { + FunctionResult functionResult = + function.execute(this, arguments); + resultString = functionResult.getResult(); + + if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { + + Double resultDouble = new Double(resultString); + + // Process a unary operator if one exists. + if (parsedFunction.getUnaryOperator() != null) { + resultDouble = new Double(parsedFunction + .getUnaryOperator().evaluate( + resultDouble.doubleValue())); + } + + // Get the final result. + resultString = resultDouble.toString(); + } + else if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { + + // The result must be a string result. + if (wrapStringFunctionResults) { + resultString = quoteCharacter + resultString + + quoteCharacter; + } + + if (parsedFunction.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } catch (FunctionException fe) { + throw new EvaluationException(fe.getMessage(), fe); + } + } else { + throw new EvaluationException("Expression is invalid."); + } + + return resultString; + } + + /** + * Returns the next operator in the expression. + * + * @param expression + * The expression being evaluated. + * @param start + * The position in the expression to start searching for the next + * operator. + * @param match + * The operator to search for. This can be null if you want the + * very next operator. If it is not null, it searches until it + * finds the match. + * + * @return The next operator in the expression. Returns null if no next + * operator is returned. + */ + private NextOperator getNextOperator(final String expression, + final int start, final Operator match) { + + final int numChars = expression.length(); + int numQuoteCharacters = 0; + + for (int charCtr = start; charCtr < numChars; charCtr++) { + // Keep track of open strings. + if (expression.charAt(charCtr) == quoteCharacter) { + numQuoteCharacters++; + } + + // Do not look into open strings. + if ((numQuoteCharacters % 2) == 1) { + continue; + } + + // Assumes the operators are installed in order of length. + final int numOperators = operators.size(); + for (int operatorCtr = 0; operatorCtr < numOperators; operatorCtr++) { + Operator operator = (Operator) operators.get(operatorCtr); + + if (match != null) { + // Look through the operators until we find the + // one we are searching for. + if (!match.equals(operator)) { + continue; + } + } + + // The operator can 1 or 2 characters in length. + if (operator.getLength() == 2) { + int endCtr = -1; + if (charCtr + 2 <= expression.length()) { + endCtr = charCtr + 2; + } else { + endCtr = expression.length(); + } + + // Look for a match. + if (expression.substring(charCtr, endCtr).equals( + operator.getSymbol())) { + NextOperator nextOperator = new NextOperator(operator, + charCtr); + + return nextOperator; + } + } else { + // Look for a match. + if (expression.charAt(charCtr) == operator.getSymbol() + .charAt(0)) { + NextOperator nextOperator = new NextOperator(operator, + charCtr); + + return nextOperator; + } + } + } + } + + return null; + } + + /** + * Determines if the string represents a valid expression string or not. + * Valid expression strings must start and end with a quote character. + * + * @param expressionString + * The string being evaluated. + * + * @return True if the string is a valid string and false if not. + */ + protected boolean isExpressionString(final String expressionString) + throws EvaluationException { + + if (expressionString.length() > 1 + && expressionString.charAt(0) == quoteCharacter + && expressionString.charAt(expressionString.length() - 1) == quoteCharacter) { + return true; + } + + if (expressionString.indexOf(quoteCharacter) >= 0) { + throw new EvaluationException("Invalid use of quotes."); + } + + return false; + } + + /** + * This method verifies if a function or variable name is valid or not. + * + * Function and variable names must follow these rules... + *
    + *
  • can not start with a number
  • + *
  • can not contain an operator (see the above list of operators)
  • + *
  • can not contain a quote character - single or double
  • + *
  • can not contain a brace character - open or closed
  • + *
  • can not contain one of the following special characters: #, ~ , ^ !
  • + *
      + * + * @param name + * The function or variable name being validated. + * + * @exception IllegalArgumentException + * Thrown if the name is invalid. + */ + public void isValidName(final String name) throws IllegalArgumentException { + + if (name.length() == 0) { + throw new IllegalArgumentException("Variable is empty."); + } + + // Check if name starts with a number. + final char firstChar = name.charAt(0); +// if (firstChar >= '0' && firstChar <= '9') { +// throw new IllegalArgumentException("A variable or function name " +// + "can not start with a number."); +// } + + // Check if name contains with a quote character. + if (name.indexOf(EvaluationConstants.SINGLE_QUOTE) > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a quote character."); + } else if (name.indexOf(EvaluationConstants.DOUBLE_QUOTE) > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a quote character."); + } + + // Check if name contains with a brace character. + if (name.indexOf(EvaluationConstants.OPEN_BRACE) > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain an open brace character."); + } else if (name.indexOf(EvaluationConstants.CLOSED_BRACE) > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a closed brace character."); + } else if (name.indexOf(EvaluationConstants.POUND_SIGN) > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a pound sign character."); + } + + // Check if name contains an operator character. + final Iterator operatorIterator = operators.iterator(); + + while (operatorIterator.hasNext()) { + final Operator operator = (Operator) operatorIterator.next(); + + if (name.indexOf(operator.getSymbol()) > -1) { + throw new IllegalArgumentException( + "A variable or function name " + + "can not contain an operator symbol."); + } + } + + // Check if name contains other special characters. + if (name.indexOf("!") > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a special character."); + } else if (name.indexOf("~") > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a special character."); + } else if (name.indexOf("^") > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a special character."); + } else if (name.indexOf(",") > -1) { + throw new IllegalArgumentException("A variable or function name " + + "can not contain a special character."); + } + } + + /** + * This method loads the system functions is necessary. + */ + private void loadSystemFunctions() { + // Install the math functions. + if (loadMathFunctions) { + final FunctionGroup mathFunctions = new MathFunctions(); + + mathFunctions.load(this); + } + + // Install the string functions. + if (loadStringFunctions) { + final FunctionGroup stringFunctions = new StringFunctions(); + + stringFunctions.load(this); + } + } + + /** + * This method loads the system variables is necessary. + */ + private void loadSystemVariables() { + // Install the math variables. + if (loadMathVariables) { + // Add the two math variables. + putVariable("E", new Double(Math.E).toString()); + putVariable("PI", new Double(Math.PI).toString()); + } + } + + /** + * Replaces the variables in the expression with the values of the variables + * for this instance of the evaluator. + * + * @param expression + * The expression being processed. + * + * @return A new expression with the variables replaced with their values. + * + * @exception EvaluateException + * Thrown is an error is encoutnered while processing the + * expression. + */ + public String replaceVariables(final String expression) + throws EvaluationException { + + int openIndex = expression.indexOf(EvaluationConstants.OPEN_VARIABLE); + + if (openIndex < 0) { + return expression; + } + + String replacedExpression = expression; + + while (openIndex >= 0) { + + int closedIndex = -1; + if (openIndex >= 0) { + + closedIndex = replacedExpression.indexOf( + EvaluationConstants.CLOSED_VARIABLE, openIndex + 1); + if (closedIndex > openIndex) { + + String variableName = replacedExpression.substring( + openIndex + + EvaluationConstants.OPEN_VARIABLE + .length(), closedIndex); + + // Validate that the variable name is valid. + try { + isValidName(variableName); + } catch (IllegalArgumentException iae) { + throw new EvaluationException("Invalid variable name of \"" + + variableName + "\".", iae); + } + + String variableValue = getVariableValue(variableName); + + String variableString = EvaluationConstants.OPEN_VARIABLE + + variableName + + EvaluationConstants.CLOSED_VARIABLE; + + replacedExpression = EvaluationHelper.replaceAll( + replacedExpression, variableString, variableValue); + } else { + + break; + } + } + + // Start looking at the beginning of the string, since + // the length string has changed and characters have moved + // positions. + openIndex = replacedExpression.indexOf( + EvaluationConstants.OPEN_VARIABLE); + } + + // If an open brace is left over, then a variable could not be replaced. + int openBraceIndex = replacedExpression + .indexOf(EvaluationConstants.OPEN_VARIABLE); + if (openBraceIndex > -1) { + throw new EvaluationException( + "A variable has not been closed (index=" + openBraceIndex + + ")."); + } + + return replacedExpression; + } + + /** + * This method process nested function calls that may be in the arguments + * passed into a higher level function. + * + * @param arguments The arguments to process. + * + * @return The arguments with any nested function calls evaluated. + * + * @throws EvaluationException Thrown if an error occurs. + */ + protected String processNestedFunctions(final String arguments) + throws EvaluationException { + + StringBuffer evaluatedArguments = new StringBuffer(); + + // Process nested function calls. + if (arguments.length() > 0) { + + Evaluator argumentsEvaluator = new Evaluator(quoteCharacter, + loadMathVariables, loadMathFunctions, loadStringFunctions, + processNestedFunctions); + argumentsEvaluator.setFunctions(getFunctions()); + argumentsEvaluator.setVariables(getVariables()); + argumentsEvaluator.setVariableResolver(getVariableResolver()); + + final ArgumentTokenizer tokenizer = new ArgumentTokenizer( + arguments, EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + List evalautedArgumentList = new ArrayList(); + while (tokenizer.hasMoreTokens()) { + + String argument = tokenizer.nextToken().trim(); + + try { + argument = argumentsEvaluator.evaluate(argument); + } catch (Exception e) { + throw new EvaluationException(e.getMessage(), e); + } + + evalautedArgumentList.add(argument); + } + + Iterator evaluatedArgumentIterator = evalautedArgumentList + .iterator(); + + while (evaluatedArgumentIterator.hasNext()) { + + if (evaluatedArguments.length() > 0) { + + evaluatedArguments + .append(EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + } + + String evaluatedArgument = (String) evaluatedArgumentIterator + .next(); + evaluatedArguments.append(evaluatedArgument); + } + } + + return evaluatedArguments.toString(); + } + + /** + * Returns the value used during construction of this object to specify if + * math variables should be loaded. + * + * @return the loadMathVariables + */ + public boolean isLoadMathVariables() { + return loadMathVariables; + } + + /** + * Returns the value used during construction of this object to specify if + * math functions should be loaded. + * + * @return the loadMathFunctions + */ + public boolean getLoadMathFunctions() { + return loadMathFunctions; + } + + /** + * Returns the value used during construction of this object to specify if + * string functions should be loaded. + * + * @return the loadStringFunctions + */ + public boolean getLoadStringFunctions() { + return loadStringFunctions; + } + + /** + * Returns the value used during construction of this object to specify if + * nested functions should be processed. + * + * @return the processNestedFunctions + */ + public boolean getProcessNestedFunctions() { + return processNestedFunctions; + } + + public String getPreviousExpression() { + return previousExpression; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperand.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperand.java new file mode 100644 index 0000000..69289f1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperand.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.operator.Operator; + +/** + * Represents an operand being processed in the expression. + */ +public class ExpressionOperand { + + // The value of the operand. + private String value = null; + + // The unary operator for the operand, if one exists. + private Operator unaryOperator = null; + + /** + * Create a new ExpressionOperand. + * + * @param value + * The value for the new ExpressionOperand. + * @param unaryOperator + * The unary operator for this object. + */ + public ExpressionOperand(final String value, final Operator unaryOperator) { + this.value = value; + this.unaryOperator = unaryOperator; + } + + /** + * Returns the value of this object. + * + * @return The value of this object. + */ + public String getValue() { + return value; + } + + /** + * Returns the unary operator for this object. + * + * @return The unary operator for this object. + */ + public Operator getUnaryOperator() { + return unaryOperator; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperator.java new file mode 100644 index 0000000..275a978 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionOperator.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.operator.Operator; + +/** + * Represents an operator being processed in the expression. + */ +public class ExpressionOperator { + + // The operator that this object represents. + private Operator operator = null; + + // The unary operator for this object, if there is one. + private Operator unaryOperator = null; + + /** + * Creates a new ExpressionOperator. + * + * @param operator + * The operator this object represents. + * @param unaryOperator + * The unary operator for this object. + */ + public ExpressionOperator(final Operator operator, + final Operator unaryOperator) { + this.operator = operator; + this.unaryOperator = unaryOperator; + } + + /** + * Returns the operator for this object. + * + * @return The operator for this object. + */ + public Operator getOperator() { + return operator; + } + + /** + * Returns the unary operator for this object. + * + * @return The unary operator for this object. + */ + public Operator getUnaryOperator() { + return unaryOperator; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionTree.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionTree.java new file mode 100644 index 0000000..c29df68 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ExpressionTree.java @@ -0,0 +1,368 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; +import com.baoying.enginex.executor.util.jeval.operator.Operator; + +/** + * Represents an expression tree made up of a left operand, right operand, + * operator and unary operator. + */ +public class ExpressionTree { + + // The left node in the tree. + private Object leftOperand = null; + + // The right node in the tree. + private Object rightOperand = null; + + // The operator for the two operands. + private Operator operator = null; + + // The unary operator, if one exists. + private Operator unaryOperator = null; + + // The Evaluator object processing this tree. + private Evaluator evaluator = null; + + /** + * Creates a new ExpressionTree. + * + * @param evaluator + * The Evaluator object processing this tree. + * @param leftOperand + * The left operand to place as the left node of the tree. + * @param rightOperand + * The right operand to place as the right node of the tree. + * @param operator + * The operator to place as the operator node of the tree. + * @param unaryOperator + * The new unary operator for this tree. + */ + public ExpressionTree(final Evaluator evaluator, final Object leftOperand, + final Object rightOperand, final Operator operator, + final Operator unaryOperator) { + + this.evaluator = evaluator; + this.leftOperand = leftOperand; + this.rightOperand = rightOperand; + this.operator = operator; + this.unaryOperator = unaryOperator; + } + + /** + * Returns the left operand of this tree. + * + * @return The left operand of this tree. + */ + public Object getLeftOperand() { + return leftOperand; + } + + /** + * Returns the right operand of this tree. + * + * @return The right operand of this tree. + */ + public Object getRightOperand() { + return rightOperand; + } + + /** + * Returns the operator for this tree. + * + * @return The operator of this tree. + */ + public Operator getOperator() { + return operator; + } + + /** + * Returns the unary operator for this tree. + * + * @return The unary operator of this tree. + */ + public Operator getUnaryOperator() { + return unaryOperator; + } + + /** + * Evaluates the operands for this tree using the operator and the unary + * operator. + * + * @param wrapStringFunctionResults + * Indicates if the results from functions that return strings + * should be wrapped in quotes. The quote character used will be + * whatever is the current quote character for this object. + * + * @exception EvaluateException + * Thrown is an error is encountered while processing the + * expression. + */ + public String evaluate(final boolean wrapStringFunctionResults) + throws EvaluationException { + + String rtnResult = null; + + // Get the left operand. + String leftResultString = null; + Double leftResultDouble = null; + + if (leftOperand instanceof ExpressionTree) { + leftResultString = ((ExpressionTree) leftOperand) + .evaluate(wrapStringFunctionResults); + + try { + leftResultDouble = new Double(leftResultString); + leftResultString = null; + } catch (NumberFormatException exception) { + leftResultDouble = null; + } + } else if (leftOperand instanceof ExpressionOperand) { + + final ExpressionOperand leftExpressionOperand = (ExpressionOperand) leftOperand; + + leftResultString = leftExpressionOperand.getValue(); + leftResultString = evaluator.replaceVariables(leftResultString); + + // Check if the operand is a string or not. If it not a string, + // then it must be a number. + if (!evaluator.isExpressionString(leftResultString)) { + try { + leftResultDouble = new Double(leftResultString); + leftResultString = null; + } catch (NumberFormatException nfe) { + throw new EvaluationException("Expression is invalid.", nfe); + } + + if (leftExpressionOperand.getUnaryOperator() != null) { + leftResultDouble = new Double(leftExpressionOperand + .getUnaryOperator().evaluate( + leftResultDouble.doubleValue())); + } + } else { + if (leftExpressionOperand.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } else if (leftOperand instanceof ParsedFunction) { + + final ParsedFunction parsedFunction = (ParsedFunction) leftOperand; + final Function function = parsedFunction.getFunction(); + String arguments = parsedFunction.getArguments(); + arguments = evaluator.replaceVariables(arguments); + + if (evaluator.getProcessNestedFunctions()) { + arguments = evaluator.processNestedFunctions(arguments); + } + + try { + FunctionResult functionResult = + function.execute(evaluator, arguments); + leftResultString = functionResult.getResult(); + + if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { + + Double resultDouble = new Double(leftResultString); + + // Process a unary operator if one exists. + if (parsedFunction.getUnaryOperator() != null) { + resultDouble = new Double(parsedFunction + .getUnaryOperator().evaluate( + resultDouble.doubleValue())); + } + + // Get the final result. + leftResultString = resultDouble.toString(); + } + else if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { + + // The result must be a string result. + if (wrapStringFunctionResults) { + leftResultString = evaluator.getQuoteCharacter() + + leftResultString + + evaluator.getQuoteCharacter(); + } + + if (parsedFunction.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } catch (FunctionException fe) { + throw new EvaluationException(fe.getMessage(), fe); + } + + if (!evaluator.isExpressionString(leftResultString)) { + try { + leftResultDouble = new Double(leftResultString); + leftResultString = null; + } catch (NumberFormatException nfe) { + throw new EvaluationException("Expression is invalid.", nfe); + } + } + } else { + if (leftOperand != null) { + throw new EvaluationException("Expression is invalid."); + } + } + + // Get the right operand. + String rightResultString = null; + Double rightResultDouble = null; + + if (rightOperand instanceof ExpressionTree) { + rightResultString = ((ExpressionTree) rightOperand) + .evaluate(wrapStringFunctionResults); + + try { + rightResultDouble = new Double(rightResultString); + rightResultString = null; + } catch (NumberFormatException exception) { + rightResultDouble = null; + } + + } else if (rightOperand instanceof ExpressionOperand) { + + final ExpressionOperand rightExpressionOperand = (ExpressionOperand) rightOperand; + rightResultString = ((ExpressionOperand) rightOperand).getValue(); + rightResultString = evaluator.replaceVariables(rightResultString); + + // Check if the operand is a string or not. If it not a string, + // then it must be a number. + if (!evaluator.isExpressionString(rightResultString)) { + try { + rightResultDouble = new Double(rightResultString); + rightResultString = null; + } catch (NumberFormatException nfe) { + throw new EvaluationException("Expression is invalid.", nfe); + } + + if (rightExpressionOperand.getUnaryOperator() != null) { + rightResultDouble = new Double(rightExpressionOperand + .getUnaryOperator().evaluate( + rightResultDouble.doubleValue())); + } + } else { + if (rightExpressionOperand.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } else if (rightOperand instanceof ParsedFunction) { + + final ParsedFunction parsedFunction = (ParsedFunction) rightOperand; + final Function function = parsedFunction.getFunction(); + String arguments = parsedFunction.getArguments(); + arguments = evaluator.replaceVariables(arguments); + + if (evaluator.getProcessNestedFunctions()) { + arguments = evaluator.processNestedFunctions(arguments); + } + + try { + FunctionResult functionResult = + function.execute(evaluator, arguments); + rightResultString = functionResult.getResult(); + + if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC) { + + Double resultDouble = new Double(rightResultString); + + // Process a unary operator if one exists. + if (parsedFunction.getUnaryOperator() != null) { + resultDouble = new Double(parsedFunction + .getUnaryOperator().evaluate( + resultDouble.doubleValue())); + } + + // Get the final result. + rightResultString = resultDouble.toString(); + } + else if (functionResult.getType() == + FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { + + // The result must be a string result. + if (wrapStringFunctionResults) { + rightResultString = evaluator.getQuoteCharacter() + + rightResultString + + evaluator.getQuoteCharacter(); + } + + if (parsedFunction.getUnaryOperator() != null) { + throw new EvaluationException("Invalid operand for " + + "unary operator."); + } + } + } catch (FunctionException fe) { + throw new EvaluationException(fe.getMessage(), fe); + } + + if (!evaluator.isExpressionString(rightResultString)) { + try { + rightResultDouble = new Double(rightResultString); + rightResultString = null; + } catch (NumberFormatException nfe) { + throw new EvaluationException("Expression is invalid.", nfe); + } + } + } else if (rightOperand == null) { + // Do nothing. + } else { + throw new EvaluationException("Expression is invalid."); + } + + // Evaluate the the expression. + if (leftResultDouble != null && rightResultDouble != null) { + double doubleResult = operator.evaluate(leftResultDouble + .doubleValue(), rightResultDouble.doubleValue()); + + if (getUnaryOperator() != null) { + doubleResult = getUnaryOperator().evaluate(doubleResult); + } + + rtnResult = new Double(doubleResult).toString(); + } else if (leftResultString != null && rightResultString != null) { + rtnResult = operator.evaluate(leftResultString, rightResultString); + } else if (leftResultDouble != null && rightResultDouble == null) { + double doubleResult = -1; + + if (unaryOperator != null) { + doubleResult = unaryOperator.evaluate(leftResultDouble + .doubleValue()); + } else { + // Do not allow numeric (left) and + // string (right) to be evaluated together. + throw new EvaluationException("Expression is invalid."); + } + + rtnResult = new Double(doubleResult).toString(); + } else { + throw new EvaluationException("Expression is invalid."); + } + + return rtnResult; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/NextOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/NextOperator.java new file mode 100644 index 0000000..87547d7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/NextOperator.java @@ -0,0 +1,62 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.operator.Operator; + +/** + * Represents the next operator in the expression to process. + */ +class NextOperator { + + // The operator this object represetns. + private Operator operator = null; + + // The index of the operator in the expression. + private int index = -1; + + /** + * Create a new NextOperator from an operator and index. + * + * @param operator + * The operator this object represents. + * @param index + * The index of the operator in the expression. + */ + public NextOperator(final Operator operator, final int index) { + this.operator = operator; + this.index = index; + } + + /** + * Returns the operator for this object. + * + * @return The operator represented by this object. + */ + public Operator getOperator() { + return operator; + } + + /** + * Returns the index for this object. + * + * @return The index of the operator in the expression. + */ + public int getIndex() { + return index; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ParsedFunction.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ParsedFunction.java new file mode 100644 index 0000000..dd4b433 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/ParsedFunction.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.operator.Operator; + +/** + * This class represents a function that has been parsed. + */ +public class ParsedFunction { + + // The function that has been parsed. + // FIXME Make all class instance methods final if possible. + private final Function function; + + // The arguments to the function. + private final String arguments; + + // The unary operator for this object, if there is one. + private final Operator unaryOperator; + + /** + * The constructor for this class. + * + * @param function + * The function that has been parsed. + * @param arguments + * The arguments to the function. + * @param unaryOperator + * The unary operator for this object, if there is one. + */ + public ParsedFunction(final Function function, final String arguments, + final Operator unaryOperator) { + + this.function = function; + this.arguments = arguments; + this.unaryOperator = unaryOperator; + } + + /** + * Returns the function that has been parsed. + * + * @return The function that has been parsed. + */ + public Function getFunction() { + return function; + } + + /** + * Returns the arguments to the function. + * + * @return The arguments to the function. + */ + public String getArguments() { + return arguments; + } + + /** + * Returns the unary operator for this object, if there is one. + * + * @return The unary operator for this object, if there is one. + */ + public Operator getUnaryOperator() { + return unaryOperator; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/VariableResolver.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/VariableResolver.java new file mode 100644 index 0000000..6ac8ce3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/VariableResolver.java @@ -0,0 +1,26 @@ +package com.baoying.enginex.executor.util.jeval; + +import com.baoying.enginex.executor.util.jeval.function.FunctionException; + +/** + * This interface can be implement with a custom resolver and set onto the + * Evaluator class. It will then be used to resolve variables when they are + * replaced in an expression as it gets evaluated. Varaibles resolved by the + * resolved will override any varibles that exist in the variable map of an + * Evaluator instance. + */ +public interface VariableResolver { + + /** + * Returns a variable value for the specified variable name. + * + * @param variableName + * The name of the variable to return the variable value for. + * + * @return A variable value for the specified variable name. If the variable + * name can not be resolved, then null should be returned. + * + * @throws Can throw a FunctionException if needed. + */ + public String resolveVariable(String variableName) throws FunctionException; +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/Function.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/Function.java new file mode 100644 index 0000000..5150299 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/Function.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +import com.baoying.enginex.executor.util.jeval.Evaluator; + +/** + * A function that can be specified in an expression. + */ +public interface Function { + + /** + * Returns the name of the function. + * + * @return The name of this function class. + */ + public String getName(); + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * The arguments that will be evaluated by the function. It is up + * to the function implementation to break the string into one or + * more arguments. + * + * @return The value of the evaluated argument and its type. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException; +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionConstants.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionConstants.java new file mode 100644 index 0000000..4512b00 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +/** + * Contains constants used by classes in this package. + */ +public class FunctionConstants { + + /** + * Indicates that the function result is a numeric or Boolean value. + */ + public static final int FUNCTION_RESULT_TYPE_NUMERIC = 0; + + /** + * Indicates that the function result is a string value. + */ + public static final int FUNCTION_RESULT_TYPE_STRING = 1; +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionException.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionException.java new file mode 100644 index 0000000..9fc83cb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionException.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +/** + * This exception is thrown when an error occurs while processing a function. + */ +public class FunctionException extends Exception { + + private static final long serialVersionUID = 4767250768467137620L; + + /** + * This constructor takes a custom message as input. + * + * @param message + * A custom message for the exception to display. + */ + public FunctionException(String message) { + super(message); + } + + /** + * This constructor takes an exception as input. + * + * @param exception + * An exception. + */ + public FunctionException(Exception exception) { + super(exception); + } + + /** + * This constructor takes an exception as input. + * + * @param message + * A custom message for the exception to display. + * @param exception + * An exception. + */ + public FunctionException(String message, Exception exception) { + super(message, exception); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionGroup.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionGroup.java new file mode 100644 index 0000000..96db715 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionGroup.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import java.util.List; + +/** + * A groups of functions that can loaded at one time into an instance of + * Evaluator. + */ +public interface FunctionGroup { + /** + * Returns the name of the function group. + * + * @return The name of this function group class. + */ + public String getName(); + + /** + * Returns a list of the functions that are loaded by this class. + * + * @return A list of the functions loaded by this class. + */ + public List getFunctions(); + + /** + * Loads the functions in this function group into an instance of Evaluator. + * + * @param evaluator + * An instance of Evaluator to load the functions into. + */ + public void load(Evaluator evaluator); + + /** + * Unloads the functions in this function group from an instance of + * Evaluator. + * + * @param evaluator + * An instance of Evaluator to unload the functions from. + */ + public void unload(Evaluator evaluator); +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionHelper.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionHelper.java new file mode 100644 index 0000000..6aa8d4d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionHelper.java @@ -0,0 +1,284 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +import com.baoying.enginex.executor.util.jeval.ArgumentTokenizer; + +import java.util.ArrayList; + +/** + * This class contains many methods that are helpful when writing functions. + * Some of these methods were created to help with the creation of the math and + * string functions packaged with Evaluator. + */ +public class FunctionHelper { + + /** + * This method first removes any white space at the beginning and end of the + * input string. It then removes the specified quote character from the the + * first and last characters of the string if a quote character exists in + * those positions. If quote characters are not in the first and last + * positions after the white space is trimmed, then a FunctionException will + * be thrown. + * + * @param arguments + * The arguments to trim and revove quote characters from. + * @param quoteCharacter + * The character to remove from the first and last position of + * the trimmed string. + * + * @return The arguments with white space and quote characters removed. + * + * @exception FunctionException + * Thrown if quote characters do not exist in the first and + * last positions after the white space is trimmed. + */ + public static String trimAndRemoveQuoteChars(final String arguments, + final char quoteCharacter) throws FunctionException { + + String trimmedArgument = arguments; + + trimmedArgument = trimmedArgument.trim(); + + if (trimmedArgument.charAt(0) == quoteCharacter) { + trimmedArgument = trimmedArgument.substring(1, trimmedArgument + .length()); + } else { + throw new FunctionException("Value does not start with a quote."); + } + + if (trimmedArgument.charAt(trimmedArgument.length() - 1) == quoteCharacter) { + trimmedArgument = trimmedArgument.substring(0, trimmedArgument + .length() - 1); + } else { + throw new FunctionException("Value does not end with a quote."); + } + + return trimmedArgument; + } + + /** + * This methods takes a string of input function arguments, evaluates each + * argument and creates a Double value for each argument from the result of + * the evaluations. + * + * @param arguments + * The arguments to parse. + * @param delimiter + * The delimiter to use while parsing. + * + * @return An array list of Double values found in the input string. + * + * @exception FunctionException + * Thrown if the string does not properly parse into Double + * values. + */ + public static ArrayList getDoubles(final String arguments, + final char delimiter) throws FunctionException { + + ArrayList returnValues = new ArrayList(); + + try { + + final ArgumentTokenizer tokenizer = new ArgumentTokenizer( + arguments, delimiter); + + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken().trim(); + returnValues.add(new Double(token)); + } + } catch (Exception e) { + throw new FunctionException("Invalid values in string.", e); + } + + return returnValues; + } + + /** + * This methods takes a string of input function arguments, evaluates each + * argument and creates a String value for each argument from the result of + * the evaluations. + * + * @param arguments + * The arguments of values to parse. + * @param delimiter + * The delimiter to use while parsing. + * + * @return An array list of String values found in the input string. + * + * @exception FunctionException + * Thrown if the stirng does not properly parse into String + * values. + */ + public static ArrayList getStrings(final String arguments, + final char delimiter) throws FunctionException { + + final ArrayList returnValues = new ArrayList(); + + try { + ArgumentTokenizer tokenizer = new ArgumentTokenizer(arguments, + delimiter); + + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken(); + returnValues.add(token); + } + } catch (Exception e) { + throw new FunctionException("Invalid values in string.", e); + } + + return returnValues; + } + + /** + * This methods takes a string of input function arguments, evaluates each + * argument and creates a one Integer and one String value for each argument + * from the result of the evaluations. + * + * @param arguments + * The arguments of values to parse. + * @param delimiter + * The delimiter to use while parsing. + * + * @return An array list of object values found in the input string. + * + * @exception FunctionException + * Thrown if the stirng does not properly parse into the + * proper objects. + */ + public static ArrayList getOneStringAndOneInteger(final String arguments, + final char delimiter) throws FunctionException { + + ArrayList returnValues = new ArrayList(); + + try { + final ArgumentTokenizer tokenizer = new ArgumentTokenizer( + arguments, delimiter); + + int tokenCtr = 0; + while (tokenizer.hasMoreTokens()) { + if (tokenCtr == 0) { + final String token = tokenizer.nextToken(); + returnValues.add(token); + } else if (tokenCtr == 1) { + final String token = tokenizer.nextToken().trim(); + returnValues.add(new Integer(new Double(token).intValue())); + } else { + throw new FunctionException("Invalid values in string."); + } + + tokenCtr++; + } + } catch (Exception e) { + throw new FunctionException("Invalid values in string.", e); + } + + return returnValues; + } + + /** + * This methods takes a string of input function arguments, evaluates each + * argument and creates a two Strings and one Integer value for each + * argument from the result of the evaluations. + * + * @param arguments + * The arguments of values to parse. + * @param delimiter + * The delimiter to use while parsing. + * + * @return An array list of object values found in the input string. + * + * @exception FunctionException + * Thrown if the stirng does not properly parse into the + * proper objects. + */ + public static ArrayList getTwoStringsAndOneInteger(final String arguments, + final char delimiter) throws FunctionException { + + final ArrayList returnValues = new ArrayList(); + + try { + final ArgumentTokenizer tokenizer = new ArgumentTokenizer( + arguments, delimiter); + + int tokenCtr = 0; + while (tokenizer.hasMoreTokens()) { + if (tokenCtr == 0 || tokenCtr == 1) { + final String token = tokenizer.nextToken(); + returnValues.add(token); + } else if (tokenCtr == 2) { + final String token = tokenizer.nextToken().trim(); + returnValues.add(new Integer(new Double(token).intValue())); + } else { + throw new FunctionException("Invalid values in string."); + } + + tokenCtr++; + } + } catch (Exception e) { + throw new FunctionException("Invalid values in string.", e); + } + + return returnValues; + } + + /** + * This methods takes a string of input function arguments, evaluates each + * argument and creates a one String and two Integers value for each + * argument from the result of the evaluations. + * + * @param arguments + * The arguments of values to parse. + * @param delimiter + * The delimiter to use while parsing. + * + * @return An array list of object values found in the input string. + * + * @exception FunctionException + * Thrown if the stirng does not properly parse into the + * proper objects. + */ + public static ArrayList getOneStringAndTwoIntegers(final String arguments, + final char delimiter) throws FunctionException { + + final ArrayList returnValues = new ArrayList(); + + try { + final ArgumentTokenizer tokenizer = new ArgumentTokenizer( + arguments, delimiter); + + int tokenCtr = 0; + while (tokenizer.hasMoreTokens()) { + if (tokenCtr == 0) { + final String token = tokenizer.nextToken().trim(); + returnValues.add(token); + } else if (tokenCtr == 1 || tokenCtr == 2) { + final String token = tokenizer.nextToken().trim(); + returnValues.add(new Integer(new Double(token).intValue())); + } else { + throw new FunctionException("Invalid values in string."); + } + + tokenCtr++; + } + } catch (Exception e) { + throw new FunctionException("Invalid values in string.", e); + } + + return returnValues; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionResult.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionResult.java new file mode 100644 index 0000000..59ad1f9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/FunctionResult.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function; + +/** + * This is a wrapper for the result value returned from a function that not only + * contains the result, but the type. All custom functions must return a + * FunctionResult. + */ +public class FunctionResult { + + // The value returned from a function call. + private String result; + + // The type of the result. Can be a numberic or string. Boolean values come + // back as numeric values. + private int type; + + /** + * Constructor. + * + * @param result + * The result value. + * @param type + * The result type. + * + * @throws FunctionException + * Thrown if result type is invalid. + */ + public FunctionResult(String result, int type) throws FunctionException { + + if (type < FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC + || type > FunctionConstants.FUNCTION_RESULT_TYPE_STRING) { + + throw new FunctionException("Invalid function result type."); + } + + this.result = result; + this.type = type; + } + + /** + * Returns the result value. + * + * @return The result value. + */ + public String getResult() { + return result; + } + + /** + * Returns the result type. + * + * @return The result type. + */ + public int getType() { + return type; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Abs.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Abs.java new file mode 100644 index 0000000..595fc5c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Abs.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the absolute value of a double value. See the Math.abs(double) method in the + * JDK for a complete description of how this function works. + */ +public class Abs implements Function { + /** + * Returns the name of the function - "abs". + * + * @return The name of this function class. + */ + public String getName() { + return "abs"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The absolute value of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.abs(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Acos.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Acos.java new file mode 100644 index 0000000..c57f8cf --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Acos.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the arc cosine of an angle. See the Math.ceil(double) method in the JDK for a + * complete description of how this function works. + */ +public class Acos implements Function { + /** + * Returns the name of the function - "acos". + * + * @return The name of this function class. + */ + public String getName() { + return "acos"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The arc cosine value of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.acos(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Asin.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Asin.java new file mode 100644 index 0000000..8d610e1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Asin.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the arc sine of an angle See the Math.asin(double) method in the JDK for a + * complete description of how this function works. + */ +public class Asin implements Function { + /** + * Returns the name of the function - "asin". + * + * @return The name of this function class. + */ + public String getName() { + return "asin"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The arc sine of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.asin(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan.java new file mode 100644 index 0000000..360dbc8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the arc tangent of an angle. See the Math.atan(double) method in the JDK for + * a complete description of how this function works. + */ +public class Atan implements Function { + /** + * Returns the name of the function - "atan". + * + * @return The name of this function class. + */ + public String getName() { + return "atan"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The arc tangent of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.atan(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan2.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan2.java new file mode 100644 index 0000000..a5d677d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Atan2.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function + * converts rectangular coordinates to polar. See the Math.atan2(double, double) + * method in the JDK for a complete description of how this function works. + */ +public class Atan2 implements Function { + /** + * Returns the name of the function - "atan2". + * + * @return The name of this function class. + */ + public String getName() { + return "atan2"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two double + * values and evaluated. + * + * @return The arc tangent2 value of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (numbers.size() != 2) { + throw new FunctionException("Two numeric arguments are required."); + } + + try { + double argumentOne = ((Double) numbers.get(0)).doubleValue(); + double argumentTwo = ((Double) numbers.get(1)).doubleValue(); + result = new Double(Math.atan2(argumentOne, argumentTwo)); + } catch (Exception e) { + throw new FunctionException("Two numeric arguments are required.", e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Average.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Average.java new file mode 100644 index 0000000..657f219 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Average.java @@ -0,0 +1,51 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.math.BigDecimal; +import java.util.ArrayList; + + +/** + * 计算多个数字的平均值 + * @author sunyk + * + */ +public class Average implements Function { + + @Override + public String getName() { + return "avg"; + } + + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + int count = numbers.size() ; + if (count < 2) { + throw new FunctionException("Two numeric arguments are required at least."); + } + + double sum=0; + for (Double num : numbers) { + //为什么使用这样的方法,而不直接相加呢? + //原因是Java中的简单浮点数类型float和double不能够进行运算,会出现类似如下情况 + //eg:sum(1,2,3,1.2,2.0,3.6)=12.79999999999而不等于12.8 + BigDecimal b1=new BigDecimal(Double.toString(sum)); + BigDecimal b2=new BigDecimal(Double.toString(num)); + sum=b1.add(b2).doubleValue(); + } + + result = new Double(sum/count); + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ceil.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ceil.java new file mode 100644 index 0000000..20afe35 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ceil.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the ceiling value of a double value. See the Math.ceil(double) method in the + * JDK for a complete description of how this function works. + */ +public class Ceil implements Function { + /** + * Returns the name of the function - "ceil". + * + * @return The name of this function class. + */ + public String getName() { + return "ceil"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The ceiling of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.ceil(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Cos.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Cos.java new file mode 100644 index 0000000..743a7b9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Cos.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the trigonometric cosine of an angle. See the Math.cos(double) method in the + * JDK for a complete description of how this function works. + */ +public class Cos implements Function { + /** + * Returns the name of the function - "cos". + * + * @return The name of this function class. + */ + public String getName() { + return "cos"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The cosine of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.cos(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Exp.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Exp.java new file mode 100644 index 0000000..9002ced --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Exp.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the exponential number e (i.e., 2.718...) raised to the power of a double + * value. See the Math.exp(double) method in the JDK for a complete description + * of how this function works. + */ +public class Exp implements Function { + /** + * Returns the name of the function - "exp". + * + * @return The name of this function class. + */ + public String getName() { + return "exp"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The the value e to the argument power, where e is the base of the + * natural logarithms + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.exp(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Floor.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Floor.java new file mode 100644 index 0000000..7b92197 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Floor.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the floor value of a double value. See the Math.floor(double) method in the + * JDK for a complete description of how this function works. + */ +public class Floor implements Function { + /** + * Returns the name of the function - "floor". + * + * @return The name of this function class. + */ + public String getName() { + return "floor"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The floor of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.floor(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Groovy.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Groovy.java new file mode 100644 index 0000000..9b5341e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Groovy.java @@ -0,0 +1,172 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.util.MD5; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.mysql.cj.xdevapi.JsonArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * This class is a function that executes within Evaluator. The function returns + * the ceiling value of a double value. See the Math.ceil(double) method in the + * JDK for a complete description of how this function works. + */ +@Component +public class Groovy implements Function { + + private static final Logger logger = LoggerFactory.getLogger(Groovy.class); + + private static final ScriptEngineManager factory = new ScriptEngineManager(); + + public static String GROOVY_SHELL_KEY_PREFIX = "GROOVY_SHELL#"; + +// private RedisManager redisManager; + + private static Cache scriptClassCache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.HOURS) + .expireAfterAccess(1, TimeUnit.HOURS) + .build(); + + /** + * Returns the name of the function - "def main". + * + * @return The name of this function class. + */ + public String getName() { + return "def main"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The ceiling of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + return null; + } + +// public String execute(final String expression, Map data) throws EvaluationException { +// String result = null; +// try { +// ScriptEngine scriptEngine = null; +// String scriptMd5 = PYTHON_SHELL_KEY_PREFIX + MD5.GetMD5Code(expression); +// ScriptEngine value = (ScriptEngine) SerializeUtils.deserialize(redisManager.get(scriptMd5.getBytes())); +// if(value != null){ +// scriptEngine = value; +// } else { +// scriptEngine = factory.getEngineByName("groovy"); +// scriptEngine.eval(expression); +// redisManager.set(scriptMd5.getBytes(), SerializeUtils.serialize(scriptEngine), 120); +// } +// +// Object functionResult = ((Invocable) scriptEngine).invokeFunction("main", data); +// result = functionResult.toString(); +// } catch (Exception e) { +// throw new EvaluationException("执行groovy脚本出错", e); +// } +// return result; +// } + + public String execute(final String expression, Map data) throws EvaluationException { + String result = null; + try { + ScriptEngine scriptEngine = null; + String scriptMd5 = GROOVY_SHELL_KEY_PREFIX + MD5.GetMD5Code(expression); + ScriptEngine value = scriptClassCache.getIfPresent(scriptMd5); + if(value != null){ + scriptEngine = value; + } else { + scriptEngine = factory.getEngineByName("groovy"); + scriptEngine.eval(expression); + scriptClassCache.put(scriptMd5, scriptEngine); + } + + Object functionResult = ((Invocable) scriptEngine).invokeFunction("main", data); + if (functionResult!=null){ + result = functionResult.toString(); + } +// result = functionResult.toString(); + } catch (Exception e) { + throw new EvaluationException("执行groovy脚本出错", e); + } + return result; + } + @Autowired + private Python python; + public Object executeForObject(final String expression, Map data) throws EvaluationException { + Object result = null; + try { + ScriptEngine scriptEngine = null; + String scriptMd5 = GROOVY_SHELL_KEY_PREFIX + MD5.GetMD5Code(expression); + ScriptEngine value = scriptClassCache.getIfPresent(scriptMd5); + if(value != null){ + scriptEngine = value; + } else { + scriptEngine = factory.getEngineByName("groovy"); + scriptEngine.eval(expression); + scriptClassCache.put(scriptMd5, scriptEngine); + } + + Object functionResult = ((Invocable) scriptEngine).invokeFunction("main", data); + if (functionResult!=null){ +// if (functionResult instanceof HashMap||functionResult instanceof ArrayList){ +// result = JSON.toJSONString(functionResult); +// }else +// if (functionResult instanceof String){ +// result = functionResult.toString(); +// }else { +// result = functionResult; +// } + result = functionResult; + } + } catch (Exception e) { + throw new EvaluationException("执行groovy脚本出错", e); + } + return result; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/IEEEremainder.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/IEEEremainder.java new file mode 100644 index 0000000..78fb2dd --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/IEEEremainder.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the remainder operation on two arguments as prescribed by the IEEE 754 + * standard. See the Math.IEEERemainder(double, double) method in the JDK for a + * complete description of how this function works. + */ +public class IEEEremainder implements Function { + /** + * Returns the name of the function - "IEEEremainder". + * + * @return The name of this function class. + */ + public String getName() { + return "IEEEremainder"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two double + * values and evaluated. + * + * @return The the remainder operation on two arguments as prescribed by the + * IEEE 754 standard. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (numbers.size() != 2) { + throw new FunctionException("Two numeric arguments are required."); + } + + try { + double argumentOne = ((Double) numbers.get(0)).doubleValue(); + double argumentTwo = ((Double) numbers.get(1)).doubleValue(); + result = new Double(Math.IEEEremainder(argumentOne, argumentTwo)); + } catch (Exception e) { + throw new FunctionException("Two numeric arguments are required.", e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ln.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ln.java new file mode 100644 index 0000000..f5ba912 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Ln.java @@ -0,0 +1,41 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * log以e为底的对数 + * + * @author Administrator + * + */ +public class Ln implements Function { + + @Override + public String getName() { + return "ln"; + } + + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.log(number)/Math.log(Math.E)); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Log.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Log.java new file mode 100644 index 0000000..1b4e6ce --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Log.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the natural logarithm (base e) of a double value. See the Math.log(double) + * method in the JDK for a complete description of how this function works. + */ +public class Log implements Function { + /** + * Returns the name of the function - "log". + * + * @return The name of this function class. + */ + public String getName() { + return "log"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The natural logarithm of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.log(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/MathFunctions.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/MathFunctions.java new file mode 100644 index 0000000..f3aac2d --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/MathFunctions.java @@ -0,0 +1,118 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionGroup; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A groups of functions that can loaded at one time into an instance of + * Evaluator. This group contains all of the functions located in the + * net.sourceforge.jeval.function.math package. + */ +public class MathFunctions implements FunctionGroup { + /** + * Used to store instances of all of the functions loaded by this class. + */ + private List functions = new ArrayList(); + + /** + * Default contructor for this class. The functions loaded by this class are + * instantiated in this constructor. + */ + public MathFunctions() { + functions.add(new Abs()); + functions.add(new Acos()); + functions.add(new Asin()); + functions.add(new Atan()); + functions.add(new Atan2()); + functions.add(new Ceil()); + functions.add(new Cos()); + functions.add(new Exp()); + functions.add(new Floor()); + functions.add(new IEEEremainder()); + functions.add(new Log()); + functions.add(new Pow()); + functions.add(new Random()); + functions.add(new Rint()); + functions.add(new Round()); + functions.add(new Sin()); + functions.add(new Sqrt()); + functions.add(new Tan()); + functions.add(new ToDegrees()); + functions.add(new ToRadians()); + functions.add(new Max()); + functions.add(new Min()); + functions.add(new Sum()); + functions.add(new Ln()); + functions.add(new Average()); + functions.add(new Groovy()); + } + + /** + * Returns the name of the function group - "numberFunctions". + * + * @return The name of this function group class. + */ + public String getName() { + return "numberFunctions"; + } + + /** + * Returns a list of the functions that are loaded by this class. + * + * @return A list of the functions loaded by this class. + */ + public List getFunctions() { + return functions; + } + + /** + * Loads the functions in this function group into an instance of Evaluator. + * + * @param evaluator + * An instance of Evaluator to load the functions into. + */ + public void load(final Evaluator evaluator) { + Iterator functionIterator = functions.iterator(); + + while (functionIterator.hasNext()) { + evaluator.putFunction((Function) functionIterator.next()); + } + } + + /** + * Unloads the functions in this function group from an instance of + * Evaluator. + * + * @param evaluator + * An instance of Evaluator to unload the functions from. + */ + public void unload(final Evaluator evaluator) { + Iterator functionIterator = functions.iterator(); + + while (functionIterator.hasNext()) { + evaluator.removeFunction(((Function) functionIterator.next()) + .getName()); + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Max.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Max.java new file mode 100644 index 0000000..02a0b72 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Max.java @@ -0,0 +1,40 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * 获取多个值得最大值 + * @author sunyk + * + */ +public class Max implements Function { + + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + int count = numbers.size() ; + if (count < 2) { + throw new FunctionException("Two numeric arguments are required at least."); + } + + result = (Double)Collections.max(numbers); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + + @Override + public String getName() { + return "max"; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Min.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Min.java new file mode 100644 index 0000000..3f9ba55 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Min.java @@ -0,0 +1,40 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * 获取多个值最小值 + * @author sunyk + * + */ +public class Min implements Function { + + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + int count = numbers.size() ; + if (count < 2) { + throw new FunctionException("Two numeric arguments are required at least."); + } + + result = (Double)Collections.min(numbers); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + + @Override + public String getName() { + return "min"; + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Pow.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Pow.java new file mode 100644 index 0000000..369f939 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Pow.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the value of the first argument raised to the second power of the second + * argument. See the Math.pow(double, double) method in the JDK for a complete + * description of how this function works. + */ +public class Pow implements Function { + /** + * Returns the name of the function - "pow". + * + * @return The name of this function class. + */ + public String getName() { + return "pow"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two double + * values and evaluated. + * + * @return The value of the first argument raised to the second power of the + * second argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (numbers.size() != 2) { + throw new FunctionException("Two numeric arguments are required."); + } + + try { + double argumentOne = ((Double) numbers.get(0)).doubleValue(); + double argumentTwo = ((Double) numbers.get(1)).doubleValue(); + result = new Double(Math.pow(argumentOne, argumentTwo)); + } catch (Exception e) { + throw new FunctionException("Two numeric arguments are required.", e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Python.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Python.java new file mode 100644 index 0000000..093592c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Python.java @@ -0,0 +1,183 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baoying.enginex.executor.util.MD5; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import org.apache.hadoop.hbase.shaded.org.apache.avro.data.Json; +import org.python.core.*; +import org.python.util.PythonInterpreter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +@Component +public class Python implements Function { + + private static final Logger logger = LoggerFactory.getLogger(Groovy.class); + + private static final ScriptEngineManager factory = new ScriptEngineManager(); + + public static String PYTHON_SHELL_KEY_PREFIX = "JYTHON_SHELL#"; + + private static Cache scriptClassCache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.HOURS) + .expireAfterAccess(1, TimeUnit.HOURS) + .build(); + /** + * Returns the name of the function - "def main". + * + * @return The name of this function class. + */ + @Override + public String getName() { + return "if __name__ == \"__main__\":"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The ceiling of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) throws FunctionException { + return null; + } + + public Object executeForObject(final String expression, Map data) throws EvaluationException { + Object result = null; + try { + ScriptEngine scriptEngine = null; + String scriptMd5 = PYTHON_SHELL_KEY_PREFIX + MD5.GetMD5Code(expression); + ScriptEngine value = scriptClassCache.getIfPresent(scriptMd5); + Object functionResult = null; + + if(value != null){ + scriptEngine = value; + } else { + scriptEngine = factory.getEngineByName("python"); + scriptEngine.eval(expression); + scriptClassCache.put(scriptMd5, scriptEngine); + } + PyDictionary pyDictionary = new PyDictionary(); + for (Map.Entry entry : data.entrySet()) { + pyDictionary.put(entry.getKey(),entry.getValue()); + } + +// PythonInterpreter interpreter = new PythonInterpreter(); +// interpreter.exec(new String(expression.getBytes())); +// PyFunction python_main = interpreter.get("python_main", PyFunction.class); +// PyObject pyObject = python_main.__call__(pyDictionary); +// System.out.println(pyObject); +// String ret = pyObject.toString(); +// String newStr = new String(ret.getBytes("iso8859-1"), "utf-8"); //通过new String(ret.getBytes("iso8859-1"), "utf-8")转一下就好了 +// System.out.println(newStr); //newStr就不会乱码了 +// System.out.println(getEncode(String.valueOf(pyObject))); + functionResult = ((Invocable) scriptEngine).invokeFunction("python_main", pyDictionary); + if (functionResult instanceof PyDictionary){ + PyObject resultPy = (PyObject)functionResult; + String ret = resultPy.toString();//这里ret可能会乱码 + System.out.println(ret); + } + result = functionResult; + } catch (Exception e) { + e.printStackTrace(); + throw new EvaluationException("执行Python脚本出错", e); + } + return result; + } + // 这里可以提供更多地编码格式,另外由于部分编码格式是一致的所以会返回 第一个匹配的编码格式 GBK 和 GB2312 + public static final String[] encodes = new String[] { "UTF-8", "GBK", "GB2312", "ISO-8859-1", "ISO-8859-2" }; + + /** + * 获取字符串编码格式 + * + * @param str + * @return + */ + public static String getEncode(String str) { + byte[] data = str.getBytes(); + byte[] b = null; + a:for (int i = 0; i < encodes.length; i++) { + try { + b = str.getBytes(encodes[i]); + if (b.length!=data.length) + continue; + for (int j = 0; j < b.length; j++) { + if (b[j] != data[j]) { + continue a; + } + } + return encodes[i]; + } catch (UnsupportedEncodingException e) { + continue; + } + } + return null; + } + + public static void main(String[] args) throws IOException { +// Properties props = new Properties(); +//// props.put("python.home", "F:\\Java\\jython\\jython2.7.1\\Lib"); +// props.put("python.console.encoding", "UTF-8"); +// props.put("python.security.respectJavaAccessibility", "false"); +// props.put("python.import.site", "false"); +// Properties preprops = System.getProperties(); +// PythonInterpreter.initialize(preprops, props, new String[0]); +// PythonInterpreter interpreter = new PythonInterpreter(); +// interpreter.exec("#coding=UTF-8 \n" + +// "print('a智障v')"); +// interpreter.execfile("E:\\python\\迭代求阶乘.py"); + + +// PythonInterpreter interpreter = new PythonInterpreter(); +// interpreter.exec("# -*- encoding: utf-8 -*- \na='智障'; "); +// interpreter.exec("print a;"); +// interpreter.exec("print '智障';"); +// String s = "python \ndef python_main(_):\n" + +// " # result 为返回结果其中内部字段解释为:ruleScore(规则命中时得分),hitResult规则是否命中可选值为:命中/未命中\n" + +// " # fieldList 为输出字段列表,内部为字典表,updateInputMap 为需要更新到入参的变量是一个字典表\n" + +// "\n" + +// " result = {\"ruleScore\":0,\"hitResult\":\"未命中\",\"fieldList\":[],\"updateInputMap\":{}}\n" + +// " print(_)\n" + +// " print(\"未命中\")\n" + +// " result[\"ruleScore\"] = 420\n" + +// " result[\"hitResult\"] = \"命中\"\n" + +// " return result\n" + +// "\n" + +// "if __name__ == \"__main__\":\n" + +// " python_main(params)"; +// String[] param = new String[2]; +// param[0] = "python3"; +// param[1] = s; +// Runtime.getRuntime().exec(s); + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Random.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Random.java new file mode 100644 index 0000000..c1facd7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Random.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * a random double value greater than or equal to 0.0 and less than 1.0. See the + * Math.random() method in the JDK for a complete description of how this + * function works. + */ +public class Random implements Function { + /** + * Returns the name of the function - "random". + * + * @return The name of this function class. + */ + public String getName() { + return "random"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * Not used. + * + * @return A random double value greater than or equal to 0.0 and less than + * 1.0. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = new Double(Math.random()); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Rint.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Rint.java new file mode 100644 index 0000000..ce74086 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Rint.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the double value that is closest in value to the argument and is equal to a + * mathematical integer. See the Math.rint(double) method in the JDK for a + * complete description of how this function works. + */ +public class Rint implements Function { + /** + * Returns the name of the function - "rint". + * + * @return The name of this function class. + */ + public String getName() { + return "rint"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A double value that is closest in value to the argument and is + * equal to a mathematical integer. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.rint(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Round.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Round.java new file mode 100644 index 0000000..b3e7768 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Round.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the closet long to a double value. See the Math.round(double) method in the + * JDK for a complete description of how this function works. + */ +public class Round implements Function { + /** + * Returns the name of the function - "round". + * + * @return The name of this function class. + */ + public String getName() { + return "round"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A long value that is closest to the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Long result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Long(Math.round(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sin.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sin.java new file mode 100644 index 0000000..026368e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sin.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the sine of an angle. See the Math.sin(double) method in the JDK for a + * complete description of how this function works. + */ +public class Sin implements Function { + /** + * Returns the name of the function - "sin". + * + * @return The name of this function class. + */ + public String getName() { + return "sin"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return The sine of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.sin(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sqrt.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sqrt.java new file mode 100644 index 0000000..1fb0089 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sqrt.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * a square root of a double value. See the Math.sqrt(double) method in the JDK + * for a complete description of how this function works. + */ +public class Sqrt implements Function { + /** + * Returns the name of the function - "sqrt". + * + * @return The name of this function class. + */ + public String getName() { + return "sqrt"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A square root of the argument. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.sqrt(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sum.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sum.java new file mode 100644 index 0000000..36bf40c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Sum.java @@ -0,0 +1,49 @@ +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.math.BigDecimal; +import java.util.ArrayList; + +/** + * 计算多个数字的和 + * @author sunyk + * + */ +public class Sum implements Function { + + @Override + public String getName() { + return "sum"; + } + + @Override + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + + ArrayList numbers = FunctionHelper.getDoubles(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + int count = numbers.size() ; + if (count < 2) { + throw new FunctionException("Two numeric arguments are required at least."); + } + + double sum=0; + for (Double num : numbers) { + //为什么使用这样的方法,而不直接相加呢? + //原因是Java中的简单浮点数类型float和double不能够进行运算,会出现类似如下情况 + //eg:sum(1,2,3,1.2,2.0,3.6)=12.79999999999而不等于12.8 + BigDecimal b1=new BigDecimal(Double.toString(sum)); + BigDecimal b2=new BigDecimal(Double.toString(num)); + sum=b1.add(b2).doubleValue(); + } + result = new Double(sum); + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } + +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Tan.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Tan.java new file mode 100644 index 0000000..a5d1716 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/Tan.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * trigonometric tangent of an angle. See the Math.tan(double) method in the JDK + * for a complete description of how this function works. + */ +public class Tan implements Function { + /** + * Returns the name of the function - "tan". + * + * @return The name of this function class. + */ + public String getName() { + return "tan"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A trigonometric tangent of an angle. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.tan(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToDegrees.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToDegrees.java new file mode 100644 index 0000000..71191ba --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToDegrees.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function + * converts an angle measured in radians to the equivalent angle measured in + * degrees. See the Math.toDegrees(double) method in the JDK for a complete + * description of how this function works. + */ +public class ToDegrees implements Function { + /** + * Returns the name of the function - "toDegrees". + * + * @return The name of this function class. + */ + public String getName() { + return "toDegrees"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A measurement of the argument in degrees. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.toDegrees(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToRadians.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToRadians.java new file mode 100644 index 0000000..1beb88e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/math/ToRadians.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.math; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function + * converts an angle measured in degress to the equivalent angle measured in + * radians. See the Math.toRadians(double) method in the JDK for a complete + * description of how this function works. + */ +public class ToRadians implements Function { + /** + * Returns the name of the function - "toRadians". + * + * @return The name of this function class. + */ + public String getName() { + return "toRadians"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted to a double value and + * evaluated. + * + * @return A measurement of the argument in radians. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(Evaluator evaluator, String arguments) + throws FunctionException { + Double result = null; + Double number = null; + + try { + number = new Double(arguments); + } catch (Exception e) { + throw new FunctionException("Invalid argument.", e); + } + + result = new Double(Math.toRadians(number.doubleValue())); + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CharAt.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CharAt.java new file mode 100644 index 0000000..f32dce5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CharAt.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the character at the specified index in the source string. See the + * String.charAt(int) method in the JDK for a complete description of how this + * function works. + */ +public class CharAt implements Function { + /** + * Returns the name of the function - "charAt". + * + * @return The name of this function class. + */ + public String getName() { + return "charAt"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string and + * one integer argument. The first argument is the source string + * and the second argument is the index. The string argument(s) + * HAS to be enclosed in quotes. White space that is not enclosed + * within quotes will be trimmed. Quote characters in the first + * and last positions of any string argument (after being + * trimmed) will be removed also. The quote characters used must + * be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return A character that is located at the specified index. The value is + * returned as a string. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string and one integer argument " + + "are required."; + + ArrayList values = FunctionHelper.getOneStringAndOneInteger(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + int index = ((Integer) values.get(1)).intValue(); + + char[] character = new char[1]; + character[0] = argumentOne.charAt(index); + + result = new String(character); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareTo.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareTo.java new file mode 100644 index 0000000..53f6dcf --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareTo.java @@ -0,0 +1,93 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function + * compares two strings lexicographically. See the String.compareTo(String) + * method in the JDK for a complete description of how this function works. + */ +public class CompareTo implements Function { + /** + * Returns the name of the function - "compareTo". + * + * @return The name of this function class. + */ + public String getName() { + return "compareTo"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is the first string to compare + * and the second argument is the second string to compare. The + * string argument(s) HAS to be enclosed in quotes. White space + * that is not enclosed within quotes will be trimmed. Quote + * characters in the first and last positions of any string + * argument (after being trimmed) will be removed also. The quote + * characters used must be the same as the quote characters used + * by the current instance of Evaluator. If there are multiple + * arguments, they must be separated by a comma (","). + * + * @return Returns an integer value of zero if the strings are equal, an + * integer value less than zero if the first string precedes the + * second string or an integer value greater than zero if the first + * string follows the second string. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Integer result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + result = new Integer(argumentOne.compareTo(argumentTwo)); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareToIgnoreCase.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareToIgnoreCase.java new file mode 100644 index 0000000..8f98fce --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/CompareToIgnoreCase.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function + * compares two strings lexicographically, ignoreing case considerations. See + * the String.compareTo(String) method in the JDK for a complete description of + * how this function works. + */ +public class CompareToIgnoreCase implements Function { + /** + * Returns the name of the function - "compareToIgnoreCase". + * + * @return The name of this function class. + */ + public String getName() { + return "compareToIgnoreCase"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is the first string to compare + * and the second argument is the second argument to compare. The + * string argument(s) HAS to be enclosed in quotes. White space + * that is not enclosed within quotes will be trimmed. Quote + * characters in the first and last positions of any string + * argument (after being trimmed) will be removed also. The quote + * characters used must be the same as the quote characters used + * by the current instance of Evaluator. If there are multiple + * arguments, they must be separated by a comma (","). + * + * @return Returns an integer value of zero if the strings are equal, an + * integer value less than zero if the first string precedes the + * second string or an integer value greater than zero if the first + * string follows the second string. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Integer result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + result = new Integer(argumentOne.compareToIgnoreCase(argumentTwo)); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Concat.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Concat.java new file mode 100644 index 0000000..4115ebb --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Concat.java @@ -0,0 +1,92 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function + * concatenates the second string to the end of the first. See the + * String.concat(String) method in the JDK for a complete description of how + * this function works. + */ +public class Concat implements Function { + /** + * Returns the name of the function - "concat". + * + * @return The name of this function class. + */ + public String getName() { + return "concat"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is the string in which the + * second argument string will be concatenated. The string + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns a strng that is made up the first string, followed by the + * second string. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + result = argumentOne.concat(argumentTwo); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Contains.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Contains.java new file mode 100644 index 0000000..1ee0c16 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Contains.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the index within the source string of the first occurrence of the substring, + * starting at the specified index. See the String.indexOf(String, int) method + * in the JDK for a complete description of how this function works. + */ +public class Contains implements Function { + /** + * Returns the name of the function - "indexOf". + * + * @return The name of this function class. + */ + public String getName() { + return "contains"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments and one integer argument. The first argument is the + * source string, the second argument is the substring and the + * third argument is the index. The string argument(s) HAS to be + * enclosed in quotes. White space that is not enclosed within + * quotes will be trimmed. Quote characters in the first and last + * positions of any string argument (after being trimmed) will be + * removed also. The quote characters used must be the same as + * the quote characters used by the current instance of + * Evaluator. If there are multiple arguments, they must be + * separated by a comma (","). + * + * @return Returns The index at where the substring is found. If the + * substring is not found, then -1 is returned. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.contains(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EndsWith.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EndsWith.java new file mode 100644 index 0000000..15afc4c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EndsWith.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function tests + * if the string ends with a specified suffix. See the String.endswith(String) + * method in the JDK for a complete description of how this function works. + */ +public class EndsWith implements Function { + /** + * Returns the name of the function - "endsWith". + * + * @return The name of this function class. + */ + public String getName() { + return "endsWith"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is the string to test and second + * argument is the suffix. The string argument(s) HAS to be + * enclosed in quotes. White space that is not enclosed within + * quotes will be trimmed. Quote characters in the first and last + * positions of any string argument (after being trimmed) will be + * removed also. The quote characters used must be the same as + * the quote characters used by the current instance of + * Evaluator. If there are multiple arguments, they must be + * separated by a comma (","). + * + * @return Returns "1.0" (true) if the string ends with the suffix, + * otherwise it returns "0.0" (false). The return value respresents + * a Boolean value that is compatible with the Boolean operators + * used by Evaluator. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.endsWith(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Equals.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Equals.java new file mode 100644 index 0000000..21b52d0 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Equals.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function tests + * one string equals another. See the String.equals(String) method in the JDK + * for a complete description of how this function works. + */ +public class Equals implements Function { + /** + * Returns the name of the function - "equals". + * + * @return The name of this function class. + */ + public String getName() { + return "equals"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is a string that will be + * compared to the second argument / string. The string + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns "1.0" (true) if the string ends with the suffix, + * otherwise it returns "0.0" (false). The return value respresents + * a Boolean value that is compatible with the Boolean operators + * used by Evaluator. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.equals(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EqualsIgnoreCase.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EqualsIgnoreCase.java new file mode 100644 index 0000000..fc941bf --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/EqualsIgnoreCase.java @@ -0,0 +1,99 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function tests + * one string equals another, but ignores case. See the + * String.equalsIgnoreCase(String) method in the JDK for a complete description + * of how this function works. + */ +public class EqualsIgnoreCase implements Function { + /** + * Returns the name of the function - "equalsIgnoreCase". + * + * @return The name of this function class. + */ + public String getName() { + return "equalsIgnoreCase"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is a string that will be + * compared to the second argument / string. The string + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns "1.0" (true) if the string ends with the suffix, + * otherwise it returns "0.0" (false). The return value respresents + * a Boolean value that is compatible with the Boolean operators + * used by Evaluator. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.equalsIgnoreCase(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Eval.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Eval.java new file mode 100644 index 0000000..7383b5c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Eval.java @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionConstants; +import com.baoying.enginex.executor.util.jeval.function.FunctionException; +import com.baoying.enginex.executor.util.jeval.function.FunctionResult; + +/** + * This class is a function that executes within Evaluator. The function returns + * the result of a Evaluator compatible expression. See the + * Evaluator.evaluate(String) method for a complete description of how this + * function works. + */ +public class Eval implements Function { + /** + * Returns the name of the function - "eval". + * + * @return The name of this function class. + */ + public String getName() { + return "eval"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of evaluator. + * @param arguments + * A string expression that is compatible with Evaluator. *** THE + * STRING ARGUMENT SHOULD NOT BE ENCLOSED IN QUOTES OR THE + * EXPRESSION MAY NOT BE EVALUATED CORRECTLY.*** *** FUNCTION + * CALLS ARE VALID WITHIN THE EVAL FUNCTION. *** + * + * @return The evaluated result fot the input expression. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, + final String arguments) throws FunctionException { + String result = null; + + try { + result = evaluator.evaluate(arguments, false, true); + } catch (EvaluationException ee) { + throw new FunctionException(ee.getMessage(), ee); + } + + int resultType = FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC; + try { + Double.parseDouble(result); + } catch (NumberFormatException nfe) { + resultType = FunctionConstants.FUNCTION_RESULT_TYPE_STRING; + } + + return new FunctionResult(result, resultType); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/IndexOf.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/IndexOf.java new file mode 100644 index 0000000..06d2401 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/IndexOf.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the index within the source string of the first occurrence of the substring, + * starting at the specified index. See the String.indexOf(String, int) method + * in the JDK for a complete description of how this function works. + */ +public class IndexOf implements Function { + /** + * Returns the name of the function - "indexOf". + * + * @return The name of this function class. + */ + public String getName() { + return "indexOf"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments and one integer argument. The first argument is the + * source string, the second argument is the substring and the + * third argument is the index. The string argument(s) HAS to be + * enclosed in quotes. White space that is not enclosed within + * quotes will be trimmed. Quote characters in the first and last + * positions of any string argument (after being trimmed) will be + * removed also. The quote characters used must be the same as + * the quote characters used by the current instance of + * Evaluator. If there are multiple arguments, they must be + * separated by a comma (","). + * + * @return Returns The index at where the substring is found. If the + * substring is not found, then -1 is returned. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Integer result = null; + String exceptionMessage = "Two string arguments and one integer " + + "argument are required."; + + ArrayList values = FunctionHelper.getTwoStringsAndOneInteger(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 3) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(1), evaluator.getQuoteCharacter()); + int index = ((Integer) values.get(2)).intValue(); + result = new Integer(argumentOne.indexOf(argumentTwo, index)); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/LastIndexOf.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/LastIndexOf.java new file mode 100644 index 0000000..d899277 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/LastIndexOf.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the index within the source string of the last occurrence of the substring, + * starting at the specified index. See the String.lastIndexOf(String, int) + * method in the JDK for a complete description of how this function works. + */ +public class LastIndexOf implements Function { + /** + * Returns the name of the function - "lastIndexOf". + * + * @return The name of this function class. + */ + public String getName() { + return "lastIndexOf"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments and one integer argument. The first argument is the + * source string, the second argument is the substring and the + * third argument is the index. The string argument(s) HAS to be + * enclosed in quotes. White space that is not enclosed within + * quotes will be trimmed. Quote characters in the first and last + * positions of any string argument (after being trimmed) will be + * removed also. The quote characters used must be the same as + * the quote characters used by the current instance of + * Evaluator. If there are multiple arguments, they must be + * separated by a comma (","). + * + * @return Returns The index at where the substring is found. If the + * substring is not found, then -1 is returned. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Integer result = null; + String exceptionMessage = "Two string arguments and one integer " + + "argument are required."; + + ArrayList values = FunctionHelper.getTwoStringsAndOneInteger(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 3) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(1), evaluator.getQuoteCharacter()); + int index = ((Integer) values.get(2)).intValue(); + result = new Integer(argumentOne.lastIndexOf(argumentTwo, index)); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Length.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Length.java new file mode 100644 index 0000000..07563b3 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Length.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +/** + * This class is a function that executes within Evaluator. The function returns + * the length of the source string. See the String.length() method in the JDK + * for a complete description of how this function works. + */ +public class Length implements Function { + /** + * Returns the name of the function - "length". + * + * @return The name of this function class. + */ + public String getName() { + return "length"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string + * argument. The string argument(s) HAS to be enclosed in quotes. + * White space that is not enclosed within quotes will be + * trimmed. Quote characters in the first and last positions of + * any string argument (after being trimmed) will be removed + * also. The quote characters used must be the same as the quote + * characters used by the current instance of Evaluator. If there + * are multiple arguments, they must be separated by a comma + * (","). + * + * @return The length of the source string. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + Integer result = null; + String exceptionMessage = "One string argument is required."; + + try { + String stringValue = arguments; + + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + stringValue, evaluator.getQuoteCharacter()); + + result = new Integer(argumentOne.length()); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result.toString(), + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotContains.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotContains.java new file mode 100644 index 0000000..8fa4f67 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotContains.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * the index within the source string of the first occurrence of the substring, + * starting at the specified index. See the String.indexOf(String, int) method + * in the JDK for a complete description of how this function works. + */ +public class NotContains implements Function { + /** + * Returns the name of the function - "indexOf". + * + * @return The name of this function class. + */ + public String getName() { + return "notContains"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments and one integer argument. The first argument is the + * source string, the second argument is the substring and the + * third argument is the index. The string argument(s) HAS to be + * enclosed in quotes. White space that is not enclosed within + * quotes will be trimmed. Quote characters in the first and last + * positions of any string argument (after being trimmed) will be + * removed also. The quote characters used must be the same as + * the quote characters used by the current instance of + * Evaluator. If there are multiple arguments, they must be + * separated by a comma (","). + * + * @return Returns The index at where the substring is found. If the + * substring is not found, then -1 is returned. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.contains(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotEquals.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotEquals.java new file mode 100644 index 0000000..e47941a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/NotEquals.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function tests + * one string equals another. See the String.equals(String) method in the JDK + * for a complete description of how this function works. + */ +public class NotEquals implements Function { + /** + * Returns the name of the function - "equals". + * + * @return The name of this function class. + */ + public String getName() { + return "notEquals"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments. The first argument is a string that will be + * compared to the second argument / string. The string + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns "1.0" (true) if the string ends with the suffix, + * otherwise it returns "0.0" (false). The return value respresents + * a Boolean value that is compatible with the Boolean operators + * used by Evaluator. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments are required."; + + ArrayList strings = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (strings.size() != 2) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) strings.get(1), evaluator.getQuoteCharacter()); + + if (argumentOne.equals(argumentTwo)) { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Replace.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Replace.java new file mode 100644 index 0000000..ca97f5a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Replace.java @@ -0,0 +1,115 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * a new string with all of the occurances of the old character in the source + * string replaced with the new character. See the String.replace(char, char) + * method in the JDK for a complete description of how this function works. + */ +public class Replace implements Function { + /** + * Returns the name of the function - "replace". + * + * @return The name of this function class. + */ + public String getName() { + return "replace"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string and + * two character arguments. The first argument is the source + * string to replace the charactes in. The second argument is the + * old character to replace in the source string. The third + * argument is the new character to replace the old character + * with in the source string. The string and character + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns a string with every occurence of the old character + * replaced with the new character. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string argument and two character " + + "arguments are required."; + + ArrayList values = FunctionHelper.getStrings(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 3) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(1), evaluator.getQuoteCharacter()); + + String argumentThree = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(2), evaluator.getQuoteCharacter()); + + char oldCharacter = ' '; + if (argumentTwo.length() == 1) { + oldCharacter = argumentTwo.charAt(0); + } else { + throw new FunctionException(exceptionMessage); + } + + char newCharacter = ' '; + if (argumentThree.length() == 1) { + newCharacter = argumentThree.charAt(0); + } else { + throw new FunctionException(exceptionMessage); + } + + result = argumentOne.replace(oldCharacter, newCharacter); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StartsWith.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StartsWith.java new file mode 100644 index 0000000..8afbefe --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StartsWith.java @@ -0,0 +1,102 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function tests + * if the string starts with a specified prefix beginning at a specified index. + * See the String.startsWith(String, int) method in the JDK for a complete + * description of how this function works. + */ +public class StartsWith implements Function { + /** + * Returns the name of the function - "startsWith". + * + * @return The name of this function class. + */ + public String getName() { + return "startsWith"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into two string + * arguments and one integer argument. The first argument is the + * string to test, the second argument is the prefix and the + * third argument is the index to start at. The string + * argument(s) HAS to be enclosed in quotes. White space that is + * not enclosed within quotes will be trimmed. Quote characters + * in the first and last positions of any string argument (after + * being trimmed) will be removed also. The quote characters used + * must be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns "1.0" (true) if the string ends with the suffix, + * otherwise it returns "0.0" (false). The return value respresents + * a Boolean value that is compatible with the Boolean operators + * used by Evaluator. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "Two string arguments and one integer " + + "argument are required."; + + ArrayList values = FunctionHelper.getTwoStringsAndOneInteger(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 3) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + String argumentTwo = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(1), evaluator.getQuoteCharacter()); + int index = ((Integer) values.get(2)).intValue(); + + if (argumentOne.startsWith(argumentTwo, index)) { + result = EvaluationConstants.BOOLEAN_STRING_TRUE; + } else { + result = EvaluationConstants.BOOLEAN_STRING_FALSE; + } + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_NUMERIC); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StringFunctions.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StringFunctions.java new file mode 100644 index 0000000..2424b55 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/StringFunctions.java @@ -0,0 +1,112 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.Function; +import com.baoying.enginex.executor.util.jeval.function.FunctionGroup; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A groups of functions that can loaded at one time into an instance of + * Evaluator. This group contains all of the functions located in the + * net.sourceforge.jeval.function.string package. + */ +public class StringFunctions implements FunctionGroup { + /** + * Used to store instances of all of the functions loaded by this class. + */ + private List functions = new ArrayList(); + + /** + * Default contructor for this class. The functions loaded by this class are + * instantiated in this constructor. + */ + public StringFunctions() { + functions.add(new CharAt()); + functions.add(new CompareTo()); + functions.add(new CompareToIgnoreCase()); + functions.add(new Concat()); + functions.add(new EndsWith()); + functions.add(new Equals()); + functions.add(new EqualsIgnoreCase()); + functions.add(new Eval()); + functions.add(new IndexOf()); + functions.add(new LastIndexOf()); + functions.add(new Length()); + functions.add(new Replace()); + functions.add(new StartsWith()); + functions.add(new Substring()); + functions.add(new ToLowerCase()); + functions.add(new ToUpperCase()); + functions.add(new Trim()); + functions.add(new Contains()); + functions.add(new NotContains()); + functions.add(new NotEquals()); + } + + /** + * Returns the name of the function group - "stringFunctions". + * + * @return The name of this function group class. + */ + public String getName() { + return "stringFunctions"; + } + + /** + * Returns a list of the functions that are loaded by this class. + * + * @return A list of the functions loaded by this class. + */ + public List getFunctions() { + return functions; + } + + /** + * Loads the functions in this function group into an instance of Evaluator. + * + * @param evaluator + * An instance of Evaluator to load the functions into. + */ + public void load(final Evaluator evaluator) { + Iterator functionIterator = functions.iterator(); + + while (functionIterator.hasNext()) { + evaluator.putFunction((Function) functionIterator.next()); + } + } + + /** + * Unloads the functions in this function group from an instance of + * Evaluator. + * + * @param evaluator + * An instance of Evaluator to unload the functions from. + */ + public void unload(final Evaluator evaluator) { + Iterator functionIterator = functions.iterator(); + + while (functionIterator.hasNext()) { + evaluator.removeFunction(((Function) functionIterator.next()) + .getName()); + } + } +} diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Substring.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Substring.java new file mode 100644 index 0000000..61485c1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Substring.java @@ -0,0 +1,93 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +import java.util.ArrayList; + +/** + * This class is a function that executes within Evaluator. The function returns + * a string that is a substring of the source string. See the + * String.substring(int, int) method in the JDK for a complete description of + * how this function works. + */ +public class Substring implements Function { + /** + * Returns the name of the function - "substring". + * + * @return The name of this function class. + */ + public String getName() { + return "substring"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string + * argument and two integer arguments. The first argument is the + * source string, the second argument is the beginning index and + * the third argument is the ending index. The string argument(s) + * HAS to be enclosed in quotes. White space that is not enclosed + * within quotes will be trimmed. Quote characters in the first + * and last positions of any string argument (after being + * trimmed) will be removed also. The quote characters used must + * be the same as the quote characters used by the current + * instance of Evaluator. If there are multiple arguments, they + * must be separated by a comma (","). + * + * @return Returns the specified substring. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string argument and two integer " + + "arguments are required."; + + ArrayList values = FunctionHelper.getOneStringAndTwoIntegers(arguments, + EvaluationConstants.FUNCTION_ARGUMENT_SEPARATOR); + + if (values.size() != 3) { + throw new FunctionException(exceptionMessage); + } + + try { + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + (String) values.get(0), evaluator.getQuoteCharacter()); + int beginningIndex = ((Integer) values.get(1)).intValue(); + int endingIndex = ((Integer) values.get(2)).intValue(); + result = argumentOne.substring(beginningIndex, endingIndex); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToLowerCase.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToLowerCase.java new file mode 100644 index 0000000..12eb7b5 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToLowerCase.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +/** + * This class is a function that executes within Evaluator. The function returns + * the source string in lower case. See the String.toLowerCase() method in the + * JDK for a complete description of how this function works. + */ +public class ToLowerCase implements Function { + /** + * Returns the name of the function - "toLowerCase". + * + * @return The name of this function class. + */ + public String getName() { + return "toLowerCase"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string + * argument. The string argument(s) HAS to be enclosed in quotes. + * White space that is not enclosed within quotes will be + * trimmed. Quote characters in the first and last positions of + * any string argument (after being trimmed) will be removed + * also. The quote characters used must be the same as the quote + * characters used by the current instance of Evaluator. If there + * are multiple arguments, they must be separated by a comma + * (","). + * + * @return The source string, converted to lowercase. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string argument is required."; + + try { + String stringValue = arguments; + + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + stringValue, evaluator.getQuoteCharacter()); + + result = argumentOne.toLowerCase(); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToUpperCase.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToUpperCase.java new file mode 100644 index 0000000..71f3160 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/ToUpperCase.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +/** + * This class is a function that executes within Evaluator. The function returns + * the source string in upper case. See the String.toUpperCase() method in the + * JDK for a complete description of how this function works. + */ +public class ToUpperCase implements Function { + /** + * Returns the name of the function - "toUpperCase". + * + * @return The name of this function class. + */ + public String getName() { + return "toUpperCase"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string + * argument. The string argument(s) HAS to be enclosed in quotes. + * White space that is not enclosed within quotes will be + * trimmed. Quote characters in the first and last positions of + * any string argument (after being trimmed) will be removed + * also. The quote characters used must be the same as the quote + * characters used by the current instance of Evaluator. If there + * are multiple arguments, they must be separated by a comma + * (","). + * + * @return The source string, converted to lowercase. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string argument is required."; + + try { + String stringValue = arguments; + + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + stringValue, evaluator.getQuoteCharacter()); + + result = argumentOne.toUpperCase(); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Trim.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Trim.java new file mode 100644 index 0000000..2a4fae7 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/function/string/Trim.java @@ -0,0 +1,81 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.function.string; + +import com.baoying.enginex.executor.util.jeval.Evaluator; +import com.baoying.enginex.executor.util.jeval.function.*; + +/** + * This class is a function that executes within Evaluator. The function returns + * the source string with white space removed from both ends. See the + * String.trim() method in the JDK for a complete description of how this + * function works. + */ +public class Trim implements Function { + /** + * Returns the name of the function - "trim". + * + * @return The name of this function class. + */ + public String getName() { + return "trim"; + } + + /** + * Executes the function for the specified argument. This method is called + * internally by Evaluator. + * + * @param evaluator + * An instance of Evaluator. + * @param arguments + * A string argument that will be converted into one string + * argument. The string argument(s) HAS to be enclosed in quotes. + * White space that is not enclosed within quotes will be + * trimmed. Quote characters in the first and last positions of + * any string argument (after being trimmed) will be removed + * also. The quote characters used must be the same as the quote + * characters used by the current instance of Evaluator. If there + * are multiple arguments, they must be separated by a comma + * (","). + * + * @return The source string, with white space removed from both ends. + * + * @exception FunctionException + * Thrown if the argument(s) are not valid for this function. + */ + public FunctionResult execute(final Evaluator evaluator, final String arguments) + throws FunctionException { + String result = null; + String exceptionMessage = "One string argument is required."; + + try { + String stringValue = arguments; + + String argumentOne = FunctionHelper.trimAndRemoveQuoteChars( + stringValue, evaluator.getQuoteCharacter()); + + result = argumentOne.trim(); + } catch (FunctionException fe) { + throw new FunctionException(fe.getMessage(), fe); + } catch (Exception e) { + throw new FunctionException(exceptionMessage, e); + } + + return new FunctionResult(result, + FunctionConstants.FUNCTION_RESULT_TYPE_STRING); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AbstractOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AbstractOperator.java new file mode 100644 index 0000000..412a0d6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AbstractOperator.java @@ -0,0 +1,182 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationException; + +/** + * This is the standard operator that is the parent to all operators found in + * expressions. + */ +public abstract class AbstractOperator implements Operator { + + private String symbol = null; + + private int precedence = 0; + + private boolean unary = false; + + /** + * A constructor that takes the operator symbol and precedence as input. + * + * @param symbol + * The character(s) that makes up the operator. + * @param precedence + * The precedence level given to this operator. + */ + public AbstractOperator(final String symbol, final int precedence) { + + this.symbol = symbol; + this.precedence = precedence; + } + + /** + * A constructor that takes the operator symbol, precedence, unary indicator + * and unary precedence as input. + * + * @param symbol + * The character(s) that makes up the operator. + * @param precedence + * The precedence level given to this operator. + * @param unary + * Indicates of the operator is a unary operator or not. + */ + public AbstractOperator( + + String symbol, int precedence, boolean unary) { + + this.symbol = symbol; + this.precedence = precedence; + this.unary = unary; + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + * + * @return String The value of the evaluated operands. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public String evaluate(final String leftOperand, final String rightOperand) + throws EvaluationException { + throw new EvaluationException("Invalid operation for a string."); + } + + /** + * Evaluate one double operand. + * + * @param operand + * The operand being evaluated. + */ + public double evaluate(double operand) { + return 0; + } + + /** + * Returns the character(s) that makes up the operator. + * + * @return The operator symbol. + */ + public String getSymbol() { + return symbol; + } + + /** + * Returns the precedence given to this operator. + * + * @return The precedecne given to this operator. + */ + public int getPrecedence() { + return precedence; + } + + /** + * Returns the length of the operator symbol. + * + * @return The length of the operator symbol. + */ + public int getLength() { + return symbol.length(); + } + + /** + * Returns an indicator of if the operator is unary or not. + * + * @return An indicator of if the operator is unary or not. + */ + public boolean isUnary() { + return unary; + } + + /** + * Determines if this operator is equal to another operator. Equality is + * determined by comparing the operator symbol of both operators. + * + * @param object + * The object to compare with this operator. + * + * @return True if the object is equal and false if not. + * + * @exception IllegalStateException + * Thrown if the input object is not of the Operator type. + */ + public boolean equals(final Object object) { + if (object == null) { + return false; + } + + if (!(object instanceof AbstractOperator)) { + throw new IllegalStateException("Invalid operator object."); + } + + AbstractOperator operator = (AbstractOperator) object; + + if (symbol.equals(operator.getSymbol())) { + return true; + } + + return false; + } + + /** + * Returns the String representation of this operator, which is the symbol. + * + * @return The operator symbol. + */ + public String toString() { + return getSymbol(); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AdditionOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AdditionOperator.java new file mode 100644 index 0000000..7e5bd77 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/AdditionOperator.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The addition operator. + */ +public class AdditionOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public AdditionOperator() { + super("+", 5, true); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + Double rtnValue = new Double(leftOperand + rightOperand); + + return rtnValue.doubleValue(); + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(final String leftOperand, final String rightOperand) { + String rtnValue = new String(leftOperand.substring(0, leftOperand + .length() - 1) + + rightOperand.substring(1, rightOperand.length())); + + return rtnValue; + } + + /** + * Evaluate one double operand. + * + * @param operand + * The operand being evaluated. + */ + public double evaluate(double operand) { + return operand; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanAndOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanAndOperator.java new file mode 100644 index 0000000..2c20c47 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanAndOperator.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The boolean and operator. + */ +public class BooleanAndOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public BooleanAndOperator() { + super("&&", 2); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand == 1 && rightOperand == 1) { + return 1; + } + + return 0; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanNotOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanNotOperator.java new file mode 100644 index 0000000..d7e955a --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanNotOperator.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The boolean not operator. + */ +public class BooleanNotOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public BooleanNotOperator() { + super("!", 0, true); + } + + /** + * Evaluate one double operand. + * + * @param operand + * The operand being evaluated. + */ + public double evaluate(final double operand) { + if (operand == 1) { + return 0; + } + + return 1; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanOrOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanOrOperator.java new file mode 100644 index 0000000..d7c0aa8 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/BooleanOrOperator.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The boolean or operator. + */ +public class BooleanOrOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public BooleanOrOperator() { + super("||", 1); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand == 1 || rightOperand == 1) { + return 1; + } + + return 0; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ClosedParenthesesOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ClosedParenthesesOperator.java new file mode 100644 index 0000000..825faf6 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ClosedParenthesesOperator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The closed parentheses operator. + */ +public class ClosedParenthesesOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public ClosedParenthesesOperator() { + super(")", 0); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/DivisionOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/DivisionOperator.java new file mode 100644 index 0000000..89092be --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/DivisionOperator.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The division operator. + */ +public class DivisionOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public DivisionOperator() { + super("/", 6); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + Double rtnValue = new Double(leftOperand / rightOperand); + + return rtnValue.doubleValue(); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/EqualOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/EqualOperator.java new file mode 100644 index 0000000..0fc50f2 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/EqualOperator.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The equal operator. + */ +public class EqualOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public EqualOperator() { + super("==", 3); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand == rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(String leftOperand, String rightOperand) { + if (leftOperand.compareTo(rightOperand) == 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOperator.java new file mode 100644 index 0000000..7b96ea9 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOperator.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The greater than operator. + */ +public class GreaterThanOperator extends AbstractOperator { + /** + * Default constructor. + */ + public GreaterThanOperator() { + super(">", 4); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand > rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(final String leftOperand, final String rightOperand) { + if (leftOperand.compareTo(rightOperand) > 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOrEqualOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOrEqualOperator.java new file mode 100644 index 0000000..c1a0360 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/GreaterThanOrEqualOperator.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The greater than or equal operator. + */ +public class GreaterThanOrEqualOperator extends AbstractOperator { + /** + * Default constructor. + */ + public GreaterThanOrEqualOperator() { + super(">=", 4); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand >= rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(final String leftOperand, final String rightOperand) { + if (leftOperand.compareTo(rightOperand) >= 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOperator.java new file mode 100644 index 0000000..304bd5c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOperator.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The less than operator. + */ +public class LessThanOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public LessThanOperator() { + super("<", 4); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand < rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(final String leftOperand, final String rightOperand) { + if (leftOperand.compareTo(rightOperand) < 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOrEqualOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOrEqualOperator.java new file mode 100644 index 0000000..44b287c --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/LessThanOrEqualOperator.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The less than or equal operator. + */ +public class LessThanOrEqualOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public LessThanOrEqualOperator() { + super("<=", 4); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand <= rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(String leftOperand, String rightOperand) { + if (leftOperand.compareTo(rightOperand) <= 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ModulusOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ModulusOperator.java new file mode 100644 index 0000000..4e8d5c1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/ModulusOperator.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The modulus operator. + */ +public class ModulusOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public ModulusOperator() { + super("%", 6); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + Double rtnValue = new Double(leftOperand % rightOperand); + + return rtnValue.doubleValue(); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/MultiplicationOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/MultiplicationOperator.java new file mode 100644 index 0000000..71026a4 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/MultiplicationOperator.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The multiplication operator. + */ +public class MultiplicationOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public MultiplicationOperator() { + super("*", 6); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + Double rtnValue = new Double(leftOperand * rightOperand); + + return rtnValue.doubleValue(); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/NotEqualOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/NotEqualOperator.java new file mode 100644 index 0000000..60af1db --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/NotEqualOperator.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationConstants; + +/** + * The not equal operator. + */ +public class NotEqualOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public NotEqualOperator() { + super("!=", 3); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + if (leftOperand != rightOperand) { + return 1; + } + + return 0; + } + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public String evaluate(String leftOperand, String rightOperand) { + if (leftOperand.compareTo(rightOperand) != 0) { + return EvaluationConstants.BOOLEAN_STRING_TRUE; + } + + return EvaluationConstants.BOOLEAN_STRING_FALSE; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/OpenParenthesesOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/OpenParenthesesOperator.java new file mode 100644 index 0000000..b5eb5e1 --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/OpenParenthesesOperator.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The open parentheses operator. + */ +public class OpenParenthesesOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public OpenParenthesesOperator() { + super("(", 0); + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/Operator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/Operator.java new file mode 100644 index 0000000..758091e --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/Operator.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +import com.baoying.enginex.executor.util.jeval.EvaluationException; + +/** + * An oerator than can specified in an expression. + */ +public interface Operator { + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public abstract double evaluate(double leftOperand, double rightOperand); + + /** + * Evaluates two string operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + * + * @return String The value of the evaluated operands. + * + * @exception EvaluateException + * Thrown when an error is found while evaluating the + * expression. + */ + public abstract String evaluate(final String leftOperand, + final String rightOperand) throws EvaluationException; + + /** + * Evaluate one double operand. + * + * @param operand + * The operand being evaluated. + */ + public abstract double evaluate(final double operand); + + /** + * Returns the character(s) that makes up the operator. + * + * @return The operator symbol. + */ + public abstract String getSymbol(); + + /** + * Returns the precedence given to this operator. + * + * @return The precedecne given to this operator. + */ + public abstract int getPrecedence(); + + /** + * Returns the length of the operator symbol. + * + * @return The length of the operator symbol. + */ + public abstract int getLength(); + + /** + * Returns an indicator of if the operator is unary or not. + * + * @return An indicator of if the operator is unary or not. + */ + public abstract boolean isUnary(); +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/SubtractionOperator.java b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/SubtractionOperator.java new file mode 100644 index 0000000..9dbca9b --- /dev/null +++ b/jar-enginex-runner/src/main/java/com/baoying/enginex/executor/util/jeval/operator/SubtractionOperator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2007 Robert Breidecker. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.baoying.enginex.executor.util.jeval.operator; + +/** + * The subtraction operator. + */ +public class SubtractionOperator extends AbstractOperator { + + /** + * Default constructor. + */ + public SubtractionOperator() { + super("-", 5, true); + } + + /** + * Evaluates two double operands. + * + * @param leftOperand + * The left operand being evaluated. + * @param rightOperand + * The right operand being evaluated. + */ + public double evaluate(final double leftOperand, final double rightOperand) { + Double rtnValue = new Double(leftOperand - rightOperand); + + return rtnValue.doubleValue(); + } + + /** + * Evaluate one double operand. + * + * @param operand + * The operand being evaluated. + */ + public double evaluate(final double operand) { + return -operand; + } +} \ No newline at end of file diff --git a/jar-enginex-runner/src/main/resources/application-dev.properties b/jar-enginex-runner/src/main/resources/application-dev.properties new file mode 100644 index 0000000..6181b46 --- /dev/null +++ b/jar-enginex-runner/src/main/resources/application-dev.properties @@ -0,0 +1,38 @@ +server.port=8081 + +logging.config=classpath:logging-config.xml + +# mysql +spring.datasource.default.url = jdbc:mysql://localhost:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true +spring.datasource.default.username = root +spring.datasource.default.password = enginex513 +spring.datasource.default.driver-class-name = com.mysql.cj.jdbc.Driver + +# redis +redis.host=localhost +redis.port=6379 +redis.db=1 +redis.password=localhost +redis.pool.maxTotal=3000 +redis.pool.maxIdle=100 +redis.pool.maxWait=1000 +redis.pool.timeout=100000 + +# mail +spring.mail.host=smtp.exmail.qq.com +spring.mail.username=xxx +spring.mail.password=xxx +spring.mail.port=465 +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.timeout=50000 +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.socketFactory.port=465 +spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback=false + +# canal +switch.use.cache=off +switch.canal.cache=off +canal.hostname=localhost +canal.port=11111 + diff --git a/jar-enginex-runner/src/main/resources/application-prod.properties b/jar-enginex-runner/src/main/resources/application-prod.properties new file mode 100644 index 0000000..2dbd1b7 --- /dev/null +++ b/jar-enginex-runner/src/main/resources/application-prod.properties @@ -0,0 +1,45 @@ +server.port=8081 + +logging.config=classpath:logging-config.xml + +# mysql +spring.datasource.default.url = jdbc:mysql://localhost:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true +spring.datasource.default.username = root +spring.datasource.default.password = enginex513! +spring.datasource.default.driver-class-name = com.mysql.cj.jdbc.Driver + +# redis +redis.host=localhost +redis.port=6379 +redis.db=1 +redis.password=localhost +redis.pool.maxTotal=3000 +redis.pool.maxIdle=100 +redis.pool.maxWait=1000 +redis.pool.timeout=100000 + +# mail +spring.mail.host=smtp.exmail.qq.com +spring.mail.username=xxx +spring.mail.password=xxx +spring.mail.port=465 +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.timeout=50000 +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.socketFactory.port=465 +spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback=false + +# hbase +spring.data.hbase.quorum: localhost:2181 +spring.data.hbase.rootDir: /usr/local/hbase/datatest +spring.data.hbase.nodeParent: /hbase + +# canal +switch.use.cache=off +switch.canal.cache=off +canal.hostname=localhost +canal.port=11111 + +# \u76D1\u63A7\u4E2D\u5FC3 \u6570\u636E\u5B58\u50A8\u65B9\u5F0F mysql \u6216\u8005 hbase +monitor.data.storage.type=mysql \ No newline at end of file diff --git a/jar-enginex-runner/src/main/resources/application-test.properties b/jar-enginex-runner/src/main/resources/application-test.properties new file mode 100644 index 0000000..1cae7c9 --- /dev/null +++ b/jar-enginex-runner/src/main/resources/application-test.properties @@ -0,0 +1,45 @@ +server.port=8081 + +logging.config=classpath:logging-config.xml + +# mysql +spring.datasource.default.url = jdbc:mysql://localhost:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true +spring.datasource.default.username = root +spring.datasource.default.password = enginex513 +spring.datasource.default.driver-class-name = com.mysql.cj.jdbc.Driver + +# redis +redis.host=localhost +redis.port=6379 +redis.db=1 +redis.password=enginex123 +redis.pool.maxTotal=3000 +redis.pool.maxIdle=100 +redis.pool.maxWait=1000 +redis.pool.timeout=100000 + +# mail +spring.mail.host=smtp.exmail.qq.com +spring.mail.username=xxx +spring.mail.password=xxx +spring.mail.port=465 +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.timeout=50000 +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.socketFactory.port=465 +spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory +spring.mail.properties.mail.smtp.socketFactory.fallback=false + +# hbase +spring.data.hbase.quorum: localhost:2181 +spring.data.hbase.rootDir: /usr/local/hbase/datatest +spring.data.hbase.nodeParent: /hbase + +# canal +switch.use.cache=off +switch.canal.cache=on +canal.hostname=localhost +canal.port=11111 + +# \u76D1\u63A7\u4E2D\u5FC3 \u6570\u636E\u5B58\u50A8\u65B9\u5F0F mysql \u6216\u8005 hbase +monitor.data.storage.type=mysql \ No newline at end of file diff --git a/jar-enginex-runner/src/main/resources/application.properties b/jar-enginex-runner/src/main/resources/application.properties new file mode 100644 index 0000000..257b306 --- /dev/null +++ b/jar-enginex-runner/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=dev \ No newline at end of file diff --git a/jar-enginex-runner/src/main/resources/logging-config.xml b/jar-enginex-runner/src/main/resources/logging-config.xml new file mode 100644 index 0000000..fc9a3ec --- /dev/null +++ b/jar-enginex-runner/src/main/resources/logging-config.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JarEnginexExecutorApplicationTests.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JarEnginexExecutorApplicationTests.java new file mode 100644 index 0000000..64d7062 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JarEnginexExecutorApplicationTests.java @@ -0,0 +1,13 @@ +package com.baoying.enginex.executor; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class JarEnginexExecutorApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JevalTest.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JevalTest.java new file mode 100644 index 0000000..4b25ac9 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/JevalTest.java @@ -0,0 +1,16 @@ +package com.baoying.enginex.executor; + +import com.baoying.enginex.executor.util.JevalUtil; +import com.baoying.enginex.executor.util.jeval.EvaluationException; +import com.baoying.enginex.executor.util.jeval.Evaluator; + +import java.util.HashMap; + +public class JevalTest { + public static void main(String[] args) throws EvaluationException { + HashMap map = new HashMap<>(); + map.put("ceshiyong","'a'"); + String expression = "(contains(#{ceshiyong},'a'))"; + System.out.println(JevalUtil.evaluateBoolean(expression.toString(), map)); + } +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/RegexTest.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/RegexTest.java new file mode 100644 index 0000000..629cac1 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/RegexTest.java @@ -0,0 +1,36 @@ +package com.baoying.enginex.executor; + +import com.alibaba.fastjson.JSON; +import com.baoying.enginex.executor.util.ExecuteUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RegexTest { + public static void main(String[] args) { + Pattern pattern$ = Pattern.compile("\\$\\{[a-zA-Z0-9_\u4e00-\u9fa5()()-]+\\}"); + Matcher matcher$ = pattern$.matcher("${aa}"); + + while (matcher$.find()){ + System.out.println(matcher$.group()); + } +// System.out.println("".matches("大abcd")); +// Pattern pattern = Pattern.compile("(abcd)+"); +// Pattern pattern = Pattern.compile("(\\[(0|([1-9]([0-9])*))\\])+$"); +// Matcher matcher = pattern.matcher("addd[0][1][2][3][4][5]"); +// +// System.out.println(matcher.find()); +// System.out.println(matcher.group(0)); +// String fieldEnStr = "a.s.d.1.2.3."; +// System.out.println(JSON.toJSONString(fieldEnStr.split("\\."))); + } + private static void testRegex(){ + String formula = "@1@2@3@4@5@6@7@"; + Pattern pattern = Pattern.compile("@[a-zA-Z0-9_\u4e00-\u9fa5()()-]+@"); + Matcher matcher = pattern.matcher(formula); + while (matcher.find()) { + String fieldEn = matcher.group().replace("@", ""); + System.out.println(matcher.group()); + } + } +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/Auth.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/Auth.java new file mode 100644 index 0000000..da71fa2 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/Auth.java @@ -0,0 +1,11 @@ +package com.baoying.enginex.executor.grouping; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Auth { + private Integer id; + private String name; +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/GroupTest.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/GroupTest.java new file mode 100644 index 0000000..afb66ca --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/GroupTest.java @@ -0,0 +1,250 @@ +package com.baoying.enginex.executor.grouping; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.junit.platform.commons.util.StringUtils; + +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class GroupTest { + public static void main(String[] args) { +// test2(); +// test3(); +// test1(); + test4(); + + } + public static void test1(){ + List list = new ArrayList(); + for (int i = 0; i < 100; i++) { + list.add(new User(i,"用户 : "+i,i%10+18,new Role((int)(Math.random()*10+1),"角色 : "+i%10,new Auth((int)(Math.random()*10+1),"权限 : "+i%20)))); + } + Map> result = new HashMap<>(); + + Map> collect = list.stream().collect(Collectors.groupingBy(user -> user.getAge())); + for (Map.Entry> entry : collect.entrySet()) { + Integer key = entry.getKey(); + Map> collect1 = entry.getValue().stream().collect(Collectors.groupingByConcurrent(user -> user.getRole().getId())); + for (Map.Entry> childEntry : collect1.entrySet()) { + result.put(""+key+":"+childEntry.getKey(),childEntry.getValue()); + } + } +// System.out.println(collect); + } +// public static void handlerGroup(Map> param,List keys){ +// Map> result = new HashMap<>(); +// for (Map.Entry> listEntry : param.entrySet()) { +// //前一次分组时的key +// String parentKey = listEntry.getKey(); +// //第一次分组完成的一个数组 +// List list = listEntry.getValue(); +// //默认key为父级key +// String resultKey = parentKey; +// +// for (String key : keys) { +// Map> collect = list.stream().collect(Collectors.groupingBy(json -> json.get(key).toString())); +// for (Map.Entry> childEntry : collect.entrySet()) { +// resultKey += (":"+ childEntry.getKey()); +// result.put(resultKey,childEntry.getValue()); +// } +// +// } +// } +// } + + + public static void test2(){ + List> list = new ArrayList(); + Map map = null; + for (int i = 0; i < 100; i++) { + map = new HashMap(); + map.put("id",i); + map.put("name","用户 : "+i); + map.put("age",i%10); + list.add(map); + } + Map>> collect = list.stream().collect(Collectors.groupingBy(item -> item.get("age"))); + + for (Map.Entry>> entry : collect.entrySet()) { + System.out.println(entry.getKey()); + System.out.println(entry.getValue()); + System.out.println(entry.getValue().size()); + } + } + + public static void test3(){ + List> list = new ArrayList(); + JSONObject map = null; + for (int i = 0; i < 100; i++) { + map = new JSONObject(); + map.put("id",i); + map.put("name","用户 : "+i); + map.put("age",i%10); + list.add(map); + } + Map>> collect = list.stream().collect(Collectors.groupingBy(item -> item.get("age"))); + + for (Map.Entry>> entry : collect.entrySet()) { + System.out.println(entry.getKey()); + System.out.println(entry.getValue()); + System.out.println(entry.getValue().size()); + } + + } + + public static void test4(){ + List list = new ArrayList(); + JSONObject map = null; + List authList; + for (int i = 0; i < 10000; i++) { + map = new JSONObject(); + map.put("id",i%5); + map.put("name","用户"+i%3); + map.put("age",i%13); + authList = new ArrayList<>(); + authList.add(new Auth(i%7,"权限"+i%7)); + map.put("role",new Role(i%11,"角色"+i%7,null,authList)); + + list.add(map); + } + +// Map> stringListMap = handlerGroup(list, Arrays.asList("age", "name", "id","role.id")); + Map> stringListMap = recursionGroup(list, Arrays.asList("age", "name", "role.name","role.authList[0].name")); + System.out.println(stringListMap); + } + +// public static Map> handlerGroup(List param, List keys ){ +// //没有给分组的key则直接返回 +// if (keys==null||keys.isEmpty()){ +// return null; +// } +// Map> result = recursionGroup(param, keys,0,""); +// return result; +// } +// +// public static Map> recursionGroup(List param,List keys,int index,String parentKey){ +// +// if (StringUtils.isNotBlank(parentKey)){ +// parentKey+=":"; +// } +// final String preKey = parentKey; +// Map> result = new HashMap<>(); +// +// Map> temp = new HashMap<>(); +// if (keys.get(index)!=null){ +// //做本次分组 +// Map> collect = param.stream().collect(Collectors.groupingBy(json -> { +// String[] split = keys.get(index).split("\\."); +// if (split.length>1){ +// JSONObject jsonObject = json; +// for (int i = 0; i < split.length; i++) { +// if (iindex+1){ +// //执行分组 +// for (Map.Entry> entry : collect.entrySet()) { +// temp.putAll(recursionGroup(entry.getValue(),keys,index+1,entry.getKey())); +// } +// }else { +// temp = collect; +// } +// }else { +// //没有分组的key无法执行 +// } +// result = temp.entrySet().stream().collect(Collectors.toMap(item->preKey+item.getKey(),item->item.getValue())); +// return result; +// } + + public static Map> recursionGroup(List param,List keys){ + return param.stream().collect(Collectors.groupingBy(item->{ + String cond = ""; + for (String key : keys) { + if (StringUtils.isNotBlank(cond)){ + cond+=":"; + } + String[] split = key.split("\\."); + if (split.length>1){ + JSONObject jsonObject = item; + for (int i = 0; i < split.length; i++) { + if (i authList; + + public Role(Integer id, String name, Auth auth, List authList) { + this.id = id; + this.name = name; + this.auth = auth; + this.authList = authList; + } + + public Role(Integer id, String name, Auth auth) { + this.id = id; + this.name = name; + this.auth = auth; + } +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/User.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/User.java new file mode 100644 index 0000000..b7f2792 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/grouping/User.java @@ -0,0 +1,13 @@ +package com.baoying.enginex.executor.grouping; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class User { + private Integer id; + private String name; + private Integer age; + private Role role; +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/RedisTest.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/RedisTest.java new file mode 100644 index 0000000..c2b6194 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/RedisTest.java @@ -0,0 +1,75 @@ +package com.baoying.enginex.executor.sql; + +import redis.clients.jedis.*; + +import java.util.List; + +public class RedisTest { + public static void main(String[] args) { +// JedisPoolConfig config = new JedisPoolConfig(); +// config.setMaxTotal(1); +// config.setMaxIdle(1); +// config.setMaxWaitMillis(3000); +// config.setTestOnBorrow(true); +// config.setTestOnReturn(true); +// +// JedisPool pool = new JedisPool(config, +// "127.0.0.1", +// 6379, +// 3000, +// "root", +// 1); +// Jedis jedis = pool.getResource(); + JedisShardInfo jedisShardInfo = new JedisShardInfo("47.102.125.25",6379,3000,"root"); + jedisShardInfo.setPassword("enginex123"); + Jedis jedis = new Jedis(jedisShardInfo); + jedis.select(1); + if (jedis.isConnected()){ + + Object eval = jedis.eval("local result = 0;\n" + + "local flag = true;\n" + + "local cursor = '0';\n" + + "while(flag)\n" + + "do\n" + + "local scanResult = redis.call('hscan','THRESHOLD_MOBILE_DAY:20211116:手机号1',cursor ,'match','12*');\n" + + "cursor = scanResult[1];\n" + + " for k, v in pairs(scanResult[2]) do\n" + + " if k%2 == 0 then\n" + + " result = result+v;\n" + + " end\n" + + " end\n" + + " if scanResult == nil or cursor == '0'then\n" + + " flag = false;\n" + + " end\n" + + "end\n" + + "return result;"); + +// System.out.println(jedis.eval("return redis.call('get', 'test1')")); +// Object eval = jedis.eval("return redis.call('LRANGE', 'list1' , 0 , -1)"); + long value = 0; + if (eval instanceof List){ + System.out.println(eval); + List result = (List) eval; + + if (result.get(1) instanceof List){ + System.out.println(result.get(1)); + List kv = (List)result.get(1); + for (int i = 0; i < kv.size(); i++) { + if (i%2 == 0){ + continue; + } + value += Long.valueOf(kv.get(i)); + } + + } + + } + + System.out.println(value); +// String aaa = jedis.get("test1"); +// System.out.println(aaa); + } + + + } +} diff --git a/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/SqlForTest.java b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/SqlForTest.java new file mode 100644 index 0000000..ea73f20 --- /dev/null +++ b/jar-enginex-runner/src/test/java/com/baoying/enginex/executor/sql/SqlForTest.java @@ -0,0 +1,51 @@ +package com.baoying.enginex.executor.sql; + +import com.alibaba.fastjson.JSON; +import com.baoying.enginex.executor.datamanage.mapper.SimpleMapper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +//@SpringBootTest +//@RunWith(SpringRunner.class) +public class SqlForTest { + + @Autowired + private SimpleMapper simpleMapper; + @Test + public void testForSql(){ + + String sqlStr = " select * from t_list_db " + + " where id in " + + " \n" + + " #{item}\n" + + " "; + Map param = new HashMap<>(); + param.put("sqlStr",sqlStr); + List ids = new ArrayList<>(); + ids.add(112L); + ids.add(114L); + ids.add(115L); + param.put("list",ids); + List> test = simpleMapper.test(param); + + System.out.println(JSON.toJSONString(test)); + + } + + public static void main(String[] args) { + String sqlStr = " select * from t_list_db " + + " where id in ( #{aaaa} )"; + Pattern sqlnPattern = Pattern.compile("\\s*in\\s*\\(\\s*#\\{([a-zA-Z0-9_\u4e00-\u9fa5()()-]+)\\}\\s*\\)"); + Matcher matcher = sqlnPattern.matcher(sqlStr); + if ( matcher.find()){ + System.out.println(matcher.group(0)); + } + } +}