/** Ths utility will ensure that the instance_name field is correct in that it matches the value of the
    attribute that contains the name of the instance.
   
   ------------------------------------------------------------------------------------------------------ **/

DEFINE VARIABLE lError              AS LOGICAL      NO-UNDO.
define variable cOldValue			as character	no-undo.
define variable cClassList			as character	no-undo.
define variable iLoop				as integer		no-undo.

define buffer rycoi		for ryc_object_instance.
define buffer rycso 	for ryc_smartobject.

function getClassChildren	returns character
	(input pcClass as character) forward.	
	
function inheritsFrom	returns logical
	(input pcClass		  as character,
	 input pcInheritsFrom as character) forward.

PUBLISH "DCU_WriteLog":U ("Updating ryc_object_instance.instance_name fields to reflect the correct instance name.").

PUBLISH "DCU_WriteLog":U ("Replacing h_dynlookup and h_dyncombo with a valid instance name, based on the FieldName attribute.").

/* For SDFs (dyn lookups and/or dyn combos) added by the AppBuilder, the instance name
 * may take the format of H_DYNLOOKUP* or H_DYNCOMBO*. If this is the case, then
 * we use the value of the FieldName attribute and assign it to the instance_name.
 */
for each ryc_object_instance where
		 ( ryc_object_instance.container_smartobject_obj >= 0 and
		   ryc_object_instance.instance_name begins 'h_dynlookup' ) or
		 ( ryc_object_instance.container_smartobject_obj >= 0 and
		   ryc_object_instance.instance_name begins 'h_dyncombo' )
		 no-lock,
   first ryc_smartobject where
	     ryc_smartobject.smartobject_obj = ryc_object_instance.smartobject_obj
		 no-lock:
	FIND FIRST ryc_attribute_value WHERE
			   ryc_attribute_value.attribute_label = "FieldName":U and
			   ryc_attribute_value.object_type_obj = ryc_smartobject.object_Type_obj and
			   ryc_attribute_value.smartobject_obj = ryc_smartobject.smartobject_obj and
			   ryc_attribute_value.object_instance_obj = ryc_object_instance.object_instance_obj
			   no-lock no-error.
	if not available ryc_attribute_Value then			   
	FIND FIRST ryc_attribute_value WHERE
			   ryc_attribute_value.attribute_label = "FieldName":U and
			   ryc_attribute_value.object_type_obj = ryc_smartobject.object_Type_obj and
			   ryc_attribute_value.smartobject_obj = ryc_smartobject.smartobject_obj and
			   ryc_attribute_value.object_instance_obj = 0
			   no-lock no-error.
	if not available ryc_attribute_value then
	do:
		assign lError = yes.
		publish "DCU_WriteLog":U ("Unable to field FieldName attribute for object " + ryc_smartobject.object_filename).
		next.
	end.	/* couldn't find FieldName attribute. */
	
	find rycoi where
		 rowid(rycoi) = rowid(ryc_object_instance)
		 exclusive-lock no-wait no-error.
	if locked rycoi then
	do:
		assign lError = yes.
		publish "DCU_WriteLog":U ("Unable to lock object instance for update.").
		next.	
	end.	/* locked */
	
	assign cOldValue           = ryc_object_instance.instance_name
		   rycoi.instance_name = ryc_attribute_value.character_value no-error.
	if error-status:error then
	do:
		assign lError = yes.
		publish "DCU_WriteLog":U ("Error updating object instance: " + error-status:get-message(1)).
		next.		
	end.	/* error updating */
	
	publish "DCU_WriteLog":U ("Changed instance name from " + cOldValue + " to " + rycoi.instance_name + " (Object Id: " + string(rycoi.object_instance_obj) + ")").
end.	/* all h_dynlookup, h_dyncombo */

PUBLISH "DCU_WriteLog":U ("Replacement of h_dynlookup and h_dyncombo with a valid instance name, completed "
                          + (IF lError THEN "with errors!" ELSE "successfully.") ).
assign lError = no.

/*  For viewers generated by the object generator, the instance name of contained
 *  DataFields may be of the format TableName(space)FieldName. We assume that the
 *  fieldname portion of this is the piece we want to use, and strip off the TableName.
 */
assign cClassList = getClassChildren('DataField').

PUBLISH "DCU_WriteLog":U ("Replacing instance_name of format TableName(space)FieldName with FieldName only.").

do iLoop = 1 to num-entries(cClassList, chr(1)):
	for each ryc_smartobject where
			 ryc_smartobject.object_type_obj = decimal(entry(iLoop,cClassList, chr(1)))
			 no-lock,
	    each ryc_object_instance where
	    	 ryc_object_instance.smartobject_obj = ryc_smartobject.smartobject_obj and
	    	 num-entries(ryc_object_instance.instance_name, " ") = 2 and
	    	 ryc_object_instance.instance_name   = replace(ryc_smartobject.object_Filename, ".":U, " ":U)
	    	 no-lock:
	    	 
		find rycoi where
			 rowid(rycoi) = rowid(ryc_object_instance)
			 exclusive-lock no-wait no-error.
		if locked rycoi then
		do:
			assign lError = yes.
			publish "DCU_WriteLog":U ("Unable to lock object instance for update.").
			next.
		end.	/* locked */
		
		assign cOldValue           = ryc_object_instance.instance_name
			   rycoi.instance_name = entry(2, ryc_object_instance.instance_name, " ":U) no-error.
		if error-status:error then
		do:
			assign lError = yes.
			publish "DCU_WriteLog":U ("Error updating object instance: " + error-status:get-message(1)).
			next.		
		end.	/* error updating */
		
		publish "DCU_WriteLog":U ("Changed instance name from " + cOldValue + " to " + rycoi.instance_name + " (Object Id: " + string(rycoi.object_instance_obj) + ")").
	end.	/* objects, instances in class */
