├── .circleci └── config.yml ├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── maven.yml ├── .gitignore ├── .project ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── com.intuit.dsl.expression.parent ├── .project ├── com.intuit.dsl.expression.ide │ ├── .classpath │ ├── .project │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.properties │ ├── pom.xml │ └── src │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── intuit │ │ └── dsl │ │ └── ide │ │ ├── ExpressionIdeModule.java │ │ └── ExpressionIdeSetup.java ├── com.intuit.dsl.expression.runtime │ ├── .classpath │ ├── .project │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── intuit │ │ │ └── dsl │ │ │ └── expression │ │ │ └── runtime │ │ │ ├── ConfigManager.java │ │ │ ├── ExpressionRuntime.java │ │ │ ├── evaluator │ │ │ ├── Evaluator.java │ │ │ ├── ExpressionEvaluator.java │ │ │ ├── config │ │ │ │ ├── PropertyEvaluator.java │ │ │ │ └── PropertyExpresssionEvaluator.java │ │ │ ├── function │ │ │ │ ├── AddToDateEvaluator.java │ │ │ │ ├── CollectionFunctionEvaluator.java │ │ │ │ ├── ConcatFuncEvaluator.java │ │ │ │ ├── ContainsEvaluator.java │ │ │ │ ├── CurrentDateEvaluator.java │ │ │ │ ├── DateFormatEvaluator.java │ │ │ │ ├── DayDifferenceEvaluator.java │ │ │ │ ├── DedupFuncEvaluator.java │ │ │ │ ├── DeleteEvaluator.java │ │ │ │ ├── ExtractEvaluator.java │ │ │ │ ├── FilterFuncEvaluator.java │ │ │ │ ├── FindFirstFuncEvaluator.java │ │ │ │ ├── FunctionReferenceEvaluator.java │ │ │ │ ├── JoinEvaluator.java │ │ │ │ ├── JsonEvaluator.java │ │ │ │ ├── LastFuncEvaluator.java │ │ │ │ ├── LengthEvaluator.java │ │ │ │ ├── LowerFuncEvaluator.java │ │ │ │ ├── MapFuncEvaluator.java │ │ │ │ ├── ParentFuncEvaluator.java │ │ │ │ ├── PickFirstEvaluator.java │ │ │ │ ├── RemoveFuncEvaluator.java │ │ │ │ ├── SortFuncEvaluator.java │ │ │ │ ├── SplitEvaluator.java │ │ │ │ ├── TernaryExpressionEvaluator.java │ │ │ │ ├── TranslateUnicodeEvaluator.java │ │ │ │ ├── UUIDFuncEvaluator.java │ │ │ │ └── UpperFuncEvaluator.java │ │ │ ├── operation │ │ │ │ ├── ArithmeticSignedEvaluator.java │ │ │ │ ├── BooleanExpressionEvaluator.java │ │ │ │ ├── BooleanNegationEvaluator.java │ │ │ │ ├── ComparisonEvaluator.java │ │ │ │ ├── EqualsEvaluator.java │ │ │ │ ├── MembershipEvaluator.java │ │ │ │ ├── MinusEvaluator.java │ │ │ │ ├── MultiOrDivOrModEvaluator.java │ │ │ │ └── PlusEvaluator.java │ │ │ └── variables │ │ │ │ ├── LiteralEvaluators.java │ │ │ │ ├── SchemaVariableEvaluator.java │ │ │ │ └── VariableReferenceEvaluator.java │ │ │ ├── exception │ │ │ └── ExpressionEvaluationException.java │ │ │ ├── model │ │ │ ├── DataModel.java │ │ │ ├── DataValue.java │ │ │ ├── JsonModel.java │ │ │ ├── NumberValue.java │ │ │ ├── RuntimeOptions.java │ │ │ └── XmlModel.java │ │ │ ├── parser │ │ │ └── XtextExpressionParser.java │ │ │ └── util │ │ │ ├── DateUtils.java │ │ │ ├── EvaluatorUtils.java │ │ │ └── JSONUtils.java │ │ └── test │ │ ├── groovy │ │ ├── ArithmeticSpecification.groovy │ │ ├── BooleanSpecification.groovy │ │ ├── CaseSpecification.groovy │ │ ├── ComplexExpressionTest.groovy │ │ ├── ConcatSpecification.groovy │ │ ├── ContainsSpecification.groovy │ │ ├── EqualitySpecification.groovy │ │ ├── ExtractSpecification.groovy │ │ ├── FilterSpecification.groovy │ │ ├── LengthSpecification.groovy │ │ ├── RemoveSpecification.groovy │ │ └── SortSpecification.groovy │ │ └── java │ │ ├── com │ │ └── intuit │ │ │ └── dsl │ │ │ └── expression │ │ │ └── runtime │ │ │ └── util │ │ │ ├── DateUtilsTest.java │ │ │ ├── EvaluatorUtilsTest.java │ │ │ └── JsonUtilsTest.java │ │ └── util │ │ └── TestUtils.java ├── com.intuit.dsl.expression.target │ ├── .project │ ├── com.intuit.dsl.expression.target.target │ └── pom.xml ├── com.intuit.dsl.expression.tests │ ├── .classpath │ ├── .project │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.properties │ ├── pom.xml │ └── src │ │ └── com │ │ └── intuit │ │ └── dsl │ │ └── tests │ │ └── ExpressionParsingTest.xtend ├── com.intuit.dsl.expression.ui.tests │ ├── .classpath │ ├── .project │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.properties │ └── pom.xml ├── com.intuit.dsl.expression.ui │ ├── .classpath │ ├── .project │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.properties │ ├── plugin.xml │ ├── pom.xml │ └── src │ │ └── com │ │ └── intuit │ │ └── dsl │ │ └── ui │ │ ├── ExpressionUiModule.java │ │ ├── contentassist │ │ └── ExpressionProposalProvider.java │ │ ├── labeling │ │ ├── ExpressionDescriptionLabelProvider.java │ │ └── ExpressionLabelProvider.java │ │ ├── outline │ │ └── ExpressionOutlineTreeProvider.java │ │ └── quickfix │ │ └── ExpressionQuickfixProvider.java ├── com.intuit.dsl.expression.web │ ├── .classpath │ ├── .project │ ├── WebRoot │ │ ├── index.html │ │ └── style.css │ ├── pom.xml │ └── src │ │ └── com │ │ └── intuit │ │ └── dsl │ │ └── web │ │ ├── ExpressionServlet.java │ │ ├── ExpressionWebModule.java │ │ ├── ExpressionWebSetup.java │ │ └── ServerLauncher.java ├── com.intuit.dsl.expression │ ├── .classpath │ ├── .project │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.properties │ ├── plugin.xml │ ├── pom.xml │ └── src │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── intuit │ │ └── dsl │ │ ├── Expression.xtext │ │ ├── ExpressionRuntimeModule.java │ │ ├── ExpressionStandaloneSetup.java │ │ ├── GenerateExpression.mwe2 │ │ ├── generator │ │ └── ExpressionGenerator.xtend │ │ ├── scoping │ │ └── ExpressionScopeProvider.java │ │ └── validation │ │ └── ExpressionValidator.java └── pom.xml ├── common-xtext-expression-language-logo.png ├── common-xtext-expression-language-logo.svg ├── documents ├── images │ ├── addRepo.png │ ├── deselectLatestVersions.png │ ├── generateFlow.png │ ├── installNewSoftware.png │ ├── xtendVersion.png │ └── xtextVersion.png ├── style-guide-eclipse.xml └── style-guide-intellij.xml ├── mkdocs ├── docs │ ├── css │ │ └── css-override.css │ ├── expressions │ │ ├── Arithmetic.md │ │ ├── Boolean.md │ │ └── Conditional.md │ ├── functions │ │ ├── concat.md │ │ ├── contains.md │ │ ├── currentDate.md │ │ ├── dateFormat.md │ │ ├── dayDifference.md │ │ ├── dedup.md │ │ ├── extract.md │ │ ├── filter.md │ │ ├── findFirst.md │ │ ├── join.md │ │ ├── json.md │ │ ├── length.md │ │ ├── map.md │ │ ├── pickFirst.md │ │ ├── remove.md │ │ ├── shuffle.md │ │ ├── sort.md │ │ └── split.md │ ├── img │ │ └── common-xtext-expression-language-logo.png │ └── index.md ├── mkdocs.yml ├── readme.md └── requirements.txt └── pom.xml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Use the latest 2.1 version of CircleCI pipeline process engine. 2 | # See: https://circleci.com/docs/2.0/configuration-reference 3 | version: 2.1 4 | 5 | jobs: 6 | build-and-test: 7 | # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/openjdk 8 | docker: 9 | - image: circleci/openjdk:8-jdk-stretch 10 | steps: 11 | - checkout 12 | - run: 13 | name: Build 14 | command: mvn -B clean install 15 | - store_test_results: 16 | path: com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/target/surefire-reports 17 | 18 | workflows: 19 | # For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows 20 | ci_builds: 21 | jobs: 22 | - build-and-test 23 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # List of source code paths and code owners 2 | # common services & repos 3 | * @scanbns @ashpak-shaikh 4 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Open source projects are “living.” Contributions in the form of issues and pull requests are welcomed and encouraged. When you contribute, you explicitly say you are part of the community and abide by its Code of Conduct. 2 | 3 | # The Code 4 | 5 | At Intuit, we foster a kind, respectful, harassment-free cooperative community. Our open source community works to: 6 | 7 | - Be kind and respectful; 8 | - Act as a global community; 9 | - Conduct ourselves professionally. 10 | 11 | As members of this community, we will not tolerate behaviors including, but not limited to: 12 | 13 | - Violent threats or language; 14 | - Discriminatory or derogatory jokes or language; 15 | - Public or private harassment of any kind; 16 | - Other conduct considered inappropriate in a professional setting. 17 | 18 | ## Reporting Concerns 19 | 20 | If you see someone violating the Code of Conduct please email TechOpenSource@intuit.com 21 | 22 | ## Scope 23 | 24 | This code of conduct applies to: 25 | 26 | All repos and communities for Intuit-managed projects, whether or not the text is included in a Intuit-managed project’s repository; 27 | 28 | Individuals or teams representing projects in official capacity, such as via official social media channels or at in-person meetups. 29 | 30 | ## Attribution 31 | 32 | This Code of Conduct is partly inspired by and based on those of Amazon, CocoaPods, GitHub, Microsoft, thoughtbot, and on the Contributor Covenant version 1.4.1. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | 11 | 12 | 13 | **To Reproduce** 14 | 15 | 16 | 17 | **Expected behavior** 18 | 19 | 20 | 21 | **Screenshots** 22 | 23 | 24 | 25 | **Desktop (please complete the following information):** 26 | 27 | - OS: [e.g. iOS] 28 | - Version [e.g. 22] 29 | 30 | **Additional context** 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | 13 | 14 | **Describe the solution you'd like** 15 | 16 | 17 | 18 | **Describe alternatives you've considered** 19 | 20 | 21 | 22 | **Additional context** 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # What Changed 2 | 3 | # Why 4 | 5 | Todo: 6 | 7 | - [ ] Add tests 8 | - [ ] Add docs 9 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ develop ] 9 | pull_request: 10 | branches: [ develop ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 8 20 | uses: actions/setup-java@v2 21 | with: 22 | java-version: '8' 23 | distribution: 'adopt' 24 | - name: Build with Maven 25 | run: mvn -B clean install --file pom.xml 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Jenkinsfile 2 | build 3 | tmp 4 | bin 5 | target 6 | generated 7 | generated-sources 8 | src-gen 9 | xtend-gen 10 | *.xml_gen 11 | .metadata 12 | Remote* 13 | .settings/ 14 | .idea/ 15 | .prefs 16 | *.iml 17 | .DS_Store 18 | .iml 19 | .launch/ 20 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | graphql-sdl 4 | 5 | 6 | com.intuit.graphql.parent 7 | 8 | 9 | 10 | org.eclipse.xtext.ui.shared.xtextBuilder 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Builder 16 | 17 | 18 | 19 | 20 | 21 | org.eclipse.m2e.core.maven2Nature 22 | org.eclipse.xtext.ui.shared.xtextNature 23 | 24 | 25 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This page explains common tasks related to working with CXEL's source code. 2 | 3 | ### Submitting an issue 4 | * If you have any questions about CXEL or something doesn't work as expected, please submit an issue [here](https://github.com/intuit/common-xtext-expression-language/issues). 5 | 6 | ### Contribution Guidelines 7 | First of all, thank you for your interest in contributing to this project! 8 | 9 | * Make sure there is a GitHub issue for what you want to work on 10 | * If a [relevant issue](https://github.com/intuit/common-xtext-expression-language/issues) already exists, have a discussion within that issue (by commenting) - and make sure the project-leads are okay with your approach 11 | * If no relevant issue exists, please [open a new issue](https://github.com/intuit/common-xtext-expression-language/issues) to start a discussion 12 | * Before submitting a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) (PR), please make sure you have had a discussion with the project-leads -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.parent 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.ide 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.xtext.ui.shared.xtextBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.pde.ManifestBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.pde.SchemaBuilder 30 | 31 | 32 | 33 | 34 | org.eclipse.wst.validation.validationbuilder 35 | 36 | 37 | 38 | 39 | org.eclipse.m2e.core.maven2Builder 40 | 41 | 42 | 43 | 44 | 45 | org.eclipse.jem.workbench.JavaEMFNature 46 | org.eclipse.wst.common.modulecore.ModuleCoreNature 47 | org.eclipse.m2e.core.maven2Nature 48 | org.eclipse.xtext.ui.shared.xtextNature 49 | org.eclipse.jdt.core.javanature 50 | org.eclipse.pde.PluginNature 51 | org.eclipse.wst.common.project.facet.core.nature 52 | 53 | 54 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Automatic-Module-Name: com.intuit.dsl.expression.ide 3 | Bundle-ManifestVersion: 2 4 | Bundle-Name: com.intuit.dsl.expression.ide 5 | Bundle-Vendor: My Company 6 | Bundle-Version: 1.0.0.qualifier 7 | Bundle-SymbolicName: com.intuit.dsl.expression.ide; singleton:=true 8 | Bundle-ActivationPolicy: lazy 9 | Require-Bundle: com.intuit.dsl.expression, 10 | org.eclipse.xtext.ide, 11 | org.eclipse.xtext.xbase.ide, 12 | org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" 13 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 14 | Export-Package: com.intuit.dsl.ide.contentassist.antlr.internal, 15 | com.intuit.dsl.ide.contentassist.antlr 16 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = .,\ 5 | META-INF/ 6 | bin.excludes = **/*.xtend 7 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.intuit.dsl.expression 5 | com.intuit.dsl.expression.parent 6 | 1.0.4-SNAPSHOT 7 | 8 | com.intuit.dsl.expression.ide 9 | eclipse-plugin 10 | 11 | 12 | 13 | 14 | org.eclipse.xtend 15 | xtend-maven-plugin 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/src/com/intuit/dsl/ide/ExpressionIdeModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ide; 5 | 6 | 7 | /** 8 | * Use this class to register ide components. 9 | */ 10 | public class ExpressionIdeModule extends AbstractExpressionIdeModule { 11 | } 12 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ide/src/com/intuit/dsl/ide/ExpressionIdeSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ide; 5 | 6 | import com.google.inject.Guice; 7 | import com.google.inject.Injector; 8 | import com.intuit.dsl.ExpressionRuntimeModule; 9 | import com.intuit.dsl.ExpressionStandaloneSetup; 10 | import org.eclipse.xtext.util.Modules2; 11 | 12 | /** 13 | * Initialization support for running Xtext languages as language servers. 14 | */ 15 | public class ExpressionIdeSetup extends ExpressionStandaloneSetup { 16 | 17 | @Override 18 | public Injector createInjector() { 19 | return Guice.createInjector(Modules2.mixin(new ExpressionRuntimeModule(), new ExpressionIdeModule())); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | runtime 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.xtext.ui.shared.xtextNature 26 | org.eclipse.jdt.core.javanature 27 | org.eclipse.m2e.core.maven2Nature 28 | 29 | 30 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/ConfigManager.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime; 2 | 3 | public interface ConfigManager { 4 | 5 | default String getProperty(String property) { 6 | return ""; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/ExpressionRuntime.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime; 2 | 3 | import static com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator.newExpressionEvaluator; 4 | import java.io.IOException; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Objects; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | import org.eclipse.xtext.resource.XtextResource; 10 | import com.fasterxml.jackson.databind.JsonNode; 11 | import com.google.common.collect.Maps; 12 | import com.intuit.dsl.expression.Expression; 13 | import com.intuit.dsl.expression.runtime.model.DataValue; 14 | import com.intuit.dsl.expression.runtime.model.JsonModel; 15 | import com.intuit.dsl.expression.runtime.model.RuntimeOptions; 16 | import com.intuit.dsl.expression.runtime.parser.XtextExpressionParser; 17 | 18 | public class ExpressionRuntime { 19 | 20 | private static Map CACHE = new ConcurrentHashMap<>(); 21 | private String expressionContent; 22 | private Expression expression; 23 | private Map data = new HashMap<>(); 24 | private RuntimeOptions options = new RuntimeOptions(); 25 | private ConfigManager configManager = new ConfigManager() {}; 26 | 27 | private ExpressionRuntime() {} 28 | 29 | public static ExpressionRuntime newExpressionRuntime() { 30 | return new ExpressionRuntime(); 31 | } 32 | 33 | public ExpressionRuntime withExpressionContent(final String expressionContent) { 34 | this.expressionContent = expressionContent; 35 | return this; 36 | } 37 | 38 | public ExpressionRuntime withExpression(final Expression expression) { 39 | this.expression = expression; 40 | return this; 41 | } 42 | 43 | public ExpressionRuntime withData(final Map data) { 44 | this.data = data; 45 | return this; 46 | } 47 | 48 | public ExpressionRuntime withOptions(final RuntimeOptions options) { 49 | this.options = options; 50 | return this; 51 | } 52 | 53 | public ExpressionRuntime withConfigManager(final ConfigManager manager) { 54 | this.configManager = manager; 55 | return this; 56 | } 57 | 58 | public DataValue evaluate() throws IOException { 59 | if(expression == null) { 60 | expression = getExpression(); 61 | } 62 | Objects.requireNonNull(expression, "No expression found"); 63 | return newExpressionEvaluator() 64 | .withInputs( 65 | Maps.transformValues(data, value -> new JsonModel(value, options.getNumberPragma()))) 66 | .withOptions(options).withConfigManager(configManager).build().doSwitch(expression); 67 | } 68 | 69 | private Expression getExpression() throws IOException { 70 | Objects.requireNonNull(expressionContent, "Expression content not provided"); 71 | Expression expFromCache = CACHE.get(expressionContent); 72 | if (Objects.nonNull(expFromCache)) { 73 | return expFromCache; 74 | } 75 | XtextResource resource = new XtextExpressionParser().parse(expressionContent); 76 | Objects.requireNonNull(resource, "Xtext resouce cannot be null"); 77 | Expression expression = (Expression) resource.getContents().get(0); 78 | Objects.requireNonNull(expression, "No expression found to evaluate"); 79 | CACHE.put(expressionContent, expression); 80 | return expression; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/Evaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator; 2 | 3 | import com.intuit.dsl.expression.runtime.exception.ExpressionEvaluationException; 4 | import com.intuit.dsl.expression.runtime.model.DataValue; 5 | import org.eclipse.emf.ecore.EObject; 6 | 7 | public interface Evaluator { 8 | 9 | default DataValue evaluate(T expression) { 10 | throw new ExpressionEvaluationException( 11 | String.format("No evaluator found for expresion: {%s}", expression.toString())); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/config/PropertyEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.config; 2 | 3 | import com.intuit.dsl.expression.Property; 4 | import com.intuit.dsl.expression.runtime.ConfigManager; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class PropertyEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | public PropertyEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final Property property) { 22 | ConfigManager configManager = visitor.getConfigManager(); 23 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 24 | return EvaluatorUtils.getPrimitiveValue(configManager.getProperty(property.getKey()), numberPragma); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/config/PropertyExpresssionEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.config; 2 | 3 | import com.intuit.dsl.expression.PropertyExpresssion; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | @Slf4j 10 | public class PropertyExpresssionEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public PropertyExpresssionEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final PropertyExpresssion variableRef) { 20 | return visitor.doSwitch(variableRef.getRef()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/AddToDateEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.AddToDate; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Calendar; 9 | import java.util.Date; 10 | import java.util.Objects; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.StringUtils; 13 | 14 | @Slf4j 15 | public class AddToDateEvaluator implements Evaluator { 16 | 17 | ExpressionEvaluator visitor; 18 | 19 | 20 | public AddToDateEvaluator(ExpressionEvaluator visitor) { 21 | this.visitor = visitor; 22 | } 23 | 24 | @Override 25 | public DataValue evaluate(final AddToDate date) { 26 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 27 | DataValue value = visitor.doSwitch(date.getExp()); 28 | DataValue givenDate = visitor.doSwitch(date.getDateExp()); 29 | if (Objects.isNull(givenDate) || givenDate.getType() == DataValue.Type.NULL) { 30 | return new DataValue(null, DataValue.Type.NULL); 31 | } 32 | try { 33 | String format = StringUtils.remove((date.getFormat()), '"'); 34 | SimpleDateFormat sdf = new SimpleDateFormat(format); 35 | Calendar calendar = Calendar.getInstance(); 36 | if (value.getType() == DataValue.Type.NUMBER) { 37 | if (StringUtils.equals(format,"ms")) { 38 | calendar.setTime(sdf.parse(givenDate.getValue().toString())); 39 | calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(value.toString())); 40 | return new DataValue(sdf.format(calendar.getTime()), DataValue.Type.STRING, 41 | numberPragma); 42 | } else { 43 | calendar.setTime(new Date(Long.parseLong(givenDate.getValue().toString()))); 44 | calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(value.toString())); 45 | return new DataValue(calendar.getTimeInMillis(), DataValue.Type.STRING, 46 | numberPragma); 47 | } 48 | } 49 | return givenDate; 50 | } catch (Exception ex) { 51 | log.debug("Invalid date to add to", date.toString()); 52 | return givenDate; 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/CollectionFunctionEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.CollectionFunction; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataModel; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import com.intuit.dsl.expression.runtime.model.JsonModel; 9 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 10 | import java.util.Objects; 11 | import lombok.extern.slf4j.Slf4j; 12 | 13 | @Slf4j 14 | public class CollectionFunctionEvaluator implements Evaluator { 15 | 16 | ExpressionEvaluator visitor; 17 | 18 | public CollectionFunctionEvaluator(ExpressionEvaluator visitor) { 19 | this.visitor = visitor; 20 | } 21 | 22 | @Override 23 | public DataValue evaluate(final CollectionFunction collection) { 24 | DataValue collectionResult = visitor.doSwitch(collection.getFunction()); 25 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 26 | 27 | if (collectionResult.getType() != DataValue.Type.NULL) { 28 | DataModel jsonModel = new JsonModel(collectionResult, numberPragma); 29 | if (Objects.nonNull(collection.getRefexp())) { 30 | DataValue index = visitor.doSwitch(collection.getRefexp()); 31 | if (index.getType() != DataValue.Type.NULL) { 32 | jsonModel = jsonModel.get(index.toString()); 33 | } 34 | } 35 | if (Objects.nonNull(collection.getResultKey())) { 36 | return EvaluatorUtils.getKeys(collection.getResultKey(), jsonModel, 0, visitor); 37 | } 38 | return jsonModel.getValue(); 39 | } 40 | return collectionResult; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/ConcatFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import static com.intuit.dsl.expression.runtime.util.JSONUtils.MAPPER; 4 | 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.node.ArrayNode; 7 | import com.intuit.dsl.expression.ConcatFunc; 8 | import com.intuit.dsl.expression.Expression; 9 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 10 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 11 | import com.intuit.dsl.expression.runtime.model.DataValue; 12 | import java.util.Iterator; 13 | import java.util.Objects; 14 | import lombok.extern.slf4j.Slf4j; 15 | 16 | @Slf4j 17 | public class ConcatFuncEvaluator implements Evaluator { 18 | 19 | ExpressionEvaluator visitor; 20 | 21 | 22 | public ConcatFuncEvaluator(ExpressionEvaluator visitor) { 23 | this.visitor = visitor; 24 | } 25 | 26 | @Override 27 | public DataValue evaluate(final ConcatFunc concat) { 28 | StringBuilder result = new StringBuilder(); 29 | ArrayNode list = MAPPER.createArrayNode(); 30 | DataValue.Type type = DataValue.Type.NULL; 31 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 32 | 33 | try { 34 | for (Expression e : concat.getExp()) { 35 | DataValue value = visitor.doSwitch(e); 36 | if (Objects.nonNull(value) && value.getType() != DataValue.Type.NULL) { 37 | if (value.getType() == DataValue.Type.STRING || value.getType() == DataValue.Type.NUMBER) { 38 | if (type == DataValue.Type.NULL) { 39 | type = DataValue.Type.STRING; 40 | } 41 | result.append(value); 42 | } else { 43 | if (value.getType() == DataValue.Type.ARRAY) { 44 | if (type == DataValue.Type.NULL) { 45 | type = DataValue.Type.ARRAY; 46 | } 47 | Iterator iter = ((ArrayNode) value.getValue()).elements(); 48 | while (iter.hasNext()) { 49 | list.add(iter.next()); 50 | } 51 | } else { 52 | list.add((JsonNode) value.getValue()); 53 | } 54 | } 55 | } else { 56 | log.debug("Null argument in Concat function "); 57 | } 58 | } 59 | } catch (Exception e) { 60 | log.debug("Exception caught in Concat function " + e.getMessage()); 61 | return new DataValue(null, DataValue.Type.NULL); 62 | } 63 | if (type == DataValue.Type.NULL) { 64 | return new DataValue(null, type); 65 | } else if (type == DataValue.Type.STRING) { 66 | return new DataValue(result.toString(), type, numberPragma); 67 | } else { 68 | return new DataValue(list, DataValue.Type.ARRAY, numberPragma); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/ContainsEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ArrayNode; 5 | import com.intuit.dsl.expression.Contains; 6 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 7 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.NumberValue; 10 | import lombok.extern.slf4j.Slf4j; 11 | 12 | import java.util.Objects; 13 | import java.util.stream.StreamSupport; 14 | 15 | @Slf4j 16 | public class ContainsEvaluator implements Evaluator { 17 | 18 | ExpressionEvaluator visitor; 19 | 20 | 21 | public ContainsEvaluator(ExpressionEvaluator visitor) { 22 | this.visitor = visitor; 23 | } 24 | 25 | @Override 26 | public DataValue evaluate(final Contains contains) { 27 | DataValue input = visitor.doSwitch(contains.getInput()); 28 | 29 | if (input.getType() == DataValue.Type.STRING || input.getType() == DataValue.Type.NUMBER) { 30 | DataValue search = visitor.doSwitch(contains.getSearch()); 31 | if (search.getType() == DataValue.Type.STRING || search.getType() == DataValue.Type.NUMBER) { 32 | return new DataValue(input.toString().contains(search.toString()), DataValue.Type.BOOLEAN); 33 | } 34 | } 35 | if (input.getType() == DataValue.Type.ARRAY) { 36 | DataValue search = visitor.doSwitch(contains.getSearch()); 37 | ArrayNode arrayNode = ArrayNode.class.cast(input.getValue()); 38 | if (search.getType() == DataValue.Type.STRING || search.getType() == DataValue.Type.NUMBER) { 39 | return new DataValue(containsElementWithSubString(arrayNode, search.toString()), DataValue.Type.BOOLEAN); 40 | } 41 | } 42 | return new DataValue(false, DataValue.Type.BOOLEAN); 43 | } 44 | 45 | private boolean containsElementWithSubString(ArrayNode arrayNode, String subsString) { 46 | return StreamSupport 47 | .stream(arrayNode.spliterator(), false) 48 | .filter(jsonNode -> jsonNode.isNumber() || jsonNode.isTextual() ) 49 | .map(jsonNode -> { 50 | if (jsonNode.isNumber()) { 51 | return jsonNode.decimalValue().toString(); 52 | } 53 | if (jsonNode.isTextual()) { 54 | return jsonNode.asText(); 55 | } 56 | return null; 57 | }) 58 | .filter(Objects::nonNull) 59 | .anyMatch(string -> string.contains(subsString)); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/CurrentDateEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.CurrentDate; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import com.intuit.dsl.expression.runtime.util.DateUtils; 9 | import java.util.Date; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.commons.lang3.StringUtils; 12 | 13 | @Slf4j 14 | public class CurrentDateEvaluator implements Evaluator { 15 | 16 | ExpressionEvaluator visitor; 17 | 18 | 19 | public CurrentDateEvaluator(ExpressionEvaluator visitor) { 20 | this.visitor = visitor; 21 | } 22 | 23 | @Override 24 | public DataValue evaluate(final CurrentDate currentDate) { 25 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 26 | if (StringUtils.equals(StringUtils.remove(currentDate.getFormat(), '"'),"ms")) { 27 | return new DataValue(new NumberValue(new Date().getTime(), numberPragma), DataValue.Type.NUMBER, 28 | numberPragma); 29 | } 30 | return new DataValue(DateUtils.currentDate(currentDate.getFormat()), DataValue.Type.STRING, numberPragma); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/DateFormatEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.DateFormat; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Calendar; 10 | import java.util.Objects; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.apache.commons.lang3.StringUtils; 13 | 14 | @Slf4j 15 | public class DateFormatEvaluator implements Evaluator { 16 | 17 | ExpressionEvaluator visitor; 18 | 19 | 20 | public DateFormatEvaluator(ExpressionEvaluator visitor) { 21 | this.visitor = visitor; 22 | } 23 | 24 | @Override 25 | public DataValue evaluate(final DateFormat date) { 26 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 27 | DataValue value = visitor.doSwitch(date.getExp()); 28 | if (Objects.isNull(value) || value.getType() == DataValue.Type.NULL) 29 | return new DataValue(null, DataValue.Type.NULL); 30 | try { 31 | String toDate = StringUtils.remove((date.getTo()), '"'); 32 | String fromDate = StringUtils.remove((date.getFrom()), '"'); 33 | SimpleDateFormat fromFormatter = new SimpleDateFormat(fromDate); 34 | SimpleDateFormat toFormatter = new SimpleDateFormat(toDate); 35 | if (StringUtils.equals(toDate,fromDate)) { 36 | return new DataValue(value.getValue(), DataValue.Type.STRING, numberPragma); 37 | } else if (StringUtils.equals(toDate, "ms")) { 38 | return new DataValue( 39 | new NumberValue(fromFormatter.parse(value.getValue().toString()).getTime(), numberPragma), 40 | DataValue.Type.NUMBER, numberPragma); 41 | } else if (StringUtils.equals(fromDate, "ms")) { 42 | Calendar calendar = Calendar.getInstance(); 43 | long milliSeconds = Long.parseLong(value.getValue().toString()); 44 | calendar.setTimeInMillis(milliSeconds); 45 | return new DataValue(toFormatter.format(calendar.getTime()), DataValue.Type.STRING, 46 | numberPragma); 47 | } else { 48 | return new DataValue(toFormatter.format(fromFormatter.parse(value.getValue().toString())), 49 | DataValue.Type.STRING,numberPragma); 50 | } 51 | } catch (Exception ex) { 52 | // invalid date we are going to convert to string and replace special characters. 53 | // -'-' are send. 54 | log.debug("Invalid date type conversion", date.toString()); 55 | return new DataValue(StringUtils.remove(value.toString(), '-'), DataValue.Type.STRING, numberPragma); 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/DayDifferenceEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.DayDifference; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import com.intuit.dsl.expression.runtime.util.DateUtils; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class DayDifferenceEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | public DayDifferenceEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final DayDifference dayDifference) { 22 | // From might be a String or a Function 23 | String from = visitor.doSwitch(dayDifference.getFrom()).toString(); 24 | // To might be a String or a Function 25 | String to = visitor.doSwitch(dayDifference.getTo()).toString(); 26 | // The formatter has double quotes in it that need to be stripped 27 | String formatter = dayDifference.getFormatter().replace("\"", ""); 28 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 29 | // Returning the difference in days 30 | return new DataValue(new NumberValue(DateUtils.dayDifference(from, to, formatter), numberPragma), 31 | DataValue.Type.NUMBER, numberPragma); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/DedupFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.DedupFunc; 4 | import com.intuit.dsl.expression.SchemaVariable; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataModel; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.JsonModel; 10 | import java.util.HashSet; 11 | import java.util.List; 12 | import java.util.Objects; 13 | import java.util.Set; 14 | import lombok.extern.slf4j.Slf4j; 15 | 16 | @Slf4j 17 | public class DedupFuncEvaluator implements Evaluator { 18 | 19 | ExpressionEvaluator expressionEvaluator; 20 | 21 | public DedupFuncEvaluator(ExpressionEvaluator visitor) { 22 | this.expressionEvaluator = visitor; 23 | } 24 | 25 | @Override 26 | public DataValue evaluate(final DedupFunc dedupFunc) { 27 | 28 | DataValue dataValue = expressionEvaluator.doSwitch(dedupFunc.getExp()); 29 | try { 30 | if (dataValue.getType() == DataValue.Type.ARRAY) { 31 | return dedup(dataValue, dedupFunc.getKey(), expressionEvaluator); 32 | } 33 | } catch (Exception e) { 34 | log.debug("Exception caught in dedup function " + e.getMessage()); 35 | } 36 | return dataValue; 37 | } 38 | 39 | private static DataValue dedup(DataValue value, SchemaVariable key, ExpressionEvaluator expressionEvaluator) { 40 | final boolean numberPragma = expressionEvaluator.getRuntimeOptions().getNumberPragma(); 41 | 42 | List newList = new JsonModel(value, numberPragma).toList(); 43 | DataModel dedupList = JsonModel.arrayNode(numberPragma); 44 | Set set = new HashSet(); 45 | 46 | for (DataModel elem : newList) { 47 | DataValue k = (Objects.isNull(key)) 48 | ? elem.getValue() 49 | : expressionEvaluator.transform(builder -> { 50 | builder.withParentVisitor(expressionEvaluator); 51 | builder.withInputs(elem.fields()); 52 | }).doSwitch(key); 53 | if (set.add(k)) { 54 | dedupList.add(elem); 55 | } 56 | } 57 | return dedupList.getValue(); 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/DeleteEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.Delete; 4 | import com.intuit.dsl.expression.SchemaVariable; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataModel; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 10 | import java.util.Objects; 11 | import java.util.stream.Stream; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.apache.commons.lang3.StringUtils; 14 | 15 | @Slf4j 16 | public class DeleteEvaluator implements Evaluator { 17 | 18 | ExpressionEvaluator expressionEvaluator; 19 | 20 | 21 | public DeleteEvaluator(ExpressionEvaluator visitor) { 22 | this.expressionEvaluator = visitor; 23 | } 24 | 25 | @Override 26 | public DataValue evaluate(final Delete delete) { 27 | SchemaVariable schemaVariable = delete.getVariable().getSchemaVariable(); 28 | Stream neutralizedPath = schemaVariable.getKey().stream().map(eachKey -> { 29 | if (Objects.nonNull(eachKey.getExp())) { 30 | DataValue value = expressionEvaluator.doSwitch(eachKey.getExp()); 31 | if (value.getType() == DataValue.Type.STRING || value.getType() == DataValue.Type.NUMBER) { 32 | return eachKey.getId() + "-" + value.toString(); 33 | } 34 | } 35 | return eachKey.getId(); 36 | }); 37 | 38 | DataModel node = EvaluatorUtils.getKeyFromInputMap(schemaVariable.getKey().get(0), expressionEvaluator); 39 | 40 | /* Since getKey is not recursive, we Iterate over parent hierarchy*/ 41 | ExpressionEvaluator parent = expressionEvaluator.getParentVisitor().get(); 42 | ExpressionEvaluator rparent = parent; 43 | while (Objects.isNull(node) && Objects.nonNull(rparent)) { 44 | node = EvaluatorUtils.getKeyFromInputMap(schemaVariable.getKey().get(0), parent); 45 | rparent = parent.getParentVisitor().get(); 46 | } 47 | 48 | if (Objects.nonNull(node)) { 49 | String path = StringUtils.join(neutralizedPath.skip(1).iterator(), '.'); 50 | node.delete(path); 51 | } 52 | return new DataValue(null, DataValue.Type.NULL); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/ExtractEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.Extract; 4 | import com.intuit.dsl.expression.Range; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataModel; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.JsonModel; 10 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 11 | import java.util.Iterator; 12 | import lombok.extern.slf4j.Slf4j; 13 | 14 | @Slf4j 15 | public class ExtractEvaluator implements Evaluator { 16 | 17 | ExpressionEvaluator visitor; 18 | 19 | 20 | public ExtractEvaluator(ExpressionEvaluator visitor) { 21 | this.visitor = visitor; 22 | } 23 | 24 | @Override 25 | public DataValue evaluate(final Extract extract) { 26 | try { 27 | DataValue input = visitor.doSwitch(extract.getInput()); 28 | return extract(input, extract.getRange(), visitor); 29 | } catch (Exception e) { 30 | log.debug("Exception caught in extract function " + e.getMessage()); 31 | return new DataValue(null, DataValue.Type.NULL); 32 | } 33 | } 34 | 35 | public static DataValue extract(DataValue input, Range range, ExpressionEvaluator visitor) { 36 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 37 | 38 | if (input.getType() == DataValue.Type.STRING || input.getType() == DataValue.Type.NUMBER) { 39 | Long low = EvaluatorUtils.getLowRangeValue(visitor, range); 40 | Long high = EvaluatorUtils.getHighRangeValue(visitor, range, input); 41 | return new DataValue(input.toString().substring(low.intValue(), high.intValue()), DataValue.Type.STRING, 42 | numberPragma); 43 | } else if (input.getType() == DataValue.Type.ARRAY) { 44 | Long low = EvaluatorUtils.getLowRangeValue(visitor, range); 45 | Long high = EvaluatorUtils.getHighRangeValue(visitor, range, input); 46 | DataModel resultNode = JsonModel.arrayNode(numberPragma); 47 | Iterator iter = new JsonModel(input, numberPragma).toList().iterator(); 48 | long index = 0; 49 | while (iter.hasNext()) { 50 | DataModel local = iter.next(); 51 | if (index >= low && index < high) { 52 | resultNode.add(local); 53 | } 54 | index++; 55 | } 56 | return resultNode.getValue(); 57 | } 58 | return new DataValue(null, DataValue.Type.NULL); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/FilterFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import static com.intuit.dsl.expression.runtime.util.JSONUtils.MAPPER; 4 | 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.node.ArrayNode; 7 | import com.intuit.dsl.expression.Expression; 8 | import com.intuit.dsl.expression.FilterFunc; 9 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 10 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 11 | import com.intuit.dsl.expression.runtime.model.DataValue; 12 | import com.intuit.dsl.expression.runtime.model.JsonModel; 13 | import java.util.Iterator; 14 | import java.util.Objects; 15 | import lombok.extern.slf4j.Slf4j; 16 | 17 | @Slf4j 18 | public class FilterFuncEvaluator implements Evaluator { 19 | 20 | ExpressionEvaluator expressionEvaluator; 21 | 22 | public FilterFuncEvaluator(ExpressionEvaluator visitor) { 23 | this.expressionEvaluator = visitor; 24 | } 25 | 26 | @Override 27 | public DataValue evaluate(final FilterFunc filter) { 28 | DataValue value = expressionEvaluator.doSwitch(filter.getExp()); 29 | try { 30 | if (Objects.nonNull(filter.getCondtion())) { 31 | return filter(value, filter.getCondtion(), expressionEvaluator); 32 | } 33 | } catch (Exception e) { 34 | log.debug("Exception caught in filter function " + e.getMessage()); 35 | return value; 36 | } 37 | return value; 38 | } 39 | 40 | public static DataValue filter(DataValue value, Expression condition, ExpressionEvaluator expressionEvaluator) { 41 | final boolean numberPragma = expressionEvaluator.getRuntimeOptions().getNumberPragma(); 42 | 43 | if (value.getType() == DataValue.Type.ARRAY) { 44 | ArrayNode resultNode = MAPPER.createArrayNode(); 45 | ArrayNode array = (ArrayNode) value.getValue(); 46 | Iterator iter = array.elements(); 47 | while (iter.hasNext()) { 48 | JsonNode local = iter.next(); 49 | ExpressionEvaluator expressionVisitor = expressionEvaluator.transform(builder -> { 50 | builder.withParentVisitor(expressionEvaluator); 51 | builder.withInputs(new JsonModel(local, numberPragma).fields()); 52 | }); 53 | if (expressionVisitor.doSwitch(condition).toBoolean()) { 54 | resultNode.add(local); 55 | } 56 | } 57 | return new DataValue(resultNode, DataValue.Type.ARRAY, numberPragma); 58 | } 59 | return value; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/FindFirstFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import static com.intuit.dsl.expression.runtime.evaluator.function.FilterFuncEvaluator.filter; 4 | 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.node.ArrayNode; 7 | import com.intuit.dsl.expression.FindFirstFunc; 8 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 9 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 10 | import com.intuit.dsl.expression.runtime.model.DataValue; 11 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 12 | import java.util.Objects; 13 | import lombok.extern.slf4j.Slf4j; 14 | 15 | @Slf4j 16 | public class FindFirstFuncEvaluator implements Evaluator { 17 | 18 | ExpressionEvaluator visitor; 19 | 20 | 21 | public FindFirstFuncEvaluator(ExpressionEvaluator visitor) { 22 | this.visitor = visitor; 23 | } 24 | 25 | @Override 26 | public DataValue evaluate(final FindFirstFunc findFirstFunc) { 27 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 28 | 29 | DataValue value = visitor.doSwitch(findFirstFunc.getExp()); 30 | try { 31 | if (Objects.nonNull(findFirstFunc.getCondition())) { 32 | DataValue filterValue = filter(value, findFirstFunc.getCondition(), visitor); 33 | ArrayNode matchingElements = (ArrayNode) (filterValue != null ? filterValue.getValue() : null); 34 | if (Objects.isNull(matchingElements) || matchingElements.size() == 0) { 35 | return new DataValue(null, DataValue.Type.NULL); 36 | } else { 37 | JsonNode el = matchingElements.get(0); 38 | return new DataValue(el, EvaluatorUtils.getType(el), numberPragma); 39 | } 40 | } 41 | } catch (Exception e) { 42 | log.debug("Exception caught in find function " + e.getMessage()); 43 | } 44 | return new DataValue(null, DataValue.Type.NULL); 45 | 46 | } 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/FunctionReferenceEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.FunctionReference; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | @Slf4j 10 | public class FunctionReferenceEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public FunctionReferenceEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final FunctionReference functionReference) { 20 | return visitor.doSwitch(functionReference.getRef()); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/JoinEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ArrayNode; 5 | import com.intuit.dsl.expression.Join; 6 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 7 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.JsonModel; 10 | import java.util.Iterator; 11 | import java.util.Objects; 12 | import lombok.extern.slf4j.Slf4j; 13 | 14 | @Slf4j 15 | public class JoinEvaluator implements Evaluator { 16 | 17 | ExpressionEvaluator expressionEvaluator; 18 | 19 | public JoinEvaluator(ExpressionEvaluator visitor) { 20 | this.expressionEvaluator = visitor; 21 | } 22 | 23 | @Override 24 | public DataValue evaluate(final Join join) { 25 | DataValue value = expressionEvaluator.doSwitch(join.getExp()); 26 | final boolean numberPragma = expressionEvaluator.getRuntimeOptions().getNumberPragma(); 27 | try { 28 | // check if this is an array 29 | if (value.getType() == DataValue.Type.ARRAY) { 30 | StringBuilder result = new StringBuilder(); 31 | ArrayNode array = (ArrayNode) value.getValue(); 32 | Iterator iter = array.elements(); 33 | while (iter.hasNext()) { 34 | JsonNode local = iter.next(); 35 | // evaluate key expression, then add it to the result 36 | if (Objects.nonNull(join.getKey())) { 37 | ExpressionEvaluator expressionVisitor = expressionEvaluator.transform(builder -> { 38 | builder.withParentVisitor(expressionEvaluator); 39 | builder.withInputs(new JsonModel(local, numberPragma).fields()); 40 | }); 41 | DataValue keyValue = expressionVisitor.doSwitch(join.getKey()); 42 | if (Objects.nonNull(keyValue)) { 43 | result.append(keyValue); 44 | if (iter.hasNext()) { 45 | result.append(join.getDelimiter()); 46 | } 47 | } 48 | } 49 | } 50 | // take care of the last element. 51 | if (!result.toString().isEmpty() && Objects.nonNull(join.getLast())) { 52 | int start = result.lastIndexOf(join.getDelimiter()); 53 | if (start >= 0) { 54 | result.replace(start, start + join.getDelimiter().length(), join.getLast()); 55 | } 56 | } 57 | return new DataValue(result.toString(), DataValue.Type.STRING, numberPragma); 58 | } 59 | 60 | } catch (Exception e) { 61 | log.debug("Exception caught in join function " + e.getMessage()); 62 | return value; 63 | } 64 | return value; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/JsonEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.intuit.dsl.expression.Json; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import com.intuit.dsl.expression.runtime.util.JSONUtils; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class JsonEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | 17 | public JsonEvaluator(ExpressionEvaluator visitor) { 18 | this.visitor = visitor; 19 | } 20 | 21 | @Override 22 | public DataValue evaluate(final Json toJson) { 23 | DataValue value = visitor.doSwitch(toJson.getExp()); 24 | // if (value.type == DataValue.Type.TSI) { 25 | // return new TSIModel(new TsiMapVal(value.value), pragmas.numberPragma).json 26 | // } else if (value.type == DataValue.Type.STRING) { 27 | try { 28 | JsonNode json = JSONUtils.getJSONFromString(value.getValue().toString()); 29 | return new DataValue(json, DataValue.Type.OBJECT, visitor.getRuntimeOptions().getNumberPragma()); 30 | } catch (Exception e) { 31 | log.debug("Exception caught in json function " + e.getMessage()); 32 | } 33 | // } 34 | return value; 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/LastFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.node.ArrayNode; 5 | import com.intuit.dsl.expression.LastFunc; 6 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 7 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 10 | import java.util.Objects; 11 | import lombok.extern.slf4j.Slf4j; 12 | 13 | @Slf4j 14 | public class LastFuncEvaluator implements Evaluator { 15 | 16 | ExpressionEvaluator visitor; 17 | 18 | 19 | public LastFuncEvaluator(ExpressionEvaluator visitor) { 20 | this.visitor = visitor; 21 | } 22 | 23 | @Override 24 | public DataValue evaluate(final LastFunc lastFunc) { 25 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 26 | 27 | DataValue dataValue = visitor.doSwitch(lastFunc.getExp()); 28 | 29 | if (dataValue.getType() == DataValue.Type.ARRAY) { 30 | ArrayNode container = (ArrayNode)dataValue.getValue(); 31 | if (Objects.isNull(container) || container.size() == 0) { 32 | return new DataValue(null, DataValue.Type.NULL); 33 | } 34 | 35 | JsonNode last = container.get(container.size() - 1).deepCopy(); 36 | 37 | return new DataValue(last, EvaluatorUtils.getType(last), numberPragma); 38 | } 39 | 40 | return dataValue; 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/LengthEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.Length; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | @Slf4j 10 | public class LengthEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | 15 | public LengthEvaluator(ExpressionEvaluator visitor) { 16 | this.visitor = visitor; 17 | } 18 | 19 | @Override 20 | public DataValue evaluate(final Length length) { 21 | DataValue value = visitor.doSwitch(length.getExp()); 22 | return new DataValue(value.length(), DataValue.Type.NUMBER, visitor.getRuntimeOptions().getNumberPragma()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/LowerFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.LowerFunc; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | @Slf4j 11 | public class LowerFuncEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | 16 | public LowerFuncEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final LowerFunc lower) { 22 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 23 | DataValue input = visitor.doSwitch(lower.getExp()); 24 | if (input.getType() == DataValue.Type.STRING) { 25 | return new DataValue(StringUtils.lowerCase(input.toString()), DataValue.Type.STRING, numberPragma); 26 | } 27 | return input; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/ParentFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.ParentFunc; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | public class ParentFuncEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | 16 | public ParentFuncEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final ParentFunc parentFunc) { 22 | if (visitor.getParentVisitor().isPresent()) { 23 | return visitor.getParentVisitor().get().doSwitch(parentFunc.getExp()); 24 | } 25 | return new DataValue(null, DataValue.Type.NULL); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/PickFirstEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.Expression; 4 | import com.intuit.dsl.expression.PickFirst; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import com.intuit.dsl.expression.runtime.model.JsonModel; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class PickFirstEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | public static final String IT = "it"; 16 | 17 | 18 | public PickFirstEvaluator(ExpressionEvaluator visitor) { 19 | this.visitor = visitor; 20 | } 21 | 22 | @Override 23 | public DataValue evaluate(final PickFirst pickFirst) { 24 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 25 | 26 | for (Expression expression : pickFirst.getExp()) { 27 | DataValue expressionValue = visitor.doSwitch(expression); 28 | //ToDo: Review this put 29 | visitor.getInputs().put(IT, new JsonModel(expressionValue, numberPragma)); 30 | if ((visitor.doSwitch(pickFirst.getCondition())).toBoolean()) { 31 | return expressionValue; 32 | } 33 | } 34 | return new DataValue(null, DataValue.Type.NULL); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/RemoveFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import static com.intuit.dsl.expression.runtime.util.JSONUtils.MAPPER; 4 | 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.node.ArrayNode; 7 | import com.intuit.dsl.expression.Expression; 8 | import com.intuit.dsl.expression.RemoveFunc; 9 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 10 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 11 | import com.intuit.dsl.expression.runtime.model.DataValue; 12 | import com.intuit.dsl.expression.runtime.model.JsonModel; 13 | import java.util.Iterator; 14 | import java.util.Objects; 15 | import lombok.extern.slf4j.Slf4j; 16 | 17 | @Slf4j 18 | public class RemoveFuncEvaluator implements Evaluator { 19 | 20 | ExpressionEvaluator visitor; 21 | 22 | 23 | public RemoveFuncEvaluator(ExpressionEvaluator visitor) { 24 | this.visitor = visitor; 25 | } 26 | 27 | @Override 28 | public DataValue evaluate(final RemoveFunc remove) { 29 | 30 | DataValue value = visitor.doSwitch(remove.getExp()); 31 | try { 32 | if (Objects.nonNull(remove.getCondition())) { 33 | return remove(value, remove.getCondition(), visitor); 34 | } 35 | } catch (Exception e) { 36 | log.debug("Exception caught in remove function " + e.getMessage()); 37 | } 38 | return value; 39 | } 40 | 41 | private DataValue remove(DataValue value, Expression condition, ExpressionEvaluator expressionEvaluator) { 42 | final boolean numberPragma = expressionEvaluator.getRuntimeOptions().getNumberPragma(); 43 | 44 | if (value.getType() == DataValue.Type.ARRAY) { 45 | ArrayNode resultNode = MAPPER.createArrayNode(); 46 | ArrayNode array = (ArrayNode) value.getValue(); 47 | Iterator iter = array.elements(); 48 | while (iter.hasNext()) { 49 | JsonNode local = iter.next(); 50 | ExpressionEvaluator expressionVisitor = expressionEvaluator.transform(builder -> { 51 | builder.withParentVisitor(expressionEvaluator); 52 | builder.withInputs(new JsonModel(local, numberPragma).fields()); 53 | }); 54 | if (!(expressionVisitor.doSwitch(condition)).toBoolean()) { 55 | resultNode.add(local); 56 | } 57 | } 58 | return new DataValue(resultNode, DataValue.Type.ARRAY, numberPragma); 59 | } 60 | return value; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/SortFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.SchemaVariable; 4 | import com.intuit.dsl.expression.SortFunc; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataModel; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.JsonModel; 10 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 11 | import java.util.Collections; 12 | import java.util.List; 13 | import java.util.Map; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.apache.commons.lang3.StringUtils; 16 | 17 | @Slf4j 18 | public class SortFuncEvaluator implements Evaluator { 19 | 20 | ExpressionEvaluator visitor; 21 | static final String ORDER_DESCENDING = "descending"; 22 | 23 | 24 | public SortFuncEvaluator(ExpressionEvaluator visitor) { 25 | this.visitor = visitor; 26 | } 27 | 28 | @Override 29 | public DataValue evaluate(final SortFunc sortFunc) { 30 | DataValue dataValue = visitor.doSwitch(sortFunc.getExp()); 31 | if (dataValue.getType() == DataValue.Type.ARRAY) { 32 | return sort(dataValue, sortFunc.getKey(), sortFunc.getType(), visitor); 33 | } 34 | return dataValue; 35 | } 36 | 37 | public static DataValue sort(DataValue value, SchemaVariable key, String order, ExpressionEvaluator visitor) { 38 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 39 | 40 | List newList = new JsonModel(value, numberPragma).toList(); 41 | Collections.sort(newList, (a, b) -> 42 | { 43 | String aValue = getValue(visitor, key, a.fields()); 44 | String bValue = getValue(visitor, key, b.fields()); 45 | int compareOutput = EvaluatorUtils.compareTo(aValue, bValue); 46 | return StringUtils.equals(order, ORDER_DESCENDING) ? compareOutput * -1 : compareOutput; 47 | }); 48 | return new DataValue(newList, DataValue.Type.ARRAY, numberPragma); 49 | } 50 | 51 | 52 | private static String getValue(ExpressionEvaluator expressionEvaluator, SchemaVariable key, 53 | Map inputMap) { 54 | ExpressionEvaluator expressionVisitor = expressionEvaluator.transform(builder -> { 55 | builder.withParentVisitor(expressionEvaluator); 56 | builder.withInputs(inputMap); 57 | }); 58 | DataValue value = expressionVisitor.doSwitch(key); 59 | return value != null ? value.toString() : null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/SplitEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import static com.intuit.dsl.expression.runtime.util.JSONUtils.MAPPER; 4 | 5 | import com.fasterxml.jackson.databind.node.ArrayNode; 6 | import com.fasterxml.jackson.databind.node.TextNode; 7 | import com.intuit.dsl.expression.Split; 8 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 9 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 10 | import com.intuit.dsl.expression.runtime.model.DataValue; 11 | import java.util.Objects; 12 | import lombok.extern.slf4j.Slf4j; 13 | 14 | @Slf4j 15 | public class SplitEvaluator implements Evaluator { 16 | 17 | ExpressionEvaluator visitor; 18 | 19 | 20 | public SplitEvaluator(ExpressionEvaluator visitor) { 21 | this.visitor = visitor; 22 | } 23 | 24 | @Override 25 | public DataValue evaluate(final Split split) { 26 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 27 | DataValue value = visitor.doSwitch(split.getExp()); 28 | if (Objects.isNull(value)) { 29 | return new DataValue(null, DataValue.Type.NULL); 30 | } 31 | if (value.getType() == DataValue.Type.STRING || value.getType() == DataValue.Type.NUMBER) { 32 | ArrayNode list = MAPPER.createArrayNode(); 33 | String[] words = value.toString().split(split.getRegex()); 34 | // TODO: Need to return a proper DataValue. 35 | for (String word : words) { 36 | list.add(new TextNode(word)); 37 | } 38 | return new DataValue(list, DataValue.Type.ARRAY, numberPragma); 39 | 40 | } 41 | return value; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/TernaryExpressionEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.TernaryExpression; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | public class TernaryExpressionEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | 16 | public TernaryExpressionEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final TernaryExpression ternaryExpression) { 22 | DataValue value = visitor.doSwitch(ternaryExpression.getExpression()); 23 | if (value.toBoolean()) 24 | return visitor.doSwitch(ternaryExpression.getTruevalue()); 25 | else if (Objects.nonNull(ternaryExpression.getFalsevalue())) 26 | return visitor.doSwitch(ternaryExpression.getFalsevalue()); 27 | else 28 | return new DataValue(null, DataValue.Type.NULL); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/TranslateUnicodeEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.TranslateUnicode; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | public class TranslateUnicodeEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | public TranslateUnicodeEvaluator(ExpressionEvaluator visitor) { 16 | this.visitor = visitor; 17 | } 18 | 19 | @Override 20 | public DataValue evaluate(final TranslateUnicode translateUnicode) { 21 | DataValue value = visitor.doSwitch(translateUnicode.getExp()); 22 | if (value.getType() != DataValue.Type.NULL) { 23 | return new DataValue(EvaluatorUtils.translateUnicode(value.toString()), DataValue.Type.STRING); 24 | } 25 | return value; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/UUIDFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.UUIDFunc; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.UUID; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | public class UUIDFuncEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | 16 | public UUIDFuncEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final UUIDFunc uuid) { 22 | return new DataValue(UUID.randomUUID().toString(), DataValue.Type.STRING, 23 | visitor.getRuntimeOptions().getNumberPragma()); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/function/UpperFuncEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.function; 2 | 3 | import com.intuit.dsl.expression.UpperFunc; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | @Slf4j 11 | public class UpperFuncEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | 16 | public UpperFuncEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final UpperFunc lower) { 22 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 23 | DataValue input = visitor.doSwitch(lower.getExp()); 24 | if (input.getType() == DataValue.Type.STRING) { 25 | return new DataValue(StringUtils.upperCase(input.toString()), DataValue.Type.STRING, numberPragma); 26 | } 27 | return input; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/ArithmeticSignedEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.ArithmeticSigned; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.util.Objects; 9 | 10 | public class ArithmeticSignedEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public ArithmeticSignedEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final ArithmeticSigned arithmeticSigned) { 20 | final DataValue value = visitor.doSwitch(arithmeticSigned.getExpression()); 21 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 22 | if (Objects.isNull(value) || value.getType() != DataValue.Type.NUMBER) { 23 | return new DataValue(new NumberValue(0, numberPragma), DataValue.Type.NUMBER, numberPragma); 24 | } 25 | return new DataValue(((NumberValue) (value.getValue())).multiply(new NumberValue(-1, numberPragma)), 26 | DataValue.Type.NUMBER, numberPragma); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/BooleanExpressionEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.BooleanExpression; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | public class BooleanExpressionEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public BooleanExpressionEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final BooleanExpression booleanExpression) { 20 | DataValue left = visitor.doSwitch(booleanExpression.getLeft()); 21 | 22 | String op = booleanExpression.getOp(); 23 | if (StringUtils.equalsAny(op, "&&", "and")) { 24 | 25 | if (left.getType() != DataValue.Type.BOOLEAN || !(left.toBoolean())) { 26 | return new DataValue(false, DataValue.Type.BOOLEAN); 27 | } 28 | 29 | DataValue right = visitor.doSwitch(booleanExpression.getRight()); 30 | 31 | if (right.getType() != DataValue.Type.BOOLEAN || Objects.isNull(right.getValue())) { 32 | return new DataValue(false, DataValue.Type.BOOLEAN); 33 | } 34 | 35 | return new DataValue((left.toBoolean() && right.toBoolean()), DataValue.Type.BOOLEAN); 36 | } else { 37 | 38 | if (left.getType() != DataValue.Type.BOOLEAN || Objects.isNull(left.getValue())) { 39 | left = new DataValue(false, DataValue.Type.BOOLEAN); 40 | } 41 | 42 | if (left.toBoolean()) { 43 | return left; 44 | } 45 | 46 | DataValue right = visitor.doSwitch(booleanExpression.getRight()); 47 | if (right.getType() != DataValue.Type.BOOLEAN || !(right.toBoolean())) { 48 | return new DataValue(false, DataValue.Type.BOOLEAN); 49 | } 50 | 51 | return right; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/BooleanNegationEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.BooleanNegation; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.commons.lang3.StringUtils; 10 | 11 | @Slf4j 12 | public class BooleanNegationEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | public BooleanNegationEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final BooleanNegation booleanNegation) { 22 | 23 | DataValue value = visitor.doSwitch(booleanNegation.getExpression()); 24 | if (Objects.isNull(value) || value.getType() == DataValue.Type.NULL) { 25 | return new DataValue(true, DataValue.Type.BOOLEAN); 26 | } else if (value.getType() != DataValue.Type.BOOLEAN) { 27 | return new DataValue(StringUtils.equalsAny(value.getValue().toString(), "", "0"), 28 | DataValue.Type.BOOLEAN); 29 | } else { 30 | return new DataValue(!(value.toBoolean()), DataValue.Type.BOOLEAN); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/ComparisonEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.Comparison; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.util.Objects; 9 | 10 | public class ComparisonEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public ComparisonEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final Comparison comparison) { 20 | DataValue left = visitor.doSwitch(comparison.getLeft()); 21 | 22 | if (Objects.isNull(left) || left.getType() != DataValue.Type.NUMBER) { 23 | return (new DataValue(false, DataValue.Type.BOOLEAN)); 24 | } 25 | 26 | DataValue right = visitor.doSwitch(comparison.getRight()); 27 | if (Objects.isNull(right) || right.getType() != DataValue.Type.NUMBER) { 28 | return (new DataValue(false, DataValue.Type.BOOLEAN)); 29 | } 30 | 31 | NumberValue leftValue = (NumberValue) left.getValue(); 32 | NumberValue rightValue = (NumberValue) right.getValue(); 33 | String op = comparison.getOp(); 34 | switch (op) { 35 | case ">": 36 | return (new DataValue(leftValue.greater(rightValue), DataValue.Type.BOOLEAN)); 37 | case "<": 38 | return (new DataValue(leftValue.less(rightValue), DataValue.Type.BOOLEAN)); 39 | case ">=": 40 | return (new DataValue(leftValue.greaterEqual(rightValue), DataValue.Type.BOOLEAN)); 41 | case "<=": 42 | return (new DataValue(leftValue.lessEqual(rightValue), DataValue.Type.BOOLEAN)); 43 | default: 44 | return (new DataValue(false, DataValue.Type.BOOLEAN)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/EqualsEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.Equals; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import org.apache.commons.lang3.StringUtils; 9 | 10 | public class EqualsEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public EqualsEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final Equals equals) { 20 | DataValue left = visitor.doSwitch(equals.getLeft()); 21 | DataValue right = visitor.doSwitch(equals.getRight()); 22 | 23 | String op = equals.getOp(); 24 | if (StringUtils.equals(op, "!=")) { 25 | return new DataValue(!Objects.equals(left, right), DataValue.Type.BOOLEAN); 26 | } else if (StringUtils.equals(op, "=~")) { 27 | return new DataValue(left.fuzzyEquals(right), DataValue.Type.BOOLEAN); 28 | } else if (StringUtils.equals(op, "!~")) { 29 | return new DataValue(!left.fuzzyEquals(right), DataValue.Type.BOOLEAN); 30 | } else { 31 | return new DataValue(Objects.equals(left, right), DataValue.Type.BOOLEAN); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/MembershipEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.Expression; 4 | import com.intuit.dsl.expression.Membership; 5 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 6 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import java.util.Iterator; 9 | 10 | public class MembershipEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public MembershipEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final Membership membership) { 20 | final DataValue left = visitor.doSwitch(membership.getLeft()); 21 | Iterator valueIterator = membership.getRight().iterator(); 22 | boolean isIn = (membership.getOp().equals("in")); 23 | while (valueIterator.hasNext()) { 24 | DataValue right = visitor.doSwitch(valueIterator.next()); 25 | if (left.equals(right)) { 26 | return new DataValue(isIn, DataValue.Type.BOOLEAN); 27 | } 28 | } 29 | return new DataValue(!isIn, DataValue.Type.BOOLEAN); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/MinusEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.Minus; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.util.Objects; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class MinusEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | public MinusEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final Minus minus) { 22 | DataValue left = visitor.doSwitch(minus.getLeft()); 23 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 24 | 25 | if (Objects.isNull(left) || left.getType() == DataValue.Type.NULL) { 26 | left = new DataValue(new NumberValue(0, numberPragma), DataValue.Type.NUMBER, numberPragma); 27 | } 28 | 29 | DataValue right = visitor.doSwitch(minus.getRight()); 30 | if (Objects.isNull(right) || right.getType() == DataValue.Type.NULL) { 31 | right = new DataValue(new NumberValue(0, numberPragma), DataValue.Type.NUMBER, numberPragma); 32 | } 33 | 34 | if (left.getType() == DataValue.Type.NUMBER && right.getType() == DataValue.Type.NUMBER) { 35 | return new DataValue(((NumberValue) left.getValue()).subtract(((NumberValue) right.getValue())), 36 | DataValue.Type.NUMBER, numberPragma); 37 | } else { 38 | log.debug("You cannot subtract from strings"); 39 | return new DataValue(null, DataValue.Type.NULL, numberPragma); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/MultiOrDivOrModEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.MultiOrDivOrMod; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.util.Objects; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.apache.commons.lang3.StringUtils; 11 | 12 | @Slf4j 13 | public class MultiOrDivOrModEvaluator implements Evaluator { 14 | 15 | ExpressionEvaluator visitor; 16 | 17 | public MultiOrDivOrModEvaluator(ExpressionEvaluator visitor) { 18 | this.visitor = visitor; 19 | } 20 | 21 | @Override 22 | public DataValue evaluate(final MultiOrDivOrMod multiOrDivOrMod) { 23 | DataValue left = visitor.doSwitch(multiOrDivOrMod.getLeft()); 24 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 25 | 26 | if (Objects.isNull(left) || left.getType() == DataValue.Type.NULL) { 27 | return new DataValue(null, DataValue.Type.NULL); 28 | } 29 | 30 | DataValue right = visitor.doSwitch(multiOrDivOrMod.getRight()); 31 | if (Objects.isNull(right) || right.getType() == DataValue.Type.NULL) { 32 | return new DataValue(null, DataValue.Type.NULL); 33 | } 34 | 35 | if (left.getType() == DataValue.Type.NUMBER && right.getType() == DataValue.Type.NUMBER) { 36 | if (StringUtils.equals(multiOrDivOrMod.getOp(), "*")) { 37 | return new DataValue(((NumberValue) left.getValue()).multiply(((NumberValue) right.getValue())), 38 | DataValue.Type.NUMBER, numberPragma); 39 | } else if (StringUtils.equals(multiOrDivOrMod.getOp(), "%")) { 40 | return new DataValue(((NumberValue) left.getValue()).remainder(((NumberValue) right.getValue())), 41 | DataValue.Type.NUMBER, numberPragma); 42 | } else { 43 | return new DataValue(((NumberValue) left.getValue()).divide(((NumberValue) right.getValue())), 44 | DataValue.Type.NUMBER, numberPragma); 45 | } 46 | } else { 47 | log.debug("You cannot multiply or divide strings"); 48 | return new DataValue(null, DataValue.Type.NULL, numberPragma); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/operation/PlusEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.operation; 2 | 3 | import com.intuit.dsl.expression.Plus; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import com.intuit.dsl.expression.runtime.model.NumberValue; 8 | import java.util.Objects; 9 | 10 | public class PlusEvaluator implements Evaluator { 11 | 12 | ExpressionEvaluator visitor; 13 | 14 | public PlusEvaluator(ExpressionEvaluator visitor) { 15 | this.visitor = visitor; 16 | } 17 | 18 | @Override 19 | public DataValue evaluate(final Plus plus) { 20 | DataValue left = visitor.doSwitch(plus.getLeft()); 21 | DataValue right = visitor.doSwitch(plus.getRight()); 22 | 23 | if (Objects.isNull(left) || left.getType() == DataValue.Type.NULL) { 24 | return right; 25 | } 26 | if (Objects.isNull(right) || right.getType() == DataValue.Type.NULL) { 27 | return left; 28 | } 29 | final boolean numberPragma = visitor.getRuntimeOptions().getNumberPragma(); 30 | // Support string concatenation or adding numbers. 31 | if (left.getType() == DataValue.Type.NUMBER && right.getType() == DataValue.Type.NUMBER) { 32 | return new DataValue(((NumberValue) left.getValue()).add((NumberValue) right.getValue()), DataValue.Type.NUMBER, 33 | numberPragma); 34 | } else { 35 | return new DataValue(left.getValue().toString() + right.getValue().toString(), DataValue.Type.STRING); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/variables/LiteralEvaluators.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.variables; 2 | 3 | import com.intuit.dsl.expression.BooleanLiteral; 4 | import com.intuit.dsl.expression.NullLiteral; 5 | import com.intuit.dsl.expression.NumberLiteral; 6 | import com.intuit.dsl.expression.StringLiteral; 7 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 8 | import com.intuit.dsl.expression.runtime.model.DataValue; 9 | import com.intuit.dsl.expression.runtime.model.NumberValue; 10 | 11 | public class LiteralEvaluators { 12 | 13 | private LiteralEvaluators(){} 14 | 15 | public static final Evaluator BOOLEAN_LITERAL = new Evaluator() { 16 | @Override 17 | public DataValue evaluate(final BooleanLiteral booleanLiteral) { 18 | return new DataValue(Boolean.parseBoolean(booleanLiteral.getValue()), DataValue.Type.BOOLEAN); 19 | } 20 | }; 21 | 22 | public static final Evaluator NUMBER_LITERAL = new Evaluator() { 23 | @Override 24 | public DataValue evaluate(final NumberLiteral numberLiteral) { 25 | return new DataValue(new NumberValue(numberLiteral.getValue(),false), DataValue.Type.NUMBER); 26 | } 27 | }; 28 | 29 | public static final Evaluator NULL_LITERAL = new Evaluator() { 30 | @Override 31 | public DataValue evaluate(final NullLiteral nullLiteral) { 32 | return new DataValue(null, DataValue.Type.NULL); 33 | } 34 | }; 35 | 36 | public static final Evaluator STRING_LITERAL = new Evaluator() { 37 | @Override 38 | public DataValue evaluate(final StringLiteral stringLiteral) { 39 | return new DataValue(stringLiteral.getValue(), DataValue.Type.STRING); 40 | } 41 | }; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/variables/SchemaVariableEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.variables; 2 | 3 | import com.intuit.dsl.expression.SchemaVariable; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataModel; 7 | import com.intuit.dsl.expression.runtime.model.DataValue; 8 | import com.intuit.dsl.expression.runtime.util.EvaluatorUtils; 9 | import lombok.extern.slf4j.Slf4j; 10 | 11 | @Slf4j 12 | public class SchemaVariableEvaluator implements Evaluator { 13 | 14 | ExpressionEvaluator visitor; 15 | 16 | public SchemaVariableEvaluator(ExpressionEvaluator visitor) { 17 | this.visitor = visitor; 18 | } 19 | 20 | @Override 21 | public DataValue evaluate(final SchemaVariable variable) { 22 | DataModel valueFromMap = EvaluatorUtils.getKeyFromInputMap(variable.getKey().get(0), visitor); 23 | return EvaluatorUtils.getKeys(variable.getKey(), valueFromMap,1,visitor); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/evaluator/variables/VariableReferenceEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.evaluator.variables; 2 | 3 | import com.intuit.dsl.expression.VariableReference; 4 | import com.intuit.dsl.expression.runtime.evaluator.Evaluator; 5 | import com.intuit.dsl.expression.runtime.evaluator.ExpressionEvaluator; 6 | import com.intuit.dsl.expression.runtime.model.DataValue; 7 | import java.util.Objects; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | @Slf4j 11 | public class VariableReferenceEvaluator implements Evaluator { 12 | 13 | ExpressionEvaluator visitor; 14 | 15 | public VariableReferenceEvaluator(ExpressionEvaluator visitor) { 16 | this.visitor = visitor; 17 | } 18 | 19 | @Override 20 | public DataValue evaluate(final VariableReference variableRef) { 21 | if (Objects.nonNull(variableRef.getRef().getSchemaVariable().getGlobal()) && visitor.getParentVisitor().isPresent()) { 22 | //This is for backward compatibility of :: operator 23 | return visitor.getParentVisitor().get().doSwitch(variableRef.getRef()); 24 | } 25 | return visitor.doSwitch(variableRef.getRef()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/exception/ExpressionEvaluationException.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.exception; 2 | 3 | public class ExpressionEvaluationException extends RuntimeException { 4 | 5 | public ExpressionEvaluationException(String message){ 6 | super(message); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/model/DataModel.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public interface DataModel { 7 | boolean has(String string); 8 | 9 | DataModel get(String string); 10 | 11 | Object get(); 12 | 13 | DataValue getValue(); 14 | 15 | void replace(String string, DataModel model); 16 | 17 | String asText(); 18 | 19 | void set(String string, DataModel model); 20 | 21 | boolean isArray(); 22 | 23 | boolean isTextual(); 24 | 25 | boolean isAtomic(); 26 | 27 | void add(DataModel data); 28 | 29 | void addAll(List data); 30 | 31 | int length(); 32 | 33 | List toList(); 34 | 35 | Map fields(); 36 | 37 | void delete(String path); 38 | 39 | String toJson(); 40 | 41 | String toXml(); 42 | 43 | byte[] toBinary(); 44 | 45 | default DataModel copy() { 46 | return this; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/model/RuntimeOptions.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.model; 2 | 3 | public class RuntimeOptions { 4 | 5 | public boolean getNumberPragma() { 6 | return numberPragma; 7 | } 8 | 9 | public RuntimeOptions(){ 10 | numberPragma = false; 11 | } 12 | final boolean numberPragma; 13 | } -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/parser/XtextExpressionParser.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.parser; 2 | 3 | import com.google.inject.Injector; 4 | import com.intuit.dsl.ExpressionStandaloneSetup; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import org.apache.commons.io.IOUtils; 8 | import org.eclipse.emf.common.util.URI; 9 | import org.eclipse.xtext.resource.IResourceFactory; 10 | import org.eclipse.xtext.resource.XtextResource; 11 | 12 | public class XtextExpressionParser { 13 | 14 | private static final Injector injector = new ExpressionStandaloneSetup().createInjectorAndDoEMFRegistration(); 15 | 16 | public XtextExpressionParser() { 17 | } 18 | 19 | private XtextResource createResourceFrom(InputStream input, URI uri, Injector injector) throws IOException { 20 | XtextResource resource = (XtextResource) injector.getInstance(IResourceFactory.class).createResource(uri); 21 | resource.load(input, null); 22 | return resource; 23 | } 24 | 25 | public XtextResource parse(String content) throws IOException { 26 | return createResource(content, content); 27 | } 28 | 29 | public XtextResource createResource(String source, String uri) throws IOException { 30 | return createResource(IOUtils.toInputStream(source), URI.createFileURI(uri + ".expr")); 31 | } 32 | 33 | public XtextResource createResource(InputStream input, URI uri) throws IOException { 34 | return createResourceFrom(input, uri, injector); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/main/java/com/intuit/dsl/expression/runtime/util/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | import java.util.concurrent.TimeUnit; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | @SuppressWarnings("all") 11 | public class DateUtils { 12 | private static final Logger LOGGER = LoggerFactory.getLogger(DateUtils.class); 13 | 14 | /** 15 | * This function calculates the difference in days from Today's date to the Date 16 | * string sent as an arg 17 | * 18 | * @param to String Target Date to calculate difference till 19 | * @param from String Source Data to alculate difference from 20 | * @param dateParser String Date parser 21 | * @return Long Difference in Days 22 | */ 23 | public static long dayDifference(final String from, final String to, final String dateParser) { 24 | final SimpleDateFormat selectedParser = new SimpleDateFormat(dateParser); 25 | try { 26 | long fromDate = selectedParser.parse(from).getTime(); 27 | long toDate = selectedParser.parse(to).getTime(); 28 | return TimeUnit.DAYS.convert((toDate - fromDate), TimeUnit.MILLISECONDS); 29 | } catch (final Exception e) { 30 | LOGGER.error("Exception caught in dayDifference: " + e.getMessage()); 31 | return Long.MAX_VALUE; 32 | } 33 | } 34 | 35 | /** 36 | * This function returns today's date as a String in the format MM/dd/yyyy 37 | * 38 | * @param format String Date 39 | * @return String Today's date in MM/dd/yyyy 40 | */ 41 | public static String currentDate(final String format) { 42 | String toFormat = (format == null) ? "MM/dd/yyyy" : StringUtils.remove(format, "\""); 43 | final SimpleDateFormat selectedParser = new SimpleDateFormat(toFormat); 44 | try { 45 | Date _date = new Date(); 46 | return selectedParser.format(_date); 47 | } catch (final Exception e) { 48 | LOGGER.error("Exception caught in dayDifference: " + e.getMessage()); 49 | return null; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/CaseSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 2 | import com.intuit.dsl.expression.runtime.model.DataValue 3 | import spock.lang.Specification 4 | 5 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.BOOLEAN 6 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.STRING 7 | 8 | class CaseSpecification extends Specification { 9 | 10 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 11 | 12 | def "Should perform lowercase operations correctly"() { 13 | setup: 14 | DataValue value = expressionRuntime.withExpressionContent(input).evaluate() 15 | DataValue.Type outputType = value.getType() 16 | def actualValue = value.getValue() 17 | 18 | expect: 19 | outputType == expectedType 20 | actualValue == expectedValue 21 | 22 | where: 23 | input | expectedType | expectedValue 24 | 'lowerCase("ABC")' | STRING | "abc" 25 | 'lowerCase("ABCxyz001")' | STRING | "abcxyz001" 26 | 'lowerCase("001")' | STRING | "001" 27 | 'lowerCase("$$,,...^%&")' | STRING | "\$\$,,...^%&" 28 | } 29 | 30 | def "Should perform uppercase operations correctly"() { 31 | setup: 32 | DataValue value = expressionRuntime.withExpressionContent(input).evaluate() 33 | DataValue.Type outputType = value.getType() 34 | def actualValue = value.getValue() 35 | 36 | expect: 37 | outputType == expectedType 38 | actualValue == expectedValue 39 | 40 | where: 41 | input | expectedType | expectedValue 42 | 'upperCase("ABC")' | STRING | "ABC" 43 | 'upperCase("abc")' | STRING | "ABC" 44 | 'upperCase("abcXYZ001")' | STRING | "ABCXYZ001" 45 | 'upperCase("001")' | STRING | "001" 46 | 'upperCase("$$,,...^%&")' | STRING | "\$\$,,...^%&" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/ConcatSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.google.common.collect.ImmutableMap 3 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 4 | import com.intuit.dsl.expression.runtime.model.DataValue 5 | import spock.lang.Specification 6 | import util.TestUtils 7 | 8 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.STRING 9 | 10 | class ConcatSpecification extends Specification { 11 | 12 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 13 | 14 | Map inputData = new HashMap() 15 | 16 | def setup() { 17 | Map dataSet = new HashMap<>() 18 | dataSet.put("anObject", ImmutableMap.of( 19 | "aString", "abc", 20 | "aNumber", "123", 21 | "aBoolean", true 22 | )) 23 | inputData.put("data", TestUtils.MAPPER.convertValue(dataSet, JsonNode.class)) 24 | } 25 | 26 | def "Should concat string literals correctly"() { 27 | setup: 28 | DataValue actualResult = expressionRuntime 29 | .withExpressionContent(input) 30 | .withData(inputData) 31 | .evaluate() 32 | 33 | 34 | expect: 35 | expectedType == actualResult.getType() 36 | expectedValue == actualResult.getValue() 37 | 38 | where: 39 | input | expectedType | expectedValue 40 | ''' concat("FirstString","SecondString") ''' | STRING | "FirstStringSecondString" 41 | ''' concat("FirstString","SecondString","LastString") ''' | STRING | "FirstStringSecondStringLastString" 42 | } 43 | 44 | def "Should concat with variables correctly"() { 45 | setup: 46 | DataValue actualResult = expressionRuntime 47 | .withExpressionContent(input) 48 | .withData(inputData) 49 | .evaluate() 50 | 51 | 52 | expect: 53 | expectedType == actualResult.getType() 54 | expectedValue == actualResult.getValue() 55 | 56 | where: 57 | input | expectedType | expectedValue 58 | ''' concat("a", data.anObject.aString, "z") ''' | STRING | "aabcz" 59 | ''' concat(data.anObject.aNumber, data.anObject.aString, "z") ''' | STRING | "123abcz" 60 | } 61 | 62 | def "Should concat with output of extract function correctly"() { 63 | setup: 64 | DataValue actualResult = expressionRuntime 65 | .withExpressionContent(input) 66 | .withData(inputData) 67 | .evaluate() 68 | 69 | 70 | expect: 71 | expectedType == actualResult.getType() 72 | expectedValue == actualResult.getValue() 73 | 74 | where: 75 | input | expectedType | expectedValue 76 | ''' concat(extract(data.anObject.aString,1..), "z") ''' | STRING | "bcz" 77 | ''' concat("a", extract(data.anObject.aString,1..), "z") ''' | STRING | "abcz" 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/ExtractSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.google.common.collect.ImmutableMap 3 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 4 | import com.intuit.dsl.expression.runtime.model.DataValue 5 | import spock.lang.Specification 6 | import util.TestUtils 7 | 8 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.STRING 9 | 10 | class ExtractSpecification extends Specification { 11 | 12 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 13 | 14 | Map inputData = new HashMap() 15 | 16 | def setup() { 17 | Map dataSet = new HashMap<>() 18 | dataSet.put("someObject", ImmutableMap.of( 19 | "stringAttribute", "SomeStringValue1", 20 | "numberStringAttribute", "1234", 21 | "booleanAttribute", true 22 | )) 23 | 24 | inputData.put("dataSet", TestUtils.MAPPER.convertValue(dataSet, JsonNode.class)) 25 | } 26 | 27 | def "Should extract correct value for a given range"() { 28 | setup: 29 | DataValue actualResult = expressionRuntime 30 | .withExpressionContent(input) 31 | .withData(inputData) 32 | .evaluate() 33 | 34 | 35 | expect: 36 | expectedType == actualResult.getType() 37 | expectedValue == actualResult.getValue() 38 | 39 | where: 40 | input | expectedType | expectedValue 41 | ''' extract("0123456789",0..) ''' | STRING | "0123456789" 42 | ''' extract("0123456789",2..) ''' | STRING | "23456789" 43 | ''' extract(dataSet.someObject.numberStringAttribute,2..) ''' | STRING | "34" 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/FilterSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.fasterxml.jackson.databind.node.ArrayNode 3 | import com.google.common.collect.ImmutableList 4 | import com.google.common.collect.ImmutableMap 5 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 6 | import com.intuit.dsl.expression.runtime.model.DataValue 7 | import spock.lang.Specification 8 | import util.TestUtils 9 | 10 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.ARRAY 11 | 12 | class FilterSpecification extends Specification { 13 | 14 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 15 | 16 | Map inputData = new HashMap() 17 | 18 | def setup() { 19 | Map dataSet1 = new HashMap<>() 20 | Map dataSet2 = new HashMap<>() 21 | dataSet2.put("someList", ImmutableList.of( 22 | ImmutableMap.of( 23 | "stringAttribute", "SomeStringValue1", 24 | "booleanAttribute", true 25 | ), 26 | ImmutableMap.of( 27 | "stringAttribute", "SomeStringValue2", 28 | "booleanAttribute", false 29 | ), 30 | )) 31 | 32 | inputData.put("dataSet1", TestUtils.MAPPER.convertValue(dataSet1, JsonNode.class)) 33 | inputData.put("dataSet2", TestUtils.MAPPER.convertValue(dataSet2, JsonNode.class)) 34 | } 35 | 36 | def "Should filter with == expression correctly"() { 37 | setup: 38 | DataValue actualResult = expressionRuntime 39 | .withExpressionContent(input) 40 | .withData(inputData) 41 | .evaluate() 42 | ArrayNode arrayNode = actualResult.value 43 | 44 | 45 | expect: 46 | expectedType == actualResult.getType() 47 | expectedSize == arrayNode.size() 48 | 49 | where: 50 | input | expectedType | expectedSize 51 | ''' filter(dataSet2.someList, booleanAttribute == true) ''' | ARRAY | 1 52 | ''' filter(dataSet2.someList, booleanAttribute == false) ''' | ARRAY | 1 53 | ''' filter(dataSet2.someList, stringAttribute == "SomeStringValue1") ''' | ARRAY | 1 54 | ''' filter(dataSet2.someList, stringAttribute == "SomeStringValue2") ''' | ARRAY | 1 55 | ''' filter(dataSet2.someList, stringAttribute == "Not Present in List") ''' | ARRAY | 0 56 | ''' filter(dataSet2.someList, stringAttribute != "Not Present in List") ''' | ARRAY | 2 57 | //''' filter(dataSet2.nonInDataSet2, 58 | // stringAttribute == "SomeStringValue1") ''' | ARRAY | 0 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/LengthSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.google.common.collect.ImmutableList 3 | import com.google.common.collect.ImmutableMap 4 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 5 | import com.intuit.dsl.expression.runtime.model.DataValue 6 | import com.intuit.dsl.expression.runtime.model.NumberValue 7 | import spock.lang.Specification 8 | import util.TestUtils 9 | 10 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.NUMBER 11 | 12 | class LengthSpecification extends Specification { 13 | 14 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 15 | 16 | Map inputData = new HashMap() 17 | 18 | def setup() { 19 | Map dataSet1 = new HashMap<>() 20 | Map dataSet2 = new HashMap<>() 21 | dataSet2.put("someList", ImmutableList.of( 22 | ImmutableMap.of( 23 | "stringAttribute", "SomeStringValue1", 24 | "booleanAttribute", true 25 | ), 26 | ImmutableMap.of( 27 | "stringAttribute", "SomeStringValue2", 28 | "booleanAttribute", false 29 | ), 30 | )) 31 | 32 | inputData.put("dataSet1", TestUtils.MAPPER.convertValue(dataSet1, JsonNode.class)) 33 | inputData.put("dataSet2", TestUtils.MAPPER.convertValue(dataSet2, JsonNode.class)) 34 | } 35 | 36 | def "Should give correct size for a filter expression"() { 37 | setup: 38 | DataValue actualResult = expressionRuntime 39 | .withExpressionContent(input) 40 | .withData(inputData) 41 | .evaluate() 42 | 43 | 44 | expect: 45 | expectedType == actualResult.getType() 46 | 47 | NumberValue numberValue = actualResult.getValue() 48 | expectedLength == numberValue.get() 49 | 50 | where: 51 | input | expectedType | expectedLength 52 | ''' length(filter(dataSet2.someList, booleanAttribute == true)) ''' | NUMBER | 1 53 | ''' length(filter(dataSet2.someList, booleanAttribute == false)) ''' | NUMBER | 1 54 | ''' length(filter(dataSet2.someList, stringAttribute == "SomeStringValue1")) ''' | NUMBER | 1 55 | ''' length(filter(dataSet2.someList, stringAttribute == "SomeStringValue2")) ''' | NUMBER | 1 56 | ''' length(filter(dataSet2.someList, stringAttribute == "Not Present in List")) ''' | NUMBER | 0 57 | ''' length(filter(dataSet2.someList, stringAttribute != "Not Present in List")) ''' | NUMBER | 2 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/RemoveSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.fasterxml.jackson.databind.node.ArrayNode 3 | import com.google.common.collect.ImmutableList 4 | import com.google.common.collect.ImmutableMap 5 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 6 | import com.intuit.dsl.expression.runtime.model.DataValue 7 | import spock.lang.Specification 8 | import util.TestUtils 9 | 10 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.ARRAY 11 | 12 | class RemoveSpecification extends Specification { 13 | 14 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 15 | 16 | Map inputData = new HashMap() 17 | 18 | def setup() { 19 | Map dataSet1 = new HashMap<>() 20 | Map dataSet2 = new HashMap<>() 21 | dataSet2.put("someList", ImmutableList.of( 22 | ImmutableMap.of( 23 | "stringAttribute", "SomeStringValue1", 24 | "booleanAttribute", true 25 | ), 26 | ImmutableMap.of( 27 | "stringAttribute", "SomeStringValue2", 28 | "booleanAttribute", false 29 | ), 30 | )) 31 | 32 | inputData.put("dataSet1", TestUtils.MAPPER.convertValue(dataSet1, JsonNode.class)) 33 | inputData.put("dataSet2", TestUtils.MAPPER.convertValue(dataSet2, JsonNode.class)) 34 | } 35 | 36 | def "Should filter with == expression correctly"() { 37 | setup: 38 | DataValue actualResult = expressionRuntime 39 | .withExpressionContent(input) 40 | .withData(inputData) 41 | .evaluate() 42 | ArrayNode arrayNode = actualResult.value 43 | 44 | expect: 45 | expectedType == actualResult.getType() 46 | expectedSize == arrayNode.size() 47 | 48 | where: 49 | input | expectedType | expectedSize 50 | ''' remove(dataSet2.someList, booleanAttribute == true) ''' | ARRAY | 1 51 | ''' remove(dataSet2.someList, booleanAttribute == false) ''' | ARRAY | 1 52 | ''' remove(dataSet2.someList, stringAttribute == "SomeStringValue1") ''' | ARRAY | 1 53 | ''' remove(dataSet2.someList, stringAttribute == "SomeStringValue2") ''' | ARRAY | 1 54 | ''' remove(dataSet2.someList, stringAttribute == "Not Present in List") ''' | ARRAY | 2 55 | ''' remove(dataSet2.someList, stringAttribute != "Not Present in List") ''' | ARRAY | 0 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/groovy/SortSpecification.groovy: -------------------------------------------------------------------------------- 1 | import com.fasterxml.jackson.databind.JsonNode 2 | import com.fasterxml.jackson.databind.node.ArrayNode 3 | import com.google.common.collect.ImmutableList 4 | import com.google.common.collect.ImmutableMap 5 | import com.intuit.dsl.expression.runtime.ExpressionRuntime 6 | import com.intuit.dsl.expression.runtime.model.DataValue 7 | import spock.lang.Specification 8 | import util.TestUtils 9 | 10 | import static com.intuit.dsl.expression.runtime.model.DataValue.Type.ARRAY 11 | 12 | class SortSpecification extends Specification { 13 | 14 | def expressionRuntime = ExpressionRuntime.newExpressionRuntime() 15 | 16 | Map inputData = new HashMap() 17 | 18 | def setup() { 19 | Map dataSet = new HashMap<>() 20 | dataSet.put("someList", ImmutableList.of( 21 | ImmutableMap.of( 22 | "id", 2, 23 | "stringAttribute", "SomeStringValue1", 24 | "booleanAttribute", true 25 | ), 26 | ImmutableMap.of( 27 | "id", 1, 28 | "stringAttribute", "SomeStringValue2", 29 | "booleanAttribute", false 30 | ), 31 | ImmutableMap.of( 32 | "id", 3, 33 | "stringAttribute", "SomeStringValue3", 34 | "booleanAttribute", true 35 | ), 36 | )) 37 | inputData.put("dataSet", TestUtils.MAPPER.convertValue(dataSet, JsonNode.class)) 38 | } 39 | 40 | def "Should sort correctly in ascending order"() { 41 | given: 42 | def sortExpression = 43 | ''' 44 | sort(dataSet.someList, id) 45 | ''' 46 | 47 | when: 48 | DataValue actualResult = expressionRuntime 49 | .withExpressionContent(sortExpression) 50 | .withData(inputData) 51 | .evaluate() 52 | 53 | then: 54 | actualResult.getType() == ARRAY 55 | 56 | ArrayNode actualArrayNode = (ArrayNode)actualResult.getValue() 57 | actualArrayNode.size() == 3 58 | actualArrayNode.get(0).get("id").asInt() == 1; 59 | actualArrayNode.get(1).get("id").asInt() == 2; 60 | actualArrayNode.get(2).get("id").asInt() == 3; 61 | } 62 | 63 | def "Should sort correctly in descending order"() { 64 | given: 65 | def sortExpression = 66 | ''' 67 | sort(dataSet.someList, id, descending) 68 | ''' 69 | 70 | when: 71 | DataValue actualResult = expressionRuntime 72 | .withExpressionContent(sortExpression) 73 | .withData(inputData) 74 | .evaluate() 75 | 76 | then: 77 | actualResult.getType() == ARRAY 78 | 79 | ArrayNode actualArrayNode = (ArrayNode)actualResult.getValue() 80 | actualArrayNode.size() == 3 81 | actualArrayNode.get(0).get("id").asInt() == 3; 82 | actualArrayNode.get(1).get("id").asInt() == 2; 83 | actualArrayNode.get(2).get("id").asInt() == 1; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/java/com/intuit/dsl/expression/runtime/util/EvaluatorUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.util; 2 | 3 | import org.junit.Test; 4 | 5 | import util.TestUtils; 6 | 7 | public class EvaluatorUtilsTest { 8 | 9 | @Test 10 | public void compareToTest() { 11 | TestUtils.assertEquals(-1, EvaluatorUtils.compareTo("abc", "bcd")); 12 | TestUtils.assertEquals(1, EvaluatorUtils.compareTo("bcdef", "abcdef")); 13 | TestUtils.assertEquals(-1, EvaluatorUtils.compareTo("123", "231")); 14 | TestUtils.assertEquals(1, EvaluatorUtils.compareTo("344", "123")); 15 | TestUtils.assertEquals(-1, EvaluatorUtils.compareTo("-344", "-123")); 16 | TestUtils.assertEquals(-1, EvaluatorUtils.compareTo("-344", "1234")); 17 | TestUtils.assertEquals(1, EvaluatorUtils.compareTo("1234", "-344")); 18 | TestUtils.assertEquals(0, EvaluatorUtils.compareTo("", "")); 19 | TestUtils.assertEquals(0, EvaluatorUtils.compareTo(null, null)); 20 | TestUtils.assertEquals(1, EvaluatorUtils.compareTo("", null)); 21 | TestUtils.assertEquals(-1, EvaluatorUtils.compareTo(null, "")); 22 | } 23 | 24 | @Test 25 | public void getNumberNodeTest() { 26 | TestUtils.assertEquals("1111111111111111111111111111111111111111111111111111111111111111111111111111111111", 27 | EvaluatorUtils 28 | .getNumberNode( 29 | "1111111111111111111111111111111111111111111111111111111111111111111111111111111111") 30 | .asText()); 31 | TestUtils.assertNull(EvaluatorUtils.getNumberNode("abc")); 32 | TestUtils.assertNull(EvaluatorUtils.getNumberNode("+25.00")); 33 | TestUtils.assertNull(EvaluatorUtils.getNumberNode("+25.00.00")); 34 | TestUtils.assertEquals("25", EvaluatorUtils.getNumberNode("25.00").asText()); 35 | TestUtils.assertEquals("-25", EvaluatorUtils.getNumberNode("-25.00").asText()); 36 | TestUtils.assertEquals("25", EvaluatorUtils.getNumberNode("25").asText()); 37 | TestUtils.assertEquals("25.12", EvaluatorUtils.getNumberNode("25.12").asText()); 38 | TestUtils.assertEquals("-25.12", EvaluatorUtils.getNumberNode("-25.12").asText()); 39 | TestUtils.assertEquals("0", EvaluatorUtils.getNumberNode("0.00").asText()); 40 | TestUtils.assertEquals("-0.12", EvaluatorUtils.getNumberNode("-0.12").asText()); 41 | TestUtils.assertEquals("120880", EvaluatorUtils.getNumberNode("120880.").asText()); 42 | TestUtils.assertEquals("0", EvaluatorUtils.getNumberNode("0.").asText()); 43 | TestUtils.assertNull(EvaluatorUtils.getNumberNode(null)); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/java/com/intuit/dsl/expression/runtime/util/JsonUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.intuit.dsl.expression.runtime.util; 2 | 3 | import java.io.IOException; 4 | 5 | import org.junit.Test; 6 | 7 | import com.fasterxml.jackson.core.JsonProcessingException; 8 | import com.fasterxml.jackson.databind.JsonNode; 9 | 10 | import util.TestUtils; 11 | 12 | public class JsonUtilsTest { 13 | 14 | @Test 15 | public void getnOrCreateTest() { 16 | TestUtils.assertEquals("{}", 17 | JSONUtils.getOrCreate("any", JSONUtils.getMapper().createObjectNode()).toString()); 18 | TestUtils.assertEquals("b", 19 | JSONUtils.getOrCreate("a", JSONUtils.getJsonOrTextNode("{'a':'b'}")).asText()); 20 | } 21 | 22 | @Test 23 | public void getJsonOrTextNodeTest() { 24 | TestUtils.assertEquals("", JSONUtils.getJsonOrTextNode(null).asText()); 25 | TestUtils.assertEquals("Abc", JSONUtils.getJsonOrTextNode("Abc").asText()); 26 | TestUtils.assertEquals("{}", JSONUtils.getJsonOrTextNode("{}").toString()); 27 | TestUtils.assertEquals(10, JSONUtils.getJsonOrTextNode("10").asInt()); 28 | TestUtils.assertEquals(10.1, JSONUtils.getJsonOrTextNode("10.1").asDouble()); 29 | TestUtils.assertEquals("1234 sjkf", JSONUtils.getJsonOrTextNode("1234 sjkf").asText()); 30 | TestUtils.assertEquals("", JSONUtils.getJsonOrTextNode("").asText()); 31 | TestUtils.assertEquals(JSONUtils.getJsonOrTextNode("{'a':'b'}"), "a", "b"); 32 | TestUtils.assertEquals(11, JSONUtils.getJsonOrTextNode("00011").asInt()); 33 | } 34 | 35 | @Test 36 | public void getArray() { 37 | TestUtils.assertNotNull(JSONUtils.getMapper()); 38 | TestUtils.assertEquals("[]", JSONUtils.getArray(null).toString()); 39 | TestUtils.assertEquals("[{}]", 40 | JSONUtils.getArray(JSONUtils.getMapper().createObjectNode()).toString()); 41 | TestUtils.assertEquals("[]", JSONUtils.getArray(JSONUtils.MAPPER.createArrayNode()).toString()); 42 | } 43 | 44 | @Test 45 | public void nullJsonNodeTest() { 46 | String test1 = 47 | "{\"IRS1040\":{\"Return\":{\"ReturnHeader\":{\"TaxYr\":\"2017\",\"IsImportFromPriorYearPdfPP\":null,\"IsYearOverYearPP\":null},\"ReturnData\":{\"PPPerson\":{\"TaxpayerFilerInfoPP\":{\"PersonFullNamePP\":{\"PersonFirstNm\":\"Ishani\",\"PersonLastNm\":null}}}}}}}"; 48 | JsonNode testJson1 = null; 49 | try { 50 | testJson1 = JSONUtils.getJSONFromString(test1); 51 | } catch (JsonProcessingException e) { 52 | e.printStackTrace(); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | TestUtils.assertNotNull(JSONUtils.getMapper()); 57 | 58 | // valid node 59 | JsonNode goodNode = testJson1.findValue("TaxYr"); 60 | TestUtils.assertEquals(true, JSONUtils.isNotNull(goodNode)); 61 | 62 | // JsonNodeType.MISSING 63 | JsonNode node1 = testJson1.path("foo"); 64 | TestUtils.assertEquals(false, JSONUtils.isNotNull(node1)); 65 | 66 | // null 67 | JsonNode node2 = testJson1.findValue("foo"); 68 | TestUtils.assertEquals(false, JSONUtils.isNotNull(node2)); 69 | 70 | // JsonNodeType.NULL 71 | JsonNode node3 = testJson1.findValue("IsYearOverYearPP"); 72 | TestUtils.assertEquals(false, JSONUtils.isNotNull(node3)); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.runtime/src/test/java/util/TestUtils.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Arrays; 4 | import org.junit.Assert; 5 | import com.fasterxml.jackson.databind.JsonNode; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import com.fasterxml.jackson.databind.node.NullNode; 8 | import com.intuit.dsl.expression.runtime.util.JSONUtils; 9 | 10 | public class TestUtils { 11 | 12 | public static final ObjectMapper MAPPER = new ObjectMapper(); 13 | 14 | public static ObjectMapper mapper() { 15 | return MAPPER; 16 | } 17 | 18 | public static void assertEquals(JsonNode output, String path, long i) { 19 | JsonNode node = JSONUtils 20 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 21 | assertEquals(i, node.asLong()); 22 | } 23 | 24 | public static void assertEquals(JsonNode output, String path, double i) { 25 | JsonNode node = JSONUtils 26 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 27 | assertEquals(i, node.asDouble()); 28 | } 29 | 30 | public static void assertEquals(JsonNode output, String path, String string) { 31 | JsonNode node = JSONUtils 32 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 33 | assertEquals(string, node.asText()); 34 | } 35 | 36 | public static void assertEquals(JsonNode output, String path, Boolean bool) { 37 | JsonNode node = JSONUtils 38 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 39 | assertEquals(bool, node.asBoolean()); 40 | } 41 | 42 | public static void assertNull(JsonNode output, String path) { 43 | JsonNode node = JSONUtils 44 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 45 | assertEquals("null", node.asText()); 46 | } 47 | 48 | public static void assertSize(JsonNode output, String path, int size) { 49 | JsonNode node = JSONUtils 50 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 51 | assertEquals(size, node.size()); 52 | } 53 | 54 | public static void assertEquals(Object expected, Object actual) { 55 | // Generic assertEquals for all objects 56 | Assert.assertEquals(expected, actual); 57 | } 58 | 59 | public static void assertNull(Object o) { 60 | Assert.assertNull(o); 61 | } 62 | 63 | public static void assertNotNull(Object o) { 64 | Assert.assertNotNull(o); 65 | } 66 | 67 | public static void assertNotNull(JsonNode output, String path) { 68 | JsonNode node = JSONUtils 69 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 70 | assertNotNull(node.asText()); 71 | } 72 | 73 | public static void assertEquals(JsonNode output, String path, NullNode instance) { 74 | JsonNode node = JSONUtils 75 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 76 | Assert.assertEquals(node.asText(), instance.asText()); 77 | } 78 | 79 | public static boolean containsKey(JsonNode output, String path) { 80 | JsonNode node = JSONUtils 81 | .recurse(Arrays.asList(path.replace("]", "").split("\\.|\\[")).iterator(), output); 82 | return node != null; 83 | } 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.target/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.target 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.m2e.core.maven2Builder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.m2e.core.maven2Nature 16 | 17 | 18 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.target/com.intuit.dsl.expression.target.target: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.target/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.intuit.dsl.expression 5 | com.intuit.dsl.expression.parent 6 | 1.0.4-SNAPSHOT 7 | 8 | com.intuit.dsl.expression.target 9 | eclipse-target-definition 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.tests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.ManifestBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.pde.SchemaBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.eclipse.m2e.core.maven2Nature 36 | org.eclipse.xtext.ui.shared.xtextNature 37 | org.eclipse.jdt.core.javanature 38 | org.eclipse.pde.PluginNature 39 | 40 | 41 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Automatic-Module-Name: com.intuit.dsl.expression.tests 3 | Bundle-ManifestVersion: 2 4 | Bundle-Name: com.intuit.dsl.expression.tests 5 | Bundle-Vendor: My Company 6 | Bundle-Version: 1.0.0.qualifier 7 | Bundle-SymbolicName: com.intuit.dsl.expression.tests; singleton:=true 8 | Bundle-ActivationPolicy: lazy 9 | Require-Bundle: com.intuit.dsl.expression, 10 | org.junit.jupiter.api;bundle-version="[5.1.0,6.0.0)", 11 | org.eclipse.xtext.testing, 12 | org.eclipse.xtext.xbase.testing, 13 | org.eclipse.xtext.xbase.lib;bundle-version="2.14.0" 14 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 15 | Export-Package: com.intuit.dsl.tests;x-internal=true 16 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = .,\ 5 | META-INF/ 6 | bin.excludes = **/*.xtend 7 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.intuit.dsl.expression 5 | com.intuit.dsl.expression.parent 6 | 1.0.4-SNAPSHOT 7 | 8 | com.intuit.dsl.expression.tests 9 | eclipse-test-plugin 10 | 11 | 12 | 13 | 14 | org.eclipse.xtend 15 | xtend-maven-plugin 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.tests/src/com/intuit/dsl/tests/ExpressionParsingTest.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.tests 5 | 6 | import com.google.inject.Inject 7 | import com.intuit.dsl.expression.Expression 8 | import org.eclipse.xtext.testing.InjectWith 9 | import org.eclipse.xtext.testing.extensions.InjectionExtension 10 | import org.eclipse.xtext.testing.util.ParseHelper 11 | import org.junit.jupiter.api.Assertions 12 | import org.junit.jupiter.api.Test 13 | import org.junit.jupiter.api.^extension.ExtendWith 14 | 15 | @ExtendWith(InjectionExtension) 16 | @InjectWith(ExpressionInjectorProvider) 17 | class ExpressionParsingTest { 18 | @Inject 19 | ParseHelper parseHelper 20 | 21 | @Test 22 | def void loadModel() { 23 | val result = parseHelper.parse(''' 24 | 1+1 25 | ''') 26 | Assertions.assertNotNull(result) 27 | val errors = result.eResource.errors 28 | Assertions.assertTrue(errors.isEmpty, '''Unexpected errors: «errors.join(", ")»''') 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui.tests/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui.tests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.ui.tests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.ManifestBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.pde.SchemaBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.eclipse.m2e.core.maven2Nature 36 | org.eclipse.xtext.ui.shared.xtextNature 37 | org.eclipse.jdt.core.javanature 38 | org.eclipse.pde.PluginNature 39 | 40 | 41 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui.tests/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Automatic-Module-Name: com.intuit.dsl.expression.ui.tests 3 | Bundle-ManifestVersion: 2 4 | Bundle-Name: com.intuit.dsl.expression.ui.tests 5 | Bundle-Vendor: My Company 6 | Bundle-Version: 1.0.0.qualifier 7 | Bundle-SymbolicName: com.intuit.dsl.expression.ui.tests; singleton:=true 8 | Bundle-ActivationPolicy: lazy 9 | Require-Bundle: com.intuit.dsl.expression.ui, 10 | org.junit.jupiter.api;bundle-version="[5.1.0,6.0.0)", 11 | org.eclipse.xtext.testing, 12 | org.eclipse.xtext.xbase.testing, 13 | org.eclipse.xtext.xbase.junit, 14 | org.eclipse.core.runtime, 15 | org.eclipse.xtext.ui.testing, 16 | org.eclipse.ui.workbench;resolution:=optional 17 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 18 | Export-Package: com.intuit.dsl.ui.tests;x-internal=true 19 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui.tests/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = .,\ 5 | META-INF/ 6 | bin.excludes = **/*.xtend 7 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui.tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.intuit.dsl.expression 5 | com.intuit.dsl.expression.parent 6 | 1.0.4-SNAPSHOT 7 | 8 | com.intuit.dsl.expression.ui.tests 9 | eclipse-test-plugin 10 | 11 | 12 | 13 | 14 | org.eclipse.xtend 15 | xtend-maven-plugin 16 | 17 | 18 | org.eclipse.tycho 19 | tycho-surefire-plugin 20 | 21 | false 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.ui 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.xtext.ui.shared.xtextBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.pde.ManifestBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.pde.SchemaBuilder 30 | 31 | 32 | 33 | 34 | org.eclipse.wst.validation.validationbuilder 35 | 36 | 37 | 38 | 39 | org.eclipse.m2e.core.maven2Builder 40 | 41 | 42 | 43 | 44 | 45 | org.eclipse.m2e.core.maven2Nature 46 | org.eclipse.xtext.ui.shared.xtextNature 47 | org.eclipse.jdt.core.javanature 48 | org.eclipse.pde.PluginNature 49 | org.eclipse.wst.common.project.facet.core.nature 50 | org.eclipse.wst.common.modulecore.ModuleCoreNature 51 | 52 | 53 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Automatic-Module-Name: com.intuit.dsl.expression.ui 3 | Bundle-ManifestVersion: 2 4 | Bundle-Name: com.intuit.dsl.expression.ui 5 | Bundle-Vendor: My Company 6 | Bundle-Version: 1.0.0.qualifier 7 | Bundle-SymbolicName: com.intuit.dsl.expression.ui; singleton:=true 8 | Bundle-ActivationPolicy: lazy 9 | Require-Bundle: com.intuit.dsl.expression, 10 | com.intuit.dsl.expression.ide, 11 | org.eclipse.xtext.ui, 12 | org.eclipse.xtext.ui.shared, 13 | org.eclipse.xtext.ui.codetemplates.ui, 14 | org.eclipse.ui.editors;bundle-version="3.5.0", 15 | org.eclipse.ui.ide;bundle-version="3.5.0", 16 | org.eclipse.ui, 17 | org.eclipse.compare, 18 | org.eclipse.xtext.builder 19 | Import-Package: org.apache.log4j 20 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 21 | Export-Package: com.intuit.dsl.ui.quickfix, 22 | com.intuit.dsl.expression.ui.internal, 23 | com.intuit.dsl.ui.contentassist 24 | Bundle-Activator: com.intuit.dsl.expression.ui.internal.ExpressionActivator 25 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = .,\ 5 | META-INF/,\ 6 | plugin.xml 7 | bin.excludes = **/*.xtend 8 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.intuit.dsl.expression 5 | com.intuit.dsl.expression.parent 6 | 1.0.4-SNAPSHOT 7 | 8 | com.intuit.dsl.expression.ui 9 | eclipse-plugin 10 | 11 | 12 | 13 | 14 | org.eclipse.xtend 15 | xtend-maven-plugin 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/ExpressionUiModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui; 5 | 6 | import org.eclipse.ui.plugin.AbstractUIPlugin; 7 | 8 | /** 9 | * Use this class to register components to be used within the Eclipse IDE. 10 | */ 11 | public class ExpressionUiModule extends AbstractExpressionUiModule { 12 | 13 | public ExpressionUiModule(AbstractUIPlugin plugin) { 14 | super(plugin); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/contentassist/ExpressionProposalProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui.contentassist; 5 | 6 | 7 | /** 8 | * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#content-assist 9 | * on how to customize the content assistant. 10 | */ 11 | public class ExpressionProposalProvider extends AbstractExpressionProposalProvider { 12 | } 13 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/labeling/ExpressionDescriptionLabelProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui.labeling; 5 | 6 | import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider; 7 | 8 | /** 9 | * Provides labels for IEObjectDescriptions and IResourceDescriptions. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#label-provider 12 | */ 13 | public class ExpressionDescriptionLabelProvider extends DefaultDescriptionLabelProvider { 14 | 15 | // Labels and icons can be computed like this: 16 | // @Override 17 | // public String text(IEObjectDescription ele) { 18 | // return ele.getName().toString(); 19 | // } 20 | // 21 | // @Override 22 | // public String image(IEObjectDescription ele) { 23 | // return ele.getEClass().getName() + ".gif"; 24 | // } 25 | } 26 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/labeling/ExpressionLabelProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui.labeling; 5 | 6 | import com.google.inject.Inject; 7 | import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; 8 | import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider; 9 | 10 | /** 11 | * Provides labels for EObjects. 12 | * 13 | * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#label-provider 14 | */ 15 | public class ExpressionLabelProvider extends DefaultEObjectLabelProvider { 16 | 17 | @Inject 18 | public ExpressionLabelProvider(AdapterFactoryLabelProvider delegate) { 19 | super(delegate); 20 | } 21 | 22 | // Labels and icons can be computed like this: 23 | 24 | // String text(Greeting ele) { 25 | // return "A greeting to " + ele.getName(); 26 | // } 27 | // 28 | // String image(Greeting ele) { 29 | // return "Greeting.gif"; 30 | // } 31 | } 32 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/outline/ExpressionOutlineTreeProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui.outline; 5 | 6 | import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider; 7 | 8 | /** 9 | * Customization of the default outline structure. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#outline 12 | */ 13 | public class ExpressionOutlineTreeProvider extends DefaultOutlineTreeProvider { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.ui/src/com/intuit/dsl/ui/quickfix/ExpressionQuickfixProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.ui.quickfix; 5 | 6 | import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider; 7 | 8 | /** 9 | * Custom quickfixes. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes 12 | */ 13 | public class ExpressionQuickfixProvider extends DefaultQuickfixProvider { 14 | 15 | // @Fix(ExpressionValidator.INVALID_NAME) 16 | // public void capitalizeName(final Issue issue, IssueResolutionAcceptor acceptor) { 17 | // acceptor.accept(issue, "Capitalize name", "Capitalize the name.", "upcase.png", new IModification() { 18 | // public void apply(IModificationContext context) throws BadLocationException { 19 | // IXtextDocument xtextDocument = context.getXtextDocument(); 20 | // String firstLetter = xtextDocument.get(issue.getOffset(), 1); 21 | // xtextDocument.replace(issue.getOffset(), 1, firstLetter.toUpperCase()); 22 | // } 23 | // }); 24 | // } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression.web 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.xtext.ui.shared.xtextBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.m2e.core.maven2Builder 30 | 31 | 32 | 33 | 34 | 35 | org.eclipse.jem.workbench.JavaEMFNature 36 | org.eclipse.wst.common.modulecore.ModuleCoreNature 37 | org.eclipse.m2e.core.maven2Nature 38 | org.eclipse.xtext.ui.shared.xtextNature 39 | org.eclipse.jdt.core.javanature 40 | org.eclipse.wst.common.project.facet.core.nature 41 | org.eclipse.wst.jsdt.core.jsNature 42 | 43 | 44 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/WebRoot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example Web Editor 6 | 7 | 8 | 9 | 31 | 32 | 33 | 34 |
35 |
36 |

