create or replace package body odwactxt is /***************************************************************************************** Purpose Package to maintain the session context Usage Called from every ODWA-package.procedure that may act as a URL i.e. that can be called directly in the Browser Remarks Revision history When Who Construct Revision What ------------------------------------------------------------------------------------------ $REVISION_HISTORY$ 05-jan-2001 Peter Ebell 1.4 - Changed get_context_label to enable excluding workarea/configuration name, and to wrap the foldername if it's too long 15-sep-2000 Lucas Jellema 1.2 new function Context_Label 28-aug-2000 Lucas Jellema 1.1 New parameter in Context: Configuration_id, Folder_ivid Provide new session id for each new-request 11-jul-2000 Lucas Jellema 1.0 Creation *****************************************************************************************/ -- -- private constants -- REVISION_LABEL constant varchar2(30) := '$LABEL::1.4 $'; PACKAGE_NAME constant varchar2(30) := 'ODWACTXT'; g_session_rec odwa_sessions%rowtype; g_static boolean:= false; g_one_file boolean:= false; function get_session_id return number is begin return g_session_rec.id; end; -- get_session_id function get_workarea_irid return number is begin return g_session_rec.workarea_irid; end; -- get_workarea_irid function get_folder_irid return number is begin return g_session_rec.folder_irid; end; -- get_folder_irid function get_folder_ivid return number is begin return g_session_rec.folder_ivid; end; -- get_folder_ivid function get_cfg_id return number is begin return g_session_rec.cfg_id; end; -- get_cfg_id function get_pac_irid return number is begin return g_session_rec.pac_irid; end; -- get_pac_irid function get_pac_ivid return number is begin return g_session_rec.pac_ivid; end; -- get_pac_ivid function get_pac_type_id return number is begin return g_session_rec.pac_type_id; end; -- get_pac_type_id -- since static and one-file only apply to static reports (otherwise they have their default values) -- they do not need to be kept persistent across browser calls; when generating static HTML, the session -- itself is persistent, and so are package variables procedure set_static is begin g_static := true; end; -- set_static procedure reset_static is begin g_static := false; end; -- reset_static procedure set_one_file is begin g_one_file := true; end; -- set_one_file procedure set_multiple_file is begin g_one_file := false; end; -- set_multiple_file function get_static return boolean is begin return g_static; end; -- get_static function get_one_file return varchar2 is begin if g_one_file then return 'Y'; else return 'N'; end if; end; -- get_one_file -- this procedure will ensure that g_session_rec contains the up to date data -- for the indicated p_session_id -- if the indicated session cannot be found (e.g. when someone has saved a URL containing -- a session id that since then has been purged, a new session is created automatically procedure refresh_cache ( p_session_id in number default g_session_rec.id ) is cursor c_ssn( b_session_id in number) is select id , username , number_of_requests , workarea_irid , timestamp_creation , timestamp_last_call , pac_irid , pac_ivid , pac_type_id , folder_irid , folder_ivid , cfg_id from odwa_sessions ssn where ssn.id = b_session_id ; begin if nvl( g_session_rec.id,-1) = p_session_id then null; -- we already refreshed the cache with this session's data else open c_ssn( b_session_id => p_session_id); fetch c_ssn into g_session_rec ; if c_ssn%notfound then g_session_rec.id := -1; end if; close c_ssn; end if; -- nvl( g_session_rec.id,-1) = p_session_id end; -- refresh_cache function get_next_session_id return number is cursor c_ssn is select odwa_session_seq.nextval from dual ; l_session_id number(10); begin open c_ssn; fetch c_ssn into l_session_id ; close c_ssn; return l_session_id ; end; -- get_next_session_id -- open a new ODWA session (create a new row in the ODWA_SESSIONS table) -- and set the Oracle Repository Workarea Context procedure open_session ( p_workarea_irid in number default -1 , p_based_on_session in number default null ) is begin if nvl( p_based_on_session, -1) <> -1 then refresh_cache ( p_session_id => p_based_on_session); else g_session_rec.pac_irid := null; g_session_rec.pac_ivid := null; g_session_rec.pac_type_id := null; g_session_rec.folder_irid := null; g_session_rec.folder_ivid := null; g_session_rec.cfg_id := null; end if; g_session_rec.id := get_next_session_id; if nvl( p_workarea_irid, -2) <> -1 then g_session_rec.workarea_irid:= p_workarea_irid; end if; g_session_rec.username:= user; g_session_rec.number_of_requests:= 1; g_session_rec.timestamp_creation:= sysdate; g_session_rec.timestamp_last_call:= sysdate; insert into odwa_sessions ( id , workarea_irid , username , timestamp_creation , timestamp_last_call , number_of_requests , pac_irid , pac_ivid , pac_type_id , folder_irid , folder_ivid , cfg_id ) values ( g_session_rec.id , g_session_rec.workarea_irid , g_session_rec.username , g_session_rec.timestamp_creation , g_session_rec.timestamp_last_call , g_session_rec.number_of_requests , g_session_rec.pac_irid , g_session_rec.pac_ivid , g_session_rec.pac_type_id , g_session_rec.folder_irid , g_session_rec.folder_ivid , g_session_rec.cfg_id ); commit; jr_context.set_workarea( workarea_irid => g_session_rec.workarea_irid); end; -- open_session procedure update_session is begin update odwa_sessions set workarea_irid = g_session_rec.workarea_irid , username = g_session_rec.username , number_of_requests = g_session_rec.number_of_requests , timestamp_creation = g_session_rec.timestamp_creation , timestamp_last_call = g_session_rec.timestamp_last_call , pac_irid = g_session_rec.pac_irid , pac_ivid = g_session_rec.pac_ivid , pac_type_id = g_session_rec.pac_type_id , folder_irid = g_session_rec.folder_irid , folder_ivid = g_session_rec.folder_ivid , cfg_id = g_session_rec.cfg_id where id = g_session_rec.id ; commit; jr_context.set_workarea( workarea_irid => g_session_rec.workarea_irid); end; -- update_session function changed ( p_new_value in number , p_old_value in out number ) return boolean is begin -- CHANGED if p_old_value is NULL and p_new_value is not -- or p_old_value is not null and p_new_value is not null and different than p_old_value if nvl( p_new_value,-1) <> -1 then p_old_value:= p_new_value; end if; if nvl(p_old_value, -19690915) <> nvl(p_new_value, -19690915) and nvl(p_new_value, 0) <> -1 -- since -1 is the default value, p_new_value is -1 indicates NO Change then p_old_value:= p_new_value; return true; else return false; end if; end; -- changed -- returns string indicating the current context. Something like: -- or function get_context_label ( p_include_icons in boolean default true , p_include_links in boolean default false -- links to Launchpad for context components , p_workarea_irid in number default odwactxt.get_workarea_irid , p_folder_irid in number default odwactxt.get_folder_irid , p_folder_ivid in number default odwactxt.get_folder_ivid , p_cfg_id in number default odwactxt.get_cfg_id , p_include_folder_versions in boolean default true , p_include_folder in boolean default true , p_include_workarea in boolean default true , p_include_config in boolean default true ) return varchar2 is l_label varchar2(4000); l_folder_irid number(38); l_vlabel varchar2(200); function wrapfolder ( p_folder in varchar2 , p_maxlength in number , p_max_iter in number --safety catch ) return varchar2 is l_folder varchar2(4000) := substr(p_folder,1,p_maxlength); l_tail varchar2(4000); l_break number; l_break2 number; begin if (p_max_iter = 0) or nvl(length(p_folder),0) <= p_maxlength then return p_folder; else -- find last "/" within max length bound l_break := instr(l_folder,'/',-1); l_break2 := instr(l_folder,' ',-1); if l_break2 > l_break then l_break := l_break2; end if; if l_break = 0 then -- if no "/" or " ", just break at maxlength l_break := p_maxlength; end if; l_tail := substr(p_folder,l_break+1); return substr(p_folder,1,l_break)||'..
..'||wrapfolder(l_tail,p_maxlength,p_max_iter-1); end if; end; begin if p_cfg_id is not null and p_include_config then l_label:=cdwp.add_images( '{configuration.gif}') ||cdwpbase.get_cfg_name( p_cfg_ivid => to_number( odwactxt.get_cfg_id), p_format => 'VLABEL') ||cdwpbase.nbsp(3) ; end if; -- p_cfg_id is not null if p_workarea_irid is not null and p_include_workarea then l_label:= cdwp.add_images( '{workarea.gif}') ||cdwpbase.get_wa_name( p_wa_irid => p_workarea_irid) ||cdwpbase.nbsp(3) ; end if; -- p_workarea_irid is not null if nvl( p_folder_ivid, p_folder_irid) is null then if nvl( odwactxt.get_pac_ivid, odwactxt.get_pac_irid) is not null then -- derive Folder Context from owning folder l_folder_irid:= jr_acc_rights.get_owning_container ( nvl ( odwactxt.get_pac_irid , cdwpbase.get_irid( odwactxt.get_pac_ivid) ) ); end if; else l_folder_irid := p_folder_irid; end if; -- nvl( p_folder_ivid, p_folder_irid) is not null if nvl( p_folder_ivid, l_folder_irid) is not null and p_include_folder then if p_include_folder_versions then l_vlabel:= odwavrsn.get_version_label( p_ivid => p_folder_ivid); end if; l_label:= l_label ||cdwp.add_images ( p_text => '{' ||cdwpbase.ifThenElse ( cdwpbase.get_el_type_of( l_folder_irid) = 'APP' , 'app_sys' , 'folder' ) ||'.gif}' ) ||wrapfolder ( jr_name.get_path( id=> nvl( p_folder_ivid , cdwpbase.get_best_ivid( l_folder_irid) ) , format => 'NAME' ) , 70 -- wrap to this length , 5 -- dont wrap more times than this ) ||cdwpbase.ifThenElse ( p_include_folder_versions and l_vlabel is not null , '(' ||l_vlabel ||')' ) ; end if; -- nvl( p_folder_ivid, p_folder_irid) is not null and p_include_folder return l_label ; end; -- get_context_label -- returns the context type; values are: -- FOL, WA, CFG, FOL_IN_WA, FOL_IN_CFG, function get_conxtext_type return varchar2 is l_root_type varchar2(10); l_type_of varchar2(10); begin if odwactxt.get_cfg_id is not null then l_root_type := 'CFG'; elsif odwactxt.get_workarea_irid is not null then l_root_type := 'WA'; end if; if nvl( odwactxt.get_folder_irid, odwactxt.get_folder_ivid) is not null then l_type_of := 'FOL'; -- consider APP? return l_type_of ||cdwpbase.ifThenElse ( l_root_type in ('WA','CFG') , '_IN_'||l_root_type ); else return l_root_type; end if; end; -- get_context_type function check_in_wa ( p_irid in number default null , p_ivid in number , p_wa_irid in number ) return boolean is cursor c_irid_wac ( b_irid in number , b_wa_irid in number ) is select 'x' from dual where exists ( select 'x' from i$sdd_object_versions ov , i$sdd_wa_context wac where wac.workarea_irid = b_wa_irid and wac.object_ivid = ov.ivid and ov.irid = b_irid ) ; cursor c_ivid_wac ( b_ivid in number , b_wa_irid in number ) is select 'x' from dual where exists ( select 'x' from i$sdd_wa_context wac where wac.workarea_irid = b_wa_irid and wac.object_ivid = b_ivid ) ; r_wac c_irid_wac%rowtype; begin if p_ivid is null then open c_irid_wac ( b_irid => p_irid , b_wa_irid => p_wa_irid ); fetch c_irid_wac into r_wac; if c_irid_wac%FOUND then close c_irid_wac; return true; else close c_irid_wac; return false; end if; -- c_irid_wac%FOUND else open c_ivid_wac ( b_ivid => p_ivid , b_wa_irid => p_wa_irid ); fetch c_ivid_wac into r_wac; if c_ivid_wac%FOUND then close c_ivid_wac; return true; else close c_ivid_wac; return false; end if; -- c_ivid_wac%FOUND end if; -- b_ivid is null end; -- check_in_wa function check_in_cfg ( p_irid in number default null , p_ivid in number , p_cfg_id in number ) return boolean is cursor c_irid_cfg ( b_irid in number , b_cfg_id in number ) is select 'x' from dual where exists ( select 'x' from i$sdd_object_versions ov , i$sdd_configuration_members cm where cm.config_ivid = b_cfg_id and cm.object_ivid = ov.ivid and ov.irid = b_irid ) ; cursor c_ivid_cfg ( b_ivid in number , b_cfg_id in number ) is select 'x' from dual where exists ( select 'x' from i$sdd_configuration_members cm where cm.config_ivid = b_cfg_id and cm.object_ivid = b_ivid ) ; r_cfg c_irid_cfg%rowtype; begin if p_ivid is null then open c_irid_cfg ( b_irid => p_irid , b_cfg_id => p_cfg_id ); fetch c_irid_cfg into r_cfg; if c_irid_cfg%FOUND then close c_irid_cfg; return true; else close c_irid_cfg; return false; end if; -- c_irid_cfg%FOUND else open c_ivid_cfg ( b_ivid => p_ivid , b_cfg_id => p_cfg_id ); fetch c_ivid_cfg into r_cfg; if c_ivid_cfg%FOUND then close c_ivid_cfg; return true; else close c_ivid_cfg; return false; end if; -- c_ivid_cfg%FOUND end if; -- b_ivid is null end; -- check_in_cfg -- check if the indicated PAC does exist in the indicated context; -- if not, the context is reset procedure check_pac_in_context ( p_ivid in number , p_irid in number , p_wa_irid in out number , p_cfg_id in out number ) is begin if p_wa_irid is not null then if not check_in_wa ( p_irid => p_irid , p_ivid => p_ivid , p_wa_irid => p_wa_irid ) then p_wa_irid:= null; -- object not found in Workarea Context if p_cfg_id is not null then check_pac_in_context ( p_ivid => p_ivid , p_irid => p_irid , p_wa_irid => p_wa_irid , p_cfg_id => p_cfg_id ); end if; --p_cfg_id is not null else p_cfg_id := null; -- cannot have both Workarea and Configuration Context end if; else if not check_in_cfg ( p_irid => p_irid , p_ivid => p_ivid , p_cfg_id => p_cfg_id ) then p_cfg_id := null; end if; end if; -- p_wa_irid is not null end; -- check_pac_in_context procedure update_context ( p_session_id in number default odwactxt.get_session_id -- when p_session_id = -1, a new session is created , p_workarea_irid in number default -1 -- if p_workarea_irid <> -1 AND <> current context workarea irid, a new session is opened , p_pac_irid in number default -1 -- the irid of the current PAC context , p_pac_ivid in number default -1 -- the ivid of the current PAC context , p_pac_type_id in number default -1 -- the element_type_id of the current PAC context (corresponds with RM_ELEMENT_TYPES.id) , p_folder_irid in number default -1 -- the irid of the current Folder context , p_folder_ivid in number default -1 -- the ivid of the current Folder context , p_cfg_irid in number default -1 -- the irid of the current Configuration context , p_cfg_ivid in number default -1 -- the ivid of the current Configuration context , p_new_request in boolean default true -- if true, the number_of_requests is increased by one , p_package_name in varchar2 default -1 -- the name of the calling package , p_procedure_name in varchar2 default -1 -- the name of the calling procedure ) is l_update boolean:= false; begin -- ALWAYS OPEN NEW SESSION if p_new_request then open_session( p_workarea_irid, p_session_id); else refresh_cache( p_session_id => p_session_id); end if; l_update:= l_update or changed(p_workarea_irid, g_session_rec.workarea_irid); -- if no pac_irid provided, but there is a pac_ivid, derive the pac_irid from the ivid l_update:= l_update or changed( cdwpbase.ifThenElse ( nvl( p_pac_irid,-1) = -1 and nvl( p_pac_ivid,-1) <> -1 , cdwpbase.get_irid( p_ivid => p_pac_ivid) , p_pac_irid ) , g_session_rec.pac_irid ); l_update:= l_update or changed(p_pac_ivid , g_session_rec.pac_ivid); l_update:= l_update or changed(p_pac_type_id , g_session_rec.pac_type_id); -- if no folder_irid provided, but there is a folder_ivid, derive the folder_irid from the ivid -- we could also set folder_irid as owning folder for pac_irid (when provided) l_update:= l_update or changed( nvl( p_folder_irid , cdwpbase.ifThenElse ( nvl( p_folder_ivid,-1) <> -1 , cdwpbase.get_irid( p_ivid => p_folder_ivid) ) ) , g_session_rec.folder_irid ); l_update:= l_update or changed(p_folder_ivid , g_session_rec.folder_ivid); l_update:= l_update or changed(p_cfg_ivid , g_session_rec.cfg_id); if p_new_request then g_session_rec.number_of_requests:= g_session_rec.number_of_requests + 1; l_update:= true; end if; if nvl( g_session_rec.pac_ivid, g_session_rec.pac_irid) is not null then if nvl( g_session_rec.cfg_id, g_session_rec.workarea_irid) is not null then check_pac_in_context ( p_ivid => g_session_rec.pac_ivid , p_irid => g_session_rec.pac_irid , p_wa_irid => g_session_rec.workarea_irid , p_cfg_id => g_session_rec.cfg_id ); end if; end if; if l_update then g_session_rec.timestamp_last_call:= sysdate; update_session; end if; -- l_update = true end; -- update_context end; -- package body odwactxt /