Skip to content

Conversation

@renczesstefan
Copy link
Member

@renczesstefan renczesstefan commented Jun 4, 2025

Description

Implements NAE-2119

Dependencies

No new dependencies were introduced

Third party dependencies

No new dependencies were introduced

Blocking Pull requests

There are no dependencies on other PR

How Has Been This Tested?

This was tested manually and with unit tests.

Test Configuration

Name Tested on
OS macOS Sequoia 15.3.1
Runtime Java 21
Dependency Manager Maven 3.9.9n
Framework version Spring Boot 3.2.5
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @machacjozef
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features
    • Introduced new data field types, including CaseField and FilterField, with support for allowed networks and filter metadata.
    • Added support for immediate data fields in cases.
    • Enhanced internationalization fields to include full translation mappings.
  • Bug Fixes
    • Improved robustness in user phone number handling to prevent errors when attributes are missing.
    • Prevented potential null pointer exceptions in event messages and user realm ID assignment.
  • Refactor
    • Unified and clarified value retrieval across various field types for more consistent data access.
  • Documentation
    • Improved constructor and method annotations for better clarity and Elasticsearch compatibility.

machacjozef and others added 5 commits June 1, 2025 22:19
- Added transformation methods `transformCaseFieldField` and `transformFilterFieldField` to `ElasticCaseMappingService`.
- Introduced new classes `CaseField` and `FilterField` in both `elastic` and `spring.elastic` domains.
- Updated `I18nField` to include `translations` using a `Map<String, String>` and annotated it appropriately for ElasticSearch.
- Enhanced `GetDataEvent` to handle null values safely in `getMessage`.
- Modified `User` domain to handle `tel` attribute when `attributes` is null.
- Fixed formatting of multiple methods for better readability.
- Updated `docker-compose.yml` to correct misplaced `networks` and `volumes` definition.
…alization

- Introduced a `getValue` method to multiple field classes (`MapField`, `DataField`, `UserField`, `CaseField`, `DateField`, and others) to standardize data retrieval from field objects.
- Created a new `ImmediateField` class for representing immediate data fields in `ElasticCase`.
- Updated `ElasticCase` to include handling for `immediateData` with proper mapping from `ImmediateField`.
- Refactored imports across the affected classes to use `java.util.*` and streamline code.
- Enhanced `FileField` with support for file paths and proper serialization via `getValue`.
- Updated various field structure definitions to ensure clarity and consistency in field data management.

This change improves maintainability and provides better support for advanced data retrieval and serialization of field objects.
- Corrects the condition to check if the user is null before accessing its realmId. Prevents potential NullPointerException when the user object is not initialized.
@renczesstefan renczesstefan self-assigned this Jun 4, 2025
@renczesstefan renczesstefan added bugfix A change that fixes a bug Medium labels Jun 4, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 4, 2025

## Walkthrough

This update introduces new domain classes for case and filter fields with allowed network support, enhances data field value extraction methods, and adds translation mapping in I18n fields. It modifies ElasticCase to include immediate data, adjusts null-check logic in task user realm assignment, and improves null safety in user telephone handling. Minor YAML formatting and method signature refactorings are also present.

## Changes

