Skip to content

Conversation

@st-manu
Copy link
Contributor

@st-manu st-manu commented Dec 19, 2025

https://sakaiproject.atlassian.net/browse/SAK-52251

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Enhanced page hierarchy reconstruction and parent-child relationship preservation when importing lesson content.
    • Improved consistency in page structure for imported lessons.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Walkthrough

Modified LessonBuilderEntityProducer.java to improve page hierarchy reconstruction during imports. Changes page creation to use null toolId initially, then reconstructs parent relationships and toolIds through multi-step processing passes that build calculated parent maps and apply them to imported pages.

Changes

Cohort / File(s) Summary
Page hierarchy and toolId reconstruction
lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java
Modified page creation to use null toolId and delayed parent assignment; added hierarchy reconstruction after import using calculatedParentMap and calculatedTopParentMap; introduced second pass to adjust child page toolIds based on topparent; updated logging and reorganized imports

Possibly related PRs

  • #14081 — Modifies mergeInternal in LessonBuilderEntityProducer.java affecting item save/update behavior during imports

Suggested reviewers

  • csev

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: fixing an issue where lesson subpages are imported as pseudo-orphans, which aligns with the core functionality introduced in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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: 1

🧹 Nitpick comments (1)
lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java (1)

1739-1751: Consider adding cycle detection to the parent chain traversal.

The while loop walks up the parent chain to find the top parent. While cycles should not exist in valid data, a defensive safeguard would prevent an infinite loop in case of corrupted data.

🔎 Suggested defensive safeguard
 // Calculate top parents by walking up the tree
 for (Long pageId : calculatedParentMap.keySet()) {
     Long currentPageId = pageId;
     Long topParent = null;
+    Set<Long> visited = new HashSet<>();
 
-    while (calculatedParentMap.containsKey(currentPageId)) {
+    while (calculatedParentMap.containsKey(currentPageId) && !visited.contains(currentPageId)) {
+        visited.add(currentPageId);
         topParent = calculatedParentMap.get(currentPageId);
         currentPageId = topParent;
     }
 
     if (topParent != null) {
         calculatedTopParentMap.put(pageId, topParent);
     }
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57fcc2a and d47debf.

📒 Files selected for processing (1)
  • lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

📄 CodeRabbit inference engine (.cursor/rules/logging-rule.mdc)

**/*.java: Use SLF4J parameterized logging (logger.info("Value is: {}", value)) instead of string concatenation (logger.info("Value is: " + value))
Log messages and code comments should be in English. Log messages should never be translated.

**/*.java: Java: Never use local variable type inference (var). Always declare explicit types. Yes: Map<String, Integer> counts = new HashMap<>(); No: var counts = new HashMap<String, Integer>();
When proposing Java code, spell out full types in local variable declarations, for loops, and try-with-resources
When editing Java, prefer clarity over brevity; avoid introducing language features that aren't widely used in the repo
Treat any PR or suggestion containing Java var as non-compliant. Recommend replacing with explicit types before merge

**/*.java: Use Java 17 for trunk development (Java 11 was used for Sakai 22 and Sakai 23)
Do not use local variable type inference (var) in Java code. Always declare explicit types (e.g., List<String> names = new ArrayList<>(); not var names = new ArrayList<String>();). Enforced by Checkstyle rule during mvn validate

Files:

  • lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java
🧠 Learnings (1)
📚 Learning: 2025-10-07T16:11:33.008Z
Learnt from: CR
Repo: sakaiproject/sakai PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-07T16:11:33.008Z
Learning: For new tools, prefer Spring MVC/Boot with Hibernate and ThymeLeaf; avoid RSF for new development and consider modernization when changing legacy tools

Applied to files:

  • lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java
🧬 Code graph analysis (1)
lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java (2)
kernel/api/src/main/java/org/sakaiproject/util/MergeConfig.java (1)
  • MergeConfig (31-41)
kernel/api/src/main/java/org/sakaiproject/util/cover/LinkMigrationHelper.java (1)
  • LinkMigrationHelper (23-52)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: maven-build
  • GitHub Check: maven-build
  • GitHub Check: sakai-deploy
🔇 Additional comments (4)
lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java (4)

101-134: Import additions are appropriate.

The added imports support the new hierarchy reconstruction functionality:

  • SakaiLTIUtil for LTI content handling
  • MergeConfig and LinkMigrationHelper for merge operations

These are all used within the file and follow proper organization.


1650-1651: Deferred parent relationship assignment is a reasonable approach.

Creating pages with a placeholder toolId of "0" and setting parent relationships in a later pass allows proper hierarchy reconstruction after all pages are created. This is cleaner than trying to resolve relationships during initial creation.


1753-1792: Hierarchy update logic looks correct.

The code properly:

  1. Iterates through the page map using old page IDs as keys
  2. Looks up calculated parent/topparent relationships
  3. Maps old IDs to new IDs via pageMap
  4. Updates and persists only when changes are needed

The logging at the end provides good visibility into the operation.


1970-1999: ToolId propagation logic is correct.

The code properly propagates the toolId from top-level pages to their descendants. The checks at line 1986-1987 correctly handle:

  • Null pages
  • Top parent with null or placeholder "0" toolId
  • Avoiding unnecessary updates when toolId already matches

Note: For very large imports, the two getPage() calls per iteration (lines 1983-1984) could be optimized by caching pages from the earlier pass, but this is acceptable for typical import scenarios.

@st-manu st-manu marked this pull request as draft December 19, 2025 10:10
@st-manu
Copy link
Contributor Author

st-manu commented Dec 19, 2025

Converted to draft: continues the work from #14300

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant