You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by ra...@apache.org on 2023/11/22 11:27:52 UTC
(incubator-kie-tools-temporary-rnd-do-not-use) 01/01: KOGITO-9195: YaRD editor validation (#1696)
This is an automated email from the ASF dual-hosted git repository.
rantunes pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools-temporary-rnd-do-not-use.git
commit 687c32adc4e099f9724d45259bc0c2a40d63d91e
Author: Toni Rikkola <to...@rikkola.net>
AuthorDate: Tue Nov 21 18:54:49 2023 +0000
KOGITO-9195: YaRD editor validation (#1696)
---
packages/serverless-logic-web-tools/package.json | 1 +
.../src/editor/EditorPage.tsx | 8 +-
.../src/editor/EditorToolbar.tsx | 28 +-
.../src/editor/hooks/useEditorNotifications.tsx | 14 +-
.../serverless-logic-web-tools/webpack.config.ts | 4 +
packages/yard-editor/dev-webapp/webpack.config.js | 4 +
packages/yard-editor/package.json | 1 +
packages/yard-editor/src/editor/YardEditorView.tsx | 21 +-
packages/yard-model/LICENSE | 201 +++++++++++++
packages/yard-model/env/index.js | 31 ++
packages/yard-model/install.js | 25 ++
packages/yard-model/package.json | 48 +++
packages/yard-model/pom.xml | 97 +++++++
.../main/java/org/yard/model/DecisionLogic.java | 32 ++
.../main/java/org/yard/model/DecisionTable.java | 72 +++++
.../src/main/java/org/yard/model/Element.java | 65 +++++
.../src/main/java/org/yard/model/InlineRule.java | 45 +++
.../src/main/java/org/yard/model/Input.java | 44 +++
.../java/org/yard/model/LiteralExpression.java | 35 +++
.../src/main/java/org/yard/model/Operators.java | 49 ++++
.../src/main/java/org/yard/model/Rule.java | 23 ++
.../java/org/yard/model/RuleDefSerializer.java | 88 ++++++
.../src/main/java/org/yard/model/WhenThenRule.java | 53 ++++
.../org/yard/model/WhenThenRuleThenSerializer.java | 56 ++++
.../src/main/java/org/yard/model/YaRD.java | 83 ++++++
packages/yard-validator-worker/README.md | 22 ++
packages/yard-validator-worker/demo/demo.html | 72 +++++
packages/yard-validator-worker/env/index.js | 31 ++
packages/yard-validator-worker/install.js | 25 ++
packages/yard-validator-worker/package.json | 50 ++++
packages/yard-validator-worker/pom.xml | 105 +++++++
.../java/org/yard/validator/CustomTreeSet.java | 121 ++++++++
.../src/main/java/org/yard/validator/Issue.java | 49 ++++
.../src/main/java/org/yard/validator/Parser.java | 236 +++++++++++++++
.../main/java/org/yard/validator/ParserResult.java | 46 +++
.../main/java/org/yard/validator/ReportBus.java | 23 ++
.../java/org/yard/validator/YardValidator.java | 97 +++++++
.../src/main/java/org/yard/validator/app.js | 34 +++
.../main/java/org/yard/validator/checks/Check.java | 27 ++
.../java/org/yard/validator/checks/CheckItem.java | 57 ++++
.../org/yard/validator/checks/CheckProducer.java | 136 +++++++++
.../java/org/yard/validator/checks/RunBundle.java | 39 +++
.../yard/validator/checks/SubsumptionCheck.java | 265 +++++++++++++++++
.../java/org/yard/validator/key/ColumnKey.java | 58 ++++
.../src/main/java/org/yard/validator/key/Key.java | 29 ++
.../main/java/org/yard/validator/key/KeyImpl.java | 46 +++
.../java/org/yard/validator/key/KeyParent.java | 28 ++
.../main/java/org/yard/validator/key/Location.java | 27 ++
.../java/org/yard/validator/key/ObjectKey.java | 40 +++
.../org/yard/validator/key/OperatorValueKey.java | 50 ++++
.../java/org/yard/validator/key/RowLocation.java | 49 ++++
.../java/org/yard/validator/runner/Runner.java | 48 +++
.../java/org/yard/validator/util/Callback.java | 26 ++
.../main/java/org/yard/validator/util/Date.java | 72 +++++
.../main/java/org/yard/validator/util/Logger.java | 41 +++
.../test/java/org/yard/validator/ParserTest.java | 84 ++++++
.../java/org/yard/validator/YardValidatorTest.java | 161 ++++++++++
.../java/org/yard/validator/util/DateTest.java | 66 +++++
.../resources/org/yard/validator/redundancy.yml | 26 ++
.../resources/org/yard/validator/service-price.yml | 24 ++
.../yard/validator/subsumption-the-other-way.yml | 29 ++
.../resources/org/yard/validator/subsumption.yml | 29 ++
.../yard/validator/traffic-violation-empty-row.yml | 29 ++
.../org/yard/validator/traffic-violation.yml | 28 ++
packages/yard-validator/README.md | 8 +
packages/yard-validator/env/index.js | 31 ++
packages/yard-validator/install.js | 25 ++
packages/yard-validator/package.json | 44 +++
packages/yard-validator/src/ValidationResult.ts | 32 ++
packages/yard-validator/src/index.ts | 20 ++
packages/yard-validator/src/main.ts | 55 ++++
packages/yard-validator/tsconfig.json | 9 +
pnpm-lock.yaml | 323 +++++++++------------
repo/graph.dot | 8 +
repo/graph.json | 11 +
75 files changed, 3923 insertions(+), 196 deletions(-)
diff --git a/packages/serverless-logic-web-tools/package.json b/packages/serverless-logic-web-tools/package.json
index 33748eba73..e81da92dcd 100644
--- a/packages/serverless-logic-web-tools/package.json
+++ b/packages/serverless-logic-web-tools/package.json
@@ -54,6 +54,7 @@
"@kie-tools/text-editor": "workspace:*",
"@kie-tools/yard-editor": "workspace:*",
"@kie-tools/yard-language-service": "workspace:*",
+ "@kie-tools/yard-validator": "workspace:*",
"@octokit/plugin-rest-endpoint-methods": "^5.0.1",
"@octokit/rest": "^18.5.3",
"@patternfly/patternfly": "^4.224.2",
diff --git a/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx b/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx
index b1164c9400..f259600546 100644
--- a/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx
+++ b/packages/serverless-logic-web-tools/src/editor/EditorPage.tsx
@@ -71,7 +71,7 @@ export function EditorPage(props: Props) {
const queryParams = useQueryParams();
const alertsDispatch = useGlobalAlertsDispatchContext();
- const notifications = useEditorNotifications({
+ const { notifications, onLazyValidate } = useEditorNotifications({
webToolsEditor,
content: lastContent.current,
fileRelativePath: props.fileRelativePath,
@@ -234,7 +234,11 @@ export function EditorPage(props: Props) {
resolved={(file) => (
<>
<Page>
- <EditorToolbar workspaceFile={file.workspaceFile} editor={webToolsEditor?.editor} />
+ <EditorToolbar
+ workspaceFile={file.workspaceFile}
+ editor={webToolsEditor?.editor}
+ onValidate={onLazyValidate}
+ />
<Divider />
<EditorPageDockDrawer
ref={editorPageDockRef}
diff --git a/packages/serverless-logic-web-tools/src/editor/EditorToolbar.tsx b/packages/serverless-logic-web-tools/src/editor/EditorToolbar.tsx
index 60ab0e40cd..83b12ebd2a 100644
--- a/packages/serverless-logic-web-tools/src/editor/EditorToolbar.tsx
+++ b/packages/serverless-logic-web-tools/src/editor/EditorToolbar.tsx
@@ -43,6 +43,7 @@ import {
import { Tooltip } from "@patternfly/react-core/dist/js/components/Tooltip";
import { Flex, FlexItem } from "@patternfly/react-core/dist/js/layouts/Flex";
import { AngleLeftIcon } from "@patternfly/react-icons/dist/js/icons/angle-left-icon";
+import { PlayIcon } from "@patternfly/react-icons/dist/js/icons/play-icon";
import { ArrowCircleUpIcon } from "@patternfly/react-icons/dist/js/icons/arrow-circle-up-icon";
import { CaretDownIcon } from "@patternfly/react-icons/dist/js/icons/caret-down-icon";
import { OutlinedHddIcon } from "@patternfly/react-icons/dist/js/icons/outlined-hdd-icon";
@@ -104,6 +105,7 @@ import { ConfirmDeleteModal } from "../table";
export interface Props {
editor: EmbeddedEditorRef | undefined;
workspaceFile: WorkspaceFile;
+ onValidate: () => void;
}
const showWhenSmall: ToolbarItemProps["visibility"] = {
@@ -938,6 +940,24 @@ If you are, it means that creating this Gist failed and it can safely be deleted
);
}, [workspaces, props.workspaceFile, githubAuthInfo, comittingAlert, commitSuccessAlert]);
+ const validateDropdownItem = useMemo(() => {
+ return isOfKind("yard", props.workspaceFile.name)
+ ? [
+ <DropdownItem
+ key={"validate-dropdown-item"}
+ icon={<PlayIcon />}
+ onClick={async () => {
+ props.onValidate();
+ }}
+ description={"Run model validation"}
+ ouiaId={"commit-button"}
+ >
+ Validate
+ </DropdownItem>,
+ ]
+ : [];
+ }, [props]);
+
const pushSuccessAlert = useGlobalAlert(
useCallback(
({ close }) => {
@@ -1724,7 +1744,12 @@ If you are, it means that creating this Gist failed and it can safely be deleted
<KebabDropdown
id={"kebab-lg"}
state={[isLargeKebabOpen, setLargeKebabOpen]}
- items={[deleteFileDropdownItem, <Divider key={"divider-0"} />, createSavePointDropdownItem]}
+ items={[
+ deleteFileDropdownItem,
+ <Divider key={"divider-0"} />,
+ createSavePointDropdownItem,
+ ...validateDropdownItem,
+ ]}
/>
</ToolbarItem>
<ToolbarItem visibility={showWhenSmall} style={{ marginRight: 0 }}>
@@ -1735,6 +1760,7 @@ If you are, it means that creating this Gist failed and it can safely be deleted
deleteFileDropdownItem,
<Divider key={"divider-0"} />,
createSavePointDropdownItem,
+ ...validateDropdownItem,
<Divider key={"divider-1"} />,
...shareDropdownItems,
...(!canBeDeployed
diff --git a/packages/serverless-logic-web-tools/src/editor/hooks/useEditorNotifications.tsx b/packages/serverless-logic-web-tools/src/editor/hooks/useEditorNotifications.tsx
index e6d75a4936..220e9ac1e9 100644
--- a/packages/serverless-logic-web-tools/src/editor/hooks/useEditorNotifications.tsx
+++ b/packages/serverless-logic-web-tools/src/editor/hooks/useEditorNotifications.tsx
@@ -33,12 +33,20 @@ interface HookArgs {
export function useEditorNotifications(args: HookArgs) {
const { webToolsEditor, content, fileRelativePath } = { ...args };
const [notifications, setNotifications] = useState<Notification[]>([]);
+ const [lazyNotifications, setLazyNotifications] = useState<Notification[]>([]);
const editorDispatch = useEditorDispatch();
useEffect(() => {
editorDispatch.setNotifications(notifications);
}, [editorDispatch, notifications]);
+ const onLazyValidate = useCallback(async () => {
+ if (!webToolsEditor?.editor) {
+ return;
+ }
+ setLazyNotifications(await webToolsEditor.editor.validate());
+ }, [webToolsEditor]);
+
useCancelableEffect(
useCallback(
({ canceled }) => {
@@ -70,13 +78,13 @@ export function useEditorNotifications(args: HookArgs) {
},
} as Notification)
);
- setNotifications(mappedDiagnostics);
+ setNotifications([...mappedDiagnostics, ...lazyNotifications]);
})
.catch((e) => console.error(e));
},
- [content, fileRelativePath, webToolsEditor]
+ [content, fileRelativePath, webToolsEditor, lazyNotifications]
)
);
- return notifications;
+ return { notifications, onLazyValidate };
}
diff --git a/packages/serverless-logic-web-tools/webpack.config.ts b/packages/serverless-logic-web-tools/webpack.config.ts
index 9d996a5520..7de03b0bad 100644
--- a/packages/serverless-logic-web-tools/webpack.config.ts
+++ b/packages/serverless-logic-web-tools/webpack.config.ts
@@ -149,6 +149,10 @@ export default async (env: any, argv: any) => {
to: "./dashbuilder-client",
globOptions: { ignore: ["**/WEB-INF/**/*"] }, // "**/*.html" omitted because dashbuilder-client/index.html is needed
},
+ {
+ from: path.resolve(__dirname, "node_modules/@kie-tools/yard-validator/dist/yard-validator-worker.js"),
+ to: "./yard-validator-worker.js",
+ },
],
}),
new ProvidePlugin({
diff --git a/packages/yard-editor/dev-webapp/webpack.config.js b/packages/yard-editor/dev-webapp/webpack.config.js
index f03f967422..168d29d76e 100644
--- a/packages/yard-editor/dev-webapp/webpack.config.js
+++ b/packages/yard-editor/dev-webapp/webpack.config.js
@@ -46,6 +46,10 @@ module.exports = (env) =>
from: path.resolve(__dirname, "./static/envelope/yard-editor-envelope.html"),
to: "./yard-editor-envelope.html",
},
+ {
+ from: path.resolve(__dirname, "../node_modules/@kie-tools/yard-validator/dist/yard-validator-worker.js"),
+ to: "./yard-validator-worker.js",
+ },
],
}),
new MonacoWebpackPlugin({
diff --git a/packages/yard-editor/package.json b/packages/yard-editor/package.json
index 9b989a3422..1b1100d20d 100644
--- a/packages/yard-editor/package.json
+++ b/packages/yard-editor/package.json
@@ -38,6 +38,7 @@
"@kie-tools-core/workspace": "workspace:*",
"@kie-tools/i18n-common-dictionary": "workspace:*",
"@kie-tools/yard-language-service": "workspace:*",
+ "@kie-tools/yard-validator": "workspace:*",
"@patternfly/react-core": "^4.276.6",
"@patternfly/react-icons": "^4.93.6",
"@types/js-yaml": "^4.0.5",
diff --git a/packages/yard-editor/src/editor/YardEditorView.tsx b/packages/yard-editor/src/editor/YardEditorView.tsx
index f8059fa021..6ebe4f89d1 100644
--- a/packages/yard-editor/src/editor/YardEditorView.tsx
+++ b/packages/yard-editor/src/editor/YardEditorView.tsx
@@ -22,6 +22,7 @@ import * as React from "react";
import { YardEditor } from "./YardEditor";
import { YardEditorApi, YardEditorChannelApi } from "../api";
import { Position } from "monaco-editor";
+import { validationPromise } from "@kie-tools/yard-validator/dist/";
export class YardEditorView implements Editor {
private readonly editorRef: React.RefObject<YardEditorApi>;
@@ -29,6 +30,7 @@ export class YardEditorView implements Editor {
public af_isReact = true;
public af_componentId: "yard-editor";
public af_componentTitle: "Yard Editor";
+ private path: string;
constructor(
private readonly envelopeContext: KogitoEditorEnvelopeContextType<YardEditorChannelApi>,
@@ -37,8 +39,8 @@ export class YardEditorView implements Editor {
this.editorRef = React.createRef<YardEditorApi>();
this.initArgs = initArgs;
}
-
public setContent(path: string, content: string): Promise<void> {
+ this.path = path;
return this.editorRef.current!.setContent(path, content);
}
@@ -74,7 +76,22 @@ export class YardEditorView implements Editor {
}
public async validate(): Promise<Notification[]> {
- return this.editorRef.current!.validate();
+ let result: Notification[] = [];
+ return this.editorRef
+ .current!.getContent()
+ .then((value) => {
+ return validationPromise(value);
+ })
+ .then((value) => {
+ result = result.concat(value);
+ return this.editorRef.current!.validate();
+ })
+ .then((value) => {
+ result = result.concat(value);
+ return new Promise<Notification[]>((resolve) => {
+ resolve(result);
+ });
+ });
}
public async setTheme(theme: EditorTheme) {
diff --git a/packages/yard-model/LICENSE b/packages/yard-model/LICENSE
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/packages/yard-model/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/packages/yard-model/env/index.js b/packages/yard-model/env/index.js
new file mode 100644
index 0000000000..425fad9efe
--- /dev/null
+++ b/packages/yard-model/env/index.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");
+
+module.exports = composeEnv([require("@kie-tools/root-env/env")], {
+ vars: varsWithName({}),
+ get env() {
+ return {
+ yardModel: {
+ version: require("../package.json").version,
+ },
+ };
+ },
+});
diff --git a/packages/yard-model/install.js b/packages/yard-model/install.js
new file mode 100644
index 0000000000..aa46eae8f3
--- /dev/null
+++ b/packages/yard-model/install.js
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const buildEnv = require("./env");
+const { setup } = require("@kie-tools/maven-config-setup-helper");
+
+setup(`
+ -Drevision=${buildEnv.env.yardModel.version}
+`);
diff --git a/packages/yard-model/package.json b/packages/yard-model/package.json
new file mode 100644
index 0000000000..8ccb6117fd
--- /dev/null
+++ b/packages/yard-model/package.json
@@ -0,0 +1,48 @@
+{
+ "private": false,
+ "name": "@kie-tools/yard-model",
+ "version": "0.0.0",
+ "description": "",
+ "license": "Apache-2.0",
+ "keywords": [],
+ "homepage": "https://github.com/kiegroup/kie-tools",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/kiegroup/kie-tools.git"
+ },
+ "bugs": {
+ "url": "https://github.com/kiegroup/kie-tools/issues"
+ },
+ "scripts": {
+ "build:dev": "run-script-os",
+ "build:dev:darwin:linux": "pnpm install:mvnw && mvn clean install -DskipTests",
+ "build:dev:win32": "pnpm install:mvnw && pnpm powershell \"mvn clean install `-DskipTests\"",
+ "build:prod": "pnpm lint && run-script-os",
+ "build:prod:darwin:linux": "pnpm install:mvnw && mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)",
+ "build:prod:win32": "pnpm install:mvnw && pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)\"",
+ "install": "node install.js",
+ "install:mvnw": "run-script-os",
+ "install:mvnw:darwin:linux": "mvn wrapper:wrapper",
+ "install:mvnw:win32": "pnpm powershell \"mvn wrapper:wrapper\"",
+ "lint": "echo 'Linting'",
+ "powershell": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command"
+ },
+ "dependencies": {
+ "@kie-tools-core/notifications": "workspace:*"
+ },
+ "devDependencies": {
+ "@kie-tools/maven-config-setup-helper": "workspace:*",
+ "@kie-tools/root-env": "workspace:*",
+ "copy-webpack-plugin": "^11.0.0",
+ "rimraf": "^3.0.2",
+ "run-script-os": "^1.1.6",
+ "typescript": "^4.6.2",
+ "webpack": "^5.88.2"
+ },
+ "kieTools": {
+ "requiredPreinstalledCliCommands": [
+ "java",
+ "mvn"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-model/pom.xml b/packages/yard-model/pom.xml
new file mode 100644
index 0000000000..568bbda361
--- /dev/null
+++ b/packages/yard-model/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" ?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ -->
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.kie.kogito</groupId>
+ <artifactId>yard-model</artifactId>
+ <version>${revision}</version>
+
+ <licenses>
+ <license>
+ <name>Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <properties>
+ <yaml.mapper>0.4</yaml.mapper>
+ <helper.maven.plugin>3.2.0</helper.maven.plugin>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.treblereel.gwt.yaml.mapper</groupId>
+ <artifactId>common</artifactId>
+ <version>${yaml.mapper}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.treblereel.gwt.yaml.mapper</groupId>
+ <artifactId>processor</artifactId>
+ <version>${yaml.mapper}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>${helper.maven.plugin}</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>target/generated-sources/annotations</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/packages/yard-model/src/main/java/org/yard/model/DecisionLogic.java b/packages/yard-model/src/main/java/org/yard/model/DecisionLogic.java
new file mode 100644
index 0000000000..eca6770d60
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/DecisionLogic.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YamlSubtype;
+import org.treblereel.gwt.yaml.api.annotation.YamlTypeInfo;
+
+@YamlTypeInfo(
+ key = "type",
+ value = {
+ @YamlSubtype(alias = "DecisionTable", type = DecisionTable.class),
+ @YamlSubtype(alias = "LiteralExpression", type = LiteralExpression.class)
+ })
+public interface DecisionLogic {
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/DecisionTable.java b/packages/yard-model/src/main/java/org/yard/model/DecisionTable.java
new file mode 100644
index 0000000000..4513608cab
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/DecisionTable.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YAMLMapper;
+import org.treblereel.gwt.yaml.api.annotation.YamlTypeDeserializer;
+import org.treblereel.gwt.yaml.api.annotation.YamlTypeSerializer;
+import org.yard.model.RuleDefSerializer;
+
+import java.util.List;
+
+@YAMLMapper
+public class DecisionTable implements DecisionLogic {
+ private List<String> inputs;
+ private String hitPolicy = "ANY";
+ @Deprecated
+ private List<String> outputComponents;
+ @YamlTypeSerializer(RuleDefSerializer.class)
+ @YamlTypeDeserializer(RuleDefSerializer.class)
+ private List rules;
+
+ public void setInputs(List<String> inputs) {
+ this.inputs = inputs;
+ }
+
+ public void setOutputComponents(List<String> outputComponents) {
+ this.outputComponents = outputComponents;
+ }
+
+ public List<String> getInputs() {
+ return inputs;
+ }
+
+ @Deprecated
+ public List<String> getOutputComponents() {
+ return outputComponents;
+ }
+
+ public String getHitPolicy() {
+ return hitPolicy;
+ }
+
+ public void setHitPolicy(String hitPolicy) {
+ this.hitPolicy = hitPolicy;
+ }
+
+ public List getRules() {
+ return rules;
+ }
+
+ public void setRules(List rules) {
+ this.rules = rules;
+ }
+
+}
\ No newline at end of file
diff --git a/packages/yard-model/src/main/java/org/yard/model/Element.java b/packages/yard-model/src/main/java/org/yard/model/Element.java
new file mode 100644
index 0000000000..7339d80039
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/Element.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YAMLMapper;
+
+import java.util.List;
+
+@YAMLMapper
+public class Element {
+
+ private String name;
+ private String type;
+ private List<String> requirements;
+ private DecisionLogic logic;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public void setRequirements(List<String> requirements) {
+ this.requirements = requirements;
+ }
+
+ public void setLogic(DecisionLogic logic) {
+ this.logic = logic;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public List<String> getRequirements() {
+ return requirements;
+ }
+
+ public DecisionLogic getLogic() {
+ return logic;
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-model/src/main/java/org/yard/model/InlineRule.java b/packages/yard-model/src/main/java/org/yard/model/InlineRule.java
new file mode 100644
index 0000000000..59f2f2e45e
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/InlineRule.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+import java.util.List;
+
+public class InlineRule implements Rule {
+
+ private final int rowNumber;
+ public List def;
+
+ public InlineRule(int rowNumber, List data) {
+ this.rowNumber = rowNumber;
+ this.def = data;
+ }
+
+ @Override
+ public int getRowNumber() {
+ return rowNumber;
+ }
+
+ public List getDef() {
+ return def;
+ }
+
+ public void setDef(List def) {
+ this.def = def;
+ }
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/Input.java b/packages/yard-model/src/main/java/org/yard/model/Input.java
new file mode 100644
index 0000000000..2f25d7882a
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/Input.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YAMLMapper;
+
+@YAMLMapper
+public class Input {
+ private String name;
+ private String type;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-model/src/main/java/org/yard/model/LiteralExpression.java b/packages/yard-model/src/main/java/org/yard/model/LiteralExpression.java
new file mode 100644
index 0000000000..160ed30754
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/LiteralExpression.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YAMLMapper;
+
+@YAMLMapper
+public class LiteralExpression implements DecisionLogic {
+ private String expression;
+
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-model/src/main/java/org/yard/model/Operators.java b/packages/yard-model/src/main/java/org/yard/model/Operators.java
new file mode 100644
index 0000000000..672eb3b088
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/Operators.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+import java.util.Objects;
+
+/**
+ * Interface instead of enum due to possible custom operators.
+ */
+public interface Operators {
+ String NOT_EQUALS = "!=";
+ String EQUALS = "=";
+ String GREATER_OR_EQUAL = ">=";
+ String GREATER_THAN = ">";
+ String LESS_OR_EQUAL = "<=";
+ String LESS_THAN = "<";
+
+ String[] ALL = {EQUALS, LESS_OR_EQUAL, LESS_THAN, GREATER_OR_EQUAL, GREATER_THAN, NOT_EQUALS};
+
+ static int compare(final String operator,
+ final String other) {
+ return getWeight(operator) - getWeight(other);
+ }
+
+ static int getWeight(final String operator) {
+ for (int i = 0; i < ALL.length; i++) {
+ if (Objects.equals(operator, ALL[i])) {
+ return i;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/Rule.java b/packages/yard-model/src/main/java/org/yard/model/Rule.java
new file mode 100644
index 0000000000..98944a05db
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/Rule.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+public interface Rule {
+ int getRowNumber();
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/RuleDefSerializer.java b/packages/yard-model/src/main/java/org/yard/model/RuleDefSerializer.java
new file mode 100644
index 0000000000..2d984cf22b
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/RuleDefSerializer.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.node.YamlMapping;
+import org.treblereel.gwt.yaml.api.node.YamlNode;
+import org.treblereel.gwt.yaml.api.node.YamlSequence;
+import org.treblereel.gwt.yaml.api.YAMLDeserializer;
+import org.treblereel.gwt.yaml.api.YAMLSerializer;
+import org.treblereel.gwt.yaml.api.exception.YAMLDeserializationException;
+import org.treblereel.gwt.yaml.api.internal.deser.YAMLDeserializationContext;
+import org.treblereel.gwt.yaml.api.internal.ser.YAMLSerializationContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RuleDefSerializer
+ implements YAMLSerializer<Object>, YAMLDeserializer<Object> {
+
+ private int rowNumber = 1;
+ @Override
+ public Object deserialize(YamlMapping yamlMapping,
+ String s,
+ YAMLDeserializationContext yamlDeserializationContext) throws YAMLDeserializationException {
+ return deserialize(yamlMapping.getNode(s), yamlDeserializationContext);
+ }
+
+ @Override
+ public Object deserialize(YamlNode yamlNode,
+ YAMLDeserializationContext yamlDeserializationContext) {
+ if (yamlNode instanceof YamlSequence) {
+ final List<Comparable> items = getItems(yamlNode);
+ return new InlineRule(rowNumber++, items);
+
+ } else if (yamlNode instanceof YamlMapping) {
+ final WhenThenRule whenThenRule = new WhenThenRule(rowNumber++);
+ final YamlNode when = ((YamlMapping) yamlNode).getNode("when");
+ final YamlNode then = ((YamlMapping) yamlNode).getNode("then");
+ whenThenRule.setWhen(getItems(when));
+ whenThenRule.setThen(then.asScalar().value());
+ return whenThenRule;
+ }
+ return new IllegalArgumentException("Unknown rule format.");
+ }
+
+ private List<Comparable> getItems(final YamlNode yamlNode) {
+ final List<Comparable> result = new ArrayList<>();
+ if (yamlNode instanceof YamlSequence) {
+ ((YamlSequence) yamlNode).iterator().forEachRemaining(x -> {
+ final Comparable value = (Comparable) x.asScalar().value();
+ result.add(value);
+ });
+ }
+ return result;
+ }
+
+ @Override
+ public void serialize(YamlMapping yamlMapping,
+ String s,
+ Object objects,
+ YAMLSerializationContext yamlSerializationContext) {
+ // Not needed, we never serialize.
+ }
+
+ @Override
+ public void serialize(YamlSequence yamlSequence,
+ Object objects,
+ YAMLSerializationContext yamlSerializationContext) {
+ // Not needed, we never serialize.
+ }
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/WhenThenRule.java b/packages/yard-model/src/main/java/org/yard/model/WhenThenRule.java
new file mode 100644
index 0000000000..2293dadc7a
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/WhenThenRule.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+import java.util.List;
+
+public class WhenThenRule implements Rule {
+
+ private final int rowNumber;
+ private List when;
+ private Object then;
+
+ public WhenThenRule(int rowNumber) {
+ this.rowNumber = rowNumber;
+ }
+
+ @Override
+ public int getRowNumber() {
+ return rowNumber;
+ }
+
+ public List getWhen() {
+ return when;
+ }
+
+ public Object getThen() {
+ return then;
+ }
+
+ public void setWhen(List when) {
+ this.when = when;
+ }
+
+ public void setThen(Object then) {
+ this.then = then;
+ }
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/WhenThenRuleThenSerializer.java b/packages/yard-model/src/main/java/org/yard/model/WhenThenRuleThenSerializer.java
new file mode 100644
index 0000000000..7debaed52e
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/WhenThenRuleThenSerializer.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+import org.treblereel.gwt.yaml.api.YAMLDeserializer;
+import org.treblereel.gwt.yaml.api.YAMLSerializer;
+import org.treblereel.gwt.yaml.api.exception.YAMLDeserializationException;
+import org.treblereel.gwt.yaml.api.internal.deser.YAMLDeserializationContext;
+import org.treblereel.gwt.yaml.api.internal.ser.YAMLSerializationContext;
+import org.treblereel.gwt.yaml.api.node.YamlMapping;
+import org.treblereel.gwt.yaml.api.node.YamlNode;
+import org.treblereel.gwt.yaml.api.node.YamlSequence;
+
+import java.util.Locale;
+
+public class WhenThenRuleThenSerializer
+ implements YAMLSerializer<Object>, YAMLDeserializer<Object> {
+ @Override
+ public Object deserialize(YamlMapping yamlMapping, String key, YAMLDeserializationContext yamlDeserializationContext) throws YAMLDeserializationException {
+ return deserialize(yamlMapping.getNode(key), yamlDeserializationContext);
+ }
+
+ @Override
+ public Object deserialize(YamlNode yamlNode, YAMLDeserializationContext yamlDeserializationContext) {
+ if (yamlNode == null || yamlNode.isEmpty()) {
+ return null;
+ }
+ return yamlNode.<String>asScalar().value().toLowerCase(Locale.ROOT);
+ }
+
+ @Override
+ public void serialize(YamlMapping yamlMapping, String s, Object o, YAMLSerializationContext yamlSerializationContext) {
+ // Not needed, we never serialize.
+ }
+
+ @Override
+ public void serialize(YamlSequence yamlSequence, Object o, YAMLSerializationContext yamlSerializationContext) {
+ // Not needed, we never serialize.
+ }
+}
diff --git a/packages/yard-model/src/main/java/org/yard/model/YaRD.java b/packages/yard-model/src/main/java/org/yard/model/YaRD.java
new file mode 100644
index 0000000000..254b5a2ca8
--- /dev/null
+++ b/packages/yard-model/src/main/java/org/yard/model/YaRD.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.model;
+
+
+import org.treblereel.gwt.yaml.api.annotation.YAMLMapper;
+
+import java.util.List;
+
+@YAMLMapper
+public class YaRD {
+
+ private String specVersion = "alpha";
+ private String kind = "YaRD";
+ private String name;
+ private String expressionLang;
+ private List<Input> inputs;
+ private List<Element> elements;
+
+ public void setInputs(List<Input> inputs) {
+ this.inputs = inputs;
+ }
+
+ public void setElements(List<Element> elements) {
+ this.elements = elements;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getExpressionLang() {
+ return expressionLang;
+ }
+
+ public void setExpressionLang(String expressionLang) {
+ this.expressionLang = expressionLang;
+ }
+
+ public String getKind() {
+ return kind;
+ }
+
+ public void setKind(String kind) {
+ this.kind = kind;
+ }
+
+ public String getSpecVersion() {
+ return specVersion;
+ }
+
+ public void setSpecVersion(String specVersion) {
+ this.specVersion = specVersion;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<Input> getInputs() {
+ return inputs;
+ }
+
+ public List<Element> getElements() {
+ return elements;
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-validator-worker/README.md b/packages/yard-validator-worker/README.md
new file mode 100644
index 0000000000..fb332661ef
--- /dev/null
+++ b/packages/yard-validator-worker/README.md
@@ -0,0 +1,22 @@
+## YARD validator
+
+###### Module for YARD (Yet Another Rule Definition) validation.
+
+### Description
+
+This module contains a standalone J2CL/Java module that can be used to validate YARD file. J2CL version is recommended
+to be ran in a webworker due to the heavy load.
+
+There is a static test page at demo/demo.html. Build the project before running it.
+
+### Validation items currently covered
+
+- Subsumption, when one row "eats" another by covering the same constraints as the subsumed row.
+- Redundant rows. Either the same result is duplicated or one row is useless.
+
+### Validation item ideas for future
+
+- Masked rows, when a row subsumes another, but also blocks the subsumed row from getting ever activated.
+- Conflicting rows. Two rows return different results with overlapping or subsuming constraints.
+- Overlapping rows. Two rows can be activated by the same data, but the rows do not subsume each other.
+- Gaps between the rows
diff --git a/packages/yard-validator-worker/demo/demo.html b/packages/yard-validator-worker/demo/demo.html
new file mode 100644
index 0000000000..8b6863615a
--- /dev/null
+++ b/packages/yard-validator-worker/demo/demo.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Example</title>
+ </head>
+ <body>
+ <script>
+ function validationPromise(yaml) {
+ const promise = new Promise(function (resolve, reject) {
+ const worker = new Worker("../dist/yard-validator-worker.js");
+ console.log("Starting web worker.");
+ worker.postMessage("ENABLE_LOGGING");
+ worker.postMessage(yaml);
+ worker.onmessage = (e) => {
+ if (e.data.startsWith("Log")) {
+ console.log(e.data);
+ } else {
+ resolve(e.data);
+ worker.terminate();
+ }
+ };
+ });
+ return promise;
+ }
+
+ function validate() {
+ let message = document.getElementById("text-area").value;
+ validationPromise(message).then(
+ function (result) {
+ document.getElementById("result-area").value = "Done\n" + result;
+ },
+ function (error) {}
+ );
+ }
+ </script>
+ <textarea id="text-area" style="height: 800px; width: 600px">
+
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', ">= 30", 1000, 7]
+ - ['="speed"', ">= 60", 1000, 7]
+ - ['="parking"', "-", 100, 1]
+ - ['="driving under the influence"', "-", 1000, 5]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
+
+ </textarea>
+ <button onclick="validate()" style="vertical-align: top">Validate</button>
+ <textarea id="result-area" style="height: 800px; width: 600px" readonly></textarea>
+ </body>
+</html>
diff --git a/packages/yard-validator-worker/env/index.js b/packages/yard-validator-worker/env/index.js
new file mode 100644
index 0000000000..26e1811bd5
--- /dev/null
+++ b/packages/yard-validator-worker/env/index.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");
+
+module.exports = composeEnv([require("@kie-tools/root-env/env")], {
+ vars: varsWithName({}),
+ get env() {
+ return {
+ yardValidator: {
+ version: require("../package.json").version,
+ },
+ };
+ },
+});
diff --git a/packages/yard-validator-worker/install.js b/packages/yard-validator-worker/install.js
new file mode 100644
index 0000000000..4247286a3f
--- /dev/null
+++ b/packages/yard-validator-worker/install.js
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const buildEnv = require("./env");
+const { setup } = require("@kie-tools/maven-config-setup-helper");
+
+setup(`
+ -Drevision=${buildEnv.env.yardValidator.version}
+`);
diff --git a/packages/yard-validator-worker/package.json b/packages/yard-validator-worker/package.json
new file mode 100644
index 0000000000..023d2a6fde
--- /dev/null
+++ b/packages/yard-validator-worker/package.json
@@ -0,0 +1,50 @@
+{
+ "private": false,
+ "name": "@kie-tools/yard-validator-worker",
+ "version": "0.0.0",
+ "description": "",
+ "license": "Apache-2.0",
+ "keywords": [],
+ "homepage": "https://github.com/kiegroup/kie-tools",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/kiegroup/kie-tools.git"
+ },
+ "bugs": {
+ "url": "https://github.com/kiegroup/kie-tools/issues"
+ },
+ "scripts": {
+ "build:dev": "rimraf dist && run-script-os && pnpm copy:webworker",
+ "build:dev:darwin:linux": "pnpm install:mvnw && mvn clean install -DskipTests",
+ "build:dev:win32": "pnpm install:mvnw && pnpm powershell \"mvn clean install `-DskipTests\"",
+ "build:prod": "pnpm lint && run-script-os && pnpm copy:webworker",
+ "build:prod:darwin:linux": "pnpm install:mvnw && mvn clean install -DskipTests=$(build-env tests.run --not) -Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)",
+ "build:prod:win32": "pnpm install:mvnw && pnpm powershell \"mvn clean install `-DskipTests=$(build-env tests.run --not) `-Dmaven.test.failure.ignore=$(build-env tests.ignoreFailures)\"",
+ "copy:webworker": "copyfiles -f target/worker/yard-validator-worker/yard-validator-worker.js dist",
+ "install": "node install.js",
+ "install:mvnw": "run-script-os",
+ "install:mvnw:darwin:linux": "mvn wrapper:wrapper",
+ "install:mvnw:win32": "pnpm powershell \"mvn wrapper:wrapper\"",
+ "lint": "echo 'Linting'",
+ "powershell": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command"
+ },
+ "dependencies": {
+ "@kie-tools-core/notifications": "workspace:*",
+ "@kie-tools/yard-model": "workspace:*"
+ },
+ "devDependencies": {
+ "@kie-tools/maven-config-setup-helper": "workspace:*",
+ "@kie-tools/root-env": "workspace:*",
+ "@kie-tools/tsconfig": "workspace:*",
+ "copyfiles": "^2.4.1",
+ "rimraf": "^3.0.2",
+ "run-script-os": "^1.1.6",
+ "typescript": "^4.6.2"
+ },
+ "kieTools": {
+ "requiredPreinstalledCliCommands": [
+ "java",
+ "mvn"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-validator-worker/pom.xml b/packages/yard-validator-worker/pom.xml
new file mode 100644
index 0000000000..3c30e4afc4
--- /dev/null
+++ b/packages/yard-validator-worker/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" ?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ -->
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.kie.kogito</groupId>
+ <artifactId>yard-validator-worker</artifactId>
+ <version>${revision}</version>
+
+ <licenses>
+ <license>
+ <name>Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <properties>
+ <yaml.mapper>0.4</yaml.mapper>
+ <org.jresearch.gwt.time>2.0.10</org.jresearch.gwt.time>
+ <compiler-plugin.version>3.8.1</compiler-plugin.version>
+ <maven.compiler.source>11</maven.compiler.source>
+ <maven.compiler.target>11</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
+ <version.junit>4.13.1</version.junit>
+ <j2cl.maven.plugin.version>0.20</j2cl.maven.plugin.version>
+ <version.org.junit>4.13.1</version.org.junit>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.treblereel.gwt.yaml.mapper</groupId>
+ <artifactId>common</artifactId>
+ <version>${yaml.mapper}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.kie.kogito</groupId>
+ <artifactId>yard-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.kie.kogito</groupId>
+ <artifactId>yard-model</artifactId>
+ <version>${project.version}</version>
+ <classifier>sources</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${version.org.junit}</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>../src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>com.vertispan.j2cl</groupId>
+ <artifactId>j2cl-maven-plugin</artifactId>
+ <version>${j2cl.maven.plugin.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <webappDirectory>${project.build.directory}/worker</webappDirectory>
+ <compilationLevel>ADVANCED</compilationLevel>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/CustomTreeSet.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/CustomTreeSet.java
new file mode 100644
index 0000000000..58c9595f5e
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/CustomTreeSet.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import org.yard.model.Operators;
+import org.yard.validator.key.ColumnKey;
+import org.yard.validator.key.Key;
+import org.yard.validator.key.OperatorValueKey;
+
+import java.util.*;
+
+public class CustomTreeSet {
+
+ private final TreeSet<Key> innerSet;
+
+ private final Set<ColumnKey> equalColumns = new HashSet<>();
+
+ public CustomTreeSet() {
+ innerSet = new TreeSet<>(getComparator());
+ }
+
+ private static Comparator<Key> getComparator() {
+ return (a, b) -> {
+ final int compareResult = compareKeys(a, b);
+ if (compareResult == 0) {
+ if (a instanceof OperatorValueKey
+ && b instanceof OperatorValueKey) {
+ return Operators.compare(
+ ((OperatorValueKey) a).getOperator(),
+ ((OperatorValueKey) b).getOperator());
+ } else {
+ throw new IllegalArgumentException("What? Looks like it was not an OperatorValueKey.");
+ }
+ }
+ return compareResult;
+ };
+ }
+
+ private static int compareKeys(final Key a,
+ final Key b) {
+ if (a.getParent() instanceof Comparable
+ && b.getParent() instanceof Comparable) {
+ return ((Comparable) a.getParent()).compareTo(b.getParent());
+ }
+ return -1;
+ }
+
+ public Set<ColumnKey> getEqualColumns() {
+ return equalColumns;
+ }
+
+ public int getHash(final Set<ColumnKey> bundleKeys) {
+ int result = 0;
+
+ // Inner HashMap would speed this up, but not sure if it is worth it.
+ // All the ParentKeys that we are looking for are like on the front of the list.
+ for (Key key : innerSet) {
+ if (bundleKeys.contains(key.getParent())) {
+ result = 31 * result + ((OperatorValueKey) key).getValue().hashCode();
+ }
+ }
+
+ return result;
+ }
+
+ public boolean addAll(final CustomTreeSet c) {
+ if (c instanceof CustomTreeSet) {
+ equalColumns.addAll(((CustomTreeSet) c).equalColumns);
+ }
+ return innerSet.addAll(c.innerSet);
+ }
+
+ public boolean add(final Key o) {
+ if (o instanceof OperatorValueKey) {
+ if (Objects.equals(Operators.EQUALS, ((OperatorValueKey) o).getOperator())) {
+ equalColumns.add((ColumnKey) o.getParent());
+ }
+ }
+ return innerSet.add(o);
+ }
+
+ public boolean isEmpty() {
+ return innerSet.isEmpty();
+ }
+
+ public int size() {
+ return innerSet.size();
+ }
+
+ public Key[] toArray(final Key[] keys) {
+ return innerSet.toArray(keys);
+ }
+
+ @Override
+ public String toString() {
+ String result = "";
+
+ for (Key key : innerSet) {
+ result += key.toString();
+ result += "\n";
+ }
+
+ return result;
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/Issue.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/Issue.java
new file mode 100644
index 0000000000..8d11223369
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/Issue.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import org.yard.validator.key.Location;
+
+import java.util.Arrays;
+
+public class Issue {
+ private String message;
+ private Location[] locations;
+
+ public Issue(final String message, final Location... locations) {
+ this.message = message;
+ this.locations = locations;
+ }
+
+ public Location[] getLocations() {
+ return locations;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ @Override
+ public String toString() {
+ return "Issue{" +
+ "message='" + message + '\'' +
+ ", locations=" + Arrays.toString(locations) +
+ '}';
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/Parser.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/Parser.java
new file mode 100644
index 0000000000..6926262542
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/Parser.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import org.yard.model.*;
+import org.yard.validator.key.*;
+import org.yard.validator.util.Date;
+import org.yard.validator.util.Logger;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+public class Parser {
+
+ private String hitPolicy;
+
+ public ParserResult parse(final String yaml) {
+
+ try {
+
+ final YaRD model = new YaRD_YamlMapperImpl().read(yaml);
+
+ Logger.log("YaRD model has been read.");
+ Logger.log("YaRD model name is " + model.getName());
+ final TreeMap<RowLocation, CustomTreeSet> result
+ = visit(findTableStartRow(yaml), model);
+
+ return new ParserResult(result, hitPolicy.toUpperCase());
+ } catch (Exception e) {
+ Logger.log("Failed to parse YAML " + e.getMessage());
+ return new ParserResult(Collections.emptyMap(), "ANY");
+ }
+
+ }
+
+ private int findTableStartRow(final String yaml) {
+ final String[] split = yaml.split("\n");
+ for (int i = 0; i < split.length; i++) {
+ final String trim = split[i].trim();
+ if (Objects.equals("rules:", trim)) {
+ return i + 1;
+ }
+ }
+ return -1;
+ }
+
+ private TreeMap<RowLocation, CustomTreeSet> visit(
+ final int rulesRow,
+ final YaRD yard) {
+ final TreeMap<RowLocation, CustomTreeSet> result = new TreeMap<>();
+ for (final Element element : yard.getElements()) {
+ if (element.getLogic() instanceof DecisionTable) {
+ final DecisionTable dt = (DecisionTable) element.getLogic();
+
+ Logger.log("Hit policy is : " + hitPolicy);
+ hitPolicy = dt.getHitPolicy();
+
+ final List<Rule> rules = dt.getRules();
+ for (Rule rule : rules) {
+ final RowLocation location = new RowLocation(
+ rule.getRowNumber(),
+ rule.getRowNumber() + rulesRow);
+ if (rule instanceof WhenThenRule) {
+ final CustomTreeSet keys = getWhenThenKeys(dt, (WhenThenRule) rule, location);
+ if (!keys.isEmpty()) {
+ result.put(location, keys);
+ }
+ } else if (rule instanceof InlineRule) {
+ final CustomTreeSet keys = getInlineRuleKeys(dt, (InlineRule) rule, location);
+ if (!keys.isEmpty()) {
+ result.put(location, keys);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private CustomTreeSet getInlineRuleKeys(
+ final DecisionTable dt,
+ final InlineRule rule,
+ final RowLocation location) {
+ final CustomTreeSet keys = new CustomTreeSet();
+ int columnIndex = 0;
+ for (Object o : rule.getDef()) {
+ if (dt.getInputs().size() > columnIndex) {
+ final String input = dt.getInputs().get(columnIndex++);
+ final ColumnKey columnKey = new ColumnKey(input);
+ keys.addAll(
+ getKeys(
+ location,
+ o,
+ columnKey));
+ }
+ }
+ return keys;
+ }
+
+ private CustomTreeSet getWhenThenKeys(final DecisionTable dt,
+ final WhenThenRule r,
+ final RowLocation location) {
+ final CustomTreeSet keys = new CustomTreeSet();
+
+ int columnIndex = 0;
+ for (Object o : r.getWhen()) {
+ final String input = dt.getInputs().get(columnIndex++);
+ final ColumnKey columnKey = new ColumnKey(input);
+ keys.addAll(
+ getKeys(
+ location,
+ o,
+ columnKey));
+ }
+ return keys;
+ }
+
+ private CustomTreeSet getKeys(final RowLocation location,
+ final Object o,
+ final ColumnKey columnKey) {
+ final CustomTreeSet keys = new CustomTreeSet();
+ if (o instanceof Comparable) {
+ if (isSplit(o)) {
+ final String text = (String) o;
+ final String start = text.substring(0, text.indexOf(".."));
+ final String end = text.substring(text.indexOf("..") + 2);
+ final String operatorStart = resolveToOperator(start.charAt(0));
+ final String operatorEnd = resolveToOperator(end.charAt(end.length() - 1));
+ final Comparable valueStart = testType(start.substring(1));
+ final Comparable valueEnd = testType(end.substring(0, end.length() - 1));
+ keys.add(new OperatorValueKey(location, columnKey, operatorStart, valueStart));
+ keys.add(new OperatorValueKey(location, columnKey, operatorEnd, valueEnd));
+ } else {
+
+ final String operator = getOperator(o);
+ final Comparable value = getValue(o, operator);
+
+ if (value == null) {
+ // no need to add nulls
+ } else if (operator == null) {
+ keys.add(new ObjectKey(location, columnKey, (Comparable) o));
+ } else {
+ keys.add(new OperatorValueKey(location, columnKey, operator, value));
+ }
+ }
+ }
+ return keys;
+ }
+
+ private String resolveToOperator(final char c) {
+ switch (c) {
+ case '(':
+ return Operators.GREATER_THAN;
+ case ')':
+ return Operators.LESS_THAN;
+ case '[':
+ return Operators.GREATER_OR_EQUAL;
+ case ']':
+ return Operators.LESS_OR_EQUAL;
+ }
+ throw new IllegalStateException("Ranged operator unknown.");
+ }
+
+ private boolean isSplit(final Object o) {
+ if (o instanceof String) {
+ return ((String) o).contains("..") && isRangeStart((String) o) && isRangeEnd((String) o);
+ }
+ return false;
+ }
+
+ private boolean isRangeEnd(final String text) {
+ return text.endsWith(")") || text.endsWith("]");
+ }
+
+ private boolean isRangeStart(final String text) {
+ return text.startsWith("(") || text.startsWith("[");
+ }
+
+ private Comparable getValue(final Object o,
+ final String operator) {
+ if (operator != null && o instanceof String) {
+ final String value = ((String) o).substring(operator.length());
+ return testType(value);
+ } else if (operator == null && o instanceof String && Objects.equals("-", ((String) o).trim())) {
+ return null;
+ }
+ return testType(o);
+ }
+
+ private Comparable testType(final Object o) {
+ if (o instanceof String) {
+ final String value = ((String) o).trim();
+ try {
+ return new BigDecimal(value);
+ } catch (NumberFormatException e) {
+ // Was a nice try, but no luck.
+ }
+ try {
+ return new Date(value);
+ } catch (IllegalArgumentException e) {
+ // Was a nice try, but no luck.
+ }
+ return value;
+ }
+ return null;
+ }
+
+ private String getOperator(final Object o) {
+ if (o instanceof String) {
+ final String text = (String) o;
+ for (final String operator : Operators.ALL) {
+ if (text.trim().startsWith(operator)) {
+ return operator;
+ }
+ }
+ }
+
+ return null; // Null is fine
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/ParserResult.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/ParserResult.java
new file mode 100644
index 0000000000..9a73de0ab3
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/ParserResult.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import org.yard.validator.key.RowLocation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ParserResult {
+
+ private final Map<RowLocation, CustomTreeSet> result;
+ private final String hitPolicy;
+
+ public ParserResult(
+ final Map<RowLocation, CustomTreeSet> result,
+ final String hitPolicy
+ ) {
+ this.result = result;
+ this.hitPolicy = hitPolicy;
+ }
+
+ public Map<RowLocation, CustomTreeSet> getResult() {
+ return result;
+ }
+
+ public String getHitPolicy() {
+ return hitPolicy;
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/ReportBus.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/ReportBus.java
new file mode 100644
index 0000000000..a1cb2f306f
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/ReportBus.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+public interface ReportBus {
+ public void report(final Issue issue);
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/YardValidator.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/YardValidator.java
new file mode 100644
index 0000000000..8e3e409b3c
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/YardValidator.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import jsinterop.annotations.JsConstructor;
+import jsinterop.annotations.JsMethod;
+import org.yard.validator.checks.Check;
+import org.yard.validator.checks.CheckProducer;
+import org.yard.validator.key.Location;
+import org.yard.validator.key.RowLocation;
+import org.yard.validator.runner.Runner;
+import org.yard.validator.util.Callback;
+import org.yard.validator.util.Logger;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class YardValidator {
+
+ private final ArrayList<String> log = new ArrayList<>();
+ private ParserResult parse;
+
+ @JsConstructor
+ public YardValidator() {
+ }
+
+ @JsMethod
+ public void setLogger(final Callback callback) {
+ Logger.startLogging(callback);
+ }
+
+ private void init(final String yaml) {
+
+ Logger.startLogging(s -> log.add("\"" + s + "\""));
+ Logger.log("Starting validator");
+
+ parse = new Parser().parse(yaml);
+ }
+
+ @JsMethod
+ public String validate(final String yaml) {
+ final ArrayList<String> issues = new ArrayList<>();
+ validate(yaml, issue -> {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("{\"issue\":\"" + issue.getMessage() + "\"");
+ builder.append(",");
+ builder.append("\"locations\":[");
+
+ builder.append(Arrays.stream(issue.getLocations()).map(i -> {
+ final StringBuilder innerBuilder = new StringBuilder();
+ innerBuilder.append("{");
+ innerBuilder.append("\"rowInFile\":" + ((RowLocation) i).getActualRowNumberInFile() + ",");
+ innerBuilder.append("\"rowInTable\":" + ((RowLocation) i).getTableRowNumber());
+ innerBuilder.append("}");
+ return innerBuilder.toString();
+ }).collect(Collectors.joining(", ")));
+
+ builder.append("]}");
+ issues.add(builder.toString());
+ });
+ return "{\"log\":[" + log.toArray().toString() + "],\"result\":[" + issues.stream().collect(Collectors.joining(",")) + "]}";
+ }
+
+ public void validate(final String yaml, final ReportBus bus) {
+ try {
+ init(yaml);
+ } catch (final Exception e) {
+ Logger.log("Failed to initialize: " + e.getMessage());
+ }
+
+ new Runner(bus).run(getChecks());
+ }
+
+ private List<Check> getChecks() {
+ if (Objects.equals("COLLECT", parse.getHitPolicy())) {
+ return Collections.emptyList();
+ } else {
+ return CheckProducer.getChecks(parse);
+ }
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/app.js b/packages/yard-validator-worker/src/main/java/org/yard/validator/app.js
new file mode 100644
index 0000000000..c0a5ab5805
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/app.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+goog.module("org.yard.validator");
+
+const YardValidator = goog.require("org.yard.validator.YardValidator");
+
+const validator = new YardValidator();
+
+self.addEventListener("message", (e) => {
+ if (e.data === "ENABLE_LOGGING") {
+ validator.setLogger((e) => {
+ self.postMessage("Log: " + e);
+ });
+ self.postMessage("Log logger set up");
+ } else {
+ self.postMessage(validator.validate(e.data));
+ }
+});
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/Check.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/Check.java
new file mode 100644
index 0000000000..170828f393
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/Check.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.checks;
+
+import org.yard.validator.Issue;
+
+import java.util.Optional;
+
+public interface Check {
+ Optional<Issue> check();
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckItem.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckItem.java
new file mode 100644
index 0000000000..9461fbb5c1
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckItem.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.checks;
+
+import org.yard.validator.CustomTreeSet;
+import org.yard.validator.key.Key;
+import org.yard.validator.key.Location;
+
+public class CheckItem {
+ private final int index;
+ private final Location location;
+ private final Key[] keys;
+
+ public CheckItem(final int index,
+ final Location location,
+ final CustomTreeSet keys) {
+
+ this.index = index;
+ this.location = location;
+ this.keys = keys.toArray(new Key[keys.size()]);
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public Key[] getKeys() {
+ return keys;
+ }
+
+ @Override
+ public String toString() {
+ return "CheckItem{" +
+ "location=" + location +
+ '}';
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckProducer.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckProducer.java
new file mode 100644
index 0000000000..876d9900b8
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/CheckProducer.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.checks;
+
+import org.yard.validator.CustomTreeSet;
+import org.yard.validator.ParserResult;
+import org.yard.validator.key.ColumnKey;
+import org.yard.validator.key.Location;
+import org.yard.validator.key.RowLocation;
+import org.yard.validator.util.Logger;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class CheckProducer {
+
+ public static List<Check> getChecks(final ParserResult parse) {
+ final List<Check> result = new ArrayList<>();
+ try {
+ final Set<ColumnKey> bundleKeys = formBundleKeys(parse.getResult());
+ final Map<Integer, RunBundle> bundles = formBundles(parse.getResult(), bundleKeys);
+
+ for (final RunBundle value : bundles.values()) {
+ result.addAll(getCheckList(parse.getHitPolicy(), value.getMap()));
+ }
+
+ } catch (final Exception e) {
+ Logger.log("Failed to create checks: " + e.getMessage());
+ }
+ return result;
+ }
+
+ private static Set<ColumnKey> formBundleKeys(final Map<RowLocation, CustomTreeSet> parse) {
+ final Set<ColumnKey> result = new HashSet<>();
+ for (final CustomTreeSet value : parse.values()) {
+ if (value != null) {
+ if (result.isEmpty()) {
+ result.addAll(value.getEqualColumns());
+ } else {
+ final Set<ColumnKey> removeKeys = result.stream().filter(x -> !value.getEqualColumns().contains(x)).collect(Collectors.toSet());
+ result.removeAll(removeKeys);
+ }
+ }
+ }
+ return result;
+ }
+
+ private static Map<Integer, RunBundle> formBundles(final Map<RowLocation, CustomTreeSet> parse,
+ final Set<ColumnKey> bundleKeys) {
+ final Map<Integer, RunBundle> result = new HashMap<>();
+ for (Map.Entry<RowLocation, CustomTreeSet> entry : parse.entrySet()) {
+ int hash = entry.getValue().getHash(bundleKeys);
+ if (!result.containsKey(hash)) {
+ result.put(hash, new RunBundle());
+ }
+ result.get(hash).put(entry.getKey(), entry.getValue());
+ }
+ return result;
+ }
+
+ private static List<Check> getCheckList(
+ final String hitPolicy,
+ final Map<RowLocation, CustomTreeSet> parse) {
+ final List<Check> result = new ArrayList<>();
+
+ // Dual row
+ int locationIndex = 0;
+ final RowLocation[] locations = new RowLocation[parse.keySet().size()];
+ for (RowLocation location : parse.keySet()) {
+ locations[locationIndex++] = location;
+ }
+
+ for (int i = 0; i < parse.entrySet().size(); i++) {
+ for (int j = i; j < parse.entrySet().size(); j++) {
+ if (i == j) {
+ continue;
+ }
+ final RowLocation locationA = getHigher(locations, i, j);
+ final RowLocation locationB = getLower(locations, i, j);
+
+ final CheckItem checkItemA = new CheckItem(
+ locationA.getTableRowNumber(),
+ locationA,
+ parse.get(locationA));
+ final CheckItem checkItemB = new CheckItem(
+ locationB.getTableRowNumber(),
+ locationB,
+ parse.get(locationB));
+
+ result.add(new SubsumptionCheck(
+ hitPolicy,
+ checkItemA,
+ checkItemB));
+ }
+ }
+ return result;
+ }
+
+ private static RowLocation getHigher(
+ final RowLocation[] locations,
+ final int i,
+ final int j) {
+ if (locations[i].getTableRowNumber() > locations[j].getTableRowNumber()) {
+ return locations[i];
+ } else {
+ return locations[j];
+ }
+ }
+
+ private static RowLocation getLower(
+ final RowLocation[] locations,
+ final int i,
+ final int j) {
+ if (locations[i].getTableRowNumber() < locations[j].getTableRowNumber()) {
+ return locations[i];
+ } else {
+ return locations[j];
+ }
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/RunBundle.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/RunBundle.java
new file mode 100644
index 0000000000..cb3e852e8f
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/RunBundle.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.checks;
+
+import org.yard.validator.CustomTreeSet;
+import org.yard.validator.key.RowLocation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RunBundle {
+
+ private final Map<RowLocation, CustomTreeSet> map = new HashMap<>();
+
+ public Map<RowLocation, CustomTreeSet> getMap() {
+ return map;
+ }
+
+ public void put(final RowLocation key,
+ final CustomTreeSet value) {
+ map.put(key, value);
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/SubsumptionCheck.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/SubsumptionCheck.java
new file mode 100644
index 0000000000..01d2b43e2d
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/checks/SubsumptionCheck.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.checks;
+
+import org.yard.validator.Issue;
+import org.yard.validator.key.Key;
+import org.yard.validator.key.KeyParent;
+import org.yard.validator.key.OperatorValueKey;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.yard.model.Operators.*;
+
+public class SubsumptionCheck
+ implements Check {
+
+ private final String hitPolicy;
+ private final CheckItem checkItemA;
+ private final CheckItem checkItemB;
+
+ public SubsumptionCheck(
+ final String hitPolicy,
+ final CheckItem checkItemA,
+ final CheckItem checkItemB) {
+ this.hitPolicy = hitPolicy;
+ this.checkItemA = checkItemA;
+ this.checkItemB = checkItemB;
+ }
+
+ @Override
+ public Optional<Issue> check() {
+ final Optional<Issue> aToB = getIssue(checkItemA, checkItemB);
+
+ if (isFirstHitPolicy()) {
+ if (aToB.isPresent()) {
+ // No need to check for redundancy. The first row masks the rest.
+ return Optional.of(new Issue(
+ "Masking row. The higher row prevents the activation of the other row.",
+ checkItemA.getLocation(),
+ checkItemB.getLocation()));
+ } else {
+ // No need to check the other row for subsumption,
+ // since subsumption is likely there by rule design
+ return Optional.empty();
+ }
+ } else {
+ final Optional<Issue> bToA = getIssue(checkItemB, checkItemA);
+
+ // If the counterpart in the table is subsumptant, meaning the other item subsumes this, we have redundancy.
+ if (aToB.isPresent() && bToA.isPresent()) {
+ return Optional.of(new Issue(
+ getRedundancyMessage(),
+ checkItemA.getLocation(),
+ checkItemB.getLocation()));
+ } else if (aToB.isPresent()) {
+ return aToB;
+ } else {
+ return bToA;
+ }
+ }
+ }
+
+ private String getRedundancyMessage() {
+ if (Objects.equals("UNIQUE", hitPolicy)) {
+ return "Redundancy found. Unique hit policy fails when more than one row returns results.";
+ } else {
+ return "Redundancy found. If both rows return the same result, the other can be removed. If they return different results, the table fails to return a value.";
+ }
+ }
+
+ private String getSubsumptionMessage() {
+ if (Objects.equals("UNIQUE", hitPolicy)) {
+ return "Subsumption found. Unique hit policy fails when more than one row returns results.";
+ } else {
+ return "Subsumption found. If both rows return the same result, the other can be removed. If they return different results, the table fails to return a value.";
+ }
+ }
+
+ private boolean isFirstHitPolicy() {
+ return Objects.equals("FIRST", hitPolicy)
+ // PRIORITY can not be set since the column header does not support listing it.
+ // For this reason it acts the same way as FIRST
+ || Objects.equals("PRIORITY", hitPolicy);
+ }
+
+ private Optional<Issue> getIssue(
+ final CheckItem checkItemA,
+ final CheckItem checkItemB) {
+ // All values and ranges in A are covered by B
+ int coveredBIndex = 0;
+ for (int aIndex = 0; aIndex < checkItemA.getKeys().length; aIndex++) {
+ final Key key = checkItemA.getKeys()[aIndex];
+ final KeyParent parent = key.getParent();
+
+ for (int bIndex = coveredBIndex; bIndex < checkItemB.getKeys().length; bIndex++) {
+ try {
+ final Key other = findCounterPartParent(checkItemB, parent, bIndex);
+ coveredBIndex = bIndex + 1;
+ if (!subsumes((OperatorValueKey) key, (OperatorValueKey) other)) {
+ return Optional.empty();
+ }
+ break;
+ } catch (NotFoundException e) {
+ // All good for now, the other has "any" marked for this parent.
+ }
+ }
+ }
+ return Optional.of(
+ new Issue(
+ getSubsumptionMessage(),
+ checkItemA.getLocation(),
+ checkItemB.getLocation()));
+ }
+
+ private Key findCounterPartParent(final CheckItem checkItem,
+ final KeyParent parent,
+ final int i) throws NotFoundException {
+ if (checkItem.getKeys()[i].getParent().equals(parent)) {
+ return checkItem.getKeys()[i];
+ }
+ throw new NotFoundException();
+ }
+
+ public boolean subsumes(final OperatorValueKey keyA,
+ final OperatorValueKey keyB) {
+ switch (keyA.getOperator()) {
+ case NOT_EQUALS:
+ switch (keyB.getOperator()) {
+ case NOT_EQUALS:
+ return valueIsEqualTo(keyA.getValue(), keyB.getValue());
+ case EQUALS:
+ boolean valueIsEqualTo = valueIsEqualTo(keyA.getValue(), keyB.getValue());
+ boolean covers = covers(keyA, keyB.getValue());
+ return !valueIsEqualTo && !covers;
+ default:
+ return false;
+ }
+ case EQUALS:
+ switch (keyB.getOperator()) {
+ case NOT_EQUALS:
+ boolean valueIsEqualTo = valueIsEqualTo(keyA.getValue(), keyB.getValue());
+ boolean covers = covers(keyA, keyB.getValue());
+ return !valueIsEqualTo && !covers;
+ default:
+ return covers(keyA, keyB.getValue());
+ }
+ case GREATER_OR_EQUAL:
+ switch (keyB.getOperator()) {
+ case GREATER_OR_EQUAL:
+ case GREATER_THAN:
+ return covers(keyA, keyB.getValue());
+ case NOT_EQUALS:
+ return valueIsGreaterThan(keyA, keyB.getValue());
+ default:
+ return false;
+ }
+
+ case LESS_OR_EQUAL:
+ switch (keyB.getOperator()) {
+ case LESS_OR_EQUAL:
+ case LESS_THAN:
+ return covers(keyA, keyB.getValue());
+ case NOT_EQUALS:
+ return valueIsLessThan(keyA, keyB.getValue());
+ default:
+ return false;
+ }
+ case LESS_THAN:
+ switch (keyB.getOperator()) {
+ case LESS_OR_EQUAL:
+ return covers(keyA, keyB.getValue());
+ case LESS_THAN:
+ case NOT_EQUALS:
+ return valueIsLessThanOrEqualTo(keyA, keyB.getValue());
+ default:
+ return false;
+ }
+ case GREATER_THAN:
+ switch (keyB.getOperator()) {
+ case GREATER_OR_EQUAL:
+ return covers(keyA, keyB.getValue());
+ case GREATER_THAN:
+ case NOT_EQUALS:
+ return valueIsGreaterThanOrEqualTo(keyA, keyB.getValue());
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ }
+
+ protected boolean valueIsEqualTo(final Comparable valueA,
+ final Comparable valueB) {
+ if (valueA == null) {
+ return valueB == null;
+ } else {
+ if (valueB == null) {
+ return false;
+ } else {
+ return valueA.compareTo(valueB) == 0;
+ }
+ }
+ }
+
+ public boolean covers(final OperatorValueKey key,
+ final Comparable otherValue) {
+ switch (key.getOperator()) {
+ case EQUALS:
+ return valueIsEqualTo(key.getValue(), otherValue);
+ case NOT_EQUALS:
+ return !valueIsEqualTo(key.getValue(), otherValue);
+ case GREATER_OR_EQUAL:
+ return valueIsGreaterThanOrEqualTo(key, otherValue);
+ case LESS_OR_EQUAL:
+ return valueIsLessThanOrEqualTo(key, otherValue);
+ case LESS_THAN:
+ return valueIsLessThan(key, otherValue);
+ case GREATER_THAN:
+ return valueIsGreaterThan(key, otherValue);
+ default:
+ return false;
+ }
+ }
+
+ protected boolean valueIsGreaterThanOrEqualTo(final OperatorValueKey key,
+ final Comparable otherValue) {
+ return valueIsEqualTo(key.getValue(), otherValue) || valueIsGreaterThan(key, otherValue);
+ }
+
+ protected boolean valueIsLessThanOrEqualTo(final OperatorValueKey key,
+ final Comparable otherValue) {
+ return valueIsEqualTo(key.getValue(), otherValue) || valueIsLessThan(key, otherValue);
+ }
+
+ protected boolean valueIsGreaterThan(final OperatorValueKey key,
+ final Comparable otherValue) {
+ return otherValue.compareTo(key.getValue()) > 0;
+ }
+
+ protected boolean valueIsLessThan(final OperatorValueKey key,
+ final Comparable otherValue) {
+ return otherValue.compareTo(key.getValue()) < 0;
+ }
+
+ private class NotFoundException extends Throwable {
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ColumnKey.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ColumnKey.java
new file mode 100644
index 0000000000..dadc536d26
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ColumnKey.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+
+import java.util.Objects;
+
+public class ColumnKey implements KeyParent, Comparable<KeyParent> {
+
+ private final String column;
+
+ public ColumnKey(final String column) {
+ this.column = column;
+ }
+
+ @Override
+ public String toString() {
+ return column;
+ }
+
+ @Override
+ public int compareTo(final KeyParent o) {
+ if (o instanceof ColumnKey) {
+ return column.compareTo(((ColumnKey) o).column);
+ } else {
+ return -1;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ColumnKey columnKey = (ColumnKey) o;
+ return Objects.equals(column, columnKey.column);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(column);
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Key.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Key.java
new file mode 100644
index 0000000000..20f6aae98d
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Key.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+/**
+ * The key, path down to field in DRL or DMN case.
+ */
+public interface Key {
+
+ Location getLocation();
+
+ KeyParent getParent();
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyImpl.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyImpl.java
new file mode 100644
index 0000000000..ad473f9002
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyImpl.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+public class KeyImpl implements Key {
+
+ protected final Location location;
+ protected final KeyParent parent;
+
+ public KeyImpl(final Location location,
+ final KeyParent parent) {
+ this.location = location;
+ this.parent = parent;
+ }
+
+ @Override
+ public Location getLocation() {
+ return location;
+ }
+
+ @Override
+ public KeyParent getParent() {
+ return parent;
+ }
+
+ @Override
+ public String toString() {
+ return parent.toString();
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyParent.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyParent.java
new file mode 100644
index 0000000000..c30e707fce
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/KeyParent.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+/**
+ * Parent of the key. Everything leading to pattern for example:
+ *
+ * rule-activation-group-from-pattern
+ */
+public interface KeyParent {
+
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Location.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Location.java
new file mode 100644
index 0000000000..447a4257d8
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/Location.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+/**
+ * Used to group keys and track the location of use.
+ */
+public interface Location<T>
+ extends Comparable<T>{
+
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ObjectKey.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ObjectKey.java
new file mode 100644
index 0000000000..9accc50ac1
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/ObjectKey.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+
+import org.yard.model.Operators;
+
+public class ObjectKey extends OperatorValueKey {
+
+ public ObjectKey(final Location location,
+ final KeyParent parent,
+ final Comparable value) {
+ super(location,
+ parent,
+ Operators.EQUALS,
+ value);
+ }
+
+ @Override
+ public String toString() {
+ return parent + " " + value;
+ }
+
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/OperatorValueKey.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/OperatorValueKey.java
new file mode 100644
index 0000000000..cbc27d3b8f
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/OperatorValueKey.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+
+public class OperatorValueKey extends KeyImpl {
+
+ private final String operator;
+ protected final Comparable value;
+
+ public OperatorValueKey(final Location location,
+ final KeyParent parent,
+ final String operator,
+ final Comparable value) {
+ super(location,
+ parent );
+ this.operator = operator;
+ this.value = value;
+ }
+
+ public String getOperator() {
+ return operator;
+ }
+
+ public Comparable getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return parent + " " + operator + " " + value;
+ }
+
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/key/RowLocation.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/RowLocation.java
new file mode 100644
index 0000000000..0baafe539e
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/key/RowLocation.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.key;
+
+public class RowLocation implements Location<RowLocation> {
+
+ private final int actualRowNumberInFile;
+ final int tableRowNumber;
+
+ public RowLocation(final int tableRowNumber,
+ final int actualRowNumberInFile) {
+ this.tableRowNumber = tableRowNumber;
+ this.actualRowNumberInFile = actualRowNumberInFile;
+ }
+
+ public int getActualRowNumberInFile() {
+ return actualRowNumberInFile;
+ }
+
+ public int getTableRowNumber() {
+ return tableRowNumber;
+ }
+
+ @Override
+ public String toString() {
+ return "Table row " + tableRowNumber + " actual row " + actualRowNumberInFile;
+ }
+
+ @Override
+ public int compareTo(final RowLocation o) {
+ return Integer.compare(tableRowNumber, o.tableRowNumber);
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/runner/Runner.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/runner/Runner.java
new file mode 100644
index 0000000000..0f45e3839f
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/runner/Runner.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.runner;
+
+import org.yard.validator.Issue;
+import org.yard.validator.ReportBus;
+import org.yard.validator.checks.Check;
+import org.yard.validator.util.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+public class Runner {
+
+ private ReportBus reportBus;
+
+ public Runner(ReportBus reportBus) {
+ this.reportBus = reportBus;
+ }
+
+ public void run(final List<Check> checks) {
+ try {
+
+ for (final Check check : checks) {
+ final Optional<Issue> issue = check.check();
+ issue.ifPresent(value -> reportBus.report(value));
+ }
+ } catch (final Exception e) {
+ Logger.log("Failed to run checks: " + e.getMessage());
+ }
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Callback.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Callback.java
new file mode 100644
index 0000000000..02d6bc51a3
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Callback.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.util;
+
+import jsinterop.annotations.JsFunction;
+
+@JsFunction
+public interface Callback {
+ void callback(final String s);
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Date.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Date.java
new file mode 100644
index 0000000000..71ef822971
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Date.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.util;
+
+/**
+ * Our own custom Date.
+ * We do not need all the features normal date has, just the ability to compare.
+ * This brings less trouble and dependencies for the J2CL.
+ */
+public class Date implements Comparable {
+
+ private final String value;
+ private final int years;
+ private final int months;
+ private final int days;
+
+
+ public Date(final String value) {
+ this.value = value;
+
+ final String[] split = value.split("-");
+ // Format yyyy-MM-dd
+ try {
+ years = Integer.parseInt(split[0]);
+ months = Integer.parseInt(split[1]);
+ days = Integer.parseInt(split[2]);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ if (o instanceof Date) {
+ final Date other = (Date) o;
+ final int compareYears = Integer.compare(years, other.years);
+ if (compareYears == 0) {
+ final int compareMonths = Integer.compare(months, other.months);
+ if (compareMonths == 0) {
+ return Integer.compare(days, other.days);
+ } else {
+ return compareMonths;
+ }
+ } else {
+ return compareYears;
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+}
diff --git a/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Logger.java b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Logger.java
new file mode 100644
index 0000000000..16c2945192
--- /dev/null
+++ b/packages/yard-validator-worker/src/main/java/org/yard/validator/util/Logger.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class Logger {
+
+ private static final Collection<Callback> callbacks = new ArrayList<>();
+
+ public static void startLogging(final Callback callback) {
+ Logger.callbacks.add(callback);
+ }
+
+ public static void log(final String s) {
+ for (Callback callback : callbacks) {
+ callback.callback(getTime() + " " + s);
+ }
+ }
+
+ private static String getTime() {
+ return System.currentTimeMillis() + "";
+ }
+}
diff --git a/packages/yard-validator-worker/src/test/java/org/yard/validator/ParserTest.java b/packages/yard-validator-worker/src/test/java/org/yard/validator/ParserTest.java
new file mode 100644
index 0000000000..f608ca6456
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/java/org/yard/validator/ParserTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+
+import org.junit.Test;
+import org.yard.validator.key.Key;
+import org.yard.validator.key.Location;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+import java.util.Scanner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ParserTest {
+
+ @Test
+ public void inlineRuleTest() throws IOException {
+ final String read = read("traffic-violation.yml");
+ final ParserResult parse = new Parser().parse(read);
+
+
+ for (Location location : parse.getResult().keySet()) {
+ System.out.println(location);
+
+ for (Key key : parse.getResult().get(location).toArray(new Key[parse.getResult().get(location).size()])) {
+ System.out.println(key);
+ }
+ }
+ assertEquals(4, parse.getResult().keySet().size());
+ }
+
+ @Test
+ public void whenThenRuleTest() throws IOException {
+ final String read = read("service-price.yml");
+ final ParserResult parse = new Parser().parse(read);
+
+
+ for (Location location : parse.getResult().keySet()) {
+ System.out.println(location);
+ for (Key key : parse.getResult().get(location).toArray(new Key[parse.getResult().get(location).size()])) {
+ System.out.println(key);
+ }
+ }
+ assertEquals(4, parse.getResult().keySet().size());
+ }
+
+ private String read(final String name) throws FileNotFoundException {
+ final StringBuffer buffer = new StringBuffer();
+
+ final URL resource = ParserTest.class.getResource(name);
+
+ final Scanner sc = new Scanner(new File(resource.getFile()));
+
+ while (sc.hasNextLine()) {
+ buffer.append(sc.nextLine());
+ buffer.append(System.lineSeparator());
+ }
+
+ return buffer.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/packages/yard-validator-worker/src/test/java/org/yard/validator/YardValidatorTest.java b/packages/yard-validator-worker/src/test/java/org/yard/validator/YardValidatorTest.java
new file mode 100644
index 0000000000..6a8b259349
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/java/org/yard/validator/YardValidatorTest.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator;
+
+import org.junit.Test;
+import org.yard.validator.key.Location;
+import org.yard.validator.key.RowLocation;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class YardValidatorTest {
+
+ @Test
+ public void subsumption() throws FileNotFoundException {
+ final String read = read("subsumption.yml");
+ final YardValidator validator = new YardValidator();
+
+ final List<Issue> issues = new ArrayList<>();
+
+ validator.validate(read, issues::add);
+
+ for (Issue issue : issues) {
+ System.out.println(issue.getMessage());
+ }
+
+ assertEquals(1, issues.size());
+ assertIssue(issues.get(0), "Subsumption found. If both rows return the same result, the other can be removed. If they return different results, the table fails to return a value.", 2, 3);
+
+ }
+
+ @Test
+ public void subsumptionTheOtherWay() throws FileNotFoundException {
+ final String read = read("subsumption-the-other-way.yml");
+ final YardValidator validator = new YardValidator();
+
+ final List<Issue> issues = new ArrayList<>();
+
+ validator.validate(read, issues::add);
+
+ for (Issue issue : issues) {
+ System.out.println(issue.getMessage());
+ }
+
+ assertEquals(1, issues.size());
+ assertIssue(issues.get(0), "Subsumption found. If both rows return the same result, the other can be removed. If they return different results, the table fails to return a value.", 2, 3);
+
+ }
+
+ @Test
+ public void maskingRule() throws FileNotFoundException {
+ final String read = read("subsumption-the-other-way.yml", "First");
+ final YardValidator validator = new YardValidator();
+
+ final List<Issue> issues = new ArrayList<>();
+
+ validator.validate(read, issues::add);
+
+ assertEquals(1, issues.size());
+ assertIssue(issues.get(0), "Masking row. The higher row prevents the activation of the other row.", 2, 3);
+ }
+
+ @Test
+ public void redundancy() throws FileNotFoundException {
+ final String read = read("redundancy.yml");
+ final YardValidator validator = new YardValidator();
+
+ final List<Issue> issues = new ArrayList<>();
+
+ validator.validate(read, issues::add);
+
+ for (Issue issue : issues) {
+ System.out.println(issue.getMessage());
+ }
+
+ assertEquals(1, issues.size());
+ assertIssue(issues.get(0), "Redundancy found. If both rows return the same result, the other can be removed. If they return different results, the table fails to return a value.", 1, 2);
+ }
+
+ @Test
+ public void redundancyWithUniqueHP() throws FileNotFoundException {
+ final String read = read("redundancy.yml", "Unique");
+ final YardValidator validator = new YardValidator();
+
+ final List<Issue> issues = new ArrayList<>();
+
+ validator.validate(read, issues::add);
+
+ for (Issue issue : issues) {
+ System.out.println(issue.getMessage());
+ }
+
+ assertEquals(1, issues.size());
+ assertIssue(issues.get(0), "Redundancy found. Unique hit policy fails when more than one row returns results.", 1, 2);
+ }
+ private void assertIssue(
+ final Issue issue,
+ final String message,
+ final Integer... wantedRows) {
+ final List<Integer> rows = Arrays.asList(wantedRows);
+ assertEquals(message, issue.getMessage());
+
+ for (Location location : issue.getLocations()) {
+ System.out.println(location);
+ }
+
+ assertEquals(issue.getLocations().length, rows.size());
+ for (Location location : issue.getLocations()) {
+ if (location instanceof RowLocation) {
+ assertTrue(rows.contains(((RowLocation) location).getTableRowNumber()));
+ }
+ }
+ }
+
+ private String read(final String name) throws FileNotFoundException {
+ return read(name, null);
+ }
+
+ private String read(
+ final String name,
+ final String hitPolicy) throws FileNotFoundException {
+ final StringBuilder buffer = new StringBuilder();
+
+ final URL resource = ParserTest.class.getResource(name);
+
+ final Scanner sc = new Scanner(new File(resource.getFile()));
+
+ while (sc.hasNextLine()) {
+ final String line = sc.nextLine();
+ buffer.append(line);
+ buffer.append(System.lineSeparator());
+ if (hitPolicy != null && line.trim().startsWith("outputComponents")) {
+ buffer.append(" hitPolicy: ").append(hitPolicy);
+ buffer.append(System.lineSeparator());
+ }
+ }
+
+ return buffer.toString();
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-validator-worker/src/test/java/org/yard/validator/util/DateTest.java b/packages/yard-validator-worker/src/test/java/org/yard/validator/util/DateTest.java
new file mode 100644
index 0000000000..8e86722dc4
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/java/org/yard/validator/util/DateTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.yard.validator.util;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+public class DateTest {
+
+ private final String givenDateA;
+ private final String givenDateB;
+ private final int expectedNumber;
+
+ public DateTest(final String givenDateA,
+ final String givenDateB,
+ final int expectedNumber) {
+
+ this.givenDateA = givenDateA;
+ this.givenDateB = givenDateB;
+ this.expectedNumber = expectedNumber;
+ }
+
+ @Parameterized.Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {"2000-10-30", "2000-10-30", 0},
+ {"2000-10-30", "2000-10-31", -1},
+ {"2000-10-31", "2000-10-30", 1},
+ {"2000-10-30", "2000-11-30", -1},
+ {"2000-11-30", "2000-10-30", 1},
+ {"2000-10-30", "2001-10-30", -1},
+ {"2001-10-30", "2000-10-30", 1}
+ });
+ }
+
+ @Test
+ public void test() {
+ assertEquals(expectedNumber,
+ new Date(givenDateA).compareTo(
+ new Date(givenDateB)));
+
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/redundancy.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/redundancy.yml
new file mode 100644
index 0000000000..ac98c5e21b
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/redundancy.yml
@@ -0,0 +1,26 @@
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', "[10..30)", 500, 3]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/service-price.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/service-price.yml
new file mode 100644
index 0000000000..bd00ac3d73
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/service-price.yml
@@ -0,0 +1,24 @@
+specVersion: alpha
+kind: YaRD
+name: "BasePrice"
+expressionLang: alpha
+inputs:
+ - name: "Age"
+ type: date
+ - name: "Previous incidents?"
+ type: boolean
+elements:
+ - name: "Base price"
+ type: Decision
+ logic:
+ type: DecisionTable
+ inputs: ["Age", "Previous incidents?"]
+ rules:
+ - when: ["<2017-09-07", false]
+ then: 800
+ - when: ["<2017-09-07", true]
+ then: 1000
+ - when: [">=2017-09-07", false]
+ then: 500
+ - when: [">=2017-09-07", true]
+ then: 650
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption-the-other-way.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption-the-other-way.yml
new file mode 100644
index 0000000000..38edae6a80
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption-the-other-way.yml
@@ -0,0 +1,29 @@
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', ">= 60", 1000, 7]
+ - ['="speed"', ">= 30", 1000, 7]
+ - ['="parking"', "-", 100, 1]
+ - ['="driving under the influence"', "-", 1000, 5]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption.yml
new file mode 100644
index 0000000000..0eb20657f7
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/subsumption.yml
@@ -0,0 +1,29 @@
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', ">= 30", 1000, 7]
+ - ['="speed"', ">= 60", 1000, 7]
+ - ['="parking"', "-", 100, 1]
+ - ['="driving under the influence"', "-", 1000, 5]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation-empty-row.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation-empty-row.yml
new file mode 100644
index 0000000000..0eb20657f7
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation-empty-row.yml
@@ -0,0 +1,29 @@
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', ">= 30", 1000, 7]
+ - ['="speed"', ">= 60", 1000, 7]
+ - ['="parking"', "-", 100, 1]
+ - ['="driving under the influence"', "-", 1000, 5]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
diff --git a/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation.yml b/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation.yml
new file mode 100644
index 0000000000..452ff7505f
--- /dev/null
+++ b/packages/yard-validator-worker/src/test/resources/org/yard/validator/traffic-violation.yml
@@ -0,0 +1,28 @@
+specVersion: alpha
+kind: YaRD
+name: "Traffic Violation"
+expressionLang: alpha
+inputs:
+ - name: "Driver"
+ type: "http://myapi.org/jsonSchema.json#Driver"
+ - name: "Violation"
+ type: "http://myapi.org/jsonSchema.json#Violation"
+elements:
+ - name: "Fine"
+ type: Decision
+ requirements: ["Violation"]
+ logic:
+ type: DecisionTable
+ inputs: ["Violation.type", "Violation.Actual Speed - Violation.Speed Limit"]
+ outputComponents: ["Amount", "Points"]
+ rules:
+ - ['="speed"', "[10..30)", 500, 3]
+ - ['="speed"', ">= 30", 1000, 7]
+ - ['="parking"', "-", 100, 1]
+ - ['="driving under the influence"', "-", 1000, 5]
+ - name: "Should the driver be suspended?"
+ type: Decision
+ requirements: ["Driver", "Fine"]
+ logic:
+ type: LiteralExpression
+ expression: 'if Driver.Points + Fine.Points >= 20 then "Yes" else "No"'
diff --git a/packages/yard-validator/README.md b/packages/yard-validator/README.md
new file mode 100644
index 0000000000..5ecc889f2c
--- /dev/null
+++ b/packages/yard-validator/README.md
@@ -0,0 +1,8 @@
+## YARD validator
+
+###### Module for YARD (Yet Another Rule Definition) validation.
+
+### When used in an editor
+
+The TypeScript source provides methods for getting the reporting as VSCode compatible Notifications.
+The webworker file needs to be included separately.
diff --git a/packages/yard-validator/env/index.js b/packages/yard-validator/env/index.js
new file mode 100644
index 0000000000..26e1811bd5
--- /dev/null
+++ b/packages/yard-validator/env/index.js
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const { varsWithName, composeEnv } = require("@kie-tools-scripts/build-env");
+
+module.exports = composeEnv([require("@kie-tools/root-env/env")], {
+ vars: varsWithName({}),
+ get env() {
+ return {
+ yardValidator: {
+ version: require("../package.json").version,
+ },
+ };
+ },
+});
diff --git a/packages/yard-validator/install.js b/packages/yard-validator/install.js
new file mode 100644
index 0000000000..4247286a3f
--- /dev/null
+++ b/packages/yard-validator/install.js
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const buildEnv = require("./env");
+const { setup } = require("@kie-tools/maven-config-setup-helper");
+
+setup(`
+ -Drevision=${buildEnv.env.yardValidator.version}
+`);
diff --git a/packages/yard-validator/package.json b/packages/yard-validator/package.json
new file mode 100644
index 0000000000..fb1bc88f4e
--- /dev/null
+++ b/packages/yard-validator/package.json
@@ -0,0 +1,44 @@
+{
+ "private": false,
+ "name": "@kie-tools/yard-validator",
+ "version": "0.0.0",
+ "description": "",
+ "license": "Apache-2.0",
+ "keywords": [],
+ "homepage": "https://github.com/kiegroup/kie-tools",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/kiegroup/kie-tools.git"
+ },
+ "bugs": {
+ "url": "https://github.com/kiegroup/kie-tools/issues"
+ },
+ "scripts": {
+ "build:dev": "rimraf dist && tsc -p tsconfig.json && pnpm copy:webworker",
+ "build:prod": "pnpm lint && tsc -p tsconfig.json && pnpm copy:webworker",
+ "copy:webworker": "copyfiles -f node_modules/@kie-tools/yard-validator-worker/dist/yard-validator-worker.js dist",
+ "install": "node install.js",
+ "install:mvnw": "run-script-os",
+ "lint": "echo 'Linting'",
+ "powershell": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command"
+ },
+ "dependencies": {
+ "@kie-tools-core/notifications": "workspace:*",
+ "@kie-tools/yard-validator-worker": "workspace:*"
+ },
+ "devDependencies": {
+ "@kie-tools/maven-config-setup-helper": "workspace:*",
+ "@kie-tools/root-env": "workspace:*",
+ "@kie-tools/tsconfig": "workspace:*",
+ "copyfiles": "^2.4.1",
+ "rimraf": "^3.0.2",
+ "run-script-os": "^1.1.6",
+ "typescript": "^4.6.2"
+ },
+ "kieTools": {
+ "requiredPreinstalledCliCommands": [
+ "java",
+ "mvn"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/packages/yard-validator/src/ValidationResult.ts b/packages/yard-validator/src/ValidationResult.ts
new file mode 100644
index 0000000000..41ad01fb62
--- /dev/null
+++ b/packages/yard-validator/src/ValidationResult.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export interface ValidationResult {
+ log: string[];
+ result: Result[];
+}
+
+export interface Result {
+ issue: string;
+ locations: Location[];
+}
+
+export interface Location {
+ rowInFile: number;
+ rowInTable: number;
+}
diff --git a/packages/yard-validator/src/index.ts b/packages/yard-validator/src/index.ts
new file mode 100644
index 0000000000..6e2da143b3
--- /dev/null
+++ b/packages/yard-validator/src/index.ts
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export * from "./main";
diff --git a/packages/yard-validator/src/main.ts b/packages/yard-validator/src/main.ts
new file mode 100644
index 0000000000..58c9fbccf6
--- /dev/null
+++ b/packages/yard-validator/src/main.ts
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Notification } from "@kie-tools-core/notifications/dist/api";
+import { ValidationResult } from "./ValidationResult";
+
+export function validationPromise(yaml: String): Promise<Notification[]> {
+ return new Promise((resolve, reject) => {
+ const worker = new Worker("/yard-validator-worker.js");
+ worker.postMessage(yaml);
+ worker.onmessage = (e) => {
+ const notifications: Notification[] = [];
+
+ try {
+ const validationResult: ValidationResult = JSON.parse(e.data);
+
+ for (const result of validationResult.result) {
+ for (const location of result.locations) {
+ notifications.push({
+ path: "",
+ severity: "ERROR",
+ message: result.issue,
+ type: "PROBLEM",
+ position: {
+ startLineNumber: location.rowInFile,
+ startColumn: 0,
+ endLineNumber: 0,
+ endColumn: 0,
+ },
+ });
+ }
+ }
+ } catch (e) {
+ // We add nothing since json is malformed.
+ }
+ resolve(notifications);
+ worker.terminate();
+ };
+ });
+}
diff --git a/packages/yard-validator/tsconfig.json b/packages/yard-validator/tsconfig.json
new file mode 100644
index 0000000000..253b1749aa
--- /dev/null
+++ b/packages/yard-validator/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@kie-tools/tsconfig/tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true
+ },
+ "include": ["./src"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 893f9a55b2..28193d2b2b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5421,7 +5421,7 @@ importers:
version: 4.8.4
url-loader:
specifier: ^4.1.1
- version: 4.1.1(webpack@5.88.2)
+ version: 4.1.1(file-loader@6.2.0)(webpack@5.88.2)
webpack:
specifier: ^5.88.2
version: 5.88.2(webpack-cli@4.10.0)
@@ -5834,7 +5834,7 @@ importers:
version: 4.1.1(file-loader@6.2.0)(webpack@5.88.2)
webpack:
specifier: ^5.88.2
- version: 5.88.2
+ version: 5.88.2(webpack-cli@4.10.0)
packages/playwright-base:
devDependencies:
@@ -6851,6 +6851,9 @@ importers:
"@kie-tools/yard-language-service":
specifier: workspace:*
version: link:../yard-language-service
+ "@kie-tools/yard-validator":
+ specifier: workspace:*
+ version: link:../yard-validator
"@octokit/plugin-rest-endpoint-methods":
specifier: ^5.0.1
version: 5.0.1(@octokit/core@3.4.0)
@@ -8655,10 +8658,10 @@ importers:
version: 4.8.4
webpack:
specifier: ^5.88.2
- version: 5.88.2
+ version: 5.88.2(webpack-cli@4.10.0)
webpack-dev-server:
specifier: ^4.15.1
- version: 4.15.1(webpack@5.88.2)
+ version: 4.15.1(webpack-cli@4.10.0)(webpack@5.88.2)
webpack-merge:
specifier: ^5.9.0
version: 5.9.0
@@ -9541,7 +9544,7 @@ importers:
version: 9.4.2(typescript@4.8.4)(webpack@5.88.2)
webpack:
specifier: ^5.88.2
- version: 5.88.2
+ version: 5.88.2(webpack-cli@4.10.0)
packages/workspace:
dependencies:
@@ -9894,6 +9897,9 @@ importers:
"@kie-tools/yard-language-service":
specifier: workspace:*
version: link:../yard-language-service
+ "@kie-tools/yard-validator":
+ specifier: workspace:*
+ version: link:../yard-validator
"@patternfly/react-core":
specifier: ^4.276.6
version: 4.276.6(react-dom@17.0.2)(react@17.0.2)
@@ -10086,6 +10092,96 @@ importers:
specifier: ^4.6.2
version: 4.8.4
+ packages/yard-model:
+ dependencies:
+ "@kie-tools-core/notifications":
+ specifier: workspace:*
+ version: link:../notifications
+ devDependencies:
+ "@kie-tools/maven-config-setup-helper":
+ specifier: workspace:*
+ version: link:../maven-config-setup-helper
+ "@kie-tools/root-env":
+ specifier: workspace:*
+ version: link:../root-env
+ copy-webpack-plugin:
+ specifier: ^11.0.0
+ version: 11.0.0(webpack@5.88.2)
+ rimraf:
+ specifier: ^3.0.2
+ version: 3.0.2
+ run-script-os:
+ specifier: ^1.1.6
+ version: 1.1.6
+ typescript:
+ specifier: ^4.6.2
+ version: 4.8.4
+ webpack:
+ specifier: ^5.88.2
+ version: 5.88.2(webpack-cli@4.10.0)
+
+ packages/yard-validator:
+ dependencies:
+ "@kie-tools-core/notifications":
+ specifier: workspace:*
+ version: link:../notifications
+ "@kie-tools/yard-validator-worker":
+ specifier: workspace:*
+ version: link:../yard-validator-worker
+ devDependencies:
+ "@kie-tools/maven-config-setup-helper":
+ specifier: workspace:*
+ version: link:../maven-config-setup-helper
+ "@kie-tools/root-env":
+ specifier: workspace:*
+ version: link:../root-env
+ "@kie-tools/tsconfig":
+ specifier: workspace:*
+ version: link:../tsconfig
+ copyfiles:
+ specifier: ^2.4.1
+ version: 2.4.1
+ rimraf:
+ specifier: ^3.0.2
+ version: 3.0.2
+ run-script-os:
+ specifier: ^1.1.6
+ version: 1.1.6
+ typescript:
+ specifier: ^4.6.2
+ version: 4.8.4
+
+ packages/yard-validator-worker:
+ dependencies:
+ "@kie-tools-core/notifications":
+ specifier: workspace:*
+ version: link:../notifications
+ "@kie-tools/yard-model":
+ specifier: workspace:*
+ version: link:../yard-model
+ devDependencies:
+ "@kie-tools/maven-config-setup-helper":
+ specifier: workspace:*
+ version: link:../maven-config-setup-helper
+ "@kie-tools/root-env":
+ specifier: workspace:*
+ version: link:../root-env
+ "@kie-tools/tsconfig":
+ specifier: workspace:*
+ version: link:../tsconfig
+ copyfiles:
+ specifier: ^2.4.1
+ version: 2.4.1
+ rimraf:
+ specifier: ^3.0.2
+ version: 3.0.2
+ run-script-os:
+ specifier: ^1.1.6
+ version: 1.1.6
+ typescript:
+ specifier: ^4.6.2
+ version: 4.8.4
+
packages/yard-vscode-extension:
dependencies:
"@kie-tools-core/backend":
@@ -11092,7 +11188,7 @@ packages:
"@babel/compat-data": 7.21.7
"@babel/core": 7.16.12
"@babel/helper-validator-option": 7.21.0
- browserslist: 4.21.5
+ browserslist: 4.22.1
semver: 6.3.1
dev: true
@@ -11106,7 +11202,7 @@ packages:
"@babel/compat-data": 7.21.7
"@babel/core": 7.23.0
"@babel/helper-validator-option": 7.21.0
- browserslist: 4.21.5
+ browserslist: 4.22.1
semver: 6.3.1
dev: true
@@ -11120,7 +11216,7 @@ packages:
"@babel/compat-data": 7.21.7
"@babel/core": 7.16.12
"@babel/helper-validator-option": 7.21.0
- browserslist: 4.21.5
+ browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
dev: true
@@ -11135,7 +11231,7 @@ packages:
"@babel/compat-data": 7.21.7
"@babel/core": 7.18.10
"@babel/helper-validator-option": 7.21.0
- browserslist: 4.21.5
+ browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
dev: true
@@ -11150,7 +11246,7 @@ packages:
"@babel/compat-data": 7.21.7
"@babel/core": 7.23.0
"@babel/helper-validator-option": 7.21.0
- browserslist: 4.21.5
+ browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
dev: true
@@ -23878,15 +23974,6 @@ packages:
acorn: 8.10.0
dev: true
- /acorn-import-assertions@1.9.0(acorn@8.8.2):
- resolution:
- { integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== }
- peerDependencies:
- acorn: ^8
- dependencies:
- acorn: 8.8.2
- dev: true
-
/acorn-jsx@5.3.2(acorn@7.4.1):
resolution:
{ integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== }
@@ -24733,8 +24820,8 @@ packages:
peerDependencies:
postcss: ^8.1.0
dependencies:
- browserslist: 4.21.5
- caniuse-lite: 1.0.30001486
+ browserslist: 4.22.1
+ caniuse-lite: 1.0.30001547
fraction.js: 4.2.0
normalize-range: 0.1.2
picocolors: 1.0.0
@@ -25491,10 +25578,10 @@ packages:
engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001332
- electron-to-chromium: 1.4.107
+ caniuse-lite: 1.0.30001547
+ electron-to-chromium: 1.4.549
escalade: 3.1.1
- node-releases: 2.0.3
+ node-releases: 2.0.13
picocolors: 1.0.0
dev: true
@@ -25504,10 +25591,10 @@ packages:
engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001486
- electron-to-chromium: 1.4.388
- node-releases: 2.0.10
- update-browserslist-db: 1.0.11(browserslist@4.21.5)
+ caniuse-lite: 1.0.30001547
+ electron-to-chromium: 1.4.549
+ node-releases: 2.0.13
+ update-browserslist-db: 1.0.13(browserslist@4.21.5)
dev: true
/browserslist@4.22.1:
@@ -25856,16 +25943,6 @@ packages:
path-temp: 2.0.0
dev: true
- /caniuse-lite@1.0.30001332:
- resolution:
- { integrity: sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== }
- dev: true
-
- /caniuse-lite@1.0.30001486:
- resolution:
- { integrity: sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg== }
- dev: true
-
/caniuse-lite@1.0.30001547:
resolution:
{ integrity: sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA== }
@@ -26672,7 +26749,7 @@ packages:
globby: 13.1.2
normalize-path: 3.0.0
schema-utils: 4.0.0
- serialize-javascript: 6.0.0
+ serialize-javascript: 6.0.1
webpack: 5.76.1(esbuild@0.15.5)
dev: true
@@ -26688,7 +26765,7 @@ packages:
globby: 13.1.2
normalize-path: 3.0.0
schema-utils: 4.0.0
- serialize-javascript: 6.0.0
+ serialize-javascript: 6.0.1
webpack: 5.88.2(webpack-cli@4.10.0)
dev: true
@@ -26709,7 +26786,7 @@ packages:
resolution:
{ integrity: sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== }
dependencies:
- browserslist: 4.21.5
+ browserslist: 4.22.1
semver: 7.0.0
dev: true
@@ -26717,7 +26794,7 @@ packages:
resolution:
{ integrity: sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA== }
dependencies:
- browserslist: 4.21.5
+ browserslist: 4.22.1
dev: true
/core-js-compat@3.33.0:
@@ -28257,16 +28334,6 @@ packages:
jake: 10.8.7
dev: true
- /electron-to-chromium@1.4.107:
- resolution:
- { integrity: sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg== }
- dev: true
-
- /electron-to-chromium@1.4.388:
- resolution:
- { integrity: sha512-xZ0y4zjWZgp65okzwwt00f2rYibkFPHUv9qBz+Vzn8cB9UXIo9Zc6Dw81LJYhhNt0G/vR1OJEfStZ49NKl0YxQ== }
- dev: true
-
/electron-to-chromium@1.4.549:
resolution:
{ integrity: sha512-gpXfJslSi4hYDkA0mTLEpYKRv9siAgSUgZ+UWyk+J5Cttpd1ThCVwdclzIwQSclz3hYn049+M2fgrP1WpvF8xg== }
@@ -28408,7 +28475,7 @@ packages:
engines: { node: ">=10.13.0" }
dependencies:
graceful-fs: 4.2.11
- tapable: 2.2.0
+ tapable: 2.2.1
dev: true
/enhanced-resolve@5.9.3:
@@ -28417,7 +28484,7 @@ packages:
engines: { node: ">=10.13.0" }
dependencies:
graceful-fs: 4.2.11
- tapable: 2.2.0
+ tapable: 2.2.1
dev: true
/enquirer@2.3.6:
@@ -30035,7 +30102,7 @@ packages:
is-glob: 4.0.3
normalize-path: 3.0.0
schema-utils: 4.0.0
- webpack: 5.88.2
+ webpack: 5.88.2(webpack-cli@4.10.0)
dev: true
/filename-reserved-regex@2.0.0:
@@ -31418,7 +31485,7 @@ packages:
html-minifier-terser: 6.1.0
lodash: 4.17.21
pretty-error: 4.0.0
- tapable: 2.2.0
+ tapable: 2.2.1
webpack: 5.88.2(@swc/core@1.3.92)(esbuild@0.18.20)(webpack-cli@4.10.0)
dev: true
@@ -33965,7 +34032,7 @@ packages:
dependencies:
glob: 7.2.0
minimatch: 3.0.5
- webpack: 5.88.2
+ webpack: 5.88.2(webpack-cli@4.10.0)
webpack-merge: 4.2.2
dev: true
@@ -35869,21 +35936,11 @@ packages:
webpack: 5.88.2(webpack-cli@4.10.0)
dev: true
- /node-releases@2.0.10:
- resolution:
- { integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== }
- dev: true
-
/node-releases@2.0.13:
resolution:
{ integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== }
dev: true
- /node-releases@2.0.3:
- resolution:
- { integrity: sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== }
- dev: true
-
/node.extend@2.0.2:
resolution:
{ integrity: sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ== }
@@ -37608,7 +37665,7 @@ packages:
"@csstools/postcss-trigonometric-functions": 1.0.2(postcss@8.4.16)
"@csstools/postcss-unset-value": 1.0.2(postcss@8.4.16)
autoprefixer: 10.4.14(postcss@8.4.16)
- browserslist: 4.21.5
+ browserslist: 4.22.1
css-blank-pseudo: 3.0.3(postcss@8.4.16)
css-has-pseudo: 3.0.4(postcss@8.4.16)
css-prefers-color-scheme: 6.0.3(postcss@8.4.16)
@@ -39797,7 +39854,7 @@ packages:
klona: 2.0.5
neo-async: 2.6.2
sass: 1.49.9
- webpack: 5.88.2
+ webpack: 5.88.2(webpack-cli@4.10.0)
dev: true
/sass-loader@13.0.2(sass@1.54.4)(webpack@5.76.1):
@@ -40502,7 +40559,7 @@ packages:
abab: 2.0.5
iconv-lite: 0.6.3
source-map-js: 0.6.2
- webpack: 5.88.2
+ webpack: 5.88.2(webpack-cli@4.10.0)
dev: true
/source-map-loader@4.0.0(webpack@5.76.1):
@@ -42386,9 +42443,9 @@ packages:
setimmediate: 1.0.5
dev: true
- /update-browserslist-db@1.0.11(browserslist@4.21.5):
+ /update-browserslist-db@1.0.13(browserslist@4.21.5):
resolution:
- { integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== }
+ { integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== }
hasBin: true
peerDependencies:
browserslist: ">= 4.21.0"
@@ -42458,23 +42515,6 @@ packages:
optional: true
dependencies:
file-loader: 6.2.0(webpack@5.88.2)
- loader-utils: 2.0.2
- mime-types: 2.1.34
- schema-utils: 3.1.1
- webpack: 5.88.2
- dev: true
-
- /url-loader@4.1.1(webpack@5.88.2):
- resolution:
- { integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== }
- engines: { node: ">= 10.13.0" }
- peerDependencies:
- file-loader: "*"
- webpack: ^4.0.0 || ^5.0.0
- peerDependenciesMeta:
- file-loader:
- optional: true
- dependencies:
loader-utils: 2.0.2
mime-types: 2.1.34
schema-utils: 3.1.1
@@ -43481,58 +43521,6 @@ packages:
- utf-8-validate
dev: true
- /webpack-dev-server@4.15.1(webpack@5.88.2):
- resolution:
- { integrity: sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== }
- engines: { node: ">= 12.13.0" }
- hasBin: true
- peerDependencies:
- webpack: ^4.37.0 || ^5.0.0
- webpack-cli: "*"
- peerDependenciesMeta:
- webpack:
- optional: true
- webpack-cli:
- optional: true
- dependencies:
- "@types/bonjour": 3.5.10
- "@types/connect-history-api-fallback": 1.3.5
- "@types/express": 4.17.17
- "@types/serve-index": 1.9.1
- "@types/serve-static": 1.13.10
- "@types/sockjs": 0.3.33
- "@types/ws": 8.5.5
- ansi-html-community: 0.0.8
- bonjour-service: 1.1.1
- chokidar: 3.5.3
- colorette: 2.0.16
- compression: 1.7.4
- connect-history-api-fallback: 2.0.0
- default-gateway: 6.0.3
- express: 4.18.2
- graceful-fs: 4.2.11
- html-entities: 2.3.2
- http-proxy-middleware: 2.0.6(@types/express@4.17.17)
- ipaddr.js: 2.0.1
- launch-editor: 2.6.0
- open: 8.4.0
- p-retry: 4.6.1
- rimraf: 3.0.2
- schema-utils: 4.0.0
- selfsigned: 2.1.1
- serve-index: 1.9.1
- sockjs: 0.3.24
- spdy: 4.0.2
- webpack: 5.88.2
- webpack-dev-middleware: 5.3.3(webpack@5.88.2)
- ws: 8.13.0
- transitivePeerDependencies:
- - bufferutil
- - debug
- - supports-color
- - utf-8-validate
- dev: true
-
/webpack-hot-middleware@2.25.4:
resolution:
{ integrity: sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w== }
@@ -43617,7 +43605,7 @@ packages:
"@webassemblyjs/wasm-parser": 1.11.1
acorn: 8.10.0
acorn-import-assertions: 1.9.0(acorn@8.10.0)
- browserslist: 4.21.5
+ browserslist: 4.22.1
chrome-trace-event: 1.0.2
enhanced-resolve: 5.15.0
es-module-lexer: 0.9.3
@@ -43630,7 +43618,7 @@ packages:
mime-types: 2.1.34
neo-async: 2.6.2
schema-utils: 3.3.0
- tapable: 2.2.0
+ tapable: 2.2.1
terser-webpack-plugin: 5.3.9(esbuild@0.15.5)(webpack@5.76.1)
watchpack: 2.4.0
webpack-sources: 3.2.3
@@ -43640,47 +43628,6 @@ packages:
- uglify-js
dev: true
- /webpack@5.88.2:
- resolution:
- { integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== }
- engines: { node: ">=10.13.0" }
- hasBin: true
- peerDependencies:
- webpack-cli: "*"
- peerDependenciesMeta:
- webpack-cli:
- optional: true
- dependencies:
- "@types/eslint-scope": 3.7.3
- "@types/estree": 1.0.1
- "@webassemblyjs/ast": 1.11.6
- "@webassemblyjs/wasm-edit": 1.11.6
- "@webassemblyjs/wasm-parser": 1.11.6
- acorn: 8.10.0
- acorn-import-assertions: 1.9.0(acorn@8.10.0)
- browserslist: 4.21.5
- chrome-trace-event: 1.0.2
- enhanced-resolve: 5.15.0
- es-module-lexer: 1.3.0
- eslint-scope: 5.1.1
- events: 3.3.0
- glob-to-regexp: 0.4.1
- graceful-fs: 4.2.11
- json-parse-even-better-errors: 2.3.1
- loader-runner: 4.2.0
- mime-types: 2.1.34
- neo-async: 2.6.2
- schema-utils: 3.3.0
- tapable: 2.2.0
- terser-webpack-plugin: 5.3.9(webpack@5.88.2)
- watchpack: 2.4.0
- webpack-sources: 3.2.3
- transitivePeerDependencies:
- - "@swc/core"
- - esbuild
- - uglify-js
- dev: true
-
/webpack@5.88.2(@swc/core@1.3.92)(esbuild@0.18.20)(webpack-cli@4.10.0):
resolution:
{ integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== }
@@ -43739,8 +43686,8 @@ packages:
"@webassemblyjs/ast": 1.11.6
"@webassemblyjs/wasm-edit": 1.11.6
"@webassemblyjs/wasm-parser": 1.11.6
- acorn: 8.8.2
- acorn-import-assertions: 1.9.0(acorn@8.8.2)
+ acorn: 8.10.0
+ acorn-import-assertions: 1.9.0(acorn@8.10.0)
browserslist: 4.21.5
chrome-trace-event: 1.0.2
enhanced-resolve: 5.15.0
@@ -44248,12 +44195,12 @@ packages:
resolution:
{ integrity: sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== }
engines: { node: ">=10" }
+ dev: true
/yargs-parser@20.2.9:
resolution:
{ integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== }
engines: { node: ">=10" }
- dev: true
/yargs-parser@21.0.0:
resolution:
@@ -44300,7 +44247,7 @@ packages:
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
- yargs-parser: 20.2.7
+ yargs-parser: 20.2.9
/yargs@17.3.1:
resolution:
diff --git a/repo/graph.dot b/repo/graph.dot
index 96fc6b4494..0f74d57881 100644
--- a/repo/graph.dot
+++ b/repo/graph.dot
@@ -146,6 +146,9 @@ digraph G {
"vscode-extension-kogito-bundle" [ color = "blue", fontcolor = "blue", style = "rounded" ];
"@kie-tools/xml-parser-ts" [ color = "blue", fontcolor = "blue", style = "rounded" ];
"@kie-tools/yard-language-service" [ color = "blue", fontcolor = "blue", style = "rounded" ];
+ "@kie-tools/yard-validator" [ color = "blue", fontcolor = "blue", style = "rounded" ];
+ "@kie-tools/yard-model" [ color = "blue", fontcolor = "blue", style = "rounded" ];
+ "@kie-tools/yard-validator-worker" [ color = "blue", fontcolor = "blue", style = "rounded" ];
"yard-vscode-extension" [ color = "blue", fontcolor = "blue", style = "rounded" ];
"@kie-tools-scripts/build-env" [ color = "blue", fontcolor = "blue", style = "rounded" ];
"kie-tools-root" -> "@kie-tools-scripts/bootstrap" [ style = "dashed", color = "black" ];
@@ -479,8 +482,13 @@ digraph G {
"@kie-tools/yard-editor" -> "@kie-tools-core/editor" [ style = "solid", color = "blue" ];
"@kie-tools/yard-editor" -> "@kie-tools/i18n-common-dictionary" [ style = "solid", color = "blue" ];
"@kie-tools/yard-editor" -> "@kie-tools/yard-language-service" [ style = "solid", color = "blue" ];
+ "@kie-tools/yard-editor" -> "@kie-tools/yard-validator" [ style = "solid", color = "blue" ];
"@kie-tools/yard-editor" -> "@kie-tools-core/webpack-base" [ style = "dashed", color = "blue" ];
"@kie-tools/yard-language-service" -> "@kie-tools/json-yaml-language-service" [ style = "solid", color = "blue" ];
+ "@kie-tools/yard-model" -> "@kie-tools-core/notifications" [ style = "solid", color = "blue" ];
+ "@kie-tools/yard-model" -> "@kie-tools/maven-config-setup-helper" [ style = "dashed", color = "blue" ];
+ "@kie-tools/yard-validator" -> "@kie-tools/yard-validator-worker" [ style = "solid", color = "blue" ];
+ "@kie-tools/yard-validator-worker" -> "@kie-tools/yard-model" [ style = "solid", color = "blue" ];
"yard-vscode-extension" -> "@kie-tools-core/vscode-extension" [ style = "solid", color = "blue" ];
"yard-vscode-extension" -> "@kie-tools/yard-editor" [ style = "solid", color = "blue" ];
"yard-vscode-extension" -> "@kie-tools/vscode-extension-common-test-helpers" [ style = "dashed", color = "blue" ];
diff --git a/repo/graph.json b/repo/graph.json
index a58c636554..9a107df4ae 100644
--- a/repo/graph.json
+++ b/repo/graph.json
@@ -133,6 +133,7 @@
{ "id": "@kie-tools/serverless-logic-web-tools-swf-builder-image-env" },
{ "id": "@kie-tools/serverless-logic-web-tools-swf-dev-mode-image-env" },
{ "id": "@kie-tools/yard-language-service" },
+ { "id": "@kie-tools/yard-validator" },
{ "id": "@kie-tools/serverless-logic-web-tools-base-builder-image" },
{ "id": "@kie-tools/serverless-logic-web-tools-swf-builder-image" },
{ "id": "sonataflow-deployment-webapp" },
@@ -146,6 +147,8 @@
{ "id": "vscode-extension-dashbuilder-editor" },
{ "id": "vscode-extension-kie-ba-bundle" },
{ "id": "vscode-extension-kogito-bundle" },
+ { "id": "@kie-tools/yard-validator-worker" },
+ { "id": "@kie-tools/yard-model" },
{ "id": "yard-vscode-extension" }
],
"links": [
@@ -783,6 +786,7 @@
{ "source": "@kie-tools/yard-editor", "target": "@kie-tools-core/editor", "weight": 1 },
{ "source": "@kie-tools/yard-editor", "target": "@kie-tools/i18n-common-dictionary", "weight": 1 },
{ "source": "@kie-tools/yard-editor", "target": "@kie-tools/yard-language-service", "weight": 1 },
+ { "source": "@kie-tools/yard-editor", "target": "@kie-tools/yard-validator", "weight": 1 },
{ "source": "@kie-tools/yard-editor", "target": "@kie-tools-core/webpack-base", "weight": 1 },
{
"source": "@kie-tools/serverless-logic-web-tools-base-builder-image-env",
@@ -800,6 +804,7 @@
"weight": 1
},
{ "source": "@kie-tools/yard-language-service", "target": "@kie-tools/json-yaml-language-service", "weight": 1 },
+ { "source": "@kie-tools/yard-validator", "target": "@kie-tools/yard-validator-worker", "weight": 1 },
{
"source": "@kie-tools/serverless-logic-web-tools-base-builder-image",
"target": "@kie-tools/serverless-logic-web-tools-base-builder-image-env",
@@ -899,6 +904,9 @@
{ "source": "vscode-extension-kogito-bundle", "target": "@kie-tools-core/webpack-base", "weight": 1 },
{ "source": "vscode-extension-kogito-bundle", "target": "@kie-tools/eslint", "weight": 1 },
{ "source": "vscode-extension-kogito-bundle", "target": "@kie-tools/tsconfig", "weight": 1 },
+ { "source": "@kie-tools/yard-validator-worker", "target": "@kie-tools/yard-model", "weight": 1 },
+ { "source": "@kie-tools/yard-model", "target": "@kie-tools-core/notifications", "weight": 1 },
+ { "source": "@kie-tools/yard-model", "target": "@kie-tools/maven-config-setup-helper", "weight": 1 },
{ "source": "yard-vscode-extension", "target": "@kie-tools-core/vscode-extension", "weight": 1 },
{ "source": "yard-vscode-extension", "target": "@kie-tools/yard-editor", "weight": 1 },
{ "source": "yard-vscode-extension", "target": "@kie-tools/vscode-extension-common-test-helpers", "weight": 1 }
@@ -1068,6 +1076,9 @@
["@kie-tools/yaml-language-server", "packages/yaml-language-server"],
["@kie-tools/yard-editor", "packages/yard-editor"],
["@kie-tools/yard-language-service", "packages/yard-language-service"],
+ ["@kie-tools/yard-model", "packages/yard-model"],
+ ["@kie-tools/yard-validator", "packages/yard-validator"],
+ ["@kie-tools/yard-validator-worker", "packages/yard-validator-worker"],
["yard-vscode-extension", "packages/yard-vscode-extension"],
["@kie-tools-scripts/bootstrap", "scripts/bootstrap"],
["@kie-tools-scripts/build-env", "scripts/build-env"],
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org