| File(s)                                                                                                    | Change Summary |
|------------------------------------------------------------------------------------------------------------|---------------|
| application-engine/docker-compose.yml                                                                       | Moved `networks` and `volumes` sections below the commented kibana service; no functional change. |
| application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy | Capitalizes the `type` parameter in `createFilter` method for consistency. |
| application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java | Adds transformation for new `CaseField` and `FilterField` types; updates `transformI18nField` to include translations; refactors method signatures for readability. |
| application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java       | Alters null-check logic for assigning `userRealmId` in constructor. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java               | Adds null checks and map initialization in `getTelNumber()` and `setTelNumber()`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java    | Adds override: `getValue()` returns `booleanValue`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java     | Adds override: `getValue()` returns `buttonValue`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java       | Introduces abstract class `CaseField` with allowed nets and value extraction logic. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java       | Adds `getValue()` method returning first fulltext value. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java       | Adds override: `getValue()` returns `dateValue`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java     | Adds `immediateData` field; updates constructor and `update()` method to handle it. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java | Introduces abstract base class for fields with allowed networks. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java       | Adds `filePath` field; implements `getValue()` to return file value(s) with path. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java     | Introduces abstract class `FilterField` with allowed nets and metadata. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java       | Adds `translations` field; updates constructor; implements `getValue()` returning `I18nString`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java        | Adds `getValue()` method for key extraction logic. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java     | Adds `getValue()` method returning `numberValue`. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java       | Adds `getValue()` method returning user value(s) as objects. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java | Adds null safety in `getMessage()`; minor formatting. |
| nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java | Introduces `ImmediateField` class for immediate data mapping. |
| nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java | Adds `CaseField` class extending new elastic domain field; exposes allowed nets for Elasticsearch. |
| nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java | Adds `FilterField` class extending new elastic domain field; exposes allowed nets and filter metadata for Elasticsearch. |
| nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java | Updates constructor to include translations; adds getter for translations, annotated for Elasticsearch. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant WorkflowDomain
    participant ElasticCaseMappingService
    participant ElasticDomain

    WorkflowDomain->>ElasticCaseMappingService: transformDataField(dataField, netField)
    alt netField is CaseField
        ElasticCaseMappingService->>ElasticDomain: transformCaseFieldField(...)
        ElasticDomain-->>ElasticCaseMappingService: CaseField instance with allowedNets
    else netField is FilterField
        ElasticCaseMappingService->>ElasticDomain: transformFilterFieldField(...)
        ElasticDomain-->>ElasticCaseMappingService: FilterField instance with allowedNets and metadata
    else netField is I18nField
        ElasticCaseMappingService->>ElasticDomain: transformI18nField(...)
        ElasticDomain-->>ElasticCaseMappingService: I18nField with translations
    end
    ElasticCaseMappingService-->>WorkflowDomain: Optional<DataField>

Possibly related PRs


<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 9796d46549e9441f5cf8ea51edbabeec022428e0 and 891b24b8e3f483ac6c3dc786cb2f0dd6688f913c.

</details>

<details>
<summary>📒 Files selected for processing (4)</summary>

* `application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy` (3 hunks)
* `nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java` (1 hunks)
* `nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java` (2 hunks)
* `nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java` (2 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (4)</summary>

* nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
* nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
* application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
* nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (4)</summary>

* GitHub Check: task-list-completed
* GitHub Check: task-list-completed
* GitHub Check: Build
* GitHub Check: task-list-completed

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=netgrif/application-engine&utm_content=315):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@coderabbitai coderabbitai bot added the Small label Jun 4, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🔭 Outside diff range comments (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

35-45: ⚠️ Potential issue

Fix missing filePath initialization in array constructor.

The constructor for multiple FileFieldValue objects doesn't initialize the filePath array, but the getValue() method assumes it exists and tries to access filePath[i]. This will cause a NullPointerException at runtime.

Apply this fix to initialize the filePath array:

 public FileField(FileFieldValue[] values) {
     super(new String[values.length]);
+    this.filePath = new String[values.length];
     this.fileNameValue = new String[values.length];
     this.fileExtensionValue = new String[values.length];
     for (int i = 0; i < values.length; i++) {
         FileNameAndExtension extracted = this.extractFileExtensionFromName(values[i].getName());
         this.fileNameValue[i] = extracted.name;
         this.fileExtensionValue[i] = extracted.extension;
         super.fulltextValue[i] = values[i].getName();
+        this.filePath[i] = values[i].getPath();
     }
 }
🧹 Nitpick comments (6)
application-engine/docker-compose.yml (1)

70-70: Add missing newline at end of file.

YAMLLint reports a missing newline at EOF. Please append a trailing blank line to satisfy the new-line-at-end-of-file rule.

Apply this diff:

--- a/application-engine/docker-compose.yml
+++ b/application-engine/docker-compose.yml
@@ -70 +71 @@
     driver: local
+
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 70-70: no new line character at the end of file

(new-line-at-end-of-file)

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java (1)

20-22: Add missing @OverRide annotation.

The getValue() method overrides the parent class method but lacks the @Override annotation, which helps catch signature mismatches at compile time.

+@Override
 public Object getValue() {
     return numberValue;
 }
application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (1)

3-3: Unused or unsupported import of com.mchange.v2.lang.StringUtils.

The imported StringUtils is neither used in this class nor guaranteed on the classpath (no new dependencies were introduced). Remove this import to avoid compilation issues or confusion.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)

