<#--
   ******************************************************
   *
   *                       NOTICE
   *
   *  THIS SOFTWARE IS THE PROPERTY OF AND CONTAINS
   *  CONFIDENTIAL INFORMATION OF INFOR, AND SHALL NOT BE
   *  COPIED, USED, NOR DISCLOSED WITHOUT EXPRESS WRITTEN
   *  AUTHORIZATION.  ALTHOUGH PUBLICATION IS NOT
   *  INTENDED, IN THE EVENT OF PUBLICATION, THE
   *  FOLLOWING NOTICE IS APPLICABLE:
   *
   *  Copyright © 2009 Infor. All rights reserved.
   *  The word and design marks set forth herein are
   *  trademarks and/or registered trademarks of Infor
   *  and/or related affiliates and subsidiaries.
   *  All rights reserved. All other trademarks listed
   *  herein are the property of their respective owners.
   *  www.infor.com.
   *
   ******************************************************
  -->
<#import "common.source.ftl" as source/> 
<#import "common.names.ftl" as names/>
<#import "common.defs.ftl" as common/>
<@common.initListAllPublicAttributes/>
<@source.startsource/>
<@source.idents iIsPublic=false/>
<#import "protected.st.common.ftl" as protected/>
<#import "public.sb.common.ftl" as public/>
<@protected.initListProtectedAttributes/>
<#include "common.check.ftl" parse=true />
<@protected.declareDefines iUndef=false/>

|******************************* Initialize ***********************************
<#include "protected.st.initialize.ftl" parse=true />

|****************************** Set & Get generic *********************************

<#if common.referenceMethodPresent()>
function extern 
void <@names.ST_DLLCode/>.set.refKey(string i.value(40))
{
	DllUsage
	EndDllUsage

	if isspace(i.value) then
		bl.refKey = uuid.format$(uuid.generate$())
	else
		bl.refKey = i.value
	endif
	bl.refKey.set = true
}

function extern 
long <@names.ST_DLLCode/>.get.refKey(ref string o.value)
{
	DllUsage
	EndDllUsage

	o.value = ""
	if bl.refKey.set = true then
		o.value = bl.refKey
	endif
	return(0)
}

function extern 
boolean <@names.ST_DLLCode/>.is.set.refKey()
{
	DllUsage
	EndDllUsage

	return(bl.refKey.set)
}
</#if><#--if common.referenceMethodPresent()-->

function extern 
boolean <@names.ST_DLLCode/>.supports.referential.integrity()
{
	DllUsage
	EndDllUsage
<#if common.referenceMethodPresent()>
	return(true)
<#else><#--if common.referenceMethodPresent()-->
	return(false)
</#if><#--if common.referenceMethodPresent()-->
}

function 
void set.permission.for.readonly.attributes(boolean i.value)
{
	bl.permission.for.setting.readonly.attributes = i.value
}

|****************************** Set & Get *********************************

<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.attributeImplementation as attributeImplementation>
		<#assign fieldname = c.componentName + "." + common.getAttributeName(attributeImplementation)>
		<#assign domain = common.getDatatypeName(common.getDatatype(attributeImplementation))>
function extern 
	<#assign array=false>
	<#if common.getMandatoryDatatype(attributeImplementation).dimensions?exists>
		<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(attributeImplementation))/>
		<#assign array=true>
long <@names.ST_DLLCode/>.set.${fieldname}(ref domain ${domain} i.value(), ref boolean i.valueIsSet())
	<#else>
