1 package body PV_MESSAGE as
2 /* $Header: pvxvmsgb.pls 115.6 2002/12/11 10:41:58 anubhavk ship $ */
3
4 MSGNAME varchar2(30);
5 MSGDATA varchar2(2000);
6 MSGSET boolean := FALSE;
7 MSGAPP varchar2(50);
8
9
10 procedure SET_NAME(APPLICATION in varchar2, NAME in varchar2) is
11 begin
12 MSGAPP := APPLICATION;
13 MSGNAME := NAME;
14 MSGDATA := '';
15 MSGSET := TRUE;
16 end;
17
18
19 procedure SET_TOKEN(TOKEN in varchar2,
20 VALUE in varchar2,
21 TRANSLATE in boolean default false) is
22 FLAG varchar2(1);
23 begin
24 if TRANSLATE then
25 FLAG := 'Y';
26 else
27 FLAG := 'N';
28 end if;
29 /* Note that we are intentionally using chr(0) rather than */
30 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
31 MSGDATA := MSGDATA||FLAG||' '||TOKEN||' '||VALUE||' ';
32 end set_token;
33
34 /* This procedure is only to be called by the ATG; */
35 /* not for external use */
36 procedure RETRIEVE(MSGOUT out nocopy varchar2) is
37 OUT_VAL varchar2(2000);
38 begin
39 if MSGSET then
40 /* Note that we are intentionally using chr(0) rather than */
41 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
42 OUT_VAL := MSGAPP||chr(0)||MSGNAME||chr(0)||MSGDATA;
43 MSGSET := FALSE;
44 else
45 OUT_VAL := '';
46 end if;
47
48 MSGOUT := OUT_VAL;
49 end;
50
51 procedure CLEAR is
52 begin
53 msgset := FALSE;
54 end;
55
56 procedure RAISE_ERROR is
57 begin
58 /* Note that we are intentionally using chr(0) rather than */
59 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
60 raise_application_error(-20001,
61 MSGNAME||': '||replace(rtrim(MSGDATA,chr(0)),
62 chr(0), ', '));
63 end;
64
65 /*
66 ** GET_STRING- get a particular translated message
67 ** from the message dictionary database.
68 **
69 ** This is a one-call interface for when you just want to get a
70 ** message without doing any token substitution.
71 ** Returns NAMEIN (Msg name) if the message cannot be found.
72 */
73 function GET_STRING(APPIN in varchar2,
74 NAMEIN in varchar2) return varchar2 is
75 MSG varchar2(2000) := NULL;
76 cursor c1(NAME_ARG varchar2) is select message_text
77 from fnd_new_messages m, fnd_application a
78 where NAME_ARG = m.message_name
79 and m.language_code = userenv('LANG')
80 and APPIN = a.application_short_name
81 and m.application_id = a.application_id;
82 cursor c2(NAME_ARG varchar2) is select message_text
83 from fnd_new_messages m, fnd_application a
84 where NAME_ARG = m.message_name
85 and 'US' = m.language_code
86 and APPIN = a.application_short_name
87 and m.application_id = a.application_id;
88 begin
89 /* get the message text out nocopy of the table */
90 open c1(UPPER(NAMEIN));
91 fetch c1 into MSG;
92 if (c1%NOTFOUND) then
93 open c2(UPPER(NAMEIN));
94 fetch c2 into MSG;
95 if (c2%NOTFOUND) then
96 MSG := NAMEIN;
97 end if;
98 close c2;
99 end if;
100 close c1;
101 /* double ampersands don't have anything to do with tokens, they */
102 /* represent access keys. So we translate them to single ampersands*/
103 /* so that the access key code will recognize them. */
104 MSG := substrb(REPLACE(MSG, '&&', '&'),1,2000);
105 return MSG;
106 end;
107
108 /*
109 ** GET_NUMBER- get the message number of a particular message.
110 **
111 ** This routine returns only the message number, given a message
112 ** name. This routine will be only used in rare cases; normally
113 ** the message name will get displayed automatically by message
114 ** dictionary when outputting a message on the client.
115 **
116 ** You should _not_ use this routine to construct a system for
117 ** storing translated messages (along with numbers) on the server.
118 ** If you need to store translated messages on a server for later
119 ** display on a client, use the set_encoded/get_encoded routines
120 ** to store the messages as untranslated, encoded messages.
121 **
122 ** If you don't know the name of the message on the stack, you
123 ** can use get_encoded and parse_encoded to find it out.
124 **
125 ** Returns 0 if the message has no message number,
126 ** or if its message number is zero.
127 ** NULL if the message can't be found.
128 */
129 function GET_NUMBER(APPIN in varchar2,
130 NAMEIN in varchar2) return NUMBER is
131 MSG_NUM NUMBER := NULL;
132 cursor c1(NAME_ARG varchar2) is select message_number
133 from fnd_new_messages m, fnd_application a
134 where NAME_ARG = m.message_name
135 and m.language_code = userenv('LANG')
136 and APPIN = a.application_short_name
137 and m.application_id = a.application_id;
138 cursor c2(NAME_ARG varchar2) is select message_number
139 from fnd_new_messages m, fnd_application a
140 where NAME_ARG = m.message_name
141 and 'US' = m.language_code
142 and APPIN = a.application_short_name
143 and m.application_id = a.application_id;
144 begin
145 /* get the message text out nocopy of the table */
146 open c1(UPPER(NAMEIN));
147 fetch c1 into MSG_NUM;
148 if(MSG_NUM is NULL) then
149 MSG_NUM := 0;
150 end if;
151 if (c1%NOTFOUND) then
152 open c2(UPPER(NAMEIN));
153 fetch c2 into MSG_NUM;
154 if(MSG_NUM is NULL) then
155 MSG_NUM := 0;
156 end if;
157 if (c2%NOTFOUND) then
158 MSG_NUM := NULL;
159 end if;
160 close c2;
161 end if;
162 close c1;
163 return MSG_NUM;
164 end;
165
166
167
168 /*
169 ** GET- get a translated and token substituted message
170 ** from the message dictionary database.
171 ** Returns NULL if the message cannot be found.
172 */
173 function GET return varchar2 is
174 MSG varchar2(2000);
175 TOK_NAM varchar2(30);
176 TOK_VAL varchar2(2000);
177 SRCH varchar2(2000);
178 FLAG varchar2(1);
179 POS NUMBER;
180 NEXTPOS NUMBER;
181 DATA_SIZE NUMBER;
182 TSLATE BOOLEAN;
183 begin
184 if (not MSGSET) then
185 MSG := '';
186 return MSG;
187 end if;
188 MSG := GET_STRING(MSGAPP, MSGNAME);
189 if ((msg is NULL) OR (msg = '')) then
190 MSG := MSGNAME;
191 end if;
192 POS := 1;
193 DATA_SIZE := LENGTH(MSGDATA);
194 while POS < DATA_SIZE loop
195 FLAG := SUBSTR(MSGDATA, POS, 1);
196 POS := POS + 2;
197 /* Note that we are intentionally using chr(0) rather than */
198 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
199 NEXTPOS := INSTR(MSGDATA, chr(0), POS);
200 TOK_NAM := SUBSTR(MSGDATA, POS, NEXTPOS - POS);
201 POS := NEXTPOS + 1;
202 NEXTPOS := INSTR(MSGDATA, chr(0), POS);
203 TOK_VAL := SUBSTR(MSGDATA, POS, NEXTPOS - POS);
204 POS := NEXTPOS + 1;
205
206 if (FLAG = 'Y') then /* translated token */
207 TOK_VAL := GET_STRING(MSGAPP, TOK_VAL);
208 end if;
209 SRCH := '&' || TOK_NAM;
210 if (INSTR(MSG, SRCH) <> 0) then
211 MSG := substrb(REPLACE(MSG, SRCH, TOK_VAL),1,2000);
212 else
213 /* try the uppercased version of the token name in case */
214 /* the caller is (wrongly) passing a mixed case token name */
215 /* Because now (July 99) all tokens in msg text should be */
216 /* uppercase. */
217 SRCH := '&' || UPPER(TOK_NAM);
218 if (INSTR(MSG, SRCH) <> 0) then
219 MSG := substrb(REPLACE(MSG, SRCH, TOK_VAL),1,2000);
220 else
221 MSG :=substrb(MSG||' ('||TOK_NAM||'='||TOK_VAL||')',1,2000);
222 end if;
223 end if;
224 END LOOP;
225 /* double ampersands don't have anything to do with tokens, they */
226 /* represent access keys. So we translate them to single ampersands*/
227 /* so that the access key code will recognize them. */
228 MSG := substrb(REPLACE(MSG, '&&', '&'),1,2000);
229 MSGSET := FALSE;
230 return MSG;
231 end;
232
233 function GET_ENCODED return varchar2 is
234 begin
235 if MSGSET then
236 MSGSET := FALSE;
237 /* Note that we are intentionally using chr(0) rather than */
238 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
239 return (MSGAPP|| ' '||MSGNAME|| ' '|| MSGDATA);
240 else
241 return ('');
242 end if;
243 end;
244
245
246 /*
247 ** SET_ENCODED- Set an encoded message onto the message stack
248 */
249 procedure SET_ENCODED(ENCODED_MESSAGE IN varchar2) is
250 POS NUMBER;
251 NEXTPOS NUMBER;
252 begin
253 POS := 1;
254
255 /* Note that we are intentionally using chr(0) rather than */
256 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
257 NEXTPOS := INSTR(ENCODED_MESSAGE, chr(0), POS);
258 MSGAPP := SUBSTR(ENCODED_MESSAGE, POS, NEXTPOS - POS);
259 POS := NEXTPOS + 1;
260
261 NEXTPOS := INSTR(ENCODED_MESSAGE, chr(0), POS);
262 MSGNAME := SUBSTR(ENCODED_MESSAGE, POS, NEXTPOS - POS);
263 POS := NEXTPOS + 1;
264
265 MSGDATA := SUBSTR(ENCODED_MESSAGE, POS);
266
267 if((MSGAPP is not null) and (MSGNAME is not null)) then
268 MSGSET := TRUE;
269 end if;
270 end;
271
272
273 /*
274 ** PARSE_ENCODED- Parse the message name and application short name
275 ** out nocopy of a message in "encoded" format.
276 */
277 procedure PARSE_ENCODED(ENCODED_MESSAGE IN varchar2,
278 APP_SHORT_NAME OUT NOCOPY varchar2,
279 MESSAGE_NAME OUT NOCOPY varchar2) is
280 POS NUMBER;
281 NEXTPOS NUMBER;
282 begin
283 null;
284 POS := 1;
285
286 /* Note that we are intentionally using chr(0) rather than */
287 /* FND_GLOBAL.LOCAL_CHR() for a performance bug (982909) */
288 NEXTPOS := INSTR(ENCODED_MESSAGE, chr(0), POS);
289 APP_SHORT_NAME := SUBSTR(ENCODED_MESSAGE, POS, NEXTPOS - POS);
290 POS := NEXTPOS + 1;
291
292 NEXTPOS := INSTR(ENCODED_MESSAGE, chr(0), POS);
293 MESSAGE_NAME := SUBSTR(ENCODED_MESSAGE, POS, NEXTPOS - POS);
294 POS := NEXTPOS + 1;
295 end;
296
297 end pv_message;