DBA Data[Home] [Help]

PACKAGE BODY: APPS.M4U_XML_EXTN

Source


1 PACKAGE BODY m4u_xml_extn AS
2 /* $Header: M4UGENXB.pls 120.0 2006/05/25 12:51:33 bsaratna noship $ */
3 
4         -- logging/error handling variables
5         g_log_lvl               NUMBER;
6         g_success_code          VARCHAR2(30);
7         g_unexp_err_code        VARCHAR2(30);
8         g_err_code              VARCHAR2(30);
9         g_remove_empty_elmt     BOOLEAN;
10         g_remove_empty_attr     BOOLEAN;
11 
12         -- get value for a element node
13         -- based on mapping type
14         -- return value or null in case of error
15         FUNCTION get_node_value(
16                         a_elmt_rec      IN            m4u_xml_extn_utils.elmnt_rec_typ,
17                         x_ret_sts       OUT NOCOPY    VARCHAR2,
18                         x_ret_msg       OUT NOCOPY    VARCHAR2)
19         RETURN VARCHAR2 AS
20                 l_tmp_val VARCHAR2(32767);
21                 l_progress VARCHAR2(4000);
22         BEGIN
23                 l_progress := 'Get value for node - ' || a_elmt_rec.id;
24                 IF g_log_lvl <= 2 THEN
25                         cln_debug_pub.add('Entering m4u_xml_extn.get_node_value',        2);
26                         cln_debug_pub.add('a_elmt_rec.id       - ' || a_elmt_rec.id,     2);
27                         cln_debug_pub.add('a_elmt_rec.map_typ  - ' || a_elmt_rec.map_typ,2);
28                 END IF;
29 
30                 l_tmp_val := NULL;
31 
32                 -- mapping type is constant then elmt_rec.const contains the
33                 -- node.value
34                 IF a_elmt_rec.map_typ   = m4u_xml_extn_utils.c_maptyp_const THEN
35 
36                         l_tmp_val := a_elmt_rec.const;
37                 -- if mapping type is variable, lookup global variables for value
38                 ELSIF a_elmt_rec.map_typ = m4u_xml_extn_utils.c_maptyp_var THEN
39 
40                         BEGIN
41                                 l_tmp_val := m4u_xml_extn_utils.g_glb_var_tab(a_elmt_rec.var);
42                         EXCEPTION
43                                 WHEN NO_DATA_FOUND THEN
44                                         FND_MESSAGE.SET_NAME('CLN','M4U_XFWK_INV_PARAM');
45                                         FND_MESSAGE.SET_TOKEN('PARAM','Global variable');
46                                         FND_MESSAGE.SET_TOKEN('VALUE',a_elmt_rec.var);
47                                         x_ret_msg := FND_MESSAGE.GET;
48                                         x_ret_sts := g_err_code;
49                                         IF g_log_lvl <= 1 THEN
50                                                 cln_debug_pub.add('Fetch global variable error',1);
51                                         END IF;
52                                         RAISE FND_API.G_EXC_ERROR;
53                         END;
54                 -- if mapping type view, call lookup view value
55                 ELSIF a_elmt_rec.map_typ = m4u_xml_extn_utils.c_maptyp_view THEN
56 
57                         l_tmp_val := m4u_xml_extn_utils.lookup_view_value
58                                         (a_elmt_rec.view_nam,a_elmt_rec.col,
59                                         a_elmt_rec.view_lvl,x_ret_sts, x_ret_msg);
60 
61                         IF x_ret_sts <> g_success_code THEN
62                                 IF g_log_lvl <= 1 THEN
63                                         cln_debug_pub.add('lookup_view_value returns error',1);
64                                 END IF;
65                                 RAISE FND_API.G_EXC_ERROR;
66                         END IF;
67 
68                 ELSE
69                         -- unknown mapping type
70                         -- return error
71                         IF g_log_lvl <= 1 THEN
72                                 cln_debug_pub.add('Mapping type not-found',1);
73                         END IF;
74                         FND_MESSAGE.SET_NAME('CLN','M4U_XFWK_INV_PARAM');
75                         FND_MESSAGE.SET_TOKEN('PARAM','Element mapping type');
76                         FND_MESSAGE.SET_TOKEN('VALUE',a_elmt_rec.map_typ);
77                         x_ret_msg := FND_MESSAGE.GET;
78                         x_ret_sts := g_err_code;
79                         RAISE FND_API.G_EXC_ERROR;
80 
81                 END IF;
82                 -- return success
83                 x_ret_sts       := g_success_code;
84                 x_ret_msg       := NULL;
85 
86                 IF g_log_lvl <= 2 THEN
87                         cln_debug_pub.add('Exiting m4u_xml_extn.get_node_value - Normal',2);
88                         cln_debug_pub.add('ret_val  - ' || substr(l_tmp_val,1,255), 2);
89                 END IF;
90 
91                 l_tmp_val := m4u_xml_extn_utils.escape_entities(l_tmp_val);
92 
93                 RETURN l_tmp_val;
94         EXCEPTION
95                 WHEN FND_API.G_EXC_ERROR THEN
96                         IF g_log_lvl <= 6 THEN
97                                 cln_debug_pub.add('Exiting m4u_xml_extn.get_node_value - Error',6);
98                                 cln_debug_pub.add('x_ret_msg        - ' || x_ret_msg,6);
99                         END IF;
100                         x_ret_sts := g_err_code;
101                         l_tmp_val := null;
102                         RETURN l_tmp_val;
103                 WHEN OTHERS THEN
104                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
105                         'm4u_xml_extn.get_node_value',x_ret_sts,x_ret_msg);
106                         l_tmp_val := null;
107                         RETURN l_tmp_val;
108         END get_node_value;
109 
110         -- push index of end tag onto level_reg.end_tag_stk
111         PROCEDURE push_end_tag(a_el_idx         IN              NUMBER,
112                                a_lvl_rec        IN OUT NOCOPY   m4u_xml_extn_utils.lvl_rec_typ,
113                                x_ret_sts        OUT NOCOPY      VARCHAR2,
114                                x_ret_msg        OUT NOCOPY      VARCHAR2)
115         IS
116                 l_progress VARCHAR2(4000);
117         BEGIN
118                 l_progress := 'Stack end tag(idx) - ' || a_el_idx;
119                 IF g_log_lvl <= 2 THEN
120                     cln_debug_pub.add('Entering push_end_tag',         2);
121                     cln_debug_pub.add('a_el_idx       - ' || a_el_idx, 2);
122                     cln_debug_pub.add('a_lvl_rec.id   - ' || a_lvl_rec.id,2);
123                     cln_debug_pub.add('end_tag_stk_ptr- ' || a_lvl_rec.end_tag_stk_ptr,2);
124                 END IF;
125 
126                 a_lvl_rec.end_tag_stk_ptr := a_lvl_rec.end_tag_stk_ptr+1;
127                 a_lvl_rec.end_tag_stk(a_lvl_rec.end_tag_stk_ptr):=  a_el_idx;
128 
129                 IF g_log_lvl <= 1 THEN
130                     cln_debug_pub.add('end_tag_stk_ptr-' || a_lvl_rec.end_tag_stk_ptr,1);
131                 END IF;
132 
133                 x_ret_sts := g_success_code;
134                 x_ret_msg := null;
135                 IF g_log_lvl <= 2 THEN
136                     cln_debug_pub.add('Exiting push_end_tag - Success',2);
137                 END IF;
138         EXCEPTION
139                 WHEN OTHERS THEN
140                     m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
141                                 'm4u_xml_extn.push_end_tag',x_ret_sts,x_ret_msg);
142         END push_end_tag;
143 
144 
145         -- processes element.
146         -- puts start tag on to level XML
147         -- gets value of element onto the level XML
148         -- process attributes of the elements
149         -- pushes element index into level end-tag-stk
150         FUNCTION process_element(a_elmt_rec     IN         m4u_xml_extn_utils.elmnt_rec_typ,
151                                  a_elmt_idx     IN         NUMBER,
152                                  a_lvl_rec      IN OUT NOCOPY m4u_xml_extn_utils.lvl_rec_typ,
153                                  x_nxt_idx      OUT NOCOPY NUMBER,
154                                  x_ret_sts      OUT NOCOPY VARCHAR2,
155                                  x_ret_msg      OUT NOCOPY VARCHAR2)
156         RETURN VARCHAR2
157         AS
158                 l_xml           VARCHAR2(32767);
159                 l_attr_idx      NUMBER;
160                 l_elmt_rec      m4u_xml_extn_utils.elmnt_rec_typ;
161                 l_tmp_val       VARCHAR2(4000);
162                 l_progress      VARCHAR2(4000);
163                 l_el_val        VARCHAR2(4000);
164                 l_no_attrval    BOOLEAN;
165         BEGIN
166                 l_progress := 'Processing element - ' || a_elmt_rec.id;
167                 IF g_log_lvl <= 2 THEN
168                         cln_debug_pub.add('Entering m4u_xml_extn.process_element',  2);
169                         cln_debug_pub.add('a_elmt_rec.id    - ' || a_elmt_rec.id,   2);
170                         cln_debug_pub.add('a_elmt_idx       - ' || a_elmt_idx,      2);
171                         cln_debug_pub.add('a_lvl_rec.id     - ' || a_lvl_rec.id,    2);
172                 END IF;
173 
174                 l_attr_idx := a_elmt_idx+1;
175 
176                 -- print start tag
177                 l_xml := '<'|| a_elmt_rec.name;
178 
179                 l_no_attrval := true;
180 
181                 -- loop through element's attributes
182                 -- process each attribute and add to start-tag
183                 LOOP
184                         IF g_log_lvl <= 1 THEN
185                                 cln_debug_pub.add('Loop l_attr_idx - ' || l_attr_idx,2);
186                         END IF;
187 
188                         -- keep checking if we are tripping off the table
189                         IF l_attr_idx > m4u_xml_extn_utils.g_elmnt_count THEN
190 
191                                 IF g_log_lvl <= 1 THEN
192                                         cln_debug_pub.add('Exit loop l_attr_idx >= m4u_xml_extn_utils.g_elmnt_count',1);
193                                 END IF;
194                                 EXIT;
195                         ELSE
196                                 l_elmt_rec := m4u_xml_extn_utils.g_elmnt_map(l_attr_idx);
197                                 IF g_log_lvl <= 1 THEN
198                                         cln_debug_pub.add('Next-rec l_elmt_rec.type     - ' || l_elmt_rec.type,         1);
199                                         cln_debug_pub.add('Next-rec l_elmt_rec.id       - ' || l_elmt_rec.id,           1);
200                                         cln_debug_pub.add('Next-rec l_elmt_rec.parent_id- ' || l_elmt_rec.parent_id,    1);
201                                 END IF;
202 
203                                 -- if next record attribute and child or current element
204                                 IF l_elmt_rec.type = m4u_xml_extn_utils.c_nodetyp_attr
205                                         AND     l_elmt_rec.parent_id = a_elmt_rec.id THEN
206 
207                                         l_tmp_val   := get_node_value(l_elmt_rec,x_ret_sts,x_ret_msg);
208 
209                                         IF l_tmp_val IS NOT NULL THEN
210                                                 l_no_attrval := false;
211                                         END IF;
212 
213                                         IF x_ret_sts <> g_success_code THEN
214                                                 IF g_log_lvl <= 1 THEN
215                                                         cln_debug_pub.add('get_node_value returns fail',1);
216                                                 END IF;
217                                                 RAISE FND_API.G_EXC_ERROR;
218                                         END IF;
219                                         -- print attribute="value" to the xml
220                                         IF l_tmp_val is NOT NULL OR g_remove_empty_attr = false THEN
221                                                 l_xml       := l_xml || ' ' || l_elmt_rec.name || '="' || l_tmp_val || '"';
222                                         END IF;
223                                         l_attr_idx  := l_attr_idx + 1;
224                                 ELSE
225                                         -- next element is not a attribute child
226                                         -- so close current element (and attributes) ends here
227                                         -- move out of loop
228                                         IF g_log_lvl <= 1 THEN
229                                                 cln_debug_pub.add('Exit loop l_attr_idx.type <> attribute',1);
230                                         END IF;
231                                         EXIT;
232                                 END IF;
233                         END IF;
234                 END LOOP;
235 
236                 l_el_val := NULL;
237 
238                 IF a_elmt_rec.type  = m4u_xml_extn_utils.c_nodetyp_elmt THEN
239 
240                         l_el_val := get_node_value(a_elmt_rec,x_ret_sts,x_ret_msg);
241                         IF x_ret_sts <> g_success_code THEN
242                                 IF g_log_lvl <= 1 THEN
243                                         cln_debug_pub.add('get_node_value returns fail',1);
244                                 END IF;
245                                 RAISE FND_API.G_EXC_ERROR;
246                         END IF;
247                 END IF;
248 
249                 IF l_el_val IS NOT NULL OR a_elmt_rec.type = m4u_xml_extn_utils.c_nodetyp_cont THEN
250 
251                         l_xml := l_xml || '>' || l_el_val;
252                         -- push end-tag to the stack
253                         push_end_tag(a_elmt_idx,a_lvl_rec,x_ret_sts,x_ret_msg);
254                         IF x_ret_sts <> g_success_code THEN
255                                 IF g_log_lvl <= 1 THEN
256                                         cln_debug_pub.add('push_end_tag returns fail',1);
257                                 END IF;
258                                 RAISE FND_API.G_EXC_ERROR;
259                         END IF;
260                 ELSE
261                         -- if element is empty and there are no non-null attributes
262                         -- then don't print the element
263                         IF g_remove_empty_elmt AND l_no_attrval THEN
264                                 l_xml := NULL;
265                         ELSE
269                 END IF;
266                                 -- shorthand for element notation
267                                 l_xml := l_xml || '/>';
268                         END IF;
270 
271 
272 
273                 -- return next index to be processed
274                 -- this will skip all the elements attributes and
275                 -- point to the next element
276                 x_nxt_idx   := l_attr_idx;
277                 x_ret_sts   := g_success_code;
278                 x_ret_msg   := NULL;
279 
280                 IF g_log_lvl <= 2 THEN
281                         cln_debug_pub.add('Exiting m4u_xml_extn.process_element - NORMAL',2);
282                         cln_debug_pub.add('x_xml            - ' || substr(l_xml,1,255),     2);
283                         cln_debug_pub.add('x_nxt_idx        - ' || x_nxt_idx,               2);
284                 END IF;
285 
286                 RETURN l_xml;
287 
288         EXCEPTION
289                 WHEN FND_API.G_EXC_ERROR THEN
290                         IF g_log_lvl <= 6 THEN
291                                 cln_debug_pub.add('Exiting m4u_xml_extn.process_element - Error',6);
292                                 cln_debug_pub.add('x_ret_msg    - ' || x_ret_msg,6);
293                         END IF;
294                         x_nxt_idx   := m4u_xml_extn_utils.g_elmnt_count+1;
295                         x_ret_sts   := g_err_code;
296                         l_xml := null;
297                         RETURN l_xml;
298                 WHEN OTHERS THEN
299                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
300                         'm4u_xml_extn.process_element',x_ret_sts,x_ret_msg);
301                         l_xml := null;
302                         RETURN l_xml;
303         END process_element;
304 
305 
306         -- pop level's end-tag-stack till the a_el_idx is reached
307         -- essentially this is called when a new element/level is to be processed.
308         -- the parent-id of new element is passed to the routine
309         -- so nested end tags are popped out
310         FUNCTION pop_end_tags(a_el_idx  IN            NUMBER,
311                               a_lvl_rec IN  OUT NOCOPY m4u_xml_extn_utils.lvl_rec_typ,
312                               x_ret_sts OUT NOCOPY    VARCHAR2,
313                               x_ret_msg OUT NOCOPY    VARCHAR2)
314         RETURN VARCHAR2 AS
315                 l_ret_str       VARCHAR2(32767);
316                 l_idx           NUMBER;
317                 l_elmt_rec      m4u_xml_extn_utils.elmnt_rec_typ;
318                 l_el_idx        NUMBER;
319                 l_progress      VARCHAR2(4000);
320         BEGIN
321                 IF g_log_lvl <= 2 THEN
322                         cln_debug_pub.add('Entering pop_end_tags',              2);
323                         cln_debug_pub.add('a_el_idx       - ' || a_el_idx,      2);
324                         cln_debug_pub.add('a_lvl_rec.id   - ' || a_lvl_rec.id , 2);
325                         cln_debug_pub.add('end_tag_stk_ptr- ' || a_lvl_rec.end_tag_stk_ptr,2);
326                 END IF;
327                 l_progress := 'Pop end-tags - ' || a_el_idx;
328                 -- pop stack till a_el_idx is found or stack is empty
329                 l_idx := a_lvl_rec.end_tag_stk_ptr;
330 
331                 LOOP
332 
333                         IF g_log_lvl <= 1 THEN
334                                 cln_debug_pub.add('Loop l_idx - ' || l_idx,1);
335                         END IF;
336 
337                         IF l_idx <= 0 THEN
338                                 IF g_log_lvl <= 1 THEN
339                                         cln_debug_pub.add('Exiting l_idx < 0');
340                                 END IF;
341                                 EXIT;
342                         END IF;
343 
344                         l_el_idx    := a_lvl_rec.end_tag_stk(l_idx);
345                         IF g_log_lvl <= 1 THEN
346                                 cln_debug_pub.add('Loop l_el_idx - ' || l_el_idx,1);
347                         END IF;
348 
349                         l_elmt_rec  := m4u_xml_extn_utils.g_elmnt_map(l_el_idx);
350                         IF g_log_lvl <= 1 THEN
351                                 cln_debug_pub.add('Loop l_elmt_rec.id - ' || l_elmt_rec.id,1);
352                         END IF;
353                         -- if node we are looking for is on tos
354                         -- return else pop xml tags to return string
355                         IF l_elmt_rec.id = a_el_idx THEN
356                                 IF g_log_lvl <= 1 THEN
357                                         cln_debug_pub.add('l_elmt_rec.id = a_el_idx',1);
358                                 END IF;
359                                 a_lvl_rec.end_tag_stk_ptr := l_idx;
360                                 EXIT;
361                         ELSE
362                                 IF g_log_lvl <= 1 THEN
363                                         cln_debug_pub.add('Loop l_elmt_rec.node_name - ' || l_elmt_rec.name,1);
364                                         cln_debug_pub.add('Loop l_ret_str            - ' || l_ret_str           ,1);
365                                 END IF;
366                                 l_ret_str :=  l_ret_str || '</' || l_elmt_rec.name || '>';
367                                 a_lvl_rec.end_tag_stk(l_idx) := null;
368                                 l_idx := l_idx - 1;
369                                 a_lvl_rec.end_tag_stk_ptr := l_idx;
370                         END IF;
371                 END LOOP;
372 
373                 x_ret_sts := g_success_code;
374                 x_ret_msg := NULL;
375 
376                 IF g_log_lvl <= 2 THEN
377                         cln_debug_pub.add('Exiting pop_end_tags - Success',2);
378                         cln_debug_pub.add('l_ret_str - ' || substr(l_ret_str,1,255),2);
379                 END IF;
383                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
380                 RETURN l_ret_str;
381         EXCEPTION
382                 WHEN OTHERS THEN
384                         'm4u_xml_extn.pop_end_tags',x_ret_sts,x_ret_msg);
385         END pop_end_tags;
386 
387         --kludge to find next non-child level given
388         --current level and start index of the current level
389         --design does not allow better code
390         FUNCTION next_lvl_elmnt(a_strt_idx    IN NUMBER,
391                                 a_lvl_id      IN NUMBER,
392                                 x_ret_sts     OUT NOCOPY VARCHAR2,
393                                 x_ret_msg     OUT NOCOPY VARCHAR2)
394 
395         RETURN NUMBER
396         IS
397                 l_tmp_str1 VARCHAR2(32767);
398                 l_tmp_str2 VARCHAR2(30);
399                 l_pid      NUMBER;
400                 l_cnt      NUMBER;
401                 l_progress VARCHAR2(4000);
402         BEGIN
403                 IF g_log_lvl <= 2 THEN
404                         cln_debug_pub.add('Entering m4u_xml_extn.next_lvl_elmnt',2);
405                         cln_debug_pub.add('a_start_idx - ' || a_strt_idx,2);
406                         cln_debug_pub.add('a_lvl_id    - ' || a_lvl_id,2);
407                 END IF;
408 
409                 l_progress := 'Lookup next element after idx - ' || a_strt_idx;
410 
411                 x_ret_sts := g_success_code;
412                 x_ret_msg := NULL;
413 
414                 l_cnt := m4u_xml_extn_utils.g_elmnt_count;
415 
416                 IF g_log_lvl <= 1 THEN
417                         cln_debug_pub.add('l_cnt - ' || l_cnt,1);
418                 END IF;
419 
420                 l_tmp_str1 := '@' || to_char(m4u_xml_extn_utils.g_elmnt_map(a_strt_idx).id) || '@';
421 
422                 FOR i in a_strt_idx+1..l_cnt LOOP
423                         l_tmp_str2 := '@' || to_char(m4u_xml_extn_utils.g_elmnt_map(i).parent_id) || '@';
424 
425                         IF  m4u_xml_extn_utils.g_elmnt_map(i).lvl_id <> a_lvl_id THEN
426                                 IF instr(l_tmp_str1,l_tmp_str2) <= 0 THEN
427                                         IF g_log_lvl <= 2 THEN
428                                                 cln_debug_pub.add('Exiting m4u_xml_extn.next_lvl_elmnt',2);
429                                                 cln_debug_pub.add('i - ' || i,2);
430                                         END IF;
431                                         return i;
432                                 END IF;
433                         END IF;
434 
435                         l_tmp_str1 := l_tmp_str1 ||  '@' || to_char(m4u_xml_extn_utils.g_elmnt_map(i).id) || '@';
436 
437                 END LOOP;
438 
439                 IF g_log_lvl <= 2 THEN
440                         cln_debug_pub.add('Exiting m4u_xml_extn.next_lvl_elmnt',2);
441                         cln_debug_pub.add('l_cnt - ' || l_cnt,2);
442                 END IF;
443 
444                 return l_cnt + 1;
445         EXCEPTION
446                 WHEN OTHERS THEN
447                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
448                         'm4u_xml_extn.next_lvl_elmnt',x_ret_sts,x_ret_msg);
449         END next_lvl_elmnt;
450 
451         -- process_level starting at a_strt_idx
452         -- return generated xml in x_xml
453         -- return next_idx to be processed x_nxt_idx
454         PROCEDURE process_level(a_strt_idx    IN         NUMBER,
455                                 x_xml         OUT NOCOPY VARCHAR2,
456                                 x_nxt_idx     OUT NOCOPY NUMBER,
457                                 x_ret_sts     OUT NOCOPY VARCHAR2,
458                                 x_ret_msg     OUT NOCOPY VARCHAR2)
459         AS
460 
461                 l_elmt_rec              m4u_xml_extn_utils.elmnt_rec_typ;
462                 l_lvl_rec               m4u_xml_extn_utils.lvl_rec_typ;
463 
464                 l_lvl_id                NUMBER;
465                 l_cur_idx               NUMBER;
466                 l_nxt_idx               NUMBER;
467                 l_prv_idx               NUMBER;
468                 l_ret_idx               NUMBER;
469                 l_child_lvl             BOOLEAN;
470                 l_progress              VARCHAR2(4000);
471 
472                 l_xml                   VARCHAR2(32767);
473                 l_tmp_xml               VARCHAR2(32767);
474                 HANDLED_EXCEPTION       exception;
475         BEGIN
476                 l_progress := 'Processing element(idx) - ' || a_strt_idx;
477                 IF g_log_lvl <= 2 THEN
478                         cln_debug_pub.add('Entering m4u_xml_extn.process_level',1);
479                         cln_debug_pub.add('a_start_idx - ' || a_strt_idx,1);
480                 END IF;
481 
482 
483                 IF a_strt_idx > m4u_xml_extn_utils.g_elmnt_count THEN
484                         x_xml       := NULL;
485                         x_nxt_idx   := a_strt_idx;
486                         x_ret_sts   := g_success_code;
487                         x_ret_msg   := NULL;
488                         RETURN;
489                 END IF;
490 
491                 l_elmt_rec   := m4u_xml_extn_utils.g_elmnt_map(a_strt_idx);
492                 l_lvl_id     := l_elmt_rec.lvl_id;
493 
494 
495                 IF g_log_lvl <= 1 THEN
496                         cln_debug_pub.add('Obtained element record',1);
497                         cln_debug_pub.add('l_elmt_rec.id  - ' || l_elmt_rec.id,1);
498                         cln_debug_pub.add('l_lvl_id       - ' || l_lvl_id,1);
499                 END IF;
500 
501                 m4u_xml_extn_utils.init_level(l_lvl_id,l_lvl_rec,x_ret_sts, x_ret_msg);
502                 IF g_log_lvl <= 1 THEN
506                 END IF;
503                         cln_debug_pub.add('m4u_xml_extn_utils.init_level returned',1);
504                         cln_debug_pub.add('x_ret_msg - ' || x_ret_msg,1);
505                         cln_debug_pub.add('x_ret_sts - ' || x_ret_sts,1);
507                 IF x_ret_sts <> g_success_code THEN
508                         RAISE FND_API.G_EXC_ERROR;
509                 END IF;
510 
511                 m4u_xml_extn_utils.push_lvl_stack(l_lvl_id,x_ret_sts,x_ret_msg);
512                 IF g_log_lvl <= 1 THEN
513                         cln_debug_pub.add('m4u_xml_extn_utils.push_lvl_stack returned',1);
514                         cln_debug_pub.add('x_ret_msg - ' || x_ret_msg,1);
515                         cln_debug_pub.add('x_ret_sts - ' || x_ret_sts,1);
516                 END IF;
517                 IF x_ret_sts <> g_success_code THEN
518                         RAISE FND_API.G_EXC_ERROR;
519                 END IF;
520 
521                 IF g_log_lvl <= 1 THEN
522                         cln_debug_pub.add('Level count - ' || l_lvl_rec.rpt_count,1);
523                 END IF;
524 
525 
526                 l_cur_idx := a_strt_idx;
527                 l_prv_idx := -1;
528                 l_nxt_idx := -1;
529                 l_ret_idx := -1;
530 
531                 WHILE l_lvl_rec.cntr < l_lvl_rec.rpt_count LOOP
532 
533                         l_progress := 'Processing element(idx) - ' || l_cur_idx;
534 
535                         IF g_log_lvl <= 1 THEN
536                                 cln_debug_pub.add('Level loop   - ' || l_lvl_rec.cntr,1);
537                                 cln_debug_pub.add('l_cur_idx    - ' || l_cur_idx,1);
538                                 cln_debug_pub.add('l_prv_idx    - ' || l_prv_idx,1);
539                                 cln_debug_pub.add('l_nxt_idx    - ' || l_nxt_idx,1);
540                         END IF;
541 
542                         IF l_cur_idx > m4u_xml_extn_utils.g_elmnt_count THEN
543                                 IF g_log_lvl <= 1 THEN
544                                         cln_debug_pub.add('l_cur_idx > g_elmnt_count',1);
545                                 END IF;
546 
547                                 l_lvl_rec.cntr  := l_lvl_rec.cntr + 1;
548                                 l_xml           := l_xml || pop_end_tags(-1,l_lvl_rec,x_ret_sts,x_ret_msg);
549                                 IF g_log_lvl <= 1 THEN
550                                         cln_debug_pub.add('pop_end_tags - ' || x_ret_sts,1);
551                                 END IF;
552                                 IF x_ret_sts <> g_success_code THEN
553                                         RAISE FND_API.G_EXC_ERROR;
554                                 END IF;
555                                 l_prv_idx       := l_cur_idx;
556                                 l_cur_idx       := a_strt_idx;
557                                 -- store changes back into global list of levels
558                                 m4u_xml_extn_utils.g_lvl_rec_tab(l_lvl_id) := l_lvl_rec;
559                         ELSE
560                                 IF g_log_lvl <= 1 THEN
561                                         cln_debug_pub.add('l_cur_idx <= g_elmnt_count',1);
562                                 END IF;
563 
564                                 l_elmt_rec      := m4u_xml_extn_utils.g_elmnt_map(l_cur_idx);
565 
566                                 IF g_log_lvl <= 1 THEN
567                                         cln_debug_pub.add('l_elmt_rec.id - ' || l_elmt_rec.id,1);
568                                 END IF;
569 
570                                 IF l_elmt_rec.lvl_id = l_lvl_id THEN
571 
572                                         IF g_log_lvl <= 1 THEN
573                                                 cln_debug_pub.add('l_elmt_rec.lvl_id = l_lvl_id',1);
574                                         END IF;
575 
576                                         l_xml := l_xml || pop_end_tags(l_elmt_rec.parent_id,l_lvl_rec,x_ret_sts,x_ret_msg);
577 
578 
579                                         IF g_log_lvl <= 1 THEN
580                                                 cln_debug_pub.add('pop_end_tags x_ret_sts - ' || x_ret_sts,1);
581                                         END IF;
582                                         IF x_ret_sts <> g_success_code THEN
583                                                 RAISE FND_API.G_EXC_ERROR;
584                                         END IF;
585 
586                                         l_xml := l_xml || process_element(l_elmt_rec,l_cur_idx,l_lvl_rec,
587                                                                         l_nxt_idx,x_ret_sts,x_ret_msg);
588 
589                                         IF g_log_lvl <= 1 THEN
590                                             cln_debug_pub.add('process_element x_ret_sts - ' || x_ret_sts,1);
591                                         END IF;
592                                         IF x_ret_sts <> g_success_code THEN
593                                                 RAISE FND_API.G_EXC_ERROR;
594                                         END IF;
595 
596                                         l_prv_idx := l_cur_idx;
597                                         l_cur_idx := l_nxt_idx;
598                                         -- store changes back into global list of levels
599                                         m4u_xml_extn_utils.g_lvl_rec_tab(l_lvl_id) := l_lvl_rec;
600 
601                                 ELSE
602                                         IF g_log_lvl <= 1 THEN
603                                                 cln_debug_pub.add('l_elmt_rec.lvl_id <> l_lvl_id',1);
604                                         END IF;
605 
606                                         l_child_lvl := false;
607 
608                                         FOR i IN 1..l_cur_idx-1 LOOP
609                                                 IF m4u_xml_extn_utils.g_elmnt_map(i).id = l_elmt_rec.parent_id THEN
613                                                 END IF;
610                                                         IF m4u_xml_extn_utils.g_elmnt_map(i).lvl_id = l_lvl_id THEN
611                                                                 l_child_lvl := true;
612                                                         END IF;
614                                         END LOOP;
615 
616                                         IF l_child_lvl THEN
617                                                 IF g_log_lvl <= 1 THEN
618                                                         cln_debug_pub.add('Child level found',1);
619                                                 END IF;
620                                                 l_xml := l_xml || pop_end_tags(l_elmt_rec.parent_id,l_lvl_rec,x_ret_sts,x_ret_msg);
621 
622                                                 IF g_log_lvl <= 1 THEN
623                                                         cln_debug_pub.add('pop_end_tags  - ' || x_ret_sts,1);
624                                                 END IF;
625                                                 IF x_ret_sts <> g_success_code THEN
626                                                         RAISE FND_API.G_EXC_ERROR;
627                                                 END IF;
628 
629                                                 process_level(l_cur_idx,l_tmp_xml,l_nxt_idx,x_ret_sts,x_ret_msg);
630 
631                                                 IF g_log_lvl <= 1 THEN
632                                                         cln_debug_pub.add('process_level x_ret_sts - ' || x_ret_sts,1);
633                                                         cln_debug_pub.add('process_level l_nxt_idx - ' || l_nxt_idx,1);
634                                                 END IF;
635 
636                                                 -- x_ret_msg now contains level/element-idx where
637                                                 -- the error has occured, dont over-write it
638                                                 IF x_ret_sts <> g_success_code THEN
639                                                         RAISE HANDLED_EXCEPTION;
640                                                 END IF;
641 
642                                                 l_xml := l_xml || l_tmp_xml;
643                                                 l_prv_idx := l_cur_idx;
644                                                 l_cur_idx := l_nxt_idx;
645 
646                                                 IF l_nxt_idx <= m4u_xml_extn_utils.g_elmnt_count THEN
647                                                         IF m4u_xml_extn_utils.g_elmnt_map(l_nxt_idx).lvl_id <> l_lvl_id THEN
648                                                                 l_ret_idx := l_nxt_idx;
649                                                         END IF;
650                                                 ELSE
651                                                         l_ret_idx := l_nxt_idx;
652                                                 END IF;
653                                                 -- store changes back into global list of levels
654                                                 m4u_xml_extn_utils.g_lvl_rec_tab(l_lvl_id) := l_lvl_rec;
655                                         ELSE
656                                                 IF g_log_lvl <= 1 THEN
657                                                         cln_debug_pub.add('non-child level found',1);
658                                                 END IF;
659                                                 l_xml := l_xml || pop_end_tags(-1,l_lvl_rec,x_ret_sts,x_ret_msg);
660 
661                                                 IF g_log_lvl <= 1 THEN
662                                                         cln_debug_pub.add('pop_end_tags x_ret_sts - ' || x_ret_sts,1);
663                                                 END IF;
664                                                 IF x_ret_sts <> g_success_code THEN
665                                                         RAISE FND_API.G_EXC_ERROR;
666                                                 END IF;
667 
668                                                 l_lvl_rec.cntr  := l_lvl_rec.cntr +1;
669                                                 l_prv_idx   := -1;
670                                                 l_nxt_idx   := -1;
671                                                 l_cur_idx   := a_strt_idx;
672                                                 -- store changes back into global list of levels
673                                                 m4u_xml_extn_utils.g_lvl_rec_tab(l_lvl_id) := l_lvl_rec;
674                                         END IF;
675                                 END IF;
676                         END IF;
677 
678                 END LOOP;
679 
680                 IF g_log_lvl <= 1 THEN
681                         cln_debug_pub.add('outside loop - ' || l_lvl_rec.cntr ,1);
682                 END IF;
683 
684                 -- just to make sure
685                 l_xml := l_xml || pop_end_tags(-1,l_lvl_rec,x_ret_sts,x_ret_msg);
686                 m4u_xml_extn_utils.g_lvl_rec_tab(l_lvl_id) := l_lvl_rec;
687 
688                 IF g_log_lvl <= 1 THEN
689                         cln_debug_pub.add('pop_end_tags x_ret_sts - ' || x_ret_sts,1);
690                 END IF;
691                 IF x_ret_sts <> g_success_code THEN
692                         RAISE FND_API.G_EXC_ERROR;
693                 END IF;
694                 -- above code can be deleted
695 
696                 m4u_xml_extn_utils.un_init_level(l_lvl_id,x_ret_sts,x_ret_msg);
697                 IF g_log_lvl <= 1 THEN
698                         cln_debug_pub.add('m4u_xml_extn_utils.un_init_level - ' || x_ret_sts,1);
699                 END IF;
700                 IF x_ret_sts <> g_success_code THEN
701                         RAISE FND_API.G_EXC_ERROR;
702                 END IF;
703 
704 
705                 IF l_ret_idx = -1 THEN
706                         IF g_log_lvl <= 1 THEN
710                         IF g_log_lvl <= 1 THEN
707                                 cln_debug_pub.add('Finding ret_idx for lvl_id - ' || l_lvl_id,1);
708                         END IF;
709                         l_ret_idx := next_lvl_elmnt(a_strt_idx,l_lvl_id,x_ret_sts,x_ret_msg);
711                                 cln_debug_pub.add('ret_idx  - ' || l_ret_idx ,1);
712                         END IF;
713                         IF x_ret_sts <> g_success_code THEN
714                                 RAISE FND_API.G_EXC_ERROR;
715                         END IF;
716                 END IF;
717                 IF g_log_lvl <= 1 THEN
718                         cln_debug_pub.add('m4u_xml_extn_utils.next_lvl_elmnt: l_ret_idx - ' || l_ret_idx,1);
719                 END IF;
720 
721                 l_lvl_id := m4u_xml_extn_utils.pop_lvl_stack(x_ret_sts,x_ret_msg);
722                 IF g_log_lvl <= 1 THEN
723                         cln_debug_pub.add('m4u_xml_extn_utils.pop_lvl_stack x_ret_sts - ' || x_ret_sts,1);
724                 END IF;
725                 IF x_ret_sts <> g_success_code THEN
726                         RAISE FND_API.G_EXC_ERROR;
727                 END IF;
728 
729                 x_xml         := l_xml;
730                 x_ret_sts     := g_success_code;
731                 x_ret_msg     := NULL;
732                 x_nxt_idx     := l_ret_idx;
733 
734                 IF g_log_lvl <= 2 THEN
735                         cln_debug_pub.add('Exiting m4u_xml_extn.process_level',2);
736                 END IF;
737         EXCEPTION
738                 WHEN  FND_API.G_EXC_ERROR THEN
739                         IF g_log_lvl <= 6 THEN
740                                 cln_debug_pub.add('process_level - WHEN FND_API.G_EXC_ERROR',6);
741                                 cln_debug_pub.add('l_lvl_id   - ' || l_lvl_id   ,6);
742                                 cln_debug_pub.add('l_cur_idx  - ' || l_cur_idx  ,6);
743                                 cln_debug_pub.add('l_progress - ' || l_progress ,6);
744                                 cln_debug_pub.add('x_ret_msg  - ' || x_ret_msg  ,6);
745                         END IF;
746 
747                         FND_MESSAGE.SET_NAME('CLN','M4U_XFWK_PROCESS_ERR');
748                         FND_MESSAGE.SET_TOKEN('LEVEL_ID'    ,l_lvl_id);
749                         FND_MESSAGE.SET_TOKEN('ELEMENT_IDX' ,l_cur_idx);
750                         FND_MESSAGE.SET_TOKEN('ACTION'      ,l_progress);
751                         FND_MESSAGE.SET_TOKEN('ERROR'       ,x_ret_msg);
752                         x_ret_msg := FND_MESSAGE.GET;
753                         x_ret_sts := g_err_code;
754 
755                 WHEN  HANDLED_EXCEPTION   THEN
756                         IF g_log_lvl <= 6 THEN
757                                 cln_debug_pub.add('process_level - HANDLED_EXCEPTION ',6);
758                                 cln_debug_pub.add('l_lvl_id   - ' || l_lvl_id   ,6);
759                                 cln_debug_pub.add('l_cur_idx  - ' || l_cur_idx  ,6);
760                                 cln_debug_pub.add('l_progress - ' || l_progress ,6);
761                                 cln_debug_pub.add('x_ret_msg  - ' || x_ret_msg  ,6);
762                         END IF;
763                         x_ret_sts := g_err_code;
764                 WHEN OTHERS THEN
765                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
766                         'm4u_xml_extn.process_level',x_ret_sts,x_ret_msg);
767         END process_level;
768 
769 
770         -- Generate XML fragment for given extn, tp_id combination
771         -- global variables for xml generation can be passed in a_param_lst
772         -- generated XML is copied back to x_xml
773         -- if a_tp_dflt = true then M4U_DEFAULT_TP is used as default TP mapping
774         PROCEDURE generate_xml_fragment
775         (
776                 a_extn_name             IN              VARCHAR2,
777                 a_tp_id                 IN              VARCHAR2,
778                 a_tp_dflt               IN              BOOLEAN,
779                 a_param_lst             IN              wf_parameter_list_t,
780                 a_log_lvl               IN              NUMBER,
781                 a_remove_empty_elmt     IN              BOOLEAN,
782                 a_remove_empty_attr     IN              BOOLEAN,
783                 x_ret_sts               OUT NOCOPY      VARCHAR2,
784                 x_ret_msg               OUT NOCOPY      VARCHAR2,
785                 x_xml                   OUT NOCOPY      VARCHAR2
786         ) AS
787                 l_tp_id         NUMBER;
788                 l_xml_frgmt     VARCHAR2(32767);
789                 l_api_ret_sts   VARCHAR2(30);
790                 l_api_ret_msg   VARCHAR2(4000);
791                 l_valdtn_sts    VARCHAR2(30);
792                 l_valdtn_msg    VARCHAR2(4000);
793                 l_nxt           NUMBER;
794                 l_progress      VARCHAR2(4000);
795         BEGIN
796 
797                 g_log_lvl := NVL(a_log_lvl,g_log_lvl);
798                 g_remove_empty_elmt := a_remove_empty_elmt;
799                 g_remove_empty_attr := a_remove_empty_attr;
800 
801                 IF g_log_lvl <= 2 THEN
802                         cln_debug_pub.add('Entering m4u_xml_extn.generate_xml_fragment',2);
803                         cln_debug_pub.add('a_extn_name  - ' || a_extn_name,     2);
804                         cln_debug_pub.add('a_tp_id      - ' || a_tp_id  ,       2);
805                         IF a_tp_dflt THEN
806                                 cln_debug_pub.add('a_tp_default         - Y' ,2);
807                         ELSE
808                                 cln_debug_pub.add('a_tp_default         - N' ,2);
809                         END IF;
810                         cln_debug_pub.add('a_log_lvl    - ' || a_log_lvl,       2);
811                 END IF;
812 
813                 -- load map data into memory structures
817                                              a_tp_id            => a_tp_id,
814                 l_progress := 'XML fragment generation - Map initialization';
815                 m4u_xml_extn_utils.init_map(
816                                              a_extn_name        => a_extn_name,
818                                              a_dflt_tp          => a_tp_dflt,
819                                              a_param_list       => a_param_lst,
820                                              a_log_lvl          => a_log_lvl,
821                                              x_ret_sts          => x_ret_sts,
822                                              x_ret_msg          => x_ret_msg);
823 
824 
825                 IF g_log_lvl <= 1 THEN
826                         cln_debug_pub.add('Returned from API m4u_xml_extn_utils.init_map',1);
827                         cln_debug_pub.add('x_ret_sts - ' || x_ret_sts,1);
828                         cln_debug_pub.add('x_ret_msg - ' || x_ret_msg,1);
829                 END IF;
830 
831                 IF x_ret_sts <> g_success_code THEN
832                         FND_MESSAGE.SET_NAME('CLN','M4U_XFWK_INIT_ERR');
833                         FND_MESSAGE.SET_TOKEN('EXTN_NAME',a_extn_name);
834                         FND_MESSAGE.SET_TOKEN('TP_ID',a_tp_id);
835                         x_ret_msg := FND_MESSAGE.GET || ' - ' || x_ret_msg;
836                         RETURN;
837                 END IF;
838 
839                 l_progress := 'XML fragment generation - Map processing';
840                 -- process elememts starting from element 1
841                 process_level(  a_strt_idx      => 1,
842                                 x_xml           => l_xml_frgmt,
843                                 x_nxt_idx       => l_nxt,
844                                 x_ret_sts       => x_ret_sts,
845                                 x_ret_msg       => x_ret_msg);
846 
847                 IF x_ret_sts <> g_success_code THEN
848                         IF g_log_lvl <= 1 THEN
849                                 cln_debug_pub.add('Returned from API m4u_xml_extn_utils.process_level Error',1);
850                         END IF;
851                         FND_MESSAGE.SET_NAME('CLN','M4U_XFWK_XMLGEN_ERR');
852                         FND_MESSAGE.SET_TOKEN('EXTN_NAME',a_extn_name);
853                         FND_MESSAGE.SET_TOKEN('TP_ID',a_tp_id);
854                         x_ret_msg := FND_MESSAGE.GET || ' - ' || x_ret_msg;
855                         RETURN;
856                 END IF;
857 
858                 l_progress := 'XML fragment generation - Logging';
859 
860                 -- log generated XML
861                 m4u_xml_extn_utils.log_xml(a_xml        => l_xml_frgmt ,
862                                            x_ret_sts   => l_api_ret_sts,
863                                            x_ret_msg   => l_api_ret_msg);
864 
865                 IF g_log_lvl <= 1 THEN
866                         cln_debug_pub.add('Returned from m4u_xml_utils.log_xml',1);
867                         cln_debug_pub.add('x_ret_sts - ' || l_api_ret_sts,1);
868                         cln_debug_pub.add('x_ret_msg - ' || l_api_ret_msg,1);
869                 END IF;
870 
871                 l_progress := 'XML fragment generation - Validation';
872 
873                 -- validate generated XML
874                 IF l_xml_frgmt IS NOT NULL AND length(l_xml_frgmt) > 0 THEN
875                         m4u_xml_extn_utils.validate(a_xml           => l_xml_frgmt,
876                                                 x_valdtn_sts    => l_valdtn_sts,
877                                                 x_valdtn_msg    => l_valdtn_msg,
878                                                 x_api_ret_sts   => l_api_ret_sts,
879                                                 x_api_ret_msg   => l_api_ret_msg);
880 
881                         IF g_log_lvl <= 1 THEN
882                                 cln_debug_pub.add('Returned from m4u_xml_utils.validate',1);
883                                 cln_debug_pub.add('x_valdtn_sts  - ' || l_valdtn_sts,1);
884                                 cln_debug_pub.add('x_valdtn_msg  - ' || l_valdtn_msg,1);
885                                 cln_debug_pub.add('x_api_ret_sts - ' || l_api_ret_sts,1);
886                                 cln_debug_pub.add('x_api_ret_msg - ' || l_api_ret_msg,1);
887                         END IF;
888 
889                         -- return success/failure of validation
890                         IF l_api_ret_sts = g_success_code THEN
891                                 x_ret_sts := l_valdtn_sts;
892                                 x_ret_msg := l_valdtn_msg;
893                         ELSE
894                                 x_ret_sts := g_unexp_err_code;
895                                 x_ret_msg := l_api_ret_msg;
896                         END IF;
897                 END IF;
898 
899                 x_xml := l_xml_frgmt;
900 
901                 l_progress := 'XML fragment generation - free resources';
902                 -- free-memory used by map
903                 m4u_xml_extn_utils.un_init_map(
904                                         x_ret_sts => l_api_ret_sts ,
905                                         x_ret_msg => l_api_ret_msg);
906                 IF g_log_lvl <= 1 THEN
907                         cln_debug_pub.add('Returned from m4u_xml_extn_utils.un_init_map',1);
908                         cln_debug_pub.add('x_api_ret_sts - ' || l_api_ret_sts,1);
909                         cln_debug_pub.add('x_api_ret_msg - ' || l_api_ret_msg,1);
910                 END IF;
911 
912 
913                 IF g_log_lvl <= 2 THEN
914                         cln_debug_pub.add('Exiting m4u_xml_extn.generate_xml_fragment - NORMAL',2);
915                 END IF;
916                 RETURN;
917         EXCEPTION
918                 WHEN OTHERS THEN
919                         m4u_xml_extn_utils.handle_exception(SQLCODE,SQLERRM,l_progress,
923                                         x_ret_sts => l_api_ret_sts ,
920                                 'm4u_xml_extn.generate_xml_fragment',x_ret_sts,x_ret_msg);
921                         BEGIN
922                                 m4u_xml_extn_utils.un_init_map(
924                                         x_ret_msg => l_api_ret_msg);
925                         EXCEPTION
926                                 WHEN OTHERS THEN
927                                         null;
928                         END;
929         END generate_xml_fragment;
930 
931 BEGIN
932         -- initialize contansts and profile dependant values
933         g_log_lvl               := NVL(FND_PROFILE.VALUE('CLN_DEBUG_LEVEL'), 5);
934         g_success_code          := FND_API.G_RET_STS_SUCCESS;
935         g_err_code              := FND_API.G_RET_STS_ERROR;
936         g_unexp_err_code        := FND_API.G_RET_STS_UNEXP_ERROR;
937 END m4u_xml_extn;