DBA Data[Home] [Help]

PACKAGE BODY: APPS.CZ_RULE_TEXT_GEN

Source


1 PACKAGE BODY cz_rule_text_gen  AS
2 /* $Header: czruletxtb.pls 120.3.12010000.2 2009/01/21 15:59:35 kksriram ship $ */
3 
4 
5 
6 PROCEDURE parse_rules(p_devl_project_id IN NUMBER, p_rule_id IN NUMBER DEFAULT NULL) IS
7   schema_version NUMBER;
8   EXPR_OPERATOR          CONSTANT PLS_INTEGER := 200;
9   EXPR_LITERAL           CONSTANT PLS_INTEGER := 201;
10   EXPR_PSNODE            CONSTANT PLS_INTEGER := 205;
11   EXPR_PROP              CONSTANT PLS_INTEGER := 207;
12   EXPR_SYS_PROP          CONSTANT PLS_INTEGER := 210;
13   EXPR_CONSTANT          CONSTANT PLS_INTEGER := 211;
14   EXPR_ARGUMENT          CONSTANT PLS_INTEGER := 221;
15   EXPR_TEMPLATE          CONSTANT PLS_INTEGER := 222;
16   EXPR_FORALL            CONSTANT PLS_INTEGER := 223;
17   EXPR_ITERATOR          CONSTANT PLS_INTEGER := 224;
18   EXPR_WHERE             CONSTANT PLS_INTEGER := 225;
19   EXPR_COMPATIBLE        CONSTANT PLS_INTEGER := 226;
20 
21   OPERATOR_CONTRIBUTE    CONSTANT PLS_INTEGER := 708;
22 
23   DATA_TYPE_INTEGER      CONSTANT PLS_INTEGER := 1;
24   DATA_TYPE_DECIMAL      CONSTANT PLS_INTEGER := 2;
25   DATA_TYPE_BOOLEAN      CONSTANT PLS_INTEGER := 3;
26   DATA_TYPE_TEXT         CONSTANT PLS_INTEGER := 4;
27 
28   PS_NODE_TYPE_REFERENCE CONSTANT PLS_INTEGER := 263;
29   PS_NODE_TYPE_CONNECTOR CONSTANT PLS_INTEGER := 264;
30 
31   EXPR_CONSTANT_E        CONSTANT PLS_INTEGER := 0;
32   EXPR_CONSTANT_PI       CONSTANT PLS_INTEGER := 1;
33 
34   CONSTANT_PI            CONSTANT VARCHAR2(3) := 'pi';
35   CONSTANT_E             CONSTANT VARCHAR2(3) := 'e';
36 
37   NewLine                CONSTANT VARCHAR2(25) := FND_GLOBAL.NEWLINE;
38 
39   CZ_UPRT_MULTIPLE_ROOTS EXCEPTION;
40   CZ_UPRT_UNKNOWN_TYPE   EXCEPTION;
41   CZ_UPRT_INCORRECT_PROP EXCEPTION;
42   CZ_UPRT_INCORRECT_NODE EXCEPTION;
43 
44   TYPE tStringTable      IS TABLE OF VARCHAR2(32767) INDEX BY VARCHAR2(15);
45   TYPE tStringTableIBI   IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
46   TYPE tIntegerTable     IS TABLE OF PLS_INTEGER INDEX BY VARCHAR2(15);
47   TYPE tIntegerTableIBI  IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER;
48   TYPE tNumberTable      IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
49 
50   TYPE tRuleId           IS TABLE OF cz_rules.rule_id%TYPE INDEX BY BINARY_INTEGER;
51   TYPE tRuleName         IS TABLE OF cz_rules.name%TYPE INDEX BY BINARY_INTEGER;
52   TYPE tTemplateToken    IS TABLE OF cz_rules.template_token%TYPE INDEX BY BINARY_INTEGER;
53   TYPE tPsNodeName       IS TABLE OF cz_ps_nodes.name%TYPE INDEX BY BINARY_INTEGER;
54   TYPE tPropertyName     IS TABLE OF cz_properties.name%TYPE INDEX BY BINARY_INTEGER;
55   TYPE tNodeId           IS TABLE OF cz_model_ref_expls.model_ref_expl_id%TYPE INDEX BY BINARY_INTEGER;
56   TYPE tParentId         IS TABLE OF cz_model_ref_expls.parent_expl_node_id%TYPE INDEX BY BINARY_INTEGER;
57   TYPE tComponentId      IS TABLE OF cz_model_ref_expls.component_id%TYPE INDEX BY BINARY_INTEGER;
58   TYPE tReferringId      IS TABLE OF cz_model_ref_expls.referring_node_id%TYPE INDEX BY BINARY_INTEGER;
59   TYPE tNodeType         IS TABLE OF cz_model_ref_expls.ps_node_type%TYPE INDEX BY BINARY_INTEGER;
60 
61   v_RuleId               tRuleId;
62   v_RuleName             tRuleName;
63   v_TemplateToken        tTemplateToken;
64   h_RuleName             tRuleName;
65   h_TemplateToken        tTemplateToken;
66   h_PsNodeName           tPsNodeName;
67   h_PropertyName         tPropertyName;
68   h_FullName             tIntegerTable;
69 
70   v_NodeId               tNodeId;
71   v_ParentId             tParentId;
72   v_ComponentId          tComponentId;
73   v_ReferringId          tReferringId;
74   v_NodeType             tNodeType;
75   h_ParentId             tParentId;
76   h_NodeType             tNodeType;
77   h_ReferringId          tReferringId;
78   h_ComponentId          tComponentId;
79   h_ContextPath          tStringTable;
80   h_ModelPath            tStringTable;
81   h_NodeName             tStringTable;
82 
83   xError                 BOOLEAN;
84   nDebug                 PLS_INTEGER;
85 ---------------------------------------------------------------------------------------
86 PROCEDURE populate_rule_text(p_rule_id IN NUMBER) IS
87 
88   TYPE tExprId           IS TABLE OF cz_expression_nodes.expr_node_id%TYPE INDEX BY BINARY_INTEGER;
89   TYPE tExprParentId     IS TABLE OF cz_expression_nodes.expr_parent_id%TYPE INDEX BY BINARY_INTEGER;
90   TYPE tExprType         IS TABLE OF cz_expression_nodes.expr_type%TYPE INDEX BY BINARY_INTEGER;
91   TYPE tExprTemplateId   IS TABLE OF cz_expression_nodes.template_id%TYPE INDEX BY BINARY_INTEGER;
92   TYPE tExprPsNodeId     IS TABLE OF cz_expression_nodes.ps_node_id%TYPE INDEX BY BINARY_INTEGER;
93   TYPE tExplNodeId       IS TABLE OF cz_expression_nodes.model_ref_expl_id%TYPE INDEX BY BINARY_INTEGER;
94   TYPE tExprPropertyId   IS TABLE OF cz_expression_nodes.property_id%TYPE INDEX BY BINARY_INTEGER;
95   TYPE tExprDataType     IS TABLE OF cz_expression_nodes.data_type%TYPE INDEX BY BINARY_INTEGER;
96   TYPE tExprDataValue    IS TABLE OF cz_expression_nodes.data_value%TYPE INDEX BY BINARY_INTEGER;
97   TYPE tExprDataNumValue IS TABLE OF cz_expression_nodes.data_num_value%TYPE INDEX BY BINARY_INTEGER;
98   TYPE tExprParamIndex   IS TABLE OF cz_expression_nodes.param_index%TYPE INDEX BY BINARY_INTEGER;
99   TYPE tExprArgumentName IS TABLE OF cz_expression_nodes.argument_name%TYPE INDEX BY BINARY_INTEGER;
100 
101   v_ExprId               tExprId;
102   v_ExprParentId         tExprParentId;
103   v_ExprType             tExprType;
104   v_ExprTemplateId       tExprTemplateId;
105   v_ExprPsNodeId         tExprPsNodeId;
106   v_ExplNodeId           tExplNodeId;
107   v_ExprPropertyId       tExprPropertyId;
108   v_ExprDataType         tExprDataType;
109   v_ExprDataValue        tExprDataValue;
110   v_ExprDataNumValue     tExprDataNumValue;
111   v_ExprParamIndex       tExprParamIndex;
112   v_ExprArgumentName     tExprArgumentName;
113 
114   vi_ExprId              tExprId;
115   vi_Name                tStringTableIBI;
116   vi_Depth               tIntegerTableIBI;
117   vi_Occurrence          tIntegerTable;
118   vi_Pos                 tIntegerTableIBI;
119 
120   v_ChildrenIndex        tIntegerTable;
121   v_NumberOfChildren     tIntegerTable;
122   v_RuleText             VARCHAR2(32767);
123   errmsg1                VARCHAR2(2000);
124   errmsg2                VARCHAR2(2000);
125   rootIndex              PLS_INTEGER;
126   isCompatible           PLS_INTEGER := 0;
127   isForall               PLS_INTEGER := 0;
128   currentLevel           PLS_INTEGER := 0;
129   v_pres_flag            number;
130 ---------------------------------------------------------------------------------------
131   FUNCTION parse_expr_node(j IN PLS_INTEGER) RETURN VARCHAR2 IS
132 
133     v_RuleText           VARCHAR2(32767);
134     v_Name               VARCHAR2(2000);
135     v_Index              PLS_INTEGER;
136     v_aux                PLS_INTEGER;
137     v_token              cz_rules.template_token%TYPE;
138 ---------------------------------------------------------------------------------------
139     FUNCTION generate_model_path(p_ps_node_id IN NUMBER) RETURN VARCHAR2 IS
140       v_Name             VARCHAR2(32767);
141     BEGIN
142 
143       IF(h_ModelPath.EXISTS(p_ps_node_id))THEN RETURN h_ModelPath(p_ps_node_id); END IF;
144 
145       FOR c_name IN (SELECT name, parent_id FROM cz_ps_nodes
146                       START WITH ps_node_id = p_ps_node_id
147                     CONNECT BY PRIOR parent_id = ps_node_id) LOOP
148 
149         IF(v_Name IS NULL)THEN
150 
151           v_Name := '''' || c_name.name || '''';
152           h_NodeName(p_ps_node_id) := v_Name;
153 
154           FOR c_node IN (SELECT NULL FROM cz_ps_nodes WHERE deleted_flag = '0'
155                             AND devl_project_id = p_devl_project_id
156                             AND name = c_name.name
157                             AND ps_node_id <> p_ps_node_id)LOOP
158             h_FullName(p_ps_node_id) := 1;
159             EXIT;
160           END LOOP;
161           FOR c_node IN (SELECT NULL FROM cz_ps_nodes WHERE deleted_flag = '0'
162                             AND devl_project_id IN
163                               (SELECT component_id FROM cz_model_ref_expls
164                                 WHERE deleted_flag = '0'
165                                   AND model_id = p_devl_project_id
166                                   AND ps_node_type IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))
167                             AND name = c_name.name)LOOP
168             h_FullName(p_ps_node_id) := 1;
169             EXIT;
170           END LOOP;
171         ELSIF(c_name.parent_id IS NOT NULL)THEN -- This is to exclude the root model name from the path.
172           v_Name := '''' || c_name.name || '''' || FND_GLOBAL.LOCAL_CHR(8) || v_Name;
173         END IF;
174       END LOOP;
175 
176       h_ModelPath(p_ps_node_id) := v_Name;
177      RETURN v_Name;
178     END generate_model_path;
179 ---------------------------------------------------------------------------------------
180     FUNCTION generate_context_path(p_expl_id IN NUMBER) RETURN VARCHAR2 IS
181       v_Node             NUMBER;
182       v_Name             VARCHAR2(32767);
183       v_ModelName        VARCHAR2(32767);
184     BEGIN
185 
186       --The path cashing is disabled because now it depends not only on expl_id, but also on the
187       --participating node (see comment below).
188 
189       --IF(h_ContextPath.EXISTS(p_expl_id))THEN RETURN h_ContextPath(p_expl_id); END IF;
190 
191       v_Node := p_expl_id;
192 
193       WHILE(v_Node IS NOT NULL)LOOP
194 
195         IF(h_NodeType(v_Node) IN (PS_NODE_TYPE_REFERENCE, PS_NODE_TYPE_CONNECTOR))THEN
196 
197           v_ModelName := NULL;
198 
199           IF(h_NodeType(v_Node) = PS_NODE_TYPE_CONNECTOR AND
200 
201              --We do not need to add the connected model name if the participating node is the model
202              --itself, otherwise it will be twice in the path.
203 
204              h_ComponentId(v_Node) <> v_ExprPsNodeId(j))THEN
205 
206             BEGIN
207 
208               SELECT name INTO v_ModelName FROM cz_ps_nodes
209                WHERE ps_node_id = h_ComponentId(v_Node);
210             EXCEPTION
211               WHEN OTHERS THEN
212                 NULL;
213             END;
214           END IF;
215 
216           IF(v_ModelName IS NOT NULL)THEN v_ModelName := FND_GLOBAL.LOCAL_CHR(7) || '''' || v_ModelName || ''''; END IF;
217 
218           IF(v_Name IS NULL)THEN v_Name := generate_model_path(h_ReferringId(v_Node)) || v_ModelName;
219           ELSE v_Name := generate_model_path(h_ReferringId(v_Node)) || v_ModelName || FND_GLOBAL.LOCAL_CHR(8) || v_Name;
220           END IF;
221         END IF;
222 
223         v_Node := h_ParentId(v_Node);
224       END LOOP;
225 
226       --h_ContextPath(p_expl_id) := v_Name;
227      RETURN v_Name;
228     END generate_context_path;
229 ---------------------------------------------------------------------------------------
230     FUNCTION generate_name RETURN VARCHAR2 IS
231       v_expl_id          NUMBER := v_ExplNodeId(j);
232       v_this             VARCHAR2(32767);
233       v_that             VARCHAR2(32767);
234       v_subthis          VARCHAR2(32767);
235       v_subthat          VARCHAR2(32767);
236       v_name             VARCHAR2(32767);
237       v_level            PLS_INTEGER;
238       v_depth            PLS_INTEGER := 0;
239     BEGIN
240 
241       IF(v_ExprPsNodeId(j) = h_ReferringId(v_expl_id))THEN
242         v_expl_id := h_ParentId(v_expl_id);
243       END IF;
244 
245       IF(v_expl_id IS NOT NULL)THEN v_this := generate_context_path(v_expl_id); END IF;
246       v_name := generate_model_path(v_ExprPsNodeId(j));
247 
248       IF(v_this IS NULL)THEN
249         IF(NOT h_FullName.EXISTS(v_ExprPsNodeId(j)))THEN v_name := h_NodeName(v_ExprPsNodeId(j)); END IF;
250       ELSE
251 
252         FOR i IN 1..v_NodeId.COUNT LOOP
253 
254           IF(h_ComponentId(v_NodeId(i)) = h_ComponentId(v_expl_id) AND v_NodeId(i) <> v_expl_id)THEN
255 
256             v_that := generate_context_path(v_NodeId(i));
257             v_level := 1;
258 
259             LOOP
260 
261               v_subthis := SUBSTR(v_this, INSTR(v_this, FND_GLOBAL.LOCAL_CHR(8), -1, v_level) + 1);
262               v_subthat := SUBSTR(v_that, INSTR(v_that, FND_GLOBAL.LOCAL_CHR(8), -1, v_level) + 1);
263 
264               IF(v_subthis = v_this)THEN EXIT; END IF;
265               IF(v_subthat = v_that)THEN v_Level := v_Level + 1; EXIT; END IF;
266               IF(v_subthis <> v_subthat)THEN EXIT; END IF;
267 
268               v_level := v_level + 1;
269             END LOOP;
270 
271             IF(v_level > v_depth)THEN v_depth := v_level; END IF;
272           END IF;
273         END LOOP;
274 
275         IF(v_depth = 0)THEN
276 
277           --Bug #4590481 - in this case we also need to concatenate the path. If the full path is not
278           --required, the second line will reset it to just the node name.
279 
280           v_name := v_this || FND_GLOBAL.LOCAL_CHR(8) || v_name;
281           IF(NOT h_FullName.EXISTS(v_ExprPsNodeId(j)))THEN v_name := h_NodeName(v_ExprPsNodeId(j)); END IF;
282         ELSE v_name := SUBSTR(v_this, INSTR(v_this, FND_GLOBAL.LOCAL_CHR(8), -1, v_depth) + 1) || FND_GLOBAL.LOCAL_CHR(8) || v_name;
283         END IF;
284       END IF;
285 
286       v_Index := vi_ExprId.COUNT + 1;
287       vi_ExprId(v_Index) := v_ExprId(j);
288 
289       v_Level := 1;
290       WHILE(INSTR(v_name, FND_GLOBAL.LOCAL_CHR(8), 1, v_Level) <> 0)LOOP v_Level := v_Level + 1; END LOOP;
291       vi_Depth(v_Index) := v_Level;
292 
293       v_name := REPLACE(v_name, '''' || FND_GLOBAL.LOCAL_CHR(7) || '''', '''.''');
294       v_name := REPLACE(v_name, '''' || FND_GLOBAL.LOCAL_CHR(8) || '''', '''.''');
295 
296       v_aux := 1;
297 
298       FOR i IN 1..vi_Name.COUNT LOOP
299         IF(v_name = vi_Name(i))THEN v_aux := v_aux + 1; END IF;
300       END LOOP;
301 
302       vi_Occurrence(v_Index) := v_aux;
303       vi_Name(v_Index) := v_name;
304 
305      RETURN v_name;
306     END generate_name;
307 ---------------------------------------------------------------------------------------
308   BEGIN
309 
310     currentLevel := currentLevel + 1;
311 
312     IF(v_ExprType(j) = EXPR_OPERATOR)THEN
313 
314 nDebug := 1000;
315 
316       --First correct a data_type upgrade problem from czrules1.sql. This is an operator, its children
317       --has not been generated into text yet. We will update data_type and data_num_value for children
321       IF(v_ExprTemplateId(j) IN
318       --in memory, if necessary, so that children will or will not be enclosed in quotes correctly. At
319       --the end, we physically update the columns in cz_expression_nodes.
320 
322           (318,320,321,322,323,350,351,352,353,399,401,402,403,
323            404,405,406,407,408,409,410,411,412,413,414,415,416,
324            417,418,430,431,432,433,434,435,436,437,438,439,551)
325          AND v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
326 
327         --This is one of the operators with only numeric operands or = or <>.
328 
329         v_Index := v_ChildrenIndex(v_ExprId(j));
330 
331         LOOP
332 
333           IF(v_ExprType(v_Index) = EXPR_LITERAL AND v_ExprDataType(v_Index) IS NULL AND
334              v_ExprDataNumValue(v_Index) IS NULL)THEN
335 
336             --This is a literal child of the operator with undefined data_type and data_num_value.
337             --Here we fix data only for such operands.
338 
339             BEGIN
340 
341               v_ExprDataNumValue(v_Index) := TO_NUMBER(v_ExprDataValue(v_Index));
342               v_ExprDataType(v_Index) := DATA_TYPE_DECIMAL;
343               IF(v_ExprTemplateId(j) = 551)THEN v_ExprDataType(v_Index) := DATA_TYPE_INTEGER; END IF;
344 
345             EXCEPTION
346               WHEN OTHERS THEN
347                 v_ExprDataType(v_Index) := DATA_TYPE_TEXT;
348             END;
349           END IF;
350 
351           v_Index := v_Index + 1;
352           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
353                      (v_ExprParentId(v_Index) IS NULL) OR
354                      (v_ExprParentId(v_Index) <> v_ExprId(j));
355         END LOOP;
356       END IF;
357 
358       --Done with the data fix for data_type, data_num_value population after czrules1.sql.
359 
360       v_token := h_TemplateToken(v_ExprTemplateId(j));
361 
362       IF((v_token IS NULL AND UPPER(h_RuleName(v_ExprTemplateId(j))) NOT IN ('CONTRIBUTESTO', 'CONSUMESFROM', 'ADDSTO')) OR
363           v_NumberOfChildren(v_ExprId(j)) > 2)THEN
364 
365         v_RuleText := NVL(h_RuleName(v_ExprTemplateId(j)), v_token) || '(';
366 
367         IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
368 
369           v_Index := v_ChildrenIndex(v_ExprId(j));
370 
371           LOOP
372 
373             v_RuleText := v_RuleText || parse_expr_node(v_Index);
374             v_Index := v_Index + 1;
375 
376             EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
377                       (v_ExprParentId(v_Index) IS NULL) OR
378                       (v_ExprParentId(v_Index) <> v_ExprId(j));
379 
380             v_RuleText := v_RuleText || ', ';
381           END LOOP;
382         END IF;
383 
384         v_RuleText := v_RuleText || ')';
385       ELSE
386 
387         IF(v_token IS NULL)THEN v_token := h_RuleName(v_ExprTemplateId(j)); END IF;
388 
389         IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
390 
391           v_Index := v_ChildrenIndex(v_ExprId(j));
392 
393           IF(v_NumberOfChildren(v_ExprId(j)) = 2)THEN
394             IF(UPPER(v_token) = 'CONTRIBUTESTO')THEN
395 
396               v_RuleText := 'Contribute ' || parse_expr_node(v_Index) || ' TO';
397               v_token := NULL;
398             ELSIF(UPPER(v_token) = 'ADDSTO')THEN
399 
400               v_RuleText := 'ADD ' || parse_expr_node(v_Index) || ' TO';
401               v_token := NULL;
402             ELSE
403 
404               v_RuleText := parse_expr_node(v_Index) || ' ';
405             END IF;
406 
407             v_Index := v_Index + 1;
408           END IF;
409 
410           v_RuleText := v_RuleText || v_token || ' ' || parse_expr_node(v_Index);
411         ELSE
412 
413           v_RuleText := v_token;
414         END IF;
415 
416         IF((isForall = 0 AND currentLevel > 1) OR (isForall = 1 AND currentLevel > 2))THEN
417 
418             v_RuleText := '(' || v_RuleText || ')';
419         END IF;
420       END IF;
421     ELSIF(v_ExprType(j) = EXPR_LITERAL)THEN
422 
423 nDebug := 1001;
424 
425       IF(v_ExprDataType(j) IN (DATA_TYPE_INTEGER, DATA_TYPE_DECIMAL))THEN
426 
427         v_RuleText := v_ExprDataNumValue(j);
428       ELSIF(v_ExprDataType(j) = DATA_TYPE_TEXT OR (v_ExprDataType(j) IS NULL AND v_ExprDataNumValue(j) IS NULL))THEN
429 
430         v_RuleText := '"' || v_ExprDataValue(j) || '"';
431       ELSIF(v_ExprDataType(j) = DATA_TYPE_BOOLEAN) THEN
432         IF(v_ExprDataValue(j)=1) THEN
433 	    v_RuleText := 'TRUE ' ;
434         ELSE
435 	    v_RuleText := 'FALSE ';
436 
437 	END IF;
438       ELSE
439 
440         v_RuleText := v_ExprDataValue(j);
441       END IF;
442 
443     ELSIF(v_ExprType(j) = EXPR_PSNODE)THEN
444 
445 nDebug := 1002;
446 
447       v_RuleText := generate_name;
448 
449       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
450 
451         v_Index := v_ChildrenIndex(v_ExprId(j));
452 
453         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
454 
455           v_RuleText := v_RuleText || parse_expr_node(v_Index);
456           v_Index := v_Index + 1;
457         END LOOP;
458       END IF;
459 
463 
460     ELSIF(v_ExprType(j) = EXPR_PROP)THEN
461 
462 nDebug := 1003;
464       IF(NOT h_PropertyName.EXISTS(v_ExprPropertyId(j)))THEN
465 
466         --We don't want to account for deleted_flag in this query because we want to parse a rule even
467         --if it refers to a deleted property instead of ignoring the rule.
468 
469         BEGIN
470           SELECT name INTO v_Name FROM cz_properties
471            WHERE property_id = v_ExprPropertyId(j);
472 
473           h_PropertyName(v_ExprPropertyId(j)) := v_Name;
474 
475         EXCEPTION
476           WHEN OTHERS THEN
477             errmsg1 := TO_CHAR(v_ExprId(j));
478             errmsg2 := TO_CHAR(v_ExprPropertyId(j));
479             RAISE CZ_UPRT_INCORRECT_PROP;
480         END;
481       ELSE
482 
483         v_Name := h_PropertyName(v_ExprPropertyId(j));
484       END IF;
485 
486       v_Name := '"' || v_Name || '"';
487       v_RuleText := '.Property(' || v_Name || ')';
488       v_aux := 1;
489 
490       FOR i IN 1..vi_Name.COUNT LOOP
491         IF(v_Name = vi_Name(i))THEN v_aux := v_aux + 1; END IF;
492       END LOOP;
493 
494       v_Index := vi_ExprId.COUNT + 1;
495       vi_ExprId(v_Index) := v_ExprId(j);
496       vi_Occurrence(v_Index) := v_aux;
497       vi_Depth(v_Index) := 0;
498       vi_Name(v_Index) := v_Name;
499 
500     ELSIF(v_ExprType(j) = EXPR_SYS_PROP)THEN
501 
502 nDebug := 1004;
503 
504       IF(isCompatible = 0)THEN v_RuleText := '.' || h_RuleName(v_ExprTemplateId(j)) || '()'; END IF;
505 
506     ELSIF(v_ExprType(j) = EXPR_ARGUMENT)THEN
507 
508 nDebug := 1005;
509 
510       v_RuleText := v_ExprArgumentName(j);
511 
512       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
513 
514         v_Index := v_ChildrenIndex(v_ExprId(j));
515 
516         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
517 
518           v_RuleText := v_RuleText || parse_expr_node(v_Index);
519           v_Index := v_Index + 1;
520         END LOOP;
521       END IF;
522 
523     ELSIF(v_ExprType(j) = EXPR_TEMPLATE)THEN
524 
525 nDebug := 1006;
526 
527       v_RuleText := '@' || h_RuleName(v_ExprTemplateId(j));
528 
529     ELSIF(v_ExprType(j) = EXPR_FORALL)THEN
530 
531 nDebug := 1007;
532 
533       isForall := 1;
534       v_RuleText := ' FOR ALL' || NewLine;
535 
536       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
537 
538         v_Index := v_ChildrenIndex(v_ExprId(j)) + v_NumberOfChildren(v_ExprId(j)) - 1;
539 
540         IF(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j) AND
541            v_ExprType(v_Index) NOT IN (EXPR_ITERATOR, EXPR_WHERE))THEN
542 
543           v_RuleText := parse_expr_node(v_Index) || v_RuleText;
544         END IF;
545 
546         v_Index := v_ChildrenIndex(v_ExprId(j));
547 
548         LOOP
549 
550           v_RuleText := v_RuleText || parse_expr_node(v_Index);
551           v_Index := v_Index + 1;
552 
553           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
554                     (v_ExprType(v_Index) NOT IN (EXPR_ITERATOR, EXPR_WHERE)) OR
555                     (v_ExprParentId(v_Index) IS NULL) OR
556                     (v_ExprParentId(v_Index) <> v_ExprId(j));
557 
558           IF(v_ExprType(v_Index - 1) = EXPR_ITERATOR AND v_ExprType(v_Index) = EXPR_ITERATOR)THEN
559             v_RuleText := v_RuleText || ',';
560           END IF;
561           v_RuleText := v_RuleText || NewLine;
562         END LOOP;
563       END IF;
564       isForall := 0;
565 
566     ELSIF(v_ExprType(j) = EXPR_ITERATOR)THEN
567 
568 nDebug := 1008;
569 
570       IF(isCompatible = 1)THEN v_RuleText := v_ExprArgumentName(j) || ' OF ';
571       ELSE v_RuleText := v_ExprArgumentName(j) || ' IN {'; END IF;
572 
573       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
574 
575         v_Index := v_ChildrenIndex(v_ExprId(j));
576 
577         LOOP
578 
579           v_RuleText := v_RuleText || parse_expr_node(v_Index);
580           v_Index := v_Index + 1;
581 
582           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
583                     (v_ExprParentId(v_Index) IS NULL) OR
584                     (v_ExprParentId(v_Index) <> v_ExprId(j));
585 
586           v_RuleText := v_RuleText || ', ';
587         END LOOP;
588       END IF;
589 
590       IF(isCompatible = 0)THEN v_RuleText := v_RuleText || '}'; END IF;
591 
592     ELSIF(v_ExprType(j) = EXPR_WHERE)THEN
593 
594 nDebug := 1009;
595 
596       v_RuleText := ' WHERE' || NewLine;
597 
598       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
599 
600         v_Index := v_ChildrenIndex(v_ExprId(j));
601 
602         WHILE(v_ExprParentId.EXISTS(v_Index) AND v_ExprParentId(v_Index) = v_ExprId(j))LOOP
603 
604           v_RuleText := v_RuleText || parse_expr_node(v_Index);
605           v_Index := v_Index + 1;
606         END LOOP;
607       END IF;
608 
609     ELSIF(v_ExprType(j) = EXPR_COMPATIBLE)THEN
610 
611 nDebug := 1010;
612 
613       isCompatible := 1;
614       v_RuleText := 'COMPATIBLE' || NewLine;
615 
616       IF(v_ChildrenIndex.EXISTS(v_ExprId(j)))THEN
617 
618         v_Index := v_ChildrenIndex(v_ExprId(j));
619 
620         LOOP
621 
622           v_RuleText := v_RuleText || parse_expr_node(v_Index);
623           v_Index := v_Index + 1;
624 
625           EXIT WHEN (NOT v_ExprParentId.EXISTS(v_Index)) OR
626                     (v_ExprParentId(v_Index) IS NULL) OR
627                     (v_ExprParentId(v_Index) <> v_ExprId(j));
628 
629           IF(v_ExprType(v_Index - 1) = EXPR_ITERATOR AND v_ExprType(v_Index) = EXPR_ITERATOR)THEN
630             v_RuleText := v_RuleText || ',';
631           END IF;
632           v_RuleText := v_RuleText || NewLine;
633         END LOOP;
634       END IF;
635       isCompatible := 0;
636     ELSIF(v_ExprType(j) = EXPR_CONSTANT)THEN
637 
638       IF(v_ExprTemplateId(j) =  EXPR_CONSTANT_E)THEN
639 
640         v_RuleText := CONSTANT_E;
641       ELSE
642 
643         v_RuleText := CONSTANT_PI;
644       END IF;
645     ELSE
646       errmsg1 := TO_CHAR(v_ExprId(j));
647       errmsg2 := TO_CHAR(v_ExprType(j));
648       RAISE CZ_UPRT_UNKNOWN_TYPE;
649     END IF;
650 
651    currentLevel := currentLevel - 1;
652    RETURN v_RuleText;
653   END parse_expr_node;
654 ---------------------------------------------------------------------------------------
655 
656 
657 BEGIN
658 
659 nDebug := 2;
660 
661    v_pres_flag:=1;
662 
663    SELECT presentation_flag
664       INTO v_pres_flag
665    FROM cz_rules ru
666    WHERE rule_id = p_rule_id
667    AND(rule_text IS NULL
668      OR EXISTS
669       (SELECT 1
670        FROM cz_expression_nodes
671        WHERE rule_id = ru.rule_id
672        AND template_id IN(712,    714 , 552 , 2))
673      );
674 
675    if v_pres_flag=1  then
676 	return;
677    end if;
678    --Read the expression into memory.
679 
680    SELECT expr_node_id, expr_parent_id, expr_type, template_id,
681           ps_node_id, model_ref_expl_id, property_id, data_type, data_value, data_num_value,
682           param_index, argument_name
683      BULK COLLECT INTO v_ExprId, v_ExprParentId, v_ExprType, v_ExprTemplateId,
684                        v_ExprPsNodeId, v_ExplNodeId, v_ExprPropertyId, v_ExprDataType, v_ExprDataValue, v_ExprDataNumValue,
685                        v_ExprParamIndex, v_ExprArgumentName
686      FROM cz_expression_nodes
687     WHERE rule_id = p_rule_id
688       AND expr_type <> 208
689       AND deleted_flag = '0'
690     ORDER BY expr_parent_id, seq_nbr;
691 
692    rootIndex := 0;
693 
694    FOR i IN 1..v_ExprId.COUNT LOOP
695 
696      IF(NOT v_NumberOfChildren.EXISTS(v_ExprId(i)))THEN v_NumberOfChildren(v_ExprId(i)) := 0; END IF;
697 
698      IF(v_ExprParentId(i) IS NOT NULL)THEN
699 
700        IF(v_NumberOfChildren.EXISTS(v_ExprParentId(i)))THEN
701          v_NumberOfChildren(v_ExprParentId(i)) := v_NumberOfChildren(v_ExprParentId(i)) + 1;
702        ELSE
703          v_NumberOfChildren(v_ExprParentId(i)) := 1;
704        END IF;
705 
706        IF(NOT v_ChildrenIndex.EXISTS(v_ExprParentId(i)))THEN
707          v_ChildrenIndex(v_ExprParentId(i)) := i;
708        END IF;
709      ELSE
710 
711        IF(rootIndex = 0)THEN rootIndex := i; ELSE RAISE CZ_UPRT_MULTIPLE_ROOTS; END IF;
712      END IF;
713    END LOOP;
714 
715 nDebug := 3;
716 
717    v_RuleText := parse_expr_node(rootIndex);
718 
719    FOR i IN 1..vi_ExprId.COUNT LOOP
720 
721      --We are trying to find the position of an occurence of the name in the text. We need to
722      --handle the situation when the name can be a part of another name. For example, if both
723      --'A'.'B'.'C' and 'A'.'B' are in the text, we should skip 'A'.'B' found as a part of
724      --'A'.'B'.'C'. So, when an occurence of 'A'.'B' is found, we check the next symbol, and
725      --if it is '.''', we need to keep looking. Note, that we can't check for just '.' as
726      --there may be a property following the name.
727 
728      currentLevel := 0;
729 
730      FOR j IN 1..vi_Occurrence(i) LOOP
731 
732        currentLevel := INSTR(v_RuleText, vi_Name(i), currentLevel + 1);
733 
734        WHILE(SUBSTR(v_RuleText, currentLevel + LENGTH(vi_Name(i)), 2) = '.''')LOOP
735 
736          currentLevel := INSTR(v_RuleText, vi_Name(i), currentLevel + 1);
737        END LOOP;
738      END LOOP;
739 
740      vi_Pos(i) := currentLevel;
741    END LOOP;
742 
743    FORALL i IN 1..vi_ExprId.COUNT
744      UPDATE cz_expression_nodes SET
745        display_node_depth = vi_Depth(i),
746        source_offset = vi_Pos(i),
747        source_length = LENGTH(vi_Name(i))
748      WHERE expr_node_id = vi_ExprId(i);
749 
750    --We need to update these columns as they may have been corrected in parse_expr_node procedure.
751 
752    FORALL i IN 1..v_ExprId.COUNT
753      UPDATE cz_expression_nodes SET
754        data_type = v_ExprDataType(i),
755        data_num_value = v_ExprDataNumValue(i)
756      WHERE expr_node_id = v_ExprId(i);
757 
758    UPDATE cz_rules SET rule_text = v_RuleText WHERE rule_id = p_rule_id;
759 
760 EXCEPTION
761   WHEN CZ_UPRT_MULTIPLE_ROOTS THEN
762     xError := cz_utils.report('rule_id = ' || p_rule_id || ': more than one record with null expr_parent_id', 1, 'CDL Rule Upgrade', 13000);
763   WHEN CZ_UPRT_UNKNOWN_TYPE THEN
764     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': unknown expression type, expr_type = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
765   WHEN CZ_UPRT_INCORRECT_PROP THEN
766     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': no such property, property_id = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
767   WHEN CZ_UPRT_INCORRECT_NODE THEN
768     xError := cz_utils.report('rule_id = ' || p_rule_id || ', expr_node_id = ' || errmsg1 || ': no such node, ps_node_id = ' || errmsg2, 1, 'CDL Rule Upgrade', 13000);
769   WHEN OTHERS THEN
770     errmsg1 := SQLERRM;
771     xError := cz_utils.report('rule_id = ' || p_rule_id || ' at ' || nDebug || ': ' || errmsg1, 1, 'CDL Rule Upgrade', 13000);
772 END populate_rule_text;
773 ---------------------------------------------------------------------------------------
774 BEGIN
775 
776 
777 DECLARE
778   xERROR  BOOLEAN;
779 BEGIN
780 
781   SELECT TO_NUMBER(value) INTO schema_version
782     FROM cz_db_settings
783    WHERE setting_id = 'MAJOR_VERSION'
784      AND section_name = 'SCHEMA';
785 
786 EXCEPTION
787   WHEN OTHERS THEN
788     xERROR:=CZ_UTILS.REPORT('Unable to resolve schema version: ' || SQLERRM, 1, 'czrules2.sql' , 13000);
789     RAISE;
790 END;
791 
792 
793 nDebug := 1;
794 
795    --Initialize the rule data for resolving token names.
796 
797    SELECT rule_id, name, template_token BULK COLLECT INTO v_RuleId, v_RuleName, v_TemplateToken
798      FROM cz_rules
799     WHERE deleted_flag = '0'
800       AND disabled_flag = '0'
801       AND rule_id < 1000;
802 
803    FOR i IN 1..v_RuleId.COUNT LOOP
804 
805      h_RuleName(v_RuleId(i)) := v_RuleName(i);
806      h_TemplateToken(v_RuleId(i)) := v_TemplateToken(i);
807    END LOOP;
808 
809    --Intitialize the explosion data.
810 
811    SELECT model_ref_expl_id, parent_expl_node_id, component_id, referring_node_id, ps_node_type
812      BULK COLLECT INTO v_NodeId, v_ParentId, v_ComponentId, v_ReferringId, v_NodeType
813      FROM cz_model_ref_expls
814     WHERE model_id = p_devl_project_id
815       AND deleted_flag = '0';
816 
817    FOR i IN 1..v_NodeId.COUNT LOOP
818 
819      h_ParentId(v_NodeId(i)) := v_ParentId(i);
820      h_NodeType(v_NodeId(i)) := v_NodeType(i);
821      h_ReferringId(v_NodeId(i)) := v_ReferringId(i);
822      h_ComponentId(v_NodeId(i)) := v_ComponentId(i);
823    END LOOP;
824 
825    IF(p_rule_id IS NOT NULL)THEN
826 
827      populate_rule_text(p_rule_id);
828    ELSE
829 
830      FOR c_rule IN (SELECT rule_id FROM cz_rules
831                      WHERE deleted_flag = '0'
832                        AND devl_project_id = p_devl_project_id
833                        AND rule_type IN (100, 200)) LOOP
834        populate_rule_text(c_rule.rule_id);
835      END LOOP;
836    END IF;
837 END parse_rules;
838 
839 END cz_rule_text_gen ;