DBA Data[Home] [Help]

PACKAGE BODY: APPS.ICX_TEMPLATE_PARSER

Source


1 package body icx_template_parser as
2 /* $Header: ICXPARSB.pls 115.7 99/07/17 03:19:51 porting ship $ */
3 
4 -- Declaring the table for replacement meta_tag, replacement character
5 type table_row is record (
6           variable_name		varchar2(200),
7           sequence              number,
8           value			varchar2(32000),
9           related_id            number,
10           parent_name           varchar2(200),
11           parent_related_id     number
12 );
13 
14 
15 type variable_table is table of table_row
16    index by binary_integer;
17 
18 vars variable_table;
19 
20 
21 
22 procedure clear_variables is
23 
24 begin
25 vars.DELETE;
26 end clear_variables;
27 
28 
29 
30 procedure add_variable(p_variable_name in varchar2,
31                        p_sequence in number,
32                        p_value in varchar2,
33                        p_related_id in number default null,
34                        p_parent_name in varchar2 default null,
35                        p_parent_related_id in number default null) is
36 
37 l_index number;
38 
39 begin
40 
41 if vars.COUNT = 0 then
42   l_index := 1;
43 else
44   l_index := vars.LAST + 1;
45 end if;
46 
47 vars(l_index).variable_name := p_variable_name;
48 vars(l_index).sequence := p_sequence;
49 vars(l_index).value := p_value;
50 vars(l_index).related_id := p_related_id;
51 vars(l_index).parent_name := p_parent_name;
52 vars(l_index).parent_related_id := p_parent_related_id;
53 
54 
55 end add_variable;
56 
57 
58 
59 
60 procedure parse(p_template_name in varchar2) is
61 
62   type tag_var_record is record (tag_var_name varchar2(100),
63                                  tag_var_value varchar2(2000));
64 
65   type tag_var_table is table of tag_var_record index by binary_integer;
66 
67 
68   type tag_loop_table is table of varchar2(2000) index by binary_integer;
69 
70 
71   type disabled_tag_record is record(tag_name varchar2(100),
72                                      disable_variable varchar2(200),
73                                      disable_condition varchar2(100),
74                                      disable_value varchar2(32000),
75                                      disabled varchar2(1));
76   type disabled_tag_table is table of disabled_tag_record index by binary_integer;
77 
78 
79   type disabled_data_record is record(tag_name varchar2(100),
80                                       disabled_sequence number);
81   type disabled_data_table is table of disabled_data_record index by binary_integer;
82 
83 
84   type related_tag_record is record(tag_name varchar2(100),
85                                     parent varchar2(100));
86   type related_tag_table is table of related_tag_record index by binary_integer;
87 
88 
89   type replace_text_record is record
90                      (replace_text icx_template_tags.replacement_text%type,
91                       tag_owner varchar2(200));
92   type replace_text_table is table of replace_text_record index by binary_integer;
93 
94 
95   cursor tag_text(name varchar2) is
96     select replacement_text
97     from icx_template_tags
98     where tag_name = name;
99 
100   TAG_DOES_NOT_EXIST exception;
101   TAG_NOT_UNIQUE exception;
102   TAG_VAR_NO_END exception;
103   TAG_NO_END exception;
104   TAG_SYNTAX_ERROR exception;
105 
106   VARIABLE number := 1;
107   EXECUTABLE number := 2;
108 
109   l_html_pieces                 utl_http.html_pieces;  -- ICX
110   l_server varchar2(1000) :=  owa_util.get_cgi_env('SERVER_NAME');
111   l_port varchar2(20) := owa_util.get_cgi_env('SERVER_PORT');
112   l_html_piece                varchar2(32000);
113 
114 
115   l_tag_beginning               number;
116   l_tag_temp_end                number;
117   l_tag_temp_start              number;
118   l_tag_current_position        number;
119   l_tag_open_count              number;
120   l_tag_count                   number;
121   l_tag_end                     number;
122 
123   l_tag                         varchar2(2000);
124   l_sub_tag                     varchar2(2000);
125   l_tag_name			varchar2(200);
126   l_tag_loop_table              tag_loop_table;
127   l_first_group_tag_loop_table  tag_loop_table;
128   l_tag_var_table               tag_var_table;
129   l_tag_var_start               number;
130   l_tag_var_name_start          number;
131   l_tag_var_end                 number;
132   l_tag_var_num                 number;
133   l_replacement_text            icx_template_tags.replacement_text%type;
134   l_replace_text_table          replace_text_table;
135   l_replace_start               number;
136   l_replace_count               number;
137   l_replace_end                 number;
138   l_replace_start_exec          number;
139   l_replace_end_exec            number;
140   l_replace_mode                number;
141   l_replace_rows                number;
142   l_dyn_end		        number;
143   l_variable_count              number;
144   l_disabled_tags               disabled_tag_table;
145   l_disabled_data               disabled_data_table;
146   l_dis_tag_num		        varchar2(3);
147   l_related_tags                related_tag_table;
148   l_dynamic_cursor              integer;
149   l_dynamic_call                varchar2(32000);
150   l_dynamic_rows                integer;
151   l_add_replace_var             boolean;
152 
153   function tag_disabled(p_tag in varchar2) return boolean is
154   l_dis_tag number;
155   begin
156     for tag_num in 1..l_disabled_tags.COUNT loop
157       if ((p_tag = 'DEFAULT') or
158           (l_disabled_tags(tag_num).tag_name = p_tag)) then
159         l_dis_tag := tag_num;
160         exit;
161       end if;
162     end loop;
163     if l_disabled_tags(l_dis_tag).disabled = 'Y' then
164       return TRUE;
165     else
166       return FALSE;
167     end if;
168   end;
169 
170 
171   procedure write(p_parent_name in varchar2 default null,
172                   p_parent_related_id in number default null) is
173   l_replace_count_w number;
174   l_write_data boolean;
175   l_children boolean;
176   l_current_tag varchar2(200);
177   l_current_related_id number;
178   l_dyn_mode number;
179   l_data_count number;
180   l_disable_data_count number;
181   begin
182 
183     -- write out tag multiple times as long as data exists
184     l_replace_count_w := 1;
185     l_write_data := TRUE;
186     l_dyn_mode := VARIABLE;
187 
188     while l_write_data loop
189       -- All tags should print once, unless disabled.
190       -- The first time through, find the data iteration numbers for the tag.
191       -- If any replace variable data is found, the tag should print
192       if l_replace_count_w = 1 then
193         -- Find how many times the tag should print
194         l_data_count := 0;
195         for replace_tab_num in l_replace_text_table.FIRST..l_replace_text_table.LAST loop
196 
197           if (substr(l_replace_text_table(replace_tab_num).replace_text, 1, 2) = '*!') then
198             for var in 1..vars.COUNT loop
199               if (((substr(l_replace_text_table(replace_tab_num).replace_text, 3, length(l_replace_text_table(replace_tab_num).replace_text) - 4) = vars(var).variable_name)
200               or (substr(l_replace_text_table(replace_tab_num).tag_owner,4)||'PDISABLE' = vars(var).variable_name))
201               and (vars(var).sequence > l_data_count)
202               and (nvl(vars(var).parent_name,' ') = nvl(p_parent_name, ' '))
203               and (nvl(vars(var).parent_related_id, 0) = nvl(p_parent_related_id, 0))) then
204                 l_data_count := vars(var).sequence;
205               end if;
206             end loop;
207           end if;
208         end loop;
209 
210         -- set up disabled data table to store the tag and sequence number
211         -- of any data-disabled tags.
212         l_disable_data_count := 1;
213         l_disabled_data.DELETE;
214         for tag in 1..l_disabled_tags.COUNT loop
215           for var in 1..vars.COUNT loop
216             if ((substr(l_disabled_tags(tag).tag_name,4)||'PDISABLE' = vars(var).variable_name)
217             and (vars(var).value = 'TRUE')) then
218               l_disabled_data(l_disable_data_count).tag_name := substr(l_disabled_tags(tag).tag_name,4);
219               l_disabled_data(l_disable_data_count).disabled_sequence := vars(var).sequence;
220               l_disable_data_count := l_disable_data_count + 1;
221             end if;
222           end loop;
223         end loop;
224 
225         l_write_data := TRUE;
226       else
227         if l_replace_count_w <= l_data_count then
228           l_write_data := TRUE;
229         else
230           l_write_data := FALSE;
231         end if;
232       end if;
233 
234 
235       -- write entire tag
236       if l_write_data then
237 
238         -- record if any tags are disabled for this iteration of data
239 
240         -- first set all tags to enabled except for those that do not
241         -- have the current parent
242         for tag in 1..l_disabled_tags.COUNT loop
243           l_disabled_tags(tag).disabled := 'N';
244         end loop;
245 
246         -- disable all tags that do not have the current parent
247         for rel_tag in 1..l_related_tags.COUNT loop
248           if ((l_related_tags(rel_tag).tag_name <> 'DEFAULT')
249           and (nvl(l_related_tags(rel_tag).parent,' ') <> nvl(p_parent_name,' '))) then
250             for dis_tag in 1..l_disabled_tags.COUNT loop
251               if (substr(l_disabled_tags(dis_tag).tag_name,4) = l_related_tags(rel_tag).tag_name) then
252                 l_disabled_tags(dis_tag).disabled := 'Y';
253                 exit;
254               end if;
255             end loop;
256           end if;
257           -- set current tag to the last tag with the current parent
258           -- This will be use for related tag recursion later
259           if (nvl(l_related_tags(rel_tag).parent,' ') = nvl(p_parent_name,' ')) then
260             l_current_tag := l_related_tags(rel_tag).tag_name;
261           end if;
262         end loop;
263 
264         -- check if tag is disabled through tag variables
265         for tag in 1..l_disabled_tags.COUNT loop
266          if l_disabled_tags(tag).disabled = 'N' then
267           if l_disabled_tags(tag).disable_variable is not null then
268             if l_disabled_tags(tag).disable_condition = 'EQUAL' then
269               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
270                 if l_replace_count_w = l_disabled_tags(tag).disable_value then
271                   l_disabled_tags(tag).disabled := 'Y';
272                 end if;
273               else
274                 for var in 1..vars.COUNT loop
275                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
276                   and (vars(var).value = l_disabled_tags(tag).disable_value)
277                   and (vars(var).sequence = l_replace_count_w)) then
278                     l_disabled_tags(tag).disabled := 'Y';
279                     exit;
280                   end if;
281                 end loop;
282               end if;
283             elsif l_disabled_tags(tag).disable_condition = 'NOT EQUAL' then
284               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
285                 if l_replace_count_w <> l_disabled_tags(tag).disable_value then
286                   l_disabled_tags(tag).disabled := 'Y';
287                 end if;
288               else
289                 for var in 1..vars.COUNT loop
290                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
291                   and (vars(var).value <> l_disabled_tags(tag).disable_value)
292                   and (vars(var).sequence = l_replace_count_w)) then
293                     l_disabled_tags(tag).disabled := 'Y';
294                     exit;
295                   end if;
296                 end loop;
297               end if;
298             elsif l_disabled_tags(tag).disable_condition = 'LESS THAN' then
299               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
300                 if l_replace_count_w < l_disabled_tags(tag).disable_value then
301                   l_disabled_tags(tag).disabled := 'Y';
302                 end if;
303               else
304                 for var in 1..vars.COUNT loop
305                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
306                   and (vars(var).value < l_disabled_tags(tag).disable_value)
307                   and (vars(var).sequence = l_replace_count_w)) then
308                     l_disabled_tags(tag).disabled := 'Y';
309                     exit;
310                   end if;
311                 end loop;
312               end if;
313             elsif l_disabled_tags(tag).disable_condition = 'MORE THAN' then
314               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
315                 if l_replace_count_w > l_disabled_tags(tag).disable_value then
316                   l_disabled_tags(tag).disabled := 'Y';
317                 end if;
318               else
319                 for var in 1..vars.COUNT loop
320                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
321                   and (vars(var).value > l_disabled_tags(tag).disable_value)
322                   and (vars(var).sequence = l_replace_count_w)) then
323                     l_disabled_tags(tag).disabled := 'Y';
324                     exit;
325                   end if;
326                 end loop;
327               end if;
328             elsif l_disabled_tags(tag).disable_condition = 'DIVISIBLE BY' then
329               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
330                 if (mod(l_replace_count_w, l_disabled_tags(tag).disable_value) <> 0) then
331                   l_disabled_tags(tag).disabled := 'Y';
332                 end if;
333               else
334                 for var in 1..vars.COUNT loop
335                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
336                   and (mod(vars(var).value, l_disabled_tags(tag).disable_value) = 0)
337                   and (vars(var).sequence = l_replace_count_w)) then
338                     l_disabled_tags(tag).disabled := 'Y';
339                     exit;
340                   end if;
341                 end loop;
342               end if;
346                   l_disabled_tags(tag).disabled := 'Y';
343             elsif l_disabled_tags(tag).disable_condition = 'NOT DIVISIBLE BY' then
344               if l_disabled_tags(tag).disable_variable = 'PDATACOUNT' then
345                 if (mod(l_replace_count_w, l_disabled_tags(tag).disable_value) = 0) then
347                 end if;
348               else
349                 for var in 1..vars.COUNT loop
350                   if ((l_disabled_tags(tag).disable_variable = vars(var).variable_name)
351                   and (mod(vars(var).value, l_disabled_tags(tag).disable_value) <> 0)
352                   and (vars(var).sequence = l_replace_count_w)) then
353                     l_disabled_tags(tag).disabled := 'Y';
354                     exit;
355                   end if;
356                 end loop;
357               end if;
358             end if;
359            end if;
360           end if;
361 
362           -- if tag is not disabled through tag variable data then
363           -- check if tag is disabled through parameter data
364           if l_disabled_tags(tag).disabled = 'N' then
365             for disabled_data in 1..l_disabled_data.COUNT loop
366               if ((substr(l_disabled_tags(tag).tag_name,4) = l_disabled_data(disabled_data).tag_name)
367               and ((l_disabled_data(disabled_data).disabled_sequence = l_replace_count_w)
368                 or (l_disabled_data(disabled_data).disabled_sequence = 0))) then
369                 l_disabled_tags(tag).disabled := 'Y';
370                 exit;
371               end if;
372             end loop;
373           end if;
374 
375         end loop;  -- end disable check
376 
377 
378 
379         -- loop through all pieces of the tag and print them
380         for replace_tab_num in l_replace_text_table.FIRST..l_replace_text_table.LAST loop
381           -- do not print anything if first tag is disabled.  This provides
382           -- for disabling a whole group.
383           if l_disabled_tags(1).disabled = 'Y' then
384             exit;
385           end if;
386 
387           if not tag_disabled(l_replace_text_table(replace_tab_num).tag_owner) then
388             if substr(l_replace_text_table(replace_tab_num).replace_text, 1, 2) = '#!' then
389               -- build the package call to execute
390               l_dynamic_call := substr(l_replace_text_table(replace_tab_num).replace_text,3);
391               l_dyn_end := instr(l_replace_text_table(replace_tab_num).replace_text, '!#');
392 
393               if l_dyn_end <> 0 then
394                 -- execute dynamic plsql call
395                 l_dynamic_call := substr(l_dynamic_call,1,length(l_dynamic_call)-2);
396                 if length(l_dynamic_call) > 0 then
397                   begin
398                     l_dynamic_cursor  := dbms_sql.open_cursor;
399                     dbms_sql.parse(l_dynamic_cursor, 'begin '||l_dynamic_call||'; end;', DBMS_SQL.native);
400                     l_dynamic_rows := dbms_sql.execute(l_dynamic_cursor);
401                     dbms_sql.close_cursor(l_dynamic_cursor);
402                     exception
403                       when others then
404                         htp.p('SQL being executed was: '||l_dynamic_call||'<BR>');
405                         htp.p(SQLERRM);
406                   end;
407                 end if;
408               else
409                 l_dyn_mode := EXECUTABLE;
410               end if;
411 
412             elsif substr(l_replace_text_table(replace_tab_num).replace_text,1,2) = '*!' then
413               for var in 1..vars.COUNT loop
414                 if ((substr(l_replace_text_table(replace_tab_num).replace_text, 3, length(l_replace_text_table(replace_tab_num).replace_text) - 4) = vars(var).variable_name)
415                 and  (vars(var).sequence = l_replace_count_w)
416                 and (nvl(vars(var).parent_name,' ') = nvl(p_parent_name, ' '))
417                 and (nvl(vars(var).parent_related_id, 0) = nvl(p_parent_related_id, 0))) then
418                   if l_dyn_mode = VARIABLE then
419                     if vars(var).value is not null then
420                       if (replace_tab_num = l_replace_text_table.LAST) then
421                         htp.p(vars(var).value);
422                       else
423                         htp.prn(vars(var).value);
424                       end if;
425                     end if;
426                   else
427                     l_dynamic_call := l_dynamic_call||vars(var).value;
428                   end if;
429                   -- set current related id for use in recursion later
430                   l_current_related_id := vars(var).related_id;
431                   exit;
432                 end if;
433               end loop;
434 
435             else
436               if l_dyn_mode = VARIABLE then
437                 if l_replace_text_table(replace_tab_num).replace_text is not null then
438                   if (replace_tab_num = l_replace_text_table.LAST) then
439                     htp.p(l_replace_text_table(replace_tab_num).replace_text);
440                   else
441                     htp.prn(l_replace_text_table(replace_tab_num).replace_text);
442                   end if;
443                 end if;
444               else
445                 l_dyn_end := instr(l_replace_text_table(replace_tab_num).replace_text, '!#');
446                 if l_dyn_end <> 0 then
447                   -- execute dynamic plsql call
448                   l_dynamic_call := l_dynamic_call||l_replace_text_table(replace_tab_num).replace_text;
449                   l_dynamic_call := substr(l_dynamic_call,1,length(l_dynamic_call)-2);
450                   if length(l_dynamic_call) > 0 then
451                     begin
452                       l_dynamic_cursor  := dbms_sql.open_cursor;
453                       dbms_sql.parse(l_dynamic_cursor, 'begin '||l_dynamic_call||'; end;', DBMS_SQL.native);
454                       l_dynamic_rows := dbms_sql.execute(l_dynamic_cursor);
458                         htp.p('SQL being executed was: '||l_dynamic_call||'<BR>');
455                       dbms_sql.close_cursor(l_dynamic_cursor);
456                       exception
457                         when others then
459                         htp.p(SQLERRM);
460                     end;
461                     l_dyn_mode := VARIABLE;
462                   end if;
463                 else
464                   l_dynamic_call := l_dynamic_call||l_replace_text_table(replace_tab_num).replace_text;
465                 end if;
466               end if;
467             end if;
468           end if;
469         end loop;
470 
471         -- write loop break text if current row is divisible by break #
472         if mod(l_replace_count_w, l_first_group_tag_loop_table(3)) = 0 then
473           htp.p(l_first_group_tag_loop_table(4));
474         end if;
475 
476 
477         -- check for child related tags and recurse if necessary
478         for rel_tag in 1..l_related_tags.COUNT loop
479           if l_related_tags(rel_tag).parent  = l_current_tag then
480             write(l_current_tag, l_current_related_id);
481             exit;
482           end if;
483         end loop;
484 
485       end if;
486 
487       l_replace_count_w := l_replace_count_w + 1;
488 
489     end loop;
490   end;  -- write procedure
491 
492 begin
493 --bug fix 924513
494 l_server := fnd_profile.value('WEB_AUTHENTICATION_SERVER');
495 
496 if l_server is null then
497   -- read html template
498   l_html_pieces := utl_http.request_pieces(FND_WEB_CONFIG.PROTOCOL ||'//'||l_server||':'||l_port||'/OA_HTML/US/'||p_template_name);
499 else l_html_pieces := utl_http.request_pieces(l_server||'/OA_HTML/US/'||p_template_name);
500 end if;
501 -- end bug fix 924513
502 
503   -- parse each html piece
504   l_html_piece := '';
505   for piece in l_html_pieces.FIRST..l_html_pieces.LAST loop
506 
507     -- set l_html_piece to current piece of html
508     l_html_piece := l_html_piece||l_html_pieces(piece);
509 
510     -- replace all special tags and print the template html
511     while length(l_html_piece) > 0  loop
512         l_tag_beginning := instr(l_html_piece,'<~!');
513         if l_tag_beginning = 0 then
514           -- no special tags left, print rest of html and exit loop
515           htp.prn(l_html_piece);
516           l_html_piece := '';
517           exit;
518         else
519           -- print out and discard html up to the special tag
520           htp.prn(substr(l_html_piece, 1, l_tag_beginning - 1));
521           l_html_piece := substr(l_html_piece, l_tag_beginning);
522         end if;
523 
524         -- count number of tags to check for grouped tags
525         l_tag_count := 1;
526         l_tag_current_position :=2;
527         l_tag_open_count := 1;
528         while l_tag_open_count > 0 loop
529           l_tag_temp_end := instr(l_html_piece, '!~>',l_tag_current_position + 1);
530           l_tag_temp_start := instr(l_html_piece, '<~!',l_tag_current_position + 1);
531           if l_tag_temp_end = 0 then
532             l_tag_end := 0;
533             exit;
534           elsif ((l_tag_temp_start < l_tag_temp_end) and
535                  (l_tag_temp_start <> 0)) then
536             l_tag_open_count := l_tag_open_count + 1;
537             l_tag_count := l_tag_count + 1;
538             l_tag_current_position := l_tag_temp_start;
539           else
540             l_tag_open_count := l_tag_open_count - 1;
541             l_tag_end := l_tag_temp_end;
542             l_tag_current_position := l_tag_temp_end;
543           end if;
544         end loop;
545 
546         if l_tag_end = 0 then
547             -- tag has no end, raise syntax error if this is the last chunk
548             -- or exit the loop for this chunk and the current chunk will
549             -- get concatenated with the next chunk and re-evaluated
550             if piece =  l_html_pieces.LAST then
551               raise TAG_NO_END;
552             end if;
553             exit;
554         end if;
555 
556 
557         -- get tag
558         l_tag := substr(l_html_piece, 1, l_tag_end + 2);
559 
560 
561         -- discard current tag from html template chunk
562         l_html_piece := substr(l_html_piece, l_tag_end + 3);
563 
564 
565         -- process tag, or group of tags
566         l_tag_current_position := 1;
567         l_replace_text_table.DELETE;  -- clear replace text table
568         l_disabled_tags.DELETE;
569         l_related_tags.DELETE;
570         l_replace_count := 1;
571         for tag in 1..l_tag_count loop
572           -- get start and end of current tag (to deal with parts of tag group)
573           if l_tag_count = 1 then
574             l_tag_temp_start := 1;
575             l_tag_temp_end := instr(l_tag, '!~>');
576             l_sub_tag := substr(l_tag, l_tag_temp_start, l_tag_temp_end + 3 - l_tag_temp_start);
577             l_tag_current_position := l_tag_temp_end + 1;
578           elsif ((l_tag_count > 1) and (tag = 1)) then
579             l_tag_temp_start := 1;
580             l_tag_temp_end := instr(l_tag, '<~!', 2);
581             l_sub_tag := substr(l_tag, l_tag_temp_start, l_tag_temp_end - l_tag_temp_start)||'!~>';
582             l_tag_current_position := l_tag_temp_end - 1;
583           else
584             l_tag_temp_start := instr(l_tag, '<~!',l_tag_current_position);
585             l_tag_temp_end := instr(l_tag, '!~>',l_tag_current_position);
586             l_sub_tag := substr(l_tag, l_tag_temp_start, l_tag_temp_end + 3 - l_tag_temp_start);
587             l_tag_current_position := l_tag_temp_end + 1;
588           end if;
589 
590           -- get tag name
591           l_tag_var_end := 4;
595             else
592           while (l_tag_var_end < length(l_sub_tag)) loop
593             if (substr(l_sub_tag, l_tag_var_end, 1) in (' ',',','!')) then
594               exit;
596               l_tag_var_end := l_tag_var_end + 1;
597             end if;
598           end loop;
599           l_tag_name := substr(l_sub_tag, 4, l_tag_var_end  - 4);
600 
601           -- get multiple tag loop formatting data if present
602           for i in 1..4 loop
603             l_tag_loop_table(i) := '';
604           end loop;
605           l_tag_var_num := 1;
606           if substr(l_sub_tag, l_tag_var_end, 1) = ',' then
607             while (l_tag_var_end < length(l_sub_tag)) loop
608               l_tag_var_start := instr(l_sub_tag, ',', l_tag_var_end);
609               if l_tag_var_start = 0 then
610                 -- no loop data variable in the tag, exit;
611                 exit;
612               else
613                 -- read variable into the tag_var_table
614                 l_tag_var_end := instr(l_sub_tag, ',', l_tag_var_start + 1);
615                 l_tag_loop_table(l_tag_var_num) := substr(l_sub_tag, l_tag_var_start + 1, l_tag_var_end - l_tag_var_start - 1);
616                 l_tag_var_num := l_tag_var_num + 1;
617               end if;
618             end loop;
619           end if;
620           if (tag = 1) then
621             l_first_group_tag_loop_table := l_tag_loop_table;
622 	  end if;
623 
624           -- get tag variables if present
625           l_tag_var_num := 1;
626           l_tag_var_table.DELETE;
627           l_tag_var_table(1).tag_var_value := 'DEFAULT';
628           while (l_tag_var_end < length(l_sub_tag)) loop
629             l_tag_var_start := instr(l_sub_tag, '"', l_tag_var_end + 1);
630             if l_tag_var_start = 0 then
631               -- no extra variable in the tag, exit;
632               exit;
633             else
634               -- read variable into the tag_var_table
635               l_tag_var_end := instr(l_sub_tag, '"', l_tag_var_start + 1);
636               if l_tag_var_end = 0 then
637                 raise TAG_SYNTAX_ERROR;
638               end if;
639               l_tag_var_name_start := l_tag_var_start;
640               while (l_tag_var_name_start <> 0) loop
641                 if (substr(l_sub_tag, l_tag_var_name_start, 1) = ' ') then
642                   exit;
643                 else
644                   l_tag_var_name_start := l_tag_var_name_start - 1;
645                 end if;
646               end loop;
647               l_tag_var_table(l_tag_var_num).tag_var_name := substr(l_sub_tag, l_tag_var_name_start + 1, l_tag_var_start - l_tag_var_name_start - 2);
648               l_tag_var_table(l_tag_var_num).tag_var_value := substr(l_sub_tag, l_tag_var_start + 1, l_tag_var_end - l_tag_var_start - 1);
649 
650               -- add variable to disabled table if needed
651               if l_tag_var_table(l_tag_var_num).tag_var_name = 'DISABLEVAR' then
652                 l_disabled_tags(tag).disable_variable := l_tag_var_table(l_tag_var_num).tag_var_value;
653               elsif l_tag_var_table(l_tag_var_num).tag_var_name = 'DISABLECOND' then
654                 l_disabled_tags(tag).disable_condition := l_tag_var_table(l_tag_var_num).tag_var_value;
655               elsif l_tag_var_table(l_tag_var_num).tag_var_name = 'DISABLEVALUE' then
656                 l_disabled_tags(tag).disable_value := l_tag_var_table(l_tag_var_num).tag_var_value;
657               end if;
658 
659               -- add variable to related table if variable name is parent
660               if l_tag_var_table(l_tag_var_num).tag_var_name = 'PARENT' then
661                 l_related_tags(tag).parent := l_tag_var_table(l_tag_var_num).tag_var_value;
662               end if;
663 
664               l_tag_var_num := l_tag_var_num + 1;
665             end if;
666           end loop;
667 
668 
669           -- add current tag name to disabled table for reference later
670           l_dis_tag_num := '001';
671           for dis_tag in 1..l_disabled_tags.COUNT loop
672             if substr(l_disabled_tags(dis_tag).tag_name, 4) = l_tag_var_table(1).tag_var_value then
673               if l_dis_tag_num <= substr(l_disabled_tags(dis_tag).tag_name,1,3) then
674                 l_dis_tag_num := substr(to_char(to_number(substr(l_disabled_tags(dis_tag).tag_name,1,3)) + 1, '000'),2);
675               end if;
676             end if;
677           end loop;
678           l_disabled_tags(tag).tag_name := l_dis_tag_num||l_tag_var_table(1).tag_var_value;
679 
680 
681           -- add current tag to related table for reference later
682           l_related_tags(tag).tag_name := l_tag_var_table(1).tag_var_value;
683 
684 
685           -- get tag replacement text
686           open tag_text(l_tag_name);
687           l_replace_rows := 0;
688           loop
689             fetch tag_text into l_replacement_text;
690             exit when tag_text%NOTFOUND or tag_text%NOTFOUND is null;
691             l_replace_rows := l_replace_rows + 1;
692           end loop;
693           close tag_text;
694           if l_replace_rows < 1 then
695             raise TAG_DOES_NOT_EXIST;
696           elsif l_replace_rows > 1 then
697             raise TAG_NOT_UNIQUE;
698           end if;
699 
700           -- replace tag vars
701           for tag_var in 1..l_tag_var_table.COUNT loop
702             l_replacement_text := replace(l_replacement_text, '*!['||l_tag_var_table(tag_var).tag_var_name||']!*', l_tag_var_table(tag_var).tag_var_value);
703             l_replacement_text := replace(l_replacement_text, '['||l_tag_var_table(tag_var).tag_var_name||']', l_tag_var_table(tag_var).tag_var_value);
704           end loop;
705 
706           -- replace un-matched tag variables in replacement text
707           -- Tag variables that are not also possibly parameters (wrapped in
708           -- '*!' and '!*') should be discarded.  Otherwise, replace tag var
712           l_replacement_text := replace(l_replacement_text, ']!*', '!*');
709           -- text with tag name variable concatenated with tag var.
710           l_replacement_text := replace(l_replacement_text, '*![', '*!'||l_tag_var_table(1).tag_var_value);
711           l_replacement_text := replace(l_replacement_text, '#![', '#!'||l_tag_var_table(1).tag_var_value);
713           l_replacement_text := replace(l_replacement_text, ']!#', '!#');
714           l_replace_start := 1;
715           while l_replace_start <> 0 loop
716             l_replace_start := instr(l_replacement_text,'[',l_replace_start);
717             if l_replace_start <> 0 then
718               l_replace_end := instr(l_replacement_text,']',l_replace_start);
719               if l_replace_end <> 0 then
720                 l_replacement_text := substr(l_replacement_text,1,l_replace_start-1)||substr(l_replacement_text,l_replace_end+1,length(l_replacement_text)-l_replace_end);
721               else
722                 raise TAG_VAR_NO_END;
723               end if;
724             end if;
725           end loop;
726 
727 
728           -- load pre-tag text
729           l_replace_text_table(l_replace_count).replace_text := l_tag_loop_table(1);
730      --     l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
731           l_replace_text_table(l_replace_count).tag_owner := 'DEFAULT';
732           l_replace_count := l_replace_count + 1;
733 
734           -- load tag static text and tag variables into seperate table recs
735           l_variable_count := 0;
736           l_replace_mode := VARIABLE;
737           while length(l_replacement_text) > 0  loop
738 
739             l_replace_start_exec := instr(l_replacement_text,'#!');
740             l_replace_start := instr(l_replacement_text,'*!');
741             if ((l_replace_start_exec <> 0) and (l_replace_start_exec <= l_replace_start)) then
742               l_replace_start := l_replace_start_exec;
743               l_replace_mode := EXECUTABLE;
744             end if;
745 
746             if l_replace_start = 0 then
747               -- no replacement vars, add to replace table and exit
748               l_replace_text_table(l_replace_count).replace_text := l_replacement_text;
749               l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
750               l_replace_count := l_replace_count + 1;
751               exit;
752             elsif l_replace_start > 1 then
753               -- add text up to variable to the replace text table
754               l_replace_text_table(l_replace_count).replace_text := substr(l_replacement_text, 1, l_replace_start - 1);
755               l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
756               l_replacement_text := substr(l_replacement_text, l_replace_start);
757               l_replace_count := l_replace_count + 1;
758             end if;
759 
760             l_replace_end_exec := instr(l_replacement_text,'!#');
761             if ((l_replace_mode = EXECUTABLE) and (l_replace_end_exec = 0)) then
762               raise TAG_SYNTAX_ERROR;
763             end if;
764 
765             -- get end of current piece of replacement text
766             if l_replace_start_exec <> 0 then
767               l_replace_end := instr(l_replacement_text, '*!', 2);
768             else
769               l_replace_end := instr(l_replacement_text, '!*') + 2;
770             end if;
771             if ((l_replace_end = 0) or ((l_replace_mode = EXECUTABLE) and (l_replace_end_exec < l_replace_end))) then
772               l_replace_end := l_replace_end_exec + 3;
773               l_replace_mode := VARIABLE;
774             end if;
775 
776             if l_replace_end = 0 then
777               -- replace var has no end, for now add to table and exit
778               -- there may be more in the next html chunk...
779               l_replace_text_table(l_replace_count).replace_text := substr(l_replacement_text, 1, l_replace_start - 1);
780               l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
781               l_replace_count := l_replace_count + 1;
782               exit;
783             end if;
784 
785             -- add replace var to table if any replacement data is present
786             -- for that variable and discard
787             if substr(l_replacement_text, 1,1) = '*' then
788               l_add_replace_var := FALSE;
789               for var in 1..vars.COUNT loop
790                 if (substr(l_replacement_text, 3, l_replace_end - 5) = vars(var).variable_name) then
791                   l_add_replace_var := TRUE;
792                   exit;
793                 end if;
794               end loop;
795               if l_add_replace_var then
796                 l_replace_text_table(l_replace_count).replace_text := substr(l_replacement_text, 1, l_replace_end - 1);
797                 l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
798                 l_replace_count := l_replace_count + 1;
799                 l_variable_count := l_variable_count + 1;
800               end if;
801             else
802               l_replace_text_table(l_replace_count).replace_text := substr(l_replacement_text, 1, l_replace_end - 1);
803               l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
804               l_replace_count := l_replace_count + 1;
805             end if;
806             l_replacement_text := substr(l_replacement_text, l_replace_end);
807 
808           end loop;
809 
810 
811           -- load post-tag text
812           if not ((l_tag_count > 1) and (tag = 1)) then
813             l_replace_text_table(l_replace_count).replace_text := l_tag_loop_table(2);
814       --      l_replace_text_table(l_replace_count).tag_owner := l_disabled_tags(tag).tag_name;
815             l_replace_text_table(l_replace_count).tag_owner := 'DEFAULT';
816             l_replace_count := l_replace_count + 1;
817           end if;
818 
819         end loop;
820 
821         -- load post-tag text for grouping tag if needed
822         if l_tag_count > 1 then
823           l_replace_text_table(l_replace_count).replace_text := l_first_group_tag_loop_table(2);
824      --     l_replace_text_table(l_replace_count).tag_owner :=l_first_group_tag_loop_table(2);
825           l_replace_text_table(l_replace_count).tag_owner := 'DEFAULT';
826           l_replace_count := l_replace_count + 1;
827         end if;
828 
829         -- write out tag multiple times as long as data exists
830         write;
831 
832     end loop;
833 
834   end loop;
835 
836   exception
837     when TAG_DOES_NOT_EXIST then
838       htp.p(l_tag_name||': Special tag does not exist.');
839     when TAG_NOT_UNIQUE then
840       htp.p(l_tag_name||': Special tag is not unique.');
841     when TAG_VAR_NO_END then
842       htp.p(l_tag_name||': Special tag has a tag variable format error.  Each tag variable should start with [ and end with ].');
843     when TAG_NO_END then
844       htp.p('Special tag has no end.');
845     when TAG_SYNTAX_ERROR then
846       htp.p(l_tag_name||': Special tag has syntax errors.');
847     when others then
848       htp.p(SQLERRM);
849 
850 end parse;
851 
852 
853 
854 
855 procedure get_HTML_file(p_file_name in varchar2) is
856 
857 l_html_pieces  utl_http.html_pieces;
858 l_server varchar2(1000) :=  owa_util.get_cgi_env('SERVER_NAME');
859 l_port varchar2(20) := owa_util.get_cgi_env('SERVER_PORT');
860 
861 begin
862   if (p_file_name is not null) then
863 -- fix bug 924513
864 l_server := fnd_profile.value('WEB_AUTHENTICATION_SERVER');
865 if l_server is null then
866     -- read html file
867     l_html_pieces := utl_http.request_pieces(FND_WEB_CONFIG.PROTOCOL || '//'||l_server||':'||l_port||p_file_name);
868 else
869    l_html_pieces := utl_http.request_pieces(l_server||p_file_name);
870 end if;
871 -- end fix bug 924513
872 
873     -- write out html file
874     for piece in l_html_pieces.FIRST..l_html_pieces.LAST loop
875       htp.p(l_html_pieces(piece));
876     end loop;
877   end if;
878 end get_HTML_file;
879 
880 
881 
882 procedure get_fnd_message(p_app_code in varchar2,
883                           p_message_name in varchar2) is
884 
885 begin
886   FND_MESSAGE.SET_NAME(p_app_code, p_message_name);
887   htp.p(FND_MESSAGE.Get);
888 end;
889 
890 
891 
892 
893 procedure print_variables is
894 
895 begin
896 
897 htp.tableOpen('BORDER=1');
898   htp.tableRowOpen;
899     htp.tableData('<B>row number</B>');
900     htp.tableData('<B>variable_name</B>');
901     htp.tableData('<B>sequence</B>');
902     htp.tableData('<B>value</B>');
903     htp.tableData('<B>related id</B>');
904     htp.tableData('<B>parent name</B>');
905     htp.tableData('<B>parent related id</B>');
906   htp.tableRowClose;
907 
908   for i in 1..vars.COUNT loop
909     htp.tableRowOpen;
910       htp.tableData(i);
911       htp.tableData(vars(i).variable_name);
912       htp.tableData(vars(i).sequence);
913       htp.tableData(vars(i).value);
914       htp.tableData(vars(i).related_id);
915       htp.tableData(vars(i).parent_name);
916       htp.tableData(vars(i).parent_related_id);
917     htp.tableRowClose;
918   end loop;
919 htp.tableClose;
920 
921 end;
922 
923 
924 procedure tag_list is
925 
926 cursor tags is
927 select tag_name, tag_description
928 from icx_template_tags
929 order by tag_name;
930 
931 begin
932 
933 null;
934 
935 end tag_list;
936 
937 
938 
939 
940 procedure tag_details(tag_name in varchar2) is
941 
942 begin
943 
944 null;
945 
946 
947 end tag_details;
948 
949 
950 
951 
952 
953 end icx_template_parser;
954