Example Expression Web Editor

37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/WebRoot/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 100%; 3 | height: 100%; 4 | overflow: hidden; 5 | font: 16px Helvetica,sans-serif; 6 | } 7 | 8 | a { 9 | color: #22a; 10 | text-decoration: none; 11 | } 12 | 13 | a:hover { 14 | text-decoration: underline; 15 | } 16 | 17 | .container { 18 | display: block; 19 | position: absolute; 20 | top: 0; 21 | bottom: 0; 22 | left: 0; 23 | right: 0; 24 | margin: 20px; 25 | } 26 | 27 | .header { 28 | display: block; 29 | position: absolute; 30 | background-color: #e8e8e8; 31 | top: 0; 32 | left: 0; 33 | right: 0; 34 | height: 60px; 35 | padding: 10px; 36 | } 37 | 38 | .content { 39 | display: block; 40 | position: absolute; 41 | top: 90px; 42 | bottom: 0; 43 | left: 0; 44 | width: 640px; 45 | } 46 | 47 | #xtext-editor { 48 | display: block; 49 | position: absolute; 50 | top: 0; 51 | bottom: 0; 52 | left: 0; 53 | right: 0; 54 | padding: 4px; 55 | border: 1px solid #aaa; 56 | } 57 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/src/com/intuit/dsl/web/ExpressionServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.web; 5 | 6 | import com.google.inject.Injector; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.annotation.WebServlet; 9 | import org.eclipse.xtext.util.DisposableRegistry; 10 | import org.eclipse.xtext.web.servlet.XtextServlet; 11 | 12 | /** 13 | * Deploy this class into a servlet container to enable DSL-specific services. 14 | */ 15 | @WebServlet(name = "XtextServices", urlPatterns = "/xtext-service/*") 16 | public class ExpressionServlet extends XtextServlet { 17 | 18 | private static final long serialVersionUID = 1L; 19 | 20 | DisposableRegistry disposableRegistry; 21 | 22 | public void init() throws ServletException { 23 | super.init(); 24 | Injector injector = new ExpressionWebSetup().createInjectorAndDoEMFRegistration(); 25 | this.disposableRegistry = injector.getInstance(DisposableRegistry.class); 26 | } 27 | 28 | public void destroy() { 29 | if (disposableRegistry != null) { 30 | disposableRegistry.dispose(); 31 | disposableRegistry = null; 32 | } 33 | super.destroy(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/src/com/intuit/dsl/web/ExpressionWebModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.web; 5 | 6 | 7 | /** 8 | * Use this class to register additional components to be used within the web application. 9 | */ 10 | public class ExpressionWebModule extends AbstractExpressionWebModule { 11 | } 12 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/src/com/intuit/dsl/web/ExpressionWebSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.web; 5 | 6 | import com.google.inject.Guice; 7 | import com.google.inject.Injector; 8 | import com.intuit.dsl.ExpressionRuntimeModule; 9 | import com.intuit.dsl.ExpressionStandaloneSetup; 10 | import com.intuit.dsl.ide.ExpressionIdeModule; 11 | import org.eclipse.xtext.util.Modules2; 12 | 13 | /** 14 | * Initialization support for running Xtext languages in web applications. 15 | */ 16 | public class ExpressionWebSetup extends ExpressionStandaloneSetup { 17 | 18 | @Override 19 | public Injector createInjector() { 20 | return Guice.createInjector(Modules2.mixin(new ExpressionRuntimeModule(), new ExpressionIdeModule(), new ExpressionWebModule())); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression.web/src/com/intuit/dsl/web/ServerLauncher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.web; 5 | 6 | import java.net.InetSocketAddress; 7 | import org.eclipse.jetty.annotations.AnnotationConfiguration; 8 | import org.eclipse.jetty.server.Server; 9 | import org.eclipse.jetty.util.log.Slf4jLog; 10 | import org.eclipse.jetty.webapp.Configuration; 11 | import org.eclipse.jetty.webapp.MetaInfConfiguration; 12 | import org.eclipse.jetty.webapp.WebAppContext; 13 | import org.eclipse.jetty.webapp.WebInfConfiguration; 14 | import org.eclipse.jetty.webapp.WebXmlConfiguration; 15 | 16 | /** 17 | * This program starts an HTTP server for testing the web integration of your DSL. 18 | * Just execute it and point a web browser to http://localhost:8080/ 19 | */ 20 | public class ServerLauncher { 21 | public static void main(String[] args) { 22 | Server server = new Server(new InetSocketAddress("localhost", 8080)); 23 | WebAppContext ctx = new WebAppContext(); 24 | ctx.setResourceBase("WebRoot"); 25 | ctx.setWelcomeFiles(new String[] {"index.html"}); 26 | ctx.setContextPath("/"); 27 | ctx.setConfigurations(new Configuration[] { 28 | new AnnotationConfiguration(), 29 | new WebXmlConfiguration(), 30 | new WebInfConfiguration(), 31 | new MetaInfConfiguration() 32 | }); 33 | ctx.setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, 34 | ".*/com\\.intuit\\.dsl\\.expression\\.web/.*,.*\\.jar"); 35 | ctx.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false"); 36 | server.setHandler(ctx); 37 | Slf4jLog log = new Slf4jLog(ServerLauncher.class.getName()); 38 | try { 39 | server.start(); 40 | log.info("Server started " + server.getURI() + "..."); 41 | new Thread() { 42 | 43 | public void run() { 44 | try { 45 | log.info("Press enter to stop the server..."); 46 | int key = System.in.read(); 47 | if (key != -1) { 48 | server.stop(); 49 | } else { 50 | log.warn( 51 | "Console input is not available. In order to stop the server, you need to cancel process manually."); 52 | } 53 | } catch (Exception e) { 54 | log.warn(e); 55 | } 56 | } 57 | 58 | }.start(); 59 | server.join(); 60 | } catch (Exception exception) { 61 | log.warn(exception.getMessage()); 62 | System.exit(1); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.intuit.dsl.expression 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.xtext.ui.shared.xtextBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.pde.ManifestBuilder 25 | 26 | 27 | 28 | 29 | org.eclipse.pde.SchemaBuilder 30 | 31 | 32 | 33 | 34 | org.eclipse.wst.validation.validationbuilder 35 | 36 | 37 | 38 | 39 | org.eclipse.m2e.core.maven2Builder 40 | 41 | 42 | 43 | 44 | 45 | org.eclipse.jem.workbench.JavaEMFNature 46 | org.eclipse.wst.common.modulecore.ModuleCoreNature 47 | org.eclipse.m2e.core.maven2Nature 48 | org.eclipse.xtext.ui.shared.xtextNature 49 | org.eclipse.jdt.core.javanature 50 | org.eclipse.pde.PluginNature 51 | org.eclipse.wst.common.project.facet.core.nature 52 | 53 | 54 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Automatic-Module-Name: com.intuit.dsl.expression 3 | Bundle-ManifestVersion: 2 4 | Bundle-Name: com.intuit.dsl.expression 5 | Bundle-Vendor: My Company 6 | Bundle-Version: 1.0.0.qualifier 7 | Bundle-SymbolicName: com.intuit.dsl.expression; singleton:=true 8 | Bundle-ActivationPolicy: lazy 9 | Require-Bundle: org.eclipse.xtext, 10 | org.eclipse.xtext.xbase, 11 | org.eclipse.equinox.common;bundle-version="3.5.0", 12 | org.eclipse.emf.ecore, 13 | org.eclipse.xtext.xbase.lib;bundle-version="2.14.0", 14 | org.eclipse.xtext.util, 15 | org.eclipse.emf.common, 16 | org.antlr.runtime;bundle-version="[3.2.0,3.2.1)" 17 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 18 | Export-Package: com.intuit.dsl, 19 | com.intuit.dsl.validation, 20 | com.intuit.dsl.expression, 21 | com.intuit.dsl.services, 22 | com.intuit.dsl.expression.util, 23 | com.intuit.dsl.expression.impl, 24 | com.intuit.dsl.generator, 25 | com.intuit.dsl.scoping, 26 | com.intuit.dsl.parser.antlr, 27 | com.intuit.dsl.parser.antlr.internal, 28 | com.intuit.dsl.serializer 29 | Import-Package: org.apache.log4j 30 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = model/generated/,\ 5 | .,\ 6 | META-INF/,\ 7 | plugin.xml 8 | bin.excludes = **/*.mwe2,\ 9 | **/*.xtend 10 | additional.bundles = org.eclipse.xtext.xbase,\ 11 | org.eclipse.xtext.common.types,\ 12 | org.eclipse.xtext.xtext.generator,\ 13 | org.eclipse.emf.codegen.ecore,\ 14 | org.eclipse.emf.mwe.utils,\ 15 | org.eclipse.emf.mwe2.launch,\ 16 | org.eclipse.emf.mwe2.lib,\ 17 | org.objectweb.asm,\ 18 | org.apache.commons.logging,\ 19 | org.apache.log4j 20 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/ExpressionRuntimeModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl; 5 | 6 | 7 | /** 8 | * Use this class to register components to be used at runtime / without the Equinox extension registry. 9 | */ 10 | public class ExpressionRuntimeModule extends AbstractExpressionRuntimeModule { 11 | } 12 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/ExpressionStandaloneSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl; 5 | 6 | 7 | /** 8 | * Initialization support for running Xtext languages without Equinox extension registry. 9 | */ 10 | public class ExpressionStandaloneSetup extends ExpressionStandaloneSetupGenerated { 11 | 12 | public static void doSetup() { 13 | new ExpressionStandaloneSetup().createInjectorAndDoEMFRegistration(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/GenerateExpression.mwe2: -------------------------------------------------------------------------------- 1 | module com.intuit.dsl.GenerateExpression 2 | 3 | import org.eclipse.xtext.xtext.generator.* 4 | import org.eclipse.xtext.xtext.generator.model.project.* 5 | 6 | var rootPath = ".." 7 | 8 | Workflow { 9 | 10 | component = XtextGenerator { 11 | configuration = { 12 | project = StandardProjectConfig { 13 | baseName = "com.intuit.dsl.expression" 14 | rootPath = rootPath 15 | runtimeTest = { 16 | enabled = true 17 | } 18 | eclipsePlugin = { 19 | enabled = true 20 | } 21 | eclipsePluginTest = { 22 | enabled = true 23 | } 24 | web = { 25 | enabled = true 26 | } 27 | createEclipseMetaData = true 28 | } 29 | code = { 30 | encoding = "UTF-8" 31 | lineDelimiter = "\n" 32 | fileHeader = "/*\n * generated by Xtext \${version}\n */" 33 | preferXtendStubs = false 34 | } 35 | } 36 | language = StandardLanguage { 37 | name = "com.intuit.dsl.Expression" 38 | fileExtensions = "expr" 39 | 40 | serializer = { 41 | generateStub = false 42 | } 43 | validator = { 44 | // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" 45 | // Generates checks for @Deprecated grammar annotations, an IssueProvider and a corresponding PropertyPage 46 | generateDeprecationValidation = true 47 | } 48 | generator = { 49 | generateXtendStub = true 50 | } 51 | junitSupport = { 52 | junitVersion = "5" 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/generator/ExpressionGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.generator 5 | 6 | import org.eclipse.emf.ecore.resource.Resource 7 | import org.eclipse.xtext.generator.AbstractGenerator 8 | import org.eclipse.xtext.generator.IFileSystemAccess2 9 | import org.eclipse.xtext.generator.IGeneratorContext 10 | 11 | /** 12 | * Generates code from your model files on save. 13 | * 14 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 15 | */ 16 | class ExpressionGenerator extends AbstractGenerator { 17 | 18 | override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) { 19 | // fsa.generateFile('greetings.txt', 'People to greet: ' + 20 | // resource.allContents 21 | // .filter(Greeting) 22 | // .map[name] 23 | // .join(', ')) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/scoping/ExpressionScopeProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.scoping; 5 | 6 | 7 | /** 8 | * This class contains custom scoping description. 9 | * 10 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping 11 | * on how and when to use it. 12 | */ 13 | public class ExpressionScopeProvider extends AbstractExpressionScopeProvider { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/validation/ExpressionValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 2.25.0 3 | */ 4 | package com.intuit.dsl.validation; 5 | 6 | 7 | /** 8 | * This class contains custom validation rules. 9 | * 10 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation 11 | */ 12 | public class ExpressionValidator extends AbstractExpressionValidator { 13 | 14 | // public static final String INVALID_NAME = "invalidName"; 15 | // 16 | // @Check 17 | // public void checkGreetingStartsWithCapital(Greeting greeting) { 18 | // if (!Character.isUpperCase(greeting.getName().charAt(0))) { 19 | // warning("Name should start with a capital", 20 | // ExpressionPackage.Literals.GREETING__NAME, 21 | // INVALID_NAME); 22 | // } 23 | // } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /common-xtext-expression-language-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/common-xtext-expression-language-logo.png -------------------------------------------------------------------------------- /documents/images/addRepo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/addRepo.png -------------------------------------------------------------------------------- /documents/images/deselectLatestVersions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/deselectLatestVersions.png -------------------------------------------------------------------------------- /documents/images/generateFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/generateFlow.png -------------------------------------------------------------------------------- /documents/images/installNewSoftware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/installNewSoftware.png -------------------------------------------------------------------------------- /documents/images/xtendVersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/xtendVersion.png -------------------------------------------------------------------------------- /documents/images/xtextVersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/documents/images/xtextVersion.png -------------------------------------------------------------------------------- /mkdocs/docs/css/css-override.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | color: black; 3 | } 4 | h2 { 5 | color: #2E0000; 6 | } 7 | h3 { 8 | color: #2C877C; 9 | font-size: 21px; 10 | font-weight: bold; 11 | } 12 | h4 { 13 | color: #25387E; 14 | font-size: 18px; 15 | } 16 | 17 | 18 | li { 19 | font-size: 16px; 20 | } 21 | tr { 22 | font-size: 16px; 23 | } 24 | 25 | img[alt$=">"] { 26 | float:right; 27 | } 28 | 29 | img[alt$="<"] { 30 | float:left; 31 | } 32 | 33 | img[alt$="<>"] { 34 | display: block; 35 | max-width: 100%; 36 | height: auto; 37 | margin: auto; 38 | float: none!important; 39 | } 40 | 41 | div p { 42 | text-align: justify; 43 | text-justify: inter-word; 44 | font-size: 16px; 45 | } 46 | 47 | .codehilite { 48 | font-size: 14px; 49 | } 50 | 51 | /* div pre { 52 | color: #EBECE4; 53 | } */ 54 | 55 | /* ul .md-nav__item { 56 | font-size: 14px; 57 | } */ 58 | 59 | /* ul .md-nav__list { 60 | color: red; 61 | } */ 62 | 63 | /* li .md-nav__item { 64 | color: red; 65 | } */ 66 | 67 | /* Right Sidebar heading color */ 68 | .md-nav--secondary > ul > li > a:first-child { 69 | color: #0a0033; 70 | } 71 | 72 | /* Right sidebar list color */ 73 | .md-nav--secondary > ul > li .md-nav__item { 74 | font-size: 13px; 75 | } 76 | 77 | code{ 78 | color: red; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /mkdocs/docs/expressions/Arithmetic.md: -------------------------------------------------------------------------------- 1 | Supported arithmetic operations in expressions are as follow: 2 | * Plus (+) 3 | * Minus (-) 4 | * Multiplicationn (*) 5 | * Division (/) 6 | * Mod (%) 7 | 8 | 9 | #Example 10 | 11 | Schema numbersSchema { 12 | number num1 13 | number num2 14 | } 15 | 16 | value numbers -> numbersSchema { 17 | 1 18 | 2 19 | } 20 | 21 | Schema outputSchema { 22 | number plusOp 23 | number minusOp 24 | number multOp 25 | number divOp 26 | number modOp 27 | } 28 | 29 | Mapping arithmeticMapping input numbers as numbers output outputSchema { 30 | outputSchema.plusOp = numbers.num1 + numbers.num2 31 | outputSchema.minusOp = numbers.num2 - numbers.num1 32 | outputSchema.multOp = numbers.num1 * numbers.num2 33 | outputSchema.divOp = numbers.num1 / numbers.num2 34 | outputSchema.modOp = numbers.num1 % numbers.num2 35 | } 36 | 37 | ##Output for Example Flow 38 | 39 | { 40 | "plusOp": 3, 41 | "minusOp": 1, 42 | "multOp": 2, 43 | "divOp": 0.5, 44 | "modOp": 1 45 | } -------------------------------------------------------------------------------- /mkdocs/docs/expressions/Boolean.md: -------------------------------------------------------------------------------- 1 | Supported boolean operations in expressions are as follow: 2 | * AND (&&) 3 | * OR (||) 4 | * NOT (!) 5 | 6 | #Example 7 | 8 | Schema booleanSchema { 9 | boolean truthValue 10 | boolean falseValue 11 | } 12 | 13 | value booleans -> booleanSchema { 14 | true 15 | false 16 | } 17 | 18 | Schema outputSchema { 19 | boolean andTT 20 | boolean andTF 21 | boolean andFT 22 | boolean andFF 23 | boolean orTT 24 | boolean orTF 25 | boolean orFT 26 | boolean orFF 27 | boolean notF 28 | boolean notT 29 | } 30 | 31 | Mapping booleanMapping input booleans as booleans output outputSchema { 32 | outputSchema.andTT = booleans.truthValue && booleans.truthValue 33 | outputSchema.andTF = booleans.truthValue && booleans.falseValue 34 | outputSchema.andFT = booleans.falseValue && booleans.truthValue 35 | outputSchema.andFF = booleans.falseValue && booleans.falseValue 36 | outputSchema.orTT = booleans.truthValue || booleans.truthValue 37 | outputSchema.orTF = booleans.truthValue || booleans.falseValue 38 | outputSchema.orFT = booleans.falseValue || booleans.truthValue 39 | outputSchema.orFF = booleans.falseValue || booleans.falseValue 40 | outputSchema.notF = !booleans.falseValue 41 | outputSchema.notT = !booleans.truthValue 42 | } 43 | 44 | ##Output for Example Flow 45 | 46 | { 47 | "andTT": true, 48 | "andTF": false, 49 | "andFT": false, 50 | "andFF": false, 51 | "orTT": true, 52 | "orTF": true, 53 | "orFT": true, 54 | "orFF": false, 55 | "notF": true, 56 | "notT": false 57 | } -------------------------------------------------------------------------------- /mkdocs/docs/expressions/Conditional.md: -------------------------------------------------------------------------------- 1 | Supported conditionals in expressions are: 2 | * Less than (<) 3 | * Greater than (>) 4 | * Less than equal to (<=) 5 | * Greater than equal to (>=) 6 | * Equal to (==) 7 | * Not equal to (!=) 8 | * Fuzzy Equals (=~) (currently works only for strings with different case and numbers) 9 | * Fuzzy not (!~) (currently works only for strings with different case and numbers) 10 | * Ternary expression: 11 | Syntax : if [expression] then [trueValue] else [falseValue] 12 | 13 | #Example 14 | 15 | Schema dataSchema { 16 | number zero 17 | number ten 18 | string lowerCaseOne 19 | } 20 | 21 | value data -> dataSchema { 22 | 0 23 | 10 24 | "one" 25 | } 26 | 27 | Schema outputSchema { 28 | boolean lt 29 | boolean gt 30 | boolean ltet 31 | boolean gtet 32 | boolean eq 33 | boolean neq 34 | boolean feqNumber 35 | boolean feqString 36 | boolean fneqNumber 37 | boolean fneqString 38 | string ternaryEx 39 | } 40 | 41 | Mapping conditionalMapping input data as data output outputSchema { 42 | outputSchema.lt = data.zero < data.ten 43 | outputSchema.gt = data.zero > data.ten 44 | outputSchema.ltet = data.zero <= data.ten 45 | outputSchema.gtet = data.zero >= data.ten 46 | outputSchema.eq = data.zero == data.ten 47 | outputSchema.neq = data.zero != data.ten 48 | outputSchema.feqNumber = data.zero =~ data.zero 49 | outputSchema.feqString = data.lowerCaseOne =~ "ONE" 50 | outputSchema.fneqNumber = data.zero !~ data.ten 51 | outputSchema.fneqString = data.lowerCaseOne !~ "ONES" 52 | outputSchema.ternaryEx = if (data.zero >= data.ten) then (data.zero * data.ten) else (data.zero + data.ten) 53 | } 54 | 55 | ##Output for Example Flow 56 | 57 | { 58 | "lt": true, 59 | "gt": false, 60 | "ltet": true, 61 | "gtet": false, 62 | "eq": false, 63 | "neq": true, 64 | "feqNumber": true, 65 | "feqString": true, 66 | "fneqNumber": true, 67 | "fneqString": true, 68 | "ternaryEx": "10" 69 | } 70 | 71 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/concat.md: -------------------------------------------------------------------------------- 1 | The concat function concats two or more objects and gives an object back. 2 | 3 | #Syntax 4 | output = concat(expression, expression) 5 | 6 | ###Inputs 7 | **_expression_** : a reference to a variable or any [[expression|Expressions]]. 8 | 9 | ###Output 10 | **_output_** : a concatenated object from input. 11 | 12 | #Example flow 13 | 14 | Schema input1 { 15 | string a 16 | b [string c] 17 | d {string e} 18 | } 19 | 20 | Schema input2 { 21 | string p 22 | q [string r] 23 | s {string t} 24 | } 25 | 26 | Schema concatOutput { 27 | string result1 28 | result2 [ 29 | string op 30 | ] 31 | string result3 32 | string result4 33 | result5 [ 34 | string op 35 | ] 36 | string result6 37 | } 38 | 39 | value inputValue1 -> input1 { 40 | "hello" 41 | b[{"12345"}] 42 | d{ "V1-120-a3qteenpmrvmjzjm45hrlr"} 43 | } 44 | 45 | value inputValue2 -> input2 { 46 | "world" 47 | q[{"V1-120-a3qteenpmrvmjzjm45hrlr"}] 48 | s{"12345"} 49 | } 50 | 51 | Mapping concatMapping input inputValue1 as x, inputValue2 as y output concatOutput as op { 52 | op.result1 = concat(x.a,y.p) 53 | op.result2 = concat(x.b,y.q) 54 | op.result3 = concat(x.d.e,y.s.t) 55 | op.result4 = concat("",null) 56 | op.result5 = concat(x.b,null) 57 | op.result6 = concat(null,null) 58 | } 59 | 60 | ##Output for Example Flow 61 | 62 | { 63 | "result1": "helloworld", 64 | "result2": [ 65 | { 66 | "c": "12345" 67 | }, 68 | { 69 | "r": "V1-120-a3qteenpmrvmjzjm45hrlr" 70 | } 71 | ], 72 | "result3": "V1-120-a3qteenpmrvmjzjm45hrlr12345", 73 | "result4": "", 74 | "result5": [ 75 | { 76 | "c": "12345" 77 | } 78 | ], 79 | "result6": null 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/contains.md: -------------------------------------------------------------------------------- 1 | Given a string or a number, contains function will check for a specified substring in it. 2 | 3 | # Syntax 4 | output = contains(expression, searchText) 5 | 6 | ### Inputs 7 | **_expression_** : a reference to a variable or any [[expression|Expressions]]. 8 | 9 | **_searchText_** : A substring or a number to search from input expression value. 10 | 11 | ### Output 12 | **_output_** : A boolean depending on if substring is found or not in the input expression value. 13 | 14 | # Example flow 15 | Schema splitWordSchema { 16 | boolean containsInString 17 | boolean containsInNumber 18 | boolean containsStringNum 19 | boolean containsNumString 20 | } 21 | 22 | Schema wordSchema { 23 | string recipes 24 | string strNum 25 | number num 26 | } 27 | 28 | value dummyWord -> wordSchema { 29 | "GTKM=B&RTP=B" 30 | "GTKM=B&RTP=B89" 31 | 8766756 32 | } 33 | 34 | Mapping containsMapping input dummyWord as dummyWord output splitWordSchema { 35 | splitWordSchema.containsInString = contains(dummyWord.recipes, "RTP=B") 36 | splitWordSchema.containsInNumber = contains(dummyWord.num, 7) 37 | splitWordSchema.containsStringNum = contains(dummyWord.num, "7") 38 | splitWordSchema.containsNumString = contains(dummyWord.strNum, "8") 39 | } 40 | 41 | ## Output for Example Flow 42 | 43 | 44 | { 45 | "containsInString": true, 46 | "containsInNumber": true, 47 | "containsStringNum": true, 48 | "containsNumString": true 49 | } 50 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/currentDate.md: -------------------------------------------------------------------------------- 1 | #Syntax 2 | 3 | currentDate() will return date in mm/dd/yyyy format 4 | 5 | currentDate( dateFormat ) where dateFormat is any valid SimpleDateFormat will return date in that format 6 | 7 | currentDate('ms') will return date in milliseconds. Notice they're single quotes, not double quotes. 8 | 9 | 10 | #Output 11 | 12 | 11/09/2018 13 | 14 | 03:35:38 15 | 16 | 1541806538347 17 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/dayDifference.md: -------------------------------------------------------------------------------- 1 | #Syntax 2 | dayDifference(input1, input2, format) 3 | 4 | **_input1_** : Value of Date form which you want to subtract. 5 | 6 | **_input2_** : Value of Date to be subtracted. 7 | 8 | **_format_** : Format can be any input from the following pre defined formats but both the inputs need to be in same format. 9 | 10 | ### Formats 11 | MM/dd/yyyy 12 | yyyyMMdd 13 | yyyy-MM-dd 14 | 15 | 16 | 17 | #Example Flow 18 | 19 | Schema dummy1 { 20 | string a 21 | string b 22 | string c 23 | string d 24 | } 25 | 26 | Schema dummy2 { 27 | string p 28 | string q 29 | string r 30 | string s 31 | } 32 | 33 | Schema dummyOutput { 34 | number result1 35 | number result2 36 | number result3 37 | number result4 38 | number result5 39 | number result6 40 | } 41 | 42 | value dummyValue1 -> dummy1 { 43 | "10/16/1990" 44 | "10/16/2018" 45 | "20161209" 46 | "2000-11-2" 47 | } 48 | 49 | value dummyValue2 -> dummy2 { 50 | "10/16/1990" 51 | "10/19/2018" 52 | "20161215" 53 | "2000-11-12" 54 | } 55 | 56 | Mapping dummyMapping input dummyValue1 as x, dummyValue2 as y output dummyOutput as op { 57 | op.result1 = dayDifference(x.a, y.p, "MM/dd/yyyy") 58 | op.result2 = dayDifference(x.b, y.q, "MM/dd/yyyy") 59 | op.result3 = dayDifference(x.b, y.p, "MM/dd/yyyy") 60 | op.result4 = dayDifference(x.a, y.q, "MM/dd/yyyy") 61 | op.result5 = dayDifference(x.c, y.r, "yyyyMMdd") 62 | op.result6 = dayDifference(x.d, y.s, "yyyy-MM-dd") 63 | } 64 | 65 | End end 66 | 67 | Flow mappingFlow { 68 | Start dummyMapping { 69 | transition { 70 | true ? end : end 71 | } 72 | } 73 | end {} 74 | } 75 | 76 | #Example Output 77 | 78 | { 79 | "result1": 0, 80 | "result2": 3, 81 | "result3": -10227, 82 | "result4": 10230, 83 | "result5": 6, 84 | "result6": 10 85 | } -------------------------------------------------------------------------------- /mkdocs/docs/functions/filter.md: -------------------------------------------------------------------------------- 1 | The filter function filters the objects from an array based on some condition. 2 | 3 | # Syntax 4 | filteredArray = filter(array, booleanExpression) 5 | 6 | ### Inputs 7 | **_array_** : a reference to an array. 8 | 9 | **_booleanExpression_** : conditional expression to filter the objects in the array. 10 | 11 | ### Output 12 | **_filteredArray_** : filtered array based on the condition. 13 | 14 | # Example flow 15 | 16 | Schema w2Schema { 17 | w2 [ 18 | string employerName 19 | number wages 20 | ] 21 | } 22 | 23 | value income -> w2Schema { 24 | w2 [ 25 | { 26 | "Intuit, Inc. 27 | 105000 28 | } 29 | { 30 | "Uber 31 | 10000 32 | } 33 | ] 34 | } 35 | 36 | Schema thresholdSchema { 37 | number wages 38 | } 39 | 40 | value threshold -> thresholdSchema { 100000 } 41 | 42 | Mapping finalMapping input income, threshold output w2Schema as output { 43 | output.w2 = filter(income.w2, employerName == "Intuit, Inc." && wages > ::threshold.wages) 44 | } 45 | 46 | Flow filterFlow { 47 | Start finalMapping { 48 | } 49 | } 50 | 51 | ## Output for Example Flow 52 | { 53 | w2 : [{ employerName : "Intuit, Inc.", wages : 105000 } 54 | } 55 | 56 | ## Explanation 57 | 58 | The condition is `employerName == "Intuit, Inc." && wages > ::threshold.wages`. 59 | 60 | The first part of the condition says `employerName == "Intuit, Inc."`. The context of the variable **employerName** here is the array, which is **income.w2**. (You don't have to specify the whole path i.e `income.w2.employerName` to filter the w2s). 61 | 62 | The second part of the condition says `wages > ::threshold.wages"`. The variable **wages** here is within the context of w2 but if you want to refer something which is outside the scope of w2, you need to refer it with a global scope operator **::** 63 | 64 | 65 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/findFirst.md: -------------------------------------------------------------------------------- 1 | The findFirst function finds the first object from an array based on some condition. 2 | 3 | # Syntax 4 | firstValFound = findFirst(array, booleanExpression) 5 | 6 | ### Inputs 7 | **_array_** : a reference to an array. 8 | 9 | **_booleanExpression_** : conditional expression to find an object in the array. 10 | 11 | ### Output 12 | **_firstValFound_** : the first value in the array that caused the boolean expression to evaluate to true. 13 | 14 | # Example flow 15 | 16 | Schema w2Schema { 17 | w2 [ 18 | string employerName 19 | number wages 20 | ] 21 | } 22 | 23 | Schema Outcome { 24 | string employerName 25 | number wages 26 | } 27 | 28 | value income -> w2Schema { 29 | w2 [ 30 | { 31 | "Intuit, Inc. 32 | 105000 33 | } 34 | { 35 | "Uber 36 | 10000 37 | } 38 | ] 39 | } 40 | 41 | Schema thresholdSchema { 42 | number wages 43 | } 44 | 45 | value threshold -> thresholdSchema { 100000 } 46 | 47 | Mapping finalMapping input income, threshold output Outcome as output { 48 | output = findFirst(income.w2, employerName == "Intuit, Inc." && wages > ::threshold.wages) 49 | } 50 | 51 | Flow filterFlow { 52 | Start finalMapping { 53 | } 54 | } 55 | 56 | ## Output for Example Flow 57 | ``` 58 | { employerName : "Intuit, Inc.", wages : 105000 } 59 | ``` 60 | 61 | ## Explanation 62 | 63 | The condition is `employerName == "Intuit, Inc." && wages > ::threshold.wages`. 64 | 65 | The first part of the condition says `employerName == "Intuit, Inc."`. The context of the variable **employerName** here is the array, which is **income.w2**. (You don't have to specify the whole path i.e `income.w2.employerName` to filter the w2s). 66 | 67 | The second part of the condition says `wages > ::threshold.wages"`. The variable **wages** here is within the context of w2 but if you want to refer something which is outside the scope of w2, you need to refer it with a global scope operator **::** 68 | 69 | 70 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/join.md: -------------------------------------------------------------------------------- 1 | The join function joins an array based on the key with a delimiter and last_delimiter. 2 | 3 | # Syntax 4 | output = join(expression,key,delimiter,last_delimiter) 5 | 6 | ### Inputs 7 | **_expression_** : a reference to a variable or any [[expression|Expressions]]. This variable needs to be a json array or a string array 8 | 9 | **_key_** : This is optional. It represents the key if the expression is a json array. Skip this parameter in case of String array. 10 | 11 | **_delimiter_** : The delimiter to join on. 12 | 13 | **_last_delimiter_** : The last delimiter. 14 | 15 | ### Output 16 | **_output_** : The joined string. 17 | 18 | # Example flow 19 | Schema dependentsSchema { 20 | spouse { 21 | string name 22 | } 23 | children[ 24 | string name 25 | ] 26 | } 27 | 28 | Schema joinOutputSchema { 29 | string dependentsText 30 | } 31 | 32 | value dependents -> dependentsSchema { 33 | spouse { "Foo" } 34 | children [ 35 | { "A" } 36 | { "B" } 37 | { "C" } 38 | ] 39 | } 40 | 41 | Mapping finalMapping input dependents output joinOutputSchema { 42 | joinOutputSchema.dependentsText = join(dependents.children,name,",","and") 43 | } 44 | 45 | ## Output for Example Flow 46 | { 47 | "dependentsText" : "A, B and C" 48 | } -------------------------------------------------------------------------------- /mkdocs/docs/functions/json.md: -------------------------------------------------------------------------------- 1 | The json function converts the variable representing TSI xml data to a json. 2 | 3 | #Syntax 4 | output = json(expression) 5 | 6 | ###Inputs 7 | **_expression_** : a reference to a TSI variable with xml data. 8 | 9 | ###Output 10 | **_output_** : a json representation of the TSI data. 11 | 12 | #Example flow 13 | 14 | Schema outputSchema { 15 | op [ 16 | string HCY 17 | string HLY 18 | ] 19 | } 20 | 21 | Schema tsiSchema { 22 | S2016US1040PER { 23 | form FONLINE { 24 | field HCY 25 | field HLY 26 | field PRODTYPE 27 | } 28 | } 29 | } 30 | 31 | Service tsiService as getTsi input requestContext output tsiSchema {} 32 | 33 | Mapping finalMapping input tsiSchema output outputSchema { 34 | outputSchema.op = json(S2016US1040PER.FONLINE) 35 | } 36 | 37 | Flow tsiFlow { 38 | 39 | Start getTsi { 40 | transition { finalMapping{} } 41 | } 42 | finalMapping{} 43 | } 44 | 45 | ##Output for Example Flow 46 | { 47 | op : { HCLX : "b", HCLY : "a" } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/length.md: -------------------------------------------------------------------------------- 1 | The length function gives the length of an expression. The expression is mostly a variable 2 | 3 | #Syntax 4 | output = length(expression) 5 | 6 | ###Inputs 7 | **_expression_** : a reference to a variable or any [[expression|Expressions]]. 8 | 9 | ###Output 10 | **_output_** : a numerical value which represents the length of the input expression. 11 | 12 | #Example flow 13 | 14 | Schema dummy{ 15 | a [string b] 16 | } 17 | Schema dummyOutput{ 18 | number x 19 | } 20 | value dummyValue -> dummy { 21 | a[{"x"}{"y"}] 22 | } 23 | 24 | Mapping dummyMapping input dummyValue as p output dummyOutput as q { 25 | q.x = length(p.a) 26 | } 27 | 28 | ##Output for Example Flow 29 | { x : 2 } 30 | 31 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/map.md: -------------------------------------------------------------------------------- 1 | The map function is used to perform one to one mapping on elements from an array to a result array, after some processing or as is. 2 | 3 | # Syntax 4 | resultArray = map(array {Range} -> { 5 | result_attr_i1 = array_attr_k1 6 | result_attr_i2 = array_attr_k2 7 | }) 8 | 9 | ### Inputs 10 | **_array_** : a reference to an array. 11 | 12 | **_Range_** :This is an **_optional_** input giving a sequence of integers. Please refer [[Range]] for the syntax. Map function will only execute on elements in the input array at given sequence of indices. 13 | 14 | ### Output 15 | **_resultArray_** : Array returned after the mapping. 16 | 17 | # Example flow 18 | ``` 19 | Schema inputSchema { 20 | string a 21 | string b 22 | number c 23 | boolean d 24 | object { 25 | string a 26 | string b 27 | } 28 | array [ 29 | string a 30 | string b 31 | string c 32 | number d 33 | ] 34 | } 35 | 36 | value inputValue -> inputSchema { 37 | "A" 38 | "B" 39 | 1 40 | true 41 | object { 42 | "a" 43 | "b" 44 | } 45 | array [ 46 | { 47 | "a" 48 | "a" 49 | "c" 50 | 100 51 | } 52 | { 53 | "a" 54 | "b" 55 | "c" 56 | 10 57 | } 58 | { 59 | "a" 60 | "b" 61 | "c" 62 | 1 63 | } 64 | { 65 | "a" 66 | "b" 67 | "c" 68 | 0 69 | } 70 | ] 71 | } 72 | 73 | Schema outputSchema { 74 | mapArray [ 75 | string name 76 | string desc 77 | string amount 78 | ] 79 | mapObject { 80 | string name 81 | string value 82 | } 83 | mapArrayWithRange [ 84 | string name 85 | string desc 86 | string amount 87 | ] 88 | 89 | } 90 | 91 | Mapping outPutMapping input inputValue as inputValue output outputSchema { 92 | 93 | outputSchema.mapArray = map(inputValue.array->{ 94 | name = a 95 | desc = b 96 | amount = d 97 | }) 98 | 99 | outputSchema.mapArrayWithRange = map(inputValue.array{0..1}->{ 100 | name = a 101 | desc = b 102 | amount = d 103 | }) 104 | 105 | outputSchema.mapObject = map(inputValue.object->{ 106 | name = a 107 | value = b 108 | }) 109 | } 110 | 111 | Flow mapFlow { 112 | Start outPutMapping{} 113 | } 114 | 115 | 116 | Output: 117 | { 118 | "mapArray": 119 | [ 120 | { 121 | "name": "a", 122 | "desc": "a", 123 | "amount": 100 124 | }, 125 | { 126 | "name": "a", 127 | "desc": "b", 128 | "amount": 10 129 | }, 130 | { 131 | "name": "a", 132 | "desc": "b", 133 | "amount": 1 134 | }, 135 | { 136 | "name": "a", 137 | "desc": "b", 138 | "amount": 0 139 | } 140 | ], 141 | "mapObject": 142 | { 143 | "name": "a", 144 | "value": "b" 145 | } 146 | "mapArrayWithRange": 147 | [ 148 | { 149 | "name": "a", 150 | "desc": "a", 151 | "amount": 100 152 | }, 153 | { 154 | "name": "a", 155 | "desc": "b", 156 | "amount": 10 157 | } 158 | ] 159 | } 160 | 161 | ``` 162 | 163 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/pickFirst.md: -------------------------------------------------------------------------------- 1 | The pickFirst function picks the first object from various provided objects based on some condition. 2 | 3 | # Syntax 4 | firstValuePicked = pickFirst(object1, object2,... -> booleanExpression) 5 | 6 | ### Inputs 7 | **_objects_** : comma separated 1 or more objects 8 | 9 | **_booleanExpression_** : conditional expression that applies to current object. (eg: **_it_** > 100) 10 | 11 | ### Output 12 | **_firstValuePicked_** : the first object value that caused the boolean expression to evaluate to true. 13 | 14 | # Example flow 15 | 16 | Schema triageSchema { 17 | coreProfile { 18 | number taxYear 19 | } 20 | } 21 | 22 | Schema requestContext { 23 | number taxYear 24 | } 25 | 26 | value triageValue -> triageSchema { 27 | coreProfile { 28 | 1980 29 | } 30 | } 31 | 32 | value requestContextValue -> requestContext { 2015 } 33 | 34 | Schema result { 35 | number taxYear 36 | } 37 | 38 | Mapping finalMapping input triageValue, requestContextValue output result { 39 | result.taxYear = pickFirst(triageValue.coreProfile.taxYear, requestContextValue.taxYear -> it>2000) 40 | } 41 | 42 | Flow filterFlow { 43 | Start finalMapping { 44 | } 45 | } 46 | 47 | ## Output for Example Flow 48 | ``` 49 | { taxYear : 2015 } 50 | ``` 51 | 52 | 53 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/remove.md: -------------------------------------------------------------------------------- 1 | The remove function essentially works as an inverse to the filter function. It takes an array and a boolean expression and returns a filtered array containing only the elements that **don't** match the expression. 2 | ### See [[filter]] for info on how the function behaves. -------------------------------------------------------------------------------- /mkdocs/docs/functions/shuffle.md: -------------------------------------------------------------------------------- 1 | This function builds a new shuffled array from a given array. Shuffled array means the order of elements in the array is changed in random manner. It works only on collection. Doesn't work on primitive types like String, Int etc 2 | 3 | # Syntax 4 | shuffledArray = shuffle(array) 5 | 6 | ### Inputs 7 | **_array_** : a reference to an array. 8 | 9 | ### Output 10 | **_shuffledArray_** : shuffled array 11 | 12 | # Example flow 13 | ``` 14 | Schema companyData { 15 | employees [ 16 | number id 17 | string name 18 | string city 19 | ] 20 | } 21 | 22 | value employeeData -> companyData { 23 | employees [ 24 | { 25 | 321 26 | "John" 27 | "San diego" 28 | } 29 | { 30 | 534 31 | "Alex" 32 | "New York" 33 | } 34 | { 35 | 456 36 | "Sam" 37 | "Seattle" 38 | } 39 | ] 40 | numberArray [ 41 | 1 42 | 2 43 | 3 44 | 4 45 | ] 46 | shuffleString: "abcd" 47 | shuffleNumber: 1234 48 | shuffleNull: ${null} 49 | } 50 | 51 | Mapping sortMapping input employeeData as empData output companyData as resultSchema { 52 | resultSchema.employees = shuffle(empData.employees) 53 | resultSchema.numberArray = shuffle(empData.numberArray) 54 | resultSchema.shuffleString = shuffle(empData.shuffleString) 55 | resultSchema.shuffleNumber = shuffle(empData.shuffleNumber) 56 | resultSchema.shuffleNull = shuffle(empData.shuffleNull) 57 | } 58 | 59 | Flow Shuffle { 60 | Start shuffleMapping {} 61 | } 62 | ``` 63 | 64 | ## Output for Example Flow 65 | ``` 66 | { 67 | "employees": [ 68 | { 69 | "id": 534, 70 | "name": "Alex", 71 | "city": "New York" 72 | }, 73 | { 74 | "id": 321, 75 | "name": "John", 76 | "city": "San diego" 77 | }, 78 | { 79 | "id": 456, 80 | "name": "Sam", 81 | "city": "Seattle" 82 | } 83 | ], 84 | "numberArray": [ 85 | 4, 86 | 1, 87 | 3, 88 | 2 89 | ], 90 | "shuffleString": "abcd", 91 | "shuffleNumber": 1234, 92 | "shuffleNull": null 93 | } 94 | ``` 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/sort.md: -------------------------------------------------------------------------------- 1 | This function builds a new sorted list from a given list. It has a key parameter to specify the attribute to be used to make comparison from each element in list. 2 | 3 | # Syntax 4 | sortedArray = sort(array, schemaVariable) 5 | sortedArray = sort(array, schemaVariable, orderType) 6 | 7 | ### Inputs 8 | **_array_** : a reference to an array. 9 | 10 | **_schemaVariable_** : object’s attribute to be used for comparison. 11 | 12 | **_orderType_** : optional parameter to specify `ascending` (default value) or `descending` order 13 | 14 | 15 | ### Output 16 | **_sortedArray_** : sorted array based on the **_orderType_**. 17 | 18 | # Example flow 19 | ``` 20 | Schema companyData { 21 | employees [ 22 | number id 23 | string name 24 | string city 25 | ] 26 | } 27 | 28 | value employeeData -> companyData { 29 | employees [ 30 | { 31 | 321 32 | "Bhavin" 33 | "San diego" 34 | } 35 | { 36 | 534 37 | "Alex" 38 | "New York" 39 | } 40 | { 41 | 456 42 | "Sam" 43 | "Seattle" 44 | } 45 | ] 46 | } 47 | 48 | Schema ResultSchema { 49 | sortById -> companyData 50 | reverseSortById -> companyData 51 | } 52 | 53 | Mapping sortMapping input employeeData as empData output ResultSchema { 54 | ResultSchema.sortById.employees = sort(empData.employees, id) 55 | ResultSchema.reverseSortById.employees = sort(empData.employees, id, descending) 56 | } 57 | 58 | Flow Sort { 59 | Start sortMapping { 60 | } 61 | } 62 | ``` 63 | 64 | ## Output for Example Flow 65 | ``` 66 | { 67 | "sortById": { 68 | "employees": [ 69 | { 70 | "id": 321, 71 | "name": "Bhavin", 72 | "city": "San diego" 73 | }, 74 | { 75 | "id": 456, 76 | "name": "Sam", 77 | "city": "Seattle" 78 | }, 79 | { 80 | "id": 534, 81 | "name": "Alex", 82 | "city": "New York" 83 | } 84 | ] 85 | }, 86 | "reverseSortById": { 87 | "employees": [ 88 | { 89 | "id": 534, 90 | "name": "Alex", 91 | "city": "New York" 92 | }, 93 | { 94 | "id": 456, 95 | "name": "Sam", 96 | "city": "Seattle" 97 | }, 98 | { 99 | "id": 321, 100 | "name": "Bhavin", 101 | "city": "San diego" 102 | } 103 | ] 104 | } 105 | } 106 | ``` 107 | 108 | ## Explanation 109 | 110 | The context of the variable **_id_** here is the array, which is **_empData.employees_**. (You don't have to specify the whole path i.e `empData.employees.id` to sort using the id for comparison). 111 | 112 | In order to sort the array in reverse using the id, The parameter `descending` is passed. There is no need to pass an `ascending` parameter as by default the array is sorted in ascending order. 113 | 114 | 115 | -------------------------------------------------------------------------------- /mkdocs/docs/functions/split.md: -------------------------------------------------------------------------------- 1 | The split function splits a string based on the splitter given and saves the result in an array. 2 | 3 | #Syntax 4 | output = split(expression, splitter) 5 | 6 | ###Inputs 7 | **_expression_** : a reference to a variable or any [[expression|Expressions]]. 8 | **_splitter_** : a string or a character based on which you want to split the string 9 | 10 | ###Output 11 | **_output_** : an array of strings resulted from splitting input. 12 | 13 | #Example flow 14 | 15 | Schema splitWordSchema { 16 | splitWord1 [string word1] 17 | splitWord2 [string word1] 18 | splitWord3 [string word1] 19 | splitWord4 [string word1] 20 | splitWord5 [string word1] 21 | splitWord6 [string word1] 22 | } 23 | 24 | Schema wordSchema { 25 | string word1 26 | string word2 27 | string word3 28 | string word4 29 | string wordSplit 30 | } 31 | 32 | value dummyWord -> wordSchema { 33 | "a|b|c" 34 | "a.b.c" 35 | "[CS]v1|2C0872A1051D7A42-6000190C600082FB[CE]" 36 | "null" 37 | } 38 | 39 | 40 | Mapping splitMapping input dummyWord as dummyWord output splitWordSchema { 41 | splitWordSchema.splitWord1 = if(contains(dummyWord.word1,"a")) then split(dummyWord.word1,"\\|") else null 42 | splitWordSchema.splitWord2 = split(dummyWord.word2,"\\.") 43 | splitWordSchema.splitWord3 = split(dummyWord.word3,"\\|") 44 | splitWordSchema.splitWord4 = if(!contains(dummyWord.word4,"a")) then split(dummyWord.word4,"\\|") else null 45 | splitWordSchema.splitWord5 = split(dummyWord.word1,"\\.") 46 | splitWordSchema.splitWord6 = split(splitWordSchema.splitWord3[1],"\\[") 47 | } 48 | 49 | ##Output for Example Flow 50 | 51 | { 52 | "splitWord1": [ 53 | "a", 54 | "b", 55 | "c" 56 | ], 57 | "splitWord2": [ 58 | "a", 59 | "b", 60 | "c" 61 | ], 62 | "splitWord3": [ 63 | "[CS]v1", 64 | "2C0872A1051D7A42-6000190C600082FB[CE]" 65 | ], 66 | "splitWord4": { 67 | "word1": null 68 | }, 69 | "splitWord5": [ 70 | "a|b|c" 71 | ], 72 | "splitWord6": [ 73 | "2C0872A1051D7A42-6000190C600082FB", 74 | "CE]" 75 | ] 76 | } -------------------------------------------------------------------------------- /mkdocs/docs/img/common-xtext-expression-language-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intuit/common-xtext-expression-language/44a9ce7bc5d7a43d5252c453c622d8a3cc013420/mkdocs/docs/img/common-xtext-expression-language-logo.png -------------------------------------------------------------------------------- /mkdocs/docs/index.md: -------------------------------------------------------------------------------- 1 | # Common-Expression-Language 2 | ![common-xtext-expression-language logo](./img/common-xtext-expression-language-logo.png) 3 | 4 | The project provides an expression language built using [Xtext](https://www.eclipse.org/Xtext/index.html) and a runtime engine to evaluate the expressions. 5 | The expression grammar can be imported in other Xtext DSLs to create composable and reusable languages using Xtext. 6 | 7 | # Usage 8 | 9 | 1. Add the maven dependency 10 | ```xml 11 | com.intuit.dsl.expression 12 | com.intuit.dsl.expression.runtime 13 | ${latest} 14 | ``` 15 | 2. Code usage 16 | 17 | ```java 18 | DataValue value = ExpressionRuntime.newExpressionRuntime() 19 | .withExpressionContent(expressionString) 20 | .evaluate(); 21 | ``` 22 | 23 | # Setting up the Project 24 | 25 | ### Pre-requisites 26 | 27 | 1. Java 8 28 | 2. Maven 3 29 | 30 | ### Making changes to Runtime 31 | 32 | * Clone [common-xtext-expression-language](https://github.com/intuit/common-xtext-expression-language) 33 | * Run `maven clean install` 34 | * Import the runtime module `com.intuit.dsl.expression.runtime`. This is standard java project which can be imported in your 35 | favorite editor. 36 | 37 | ### Making changes to Expression Grammar 38 | 39 | 1. Download and install Eclipse [MAC](https://www.eclipse.org/downloads/download.php?file=/oomph/epp/2019-03/R/eclipse-inst-mac64.dmg) 40 | / [Windows](https://www.eclipse.org/downloads/download.php?file=/oomph/epp/2019-03/R/eclipse-inst-win64.exe) 41 | / [Linux](https://www.eclipse.org/downloads/download.php?file=/oomph/epp/2019-03/R/eclipse-inst-linux64.tar.gz). 42 | 2. Install Xtext SDK in Eclipse: 43 | a. In Eclipse, click Help --> Install New Software. 44 | b. In Available Software, click Add to add a repository with the following location 45 | http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/ 46 | c. Select the repository just added in 'Work with' dropdown. 47 | d. Select and install Xtext Complete SDK. 48 | 3. Restart Eclipse. 49 | 4. Edit the [grammar](https://github.com/intuit/common-xtext-expression-language/blob/master/com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/Expression.xtext) 50 | 5. Right click on [GenerateExpression.mwe2](https://github.com/intuit/common-xtext-expression-language/blob/master/com.intuit.dsl.expression.parent/com.intuit.dsl.expression/src/com/intuit/dsl/GenerateExpression.mwe2). 51 | Run As --> 1 MWE2 Workflow. 52 | 53 | OR 54 | 55 | `mvn clean install` inside the project 56 | 57 | You should be able to use the grammar changes in your runtime. 58 | 59 | ## Formatting 60 | Read the [Contribution guide](./CONTRIBUTING.md) 61 | -------------------------------------------------------------------------------- /mkdocs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Common Xtext Expression Language Documentation 2 | site_description: Common Xtext Expression Language Documentation 3 | docs_dir: docs 4 | theme: 5 | name: material 6 | # logo: 7 | # icon: home 8 | font: 9 | text: Work Sans 10 | code: Menlo 11 | favicon: img/graphql.ico 12 | extra_css: ["css/css-override.css"] 13 | repo_url: "https://github.com/intuit/common-xtext-expression-language.git" 14 | repo_name: 'common-xtext-expression-language' 15 | copyright: 'Copyright © 2021 Intuit' 16 | 17 | markdown_extensions: 18 | - markdown.extensions.admonition 19 | - markdown.extensions.codehilite: 20 | guess_lang: true 21 | - markdown.extensions.def_list 22 | - markdown.extensions.footnotes 23 | - markdown.extensions.meta 24 | - markdown.extensions.toc: 25 | permalink: true 26 | - pymdownx.arithmatex 27 | - pymdownx.betterem: 28 | smart_enable: all 29 | - pymdownx.caret 30 | - pymdownx.critic 31 | - pymdownx.details 32 | - pymdownx.emoji: 33 | emoji_generator: !!python/name:pymdownx.emoji.to_svg 34 | - pymdownx.inlinehilite 35 | - pymdownx.keys 36 | - pymdownx.magiclink 37 | - pymdownx.mark 38 | - pymdownx.smartsymbols 39 | - pymdownx.superfences 40 | - pymdownx.tasklist: 41 | custom_checkbox: true 42 | - pymdownx.tilde 43 | 44 | nav: 45 | - Home: index.md 46 | - Expressions: 47 | - Arithmetic: expressions/Arithmetic.md 48 | - Boolean: expressions/Boolean.md 49 | - Conditional: expressions/Conditional.md 50 | - Functions: 51 | - Join: functions/join.md 52 | - Length: functions/length.md 53 | - Filter: functions/filter.md 54 | - Concat: functions/concat.md 55 | - DateFormat: functions/dateFormat.md 56 | - Json: functions/json.md 57 | - Split: functions/split.md 58 | - Contains: functions/contains.md 59 | - DayDifference: functions/dayDifference.md 60 | - CurrentDate: functions/currentDate.md 61 | - FindFirst: functions/findFirst.md 62 | - PickFirst: functions/pickFirst.md 63 | - Remove: functions/remove.md 64 | - Extract: functions/extract.md 65 | - Sort: functions/sort.md 66 | - Shuffle: functions/shuffle.md 67 | - Dedup: functions/dedup.md 68 | - Map: functions/map.md 69 | 70 | 71 | -------------------------------------------------------------------------------- /mkdocs/readme.md: -------------------------------------------------------------------------------- 1 | 1. Run `pip3 install -Ur requirements.txt` 2 | 2. For local development: `mkdocs serve` 3 | 3. To push to github: `mkdocs gh-deploy` -------------------------------------------------------------------------------- /mkdocs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs 2 | mkdocs-material 3 | backports-abc 4 | Click 5 | Jinja2 6 | livereload 7 | Markdown 8 | MarkupSafe 9 | Pygments 10 | pymdown-extensions 11 | PyYAML 12 | singledispatch 13 | tornado -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | scm:git:https://github.com/intuit/common-xtext-expression-language 6 | https://github.com/intuit/common-xtext-expression-language 7 | HEAD 8 | 9 | 10 | com.intuit.dsl 11 | common-xtext-expression-language 12 | 1.0.4-SNAPSHOT 13 | Simple Expression DSL 14 | ${project.artifactId} 15 | https://github.com/intuit/common-xtext-expression-language 16 | pom 17 | 18 | 19 | Apache 2.0 20 | https://www.apache.org/licenses/LICENSE-2.0.txt 21 | 22 | 23 | 24 | 25 | 26 | Ashpak Shaikh 27 | Shaikh 28 | Intuit, Inc. 29 | http://www.intuit.com 30 | 31 | 32 | 33 | UTF-8 34 | 1.8 35 | 1.8 36 | 37 | 38 | 39 | 40 | 41 | 42 | com.intuit.dsl.expression.parent 43 | 44 | 45 | 46 | codehaus-snapshots 47 | http://nexus.codehaus.org/snapshots/ 48 | 49 | 50 | Xtext Update Site 51 | p2 52 | http://download.eclipse.org/modeling/tmf/xtext/updates/releases/${xtextVersion}/ 53 | 54 | 55 | 56 | 57 | 58 | release 59 | 60 | 61 | 62 | org.apache.maven.plugins 63 | maven-gpg-plugin 64 | 1.5 65 | 66 | 67 | sign-artifacts 68 | verify 69 | 70 | sign 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | ossrh 82 | https://oss.sonatype.org/content/repositories/snapshots 83 | 84 | 85 | ossrh 86 | https://oss.sonatype.org/service/local/staging/deploy/maven2 87 | 88 | 89 | 90 | --------------------------------------------------------------------------------