DBA Data[Home] [Help]

PACKAGE BODY: APPS.XLA_CMP_STRING_PKG

Source


1 PACKAGE BODY xla_cmp_string_pkg AS
2 /* $Header: xlacpstr.pkb 120.15.12010000.2 2010/05/11 10:58:57 karamakr ship $   */
3 /*===========================================================================+
4 |             Copyright (c) 2001-2002 Oracle Corporation                     |
5 |                       Redwood Shores, CA, USA                              |
6 |                         All rights reserved.                               |
7 +============================================================================+
8 | PACKAGE NAME                                                               |
9 |     xla_cmp_string_pkg                                                     |
10 |                                                                            |
11 | DESCRIPTION                                                                |
12 |     This is a XLA private package, which contains all the logic required   |
13 |     to handle the text gcreated by the compiler                            |
14 |                                                                            |
15 | HISTORY                                                                    |
16 |     25-JUL-2002 K.Boussema    Created                                      |
17 |     19-APR-2003 K.Boussema    Included Error messages                      |
18 |     23-FEB-2004 K.Boussema    Made changes for the FND_LOG.                |
19 |     22-MAR-2004 K.Boussema    Added a parameter p_module to the TRACE calls|
20 |                               and the procedure.                           |
21 |     11-MAY-2004 K.Boussema    Removed the call to XLA trace routine from   |
22 |                               trace() procedure                            |
23 |     21-Sep-2004 S.Singhania   Replaced long VARCHAR2 variables with CLOB.  |
24 |                               Added routine replace_token to handle REPLACE|
25 |                                 in CLOB variables.                         |
26 |     01-Oct-2004 S.Singhania   Bug 3918467: Modfied the logic in the routine|
27 |                                 CreateString to improve the performance.   |
28 |     21-Jun-2005 S.Singhania   Bug 4444678. Modified replace_token routine. |
29 |                                 The code uses iterative calls to iteself   |
30 |                                 instead of unconditional looping.          |
31 |     21-Jul-2006 A.Wan         Bug 5403943: replace SUBSTR with SUBSTRB and |
32 |                                 INSTR with INSTRB, except for SUBSTR of    |
33 |                                 CLOB.                                      |
34 +===========================================================================*/
35 --+==========================================================================+
36 --|                                                                          |
37 --| OVERVIEW of private procedures and functions                             |
38 --|                                                                          |
39 --+==========================================================================+
40 --
41 g_Max_line            CONSTANT NUMBER        := 255;
42 g_chr_quote           CONSTANT VARCHAR2(9)   :='''';
43 g_chr_space           CONSTANT VARCHAR2(9)   :=' ';
44 g_chr_newline         CONSTANT VARCHAR2(10)  := xla_environment_pkg.g_chr_newline;
45 --
46 --=============================================================================
47 --               *********** Local Trace Routine **********
48 --=============================================================================
49 
50 C_LEVEL_STATEMENT     CONSTANT NUMBER := FND_LOG.LEVEL_STATEMENT;
51 C_LEVEL_PROCEDURE     CONSTANT NUMBER := FND_LOG.LEVEL_PROCEDURE;
52 C_LEVEL_EVENT         CONSTANT NUMBER := FND_LOG.LEVEL_EVENT;
53 C_LEVEL_EXCEPTION     CONSTANT NUMBER := FND_LOG.LEVEL_EXCEPTION;
54 C_LEVEL_ERROR         CONSTANT NUMBER := FND_LOG.LEVEL_ERROR;
55 C_LEVEL_UNEXPECTED    CONSTANT NUMBER := FND_LOG.LEVEL_UNEXPECTED;
56 
57 C_LEVEL_LOG_DISABLED  CONSTANT NUMBER := 99;
58 C_DEFAULT_MODULE      CONSTANT VARCHAR2(240) := 'xla.plsql.xla_cmp_string_pkg';
59 
60 g_log_level           NUMBER;
61 g_log_enabled         BOOLEAN;
62 
63 PROCEDURE trace
64            (p_msg                        IN VARCHAR2
65            ,p_level                      IN NUMBER
66            ,p_module                     IN VARCHAR2 DEFAULT C_DEFAULT_MODULE) IS
67 BEGIN
68 ----------------------------------------------------------------------------
69 -- Following is for FND log.
70 ----------------------------------------------------------------------------
71 IF (p_msg IS NULL AND p_level >= g_log_level) THEN
72           fnd_log.message(p_level, p_module);
73 ELSIF p_level >= g_log_level THEN
74           fnd_log.string(p_level, p_module, p_msg);
75 END IF;
76 
77 EXCEPTION
78        WHEN xla_exceptions_pkg.application_exception THEN
79           RAISE;
80        WHEN OTHERS THEN
81           xla_exceptions_pkg.raise_message
82              (p_location   => 'xla_cmp_string_pkg.trace');
83 END trace;
84 
85 --+==========================================================================+
86 --|                                                                          |
87 --| PUBLIC Function                                                          |
88 --|                                                                          |
89 --+==========================================================================+
90 --
91 FUNCTION  ConcatTwoStrings (
92                    p_array_string_1           IN DBMS_SQL.VARCHAR2S
93                   ,p_array_string_2           IN DBMS_SQL.VARCHAR2S
94 )
95 RETURN DBMS_SQL.VARCHAR2S
96 IS
97 l_array_string       DBMS_SQL.VARCHAR2S;
98 l_Index              BINARY_INTEGER;
99 l_log_module         VARCHAR2(240);
100 BEGIN
101 --
102 IF g_log_enabled THEN
103       l_log_module := C_DEFAULT_MODULE||'.ConcatTwoStrings';
104 END IF;
105 --
106 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
107 
108       trace
109          (p_msg      => 'BEGIN of ConcatTwoStrings'
110          ,p_level    => C_LEVEL_PROCEDURE
111          ,p_module   => l_log_module);
112 
113 END IF;
114 --
115 IF (C_LEVEL_STATEMENT >= g_log_level) THEN
116 
117       trace
118          (p_msg      => 'LENGTH string 1 = '||p_array_string_1.COUNT
119          ,p_level    => C_LEVEL_STATEMENT
120          ,p_module   => l_log_module);
121 
122       trace
123          (p_msg      => 'LENGTH string 2 = '||p_array_string_2.COUNT
124          ,p_level    => C_LEVEL_STATEMENT
125          ,p_module   => l_log_module);
126 
127 END IF;
128 --
129 l_array_string := p_array_string_1;
130 --
131 IF p_array_string_2.COUNT > 0 THEN
132 --
133   l_Index        := NVL(l_array_string.LAST,0);
134   --
135   FOR Idx IN p_array_string_2.FIRST .. p_array_string_2.LAST LOOP
136   --
137     IF p_array_string_2.EXISTS(Idx) THEN
138     --
139       l_Index                 := l_Index + 1;
140       l_array_string(l_Index) := p_array_string_2(Idx);
141     --
142     END IF;
143   --
144   END LOOP;
145   --
146 END IF;
147 --
148 IF (C_LEVEL_STATEMENT >= g_log_level) THEN
149 
150       trace
151          (p_msg      => 'LENGTH result = '||l_array_string.COUNT
152          ,p_level    => C_LEVEL_STATEMENT
153          ,p_module   => l_log_module);
154 
155 END IF;
156 --
157 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
158 
159       trace
160          (p_msg      => 'END of ConcatTwoStrings'
161          ,p_level    => C_LEVEL_PROCEDURE
162          ,p_module   => l_log_module);
163 
164 END IF;
165 --
166 RETURN l_array_string;
167 --
168 EXCEPTION
169    WHEN xla_exceptions_pkg.application_exception   THEN
170         RETURN g_null_varchar2s;
171    WHEN OTHERS    THEN
172       xla_exceptions_pkg.raise_message
173          (p_location => 'xla_cmp_string_pkg.ConcatTwoStrings');
174 END ConcatTwoStrings;
175 --
176 --
177 --+==========================================================================+
178 --| PRIVATE procedures and functions                                         |
179 --|    CreateString                                                          |
180 --|    transforms CLOB lines (length > 255) into a list of lines not         |
181 --|    exceeding 255 characters                                              |
182 --|                                                                          |
183 --|    Modified this procedure to improve performance bug 3918467            |
184 --+==========================================================================+
185 --
186 PROCEDURE CreateString
187         (p_package_text  IN  CLOB
188         ,p_array_string  OUT NOCOPY DBMS_SQL.VARCHAR2S)
189 IS
190 --
191 l_Text                VARCHAR2(32000);
192 l_SubText             VARCHAR2(256);
193 --
194 l_MaxLine             NUMBER   := 255;
195 --
196 l_NewLine             BOOLEAN;
197 l_Literal             BOOLEAN;
198 l_Space               BOOLEAN;
199 --
200 l_pos                 NUMBER         ;
201 --
202 l_Idx                 BINARY_INTEGER;
203 l_array_string        DBMS_SQL.VARCHAR2S;
204 l_log_module          VARCHAR2(240);
205 
206 l_clob_string        CLOB;
207 l_maxLength          NUMBER := 8000;
208 --
209 l_length   number;
210 l_iteration number;
211 BEGIN
212 --
213    IF g_log_enabled THEN
214          l_log_module := C_DEFAULT_MODULE||'.CreateString';
215    END IF;
216    --
217    IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
218 
219          trace
220             (p_msg      => 'BEGIN of CreateString'
221             ,p_level    => C_LEVEL_PROCEDURE
222             ,p_module   => l_log_module);
223 
224    END IF;
225    --
226 
227     l_clob_string := p_package_text;
228 
229     l_pos       := 0;
230     l_NewLine   := FALSE;
231     l_Literal   := FALSE;
232     l_Space     := FALSE;
233     l_Idx       := 0;
234 
235     --
236 
237    IF (C_LEVEL_STATEMENT >= g_log_level) THEN
238          trace
239             (p_msg      => 'Begin looping....'
240             ,p_level    => C_LEVEL_STATEMENT
241             ,p_module   => l_log_module);
242    END IF;
243    WHILE length(l_clob_string) > 0 LOOP
244       l_text := substr(l_clob_string,1,l_maxLength);
245 
246        WHILE ( LENGTH(l_Text) >= l_MaxLine ) LOOP
247          BEGIN
248             l_SubText   := SUBSTRB(l_Text,1,l_MaxLine);
249             l_pos       := INSTRB(l_SubText,g_chr_newline,1,1);
250             IF l_pos = 0 THEN
251               l_NewLine := FALSE;
252               l_pos := INSTRB(l_SubText,g_chr_quote,1,1);
253               IF l_pos = 0 THEN
254                 l_Literal := FALSE;
255                 l_pos     := INSTRB(l_SubText,g_chr_space,1,1);
256                 l_Space   := (l_pos = 0);
257               ELSE
258                 l_Literal := TRUE;
259               END IF;
260             ELSE
261               l_NewLine := TRUE;
262             END IF;
263 
264             IF l_newline THEN
265               l_Idx                  := l_Idx + 1;
266               l_array_string(l_Idx)  := SUBSTRB(l_SubText,1,l_pos);
267               l_Text                 := SUBSTRB(l_Text,l_pos + 1);
268             ELSIF l_Literal THEN
269               l_Idx                  := l_Idx + 1;
270               l_array_string(l_Idx)  := SUBSTRB(l_SubText,1,l_pos-1) || g_chr_newline;
271               l_Text                 := SUBSTRB(l_Text,l_pos);
272             ELSIF l_Space   THEN
273               l_Idx                  := l_Idx + 1;
274               l_array_string(l_Idx)  := SUBSTRB(l_SubText,1,l_pos-1) || g_chr_newline;
275               l_Text                 := SUBSTRB(l_Text,l_pos + 1);
276             ELSE
277               l_Idx                  := l_Idx + 1;
278               l_array_string(l_Idx)  := l_SubText;
279               l_Text                 := SUBSTRB(l_Text,l_MaxLine + 1);
280             END IF;
281          END;
282        END LOOP;
283 
284     IF (length(l_clob_string)-l_maxLength) >= 0 THEN
285         l_clob_string := substr(l_clob_string,(l_maxLength - nvl(length(l_Text),0) + 1)); --Fix for Bug 9609429
286     ELSE
287        l_clob_string := NULL;
288        l_Idx                 := l_Idx + 1;
289        l_array_string(l_Idx) := l_Text;
290     END IF;
291 END LOOP;
292 p_array_string := l_array_string;
293 
294 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
295 
296       trace
297          (p_msg      => 'END of CreateString'
298          ,p_level    => C_LEVEL_PROCEDURE
299          ,p_module   => l_log_module);
300 
301 END IF;
302 END CreateString;
303 --
304 --+==========================================================================+
305 --| PRIVATE procedures and functions                                         |
306 --|    AddNewLine                                                          |
307 --|    transforms CLOB lines (length > 255) into a list of lines not         |
308 --|    exceeding 255 characters                                              |
309 --|                                                                          |
310 --|                                                                          |
311 --+==========================================================================+
312 
313 PROCEDURE AddNewLine(p_array_string  IN  OUT NOCOPY DBMS_SQL.VARCHAR2S)
314 IS
315 --
316 l_Idx                 BINARY_INTEGER;
317 l_array_string        DBMS_SQL.VARCHAR2S;
318 l_log_module          VARCHAR2(240);
319 --
320 BEGIN
321 --
322 IF g_log_enabled THEN
323       l_log_module := C_DEFAULT_MODULE||'.AddNewLine';
324 END IF;
325 --
326 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
327 
328       trace
329          (p_msg      => 'BEGIN of AddNewLine'
330          ,p_level    => C_LEVEL_PROCEDURE
331          ,p_module   => l_log_module);
332 
333 END IF;
334 --
335 l_array_string := p_array_string;
336 --
337 IF l_array_string.COUNT > 0 THEN
338 --
339   FOR Idx IN l_array_string.FIRST .. l_array_string.LAST LOOP
340   --
341     IF l_array_string.EXISTS(Idx) THEN
342     --
343       IF SUBSTR(l_array_string(Idx),LENGTH(l_array_string(Idx))) <> g_chr_newline THEN
344       --
345          l_array_string(Idx) := l_array_string(Idx) || g_chr_newline;
346       --
347       END IF;
348     --
349     END IF;
350   --
351   END LOOP;
352 --
353 END IF;
354 --
355 p_array_string := l_array_string;
356 --
357 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
358 
359       trace
363 
360          (p_msg      => 'END of AddNewLine'
361          ,p_level    => C_LEVEL_PROCEDURE
362          ,p_module   => l_log_module);
364 END IF;
365 EXCEPTION
366    WHEN xla_exceptions_pkg.application_exception   THEN
367        RAISE;
368    WHEN OTHERS    THEN
369       xla_exceptions_pkg.raise_message
370          (p_location => 'xla_cmp_string_pkg.AddNewLine');
371 END AddNewLine;
372 --
373 --
374 --+==========================================================================+
375 --| PRIVATE procedures and functions                                         |
376 --|    truncate_lines                                                        |
377 --|    transforms CLOB lines (length > 255) into a list of lines not         |
378 --|    exceeding 255 characters, this constraint was inposed by MRC product  |
379 --|                                                                          |
380 --|                                                                          |
381 --+==========================================================================+
382 --
383 PROCEDURE truncate_lines(p_package_text IN OUT NOCOPY CLOB)
384 IS
385 --
386 --
387 l_Text                CLOB;
388 l_SubText             VARCHAR2(1024); --bug6600635 increased size to accomodate
389                                                   --multibyte strings.
390 --
391 l_MaxLine             NUMBER   := g_Max_line;
392 --
393 l_NewLine             BOOLEAN;
394 l_Literal             BOOLEAN;
395 l_Space               BOOLEAN;
396 --
397 l_pos                 NUMBER         ;
398 --
399 l_Output              CLOB;
400 l_log_module          VARCHAR2(240);
401 --
402 BEGIN
403 --
404 IF g_log_enabled THEN
405       l_log_module := C_DEFAULT_MODULE||'.truncate_lines';
406 END IF;
407 --
408 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
409 
410       trace
411          (p_msg      => 'BEGIN of truncate_lines'
412          ,p_level    => C_LEVEL_PROCEDURE
413          ,p_module   => l_log_module);
414 
415 END IF;
416 --
417 --
418     l_Text      := p_package_text;
419     l_pos       := 0;
420     l_NewLine   := FALSE;
421     l_Literal   := FALSE;
422     l_Space     := FALSE;
423     l_Output    := NULL;
424     --
425     WHILE ( LENGTH(l_Text) >= l_MaxLine ) LOOP
426     --
427       BEGIN
428          --
429          l_SubText   := SUBSTR(l_Text,1,l_MaxLine);
430          l_pos       := INSTR(l_SubText,g_chr_newline,1,1);
431          --
432          IF l_pos = 0 THEN
433          --
434            l_NewLine := FALSE;
435            l_pos := INSTR(l_SubText,g_chr_quote,1,1);
436            --
437            IF l_pos = 0 THEN
438            --
439              l_Literal := FALSE;
440              l_pos     := INSTR(l_SubText,g_chr_space,1,1);
441              l_Space   := (l_pos = 0);
442            --
443            ELSE
444            --
445              l_Literal := TRUE;
446            --
447            END IF;
448          --
449          ELSE
450          --
451            l_NewLine := TRUE;
452          --
453          END IF;
454          --
455          --
456          IF l_newline THEN
457          --
458            l_Output               := l_Output || SUBSTR(l_SubText,1,l_pos);
459            l_Text                 := SUBSTR(l_Text,l_pos + 1);
460          --
461          ELSIF l_Literal THEN
462          --
463            l_Output               := l_Output || SUBSTR(l_SubText,1,l_pos-1) || g_chr_newline;
464            l_Text                 := SUBSTR(l_Text,l_pos);
465          --
466          ELSIF l_Space   THEN
467          --
468            l_Output               := l_Output || SUBSTR(l_SubText,1,l_pos-1) || g_chr_newline;
469            l_Text                 := SUBSTR(l_Text,l_pos + 1);
470          --
471          ELSE
472          --
473            l_Output               := l_Output || l_SubText;
474            l_Text                 := SUBSTR(l_Text,l_MaxLine + 1);
475          --
476          END IF;
477          --
478       END;
479      --
480     END LOOP;
481 --
482 IF LENGTH(l_Text) > 0 THEN
483 --
484   l_Output              := l_Output|| l_Text;
485 --
486 END IF;
487 --
488 p_package_text := l_Output;
489 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
490 
491       trace
492          (p_msg      => 'END of truncate_lines'
493          ,p_level    => C_LEVEL_PROCEDURE
494          ,p_module   => l_log_module);
495 
496 END IF;
497 EXCEPTION
498    WHEN xla_exceptions_pkg.application_exception   THEN
499        RAISE;
500    WHEN OTHERS    THEN
501       xla_exceptions_pkg.raise_message
502          (p_location => 'xla_cmp_string_pkg.truncate_lines');
503 END truncate_lines;
504 --
505 --+==========================================================================+
506 --|                                                                          |
507 --| PUBLIC Procedure                                                         |
511 PROCEDURE DumpLines (p_array_output_string      IN DBMS_SQL.VARCHAR2S)
508 --|                                                                          |
509 --+==========================================================================+
510 --
512 IS
513 l_array_string          DBMS_SQL.VARCHAR2S;
514 l_log_module            VARCHAR2(240);
515 BEGIN
516 --
517 --
518 IF g_log_enabled THEN
519       l_log_module := C_DEFAULT_MODULE||'.DumpLines';
520 END IF;
521 --
522 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
523 
524       trace
525          (p_msg      => 'BEGIN of DumpLines'
526          ,p_level    => C_LEVEL_PROCEDURE
527          ,p_module   => l_log_module);
528 
529 END IF;
530 
531 IF p_array_output_string.COUNT > 0 THEN
532  --
533  FOR Idx IN p_array_output_string.FIRST .. p_array_output_string.LAST LOOP
534  --
535    IF p_array_output_string.EXISTS(Idx) THEN
536    --
537      IF (C_LEVEL_STATEMENT >= g_log_level) THEN
538 
539          trace
540              (p_msg      =>  RPAD(Idx,10,' ')||' '||p_array_output_string(Idx)
541              ,p_level    => C_LEVEL_STATEMENT
542              ,p_module   => l_log_module);
543 
544      END IF;
545    --
546    END IF;
547  --
548  END LOOP;
549  --
550 END IF;
551 --
552 --
553 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
554 
555       trace
556          (p_msg      => 'END of DumpLines'
557          ,p_level    => C_LEVEL_PROCEDURE
558          ,p_module   => l_log_module);
559 
560 END IF;
561 EXCEPTION
562    WHEN xla_exceptions_pkg.application_exception   THEN
563         RAISE;
564    WHEN OTHERS    THEN
565       xla_exceptions_pkg.raise_message
566          (p_location => 'xla_cmp_string_pkg.DumpLines');
567 END DumpLines;
568 --
569 --+==========================================================================+
570 --|                                                                          |
571 --| PUBLIC Procedure                                                         |
572 --|                                                                          |
573 --+==========================================================================+
574 --
575 FUNCTION replace_token
576        (p_original_text             IN  CLOB
577        ,p_token                     IN  VARCHAR2
578        ,p_replacement_text          IN  CLOB)
579 RETURN CLOB IS
580 l_found_position        INTEGER;
581 l_return_value          CLOB;
582 l_log_module            VARCHAR2(240);
583 BEGIN
584 IF g_log_enabled THEN
585    l_log_module := C_DEFAULT_MODULE||'.replace_token';
586 END IF;
587 --
588 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
589    trace
590       (p_msg      => 'BEGIN of replace_token'
591       ,p_level    => C_LEVEL_PROCEDURE
592       ,p_module   => l_log_module);
593 END IF;
594 
595 --
596 -- Copy the original clob into a local variable
597 --
598 l_return_value   := p_original_text;
599 
600 --
601 -- Find the first occurrence of the token
602 --
603 l_found_position := INSTR(l_return_value, p_token);
604 
605 --
606 -- If not found exit
607 --
608 IF l_found_position = 0 OR l_found_position IS NULL THEN
609    NULL;
610 ELSE
611    --
612    -- Extract the portions around the token and embed the replacement
613    -- Bug 4444678. Used the iterative call to replace_token
614    --
615    l_return_value := SUBSTR(l_return_value ,1 ,l_found_position - 1) ||
616                      p_replacement_text  ||
617                      replace_token
618                         (SUBSTR(l_return_value,l_found_position + LENGTH(p_token))
619                         ,p_token
620                         ,p_replacement_text);
621 END IF;
622 
623 IF (C_LEVEL_PROCEDURE >= g_log_level) THEN
624    trace
625       (p_msg      => 'END of replace_token'
626       ,p_level    => C_LEVEL_PROCEDURE
627       ,p_module   => l_log_module);
628 END IF;
629 
630 RETURN l_return_value;
631 EXCEPTION
632 WHEN xla_exceptions_pkg.application_exception   THEN
633    RAISE;
634 WHEN OTHERS    THEN
635    xla_exceptions_pkg.raise_message
636       (p_location => 'xla_cmp_string_pkg.replace_token');
637 END replace_token;
638 
639 --=============================================================================
640 --
641 --
642 --
643 --
644 --
645 --
646 --
647 --
648 --
649 --
650 --
651 --
652 --
653 --
654 --
655 --
656 --
657 --
658 --
659 --
660 --
661 --
662 --=============================================================================
663 --=============================================================================
664 --          *********** Initialization routine **********
665 --=============================================================================
666 
667 BEGIN
668 
669    g_log_level      := FND_LOG.G_CURRENT_RUNTIME_LEVEL;
670    g_log_enabled    := fnd_log.test
671                           (log_level  => g_log_level
672                           ,module     => C_DEFAULT_MODULE);
673 
674    IF NOT g_log_enabled  THEN
675       g_log_level := C_LEVEL_LOG_DISABLED;
676    END IF;
677 --
678 END xla_cmp_string_pkg;