36-43: Consider return type consistency for the getValue() method.

The method logic is correct, but returning different types (String vs LinkedHashSet<String>) based on array size could lead to casting issues for consumers. Consider documenting this behavior clearly or providing type-safe alternatives.

However, this appears to be part of a broader standardization effort across field types, so the current implementation may be intentional for flexibility.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (1)

3-3: Remove unused import.

FileFieldValue is imported but not used in this class.

-import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue;
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (1)

22-25: Remove redundant getValue() method override.

The overridden getValue() method simply calls super.getValue() without adding any functionality. This override is unnecessary and can be removed to reduce code complexity.

-    @Override
-    public Object getValue() {
-        return super.getValue();
-    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06e0fea and 9796d46.

📒 Files selected for processing (23)
  • application-engine/docker-compose.yml (1 hunks)
  • application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (10 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (5 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (1)
  • Data (24-141)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (3)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (10-29)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1)
  • Data (10-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1)
  • NoArgsConstructor (8-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (2)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1)
  • NoArgsConstructor (10-32)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (1)
  • NoArgsConstructor (12-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (10-29)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1)
  • Data (10-23)
🪛 YAMLlint (1.37.1)
application-engine/docker-compose.yml

[error] 70-70: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (24)
application-engine/docker-compose.yml (1)

63-70: Approve repositioning of networks and volumes sections.

Moving the networks and volumes blocks to the bottom of the file follows common Docker Compose layout conventions and has no functional impact.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 70-70: no new line character at the end of file

(new-line-at-end-of-file)

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1)

20-23: LGTM! Proper method override implementation.

The getValue() method is correctly implemented with the @Override annotation and follows the established pattern for field value access.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java (1)

31-31: Excellent null safety improvement.

The added null check prevents potential NullPointerException and provides clear feedback when the message is null. This follows good defensive programming practices.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java (1)

26-30: LGTM! Clean implementation of the getValue() standardization.

The override correctly returns the dateValue field, aligning with the broader effort to standardize getValue() methods across field types. The implementation is simple, direct, and follows the expected pattern.

application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java (1)

89-89: LGTM! Improved null safety and consistency.

The change correctly applies the same null-check pattern used for userId on line 88, preventing potential NullPointerException when task.getUser() returns null. This ensures consistent null handling across both user-related field assignments.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (1)

7-8: LGTM! Proper import consolidation.

The import statements are appropriately consolidated to support the new getValue() method implementation.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java (1)

20-23: LGTM! Consistent getValue() implementation.

The method correctly overrides the parent's getValue() method to return the specific booleanValue field. This aligns with the standardization effort mentioned in the AI summary across multiple field types.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java (1)

344-346: LGTM! Good null safety improvement.

The early null check prevents NullPointerException and follows good defensive programming practices.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1)

18-25: LGTM! Clean implementation of translations support.

The addition of the translations field and updated constructor properly extends the I18nField functionality.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java (1)

1-27: LGTM! Well-implemented data class.

The ImmediateField class is cleanly designed with:

  • Proper Serializable implementation with explicit serialVersionUID
  • Clear constructor that extracts relevant field metadata
  • Focused responsibility as a lightweight field representation

The implementation follows best practices and integrates well with the broader elastic domain model enhancements.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (3)

64-64: Good addition of immediateData field.

The new immediateData field properly extends the ElasticCase model to include immediate field metadata.


118-118: Clean implementation of immediateData initialization.

The constructor properly maps from the Case object's immediate data to ImmediateField objects using an efficient stream approach.


139-139: Consistent update pattern for immediateData.

The update method correctly assigns the immediateData field, maintaining consistency with other field updates in the method.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (2)

15-17: LGTM! Constructor update aligns with domain class changes.

The updated constructor properly accepts the translations parameter and passes it to the superclass, maintaining consistency with the domain layer changes.


