1 PACKAGE BODY AS_MESSAGE as
2 /* $Header: asxutmgb.pls 115.6 2002/11/06 00:57:15 appldev ship $ */
3 --
4 -- PURPOSE
5 -- Allow messages (both for reporting and debugging) to be written to
6 -- database table or to memory by PL/SQL programs executed on the server.
7 -- When program control is returned to the client, messages can be
8 -- retrieved and used in a report or a log file, etc.
9 --
10 --
11 -- HISTORY
12 --
13 -- 14-JAN-94 R Lee Created.
14 -- 23-FEB-94 R Lee Modified so that messages can be ouputed
15 -- to table AS_CONC_REQUEST_MESSAGES.
16 -- 27-FEB-94 R Lee Renamed Put_DB_Error to Set_Error
17 -- 28-FEB-94 R Lee Modified Initialize. The output buffers
18 -- (db tables or memory) of normal messages
19 -- and debugging messages can now be controlled
20 -- independently.
21 -- 17-MAR-94 R Lee Added Set_Line to replace Put_Line.
22 -- 31-MAR-94 R Lee Changed references to AS_REPORT_ENTRIES to
23 -- AS_CONC_REQUEST_MESSAGES.
24 -- 20-APR-94 R Lee Added funtion Last_Message_Sequence()
25 -- 05-OCT-94 J Lewis Replaced calls to FND_PROFILE for who info
26 -- with calls to FND_GLOBAL
27 --
28 /*------------------------------ DATA TYPES ---------------------------------*/
29 TYPE MESSAGE_TABLE_TYPE IS TABLE of
30 VARCHAR2(255)
31 INDEX BY BINARY_INTEGER;
32
33 TYPE CODE_TABLE_TYPE IS TABLE of
34 VARCHAR2(12)
35 INDEX BY BINARY_INTEGER;
36
37 /*---------------------------- PRIVATE VARIABLES ----------------------------*/
38
39 G_TMessage_Buffer MESSAGE_TABLE_TYPE; -- Message Stack
40 G_TEmpty_Msg_Buffer MESSAGE_TABLE_TYPE; -- Empty Stack used for
41 -- clearing memory
42 G_TMessage_Type CODE_TABLE_TYPE; -- Message Type Stack in sync.
43 -- with Message Stack
44 G_TEmpty_Type CODE_TABLE_TYPE; -- Emtpy Type Stack
45 G_Msg_Count NUMBER := 0; -- Num of Messages on stack
46 G_Msg_Ptr NUMBER := 1; -- Points to next Message
47 -- on stack to retreive.
48 G_Output_Code VARCHAR2(5) := 'STACK'; -- Determines whether messages
49 -- will be stored in a table
50 -- or in memory.
51 G_Debug_Flag VARCHAR2(1) := 'N'; -- Flag determines whether
52 -- debug mode is on or off.
53 G_Debug_Output_Code VARCHAR2(5) := 'STACK'; -- Determines how debugging
54 -- messages will be stored.
55 G_Ins_Message_Flag VARCHAR2(1) := 'N'; -- Flag to indicate whether
56 -- the current message needs
57 -- to be inserted into
58 -- AS_CONC_REQUEST_MESSAGES
59
60 G_User_Id NUMBER := FND_GLOBAL.User_Id;
61 G_Conc_Request_Id NUMBER := 0;
62
63 /*--------------------------- PRIVATE ROUTINES ------------------------------*/
64
65 PROCEDURE Insert_Row(X_Message_Text VARCHAR2,
66 X_Message_Type VARCHAR2,
67 X_Error_Number NUMBER) IS
68 BEGIN
69 INSERT INTO as_conc_request_messages(conc_request_message_id,
70 creation_date,
71 created_by,
72 request_id,
73 type,
74 error_number,
75 text)
76 VALUES(as_conc_request_messages_s.nextval,
77 SYSDATE,
78 G_User_Id,
79 G_Conc_Request_Id,
80 X_Message_Type,
81 X_Error_Number,
82 X_Message_Text);
83 EXCEPTION
84 When OTHERS then
85 Set_Error('AS_MESSAGE.Insert_Message');
86 END;
87
88
89 PROCEDURE Insert_Message(Message_Text VARCHAR2,
90 Message_Type VARCHAR2,
91 Error_Number NUMBER) IS
92 BEGIN
93 if ( (G_Output_Code = 'TABLE')
94 and (G_Ins_Message_Flag = 'Y')) then
95 Insert_Row(G_TMessage_Buffer(G_Msg_Count),
96 G_TMessage_Type(G_Msg_Count), NULL);
97 G_Ins_Message_Flag := 'N';
98 end if;
99 Insert_Row(Message_Text, Message_Type, Error_Number);
100 END;
101
102 --
103 -- NAME
104 -- Set_Line
105 --
106 -- Writes message either to the message stack or AS_CONC_REQUEST_MESSAGES
107 --
108 --
109 PROCEDURE Set_Line(Message_Text IN VARCHAR2,
110 Message_Type IN VARCHAR2,
111 Error_Number IN NUMBER) IS
112 BEGIN
113 if ( ( (Message_Type = 'DEBUG')
114 and (G_Debug_Output_Code = 'TABLE'))
115 or ( (G_Output_Code = 'TABLE')
116 and (Message_Type <> 'DEBUG'))) then
117 Insert_Message(Message_Text, Message_Type, Error_Number);
118 else
119 G_Msg_Count := G_Msg_Count + 1;
120 G_TMessage_Buffer(G_Msg_Count) := Message_Text;
121 G_TMessage_Type(G_Msg_Count) := Message_Type;
122 end if;
123 END;
124
125 /*---------------------------- PUBLIC ROUTINES ------------------------------*/
126 --
127 -- NAME
128 -- Initialize
129 --
130 -- PURPOSE
131 -- Controls whether output is stored in a DB table or in memory via the
132 -- message stack and sets the REQUEST_ID of the concurrent program if
133 -- applicabale.
134 --
135 -- USAGE
136 -- When Output_Code = 'TABLE' messages will be inserted into
137 -- AS_CONC_REQUEST_MESSAGES.
138 --
139 -- When Output_Code = 'STACK' messages will be written to memory on
140 -- the message stack.
141 --
142 -- Same logic applies to Debug_Output_Code
143 --
144 -- When Debug_Flag = 'Y', debug mode is turned on.
145 --
146 -- HISTORY
147 -- 14-FEB-94 R Lee Created.
148 -- 28-FEB-94 R Lee Added argument Debug_Output_Code
149 -- 31-MAR-94 R Lee Added argument Debug_Flag
150 --
151 PROCEDURE Initialize(Output_Code VARCHAR2,
152 Conc_Request_Id NUMBER,
153 Debug_Flag VARCHAR2 Default 'N',
154 Debug_Output_Code VARCHAR2 Default 'STACK') IS
155 BEGIN
156 G_Conc_Request_Id := Conc_Request_Id;
157 G_Debug_Flag := Debug_Flag;
158 if (Upper(Debug_Output_Code) IN ('STACK', 'TABLE')) then
159 G_Debug_Output_Code := Debug_Output_Code;
160 else
161 G_Debug_Output_Code := 'STACK';
162 end if;
163 if (Upper(Output_Code) IN ('STACK', 'TABLE')) then
164 G_Output_Code := Output_Code;
165 else
166 --
167 -- Hardcoded message for the moment
168 --
169 Set_Line('Invalid Argument to Set_Output. ' ||
170 'Messages will be written to memory by default.');
171 G_Output_Code := 'STACK';
172 end if;
173 END;
174
175 --
176 -- NAME
177 -- Flush
178 --
179 -- PURPOSE
180 -- Ensures that all messages on the message stack that need to be
181 -- inserted into AS_CONC_REQUEST_MESSAGES are inserted.
182 --
183 --
184 PROCEDURE Flush IS
185 BEGIN
186 if ( (G_Output_Code = 'TABLE')
187 and (G_Ins_Message_Flag = 'Y')) then
188 Insert_Row(G_TMessage_Buffer(G_Msg_Count),
189 G_TMessage_Type(G_Msg_Count),
190 NULL);
191 G_Ins_Message_Flag := 'N';
192 end if;
193 END;
194
195 --
196 -- NAME
197 -- Put_Line
198 --
199 -- NOTES
200 -- Temporary function for backwards compatibility.
201 -- Use Set_Error instead.
202 --
203 PROCEDURE Put_Line(Message_Text IN VARCHAR2) IS
204 BEGIN
205 Set_Line(Message_Text, 'NO_TRANSLATE', NULL);
206 END;
207
208 --
209 -- NAME
210 -- Set_Line
211 --
212 -- PURPOSE
213 -- Puts a char string to Message Stack
214 --
215 PROCEDURE Set_Line(Message_Text IN VARCHAR2) IS
216 BEGIN
217 Set_Line(Message_Text, 'NO_TRANSLATE', NULL);
218 END;
219
220 --
221 -- NAME
222 -- Set_Name
223 --
224 -- PURPOSE
225 -- Puts an "encoded" message name on the Message Stack
226 --
227 PROCEDURE Set_Name(Appl_Short_Name IN VARCHAR2,
228 Message_Name IN VARCHAR2) IS
229 BEGIN
230 if ( (G_Ins_Message_Flag = 'Y')
231 and (G_Output_Code = 'TABLE')) then
232 Insert_Row(G_TMessage_Buffer(G_Msg_Count),
233 G_TMessage_Type(G_Msg_Count),
234 NULL);
235 end if;
236 G_Msg_Count := G_Msg_Count + 1;
237 G_TMessage_Buffer(G_Msg_Count) := Appl_Short_Name || ' ' || Message_Name;
238 G_TMessage_Type(G_Msg_Count) := 'TRANSLATE';
239 G_Ins_Message_Flag := 'Y';
240 END;
241
242 --
243 -- NAME
244 -- DEBUG
245 --
246 -- PURPOSE
247 -- Writes a debugging message to the Message Stack only if
248 -- the profile option value for AS_DEBUG = 'Y'.
249
250 PROCEDURE Debug(Message_Text IN VARCHAR2) IS
251 BEGIN
252 if (G_Debug_Flag = 'Y') then
253 Set_Line(Message_Text, 'DEBUG', NULL);
254 end if;
255 END;
256
257 --
258 -- NAME
259 -- Set_Token
260 --
261 -- PURPOSE
262 -- Add Token Information to the current message on the stack.
263 -- The current message must be of type 'TRANSLATE' for this
264 -- to work properly when the message is translated on the client,
265 -- although no serious errors will occur.
266 --
267 PROCEDURE Set_Token(Token_Name IN VARCHAR2,
268 Token_Value IN VARCHAR2,
269 Translate IN BOOLEAN Default False) IS
270 Trans_Label VARCHAR2(5);
271 BEGIN
272 if (Translate) then
273 Trans_Label := 'TRUE';
274 else
275 Trans_Label := 'FALSE';
276 end if;
277 G_TMessage_Buffer(G_Msg_Count)
278 := G_TMessage_Buffer(G_Msg_Count) || ' ' ||
279 Token_Name || ' \"' ||
280 Token_Value || '\" ' || Trans_Label;
281 END;
282
283 PROCEDURE Get(Message_Buf OUT VARCHAR2,
284 Message_Type OUT VARCHAR2,
285 Status OUT NUMBER) IS
286 BEGIN
287 if ( (G_Msg_Ptr > G_Msg_Count)
288 or (G_Msg_Count = 0)) then
289 Status := 0;
290 Clear;
291 else
292 Message_Buf := G_TMessage_Buffer(G_Msg_Ptr);
293 Message_Type := G_TMessage_Type(G_Msg_Ptr);
294 Status := LengthB(G_TMessage_Buffer(G_Msg_Ptr));
295 G_Msg_Ptr := G_Msg_Ptr + 1;
296 end if;
297 END;
298
299 --
300 -- NAME
301 -- Clear
302 --
303 -- PURPOSE
304 -- Frees memory used the the Message Stack and resets the
305 -- the Message Stack counter and pointer variables.
306 --
307 PROCEDURE Clear IS
308 BEGIN
309 G_TMessage_Buffer := G_TEmpty_Msg_Buffer;
310 G_TMessage_Type := G_TEmpty_Type;
311 G_Msg_Count := 0;
312 G_Msg_Ptr := 1;
313 END;
314
315 --
316 -- Temporary function for backwards compatibility.
317 -- Use Set_Error instead.
318 --
319 PROCEDURE Put_DB_Error(Routine IN VARCHAR2 Default NULL,
320 Context IN VARCHAR2 Default NULL) IS
321 BEGIN
322 Set_Error(Routine, Context);
323 END;
324
325 PROCEDURE Set_Error(Routine IN VARCHAR2 Default NULL,
326 Context IN VARCHAR2 Default NULL) IS
327 Delimiter1 VARCHAR2(3);
328 Delimiter2 VARCHAR2(3);
329 BEGIN
330 if (Routine is not NULL) then
331 Delimiter1 := ' : ';
332 end if;
333 if (Context is not NULL) then
334 Delimiter2 := ' : ';
335 end if;
336 Set_Line(Routine||Delimiter1||Context||Delimiter2||SQLERRM);
337 END;
338
339 FUNCTION Message_Count Return NUMBER IS
340 BEGIN
341 Return(G_Msg_Count);
342 END;
343
344 PROCEDURE Purge_Messages(X_Request_Id IN NUMBER) IS
345 BEGIN
346 DELETE from as_conc_request_messages
347 WHERE request_id = X_Request_Id;
348 COMMIT;
349 END;
350
351 FUNCTION Last_Message_Sequence Return NUMBER IS
352 CURSOR C_Last_Seq IS
353 SELECT max(conc_request_message_id)
354 FROM as_conc_request_messages
355 WHERE request_id = G_Conc_Request_Id;
356
357 Last_Msg_Seq NUMBER;
358
359 BEGIN
360 OPEN C_Last_Seq;
361 FETCH C_Last_Seq INTO Last_Msg_Seq;
362 CLOSE C_Last_Seq;
363 return(Last_Msg_Seq);
364
365 EXCEPTION
366 When OTHERS then
367 AS_MESSAGE.Set_Error('Last_Message_Sequence');
368 Raise;
369 END;
370
371 END AS_MESSAGE;