1 package body FND_RUN_FUNCTION as
2 /* $Header: AFRFB.pls 120.4.12020000.3 2013/02/21 09:14:50 absandhw 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 l_currRel varchar2(10);
194
195 cursor lc is select userenv('LANG') from dual;
196 begin
197
198 if ( p_function_id is null ) then
199 return null;
200 end if;
201
202 --
203 -- This mirrors what the equivalent java (see RunFunction.java) code
204 -- does (see bug 2942720), primarily for backwards compatibility.
205 --
206 l_db_id := fnd_profile.value_specific('APPS_DATABASE_ID', null, p_resp_id,
207 p_resp_appl_id, p_security_group_id);
208 if ( l_db_id is null ) then
209 l_db_id := fnd_web_config.database_id;
210 end if;
211
212 if ( p_override_agent is not null ) then
213 l_jsp_agent := fnd_web_config.trail_slash(p_override_agent);
214 else
215 l_jsp_agent := get_jsp_agent(p_resp_id, p_resp_appl_id,
216 p_security_group_id);
217 end if;
218
219
220 l_mac_data := 'RF.jsp?function_id=' || p_function_id ||
221 '&resp_id=' || NVL(p_resp_id, -1) ||
222 '&resp_appl_id=' || NVL(p_resp_appl_id, -1) ||
223 '&security_group_id=' || NVL(p_security_group_id, 0);
224 if ( p_org_id is not null ) then
225 l_mac_data := l_mac_data || '&org_id=' || p_org_id;
226 end if;
227
228 if ( p_lang_code is null ) then
229 open lc;
230 fetch lc into l_lang_code;
231 if ( lc%found ) then
232 l_mac_data := l_mac_data || '&lang_code=' || l_lang_code;
233 end if;
234 else
235 l_mac_data := l_mac_data || '&lang_code=' || p_lang_code;
236 end if;
237
238 if ( p_parameters is not null ) then
239 if ( p_encryptParameters ) then
240 l_mac_data := l_mac_data || '¶ms=' ||
241 fnd_web_sec.URLEncrypt(l_db_id,p_parameters);
242 else
243 l_mac_data := l_mac_data || '¶ms2=' ||
244 wfa_html.conv_special_url_chars(p_parameters);
245 end if;
246 end if;
247
248 l_url := l_jsp_agent || l_mac_data;
249
250 if ( fnd_session_management.g_session_id <> -1 ) then
251 l_session_id := fnd_session_management.g_session_id;
252 elsif ( icx_sec.g_session_id <> -1 ) then
253 l_session_id := icx_sec.g_session_id;
254 end if;
255
256 if ( l_session_id <> -1 ) then
257 -- Bug 14355908 : From 12.2.2, the profiles are being obsoleted.
258 -- The logic should be as if the profiles are having value as 'ERROR'
259
260 l_mac_enabled := fnd_profile.value('FND_VALIDATION_LEVEL');
261 l_mac_lite_enabled := fnd_profile.value('FND_FUNCTION_VALIDATION_LEVEL');
262
263 l_currRel := fnd_release.major_version || '.' || fnd_release.minor_version || '.' || fnd_release.point_version ;
264 if (l_currRel >= '12.2.2' OR ( l_mac_enabled <> 'NONE' or l_mac_lite_enabled <> 'NONE' )) then
265 l_mac_code := fnd_session_utilities.mac(l_mac_data, l_session_id);
266 return l_url || '&oas=' || l_mac_code;
267 end if;
268 end if;
269
270 --
271 -- if the session ID is not set or mac'ing is not enabled, just return the
272 -- url without the mac code.
273 --
274 return l_url;
275 end;
276
277
278 --
279 -- Version of get_run_function_url that takes names instead of ID's.
280 --
281 function get_run_function_url ( p_function_name in varchar2,
282 p_resp_appl in varchar2,
283 p_resp_key in varchar2,
284 p_security_group_key in varchar2,
285 p_parameters in varchar2 default null,
286 p_override_agent in varchar2 default null,
287 p_org_id in number default null,
288 p_lang_code in varchar2 default null,
289 p_encryptParameters in boolean default true )
290 return varchar2 is
291 l_function_id number;
292 l_resp_appl_id number;
293 l_resp_id number;
294 l_secgrp_id number;
295 l_status boolean;
296 begin
297 l_status := lookup_context(p_function_name,
298 p_resp_appl, p_resp_key,
299 p_security_group_key,
300 l_function_id,
301 l_resp_appl_id, l_resp_id,
302 l_secgrp_id);
303 if ( not l_status ) then
304 return null;
305 else
306 return get_run_function_url(l_function_id, l_resp_appl_id, l_resp_id,
307 l_secgrp_id, p_parameters, p_override_agent,
308 p_org_id, p_lang_code, p_encryptParameters);
309 end if;
310 end;
311
312
313 --
314 -- Generates a link automatically - returns HTML of the form
315 -- <a href=...> .. </a>
316 -- which will run the specified function in the given responsibility.
317 --
318 -- If called on a function of type 'FORM', make sure the output from
319 -- 'get_forms_launcher_setup' is printed out first.
320 --
321 function get_run_function_link ( p_text in varchar2,
322 p_target in varchar2,
323 p_function_id in number,
324 p_resp_appl_id in number,
325 p_resp_id in number,
326 p_security_group_id in number,
327 p_parameters in varchar2 default null,
328 p_override_agent in varchar2 default null,
329 p_org_id in number default null,
330 p_lang_code in varchar2 default null,
331 p_encryptParameters in boolean default true )
332 return varchar2 is
333 l_url varchar2(2000);
334 l_mouse_over_text varchar2(2000);
335 l_function_type varchar2(30);
336 l_user_function_name varchar2(80);
337 l_form_id number;
338
339 cursor c1 is select type, user_function_name, form_id
340 from fnd_form_functions_vl
341 where function_id = p_function_id;
342 begin
343 if ( p_function_id is null ) then
344 return null;
345 end if;
346
347 open c1;
348 fetch c1 into l_function_type, l_user_function_name, l_form_id;
349 if ( c1%notfound ) then
350 return null;
351 end if;
352
353 l_url := get_run_function_url(p_function_id, p_resp_appl_id, p_resp_id,
354 p_security_group_id, p_parameters,
355 p_override_agent, p_org_id, p_lang_code,
356 p_encryptParameters);
357
358 --
359 -- Display the user function name when mousing over the generated link.
360 --
361 l_mouse_over_text := 'onMouseOver="window.status=''' ||
362 replace_onMouseOver_quotes(l_user_function_name) ||
363 '''; return true"';
364
365 --
366 -- See bug 2767549 - the function type column for compatibility reasons
367 -- has not been validated, so the values may not be correct. We can't
368 -- handle every possible invalid combination, but try to at least
369 -- be robust about handling FORM functions, since the old Forms
370 -- navigator didn't check for function type either, it just checked
371 -- the form_id.
372 --
373 if ( l_function_type is null and l_form_id is not null ) then
374 l_function_type := 'FORM';
375 end if;
376
377 --
378 -- FORM functions need to call the javascript that is generated
379 -- by the 'get_forms_launcher_setup' function above.
380 --
381 if ( l_function_type = 'FORM' ) then
382 l_url := l_url || '&prompt=yes';
383 return '<a href="javascript:launchForm(''' || l_url || ''')" ' ||
384 l_mouse_over_text || '>' || p_text || '</a>';
385
386 --
387 -- Functions of type WWK need to be opened in a separate window.
388 --
389 elsif ( l_function_type = 'WWK') then
390 return '<a href="javascript:void window.open(''' || l_url ||
391 ''',''function_window'',''status=yes,resizable=yes,' ||
392 'scrollbars=yes,menubar=no,toolbar=no'')" TARGET=''' ||
393 p_target || ''' ' || l_mouse_over_text || '>' || p_text || '</a>';
394
395 --
396 -- All other types generate a simple link. Note that this includes
397 -- invalid function types, the link will get generated and we'll
398 -- just let it pass on through to the eventual RF.jsp call.
399 --
400 else
401 return '<a href="' || l_url || '" target=' || p_target || ' ' ||
402 l_mouse_over_text || '>' || p_text || '</a>';
403 end if;
404 end;
405
406
407 --
408 -- Version of get_run_function_link that takes names instead of ID's.
409 --
410 function get_run_function_link ( p_text in varchar2,
411 p_target in varchar2,
412 p_function_name in varchar2,
413 p_resp_appl in varchar2,
414 p_resp_key in varchar2,
415 p_security_group_key in varchar2,
416 p_parameters in varchar2 default null,
417 p_override_agent in varchar2 default null,
418 p_org_id in number default null,
419 p_lang_code in varchar2 default null,
420 p_encryptParameters in boolean default true )
421 return varchar2 is
422 l_function_id number;
423 l_resp_appl_id number;
424 l_resp_id number;
425 l_secgrp_id number;
426 l_status boolean;
427 begin
428 l_status := lookup_context(p_function_name,
429 p_resp_appl, p_resp_key,
430 p_security_group_key,
431 l_function_id,
432 l_resp_appl_id, l_resp_id,
433 l_secgrp_id);
434
435 if ( not l_status ) then
436 return null;
437 else
438 return get_run_function_link(p_text, p_target, l_function_id,
439 l_resp_appl_id, l_resp_id,
440 l_secgrp_id, p_parameters,
441 p_override_agent, p_org_id, p_lang_code,
442 p_encryptParameters);
443 end if;
444 end;
445
446 end FND_RUN_FUNCTION;