30-33: Good use of @Field(type = Flattened) for the translations map.

The Flattened field type is the appropriate choice for Map<String, String> in Elasticsearch, allowing efficient storage and querying of key-value pairs.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (2)

15-17: Constructor implementation looks correct.

The constructor properly delegates to the superclass with both parameters, maintaining the field hierarchy pattern.


19-22:

Details

✅ Verification successful

Verify the getValue() return type change.

The getValue() method returns a mutable ArrayList instead of the parent's single string value. While this makes sense for a field that may contain multiple case references, ensure that consuming code expects a List rather than a String.


🏁 Script executed:

#!/bin/bash
# Description: Check how CaseField.getValue() is used in the codebase
# Expected: Find usages that expect List return type

# Search for CaseField getValue() usage
rg -A 3 -B 1 "\.getValue\(\)" --type java | rg -A 5 -B 5 "CaseField"

# Search for any casting or type assumptions
ast-grep --pattern 'CaseField $_ = $$$;
$_.getValue()'

Length of output: 2715


CaseField.getValue() return type validated – no further action needed

In ElasticCaseMappingService.transformCaseFieldField, the call

String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);

already casts the returned value to List<String>. No other usages assume a single String.
All existing consumers expect a list, so the change is safe.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (2)

11-13: Constructor follows the correct pattern.

The constructor properly delegates to the superclass, maintaining consistency with other Spring adapter implementations.


15-24: Elasticsearch field mappings are correctly implemented.

Both getFulltextValue() and getAllowedNets() are properly annotated with @Field(type = Text), which is appropriate for string arrays in Elasticsearch indexing. This follows the same pattern as other adapter classes like FilterField and I18nField.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (2)

13-15: Constructor implementation is correct.

The constructor properly accepts all required parameters and delegates to the superclass, following the established pattern for Spring adapter classes.


17-31: Elasticsearch field mappings are appropriately configured.

The field annotations are correctly chosen:

  • @Field(type = Text) for string arrays (fulltextValue and allowedNets)
  • @Field(type = Flattened) for the metadata map, which is ideal for arbitrary key-value structures in Elasticsearch

This follows the same pattern as other adapter classes in the codebase.

application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (3)

82-85: New field type support added correctly.

The additions for CaseField and FilterField type detection follow the established pattern in the transformation switch logic.


115-115: I18nField transformation enhancement is appropriate.

Adding the translations map to the I18nField constructor provides richer data for Elasticsearch indexing, which aligns with the Spring adapter's support for translation mapping.


94-95: Code formatting improvements enhance readability.

The method signature formatting changes improve code readability by properly breaking long parameter lists across multiple lines, following Java style guidelines.

Also applies to: 109-111, 130-131, 137-138, 145-146, 167-168, 183-184, 207-208, 215-216, 220-221, 228-229, 255-257, 272-273, 286-287, 299-300, 304-305, 312-313, 317-318, 322-323

Comment on lines +124 to +128
protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for FilterField transformation.

The method assumes getAllowedNets() and getFilterMetadata() methods exist and that the value can be safely converted to string. Add proper null checks and error handling.

 protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
+    if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
+        return Optional.empty();
+    }
     String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
     Map<String, Object> filterMetadata = dataField.getFilterMetadata();
+    if (filterMetadata == null) {
+        filterMetadata = new HashMap<>();
+    }
     return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
}
protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
return Optional.empty();
}
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
if (filterMetadata == null) {
filterMetadata = new HashMap<>();
}
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(
dataField.getValue().toString(),
allowedNets,
filterMetadata
));
}
🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
around lines 124 to 128, the method transformFilterFieldField assumes
getAllowedNets(), getFilterMetadata(), and dataField.getValue() are non-null and
safely convertible to string. Add null checks for dataField, its allowedNets,
filterMetadata, and value before using them. If any are null, handle gracefully
by returning Optional.empty() or a default value. Also, wrap the conversion to
string in a try-catch block to handle potential exceptions and avoid runtime
errors.

Comment on lines +118 to +122
protected Optional<DataField> transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add type safety checks for CaseField transformation.

