rem rem $Header: L:\\\\model\\repman40\\api\\RCS\\cient.hpb 1.1 1998/12/16 16:40:23 cvanes Exp $ rem Rem Copyright (c) 1994 by Oracle Corporation Rem NAME Rem cient.hpb - Rem DESCRIPTION Rem Rem RETURNS Rem Rem NOTES Rem Rem MODIFIED (MM/DD/YY) Rem loldham 16/12/98 - Remove denormalised supertype_name Rem jwetherb 10/22/94 - Fix bug with sub-types in check_delete Rem jwetherb 09/22/94 - synonym_reference -> entity_reference Rem jwetherb 09/13/94 - Creation REM *************************************************************************** REM Hand-carved package body for ENTITY created on 09-SEP-94 REM *************************************************************************** CREATE OR REPLACE PACKAGE BODY cihent IS -- Generic post-process routines PROCEDURE check_delete(id number); PROCEDURE connect_subtypes(entity_ref number , ae_as_ref number , ae_application_system varchar2); --#BEGIN -- Type-specific pre-process routines PROCEDURE get_plural(id number,name varchar2,plural in out NOCOPY varchar2); PROCEDURE get_short_name(id number,name varchar2, short_name in out NOCOPY varchar2); FUNCTION is_duplicate_short_name(short_name varchar2, entity_ref number default 0) RETURN boolean; -- Type-specific pre-process routines PROCEDURE connect_ent(ent_reference number,as_ref number,as_name varchar2); PROCEDURE connect_to_parent(curr_ent_supertype_ref number, curr_ent_reference number); FUNCTION get_abbreviation(name varchar2, max_len number) RETURN varchar2; -- Miscellaneous variables to store old property values old_name varchar2(240); old_short_name varchar2(100); old_plural varchar2(240); old_supertype_reference number(38); --#END pac_type constant varchar2(6) := 'ENT'; --======================== PRE-PROCESS (INS,UPD) ============================-- PROCEDURE pre_process(operation varchar2,id number, pl in out NOCOPY cioentity.data) IS BEGIN -- Access control checks -- Access rights checking performed by triggers in config 4.0.9 -- ciiacc.check_access_rights(pl.v.id,pac_type,operation,'SHR'); -- Validate user-defined properties if cieval.is_extended then cieval.check_element(id,pl.v.types,(operation='UPD') ,pl.v.user_defined_property_0,pl.i.user_defined_property_0 ,pl.v.user_defined_property_1,pl.i.user_defined_property_1 ,pl.v.user_defined_property_2,pl.i.user_defined_property_2 ,pl.v.user_defined_property_3,pl.i.user_defined_property_3 ,pl.v.user_defined_property_4,pl.i.user_defined_property_4 ,pl.v.user_defined_property_5,pl.i.user_defined_property_5 ,pl.v.user_defined_property_6,pl.i.user_defined_property_6 ,pl.v.user_defined_property_7,pl.i.user_defined_property_7 ,pl.v.user_defined_property_8,pl.i.user_defined_property_8 ,pl.v.user_defined_property_9,pl.i.user_defined_property_9 ,pl.v.user_defined_property_10,pl.i.user_defined_property_10 ,pl.v.user_defined_property_11,pl.i.user_defined_property_11 ,pl.v.user_defined_property_12,pl.i.user_defined_property_12 ,pl.v.user_defined_property_13,pl.i.user_defined_property_13 ,pl.v.user_defined_property_14,pl.i.user_defined_property_14 ,pl.v.user_defined_property_15,pl.i.user_defined_property_15 ,pl.v.user_defined_property_16,pl.i.user_defined_property_16 ,pl.v.user_defined_property_17,pl.i.user_defined_property_17 ,pl.v.user_defined_property_18,pl.i.user_defined_property_18 ,pl.v.user_defined_property_19,pl.i.user_defined_property_19 ); end if; -- Initialize unassigned properties with default values on INSERT if operation = 'INS' then pl.v.element_type_name := pac_type; pl.i.element_type_name := true; pl.v.instantiable_flag := 'Y'; pl.i.instantiable_flag := true; end if; --#BEGIN if operation = 'UPD' then select name,short_name,plural,supertype_reference into old_name,old_short_name,old_plural,old_supertype_reference from ci_entities where id = pl.v.id; end if; -- Assign denormalized and derived property values -- If the (plural) is not provided, generate it if pl.v.plural is null and pl.v.name is not null then get_plural(pl.v.id,pl.v.name,pl.v.plural); -- If the plural name is not unique, set it to the entity name if (cihsyn.is_duplicate(pl.v.plural,pl.v.id)) then pl.v.plural := pl.v.name; end if; pl.i.plural := true; end if; -- If the (short_name) is not provided, generate it if pl.v.short_name is null and pl.v.name is not null then -- The short name will come back as the name or as a unique synonym get_short_name(pl.v.id,pl.v.name,pl.v.short_name); pl.i.short_name := true; end if; --#END END; --======================== PRE-PROCESS (DEL,SEL) ============================-- PROCEDURE pre_process(operation varchar2,id number) IS BEGIN -- Access control checks -- Access rights checking performed by triggers in config 4.0.9 -- ciiacc.check_access_rights(id,pac_type,operation,'SHR'); -- if operation is 'DELETE', make sure no non-cascading references exist if operation = 'DEL' then check_delete(id); end if; END; --===================== POST-PROCESS (INS,UPD,SEL) ==========================-- PROCEDURE post_process(operation varchar2,id number, pl in out NOCOPY cioentity.data) IS supertype_owner number; BEGIN if operation = 'INS' then rmdbg.trace('Creating APPENT...'); ciiutl.create_appxxx(pac_type,pl.v.id,pl.v.name); elsif operation = 'UPD' and (pl.i.name or pl.i.short_name or pl.i.plural) then cioapp_con_interface.traverse('CIHAPPCONU1',id,'APPENT'); end if; --#BEGIN -- hand-carved referential integrity constraint checks if operation in ('INS','UPD') and pl.i.supertype_reference and pl.v.supertype_reference is not null then select fm.folder_reference into supertype_owner from sdd_folder_members fm where fm.member_object = pl.v.supertype_reference and fm.ownership_flag = 'Y'; if (supertype_owner <> cdapi.app_sys_ref) then ciierr.fatal(1010,ciiutl.identify(id, 'ENT'),ciiutl.identify(pl.v.supertype_reference, 'ENT')); end if; -- check that the specified supertype is not a subtype rmdbg.trace('Calling log_change'); rmman.log_change('CIHENTE_SUPER_IS_SUB',pl.v.id); end if; if cdapi.load_mode then return; end if; -- if a supertype is provided, connect the entity to those applications -- the supertype is connected to -- REMOVED DUE TO 1008868 --if operation in ('INS','UPD') and -- pl.i.supertype_reference and pl.v.supertype_reference is not null then -- rmdbg.trace('Calling connect to parent'); -- connect_to_parent(pl.v.supertype_reference,pl.v.id); --end if; if pl.i.supertype_reference then if (pl.v.supertype_reference is not null and operation = 'INS') or (pl.v.supertype_reference is not null and pl.v.supertype_reference != old_supertype_reference and operation = 'UPD') then rmdbg.trace('Updating instantiable flag'); update sdd_ent set instantiable_flag = 'N' where id = pl.v.supertype_reference; elsif operation = 'UPD' and pl.v.supertype_reference != old_supertype_reference and old_supertype_reference is not null then update sdd_ent set instantiable_flag = 'Y' where id = old_supertype_reference and not exists (select null from sdd_ent where supertype_ref = old_supertype_reference); end if; end if; --#END END; --========================= POST PROCESS (DEL) ==============================-- PROCEDURE post_process(operation varchar2,id number) IS BEGIN if operation = 'DEL' then -- Delete the entity and all it's related sub-bits ciiutl.delete_element(id,pac_type); end if; END; --============================= CHECK DELETE ================================-- PROCEDURE check_delete(id number) IS dummy number; error_count number := 0; BEGIN null; -- 4.0.12 Removed all simple delete checking -- Check if this entity is connected to other application systems -- Check if any events are connected to me -- Check if any externals are connected to me -- Check if referenced from a Function -- Check if sub-types exist END; --#BEGIN --=========================== CONNECT TO PARENT =============================-- PROCEDURE connect_to_parent(curr_ent_supertype_ref number, curr_ent_reference number) IS top_ent number; cur_supertype number; /* apps to which the current entity or the parent is connected */ /* minus */ /* apps to which both the current entity and the parent are connected */ cursor new_apps is select app.name ae_application_system , appent.application_system_reference ae_as_ref from ci_app_sys_entities appent, sdd_folders app where appent.entity_reference in (curr_ent_supertype_ref, curr_ent_reference) and appent.application_system_reference = app.irid MINUS select app.name , appent.application_system_reference from ci_app_sys_entities appent, sdd_folders app where appent.entity_reference = curr_ent_reference and appent.application_system_reference = app.irid AND exists (select null from ci_app_sys_entities where entity_reference = curr_ent_supertype_ref) ; cursor walk_down (p_id number) is select id, supertype_reference from ci_entities where supertype_reference = p_id; /* cursor walk_up is select id from ci_entities connect by id = prior supertype_reference START with id = curr_ent_supertype_ref ; cursor walk_down is select id from ci_entities connect by supertype_reference = prior id START with id = top_ent ; */ BEGIN rmdbg.trace('Starting connect_to_parent'); cur_supertype := curr_ent_supertype_ref; while (cur_supertype <> 0) loop rmdbg.trace('Start loop, cur_supertype is :'||to_char(cur_supertype)); top_ent := cur_supertype; cur_supertype := get_supertype(cur_supertype); rmdbg.trace('End loop, cur_supertype is :'||to_char(cur_supertype)); end loop; for app in new_apps loop /* Added this code as new but can't get it to go through this loop */ /* Hence this code may not actually work !! */ rmdbg.trace('Calling connect subtypes'); connect_subtypes(top_ent ,app.ae_as_ref ,app.ae_application_system); end loop; EXCEPTION when others then null; END; --============================ CONNECT ENTITY ===============================-- PROCEDURE connect_ent(ent_reference number,as_ref number,as_name varchar2) IS dummy varchar2(1); appent_id number; BEGIN -- Check whether the entity is already connected to the specified appsys select max(dummy) into dummy from sys.dual where exists (select null from ci_app_sys_entities where entity_reference = ent_reference and application_system_reference = as_ref); -- If entity not already connected, connect it if dummy is null then rmdbg.trace('Calling cioapp_con_interface'); cioapp_con_interface.ins(appent_id,ent_reference,as_ref,'ENT'); end if; END; --============================== GET PLURAL =================================-- PROCEDURE get_plural(id number,name varchar2,plural in out NOCOPY varchar2) IS penultimate varchar2(1); ultimate varchar2(1); temp_plural varchar2(50); nls_lang rm_repositories.nls_language%TYPE; -- line 331 BEGIN temp_plural := name; penultimate := substrb(temp_plural,length(temp_plural)-1, 1); ultimate := substrb(temp_plural,length(temp_plural), 1); -- select nls_language into nls_lang from rm_repositories; if nls_lang != 'US' then plural := name; else if ( substrb(temp_plural,length(temp_plural), 1) = 'Y' ) then penultimate := substrb(temp_plural,length(temp_plural)-1, 1); if ( penultimate = 'A' or penultimate = 'E' or penultimate = 'I' or penultimate = 'O' or penultimate = 'U') then -- as in essays and boys temp_plural := temp_plural||'S'; else -- as in entities temp_plural := rtrim(temp_plural,'Y')||'IES'; end if; elsif ( temp_plural like '%IS' ) then -- as in crisis temp_plural := substrb(temp_plural,1,length(temp_plural)-2)||'ES'; elsif (ultimate in ('X','S') or penultimate||ultimate in ('CH','SH')) then -- as in glass and box and bus and match and wash temp_plural := temp_plural||'ES'; elsif ( temp_plural like '%PERSON' ) then -- a common one this temp_plural := replace(temp_plural,'PERSON','PEOPLE'); elsif ( temp_plural = 'SHEEP' ) then -- the one everyone tries null; elsif ( temp_plural like '%EAU' ) then -- for our French friends temp_plural := temp_plural||'X'; elsif ( ultimate = 'Z' ) then -- for our German friends temp_plural := temp_plural||'EN'; else temp_plural := temp_plural||'S'; end if; -- Raise a warning if the plural could not be generated and defaulted to -- the entity name if ( length(temp_plural) > 40 ) then rmman.record_check('CIHENTW_PLURAL',id,null,null,false, 'Y',ciiutl.identify(id, 'ENT')); plural := name; else plural := temp_plural; end if; end if; END; --============================ GET SHORT NAME ===============================-- PROCEDURE get_short_name(id number,name varchar2, short_name in out NOCOPY varchar2) IS sequence_num integer; base_name varchar2(10); BEGIN short_name := get_abbreviation(name,10); if length(short_name) = 1 then short_name := substr(name, 1,3); end if; -- Append a sequence number to the first 6 characters, and continue -- incrementing the value until the name is unique for entities and synonyms sequence_num := 0; base_name := substrb(short_name,1,9); while (cihsyn.is_duplicate(short_name,id) or is_duplicate_short_name(short_name,id)) LOOP sequence_num := sequence_num + 1; if sequence_num = 10 then base_name := substrb(base_name,1,8); elsif sequence_num = 100 then base_name := substrb(base_name,1,7); end if; short_name := base_name || to_char(sequence_num); end LOOP; END; --=============================== get_abbreviation ==========================-- -- name is the string to be abbreviated -- max_len is the maximum length of the abbreviation FUNCTION get_abbreviation(name varchar2, max_len number) RETURN varchar2 IS short_name varchar2(20); -- the resulting abbreviation long_str_len integer; -- the length in bytes of the incoming string long_str_ptr integer; -- a pointer to the current byte in the in string char_ptr integer; -- a pointer to the current char in the in string next_char varchar2(4); -- maximum number of bytes for a single -- character (presumably Chinese) BEGIN -- initialise long_str_ptr:=1; char_ptr:=1; long_str_len := lengthb(name); next_char := substr(name,char_ptr,1); -- loop until the abbreviation is full while (nvl(lengthb(short_name),0) + lengthb(next_char)) <= max_len loop short_name := short_name || next_char; char_ptr:=char_ptr+1; long_str_ptr:=long_str_ptr+lengthb(next_char); -- loop until either checked all of in string, or we start new word while long_str_ptr < long_str_len loop -- get next whole char (not byte) next_char := substr(name,char_ptr,1); -- if this char is a word seperator ... if next_char = ' ' or next_char = '_' or next_char = '-' or next_char = '.' then char_ptr:=char_ptr+1; long_str_ptr := long_str_ptr + lengthb(next_char); -- ... the next char is a candidate for the abbreviation next_char := substr(name,char_ptr,1); exit; -- inner loop end if; char_ptr:=char_ptr+1; long_str_ptr := long_str_ptr + lengthb(next_char); end loop; -- inner -- if we've checked all of the in string ... if long_str_ptr >= long_str_len then exit; -- outer loop end if; end loop; -- outer return (short_name); END; --======================== IS SHORT NAME A DUPLICATE? ==========================-- function is_duplicate_short_name( short_name varchar2, entity_ref number default 0) return boolean is begin for i in ( select null from ci_entity_namespace_objects ent, ci_app_sys_entities appent where appent.application_system_reference = cdapi.app_sys_ref and appent.entity_reference = ent.irid and (ent.short_name = is_duplicate_short_name.short_name or ent.name = is_duplicate_short_name.short_name or ent.plural = is_duplicate_short_name.short_name) and ent.irid != entity_ref) loop return (true); exit; end loop; return(false); end; --======================== CONNECT SUBTYPES ==========================-- procedure connect_subtypes(entity_ref number, ae_as_ref number ,ae_application_system varchar2) is cursor walk_down (p_subtype number) is select id from ci_entities where supertype_reference = p_subtype; sub_entity_ref number; begin for sub in walk_down(entity_ref) loop rmdbg.trace('In walk_down loop'); connect_subtypes(sub.id, ae_as_ref, ae_application_system ); end loop; rmdbg.trace('About to connect ent :'||to_char(entity_ref)); connect_ent(entity_ref ,ae_as_ref ,ae_application_system); end; --======================== GET SUPERTYPE ==========================-- function get_supertype(entity_ref in number ) return number is cursor walk_up (p_supertype number) is select supertype_reference from ci_entities where id = p_supertype; super_entity_ref number := 0; begin OPEN walk_up (entity_ref); FETCH walk_up into super_entity_ref; CLOSE walk_up; return NVL(super_entity_ref, 0); end; --#END --================================== END ====================================-- -- -- Package instantiation block -- BEGIN is_installed := true; END; /