long <@names.ST_DLLCode/>.set.${fieldname}(const domain ${domain} i.value)
	</#if><#--if common.getMandatoryDatatype(attributeImplementation).dimensions?exists-->
{
	DllUsage
	EndDllUsage

	<#if attributeImplementation.isReadOnly>
	if not bl.permission.for.setting.readonly.attributes then
		dal.set.error.message("tlbctst0002", "${fieldname}")
		|* Setting the readonly attribute '%1$s' is not allowed.
		return (DALHOOKERROR)
	endif
	</#if>

	<#if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content>
	boolean cancel
	</#if><#--if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content-->

	if not bl.${c.componentName}.initialize then
		<@names.ST_DLLCode/>.${c.componentName}.initialize()
	endif
	<#assign arrayPart=""> 
	<#if array>
		<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
			<#assign arrayPart="(1, i.element)"> 
		<#else>
			<#assign arrayPart="(i.element)"> 
		</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
	</#if><#--if array-->
	<#if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content>
	RETIFNOK(Hook.BeforeSet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
		bl.${c.componentName}.${hookarg.name},
		bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
		cancel))
	if not cancel then
	</#if><#--if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content-->
	<#if array>
		long	i
		for i = 1 to ${dimensions?number}
			if i.valueIsSet(i) then
		<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
				bl.${fieldname}(1,i) = i.value(1,i)
		<#else>
				bl.${fieldname}(i) = i.value(i)
		</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
				bl.${fieldname}.set(i) = true
			endif
		endfor
	<#else>
		bl.${fieldname} = i.value
		bl.${fieldname}.set = true
	</#if><#--if array-->
	<#--#TODO This is incorrect: only set if attribute implementation is mapped to the table!-->
	<#if attributeImplementation.type=="column" && attributeImplementation.componentImplementationTable?exists>
		<#if !attributeImplementation.componentImplementationTable.idref.isReferentialIntegrityTable>
		bl.${attributeImplementation.componentImplementationTable.idref.table.idref.name}.set = true
		<#-- Are we sure that column must be set if attr. impl. maps to column?
		     maybe the get is done from column, but set for column is done through another path? -->
		</#if>
	</#if>
	<#if attributeImplementation.onSetHookExpression?exists && attributeImplementation.onSetHookExpression?has_content>
		RETIFNOK(Hook.OnSet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
			bl.${c.componentName}.${hookarg.name},
			bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
			bl.${fieldname},
			bl.${fieldname}.set))
	</#if><#--if attributeImplementation.onSetHookExpression?exists && attributeImplementation.onSetHookExpression?has_content-->
	<#if attributeImplementation.afterSetHookExpression?exists && attributeImplementation.afterSetHookExpression?has_content>
		RETIFNOK(Hook.AfterSet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
			bl.${c.componentName}.${hookarg.name},
			bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
			bl.${fieldname},
			bl.${fieldname}.set))
	</#if><#--if attributeImplementation.afterSetHookExpression?exists && attributeImplementation.afterSetHookExpression?has_content-->
	<#if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content>
	endif
	</#if><#--if attributeImplementation.beforeSetHookExpression?exists && attributeImplementation.beforeSetHookExpression?has_content-->
	return(0)
}

function extern 
	<#assign array=false>
	<#if common.getMandatoryDatatype(attributeImplementation).dimensions?exists>
		<#assign dimensions=common.getDimensionsForDataType(common.getMandatoryDatatype(attributeImplementation))/>
		<#assign array=true>
long <@names.ST_DLLCode/>.get.${fieldname}(ref domain ${domain} o.value(), ref boolean o.valueIsSet())
	<#else>