The method assumes dataField.getValue() returns List<String> and that getAllowedNets() exists on the workflow DataField. Add null checks and type verification to prevent runtime exceptions.

 protected Optional<DataField> transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) {
+    if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
+        return Optional.empty();
+    }
+    if (!(dataField.getValue() instanceof List)) {
+        log.error("CaseField value is not a List. Found: " + dataField.getValue().getClass().getCanonicalName());
+        return Optional.empty();
+    }
     String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
-    String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);
+    List<?> valueList = (List<?>) dataField.getValue();
+    String[] referencedCases = valueList.stream()
+        .filter(Objects::nonNull)
+        .map(Object::toString)
+        .toArray(String[]::new);
     return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets));
 }
🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
around lines 118 to 122, the method transformCaseFieldField assumes
dataField.getValue() returns a List<String> and that getAllowedNets() is
non-null, which can cause runtime exceptions. Add null checks to verify
dataField.getValue() is not null and is an instance of List<?> before casting,
and ensure getAllowedNets() is not null before converting to array. If checks
fail, handle gracefully by returning Optional.empty() or an appropriate
fallback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (1)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

35-45: ⚠️ Potential issue

Critical: Missing filePath initialization in array constructor.

The array constructor doesn't initialize or populate the filePath array, but the getValue() method expects it to be available when handling multiple files. This will cause a NullPointerException when getValue() tries to access filePath[i].

Apply this fix to initialize the filePath array:

 public FileField(FileFieldValue[] values) {
     super(new String[values.length]);
+    this.filePath = new String[values.length];
     this.fileNameValue = new String[values.length];
     this.fileExtensionValue = new String[values.length];
     for (int i = 0; i < values.length; i++) {
         FileNameAndExtension extracted = this.extractFileExtensionFromName(values[i].getName());
         this.fileNameValue[i] = extracted.name;
         this.fileExtensionValue[i] = extracted.extension;
+        this.filePath[i] = values[i].getPath();
         super.fulltextValue[i] = values[i].getName();
     }
 }
🧹 Nitpick comments (4)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (2)

7-8: Improve import specificity and remove unused imports.

The wildcard import java.util.* should be replaced with specific imports for better code clarity. Additionally, java.util.stream.Collectors is imported but not used anywhere in this file.

-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Arrays;
+import java.util.LinkedHashSet;

36-43: Add null safety for array element access.

The method logic is sound, but there's a potential null safety issue when accessing keyValue[0] without checking if the array element itself is null.

 public Object getValue() {
-    if (keyValue != null && keyValue.length == 1) {
-        return keyValue[0];
+    if (keyValue != null && keyValue.length == 1 && keyValue[0] != null) {
+        return keyValue[0];
     } else if (keyValue != null && keyValue.length > 1) {
         return new LinkedHashSet<>(Arrays.asList(keyValue));
     }
     return null;
 }
application-engine/docker-compose.yml (1)

70-70: Add missing newline at end of file.

YAML files should end with a newline character for proper formatting standards compliance.

 volumes:
   minio_data:
-    driver: local
+    driver: local
+
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 70-70: no new line character at the end of file

(new-line-at-end-of-file)

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (1)

3-3: Remove unused import.

The FileFieldValue import is not used in this file.

-import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06e0fea and 9796d46.

📒 Files selected for processing (23)
  • application-engine/docker-compose.yml (1 hunks)
  • application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (2 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (10 hunks)
  • application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (5 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java (1 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java (2 hunks)
  • nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1 hunks)
  • nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1)
  • Data (10-23)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (10-29)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (2)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1)
  • NoArgsConstructor (8-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (1)
  • NoArgsConstructor (12-34)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java (2)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (2)
  • AllArgsConstructor (65-69)
  • Data (13-70)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (10-29)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (3)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java (1)
  • Data (10-29)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1)
  • Data (10-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1)
  • NoArgsConstructor (8-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (2)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1)
  • NoArgsConstructor (8-26)
nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1)
  • NoArgsConstructor (10-32)
🪛 YAMLlint (1.37.1)
application-engine/docker-compose.yml

[error] 70-70: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms (22)
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: Test
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
  • GitHub Check: task-list-completed
