DBA Data[Home] [Help]

PACKAGE BODY: APPS.WF_BES_CACHE

Source


1 package body WF_BES_CACHE as
2 /* $Header: WFBECACB.pls 120.7.12020000.2 2012/10/30 13:14:25 alsosa ship $ */
3 
4 /*---------+
5  | Globals |
6  +---------*/
7 g_Event_Idx  number := 1;
8 g_Agent_Idx  number := 2;
9 g_System_Idx number := 3;
10 
11 g_event_const  varchar2(30) := 'EVENTS';
12 g_agent_const  varchar2(30) := 'AGENTS';
13 g_system_const varchar2(30) := 'SYSTEMS';
14 
15 g_src_type_local    varchar2(8) := 'LOCAL';
16 g_src_type_external varchar2(8) := 'EXTERNAL';
17 g_src_type_error    varchar2(8) := 'ERROR';
18 
19 g_event_any         varchar2(240) := 'oracle.apps.wf.event.any';
20 g_event_unexpected  varchar2(240) := 'oracle.apps.wf.event.unexpected';
21 
22 g_java_sub     varchar2(240) := 'java://';
23 
24 g_status_yes   varchar2(1) := 'Y';
25 g_status_no    varchar2(1) := 'N';
26 
27 g_date_mask    varchar2(26) := 'YYYY/MM/DD HH24:MI:SS';
28 
29 g_initialized  boolean := false;
30 
31 -- Initialize (PRIVATE)
32 --   Procedure to initialize the cache management related variables like
33 --   cache size, hash size etc.
34 procedure Initialize
35 is
36   l_cache_size number;
37 begin
38   if (g_initialized) then
39     return;
40   end if;
41 
42   -- the token value may not have been loaded, null or may be a non-numeric
43   -- value specified. in such cases, default it to 50.
44   begin
45     l_cache_size := to_number(wf_core.translate('WFBES_MAX_CACHE_SIZE'));
46   exception
47     when others then
48       l_cache_size := 50;
49   end;
50 
51   wf_object_cache.SetCacheSize(l_cache_size);
52 
53   g_local_system_guid := hextoraw(wf_core.translate('WF_SYSTEM_GUID'));
54   g_local_system_status := wf_core.translate('WF_SYSTEM_STATUS');
55   g_schema_name       := wf_core.translate('WF_SCHEMA');
56   begin
57     SELECT name
58     INTO   g_local_system_name
59     FROM   wf_systems
60     WHERE  guid = g_local_system_guid;
61   exception
62     when no_data_found then
63       g_local_system_name := null;
64   end;
65   g_initialized := true;
66 end Initialize;
67 
68 -- SetMetaDataUploaded
69 --   This procedure is called from the BES table handlers when meta-data
70 --   is being uploaded to the database tables. This procedure sets a BES
71 --   caching context with the sysdate when the meta-data is loaded.
72 procedure SetMetaDataUploaded
73 is
74   --Bug 14602624. Deferred agent listener runs by under the SYSADMIN schema. It
75   --needs to be set for name spaces not to get lost
76   l_username FND_USER.USER_NAME%TYPE := nvl(FND_GLOBAL.user_name,'SYSADMIN');
77 begin
78   dbms_session.set_context(namespace => 'WFBES_CACHE_CTX',
79                            attribute => 'WFBES_METADATA_UPLOADED',
80                            value     => to_char(sysdate, g_date_mask),
81                            client_id => l_username);
82 exception
83   when others then
84     wf_core.context('WF_BES_CACHE', 'MetaDataUploaded');
85     raise;
86 end SetMetaDataUploaded;
87 
88 -- GetMetaDataUploaded (PRIVATE)
89 --   This function returns the date at which BES meta-data was last uploaded
90 --   to the database after the session's cache was initialized.
91 function GetMetaDataUploaded
92 return date
93 is
94   l_value varchar2(4000);
95 begin
96   l_value := sys_context('WFBES_CACHE_CTX', 'WFBES_METADATA_UPLOADED');
97   return to_date(l_value, g_date_mask);
98 exception
99   when others then
100     wf_core.context('WF_BES_CACHE', 'GetMetaDataUploaded');
101     raise;
102 end GetMetaDataUploaded;
103 
104 -- SetMetaDataCached (PRIVATE)
105 --   This procedure is called when cache is created to set the timestamp
106 --   at which the cache is initialized for this session
107 procedure SetMetaDataCached(p_date in date)
108 is
109 begin
110   -- If the date is already set in this session, do not set it again
111   -- or if the p_date is null, we want to reset the last cache update
112   if (g_LastCacheUpdate is null or p_date is null) then
113     g_LastCacheUpdate := p_date;
114   end if;
115 end SetMetaDataCached;
116 
117 -- CacheValid
118 --   This function validates if the current session's cache is valid or
119 --   not. This procedure compares the time at which the meta-data was
120 --   loaded into the database with the time at which the sessions cache
121 --   was initialized. If the former is greater than the latter, new data
122 --   has been uploaded to the database and cache is invalid.
123 -- RETURN
124 --   Boolean status of whether cache is valid or not
125 function CacheValid
126 return boolean
127 is
128   l_lastMetaUpload date;
129 begin
130   l_lastMetaUpload := GetMetaDataUploaded();
131 
132   if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
133     wf_log_pkg.string(wf_log_pkg.level_statement,
134                     'wf.plsql.WF_BES_CACHE.CacheValid.Check',
135                     'Last upload time {'||to_char(l_lastMetaUpload, g_date_mask)||
136                     '} Last cache time {'||to_char(g_LastCacheUpdate, g_date_mask)||'}');
137   end if;
138 
139   if (l_lastMetaUpload is not null and g_LastCacheUpdate is not null and
140       l_lastMetaUpload > g_LastCacheUpdate) then
141     return false;
142   end if;
143   return true;
144 end CacheValid;
145 
146 -- ClearCache
147 --   Clears the cached objects from memory and resets requires variables
148 --   given the name of the cache.
149 procedure ClearCache
150 is
151 begin
152   wf_object_cache.Clear();
153   g_initialized := false;
154   SetMetaDataCached(null);
155 end ClearCache;
156 
157 -- ValidateCache (PRIVATE)
158 --   This procedure validates the cache and clears if found invalid
159 procedure ValidateCache
160 is
161 begin
162   -- if cache is invalid, clear it so that it can be rebuilt from database
163   if (not CacheValid()) then
164     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
165       wf_log_pkg.string(wf_log_pkg.level_statement,
166                       'wf.plsql.WF_BES_CACHE.ValidateCache.Cache_Invalid',
167                       'Cache is invalid. Clearing the cache');
168     end if;
169     ClearCache();
170   end if;
171 end ValidateCache;
172 
173 --
174 -- EVENTS and SUBSCRIPTIONS caching routines
175 --
176 
177 -- Get_Event_Object (PRIVATE)
178 --   This procedure sets the given event object to the Object cache. This
179 --   procedure set the event object to the appropriate cache created for
180 --   events
181 procedure Get_Event_Object(p_event_name in  varchar2,
182                            p_event_obj  in out nocopy WF_Event_Obj)
183 is
184   l_any_data AnyData;
185   l_dummy    pls_integer;
186 begin
187   -- Get the event from the object cache
188   l_any_data := wf_object_cache.GetObject(g_Event_Idx, p_event_name);
189   if (l_any_data is not null) then
190     l_dummy := l_any_data.getObject(p_event_obj);
191   else
192     p_event_obj := null;
193   end if;
194 end Get_Event_Object;
195 
196 -- Set_Event_Object (PRIVATE)
197 --   This procedure gets the event object from the Object cache for the given
198 --   event name.
199 procedure Set_Event_Object(p_event_name in varchar2,
200                            p_event_obj  in WF_Event_Obj)
201 is
202   l_any_data AnyData;
203 begin
204   -- Store this object in the cache for future use
205   l_any_data := sys.AnyData.ConvertObject(p_event_obj);
206   wf_object_cache.SetObject(g_Event_Idx, l_any_data, p_event_name);
207 end Set_Event_Object;
208 
209 -- Load_Event (PRIVATE)
210 --   Given the event name, this procedure loads the event information to the
211 --   wf_event_obj instance
212 procedure Load_Event(p_event_name in varchar2,
213                      p_event_obj   in out nocopy wf_event_obj)
214 is
215 
216   CURSOR c_get_event (cp_event_name varchar2) IS
217   SELECT guid, name, type, status, generate_function,
218          java_generate_func, licensed_flag
219   FROM   wf_events
220   WHERE  name = cp_event_name;
221 
222 begin
223   if (p_event_obj is null) then
224     wf_event_obj.Initialize(p_event_obj);
225   end if;
226 
227   open c_get_event(p_event_name);
228   fetch c_get_event into p_event_obj.guid, p_event_obj.name, p_event_obj.type,
229                          p_event_obj.status, p_event_obj.generate_function,
230                          p_event_obj.java_generate_func, p_event_obj.licensed_flag;
231   if (c_get_event%NOTFOUND) then
232     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
233       wf_log_pkg.string(wf_log_pkg.level_statement,
234                       'wf.plsql.WF_BES_CACHE.Load_Event.Not_Found',
235                       'Event {'||p_event_name||'} not found in the database');
236     end if;
237     -- If event not found in the set wf_event_obj to null
238     p_event_obj := null;
239   end if;
240   close c_get_event;
241 
242 end Load_Event;
243 
244 -- Load_Subscriptions (PRIVATE)
245 --   Given the event name this procedure loads all the valid subscriptions
246 --   into the wf_event_obj
247 procedure Load_Subscriptions(p_event_name   in varchar2,
248                              p_source_type  in varchar2,
249                              p_source_agent in raw,
250                              p_subs_count   in out nocopy number,
251                              p_event_obj    in out nocopy wf_event_obj)
252 is
253 
254   -- Cursor from wf_event.Dispatch that fetches all the valid subscriptions to the
255   -- event and the event group to which the event belongs
256   cursor active_subs (cp_event_name        varchar2,
257                       cp_source_type       varchar2,
258                       cp_source_agent_guid raw)
259   is
260   select subscription_guid,
261          system_guid,
262          subscription_source_type,
263          subscription_source_agent_guid,
264          subscription_phase,
265          subscription_rule_data,
266          subscription_out_agent_guid,
267          subscription_to_agent_guid,
268          subscription_priority,
269          subscription_rule_function,
270          wf_process_type,
271          wf_process_name,
272          subscription_parameters,
273          '',
274          '',
275          '',
276          '',
277          '',
278          subscription_on_error_type,
279          ''
280   from wf_active_subscriptions_v
281   where event_name in(cp_event_name, g_event_any)
282   and   subscription_source_type = cp_source_type
283   and   ((subscription_source_agent_guid is NOT NULL AND
284           subscription_source_agent_guid = nvl(cp_source_agent_guid, subscription_source_agent_guid))
285           OR subscription_source_agent_guid is NULL)
286   and   system_guid = wf_bes_cache.g_local_system_guid
287   order by 5;
288 
289   cursor active_event_subs(cp_event_name        varchar2,
290                            cp_source_type       varchar2,
291                            cp_source_agent_guid raw)
292   is
293   (select sub.guid                  sub_guid,
294           sub.system_guid           sys_guid,
295           sub.source_type           src_type,
296           sub.source_agent_guid     src_agt,
297           nvl(sub.phase,0)          phase,
298           sub.rule_data             rule_data,
299 	  sub.out_agent_guid        out_agt,
300           sub.to_agent_guid         to_agt,
301           sub.priority              priority,
302 	  DECODE(sub.rule_function, NULL,
303                  DECODE(sub.java_rule_func, NULL, NULL,
304                         g_java_sub||sub.java_rule_func),
305 	         sub.rule_function) rule_func,
306           sub.wf_process_type       proc_type,
307           sub.wf_process_name       proc_name,
308           sub.parameters            params,
309           sub.expression            exp,
310           sub.invocation_id         inv_id,
311           sub.map_code              map_code,
312           sub.standard_type         std_type,
313           sub.standard_code         std_code,
314           sub.on_error_code         on_error,
315           sub.action_code           action
316    from   wf_event_subscriptions sub,
317           wf_events evt
318    where  sub.system_guid   = wf_event.local_system_guid
319    and    sub.status        = 'ENABLED'
320    and    sub.licensed_flag = 'Y'
321    and    sub.source_type   = cp_source_type
322    and    ((sub.source_agent_guid is NOT NULL AND
323            sub.source_agent_guid = nvl(cp_source_agent_guid, sub.source_agent_guid))
324            OR sub.source_agent_guid is NULL)
325    and    sub.event_filter_guid  = evt.guid
326    and    evt.name          = cp_event_name
327    and    evt.type          = 'EVENT'
328    and    evt.status        = 'ENABLED'
329    and    evt.licensed_flag = 'Y')
330    order by 5;
331 
332    l_subscription WF_Event_Subs_Obj;
333    l_count        number;
334 begin
335 
336   -- Check if subscriptions are already loaded for this source type
337   if (upper(p_event_obj.GetSubsLoaded(p_source_type)) = g_status_yes) then
338     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
339       wf_log_pkg.string(wf_log_pkg.level_statement,
340                       'wf.plsql.WF_BES_CACHE.Load_Subscriptions.Check',
341                       p_source_type||' subscriptions for event {'||
342                       p_event_name||'} are already loaded.');
343     end if;
344     return;
345   end if;
346 
347   WF_Event_Subs_Obj.Initialize(l_subscription);
348   l_count := 0;
349 
350   -- Load all LOCAL subscriptions from the Database
351   if (lower(p_event_name) in (g_event_unexpected, g_event_any)) then
352     open active_event_subs(p_event_name, p_source_type, p_source_agent);
353     if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
354       wf_log_pkg.string(wf_log_pkg.level_procedure,
355                        'wf.plsql.WF_BES_CACHE.Load_Subscriptions.active_event_subs',
356                        'Using cursor active_event_subs for event {'||p_event_name||'}');
357     end if;
358 
359     loop
360       fetch active_event_subs into l_subscription.GUID,
361                                    l_subscription.SYSTEM_GUID,
362                                    l_subscription.SOURCE_TYPE,
363                                    l_subscription.SOURCE_AGENT_GUID,
364                                    l_subscription.PHASE,
365                                    l_subscription.RULE_DATA,
366                                    l_subscription.OUT_AGENT_GUID,
367                                    l_subscription.TO_AGENT_GUID,
368                                    l_subscription.PRIORITY,
369                                    l_subscription.RULE_FUNCTION,
370                                    l_subscription.WF_PROCESS_TYPE,
371                                    l_subscription.WF_PROCESS_NAME,
372                                    l_subscription.PARAMETERS,
373                                    l_subscription.EXPRESSION,
374                                    l_subscription.INVOCATION_ID,
375                                    l_subscription.MAP_CODE,
376                                    l_subscription.STANDARD_TYPE,
377                                    l_subscription.STANDARD_CODE,
378                                    l_subscription.ON_ERROR_CODE,
379                                    l_subscription.ACTION_CODE;
380 
381       exit when active_event_subs%NOTFOUND;
382 
383       -- This is an optimization flag to indicate that the subcription list has
384       -- non-null source agent For an agent listener session, if this flag is Y,
385       -- the list will be searched. Else the complete subscription list is returned
386       if (l_subscription.SOURCE_AGENT_GUID is not null) then
387         p_event_obj.SetSourceAgentAvl(p_source_type, g_status_yes);
388       end if;
389 
390       p_event_obj.AddSubscriptionToList(l_subscription, p_source_type);
391       l_count := l_count+1;
392     end loop;
393     close active_event_subs;
394   else
395     open active_subs(p_event_name, p_source_type, p_source_agent);
396     if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
397       wf_log_pkg.string(wf_log_pkg.level_procedure,
398                        'wf.plsql.WF_BES_CACHE.Load_Subscriptions.active_subs',
399                        'Using cursor active_subs for event {'||p_event_name||'}');
400     end if;
401 
402     loop
403       fetch active_subs into l_subscription.GUID,
404                              l_subscription.SYSTEM_GUID,
405                              l_subscription.SOURCE_TYPE,
406                              l_subscription.SOURCE_AGENT_GUID,
407                              l_subscription.PHASE,
408                              l_subscription.RULE_DATA,
409                              l_subscription.OUT_AGENT_GUID,
410                              l_subscription.TO_AGENT_GUID,
411                              l_subscription.PRIORITY,
412                              l_subscription.RULE_FUNCTION,
413                              l_subscription.WF_PROCESS_TYPE,
414                              l_subscription.WF_PROCESS_NAME,
415                              l_subscription.PARAMETERS,
416                              l_subscription.EXPRESSION,
417                              l_subscription.INVOCATION_ID,
418                              l_subscription.MAP_CODE,
419                              l_subscription.STANDARD_TYPE,
420                              l_subscription.STANDARD_CODE,
421                              l_subscription.ON_ERROR_CODE,
422                              l_subscription.ACTION_CODE;
423 
424       exit when active_subs%NOTFOUND;
425 
426       -- This is an optimization flag to indicate that the subcription list has
427       -- non-null source agent For an agent listener session, if this flag is Y,
428       -- the list will be searched. Else the complete subscription list is returned
429       if (l_subscription.SOURCE_AGENT_GUID is not null) then
430         p_event_obj.SetSourceAgentAvl(p_source_type, g_status_yes);
431       end if;
432 
433       p_event_obj.AddSubscriptionToList(l_subscription, p_source_type);
434       l_count := l_count+1;
435     end loop;
436     close active_subs;
437   end if;
438 
439   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
440     wf_log_pkg.string(wf_log_pkg.level_procedure,
441                     'wf.plsql.WF_BES_CACHE.Load_Subscriptions.End',
442                     'Loaded {'||l_count||'} '||p_source_type||' subscriptions '||
443                     'for event {'||p_event_name||'}');
444   end if;
445 
446   p_event_obj.SetSubsLoaded(p_source_type, g_status_yes);
447   p_subs_count := l_count;
448 end Load_Subscriptions;
449 
450 -- GetEventByName
451 --   This function returns an instance of WF_Event_Obj object type which
452 --   contains the complete event information along with valid subscriptions
453 --   to the event. The information could come from the cache memory or from
454 --   the database.
455 -- IN
456 --   p_event_name - Event name whose information is required
457 function GetEventByName(p_event_name  in varchar2)
458 return wf_event_obj
459 is
460   l_event_obj wf_event_obj;
461   l_any_data  anyData;
462   l_dummy     pls_integer;
463 begin
464   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
465     wf_log_pkg.string(wf_log_pkg.level_procedure,
466                     'wf.plsql.WF_BES_CACHE.GetEventByName.Begin',
467                     'Getting event details for {'||p_event_name||'}');
468   end if;
469 
470   l_event_obj := null;
471 
472   if (not g_initialized) then
473     Initialize();
474   end if;
475 
476   ValidateCache();
477 
478   -- Each object type being cached is identified by a number within
479   -- the session
480   if (not wf_object_cache.IsCacheCreated(g_Event_Idx)) then
481     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
482       wf_log_pkg.string(wf_log_pkg.level_statement,
483                       'wf.plsql.WF_BES_CACHE.GetEventByName.Create_Cache',
484                       'Cache is not created for EVENTS index {'||g_Event_Idx||'}');
485     end if;
486     wf_object_cache.CreateCache(g_Event_Idx);
487     SetMetaDataCached(sysdate);
488   else
489     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
490       wf_log_pkg.string(wf_log_pkg.level_statement,
491                       'wf.plsql.WF_BES_CACHE.GetEventByName.Cache_Get',
492                       'Getting the event from Cache');
493     end if;
494     Get_Event_Object(p_event_name, l_event_obj);
495   end if;
496 
497   -- If the event is not in the object cache, initialize the object and
498   -- retrieve the details from the database
499   if (l_event_obj is null) then
500     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
501       wf_log_pkg.string(wf_log_pkg.level_statement,
502                       'wf.plsql.WF_BES_CACHE.GetEventByName.Load_Event',
503                       'Event not found in cache. Loading from Database');
504     end if;
505     -- Load event from the database to the object
506     Load_Event(p_event_name, l_event_obj);
507 
508     if (l_event_obj is not null) then
509       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
510         wf_log_pkg.string(wf_log_pkg.level_statement,
511                         'wf.plsql.WF_BES_CACHE.GetEventByName.Set_Cache',
512                         'Setting event {'||p_event_name||'} to cache');
513       end if;
514       Set_Event_Object(p_event_name, l_event_obj);
515     end if;
516   end if;
517 
518   -- return the event object only if the event is ENABLED and product licensed
519   if (l_event_obj is not null and
520        l_event_obj.STATUS = 'ENABLED' and
521 	 l_event_obj.LICENSED_FLAG = 'Y') then
522     return l_event_obj;
523   else
524     return null;
525   end if;
526 
527 exception
528   when others then
529     wf_core.context('WF_BES_CACHE', 'GetEventByName', p_event_name);
530     raise;
531 end GetEventByName;
532 
533 -- GetSubscriptions
534 --   This function returns a table of WF_EVENT_SUBS_OBJ that are the valid
535 --   subscriptions to the given event.
536 function GetSubscriptions(p_event_name   in varchar2,
537                           p_source_type  in varchar2,
538                           p_source_agent in raw)
539 return wf_event_subs_tab
540 is
541   l_event_obj     wf_event_obj;
542   l_any_data      anyData;
543   l_dummy         pls_integer;
544   l_subs_count    number;
545 begin
546   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
547     wf_log_pkg.string(wf_log_pkg.level_procedure,
548                     'wf.plsql.WF_BES_CACHE.GetSubscriptions.Begin',
549                     'Getting subscriptions for event {'||p_event_name||'}'||
550                     ' Source Type {'||p_source_type||'} Source Agt {'||p_source_agent||'}');
551   end if;
552 
553   -- Get the event information from the cache or the database
554   l_event_obj := GetEventByName(p_event_name);
555 
556   -- Event not found in the cache as well as in database or disabled
557   if (l_event_obj is null) then
558     return null;
559   end if;
560 
561   -- Load subscriptions for a given source type if not already loaded
562   if (upper(l_event_obj.GetSubsLoaded(p_source_type)) = g_status_no) then
563 
564     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
565       wf_log_pkg.string(wf_log_pkg.level_statement,
566                       'wf.plsql.WF_BES_CACHE.GetSubscriptions.Load_Subs',
567                       'Subscriptions for {'||p_event_name||'} is not already loaded.'||
568                       ' Loading from DB for Source Type {'||p_source_type||
569                       '} Source Agt {'||p_source_agent||'}');
570     end if;
571 
572     -- NOTE: within an agent listener's session we would only require subscriptions
573     -- with the same source_agent_guid. so it should be ok to cache only subscriptions
574     -- with that source_agent_guid and with null source_agent_guid
575     -- TODO!! currently we are loading for all source_agent_guid
576 
577     -- load subscriptions for all source_agents if not already loaded
578     Load_Subscriptions(p_event_name, p_source_type, null, l_subs_count, l_event_obj);
579     Set_Event_Object(p_event_name, l_event_obj);
580   else
581     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
582       wf_log_pkg.string(wf_log_pkg.level_statement,
583                       'wf.plsql.WF_BES_CACHE.GetSubscriptions.Subs_Loaded',
584                       'Subscriptions for {'||p_event_name||'} is already loaded to cache');
585     end if;
586   end if;
587 
588   -- If p_source_agent is not null, dispatcher needs only subscriptions
589   -- with the specified SOURCE_AGENT_GUID
590   if (p_source_agent is not null and
591        l_event_obj.GetSourceAgentAvl(p_source_type) = g_status_yes) then
592     return l_event_obj.GetSubscriptionBySrcAgtGUID(p_source_type, p_source_agent);
593   else
594     -- All subscriptions for a given event are loaded for the given source type
595     return l_event_obj.GetSubscriptionList(p_source_type);
596   end if;
597 exception
598   when others then
599     wf_core.context('WF_BES_CACHE', 'GetSubscriptions', p_event_name, p_source_type);
600     raise;
601 end GetSubscriptions;
602 
603 -- GetSubscriptionByGUID
604 --   This function returns a WF_EVENT_SUBS_OBJ that contains the subscription
605 --   to the given event and mathing the given subscription GUID.
606 function GetSubscriptionByGUID(p_event_name in varchar2,
607                                 p_sub_guid   in raw)
608 return wf_event_subs_obj
609 is
610   l_event_obj   WF_Event_Obj;
611   l_subs_count  number;
612   l_subs_loaded boolean;
613 begin
614   -- If either of the parameter values are null, no info can be returned
615   if (p_event_name is null or p_sub_guid is null) then
616     return null;
617   end if;
618 
619   l_event_obj := wf_bes_cache.GetEventByName(p_event_name);
620 
621   if (l_event_obj is null) then
622     return null;
623   end if;
624 
625   l_subs_loaded := false;
626   -- Load subscriptions if not already loaded
627   if (upper(l_event_obj.GetSubsLoaded(g_src_type_local)) = g_status_no) then
628     Load_Subscriptions(p_event_name, g_src_type_local, null, l_subs_count, l_event_obj);
629     l_subs_loaded := true;
630   end if;
631   if (upper(l_event_obj.GetSubsLoaded(g_src_type_external)) = g_status_no) then
632     Load_Subscriptions(p_event_name, g_src_type_external, null, l_subs_count, l_event_obj);
633     l_subs_loaded := true;
634   end if;
635   if (upper(l_event_obj.GetSubsLoaded(g_src_type_error)) = g_status_no) then
636     Load_Subscriptions(p_event_name, g_src_type_error, null, l_subs_count, l_event_obj);
637     l_subs_loaded := true;
638   end if;
639 
640   if (l_subs_loaded) then
641     -- Set the event object to cache if in case some subscriptions were loaded
642     Set_Event_Object(p_event_name, l_event_obj);
643   end if;
644 
645   return l_event_obj.GetSubscriptionByGUID(p_sub_guid);
646 exception
647   when others then
648     wf_core.context('WF_BES_CACHE', 'GetSubscriptionByGUID', p_event_name, p_sub_guid);
649     raise;
650 end GetSubscriptionByGUID;
651 
652 --
653 -- AGENTS caching routines
654 --
655 
656 -- Get_Agent_Object (PRIVATE)
657 --   This procedure sets the given agent object to the Object cache. This
658 --   procedure sets the agent object to the appropriate cache created for
659 --   agents
660 procedure Get_Agent_Object(p_agent_key in  varchar2,
661                            p_agent_obj in out nocopy WF_Agent_Obj)
662 is
663   l_any_data AnyData;
664   l_dummy    pls_integer;
665 begin
666   -- Get the agent from the object cache
667   l_any_data := wf_object_cache.GetObject(g_Agent_Idx, p_agent_key);
668   if (l_any_data is not null) then
669     l_dummy := l_any_data.getObject(p_agent_obj);
670   else
671     p_agent_obj := null;
672   end if;
673 end Get_Agent_Object;
674 
675 -- Set_Agent_Object (PRIVATE)
676 --   This procedure gets the agent object from the Object cache for the given
677 --   agent name + system name.
678 procedure Set_Agent_Object(p_agent_key in varchar2,
679                            p_agent_obj in WF_Agent_Obj)
680 is
681   l_any_data AnyData;
682 begin
683   -- Store this object in the cache for future use
684   l_any_data := sys.AnyData.ConvertObject(p_agent_obj);
685   wf_object_cache.SetObject(g_Agent_Idx, l_any_data, p_agent_key);
686 end Set_Agent_Object;
687 
688 -- Load_Agent (PRIVATE)
689 --   Given the agent name and system name, this procedure loads the agent
690 --   information to the wf_agent_obj instance. This procedure takes agent
691 --   name, system name and agent guid as inputs.
692 -- o if agent name and system name are not null, it uses this to get info
693 -- o if agent name and/or system name are null and agent guid is not null
694 --   it agent guid to get the info
695 procedure Load_Agent(p_agent_guid  in raw,
696                      p_agent_name  in varchar2,
697                      p_system_name in varchar2,
698                      p_agent_obj   in out nocopy wf_agent_obj)
699 is
700 
701   CURSOR c_get_agent_n (cp_agent_name varchar2, cp_system_name varchar2) IS
702   SELECT a.guid, a.name, a.system_guid, s.name, a.protocol, a.address,
703          a.queue_handler, a.queue_name, a.direction, a.status,
704          a.display_name, a.type, a.java_queue_handler
705   FROM   wf_agents a, wf_systems s
706   WHERE  a.name        = cp_agent_name
707   AND    a.system_guid = s.guid
708   AND    s.name        = cp_system_name;
709 
710   CURSOR c_get_agent_g (cp_agent_guid raw) IS
711   SELECT a.guid, a.name, a.system_guid, s.name, a.protocol, a.address,
712          a.queue_handler, a.queue_name, a.direction, a.status,
713          a.display_name, a.type, a.java_queue_handler
714   FROM   wf_agents a, wf_systems s
715   WHERE  a.guid = cp_agent_guid
716   AND    s.guid = a.system_guid;
717 
718 begin
719   if (p_agent_obj is null) then
720     wf_agent_obj.Initialize(p_agent_obj);
721   end if;
722 
723   if (p_agent_name is not null and p_system_name is not null) then
724     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
725       wf_log_pkg.string(wf_log_pkg.level_statement,
726                        'wf.plsql.WF_BES_CACHE.Load_Agent.Cursor',
727                        'Loading agent by name '||p_agent_name||'+'||p_system_name);
728     end if;
729     open c_get_agent_n(p_agent_name, p_system_name);
730     fetch c_get_agent_n into p_agent_obj.GUID,
731                              p_agent_obj.NAME,
732                              p_agent_obj.SYSTEM_GUID,
733                              p_agent_obj.SYSTEM_NAME,
734                              p_agent_obj.PROTOCOL,
735                              p_agent_obj.ADDRESS,
736                              p_agent_obj.QUEUE_HANDLER,
737                              p_agent_obj.QUEUE_NAME,
738                              p_agent_obj.DIRECTION,
739                              p_agent_obj.STATUS,
740                              p_agent_obj.DISPLAY_NAME,
741                              p_agent_obj.TYPE,
742                              p_agent_obj.JAVA_QUEUE_HANDLER;
743 
744     if (c_get_agent_n%NOTFOUND) then
745       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
746         wf_log_pkg.string(wf_log_pkg.level_statement,
747                         'wf.plsql.WF_BES_CACHE.Load_Agent.Not_Found',
748                         'Agent not found in the database.');
749       end if;
750       -- If agent not found in the set wf_agent_obj to null
751       p_agent_obj := null;
752     end if;
753     close c_get_agent_n;
754   elsif (p_agent_guid is not null) then
755     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
756       wf_log_pkg.string(wf_log_pkg.level_statement,
757                        'wf.plsql.WF_BES_CACHE.Load_Agent.Not_Found',
758                        'Loading agent by GUID '||p_agent_guid);
759     end if;
760     open c_get_agent_g(p_agent_guid);
761     fetch c_get_agent_g into p_agent_obj.GUID,
762                              p_agent_obj.NAME,
763                              p_agent_obj.SYSTEM_GUID,
764                              p_agent_obj.SYSTEM_NAME,
765                              p_agent_obj.PROTOCOL,
766                              p_agent_obj.ADDRESS,
767                              p_agent_obj.QUEUE_HANDLER,
768                              p_agent_obj.QUEUE_NAME,
769                              p_agent_obj.DIRECTION,
770                              p_agent_obj.STATUS,
771                              p_agent_obj.DISPLAY_NAME,
772                              p_agent_obj.TYPE,
773                              p_agent_obj.JAVA_QUEUE_HANDLER;
774 
775     if (c_get_agent_g%NOTFOUND) then
776       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
777         wf_log_pkg.string(wf_log_pkg.level_statement,
778                         'wf.plsql.WF_BES_CACHE.Load_Agent.Not_Found',
779                         'Agent not found in the database');
780       end if;
781       -- If agent not found in the set wf_agent_obj to null
782       p_agent_obj := null;
783     end if;
784     close c_get_agent_g;
785   else
786     p_agent_obj := null;
787   end if;
788 
789 end Load_Agent;
790 
791 -- Load_Agent_QH (PRIVATE)
792 --   Given the queue handler name, this procedure loads the agent
793 --   information to the wf_agent_obj instance of the first agent whose
794 --   queue handler matches with this queue handler
795 procedure Load_Agent_QH(p_agent_qh  in varchar2,
796                         p_direction in varchar2,
797                         p_agent_obj in out nocopy wf_agent_obj)
798 is
799 
800   CURSOR c_get_agent (cp_agent_qh varchar2, cp_direction varchar2) IS
801   SELECT a.guid, a.name, a.system_guid, s.name, a.protocol, a.address,
802          a.queue_handler, a.queue_name, a.direction, a.status,
803          a.display_name, a.type, a.java_queue_handler
804   FROM   wf_agents  a, wf_systems s
805   WHERE  a.system_guid   = wf_event.local_system_guid
806   AND    a.system_guid   = s.guid
807   AND    a.queue_handler = cp_agent_qh
808   AND    a.direction     = cp_direction;
809 
810 begin
811   if (p_agent_obj is null) then
812     wf_agent_obj.Initialize(p_agent_obj);
813   end if;
814 
815   if (p_agent_qh is null) then
816     return;
817   end if;
818 
819   if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
820     wf_log_pkg.string(wf_log_pkg.level_statement,
821                      'wf.plsql.WF_BES_CACHE.Load_Agent_QH.Cursor',
822                      'Loading from DB for Queue Handler '||p_agent_qh);
823   end if;
824 
825   open c_get_agent(p_agent_qh, p_direction);
826   fetch c_get_agent into p_agent_obj.GUID,
827                          p_agent_obj.NAME,
828                          p_agent_obj.SYSTEM_GUID,
829                          p_agent_obj.SYSTEM_NAME,
830                          p_agent_obj.PROTOCOL,
831                          p_agent_obj.ADDRESS,
832                          p_agent_obj.QUEUE_HANDLER,
833                          p_agent_obj.QUEUE_NAME,
834                          p_agent_obj.DIRECTION,
835                          p_agent_obj.STATUS,
836                          p_agent_obj.DISPLAY_NAME,
837                          p_agent_obj.TYPE,
838                          p_agent_obj.JAVA_QUEUE_HANDLER;
839 
840   if (c_get_agent%NOTFOUND) then
841     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
842       wf_log_pkg.string(wf_log_pkg.level_statement,
843                       'wf.plsql.WF_BES_CACHE.Load_Agent.Not_Found',
844                       'No Agent exists for the given queue handler');
845     end if;
846     -- If agent not found in the set wf_agent_obj to null
847     p_agent_obj := null;
848   end if;
849   close c_get_agent;
850 
851 end Load_Agent_QH;
852 
853 -- GetAgentByName
854 --   This function returns an instance of WF_AGENT_OBJ that contains the
855 --   information about the specified Agent name + System Name. If null
856 --   system name is provided, local system is assumed.
857 function GetAgentByName(p_agent_name  in varchar2,
858                         p_system_name in varchar2)
859 return wf_agent_obj
860 is
861   l_agent_obj   wf_agent_obj;
862   l_any_data    anyData;
863   l_dummy       pls_integer;
864   l_agent_key   varchar2(60);
865   l_system_name varchar2(30);
866 begin
867   if (wf_log_pkg.level_procedure >= fnd_log.g_current_runtime_level) then
868     wf_log_pkg.string(wf_log_pkg.level_procedure,
869                     'wf.plsql.WF_BES_CACHE.GetAgentByName.Begin',
870                     'Getting agent details for {'||p_agent_name||
871                     '+'||p_system_name||'}');
872   end if;
873 
874   -- Initialize cache variables if not already initialized
875   if (not g_initialized) then
876     Initialize();
877   end if;
878 
879   -- if provided system name is null, default to local system name
880   if (p_system_name is null) then
881     l_system_name := g_local_system_name;
882   else
883     l_system_name := p_system_name;
884   end if;
885 
886   if (p_agent_name is null) then
887     return null;
888   end if;
889 
890   l_agent_key := p_agent_name||l_system_name;
891   l_agent_obj := null;
892 
893   ValidateCache();
894 
895   -- Each object type being cached is identified by a number within
896   -- the session
897   if (not wf_object_cache.IsCacheCreated(g_Agent_Idx)) then
898     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
899       wf_log_pkg.string(wf_log_pkg.level_statement,
900                       'wf.plsql.WF_BES_CACHE.GetAgentByName.Create_Cache',
901                       'Cache is not created for AGENTS index {'||g_Agent_Idx||'}');
902     end if;
903     wf_object_cache.CreateCache(g_Agent_Idx);
904     SetMetaDataCached(sysdate);
905   else
906     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
907       wf_log_pkg.string(wf_log_pkg.level_statement,
908                       'wf.plsql.WF_BES_CACHE.GetAgentByName.Cache_Get',
909                       'Getting the Agent from Cache');
910     end if;
911     Get_Agent_Object(l_agent_key, l_agent_obj);
912   end if;
913 
914   -- If the Agent is not in the object cache, initialize the object and
915   -- retrieve the details from the database
916   if (l_agent_obj is null) then
917     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
918       wf_log_pkg.string(wf_log_pkg.level_statement,
919                       'wf.plsql.WF_BES_CACHE.GetAgentByName.Load_Agent',
920                       'Agent not found in cache. Loading from Database');
921     end if;
922     -- Load agent from the database to the object
923 
924     Load_Agent(null, p_agent_name, l_system_name, l_agent_obj);
925 
926     if (l_agent_obj is not null) then
927       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
928         wf_log_pkg.string(wf_log_pkg.level_statement,
929                         'wf.plsql.WF_BES_CACHE.GetAgentByName.Set_Cache',
930                         'Setting Agent {'||l_agent_key||'} to cache');
931       end if;
932       Set_Agent_Object(l_agent_key, l_agent_obj);
933     end if;
934   end if;
935 
936   return l_agent_obj;
937 
938 end GetAgentByName;
939 
940 -- GetAgentByGUID
941 --   This function returns an instance of WF_AGENT_OBJ that contains the
942 --   information about the specified Agent guid
943 function GetAgentByGUID(p_agent_guid in raw)
944 return wf_agent_obj
945 is
946   l_all_agents  wf_object_cache.wf_objects_t;
947   l_agent_key   varchar2(60);
948   l_agent_obj   wf_agent_obj;
949   l_dummy       pls_integer;
950   l_agent_name  varchar2(30);
951   l_system_name varchar2(30);
952   l_found       boolean;
953   l_loc         number;
954 begin
955 
956   if (p_agent_guid is null) then
957     return null;
958   end if;
959 
960   -- Initialize cache if not already initialized
961   if (not g_initialized) then
962     Initialize();
963   end if;
964 
965   l_agent_obj := null;
966 
967   ValidateCache();
968 
969   -- check if the Agent cache is created. if created get all agent objects
970   if (not wf_object_cache.IsCacheCreated(g_Agent_Idx)) then
971     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
972       wf_log_pkg.string(wf_log_pkg.level_statement,
973                       'wf.plsql.WF_BES_CACHE.GetAgentByGUID.Create_Cache',
974                       'Cache is not created for AGENTS index {'||g_Agent_Idx||'}');
975     end if;
976     wf_object_cache.CreateCache(g_Agent_Idx);
977     SetMetaDataCached(sysdate);
978   else
979     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
980       wf_log_pkg.string(wf_log_pkg.level_statement,
981                       'wf.plsql.WF_BES_CACHE.GetAgentByGUID.Get_All',
982                       'Getting all cached agent objects');
983     end if;
984     l_all_agents := wf_object_cache.GetAllObjects(g_Agent_Idx);
985   end if;
986 
987   -- check if at least one agent is cached. then look for the agent with GUID
988   if (l_all_agents is not null) then
989 
990     l_found := false;
991 
992     l_loc := l_all_agents.FIRST;
993     while (l_loc is not null) loop
994       l_dummy := l_all_agents(l_loc).getObject(l_agent_obj);
995       if (l_agent_obj.GUID = p_agent_guid) then
996         l_found := true;
997         exit;
998       end if;
999       l_loc := l_all_agents.NEXT(l_loc);
1000     end loop;
1001 
1002     if (l_found) then
1003       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1004         wf_log_pkg.string(wf_log_pkg.level_statement,
1005                         'wf.plsql.WF_BES_CACHE.GetAgentByGUID.Cache_Hit',
1006                         'Agent found in cache for GUID '||p_agent_guid);
1007       end if;
1008       return l_agent_obj;
1009     end if;
1010   end if;
1011 
1012   -- agent not in cache. add the agent to cache from database
1013   Load_Agent(p_agent_guid, null, null, l_agent_obj);
1014 
1015   -- set it to cache if found in database
1016   if (l_agent_obj is not null) then
1017     l_agent_name := l_agent_obj.NAME;
1018     l_system_name := l_agent_obj.SYSTEM_NAME;
1019     l_agent_key := l_agent_name||l_system_name;
1020     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1021       wf_log_pkg.string(wf_log_pkg.level_statement,
1022                        'wf.plsql.WF_BES_CACHE.GetAgentByGUID.Set_Object',
1023                        'Agent loaded from Database for GUID '||p_agent_guid||
1024                        '. Setting to cache for '||l_agent_key);
1025     end if;
1026     Set_Agent_Object(l_agent_key, l_agent_obj);
1027   end if;
1028   return l_agent_obj;
1029 
1030 exception
1031   when others then
1032     wf_core.context('WF_BES_CACHE', 'GetAgentByGUID', p_agent_guid);
1033     raise;
1034 end GetAgentByGUID;
1035 
1036 -- GetAgentByQH
1037 --   This function returns an instance of WF_AGENT_OBJ that contains the
1038 --   information about first agent that matches the specified Queue Handler
1039 function GetAgentByQH(p_agent_qh  in varchar2,
1040                       p_direction in varchar2)
1041 return wf_agent_obj
1042 is
1043   l_all_agents  wf_object_cache.wf_objects_t;
1044   l_agent_key   varchar2(60);
1045   l_agent_obj   wf_agent_obj;
1046   l_dummy       pls_integer;
1047   l_agent_name  varchar2(30);
1048   l_system_name varchar2(30);
1049   l_found       boolean;
1050   l_loc         number;
1051 begin
1052 
1053   if (p_agent_qh is null) then
1054     return null;
1055   end if;
1056 
1057   -- Initialize cache if not already initialized
1058   if (not g_initialized) then
1059     Initialize();
1060   end if;
1061 
1062   l_agent_obj := null;
1063 
1064   ValidateCache();
1065 
1066   -- check if the Agent cache is created. if created get all agent objects
1067   if (not wf_object_cache.IsCacheCreated(g_Agent_Idx)) then
1068     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1069       wf_log_pkg.string(wf_log_pkg.level_statement,
1070                       'wf.plsql.WF_BES_CACHE.GetAgentByQH.Create_Cache',
1071                       'Cache is not created for AGENTS index {'||g_Agent_Idx||'}');
1072     end if;
1073     wf_object_cache.CreateCache(g_Agent_Idx);
1074     SetMetaDataCached(sysdate);
1075   else
1076     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1077       wf_log_pkg.string(wf_log_pkg.level_statement,
1078                       'wf.plsql.WF_BES_CACHE.GetAgentByQH.Get_All',
1079                       'Getting all cached agent objects');
1080     end if;
1081     l_all_agents := wf_object_cache.GetAllObjects(g_Agent_Idx);
1082   end if;
1083 
1084   -- check if at least one agent is cached. then look for the agent with GUID
1085   if (l_all_agents is not null) then
1086 
1087     l_found := false;
1088 
1089     l_loc := l_all_agents.FIRST;
1090     while (l_loc is not null) loop
1091       l_dummy := l_all_agents(l_loc).getObject(l_agent_obj);
1092       if (l_agent_obj.DIRECTION = p_direction and
1093             l_agent_obj.QUEUE_HANDLER = p_agent_qh) then
1094         l_found := true;
1095         exit;
1096       end if;
1097       l_loc := l_all_agents.NEXT(l_loc);
1098     end loop;
1099 
1100     if (l_found) then
1101       if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1102         wf_log_pkg.string(wf_log_pkg.level_statement,
1103                         'wf.plsql.WF_BES_CACHE.GetAgentByQH.Cache_Hit',
1104                         'Agent found in cache for Queue Handler '||p_agent_qh);
1105       end if;
1106       return l_agent_obj;
1107     end if;
1108   end if;
1109 
1110   -- agent not in cache. add the agent to cache from database
1111   Load_Agent_QH(p_agent_qh, p_direction, l_agent_obj);
1112 
1113   -- set it to cache if found in database
1114   if (l_agent_obj is not null) then
1115     l_agent_name := l_agent_obj.NAME;
1116     l_system_name := l_agent_obj.SYSTEM_NAME;
1117     l_agent_key := l_agent_name||l_system_name;
1118     if (wf_log_pkg.level_statement >= fnd_log.g_current_runtime_level) then
1119       wf_log_pkg.string(wf_log_pkg.level_statement,
1120                        'wf.plsql.WF_BES_CACHE.GetAgentByQH.Set_Object',
1121                        'Agent loaded from Database for Queue Hander '||p_agent_qh||
1122                        '. Setting to cache for '||l_agent_key);
1123     end if;
1124     Set_Agent_Object(l_agent_key, l_agent_obj);
1125   end if;
1126   return l_agent_obj;
1127 
1128 exception
1129   when others then
1130     wf_core.context('WF_BES_CACHE', 'GetAgentByQH', p_agent_qh, p_direction);
1131     raise;
1132 end GetAgentByQH;
1133 
1134 --
1135 -- SYSTEMS caching routines
1136 --
1137 
1138 -- GetSystemByName
1139 --   This function returns an instance of WF_SYSTEM_OBJ that contains the
1140 --   information about the specified System name.
1141 function GetSystemByName(p_system_name in varchar2)
1142 return wf_system_obj
1143 is
1144 begin
1145   return null;
1146 end GetSystemByName;
1147 
1148 end WF_BES_CACHE;