long <@names.ST_DLLCode/>.get.${fieldname}(
					ref domain ${domain} o.value)
	</#if><#--if common.getMandatoryDatatype(attributeImplementation).dimensions?exists-->
{
	DllUsage
	EndDllUsage

	<#if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content>
	boolean cancel
	</#if><#--if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content-->
	<#if attributeImplementation.type=="association" || (attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content)>
	long	duml

	duml = 0
	</#if><#--if attributeImplementation.type=="association" || (attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content)-->

	<#if attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content>
		<#list attributeImplementation.attributeImplementationRelationship?sort_by("position") as air>
			<#if !common.getMandatoryDatatype(air.attributeImplementation.idref).dimensions?exists>
	duml = <@names.ST_DLLCode/>.get.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)}(
		bl.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)})
		bl.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)}.set = 
			<@names.ST_DLLCode/>.is.set.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)}()
			<#else>
	duml = <@names.ST_DLLCode/>.get.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)}(
		bl.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)},
		bl.${c.componentName}.${common.getAttributeName(air.attributeImplementation.idref)}.set)
			</#if>
		</#list><#--list attributeImplementation.attributeImplementationRelationship?sort_by("position") as air-->
	</#if><#--if attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content-->
	<#if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content>
	RETIFNOK(Hook.BeforeGet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
			bl.${c.componentName}.${hookarg.name},
			bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
			cancel))
	if not cancel then
	</#if><#--if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content-->
	<#if !attributeImplementation.interactionPoint?exists>
		<#assign defaultVal=protected.getDefaultFromAttributeImplementation(attributeImplementation)>
		<#if defaultVal.dimensions==0 && defaultVal.present><#-- no defaults for arrays-->
	if not bl.${fieldname}.set then
		bl.${fieldname} = ${defaultVal.value}
		bl.${fieldname}.set = true
	endif
		</#if>
	</#if>
	<#if array>
		<#if attributeImplementation.type=="association">
	RETIFNOK(private.Read.${fieldname}())
			<#-- Use Read from other BDE to get info -->
		</#if><#--#if attributeImplementation.type=="association"-->
	long	i
	for i = 1 to ${dimensions?number}
		if bl.${fieldname}.set(i) then
			o.valueIsSet(i) = true
		<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
			o.value(1,i) = bl.${fieldname}(1,i)
		<#else>
			o.value(i) = bl.${fieldname}(i)
		</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
		else
			o.valueIsSet(i) = false
		endif
	endfor
	<#else>
		<#if attributeImplementation.type=="association">
	RETIFNOK(private.Read.${fieldname}())
			<#-- Use Read from other BDE to get info -->
		</#if><#--#if attributeImplementation.type=="association"-->
	o.value = bl.${fieldname}
	</#if><#--array-->
	<#if attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content>

	RETIFNOK(Hook.OnGet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
		bl.${c.componentName}.${hookarg.name},
		bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
		<#if array>
		bl.${fieldname},
		bl.${fieldname}.set))
	for i = 1 to ${dimensions?number}
		if bl.${fieldname}.set(i) then
			o.valueIsSet(i) = true
				<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
			o.value(1,i) = bl.${fieldname}(1,i)
				<#else>
			o.value(i) = bl.${fieldname}(i)
				</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
		else
			o.valueIsSet(i) = false
		endif
	endfor
		<#else>
		o.value,
		bl.${fieldname}.set))
		</#if><#--array-->
		<#if common.isAnyType(attributeImplementation)>
			<#assign alias=public.getAttributeAlias(c.componentImplementation.component.idref, attributeImplementation.attribute.idref)>
			<#if array>

	for i = 1 to ${dimensions?number}
		if o.valueIsSet(i) = true and
					<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
		   xmlName$(o.value(1,i)) <> "${alias}" then
					<#else>
		   xmlName$(o.value(i)) <> "${alias}" then
					</#if>
			dal.set.error.message("tlbctst0050", "${common.getAttributeName(attributeImplementation)}", str$(i))
			|* Top-level node for anyType attribute %1$s array element %2$s is not valid.
			return (DALHOOKERROR)
		endif
	endfor
			<#else>
	
	if bl.${fieldname}.set and xmlName$(o.value) <> "${alias}" then
		dal.set.error.message("tlbctst0049", "${common.getAttributeName(attributeImplementation)}")
		|* Top-level node for anyType attribute %1$s is not valid.
		return (DALHOOKERROR)
	endif
			</#if>
		</#if>
	</#if><#--if attributeImplementation.onGetHookExpression?exists && attributeImplementation.onGetHookExpression?has_content-->
	<#if attributeImplementation.afterGetHookExpression?exists && attributeImplementation.afterGetHookExpression?has_content>

	RETIFNOK(Hook.AfterGet.${fieldname}(
		<#list protected.getAttributeHookArguments(attributeImplementation) as hookarg>
		bl.${c.componentName}.${hookarg.name},
		bl.${c.componentName}.${hookarg.name}.set,
		</#list><#--list getAttributeHookArguments(attributeImplementation) as hookarg-->
			<#if array>
		bl.${fieldname},
		bl.${fieldname}.set))
		for i = 1 to ${dimensions?number}
			if bl.${fieldname}.set(i) then
				o.valueIsSet(i) = true
					<#if common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING">
				o.value(1,i) = bl.${fieldname}(1,i)
					<#else>
				o.value(i) = bl.${fieldname}(i)
					</#if><#--common.get_BaanDatatype_from_XMLSchemaDatatype(common.getMandatoryDatatype(attributeImplementation))=="DB.STRING"-->
			else
				o.valueIsSet(i) = false
			endif
		endfor
			<#else>
			o.value,
			bl.${fieldname}.set))
			</#if><#--array-->
	</#if><#--if attributeImplementation.afterGetHookExpression?exists && attributeImplementation.afterGetHookExpression?has_content-->
	<#if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content>
	endif
	</#if><#--if attributeImplementation.beforeGetHookExpression?exists && attributeImplementation.beforeGetHookExpression?has_content-->
	<#if array>

	for i = 1 to ${dimensions?number}
		bl.${fieldname}.get(i) = true
	endfor
	<#else>

	bl.${fieldname}.get = true
	</#if><#--array-->

	return(0)
}

function extern 
	<#assign array=false>
	<#if common.getMandatoryDatatype(attributeImplementation).dimensions?exists>
		<#assign array=true>
boolean <@names.ST_DLLCode/>.is.set.${fieldname}(long i.element)
	<#else>
boolean <@names.ST_DLLCode/>.is.set.${fieldname}()
	</#if><#--if common.getMandatoryDatatype(attributeImplementation).dimensions?exists-->
{
	DllUsage
	EndDllUsage
	<#if array=true>
	return(bl.${fieldname}.set(i.element))
	<#else>
	return(bl.${fieldname}.set)
	</#if><#--array=true-->
}

<#-- Check is there is a hook needed..... -->

	</#list><#--list c.componentImplementation.attributeImplementation as attributeImplementation-->