🔇 Additional comments (28)
nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java (1)

20-22: LGTM!

The implementation is clean and follows the consistent getValue() pattern established across field classes.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java (1)

20-23: LGTM!

The implementation correctly overrides the parent class method and follows the established pattern for field value access.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java (1)

27-30: LGTM! Consistent value accessor implementation.

The getValue() method correctly returns the dateValue field, providing standardized access to the internal date representation. This aligns well with the broader refactoring to unify value retrieval across different field types.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java (1)

30-32: Excellent null safety improvement!

The addition of null checking prevents potential NullPointerException when eventOutcome.getMessage() returns null. Using a ternary operator to return "NULL" string is a clean defensive programming approach.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java (1)

20-23: LGTM! Consistent with standardization pattern.

The getValue() method correctly returns the booleanValue field, maintaining consistency with the value accessor pattern being implemented across all field types in the elastic domain model.

application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java (1)

89-89: LGTM! Improved null safety and consistency.

The change correctly aligns the null-check logic with the pattern used for userId on line 88, ensuring we check for the user object's existence before accessing its properties. This prevents potential NullPointerException when calling getRealmId() on a null user object.

application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy (1)

1604-1604:

Details

✅ Verification successful

Good change for type consistency.

Capitalizing the type parameter ensures consistent handling with the new FilterField class processing. This aligns well with the enhanced metadata support mentioned in the summary.

Please verify that existing callers of this method are compatible with the capitalized type values, as this could be a breaking change if downstream code expects the original case.


🏁 Script executed:

#!/bin/bash
# Description: Check for potential breaking changes by finding all callers of createFilter method
# Expected: Find all usages and verify they handle capitalized type values correctly

echo "Searching for createFilter method calls..."
rg -A 3 -B 1 "createFilter\s*\(" --type groovy

echo -e "\nSearching for specific type values that might be affected..."
rg -A 2 -B 2 "(\"case\"|\"task\"|'case'|'task')" --type groovy

Length of output: 28811


🏁 Script executed:

#!/bin/bash
# Print the createFilter method definition with context
rg -n "Case createFilter" -A 20 -B 5 application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy

Length of output: 8013


🏁 Script executed:

#!/bin/bash
# Locate DefaultFiltersRunner constants for FILTER_TYPE_CASE and FILTER_TYPE_TASK
rg -n "FILTER_TYPE_CASE" -A 3 -B 3 --type groovy
rg -n "FILTER_TYPE_TASK" -A 3 -B 3 --type groovy

Length of output: 21825


🏁 Script executed:

#!/bin/bash
# Locate the DefaultFiltersRunner class file
FILTER_RUNNER_FILE=$(rg -l "class DefaultFiltersRunner" --type groovy)

# Print the file path
echo "Found DefaultFiltersRunner at: $FILTER_RUNNER_FILE"

# Show the definitions of FILTER_TYPE_CASE and FILTER_TYPE_TASK
rg -n "FILTER_TYPE_CASE" -A1 -B1 "$FILTER_RUNNER_FILE"
rg -n "FILTER_TYPE_TASK" -A1 -B1 "$FILTER_RUNNER_FILE"

Length of output: 300


🏁 Script executed:

#!/bin/bash
# Search for DefaultFiltersRunner definition across groovy and java sources
rg -n "class DefaultFiltersRunner" -n application-engine/src
rg -n "interface DefaultFiltersRunner" -n application-engine/src
rg -l "DefaultFiltersRunner" -n application-engine/src

Length of output: 1025


No breaking changes to createFilter type handling

All existing callers pass in the official DefaultFiltersRunner.FILTER_TYPE_CASE and …_TASK constants (whose values are already “Case” and “Task”), so capitalizing the incoming type produces the same strings. No downstream code relies on lowercase literals for filter types.

• Named variants (createCaseFilter, createTaskFilter) use constants
• Deprecated createFilterInMenu overloads forward constants
• Test code referencing "case"/"task" pertains to transition IDs, not filter types

nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java (1)

344-346: LGTM! Good null safety improvement.

The null check prevents potential NullPointerException when accessing the attributes map.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java (1)

