1212import org .kie .api .runtime .KieSession ;
1313import org .kie .dmn .api .core .*;
1414import org .kie .dmn .api .core .ast .DecisionNode ;
15+ import org .kie .dmn .api .core .ast .InputDataNode ;
16+ import com .fasterxml .jackson .databind .JsonNode ;
17+ import com .fasterxml .jackson .databind .ObjectMapper ;
18+ import com .fasterxml .jackson .databind .node .ArrayNode ;
19+ import com .fasterxml .jackson .databind .node .ObjectNode ;
1520
1621import java .io .*;
1722import java .util .*;
@@ -28,6 +33,16 @@ public DmnCompilationResult(byte[] dmnBytes, List<String> errors) {
2833 }
2934}
3035
36+ class DmnModelResult {
37+ public DMNModel model ;
38+ public DMNRuntime runtime ;
39+
40+ public DmnModelResult (DMNModel model , DMNRuntime runtime ) {
41+ this .model = model ;
42+ this .runtime = runtime ;
43+ }
44+ }
45+
3146@ ApplicationScoped
3247public class KieDmnService implements DmnService {
3348 @ Inject
@@ -43,6 +58,23 @@ private KieSession initializeKieSession(byte[] moduleBytes) throws IOException {
4358 return kieContainer .newKieSession ();
4459 }
4560
61+ private DmnModelResult compileAndGetDmnModel (String dmnXml , Map <String , String > dependenciesMap , String modelId ) throws Exception {
62+ DmnCompilationResult compilationResult = compileDmnModel (dmnXml , dependenciesMap , modelId );
63+ if (!compilationResult .errors .isEmpty ()) {
64+ throw new IllegalStateException ("DMN compilation failed: " + String .join (", " , compilationResult .errors ));
65+ }
66+
67+ KieSession kieSession = initializeKieSession (compilationResult .dmnBytes );
68+ DMNRuntime dmnRuntime = kieSession .getKieRuntime (DMNRuntime .class );
69+
70+ List <DMNModel > dmnModels = dmnRuntime .getModels ();
71+ if (dmnModels .size () != 1 ) {
72+ throw new RuntimeException ("Expected exactly one DMN model, found: " + dmnModels .size ());
73+ }
74+
75+ return new DmnModelResult (dmnModels .get (0 ), dmnRuntime );
76+ }
77+
4678 // Validates that the DMN XML can compile and contains the required decision.
4779 // Returns a list of error messages if any issues are found.
4880 public List <String > validateDmnXml (
@@ -148,27 +180,12 @@ public EvaluationResult evaluateDmn(
148180 String dmnXml = dmnXmlOpt .get ();
149181
150182 HashMap <String , String > dmnDependenciesMap = new HashMap <String , String >();
151- DmnCompilationResult compilationResult = compileDmnModel (dmnXml , dmnDependenciesMap , dmnModelName );
152- if (!compilationResult .errors .isEmpty ()) {
153- Log .error ("DMN Compilation errors for model " + dmnModelName + ":" );
154- for (String error : compilationResult .errors ) {
155- Log .error (error );
156- }
157- throw new IllegalStateException ("DMN Model compilation failed for model: " + dmnModelName );
158- }
183+ DmnModelResult modelResult = compileAndGetDmnModel (dmnXml , dmnDependenciesMap , dmnModelName );
184+ DMNModel dmnModel = modelResult .model ;
185+ DMNRuntime dmnRuntime = modelResult .runtime ;
159186
160- KieSession kieSession = initializeKieSession (compilationResult .dmnBytes );
161- DMNRuntime dmnRuntime = kieSession .getKieRuntime (DMNRuntime .class );
162-
163- List <DMNModel > dmnModels = dmnRuntime .getModels ();
164- if (dmnModels .size () != 1 ) {
165- throw new RuntimeException ("Expected exactly one DMN model, found: " + dmnModels .size ());
166- }
187+ Log .info ("DMN Model loaded: " + dmnModel .getName () + " Namespace: " + dmnModel .getNamespace ());
167188
168- Log .info ("DMN Model loaded: " + dmnModels .get (0 ).getName () + " Namespace: " + dmnModels .get (0 ).getNamespace ());
169-
170- // Prepare model and context using inputs
171- DMNModel dmnModel = dmnModels .get (0 );
172189 DMNContext context = dmnRuntime .newContext ();
173190
174191 for (Map .Entry <String , Object > input : inputs .entrySet ()) {
@@ -202,4 +219,66 @@ else if (result instanceof Boolean && !(Boolean) result) {
202219 }
203220 throw new RuntimeException ("Unexpected decision result type: " + result .getClass ().getName ());
204221 }
222+
223+ public JsonNode extractInputSchema (
224+ String dmnXml ,
225+ Map <String , String > dependenciesMap ,
226+ String modelId
227+ ) throws Exception {
228+ Log .info ("Extracting input schema from DMN model: " + modelId );
229+
230+ DmnModelResult modelResult = compileAndGetDmnModel (dmnXml , dependenciesMap , modelId );
231+ DMNModel dmnModel = modelResult .model ;
232+ Set <InputDataNode > inputs = dmnModel .getInputs ();
233+
234+ ObjectMapper mapper = new ObjectMapper ();
235+
236+ // Create custom object for non-parameters inputs
237+ ObjectNode customObj = mapper .createObjectNode ();
238+ customObj .put ("type" , "object" );
239+
240+ ArrayList <String > requiredCustomProps = new ArrayList <String >();
241+
242+ // Fill out custom properties and check if parameters input exists
243+ ObjectNode customProperties = mapper .createObjectNode ();
244+ boolean hasParametersInput = false ;
245+ for (InputDataNode input : inputs ) {
246+ String inputName = input .getName ();
247+ if ("parameters" .equals (inputName )) {
248+ hasParametersInput = true ;
249+ continue ;
250+ }
251+ // Add as empty object (no type constraints)
252+ customProperties .set (inputName , mapper .createObjectNode ());
253+ requiredCustomProps .add (inputName );
254+ }
255+ ArrayNode requiredCustomPropsNode = mapper .valueToTree (requiredCustomProps );
256+ customObj .set ("required" , requiredCustomPropsNode );
257+ customObj .set ("properties" , customProperties );
258+
259+ ObjectNode properties = mapper .createObjectNode ();
260+ properties .set ("custom" , customObj );
261+
262+ ArrayList <String > requiredTopLevelProps = new ArrayList <String >();
263+ requiredTopLevelProps .add ("custom" );
264+
265+ // Only add parameters to schema if it's defined as an input in the DMN
266+ if (hasParametersInput ) {
267+ ObjectNode parametersObj = mapper .createObjectNode ();
268+ ObjectNode parametersProperties = mapper .createObjectNode ();
269+ parametersObj .put ("type" , "object" );
270+ parametersObj .set ("properties" , parametersProperties );
271+ properties .set ("parameters" , parametersObj );
272+ requiredTopLevelProps .add ("parameters" );
273+ }
274+
275+ ObjectNode schema = mapper .createObjectNode ();
276+ ArrayNode requiredTopLevelPropsNode = mapper .valueToTree (requiredTopLevelProps );
277+ schema .put ("type" , "object" );
278+ schema .set ("properties" , properties );
279+ schema .set ("required" , requiredTopLevelPropsNode );
280+
281+ Log .info ("Extracted " + inputs .size () + " inputs from DMN model: " + modelId );
282+ return schema ;
283+ }
205284}
0 commit comments