DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_LOG

Source


1 package body FND_LOG as
2 /* $Header: AFUTLOGB.pls 120.5.12010000.3 2010/03/17 17:29:22 pferguso ship $ */
3    /* Documentation for this package is at */
4    /* http://www-apps.us.oracle.com/logging/ */
5 
6    /*
7    ** EXCEPTIONS
8    */
9    bad_parameter EXCEPTION;
10    PRAGMA EXCEPTION_INIT(bad_parameter, -06501); -- program error
11 
12    /*
13    ** PACKAGE VARIABLES
14    */
15 /* Removing these from pkg body as they already exist in spec. 10.1.0.4 throws
16    error in case of duplicate definition
17 
18    LEVEL_UNEXPECTED CONSTANT NUMBER  := 6;
19    LEVEL_ERROR      CONSTANT NUMBER  := 5;
20    LEVEL_EXCEPTION  CONSTANT NUMBER  := 4;
21    LEVEL_EVENT      CONSTANT NUMBER  := 3;
22    LEVEL_PROCEDURE  CONSTANT NUMBER  := 2;
23    LEVEL_STATEMENT  CONSTANT NUMBER  := 1;
24 */
25    /* Message buffer */
26    internal_messages VARCHAR2(10000);
27 
28    /*
29    ** PRIVATE PROCEDURES
30    */
31 
32    /* Set the contents of the message buffer */
33    procedure INTERNAL_MESSAGE(msg VARCHAR2) IS
34    begin
35       internal_messages := internal_messages || msg || fnd_global.newline;
36    end;
37 
38    /* Set error message and raise exception for unexpected sql errors */
39 
40    procedure GENERIC_ERROR(routine in varchar2,
41                            errcode in number,
42                            errmsg in varchar2) is
43    begin
44        fnd_message.set_name('FND', 'SQL_PLSQL_ERROR');
45        fnd_message.set_token('ROUTINE', routine);
46        fnd_message.set_token('ERRNO', errcode);
47        fnd_message.set_token('REASON', errmsg);
48        app_exception.raise_exception;
49    end;
50 
51 
52 
53    FUNCTION STR_UNCHKED_INT_WITH_CONTEXT(
54                     LOG_LEVEL       IN NUMBER,
55                     MODULE          IN VARCHAR2,
56                     MESSAGE_TEXT    IN VARCHAR2,
57                     ENCODED         IN VARCHAR2 DEFAULT 'N',
58                     NODE            IN VARCHAR2 DEFAULT NULL,
59                     NODE_IP_ADDRESS IN VARCHAR2 DEFAULT NULL,
60                     PROCESS_ID      IN VARCHAR2 DEFAULT NULL,
61                     JVM_ID          IN VARCHAR2 DEFAULT NULL,
62                     THREAD_ID       IN VARCHAR2 DEFAULT NULL,
63                     AUDSID          IN NUMBER   DEFAULT NULL,
64                     DB_INSTANCE     IN NUMBER   DEFAULT NULL) RETURN NUMBER is
65 
66    CALL_STACK   VARCHAR2(4000) := NULL;
67    ERR_STACK    VARCHAR2(4000) := NULL;
68    l_seq        NUMBER;
69 
70    begin
71 
72       if (LOG_LEVEL >= FND_LOG.LEVEL_EXCEPTION) THEN
73            CALL_STACK := DBMS_UTILITY.FORMAT_CALL_STACK;
74            ERR_STACK := DBMS_UTILITY.FORMAT_ERROR_STACK;
75       end if;
76 
77       l_seq := FND_LOG_REPOSITORY.STR_UNCHKED_INT_WITH_CONTEXT(
78                       LOG_LEVEL       => LOG_LEVEL,
79                       MODULE          => MODULE,
80                       MESSAGE_TEXT    => MESSAGE_TEXT,
81                       ENCODED         => ENCODED,
82                       NODE            => NODE,
83                       NODE_IP_ADDRESS => NODE_IP_ADDRESS,
84                       PROCESS_ID      => PROCESS_ID,
85                       JVM_ID          => JVM_ID,
86                       THREAD_ID       => THREAD_ID,
87                       AUDSID          => AUDSID,
88                       DB_INSTANCE     => DB_INSTANCE,
89                       CALL_STACK      => CALL_STACK,
90                       ERR_STACK       => ERR_STACK);
91 
92       return l_seq;
93 
94    end;
95 
96 
97 
98    /*
99    ** PUBLIC PROCEDURES
100    */
101 
102    /*
103    ** FND_LOG.INIT_TRANSACTION
104    **
105    ** Description:
106    ** Initializes a log transaction.  A log transaction
107    ** corresponds to an instance or invocation of a single
108    ** component.  (e.g. A concurrent request, service process,
109    ** open form, ICX function)
110    **
111    ** This routine should be called only after
112    ** FND_GLOBAL.INITIALIZE, since some of the context information
113    ** is retrieved from FND_GLOBAL.
114    **
115    ** Arguments:
116    **   CONC_REQUEST_ID       - Concurrent request id
117    **   FORM_ID               - Form id
118    **   FORM_APPLICATION_ID   - Form application id
119    **   CONCURRENT_PROCESS_ID - Service process id
120    **   CONCURRENT_QUEUE_ID   - Service queue id
121    **   QUEUE_APPLICATION_ID  - Service queue application id
122    **   SOA_INSTANCE_ID       - SOA instance id
123    **
124    ** Use only the arguments that apply to the caller.
125    ** Any argument that does not apply should be passed as NULL
126    ** i.e. when calling from a form, pass in FORM_ID and FORM_APPLICATION_ID
127    ** and leave all other parameters NULL.
128    **
129    ** Returns:
130    **   ID of the log transaction context
131    **
132    */
133    FUNCTION INIT_TRANSACTION (CONC_REQUEST_ID             IN NUMBER DEFAULT NULL,
134                               FORM_ID                     IN NUMBER DEFAULT NULL,
135                               FORM_APPLICATION_ID         IN NUMBER DEFAULT NULL,
136                               CONCURRENT_PROCESS_ID       IN NUMBER DEFAULT NULL,
137                               CONCURRENT_QUEUE_ID         IN NUMBER DEFAULT NULL,
138                               QUEUE_APPLICATION_ID        IN NUMBER DEFAULT NULL,
139 			      SOA_INSTANCE_ID             IN NUMBER DEFAULT NULL)
140                                                           return NUMBER is
141 
142    l_transaction_context_id   number;
143    begin
144 
145      l_transaction_context_id :=
146                FND_LOG_REPOSITORY.INIT_TRANS_INT_WITH_CONTEXT(
147                                      CONC_REQUEST_ID       => CONC_REQUEST_ID,
148                                      FORM_ID               => FORM_ID,
149                                      FORM_APPLICATION_ID   => FORM_APPLICATION_ID,
150 	                             CONCURRENT_PROCESS_ID => CONCURRENT_PROCESS_ID,
151 	                             CONCURRENT_QUEUE_ID   => CONCURRENT_QUEUE_ID,
152                                      QUEUE_APPLICATION_ID  => QUEUE_APPLICATION_ID,
153                                      SOA_INSTANCE_ID       => SOA_INSTANCE_ID);
154        return l_transaction_context_id;
155 
156    exception
157        when others then
158            generic_error('FND_LOG.INIT_TRANSACTION', SQLCODE, SQLERRM);
159            return -1;
160 
161 
162    end INIT_TRANSACTION;
163 
164    /*
165    ** FND_LOG.SET_TRANSACTION
166    ** Description:
167    **     Sets the log transaction ID for the current DB connection.
168    **     This routine should be used whenever the database connection
169    **     changes within the context of a transaction.  For example, this
170    **     routine will be used for successive hits within the same ICX
171    **     transaction or when a concurrent process reconnects to the database.
172    **
173    ** Arguments:
174    **     Log_Transaction
175    **
176    */
177    PROCEDURE SET_TRANSACTION (TRANS_CONTEXT_ID IN NUMBER) is
178    dummy number;
179 
180    begin
181 
182      select count(*)
183        into dummy
184        from FND_LOG_TRANSACTION_CONTEXT
185       where TRANSACTION_CONTEXT_ID = TRANS_CONTEXT_ID;
186 
187      if (dummy = 1) then
188        FND_LOG.G_TRANSACTION_CONTEXT_ID := TRANS_CONTEXT_ID;
189      else
190        internal_message('bad TRANSACTION_CONTEXT_ID: '|| TRANS_CONTEXT_ID);
191        internal_message('TRANSACTION_CONTEXT_ID not found in table FND_LOG_TRANSACTION_CONTEXT');
192        raise bad_parameter;
193      end if;
194 
195    end SET_TRANSACTION;
196 
197    /*
198    **  Writes the message to the log file for the spec'd level and module
199    **  if logging is enabled for this level and module
200    */
201    PROCEDURE STRING(LOG_LEVEL IN NUMBER,
202                     MODULE    IN VARCHAR2,
203                     MESSAGE   IN VARCHAR2) is
204 
205    l_seq   number;
206    l_message varchar2(4000);
207 
208    begin
209       /* Short circuit if logging not turned on at this level */
210       if (LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL) then
211          return;
212       end if;
213 
214       if FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE, LOG_LEVEL) then
215 	 l_message := substrb(MESSAGE,1,4000); --6313496
216          l_seq := STR_UNCHKED_INT_WITH_CONTEXT(
217                                LOG_LEVEL       => LOG_LEVEL,
218                                MODULE          => MODULE,
219                                MESSAGE_TEXT    => l_message);
220       end if;
221 
222       exception
223          when others then
224 	    NULL; /* supress the exception */
225    end;
226 
227    /*
228    **  Writes the message with context information to the log file for
229    **  the spec'd level and module if logging is enabled for this level
230    **  and module
231    */
232    PROCEDURE STRING_WITH_CONTEXT(LOG_LEVEL  IN NUMBER,
233                       MODULE           IN VARCHAR2,
234                       MESSAGE          IN VARCHAR2,
235                       ENCODED          IN VARCHAR2 DEFAULT NULL,
236                       NODE             IN VARCHAR2 DEFAULT NULL,
237                       NODE_IP_ADDRESS  IN VARCHAR2 DEFAULT NULL,
238                       PROCESS_ID       IN VARCHAR2 DEFAULT NULL,
239                       JVM_ID           IN VARCHAR2 DEFAULT NULL,
240                       THREAD_ID        IN VARCHAR2 DEFAULT NULL,
241                       AUDSID          IN NUMBER   DEFAULT NULL,
242                       DB_INSTANCE     IN NUMBER   DEFAULT NULL) is
243 
244    l_seq   number;
245    l_message varchar2(4000);
246 
247    begin
248       /* Short circuit if logging not turned on at this level */
249       if (LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL) then
250          return;
251       end if;
252 
253       if FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE, LOG_LEVEL) then
254 
255          l_message:=substrb(MESSAGE,1,4000); --6313496
256 
257          l_seq := STR_UNCHKED_INT_WITH_CONTEXT(
258                       LOG_LEVEL       => LOG_LEVEL,
259                       MODULE          => MODULE,
260                       MESSAGE_TEXT    => l_message,
261                       ENCODED         => ENCODED,
262                       NODE            => NODE,
263                       NODE_IP_ADDRESS => NODE_IP_ADDRESS,
264                       PROCESS_ID      => PROCESS_ID,
265                       JVM_ID          => JVM_ID,
266                       THREAD_ID       => THREAD_ID,
267                       AUDSID          => AUDSID,
268                       DB_INSTANCE     => DB_INSTANCE);
269       end if;
270    end;
271 
272    /*
273    ** Internal (private) API that handles all the logic
274    */
275    FUNCTION MESSAGE_INTERNAL(LOG_LEVEL   IN NUMBER,
276                      MODULE      IN VARCHAR2,
277                      POP_MESSAGE IN BOOLEAN DEFAULT NULL,
278 		     AUTO_LOG    IN VARCHAR2) RETURN NUMBER is
279    msg_buf varchar2(32000);
280    l_sequence number := -1;
281    begin
282       /* Short circuit if logging not turned on at this level */
283       if (LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL) then
284          return l_sequence;
285       end if;
286 
287       if FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE, LOG_LEVEL) then
288          msg_buf := FND_MESSAGE.GET_ENCODED(AUTO_LOG);
289          l_sequence := STR_UNCHKED_INT_WITH_CONTEXT(
290                       LOG_LEVEL       => LOG_LEVEL,
291                       MODULE          => MODULE,
292                       MESSAGE_TEXT    => msg_buf,
293                       ENCODED         => 'Y');
294 
295 	 /* No change in Message Stack if this PROCEDURE is called for Auto-Log = 'Y' */
296          if( (AUTO_LOG <> 'Y') and
297              ((pop_message = FALSE) OR (pop_message is NULL)) )then
298                  FND_MESSAGE.SET_ENCODED(msg_buf);
299          end if;
300       end if;
301 
302       return l_sequence;
303 
304       exception
305          when others then
306             /* supress the exception */
307             return l_sequence;
308    end;
309 
310    /*
311    **  Writes a message to the log file if this level and module is enabled
312    **  This requires that the message was set previously with
313    **  FND_MESSAGE.SET_NAME, SET_TOKEN, etc.
314    **  The message is popped off the message dictionary stack, if POP_MESSAGE
315    **  is TRUE.  Pass FALSE for POP_MESSAGE if the message will also be
316    **  displayed to the user later.  If POP_MESSAGE isn't passed, the
317    **  message will not be popped off the stack, so it must be displayed
318    **  or explicitly cleared later on.
319    */
320    PROCEDURE MESSAGE(LOG_LEVEL   IN NUMBER,
321                      MODULE      IN VARCHAR2,
322                      POP_MESSAGE IN BOOLEAN DEFAULT NULL,
323                      AUTO_LOG    IN VARCHAR2)
324    is
325    l_sequence number;
326    begin
327       l_sequence := MESSAGE_INTERNAL(LOG_LEVEL, MODULE, POP_MESSAGE, AUTO_LOG);
328    end;
329 
330    PROCEDURE MESSAGE(LOG_LEVEL   IN NUMBER,
331                      MODULE IN VARCHAR2,
332                      POP_MESSAGE IN BOOLEAN DEFAULT NULL)
333    is
334    begin
335       /* Message is already being logged, so AUTO_LOG = 'N' */
336       MESSAGE(LOG_LEVEL, MODULE, POP_MESSAGE, 'N');
337    end;
338 
339    /*
340    **  Writes a message to the log file if this level and module is enabled
341    **  The message gets set previously with FND_MESSAGE.SET_NAME,
342    **  SET_TOKEN, etc.
343    **  The message is popped off the message dictionary stack, if POP_MESSAGE
344    **  is TRUE.  Pass FALSE for POP_MESSAGE if the message will also be
345    **  displayed to the user later.
346    **  Code Sample:
347    **  if( FND_LOG.LEVEL_UNEXPECTED >=
348    **     FND_LOG.G_CURRENT_RUNTIME_LEVEL) then
349    **    FND_MESSAGE.SET_NAME(...);    -- Set message
350    **    FND_MESSAGE.SET_TOKEN(...);   -- Set token in message
351    **    ATTACHMENT_ID := FND_LOG.MESSAGE_WITH_ATTACHMENT(FND_LOG.LEVEL_UNEXPECTED,...,TRUE);
352    **    if ( ATTACHMENT_ID <> -1 ) then
353    **	   -- For ASCII data use WRITE
354    **      FND_LOG_ATTACHMENT.WRITE(ATTACHMENT_ID, ...);
355    **	   -- For Non-ASCII data use WRITE_RAW
356    **      FND_LOG_ATTACHMENT.WRITE_RAW(ATTACHMENT_ID, ...);
357    **      FND_LOG_ATTACHMENT.CLOSE(ATTACHMENT_ID);
358    **    end if;
359    **  end if;
360    */
361    FUNCTION MESSAGE_WITH_ATTACHMENT(LOG_LEVEL   IN NUMBER,
362                      MODULE      IN VARCHAR2,
363                      POP_MESSAGE IN BOOLEAN DEFAULT NULL,
364                      P_CHARSET IN VARCHAR2 DEFAULT 'ascii',
365                      P_MIMETYPE IN VARCHAR2 DEFAULT 'text/html',
366                      P_ENCODING IN VARCHAR2 DEFAULT NULL,
367                      P_LANG IN VARCHAR2 DEFAULT NULL,
368                      P_FILE_EXTN IN VARCHAR2 DEFAULT 'txt',
369                      P_DESC IN VARCHAR2 DEFAULT NULL) RETURN NUMBER is
370    l_sequence number := -1;
371    begin
372      l_sequence := MESSAGE_INTERNAL(LOG_LEVEL, MODULE, POP_MESSAGE, 'N');
373      if ( l_sequence > 0 ) then
374        FND_LOG_REPOSITORY.INSERT_BLOB(l_sequence, P_CHARSET, P_MIMETYPE,
375 			P_ENCODING, P_LANG, P_FILE_EXTN, P_DESC);
376      end if;
377      return l_sequence;
378    end;
379 
380    /*
381    **  Writes a message with context to the log file if this level and
382    **  module is enabled.  This requires that the message was set
383    **  previously with FND_MESSAGE.SET_NAME, SET_TOKEN, etc.
384    **  The message is popped off the message dictionary stack, if POP_MESSAGE
385    **  is TRUE.  Pass FALSE for POP_MESSAGE if the message will also be
386    **  displayed to the user later.  If POP_MESSAGE isn't passed, the
387    **  message will not be popped off the stack, so it must be displayed
388    **  or explicitly cleared later on.
389    */
390    PROCEDURE MESSAGE_WITH_CONTEXT(LOG_LEVEL IN NUMBER,
391                       MODULE           IN VARCHAR2,
392                       POP_MESSAGE      IN BOOLEAN DEFAULT NULL, --Default FALSE
393                       NODE             IN VARCHAR2 DEFAULT NULL,
394                       NODE_IP_ADDRESS  IN VARCHAR2 DEFAULT NULL,
395                       PROCESS_ID       IN VARCHAR2 DEFAULT NULL,
396                       JVM_ID           IN VARCHAR2 DEFAULT NULL,
397                       THREAD_ID        IN VARCHAR2 DEFAULT NULL,
398                       AUDSID          IN NUMBER   DEFAULT NULL,
399                       DB_INSTANCE     IN NUMBER   DEFAULT NULL) is
400    msg_buf varchar2(32000);
401    l_seq   number;
402    begin
403       /* Short circuit if logging not turned on at this level */
404       if (LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL) then
405          return;
406       end if;
407 
408       if FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE, LOG_LEVEL) then
409          msg_buf := FND_MESSAGE.GET_ENCODED;
410 
411          l_seq := STR_UNCHKED_INT_WITH_CONTEXT(
412                       LOG_LEVEL       => LOG_LEVEL,
413                       MODULE          => MODULE,
414                       MESSAGE_TEXT    => msg_buf,
415                       ENCODED         => 'Y',
416                       NODE            => NODE,
417                       NODE_IP_ADDRESS => NODE_IP_ADDRESS,
418                       PROCESS_ID      => PROCESS_ID,
419                       JVM_ID          => JVM_ID,
420                       THREAD_ID       => THREAD_ID,
421                       AUDSID          => AUDSID,
422                       DB_INSTANCE     => DB_INSTANCE);
423          if((pop_message = FALSE) OR (pop_message is NULL))then
424             FND_MESSAGE.SET_ENCODED(msg_buf);
425          end if;
426 
427       end if;
428    end;
429 
430 
431    /*
432    ** FND_LOG.WORK_METRIC
433    ** Description:
434    **     Writes a metric value out to the FND tables in an
435    **     autonomous transaction.  Posting to the Business Event
436    **     system is deferred until WORK_METRICS_EVENT is called.
437    **
438    ** Arguments:
439    **     Module       - Module name (See FND_LOG standards.)
440    **     Metric_code  - Internal name of metric.
441    **     Metric_value - Value for metric (string, number, or date)
442    **
443    */
444 
445    procedure WORK_METRIC (MODULE       IN VARCHAR2,
446                      METRIC_CODE  IN VARCHAR2,
447                      METRIC_VALUE IN VARCHAR2) is
448 
449    begin
450      FND_LOG_REPOSITORY.METRIC_INTERNAL_WITH_CONTEXT(
451                                        MODULE              => MODULE,
452                                        METRIC_CODE         => METRIC_CODE,
453                                        METRIC_VALUE_STRING => METRIC_VALUE);
454    end WORK_METRIC;
455 
456    procedure WORK_METRIC (MODULE       IN VARCHAR2,
457                      METRIC_CODE  IN VARCHAR2,
458                      METRIC_VALUE IN NUMBER) is
459 
460    begin
461      FND_LOG_REPOSITORY.METRIC_INTERNAL_WITH_CONTEXT(
462                                        MODULE              => MODULE,
463                                        METRIC_CODE         => METRIC_CODE,
464                                        METRIC_VALUE_NUMBER => METRIC_VALUE);
465    end WORK_METRIC;
466 
467    procedure WORK_METRIC (MODULE       IN VARCHAR2,
468                      METRIC_CODE  IN VARCHAR2,
469                      METRIC_VALUE IN DATE) is
470 
471    begin
472      FND_LOG_REPOSITORY.METRIC_INTERNAL_WITH_CONTEXT(
473                                        MODULE              => MODULE,
474                                        METRIC_CODE         => METRIC_CODE,
475                                        METRIC_VALUE_DATE   => METRIC_VALUE);
476    end WORK_METRIC;
477 
478    /*
479    ** FND_LOG.WORK_METRICS_EVENT
480    ** Description:
481    **     Posts the pending metrics for the current component
482    **     session to the Business Event system and updates the pending
483    **     metrics with the event key. The metrics will be bundled in an
484    **     XML message included in the event.  The event will be named:
485    **     "oracle.apps.fnd.system.metrics"
486    **
487    ** Arguments:
488    **     CONTEXT_ID    ID of the context to post the metrics event for.
489    **                   Use NULL for the current context.
490    */
491 
492    PROCEDURE WORK_METRICS_EVENT(CONTEXT_ID IN NUMBER DEFAULT NULL) IS
493    begin
494 
495       FND_LOG_REPOSITORY.METRICS_EVENT_INT_WITH_CONTEXT(CONTEXT_ID);
496 
497    end WORK_METRICS_EVENT;
498 
499    /*
500    ** FND_LOG.GET_TEXT
501    **
502    ** Description:
503    ** Retrieves the fully translated message text, given a log sequence ID
504    **
505    ** Arguments:
506    **      log_sequence_id   - FND_LOG message identifier.
507    **      lang              - Language code for translation (optional).
508    **
509    ** Returns:
510    **      If an encoded message, the full translated text of the message.
511    **      If message not encoded, the text of the message as logged.
512    **      Returns NULL if the message cannot be found.
513    */
514    FUNCTION GET_TEXT(LOG_SEQUENCE_ID IN NUMBER,
515                      LANG            IN VARCHAR2 DEFAULT NULL
516                      ) RETURN  VARCHAR2 is
517        --6434437, the tok_val variable was too small
518        --I also went ahead and modified msg_text and msg just in case
519        --the underlying columns are changed in the future.
520 
521        msg_text           fnd_log_messages.message_text%type;
522        msg                fnd_new_messages.message_text%type;
523        tok_val            fnd_log_messages.message_text%type;
524 
525 
526        encoded            varchar2(1);
527        msg_app_short_name varchar2(50);
528        msg_name           varchar2(30);
529        tok_nam            varchar2(30);
530        tok_type           varchar2(1);
531        srch               varchar2(2000);
532        pos                number;
533        nextpos            number;
534        data_size          number;
535 
536    begin
537 
538 
539       begin
540         select MESSAGE_TEXT, DECODE(ENCODED, 'Y', 'Y', 'N')
541           into msg_text, encoded
542           from FND_LOG_MESSAGES
543          where LOG_SEQUENCE = LOG_SEQUENCE_ID;
544 
545         if (encoded = 'N') then
546            return msg_text;
547         end if;
548 
549       exception
550         when no_data_found then
551           msg_text := '';
552           return msg_text;
553       end;
554 
555 
556       if (LANG is not NULL) then
557          begin
558            FND_GLOBAL.SET_NLS_CONTEXT(p_nls_language => LANG);
559          exception
560            when others then
561         /*--------------------------------------------------------------+
562          | If LANG parameter is bad, set a message then continue in the |
563          | language of the current database session.                    |
564          +--------------------------------------------------------------*/
565             FND_MESSAGE.SET_NAME ('FND', 'SQL-Generic error');
566             FND_MESSAGE.SET_TOKEN ('ERRNO', sqlcode, FALSE);
567             FND_MESSAGE.SET_TOKEN ('REASON', sqlerrm, FALSE);
568             FND_MESSAGE.SET_TOKEN ('ROUTINE', 'FND_LOG.GET_TEXT', FALSE);
569          end;
570       end if;
571 
572       begin
573           FND_MESSAGE.PARSE_ENCODED(msg_text,
574                                   msg_app_short_name,
575                                   msg_name);
576           /* GET_STRING with Auto-Log = 'N' */
577           msg := FND_MESSAGE.GET_STRING(msg_app_short_name,
578                                       msg_name, 'N');
579       exception
580         when others then
581         /*--------------------------------------------------------------+
582          | If it this is not really an encoded message, then            |
583          | FND_MESSAGE.PARSE_ENCODED may have tried to put entire       |
584          | msg_text in msg_app_short_name.                              |
585          +--------------------------------------------------------------*/
586            return msg_text;
587       end;
588 
589       /*--------------------------------------------------------------+
590       | It seems to be an authentic encoded message.                  |
591       +---------------------------------------------------------------*/
592 
593         /* Get rid of msg_app_short_name, msg_name     */
594         pos := INSTRB(msg_text, chr(0), 1, 2) + 1;
595         msg_text := SUBSTRB(msg_text, pos);
596 
597         /* Start the same routine from FND_MESSAGE.GET */
598         pos := 1;
599         data_size := LENGTH(msg_text);
600         while pos < data_size loop
601             tok_type := SUBSTR(msg_text, pos, 1);
602             pos := pos + 2;
603             nextpos := INSTR(msg_text, chr(0), pos);
604             if (nextpos = 0) then /* For bug 1893617 */
605               exit; /* Should never happen, but prevent spins on bad data*/
606             end if;
607             tok_nam := SUBSTR(msg_text, pos, nextpos - pos);
608             pos := nextpos + 1;
609             nextpos := INSTR(msg_text, chr(0), pos);
610             if (nextpos = 0) then /* For bug 1893617 */
611               exit; /* Should never happen, but prevent spins on bad data*/
612             end if;
613             tok_val := SUBSTR(msg_text, pos, nextpos - pos);
614             pos := nextpos + 1;
615 
616             if (tok_type = 'Y') then  /* translated token */
617                 /* GET_STRING with Auto-Log = 'N' */
618                 tok_val := FND_MESSAGE.GET_STRING(msg_app_short_name, tok_val, 'N');
619             elsif (tok_type = 'S') then  /* SQL query token */
620                 tok_val := FND_MESSAGE.FETCH_SQL_TOKEN(tok_val);
621             end if;
622             srch := '&' || tok_nam;
623             if (INSTR(msg, srch) <> 0) then
624                 msg := SUBSTRB(REPLACE(msg, srch, tok_val),1,2000);
625             else
626                 /* try the uppercased version of the token name in case */
627                 /* the caller is (wrongly) passing a mixed case token name */
628                 /* Because begin July 99 all tokens in msg text should be */
629                 /* uppercase. */
630                 srch := '&' || UPPER(tok_nam);
631                 if (INSTR(msg, srch) <> 0) then
632                    msg := SUBSTRB(REPLACE(msg, srch, tok_val),1,2000);
633                 else
634                    msg :=SUBSTRB(msg||' ('||tok_nam||'='||tok_val||')',1,2000);
635               end if;
636             end if;
637         end loop;
638         /* double ampersands don't have anything to do with tokens, they */
639         /* represent access keys.  So we translate them to single ampersands*/
640         /* so that the access key code will recognize them. */
641         msg := SUBSTRB(REPLACE(msg, '&&', '&'),1,2000);
642         return msg;
643     end GET_TEXT;
644 
645    /*
646    ** Tests whether logging is enabled for this level and module, to
647    ** avoid the performance penalty of building long debug message
648    ** strings unnecessarily.
649    */
650    FUNCTION TEST(LOG_LEVEL IN NUMBER,
651                  MODULE    IN VARCHAR2) RETURN BOOLEAN is
652    begin
653       if ( LOG_LEVEL < G_CURRENT_RUNTIME_LEVEL ) then
654          return FALSE;
655       end if;
656       return FND_LOG_REPOSITORY.CHECK_ACCESS_INTERNAL (MODULE, LOG_LEVEL);
657    end;
658 
659 
660     /**
661      * Procedure to enable PL/SQL Buffered Logging (for Batch Mode).
662      * Caller is responsible for calling RESET_BUFFERED_MODE to flush
663      * messages at end. Only messages with log_level < 4 are bufferable.
664      * All error messages (log_level >= 4) are logged immediately.
665      *
666      * Internally reads AFLOG_BUFFER_MODE Profile and if !=0
667      * buffers messages in PL/SQL Collection for Bulk-Inserting.
668      */
669     PROCEDURE SET_BUFFERED_MODE is
670     begin
671 	FND_LOG_REPOSITORY.SET_BUFFERED_MODE;
672     end SET_BUFFERED_MODE;
673 
674     /**
675      * Flushes any buffered messages, and switches back to the
676      * default synchronous (non-buffered) logging.
677      */
678     PROCEDURE RESET_BUFFERED_MODE is
679     begin
680         FND_LOG_REPOSITORY.RESET_BUFFERED_MODE;
681     end RESET_BUFFERED_MODE;
682 
683     /**
684      * API for raising a proxy alert on behalf of the given
685      * concurrent request. The transaction context for the alert is set to
686      * that of the given request ID. The current transaction context is also
687      * captured as a parent context.
688      *
689      * This API does the following:
690      * 1) Sets a child context for the given request ID
691      * 2) Raises the proxy alert by calling fnd_log.message in the normal
692      *    fashion
693      * 3) Clears the child context.
694      */
695     PROCEDURE PROXY_ALERT_FOR_CONC_REQ(
696 	MODULE IN VARCHAR2,
697 	POP_MESSAGE IN BOOLEAN DEFAULT NULL,
698 	REQUEST_ID IN NUMBER) is
699     BEGIN
700 	if (fnd_log.level_unexpected >= fnd_log.g_current_runtime_level) then
701 		fnd_log_repository.set_child_context_for_conc_req(REQUEST_ID);
702 		fnd_log.message(
703 		  log_level => fnd_log.level_unexpected,
704 		  module => MODULE,
705 		  pop_message => POP_MESSAGE);
706 		fnd_log_repository.clear_child_context;
707         end if;
708     END PROXY_ALERT_FOR_CONC_REQ;
709 
710 end FND_LOG;