end.	/* loop through datafield classes */

PUBLISH "DCU_WriteLog":U ("Replacement of instance name of format TableName(space)FieldName with FieldName, completed "
                          + (IF lError THEN "with errors!" ELSE "successfully.") ).
assign lError = no.
 
/* There may be cases where the instance name is SDOName.Fieldname for DataFields
 * contained by viewers. If this viewer is running against an SDO then we strip off 
 * the SdoName part. If this viewer is running against an SBO we check whether the
 * SdoName is part of the DataSourceNames. If it is,then we leave things alone.
 * If not, then we remove the SdoName.
 */
assign cClassList = getClassChildren('DynView'). 

PUBLISH "DCU_WriteLog":U ("Replacing instance_name of format TableName(period)FieldName with FieldName only, "
						  + "for cases where the design datasource is an SDO (not an SBO)." ).

do iLoop = 1 to num-entries(cClassList, chr(1)):
	/* Get all viewers & their design data objects. */
	for each ryc_smartobject where
			 ryc_smartobject.object_type_obj = decimal(entry(iLoop,cClassList, chr(1)))
			 no-lock:
        
        find first rycso where
                   rycso.smartobject_obj = ryc_smartobject.sdo_smartobject_obj
                   no-lock no-error.
        if available rycso then
            find first gsc_object_type where
                       gsc_object_type.object_type_obj = ryc_smartobject.object_type_obj
                       no-lock no-error.
	   	/* Only check those instances where the viewer has a design data source of SDO 
	   	 * SDO's are query/data objects, SBO's are container objects.
	   	 */
		if (available gsc_object_type and inheritsFrom(gsc_object_type.object_type_code, 'SBO')) then
            next.
        
		for each ryc_object_instance where
		    	 ryc_object_instance.container_smartobject_obj = ryc_smartobject.smartobject_obj and
		    	 num-entries(ryc_object_instance.instance_name, ".") eq 2
		    	 no-lock:
		    		    	 	    	 
			find rycoi where
				 rowid(rycoi) = rowid(ryc_object_instance)
				 exclusive-lock no-wait no-error.
			if locked rycoi then
			do:
				assign lError = yes.
				publish "DCU_WriteLog":U ("Unable to lock object instance for update.").
				next.
			end.	/* locked */
			
			assign cOldValue           = ryc_object_instance.instance_name
				   rycoi.instance_name = entry(2, ryc_object_instance.instance_name, ".":U) no-error.
			if error-status:error then
			do:
				assign lError = yes.
				publish "DCU_WriteLog":U ("Error updating object instance: " + error-status:get-message(1)).
				next.
			end.	/* error updating */
			
			publish "DCU_WriteLog":U ("Changed instance name from " + cOldValue + " to " + rycoi.instance_name + " (Object Id: " + string(rycoi.object_instance_obj) + ")").
		end.	/* instances where design SDO is SDO, not SBO */			
	end.	/* objects, instances in class */
end.	/* loop through datafield classes */
		 		 
PUBLISH "DCU_WriteLog":U ("Replacement of instance name of format TableName(period)FieldName with FieldName, completed "
                          + (IF lError THEN "with errors!" ELSE "successfully.") ).

RETURN.

function getClassChildren	returns character
	(input pcClass as character):
	
	DEFINE VARIABLE cCurrentClassList AS CHARACTER  NO-UNDO.
    DEFINE VARIABLE dObjectTypeObj    AS DECIMAL    NO-UNDO.

    /* Localize the gsc_object_type buffer to this function. This is particularly important seeing that the function is called recursively */
    DEFINE BUFFER gsc_object_type FOR gsc_object_type.
  
	/* See if the given class exists */
	FIND FIRST gsc_object_type WHERE	
			   gsc_object_type.object_type_code = pcClass 
			   no-lock NO-ERROR.
	/* See if the specified class exists */
  	IF AVAILABLE gsc_object_type THEN
  	DO:
        ASSIGN dObjectTypeObj    = gsc_object_type.object_type_obj
        	   cCurrentClassList = string(dObjectTypeObj).
        	   
        /* Step through all the children of the current class */
        FOR EACH gsc_object_type WHERE 
        	     gsc_object_type.extends_object_type_obj = dObjectTypeObj
        	     no-lock:
        	/* For every child, see if there are any children underneath it, by recursively calling this function */
			assign cCurrentClassList = cCurrentClassList + chr(1) + getClassChildren(gsc_object_type.object_type_code).
        END.	/* each class */
    END.	/* available class */
    
	return cCurrentClassList.                 
end function.	/* getclasschildren */

function inheritsFrom	returns logical
	( input pcClass		   as character,
	  input pcInheritsFrom as character	  ):
	
	define variable cHierarchy		as character	no-undo.
	
	assign cHierarchy = getClassChildren(pcInheritsFrom).
	
	if cHierarchy = "":U then
		return no.
        	
	find first gsc_object_type where
			   gsc_object_type.object_type_code = pcClass
			   no-lock no-error.
	if not available gsc_object_Type then
		return no.
    		
	return lookup(string(gsc_object_type.object_type_obj), cHierarchy, chr(1)) gt 0.
end function.	/* inheritsFrom */