</#list><#--list protected.listProtectedComponents() as c-->

|****************************** Helper functions for control data **********

function boolean getControlAttribute(
	const	string	i.name,
	ref	string	o.value)
{
	return(getControlAttributeFromRequest(
		bl.RequestArgument, i.name, o.value))
}

function boolean setControlAttribute(
	const	string	i.name,
	const	string	i.value)
{
	return(setControlAttributeInResponse(
		bl.ResponseArgument, i.name, i.value))
}

function boolean getControlAttributeFromRequest(
		long	i.request,
	const	string	i.name,
	ref	string	o.value)
{
	xmlnode ControlAreaNode
	long	retl

	ControlAreaNode = xmlFindFirst("ControlArea", i.request)
	retl = xmlGetDataElement(ControlAreaNode, i.name, o.value)
	if retl = 0 then
		return (false)
	endif
	return (true)
}

function boolean setControlAttributeInResponse(
		long	io.response,
	const	string	i.name,
	const	string	i.value)
{
	xmlnode ControlAreaNode
	long	retl

	ControlAreaNode = xmlFindFirst("ControlArea", io.response)
	if ControlAreaNode = 0 then
		ControlAreaNode = xmlNewNode("ControlArea")
		retl = xmlInsertInChilds(io.response, ControlAreaNode)
		if retl = 0 then
			return (false)
		endif
	endif
	retl = xmlRewriteDataElement(ControlAreaNode, i.name, i.value)
	if retl = 0 then
		return (false)
	endif
	return (true)
}

function boolean getAttributeValueFromRequest(
		long	i.request,
	const	string	i.path,
	ref	string	o.value)
{
	string	path(1000)
	long	matching.node

	path = i.path
	if isspace(i.path) or not tlbct.dll1000.replace.data(path, ".", ">.<") then
		o.value = ""
		return(false)
	endif
	matching.node = xmlFindFirstMatch(sprintf$("<>.<DataArea>.<%s>", path),
					i.request)
	if matching.node = 0 or xmlGetType(xmlGetFirstChild(matching.node)) <> XML_DATA then
		o.value = ""
		return(false)
	endif
	o.value = xmlData$(matching.node)
	return(true)
}

function long getRequest()
{
	return(bl.RequestArgument)
}

#define attributeIsSelected(componentName, attributeImplementationName)
^	bl.##componentName##.##attributeImplementationName##.selected

function do.not.use.this.function()
{
| The purpose of this function is to avoid compile warnings on unused
| functions.
	
	boolean	dumb
	long	duml
	string	dums(1)
	
	if false then
		do.not.use.this.function()
		dumb = getControlAttribute(dums, dums)
		dumb = setControlAttribute(dums, dums)
		dumb = getControlAttributeFromRequest(duml, dums, dums)
		dumb = setControlAttributeInResponse(duml, dums, dums)
		dumb = getAttributeValueFromRequest(duml, dums, dums)
		duml = getRequest()
		duml = handle.result(duml)
<#list protected.listProtectedComponents() as c>
	<#list c.componentImplementation.methodImplementation as methodImplementation>
		<#assign methodName = common.getNameFromMethodImplementation(methodImplementation)/>
		<#if methodImplementation.processingOrder != "batch"&&
		     protected.hasMethodAlternativeImplementation(methodName)=="" &&
			(common.isQueryMethod(methodName) || common.isPublishMethod(methodName) || common.isEventMethod(methodName))>
		duml = <@names.ST_DLLCode/>.${c.componentName}.${methodName}.set.derived()
		</#if>
	</#list>
</#list>
<#if common.queryMethodPresent()>
	<#list protected.listProtectedComponents() as c>
		dums = childComponentJoin.${c.componentName}("")
		<#list c.componentImplementation.componentImplementationTable as cit>
		dums = nonRootJoin.${c.componentName}.${cit.table.idref.name}_${cit.position}()
		</#list>
	</#list>
</#if>
	endif
}

<#-- AFS -->
<#include "protected.st.afs.ftl" parse=true />

|****************************** Methods ********************************

<#include "protected.st.methods.ftl" parse=true />

<#-- Query List/Show -->
<#include "protected.st.query.ftl" parse=true />

<#if common.eventMethodPresent() || common.batchMethodPresent() >

<#-- ****************************** Event Methods******************************** -->

<#include "protected.st.events.ftl" parse=true />     

</#if><#-- common.eventMethodPresent() || common.batchMethodPresent() -->

<@protected.declareDefines iUndef=true/>

|****************************** Hooks **********************************

<#-- Hooks must be done AFTER undefining all used defines (except helper functions to be used in hooks)!-->
<#include "protected.st.hooks.ftl" parse=true />

<@source.endsource/>