19-22: Intentional behavior change in getValue() method.

The override changes the return type from String (first element from DataField) to List (all elements). This provides access to all full-text values rather than just the first one, which aligns with the case field's purpose.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java (2)

17-20: Good null safety implementation.

The constructor properly handles null filterMetadata by initializing it with an empty HashMap, preventing potential issues downstream.


22-25: Consistent getValue() behavior.

The delegation to super.getValue() maintains the inherited behavior of returning the first full-text value element, which is appropriate for filter fields.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java (2)

22-26: Clean copy constructor implementation.

The constructor efficiently copies the essential properties (stringId, name, type) from the Field object, providing a clean way to create immediate field representations.


12-13: Proper serialization support.

The serialVersionUID is correctly defined for serialization compatibility.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java (1)

47-55: Good implementation of getValue() method.

The method correctly handles both single and multiple file scenarios, returning appropriate FileFieldValue objects. The logic is sound and the return types are consistent.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java (1)

18-30: Well-implemented internationalization enhancement.

The addition of the translations map and the getValue() method override is consistent and properly implemented. The constructor correctly initializes all fields, and the getValue() method returns a well-structured I18nString object.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java (1)

1-26: Consistent Spring adapter implementation.

The new CaseField adapter class follows the established pattern correctly. The constructor delegation, field annotations, and getter methods are properly implemented and consistent with other adapter classes in the same package.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java (1)

15-33: Consistent adapter enhancement for translation support.

The constructor update and new getTranslations() method with @Field(type = Flattened) annotation properly expose the translations map for Elasticsearch indexing. This aligns well with the domain class changes and follows the established adapter pattern.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java (1)

17-25: Constructor implementations look correct.

Both constructors properly delegate to the parent class and initialize the allowedNets field appropriately.

nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java (4)

8-8: Import addition looks good.

The import for ImmediateField is correctly added to support the new functionality.


64-64: Field addition is well-structured.

The immediateData field follows the existing field patterns in the class and is properly typed.


118-118: Constructor initialization is implemented correctly.

The stream mapping from useCase.getImmediateData() to create new ImmediateField instances is appropriate and follows functional programming best practices.


139-139: Update method modification is correct.

Direct assignment of immediateData in the update method is consistent with how other fields are handled.

nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java (1)

10-32: FilterField adapter implementation follows established patterns correctly.

The class properly extends the domain FilterField, delegates constructor calls to the superclass, and applies appropriate Elasticsearch @Field annotations:

  • getFulltextValue() and getAllowedNets() use Text type for searchable content
  • getFilterMetadata() uses Flattened type for complex object mapping

This implementation is consistent with other adapter classes like CaseField and I18nField.

application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java (5)

82-85: New field type transformations are properly integrated.

The addition of CaseField and FilterField transformations in the conditional chain follows the established pattern and maintains the proper order of type checking.


118-122: CaseField transformation method is implemented correctly.

The method properly extracts allowedNets and referencedCases from the data field and creates the appropriate elastic domain object.


124-128: FilterField transformation method is implemented correctly.

The method appropriately extracts allowedNets and filterMetadata from the data field and creates the corresponding elastic domain object.


115-115: Enhanced I18nField transformation with translations mapping.

The addition of the full translations map to the I18nField constructor enhances the searchable content and is a valuable improvement over the previous implementation that only included keys and values.


94-95: Method signature formatting improvements enhance readability.

The reformatting of method signatures across multiple methods improves code readability without altering functionality. This is a positive maintenance change.

Also applies to: 109-111, 130-131, 137-138, 145-146, 167-168, 183-184, 207-208, 215-216, 220-221, 228-229, 255-257, 272-273, 286-287, 299-300, 304-305, 312-313, 317-318, 322-323

Adjusted null and boundary checks in `getValue` methods to prevent runtime exceptions and ensure data integrity. Added validation for filter type in `ActionDelegate` to avoid illegal arguments and improved string handling for robustness.
@machacjozef machacjozef merged commit cb581e3 into release/7.0.0-rev2 Jun 5, 2025
6 of 7 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 18, 2025
18 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix A change that fixes a bug Medium Small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants