-
-
Notifications
You must be signed in to change notification settings - Fork 393
Feat: Implement hierarchical split functionality for PDF bookmarks #799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -33,6 +33,9 @@ | |||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.notification.event.TaskExecutionCompletedEvent; | ||||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.notification.event.TaskExecutionFailedEvent; | ||||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.notification.event.TaskExecutionStartedEvent; | ||||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.parameter.SplitByOutlineLevelParameters; | ||||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.parameter.base.TaskParameters; | ||||||||||||||||||||||||||||||||||||||||||
| import org.sejda.model.task.NotifiableTaskMetadata; | ||||||||||||||||||||||||||||||||||||||||||
| import org.slf4j.Logger; | ||||||||||||||||||||||||||||||||||||||||||
| import org.slf4j.LoggerFactory; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -85,10 +88,52 @@ public void request(TaskExecutionRequest event) { | |||||||||||||||||||||||||||||||||||||||||
| LOG.trace("Task execution request received"); | ||||||||||||||||||||||||||||||||||||||||||
| usageService.incrementUsageFor(event.toolId()); | ||||||||||||||||||||||||||||||||||||||||||
| currentModule = event.toolId(); | ||||||||||||||||||||||||||||||||||||||||||
| executor.execute(() -> executionService.execute(event.parameters())); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| TaskParameters params = event.parameters(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Check if this is a hierarchical split request | ||||||||||||||||||||||||||||||||||||||||||
| if (isHierarchicalSplitRequest(params)) { | ||||||||||||||||||||||||||||||||||||||||||
| LOG.debug("Executing hierarchical split task"); | ||||||||||||||||||||||||||||||||||||||||||
| executor.execute(() -> executeHierarchicalSplit(params)); | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| executor.execute(() -> executionService.execute(params)); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| LOG.trace("Task execution submitted"); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private boolean isHierarchicalSplitRequest(TaskParameters params) { | ||||||||||||||||||||||||||||||||||||||||||
| // Check if this is a hierarchical split request by checking the class name | ||||||||||||||||||||||||||||||||||||||||||
| // We use the class name to avoid a circular dependency on the tool module | ||||||||||||||||||||||||||||||||||||||||||
| return params.getClass().getSimpleName().equals("HierarchicalSplitByOutlineLevelParameters"); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private void executeHierarchicalSplit(TaskParameters params) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!(params instanceof SplitByOutlineLevelParameters)) { | ||||||||||||||||||||||||||||||||||||||||||
| LOG.error("Invalid parameters type for hierarchical split"); | ||||||||||||||||||||||||||||||||||||||||||
| GlobalNotificationContext.getContext() | ||||||||||||||||||||||||||||||||||||||||||
| .notifyListeners(new TaskExecutionFailedEvent( | ||||||||||||||||||||||||||||||||||||||||||
| new IllegalArgumentException("Invalid parameters type for hierarchical split"), | ||||||||||||||||||||||||||||||||||||||||||
| NotifiableTaskMetadata.NULL)); | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| // Use reflection to instantiate and execute the hierarchical task | ||||||||||||||||||||||||||||||||||||||||||
| Class<?> taskClass = Class.forName( | ||||||||||||||||||||||||||||||||||||||||||
| "org.pdfsam.tools.splitbybookmarks.HierarchicalSplitByBookmarksTask"); | ||||||||||||||||||||||||||||||||||||||||||
| Object task = taskClass.getDeclaredConstructor().newInstance(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Execute the task | ||||||||||||||||||||||||||||||||||||||||||
| java.lang.reflect.Method executeMethod = taskClass.getMethod("execute", | ||||||||||||||||||||||||||||||||||||||||||
| SplitByOutlineLevelParameters.class); | ||||||||||||||||||||||||||||||||||||||||||
| executeMethod.invoke(task, params); | ||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception e) { | ||||||||||||||||||||||||||||||||||||||||||
| LOG.error("Failed to execute hierarchical split task", e); | ||||||||||||||||||||||||||||||||||||||||||
| GlobalNotificationContext.getContext() | ||||||||||||||||||||||||||||||||||||||||||
| .notifyListeners(new TaskExecutionFailedEvent(e, NotifiableTaskMetadata.NULL)); | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+121
to
+133
|
||||||||||||||||||||||||||||||||||||||||||
| // Use reflection to instantiate and execute the hierarchical task | |
| Class<?> taskClass = Class.forName( | |
| "org.pdfsam.tools.splitbybookmarks.HierarchicalSplitByBookmarksTask"); | |
| Object task = taskClass.getDeclaredConstructor().newInstance(); | |
| // Execute the task | |
| java.lang.reflect.Method executeMethod = taskClass.getMethod("execute", | |
| SplitByOutlineLevelParameters.class); | |
| executeMethod.invoke(task, params); | |
| } catch (Exception e) { | |
| LOG.error("Failed to execute hierarchical split task", e); | |
| GlobalNotificationContext.getContext() | |
| .notifyListeners(new TaskExecutionFailedEvent(e, NotifiableTaskMetadata.NULL)); | |
| // Route hierarchical split through the standard TaskExecutionService so that | |
| // task lifecycle (before/after) and notifications are handled correctly. | |
| executionService.execute(params); | |
| } catch (Exception e) { | |
| // Let TaskExecutionService / task infrastructure handle failure notifications | |
| // to avoid duplicate TaskExecutionFailedEvent emissions. | |
| LOG.error("Failed to execute hierarchical split task", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isHierarchicalSplitRequestmatches ongetSimpleName(). This is brittle (a different parameters class in another package with the same simple name would be treated as hierarchical) and makes refactors risky. Prefer matching on the fully qualified class name (e.g.,getName()) or a stable marker exposed by the parameters type.