1 package body FND_RUN_FUNCTION as
2 /* $Header: AFRFB.pls 120.4 2006/09/16 00:10:01 rou ship $ */
3
4 --
5 -- Helper function to escape quotes
6 -- Copied from an ICX_UTIL routine
7 --
8 function replace_onMouseOver_quotes(p_string in varchar2) return varchar2 is
9 temp_string varchar2(32000);
10 begin
11 -- replace single quotes
12 temp_string := replace(p_string,'''','\''');
13 temp_string := replace(temp_string,'"','`"');
14 -- check for double escapes
15 temp_string := replace(temp_string,'\\','\');
16 return temp_string;
17 end replace_onMouseOver_quotes;
18
19
20 --
21 -- Helper function, given the names of the function, responsibility,
22 -- and security group, it returns the corresponding ID's.
23 --
24 function lookup_context ( p_function_name in varchar2,
25 p_resp_appl in varchar2,
26 p_resp_key in varchar2,
27 p_security_group_key in varchar2,
28 p_function_id out nocopy number,
29 p_resp_appl_id out nocopy number,
30 p_resp_id out nocopy number,
31 p_security_group_id out nocopy number )
32 return boolean is
33 cursor c_func is select function_id from fnd_form_functions
34 where function_name = p_function_name;
35 cursor c_app is select application_id from fnd_application
36 where application_short_name = p_resp_appl;
37 cursor c_resp is select responsibility_id from fnd_responsibility
38 where responsibility_key = p_resp_key;
39 cursor c_sec is select security_group_id from fnd_security_groups
40 where security_group_key = p_security_group_key;
41 begin
42 open c_func;
43 fetch c_func into p_function_id;
44 if ( c_func%notfound ) then
45 close c_func;
46 return false;
47 end if;
48 close c_func;
49
50 --
51 -- if null is passed in for the responsibility, use -1 for the ID's.
52 --
53 if ( p_resp_appl is null and p_resp_key is null ) then
54 p_resp_appl_id := -1;
55 p_resp_id := -1;
56 else
57 open c_app;
58 fetch c_app into p_resp_appl_id;
59 if ( c_app%notfound ) then
60 close c_app;
61 return false;
62 end if;
63 close c_app;
64
65 open c_resp;
66 fetch c_resp into p_resp_id;
67 if ( c_resp%notfound ) then
68 close c_resp;
69 return false;
70 end if;
71 close c_resp;
72 end if;
73
74 --
75 -- if null is passed in for the security group, use 0.
76 --
77 if ( p_security_group_key is null ) then
78 p_security_group_id := 0;
79 else
80 open c_sec;
81 fetch c_sec into p_security_group_id;
82 if ( c_sec%notfound ) then
83 close c_sec;
84 return false;
85 end if;
86 close c_sec;
87 end if;
88
89 return true;
90 end;
91
92
93 --
94 -- copied from fnd_web_config, but this version uses a call to
95 -- fnd_profile.value_specific when getting the APPS_SERVLET_AGENT
96 --
97 function GET_JSP_AGENT ( p_resp_id number,
98 p_resp_appl_id number,
99 p_security_group_id number )
100 return VARCHAR2 is
101 agent_url varchar2(2000) := NULL;
102 index1 number;
103 index2 number;
104 begin
105 agent_url := fnd_profile.value_specific('APPS_SERVLET_AGENT',
106 null,
107 p_resp_id,
108 p_resp_appl_id,
109 p_security_group_id);
110 if (agent_url is null) then
111 FND_MESSAGE.SET_NAME('FND', 'PROFILES-CANNOT READ');
112 FND_MESSAGE.SET_TOKEN('OPTION','APPS_SERVLET_AGENT');
113 return NULL;
114 end if;
115
116 agent_url := FND_WEB_CONFIG.TRAIL_SLASH(agent_url);
117
118 index1 := INSTRB(agent_url, '//', 1) + 2; /* skip 'http://' */
119
120 index2 := INSTRB(agent_url, '/', index1); /* get to 'http://serv:port/' */
121
122 if(index1 <> index2) AND (index1 <> 2) AND (index2 > 2)
123 AND (index1 is not NULL) AND (index2 is not NULL) then
124 return FND_WEB_CONFIG.TRAIL_SLASH(SUBSTRB(agent_url, 1, index2-1)) ||
125 'OA_HTML/';
126 else
127 /* Incorrect format; give an error message */
128 FND_MESSAGE.SET_NAME('FND', 'AF_WCFG_BAD_AGENT_URL_FORMAT');
129 FND_MESSAGE.SET_TOKEN('URL', agent_url);
130 FND_MESSAGE.SET_TOKEN('PROFILE', 'APPS_SERVLET_AGENT');
131 FND_MESSAGE.SET_TOKEN('FORMAT', 'http://server[:port]/');
132 return NULL;
133 end if;
134
135 end GET_JSP_AGENT;
136
137
138 --
139 -- Returns iframe and JavaScript initialization code needed by the
140 -- Forms Launcher.
141 --
142 function get_forms_launcher_setup return varchar2 is
143 begin
144 return
145 '<iframe name=formsLauncher src="/OA_HTML/blank.html" title=""
146 height=5px width=5px scrolling=no frameborder=no></iframe>
147 <script>
148 function launchForm (url)
149 {
150 if ( navigator.appName == "Netscape" )
151 {
152 open(url, "formsWindow");
153 }
154 else
155 {
156 formsLauncher.location.replace(url + "&formsLink=yes");
157 }
158 }
159 </script>';
160 end;
161
162
163 --
164 -- Returns the URL to run the specified function in the given responsibility.
165 -- If null is passed in for the responsibility default to -1. The security
166 -- group should be passed in, but if not default to 0 for backwards
167 -- compatibility (see bug 3353820).
168 --
169 -- Unlike its java counterpart, for WWK functions this does not
170 -- return a javascript call - the existing ICX code which currently
171 -- calls these api's already adds the javascript portion on itself.
172 -- The get_run_function_link api's do add the javascript as well.
173 --
174 function get_run_function_url ( p_function_id in number,
175 p_resp_appl_id in number,
176 p_resp_id in number,
177 p_security_group_id in number,
178 p_parameters in varchar2 default null,
179 p_override_agent in varchar2 default null,
180 p_org_id in number default null,
181 p_lang_code in varchar2 default null,
182 p_encryptParameters in boolean default true )
183 return varchar2 is
184 l_db_id varchar2(255);
185 l_jsp_agent varchar2(2000);
186 l_url varchar2(2000);
187 l_mac_enabled varchar2(255);
188 l_mac_lite_enabled varchar2(255);
189 l_mac_data varchar2(2000);
190 l_mac_code varchar2(2000);
191 l_session_id number := -1;
192 l_lang_code varchar2(62);
193
194 cursor lc is select userenv('LANG') from dual;
195 begin
196
197 if ( p_function_id is null ) then
198 return null;
199 end if;
200
201 --
202 -- This mirrors what the equivalent java (see RunFunction.java) code
203 -- does (see bug 2942720), primarily for backwards compatibility.
204 --
205 l_db_id := fnd_profile.value_specific('APPS_DATABASE_ID', null, p_resp_id,
206 p_resp_appl_id, p_security_group_id);
207 if ( l_db_id is null ) then
208 l_db_id := fnd_web_config.database_id;
209 end if;
210
211 if ( p_override_agent is not null ) then
212 l_jsp_agent := fnd_web_config.trail_slash(p_override_agent);
213 else
214 l_jsp_agent := get_jsp_agent(p_resp_id, p_resp_appl_id,
215 p_security_group_id);
216 end if;
217
218
219 l_mac_data := 'RF.jsp?function_id=' || p_function_id ||
220 '&resp_id=' || NVL(p_resp_id, -1) ||
221 '&resp_appl_id=' || NVL(p_resp_appl_id, -1) ||
222 '&security_group_id=' || NVL(p_security_group_id, 0);
223 if ( p_org_id is not null ) then
224 l_mac_data := l_mac_data || '&org_id=' || p_org_id;
225 end if;
226
227 if ( p_lang_code is null ) then
228 open lc;
229 fetch lc into l_lang_code;
230 if ( lc%found ) then
231 l_mac_data := l_mac_data || '&lang_code=' || l_lang_code;
232 end if;
233 else
234 l_mac_data := l_mac_data || '&lang_code=' || p_lang_code;
235 end if;
236
237 if ( p_parameters is not null ) then
238 if ( p_encryptParameters ) then
239 l_mac_data := l_mac_data || '¶ms=' ||
240 fnd_web_sec.URLEncrypt(l_db_id,p_parameters);
241 else
242 l_mac_data := l_mac_data || '¶ms2=' ||
243 wfa_html.conv_special_url_chars(p_parameters);
244 end if;
245 end if;
246
247 l_url := l_jsp_agent || l_mac_data;
248
249 if ( fnd_session_management.g_session_id <> -1 ) then
250 l_session_id := fnd_session_management.g_session_id;
251 elsif ( icx_sec.g_session_id <> -1 ) then
252 l_session_id := icx_sec.g_session_id;
253 end if;
254
255 if ( l_session_id <> -1 ) then
256 l_mac_enabled := fnd_profile.value('FND_VALIDATION_LEVEL');
257 l_mac_lite_enabled := fnd_profile.value('FND_FUNCTION_VALIDATION_LEVEL');
258 if ( l_mac_enabled <> 'NONE' or l_mac_lite_enabled <> 'NONE' ) then
259 l_mac_code := fnd_session_utilities.mac(l_mac_data, l_session_id);
260 return l_url || '&oas=' || l_mac_code;
261 end if;
262 end if;
263
264 --
265 -- if the session ID is not set or mac'ing is not enabled, just return the
266 -- url without the mac code.
267 --
268 return l_url;
269 end;
270
271
272 --
273 -- Version of get_run_function_url that takes names instead of ID's.
274 --
275 function get_run_function_url ( p_function_name in varchar2,
276 p_resp_appl in varchar2,
277 p_resp_key in varchar2,
278 p_security_group_key in varchar2,
279 p_parameters in varchar2 default null,
280 p_override_agent in varchar2 default null,
281 p_org_id in number default null,
282 p_lang_code in varchar2 default null,
283 p_encryptParameters in boolean default true )
284 return varchar2 is
285 l_function_id number;
286 l_resp_appl_id number;
287 l_resp_id number;
288 l_secgrp_id number;
289 l_status boolean;
290 begin
291 l_status := lookup_context(p_function_name,
292 p_resp_appl, p_resp_key,
293 p_security_group_key,
294 l_function_id,
295 l_resp_appl_id, l_resp_id,
296 l_secgrp_id);
297 if ( not l_status ) then
298 return null;
299 else
300 return get_run_function_url(l_function_id, l_resp_appl_id, l_resp_id,
301 l_secgrp_id, p_parameters, p_override_agent,
302 p_org_id, p_lang_code, p_encryptParameters);
303 end if;
304 end;
305
306
307 --
308 -- Generates a link automatically - returns HTML of the form
309 -- <a href=...> .. </a>
310 -- which will run the specified function in the given responsibility.
311 --
312 -- If called on a function of type 'FORM', make sure the output from
313 -- 'get_forms_launcher_setup' is printed out first.
314 --
315 function get_run_function_link ( p_text in varchar2,
316 p_target in varchar2,
317 p_function_id in number,
318 p_resp_appl_id in number,
319 p_resp_id in number,
320 p_security_group_id in number,
321 p_parameters in varchar2 default null,
322 p_override_agent in varchar2 default null,
323 p_org_id in number default null,
324 p_lang_code in varchar2 default null,
325 p_encryptParameters in boolean default true )
326 return varchar2 is
327 l_url varchar2(2000);
328 l_mouse_over_text varchar2(2000);
329 l_function_type varchar2(30);
330 l_user_function_name varchar2(80);
331 l_form_id number;
332
333 cursor c1 is select type, user_function_name, form_id
334 from fnd_form_functions_vl
335 where function_id = p_function_id;
336 begin
337 if ( p_function_id is null ) then
338 return null;
339 end if;
340
341 open c1;
342 fetch c1 into l_function_type, l_user_function_name, l_form_id;
343 if ( c1%notfound ) then
344 return null;
345 end if;
346
347 l_url := get_run_function_url(p_function_id, p_resp_appl_id, p_resp_id,
348 p_security_group_id, p_parameters,
349 p_override_agent, p_org_id, p_lang_code,
350 p_encryptParameters);
351
352 --
353 -- Display the user function name when mousing over the generated link.
354 --
355 l_mouse_over_text := 'onMouseOver="window.status=''' ||
356 replace_onMouseOver_quotes(l_user_function_name) ||
357 '''; return true"';
358
359 --
360 -- See bug 2767549 - the function type column for compatibility reasons
361 -- has not been validated, so the values may not be correct. We can't
362 -- handle every possible invalid combination, but try to at least
363 -- be robust about handling FORM functions, since the old Forms
364 -- navigator didn't check for function type either, it just checked
365 -- the form_id.
366 --
367 if ( l_function_type is null and l_form_id is not null ) then
368 l_function_type := 'FORM';
369 end if;
370
371 --
372 -- FORM functions need to call the javascript that is generated
373 -- by the 'get_forms_launcher_setup' function above.
374 --
375 if ( l_function_type = 'FORM' ) then
376 l_url := l_url || '&prompt=yes';
377 return '<a href="javascript:launchForm(''' || l_url || ''')" ' ||
378 l_mouse_over_text || '>' || p_text || '</a>';
379
380 --
381 -- Functions of type WWK need to be opened in a separate window.
382 --
383 elsif ( l_function_type = 'WWK') then
384 return '<a href="javascript:void window.open(''' || l_url ||
385 ''',''function_window'',''status=yes,resizable=yes,' ||
386 'scrollbars=yes,menubar=no,toolbar=no'')" TARGET=''' ||
387 p_target || ''' ' || l_mouse_over_text || '>' || p_text || '</a>';
388
389 --
390 -- All other types generate a simple link. Note that this includes
391 -- invalid function types, the link will get generated and we'll
392 -- just let it pass on through to the eventual RF.jsp call.
393 --
394 else
395 return '<a href="' || l_url || '" target=' || p_target || ' ' ||
396 l_mouse_over_text || '>' || p_text || '</a>';
397 end if;
398 end;
399
400
401 --
402 -- Version of get_run_function_link that takes names instead of ID's.
403 --
404 function get_run_function_link ( p_text in varchar2,
405 p_target in varchar2,
406 p_function_name in varchar2,
407 p_resp_appl in varchar2,
408 p_resp_key in varchar2,
409 p_security_group_key in varchar2,
410 p_parameters in varchar2 default null,
411 p_override_agent in varchar2 default null,
412 p_org_id in number default null,
413 p_lang_code in varchar2 default null,
414 p_encryptParameters in boolean default true )
415 return varchar2 is
416 l_function_id number;
417 l_resp_appl_id number;
418 l_resp_id number;
419 l_secgrp_id number;
420 l_status boolean;
421 begin
422 l_status := lookup_context(p_function_name,
423 p_resp_appl, p_resp_key,
424 p_security_group_key,
425 l_function_id,
426 l_resp_appl_id, l_resp_id,
427 l_secgrp_id);
428
429 if ( not l_status ) then
430 return null;
431 else
432 return get_run_function_link(p_text, p_target, l_function_id,
433 l_resp_appl_id, l_resp_id,
434 l_secgrp_id, p_parameters,
435 p_override_agent, p_org_id, p_lang_code,
436 p_encryptParameters);
437 end if;
438 end;
439
440 end FND_RUN_FUNCTION;