REM *************************************************************************** REM Hand-carved package body for METHOD created on 16-OCT-98 REM *************************************************************************** CREATE OR REPLACE PACKAGE BODY cihmet IS -- Generic post-process routines PROCEDURE check_delete(id number); PROCEDURE create_metrul(id number, pl ciomethod.data); sac_type constant varchar2(6) := 'MET'; pac_type constant varchar2(6) := 'CLA'; --======================== PRE-PROCESS (INS,UPD) ============================-- PROCEDURE pre_process(operation varchar2,id number, pl in out NOCOPY ciomethod.data) IS cursor class_name_c(class_id number) IS select class_name from sdd_cla where irid = class_id; CURSOR int_classifier_c(class_id number) IS select 1 from ci_classifiers where irid = class_id and classifier_subtype = 'INC'; BEGIN -- Access rights for method derive from the classifier -- Access rights checking performed by triggers in config 4.0.9 -- ciiacc.check_access_rights(pl.v.classifier_reference,pac_type, -- 'UPD','SHR'); -- Initialize unassigned properties with default values on INSERT if operation = 'INS' then pl.v.element_type_name := sac_type; pl.i.element_type_name := true; if not cdapi.load_mode then -- Temp fix -- This could go wrong very rarely, but if this was loaded into a new -- appsys, given a new id, and then another MET was created (or already -- existed) with the old id this one had, then there would be two -- identical internal names pl.v.internal_name := pl.v.name || pl.v.id; pl.i.internal_name := true; end if; if not pl.i.sequence then pl.v.sequence :=ciiexp.default_seq( pl.v.classifier_reference, sac_type); pl.i.sequence :=true; end if; pl.v.return_type_defined_by := 'NONE'; -- but see below pl.i.return_type_defined_by := true; --set return_type_scalar if pl.v.return_classifier_reference IS NULL and pl.v.return_type_scalar IS NULL then if pl.v.constructor_flag != 'Y' then pl.v.return_type_scalar := 'void'; pl.i.return_type_scalar := true; end if; end if; elsif operation = 'UPD' and pl.v.visibility != 'PUBLIC' and pl.i.visibility then pl.v.exported_flag := 'N'; pl.i.exported_flag := true; end if; -- Remove spaces from name pl.v.name := REPLACE (pl.v.name, ' ', NULL); pl.i.name := true; --set return_type_defined_by if method name and classifier name match FOR class_name_rec in class_name_c(pl.v.classifier_reference) LOOP if class_name_rec.class_name = pl.v.name then pl.v.constructor_flag := 'Y'; pl.i.constructor_flag := true; pl.v.return_type_defined_by := 'NONE'; pl.i.return_type_defined_by := true; pl.v.return_type_scalar := NULL; pl.i.return_type_scalar := true; pl.v.return_classifier_reference := NULL; pl.i.return_classifier_reference := true; pl.v.static_flag := 'N'; pl.i.static_flag := true; pl.v.overridable := 'MAY'; pl.i.overridable := true; else pl.v.constructor_flag := 'N'; pl.i.constructor_flag := true; if pl.i.return_type_scalar or pl.i.return_classifier_reference then if pl.v.return_type_scalar is not null then pl.v.return_type_defined_by := 'SCALAR'; pl.i.return_type_defined_by := true; elsif pl.v.return_classifier_reference is not null then pl.v.return_type_defined_by := 'CLASSIFIER'; pl.i.return_type_defined_by := true; end if; elsif pl.v.return_type_scalar IS NULL and pl.v.return_classifier_reference IS NULL then pl.v.return_type_defined_by := 'NONE'; pl.i.return_type_defined_by := true; end if; end if; END LOOP; -- set overridable depending on visibility -- this takes precedence over above where overiddable could have been set to 'MAY' if pl.v.visibility = 'PRIVATE' and pl.i.visibility then pl.v.overridable := 'CANNOT'; pl.i.overridable := true; end if; --Bug #1019127 --if methods is in a Interface Classifier then default overridable_flag FOR int_classifier_rec IN int_classifier_c(pl.v.classifier_reference) LOOP pl.v.overridable := 'MUST'; pl.i.overridable := true; END LOOP; -- The following constraint is documented in each of the classifier sub-type specs if pl.i.overridable and pl.v.overridable = 'MUST' then update sdd_cla set abstract_flag = 'Y' where irid = pl.v.classifier_reference; end if; --Maintain the out_of_sync_flag for a corresponding file_usage ciheoc.maintain_sync_flag(pl.v.classifier_reference); END; --======================== PRE-PROCESS (DEL,SEL) ============================-- PROCEDURE pre_process(operation varchar2,id number) IS CURSOR file_c(irid_ref number) IS select classifier_reference cla from ci_methods where irid = irid_ref; BEGIN -- Access rights for method derive from the classifier -- Access rights checking performed by triggers in config 4.0.9 -- ciiacc.check_access_rights(id,sac_type,operation,'SAC'); -- if operation is 'DELETE', make sure no non-cascading references exist if operation = 'DEL' then check_delete(id); FOR file_rec IN file_c(pre_process.id) LOOP --Maintain the out_of_sync_flag for a corresponding file_usage ciheoc.maintain_sync_flag(file_rec.cla); END LOOP; end if; END; --===================== POST-PROCESS (INS,UPD,SEL) ==========================-- PROCEDURE post_process(operation varchar2,id number, pl ciomethod.data) IS dummy number; error_flag boolean := false; CURSOR visibility_c(irid_ref number) IS select visibility from ci_methods where irid = irid_ref; CURSOR calltype_c(irid_ref number, calltype varchar2) IS select metrul.named_rule_reference rule_ref from ci_method_rule_usages metrul ,ci_activity_definitions act ,ci_named_rules rul where act.method_reference = irid_ref and metrul.call_type = calltype and metrul.named_rule_reference = rul.irid and metrul.method_reference = irid_ref; superCount number := 0; k number; superTypes cihclacla.superType_type; BEGIN /* now moved to Activity if operation = 'INS' and pl.i.activity_reference then create_metrul(id, pl); end if; */ if (operation = 'INS' or (operation = 'UPD' and (pl.i.internal_name or pl.i.name)))then --deferred unique name check rmman.log_change('CIHMETE_INT_UNIQUE',pl.v.id); rmman.log_change('CIHMETE_UNIQUE_NAME',pl.v.id); end if; if operation != 'SEL' then -- Bug 1024673, removed constraints on external_flag if pl.v.overriding_method_reference IS NOT NULL then --check that Overriding_Method_Ref is valid superTypes := cihclacla.get_ClassifierSuperTypes(pl.v.classifier_reference); for k in 1..superTypes.COUNT LOOP select count(*) into dummy from ci_methods where classifier_reference = superTypes(k) and irid = pl.v.overriding_method_reference and classifier_reference != pl.v.classifier_reference; --get_SuperTypes also returns the root of the super types so the --last and here is to make sure that one does not get included. if dummy is not null then superCount := superCount + dummy; end if; END LOOP; if superCount < 1 then --%0!s: An overriding Method must be in one of the super-types ciierr.post(2091,ciiutl.identify(id, 'EAT')); --ciierr.post(superCount,ciiutl.identify(id, 'EAT')); error_flag := true; end if; end if; --visibilty constraint----------------------------------------------- FOR vis_rec in visibility_c(pl.v.overriding_method_reference) LOOP if pl.v.visibility = 'PRIVATE' then if vis_rec.visibility = 'PUBLIC' or vis_rec.visibility = 'PACKAGE' or vis_rec.visibility = 'PROTECTED' then --%0!s: Visibility of overriden Method may not be less than overriding Method ciierr.post(2085,ciiutl.identify(id, 'MET')); error_flag := true; end if; elsif pl.v.visibility = 'PROTECTED' then if vis_rec.visibility = 'PUBLIC' or vis_rec.visibility = 'PACKAGE' then --%0!s: Visibility of overriden Method may not be less than overriding Method ciierr.post(2085,ciiutl.identify(id, 'MET')); error_flag := true; end if; elsif pl.v.visibility = 'PACKAGE' then if vis_rec.visibility = 'PUBLIC' then --%0!s: Visibility of overriden Method may not be less than overriding Method ciierr.post(2085,ciiutl.identify(id, 'MET')); error_flag := true; end if; end if; END LOOP; --call type constraints---------------------------------------------------- dummy := null; FOR calltype_rec in calltype_c(post_process.id, 'PRE') LOOP select count(*) into dummy from ci_activity_definitions where pre_rule_reference = calltype_rec.rule_ref; if dummy IS NULL then --%0!s: Method and Activity Definition refs to Named Rule must match -%1!s: ciierr.post(2092,ciiutl.identify(id, 'MET'), 'PRE'); error_flag := true; end if; END LOOP; dummy := null; FOR calltype_rec in calltype_c(post_process.id, 'POST') LOOP select count(*) into dummy from ci_activity_definitions where post_rule_reference = calltype_rec.rule_ref; if dummy IS NULL then --%0!s: Method and Activity Definition refs to Named Rule must match -%1!s: ciierr.post(2092,ciiutl.identify(id, 'MET'), 'POST'); error_flag := true; end if; END LOOP; end if; if error_flag then raise cdapi.apierror; end if; END; --========================= POST PROCESS (DEL, LCK) ==============================-- PROCEDURE post_process(operation varchar2,id number) IS CURSOR cfilpac IS select usage.primary_access_file_reference file_irid , usage.irid fu_irid from ci_file_usages usage , ci_methods met where usage.classifier_reference = met.classifier_reference and met.id = post_process.id; vfile_irid number; vfu_irid number; BEGIN if operation = 'LCK' then FOR files_rec IN cfilpac LOOP vfile_irid := files_rec.file_irid; vfu_irid := files_rec.fu_irid; cioprimary_access_file.lck(files_rec.file_irid); END LOOP; end if; EXCEPTION WHEN cioprimary_access_file.invalid_ref then ciierr.fatal(6089,ciiutl.identify(id, 'MET'), to_char(vfile_irid), ciiutl.identify(vfu_irid, 'FILPAC')); raise; WHEN OTHERS then raise; END; --============================= CHECK DELETE ================================-- PROCEDURE check_delete(id number) IS dummy number; error_flag boolean := false; BEGIN null; /* Bug 1024673, constraints on external_flag removed select count(*) into dummy from ci_generic_classes gen ,ci_methods met where met.irid = check_delete.id and gen.irid = met.classifier_reference and gen.external_flag = 'Y'; if dummy > 0 then --%0!s: A method referencing an external Generic Class cannot be deleted ciierr.post(108,ciiutl.identify(id, 'MET')); raise cdapi.apierror; end if; */ END; --========================= CREATE METRUL =====================================-- PROCEDURE create_metrul(id number, pl ciomethod.data) IS save_csynch boolean; metrulpl ciomethod_rule_usage.data; pre_rule_id number; post_rule_id number; BEGIN if cdapi.load_mode then return; end if; /* select act.pre_rule_ref , act.post_rule_ref into pre_rule_id , post_rule_id from sdd_act act where act.irid = pl.v.activity_reference; metrulpl.v.method_reference := pl.v.id; metrulpl.i.method_reference := true; if pre_rule_id is not NULL then metrulpl.v.named_rule_reference := pre_rule_id; metrulpl.v.call_type := 'PRE'; elsif post_rule_id is not NULL then metrulpl.v.named_rule_reference := post_rule_id; metrulpl.v.call_type := 'POST'; else return; end if; metrulpl.i.named_rule_reference := true; metrulpl.i.call_type := true; save_csynch := rm.do_csynch; rm.do_csynch := true; ciomethod_rule_usage.ins(null, metrulpl); rm.do_csynch := save_csynch; */ exception -- In case ins call fails, must not be left in system mode when others then rm.do_csynch := save_csynch; raise; end; --================================== MAINTAIN CONSTRUCTOR FLAG ==============-- PROCEDURE maintain_constructor_flag(name varchar2, id number) IS BEGIN update ci_methods met set constructor_flag = 'Y' where met.name = maintain_constructor_flag.name and met.classifier_reference = maintain_constructor_flag.id; update ci_methods met set constructor_flag = 'N' where met.name != maintain_constructor_flag.name and met.classifier_reference = maintain_constructor_flag.id; END; --================================== END ====================================-- -- -- Package instantiation block -- BEGIN is_installed := true; END; /