McpServices.mcp.ResolveScreenPath.xml
4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?xml version="1.0" encoding="UTF-8"?>
<!--
This software is in the public domain under CC0 1.0 Universal plus a
Grant of Patent License.
To the extent possible under law, author(s) have dedicated all
copyright and related and neighboring rights to this software to the
public domain worldwide. This software is distributed without any
warranty.
-->
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-3.xsd">
<service verb="mcp" noun="ResolveScreenPath" authenticate="false" allow-remote="true" transaction-timeout="30">
<description>Resolve a simple screen path to component path, subscreen name, and screen definition.</description>
<in-parameters>
<parameter name="path" required="true"/>
</in-parameters>
<out-parameters>
<parameter name="result" type="Map"/>
</out-parameters>
<actions>
<script><![CDATA[
import org.moqui.context.ExecutionContext
ExecutionContext ec = context.ec
def resolvedPath = null
def subscreenName = null
def screenDef = null
if (!path || path == "root") {
return [
screenPath: null,
subscreenName: null,
screenDef: null
]
}
// Support both dot and slash notation
def pathParts = path.contains('/')
? path.split('/')
: path.split('\\.')
def componentName = pathParts[0]
// Use longest prefix match to find actual screen file
for (int i = pathParts.size(); i >= 1; i--) {
def subPath = i > 1 ? pathParts[0] + "/" + (pathParts[1..<i].join('/')) : pathParts[0]
def currentTry = "component://${componentName}/screen/${subPath}.xml"
if (ec.resource.getLocationReference(currentTry).getExists()) {
resolvedPath = currentTry
// If we found a screen matching the full path, we're already at the target
if (i < pathParts.size()) {
def remainingParts = pathParts[i..-1]
subscreenName = remainingParts.size() > 1 ? remainingParts.join('_') : remainingParts[0]
}
break
}
}
// Fallback to component root screen if no match found
if (!resolvedPath) {
resolvedPath = "component://${componentName}/screen/${componentName}.xml"
if (pathParts.size() > 1) {
subscreenName = pathParts[1..-1].join('_')
}
}
// Navigate to subscreen if needed
if (resolvedPath) {
try {
screenDef = ec.screen.getScreenDefinition(resolvedPath)
if (subscreenName && screenDef) {
for (subName in subscreenName.split('_')) {
def subItem = screenDef?.getSubscreensItem(subName)
if (subItem && subItem.getLocation()) {
screenDef = ec.screen.getScreenDefinition(subItem.getLocation())
} else {
break
}
}
}
} catch (Exception e) {
ec.logger.warn("ResolveScreenPath: Error loading screen definition: ${e.message}")
}
}
result = [
screenPath: resolvedPath,
subscreenName: subscreenName,
screenDef: screenDef
]
]]></script>
</actions>
</service>
</services>