-- Data model to support content repository of the ArsDigita -- Community System -- Copyright (C) 1999-2000 ArsDigita Corporation -- Author: Karl Goldstein (karlg@arsdigita.com) -- $Id: content-symlink.sql,v 1.8 2004/03/12 18:48:46 jeffd Exp $ -- This is free software distributed under the terms of the GNU Public -- License. Full text of the license is available from the GNU Project: -- http://www.fsf.org/copyleft/gpl.html create or replace package body content_symlink as function new ( name in cr_items.name%TYPE default null, label in cr_symlinks.label%TYPE default null, target_id in cr_items.item_id%TYPE, parent_id in cr_items.parent_id%TYPE, symlink_id in cr_symlinks.symlink_id%TYPE default null, creation_date in acs_objects.creation_date%TYPE default sysdate, creation_user in acs_objects.creation_user%TYPE default null, creation_ip in acs_objects.creation_ip%TYPE default null, package_id in acs_objects.package_id%TYPE ) return cr_symlinks.symlink_id%TYPE is v_symlink_id cr_symlinks.symlink_id%TYPE; v_package_id acs_objects.package_id%TYPE; v_name cr_items.name%TYPE; v_label cr_symlinks.label%TYPE; begin -- SOME CHECKS -- -- 1) check that the target is now a symlink if content_symlink.is_symlink( target_id ) = 't' then raise_application_error(-20000, 'Cannot create a symlink to a symlink ' || target_id); end if; -- 2) check that the parent is a folder if content_folder.is_folder(parent_id) = 'f' then raise_application_error(-20000, 'The parent is not a folder'); end if; -- 3) check that parent folder supports symlinks if content_folder.is_registered(parent_id,'content_symlink') = 'f' then raise_application_error(-20000, 'This folder does not allow symlinks to be created'); end if; -- 4) check that the content folder supports the target item's content type if content_folder.is_registered( parent_id,content_item.get_content_type(target_id)) = 'f' then raise_application_error(-20000, 'This folder does not allow symlinks to items of type ' || content_item.get_content_type(target_id) || ' to be created'); end if; -- PASSED ALL CHECKS -- -- Select default name if the name is null begin if name is null then select 'symlink_to_' || name into v_name from cr_items where item_id = target_id; else v_name := name; end if; exception when no_data_found then v_name := null; end; -- Select default label if the label is null if content_symlink.new.label is null then v_label := 'Symlink to ' || v_name; else v_label := content_symlink.new.label; end if; if package_id is null then v_package_id := acs_object.package_id(new.parent_id); else v_package_id := package_id; end if; v_symlink_id := content_item.new( item_id => content_symlink.new.symlink_id, name => v_name, package_id => v_package_id, content_type => 'content_symlink', creation_date => content_symlink.new.creation_date, creation_user => content_symlink.new.creation_user, creation_ip => content_symlink.new.creation_ip, parent_id => content_symlink.new.parent_id ); insert into cr_symlinks (symlink_id, target_id, label) values (v_symlink_id, content_symlink.new.target_id, v_label); update acs_objects set title = v_label where object_id = v_symlink_id; return v_symlink_id; end new; procedure del ( symlink_id in cr_symlinks.symlink_id%TYPE ) is begin delete from cr_symlinks where symlink_id = content_symlink.del.symlink_id; content_item.del(content_symlink.del.symlink_id); end del; function is_symlink ( item_id in cr_items.item_id%TYPE ) return char is v_symlink_p integer := 0; begin select count(*) into v_symlink_p from cr_symlinks where symlink_id = is_symlink.item_id; if v_symlink_p = 1 then return 't'; else return 'f'; end if; end is_symlink; procedure copy ( symlink_id in cr_symlinks.symlink_id%TYPE, target_folder_id in cr_folders.folder_id%TYPE, creation_user in acs_objects.creation_user%TYPE, creation_ip in acs_objects.creation_ip%TYPE default null, name in cr_items.name%TYPE default null ) is v_current_folder_id cr_folders.folder_id%TYPE; v_name cr_items.name%TYPE; v_target_id cr_items.item_id%TYPE; v_label cr_symlinks.label%TYPE; v_symlink_id cr_symlinks.symlink_id%TYPE; begin if content_folder.is_folder(copy.target_folder_id) = 't' then select parent_id into v_current_folder_id from cr_items where item_id = copy.symlink_id; select i.name, content_symlink.resolve(i.item_id), s.label into v_name, v_target_id, v_label from cr_symlinks s, cr_items i where s.symlink_id = i.item_id and s.symlink_id = copy.symlink_id; -- can't copy to the same folder if copy.target_folder_id ^= v_current_folder_id or (v_name != copy.name and copy.name is not null) then if copy.name is not null then v_name := copy.name; end if; if content_folder.is_registered(copy.target_folder_id, 'content_symlink') = 't' then if content_folder.is_registered(copy.target_folder_id, content_item.get_content_type(resolve(copy.symlink_id))) = 't' then v_symlink_id := content_symlink.new( parent_id => copy.target_folder_id, name => v_name, label => v_label, target_id => v_target_id, creation_user => copy.creation_user, creation_ip => copy.creation_ip ); end if; end if; end if; end if; end copy; function resolve ( item_id in cr_items.item_id%TYPE ) return cr_items.item_id%TYPE is v_target_id cr_items.item_id%TYPE; begin select target_id into v_target_id from cr_symlinks where symlink_id = resolve.item_id; return v_target_id; exception when no_data_found then return resolve.item_id; end resolve; function resolve_content_type ( item_id in cr_items.item_id%TYPE ) return cr_items.content_type%TYPE is v_content_type cr_items.content_type%TYPE; begin select content_item.get_content_type( target_id ) into v_content_type from cr_symlinks where symlink_id = resolve_content_type.item_id; return v_content_type; exception when NO_DATA_FOUND then return null; end resolve_content_type; end content_symlink; / show errors -- Convenience view to simply access to symlink targets create or replace view cr_resolved_items as select i.parent_id, i.item_id, i.name, decode(s.target_id, NULL, 'f', 't') is_symlink, nvl(s.target_id, i.item_id) resolved_id, s.label from cr_items i, cr_symlinks s where i.item_id = s.symlink_id (+);