<#--
   ******************************************************
   *
   *                       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.
   *
   ******************************************************
 -->
<@common.checkCancel/>

<#function fillDefaultStruct iDefaultValue iDefaultPresent iWhere>
	<#assign defaultX={
		"value":iDefaultValue,
		"present":iDefaultPresent,
		"where":iWhere	}>
	<#return defaultX>
</#function>

<#function getDefaultValueFromMethodArgument iMethodArgument>
	<#assign defaultX=fillDefaultStruct("", false, "Not found")>
	<#-- Search in method arguments -->
	<#if iMethodArgument.defaultValue?exists && iMethodArgument.defaultValue!="">
		<#assign defaultX=fillDefaultStruct(iMethodArgument.defaultValue, true, "MethodArgument.defaultValue")>
	<#elseif iMethodArgument.attribute.idref.defaultValue?exists && iMethodArgument.attribute.idref.defaultValue!="">
		<#assign defaultX=fillDefaultStruct(iMethodArgument.attribute.idref.defaultValue, true, "Attribute.defaultValue")>
	</#if>
	<#if defaultX.present && defaultX.value!="">
		<#return fillDefaultStruct("\""+defaultX.value+"\"", true, defaultX.where)>
	<#else>
		<#return fillDefaultStruct("", false, "Not found")>
	</#if>
	<#return defaultX>
</#function>

<#function listMethodArguments iMethodName iobject=object>
	<#local methodArgumentList=[]/>
	<#list iobject.businessInterfaceDefinition.idref.method as method>
		<#if method.name==iMethodName>
			<#list method.methodArgument as methodArgument>
				<#local methodArgumentList=methodArgumentList+[methodArgument]/>
			</#list>	
		</#if>
	</#list>
	<#return methodArgumentList>
</#function>

<#function listPublicSubComponents iMethodName iComponentName>
	<#local subComponentList=[]>
	<#list listPublicComponents(iMethodName) as c>
		<#if c.componentName==iComponentName>
			<#list c.componentImplementation.relationshipImplementation as relationshipImplementation>
				<#if relationshipImplementation.relationship?has_content && relationshipImplementation.relationship.idref.type=="aggregation">
					<#assign componentImplementation=relationshipImplementation.componentImplementation>
					<#if listPublicAttributes(iMethodName, common.getComponentName(componentImplementation))?size!=0 &&
					     protectedComponentMethodPresent(common.getComponentName(componentImplementation), iMethodName)>
						<#local subComponentList=subComponentList+[{	
							"parentComponentName":c.componentName,
							"parentComponentImplementation":c.componentImplementation,
							"componentName":common.getComponentName(componentImplementation),
							"componentPublicName":common.getComponentPublicName(componentImplementation),
							"componentImplementation":componentImplementation
						}]>
					</#if>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return subComponentList>			
</#function>

<#function createPublicSubComponentsStructure>
	<#assign subComponentsStructure=[]>
	<#list object.methodImplementation as methodImplementation>
		<#assign methodName=common.getNameFromMethodImplementation(methodImplementation)>
		<#list listPublicComponents(methodName) as c>
			<#local subComponentsStructure = subComponentsStructure + [{
						"method":methodName,
						"component":c.componentName,
						"list":listPublicSubComponents(methodName, c.componentName)
					}]>
		</#list>
	</#list>
	<#return subComponentsStructure>			
</#function>

<#function listPublicSubComponentsFromStructure iPublicSubComponentsStructure iMethodName iComponentName>
	<#list iPublicSubComponentsStructure as str>
		<#if str.method == iMethodName && str.component == iComponentName>
			<#return str.list>
		</#if>
	</#list>
	<#return []>
</#function>

<#function isPublicSubComponent iMethodName iComponentName iSubComponentName>
	<#if public.isPublicComponent(iSubComponentName) &&
		protectedComponentMethodPresent(iSubComponentName, iMethodName) &&
		listPublicAttributes(iMethodName, iSubComponentName)?size!=0>
		<#return true>
	</#if>
	<#return false>
</#function>

<#function protectedComponentMethodPresent iComponentName iMethodName iobject=object>
	<#-- This function checks if a component is present on protected level
		 for a certain method -->
	<#local found = false>
	<#list protected.listProtectedComponents("", iobject) as c1>
		<#if iComponentName == c1.componentName>
			<#list c1.componentImplementation.methodImplementation as mi>
				<#if iMethodName == common.getNameFromMethodImplementation(mi) ||
					 iMethodName == "">
					<#local found = true>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return found>
</#function>

<#function getPublicPath iComponentName>
	<#local componentPath = "">
	<#list listComponentPath(iComponentName) as c>
		<#if componentPath=="">
			<#local componentPath = c.componentPublicName>
		<#else>
			<#local componentPath = componentPath+"."+c.componentPublicName>
		</#if>
	</#list>
	<#return componentPath>
</#function>

<#function getPublicComponentSearchPath iComponentName>
	<#local componentPath = "">
	<#list listComponentPath(iComponentName) as c>
		<#if componentPath=="">
			<#local componentPath = "<"+c.componentPublicName+">">
		<#else>
			<#local componentPath = componentPath+".<"+c.componentPublicName+">">
		</#if>
	</#list>
	<#return componentPath>
</#function>

<#function listComponentPath iComponentName componentList=[]>
	<#list common.listComponentImplementations() as c>
		<#if c.componentName== iComponentName>
			<#local componentList=[c]+componentList>
			<#if c.parentComponentName!="">
				<#local componentList=listComponentPath(c.parentComponentName,componentList)>
			</#if>
		</#if>
	</#list>
	<#return componentList>
</#function>

<#function listPublicComponents iMethodName iobject=object>
	<#local componentImplementationList=[]>
	<#list common.listComponentImplementations("", iobject) as c>
		<#if listPublicAttributes(iMethodName, c.componentName, iobject)?size!=0 && 
		     protectedComponentMethodPresent(c.componentName, iMethodName, iobject)>
			<#local componentImplementationList=componentImplementationList+[c]>
		</#if>
	</#list>
	<#return componentImplementationList>
</#function>

<#function listAllPublicComponents iobject=object>
<#-- formerly: listPublicComponents("List") -->
	<#local componentImplementationList=[]>
	<#list common.listComponentImplementations("", iobject) as c>
			<#local componentImplementationList=componentImplementationList+[c]>
	</#list>
	<#return componentImplementationList>
</#function>

<#function isPublicComponent iComponentName>
<#-- Checks if the specified component name exists as component in the BII. -->
	<#list common.listComponentImplementations("", object) as c>
		<#if c.componentName == iComponentName>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function> 

<#function getAttributeGroupFromAttribute iComponent iAttribute>
	<#list iComponent.attribute as a>
		<#if a.type=="complex" || a.type=="group">
			<#list a.attributeRelationship as ar>
				<#if ar.attribute.idref==iAttribute>
					<#local parent=getAttributeGroupFromAttribute(iComponent,a)>
					<#if parent!="">							
							<#return parent+".<"+ar.name+">">
					</#if>
					<#return "<"+ar.name>">
				</#if>
			</#list>
		</#if>
	</#list>
	<#return "<"+iAttribute.name+">">
</#function>

<#function getAttributeGroupForSelection iComponent iAttribute>
	<#list iComponent.attribute as a>
		<#if a.type=="complex" || a.type=="group">
			<#list a.attributeRelationship as ar>
				<#if ar.attribute.idref==iAttribute>
					<#local parent=getAttributeGroupForSelection(iComponent,a)>
					<#if parent!="">
						<#return parent+"."+ar.name>
					</#if>
					<#return "."+ar.name>					
				</#if>
			</#list>
		</#if>
	</#list>
	<#return iAttribute.name>
</#function>

<#function getAttributeAlias iComponent iAttribute>
	<#list iComponent.attribute as a>
		<#if a.type=="complex" || a.type=="group">
			<#list a.attributeRelationship as ar>
				<#if ar.attribute.idref==iAttribute>
					<#return ar.name>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return iAttribute.name>
</#function>

<#function listPublicAttributeGroups iComponent>
	<#local attributeGroupsList=[]>
	<#list iComponent.attribute as a>
		<#if !a.isHidden>
			<#if a.type=="complex" || a.type=="group">
				<#local attributeGroupsList=attributeGroupsList+[{
						"groupName":getAttributeAlias(iComponent, a),
						"path":getAttributeGroupFromAttribute(iComponent, a),
						"selectionPath":getAttributeGroupForSelection(iComponent, a),
						"attributeIdref":a
				}]>
			</#if>
		</#if>
	</#list>
	<#return attributeGroupsList>
</#function>

<#function containedIn iValue iList>
	<#list iList as value>
		<#if value==iValue>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function listPublicAttributesFromGroup iAttributeGroup iAttributeList>
	<#local attributeList = iAttributeList>
	<#list iAttributeGroup.attributeRelationship as ar>
		<#local a = ar.attribute.idref>
		<#if a.type=="complex" || a.type=="group">
			<#local attributeList = listPublicAttributesFromGroup(a, attributeList)>
		<#else>
			<#if !containedIn(a, attributeList)>
				<#local attributeList = attributeList+[a]>
			</#if>
		</#if>
	</#list>
	<#return attributeList>
</#function>

<#function listPublicAttributesOrderDef iMethodName iComponent>
	<#local attributeList=[]>
	<#list iComponent.componentImplementation.component.idref.attribute as a>
		<#if a.type=="complex" || a.type=="group">
			<#local attributeList = listPublicAttributesFromGroup(a, attributeList)>
		<#else>
			<#if !containedIn(a, attributeList)>
				<#local attributeList = attributeList+[a]>
			</#if>
		</#if>
	</#list>
	<#local publicAttributes = listPublicAttributes(iMethodName, iComponent.componentName)>
	<#local publicAttributesList=[]>
	<#list attributeList as a>
		<#list publicAttributes as pa>
			<#if a.name == pa.attributeName>
				<#local publicAttributesList = publicAttributesList + [pa]>
			</#if>
		</#list>
	</#list>
	<#return publicAttributesList>
</#function>

<#function getMandatoryFromMethodArgumentImplementation iComponentImplementation iMethodName iAttributeImplementation>
	<#list common.listMethodArgumentImplementationsAA(iComponentImplementation, iMethodName) as methodArgumentImplementation>
		<#if methodArgumentImplementation.attributeImplementation?exists && methodArgumentImplementation.attributeImplementation.idref==iAttributeImplementation>
			<#return common.getIsMandatoryFromMethodArgumentImplementation(methodArgumentImplementation)>
		</#if>
	</#list>
	<#return iAttributeImplementation.isMandatory>
</#function>

<#function listPublicAttributes0 iMethodName iComponentName="" iobject=object>
<#-- lists all public attributes from a certain component used in a certain method -->
	<#local attributesList=[]>
	<#list common.listComponentImplementations("", iobject) as c>
		<#if (iComponentName=="" || c.componentName==iComponentName)>
			<#local publicMethodPresentOrNotProtectedMethodPresent=(common.publicMethodPresent(iMethodName,c.componentImplementation) || !common.protectedMethodPresent(iMethodName,c.componentImplementation))>
			<#list c.componentImplementation.attributeImplementation as attributeImplementation>
				<#if attributeImplementation.attribute?exists>
					<#if publicMethodPresentOrNotProtectedMethodPresent>
						<#-- retrieve attributes via public method -->
						<#list listMethodArguments(iMethodName, iobject) as methodArgument>
							<#if methodArgument.type == "attribute" &&
								((common.getComponentNameFromMethodArgument(methodArgument)==c.componentName) &&
								attributeImplementation.attribute.idref?exists &&
								(methodArgument.attribute.idref.name==attributeImplementation.attribute.idref.name))>
								<#local attributesList=attributesList+[{
									"componentName":c.componentName,
									"componentPublicName":c.componentPublicName,
									"componentImplementation":c.componentImplementation, 
									"attributeName":attributeImplementation.attribute.idref.name, 
									"attributeImplementation":attributeImplementation,
									"defaultVal":getDefaultValueFromMethodArgument(methodArgument),
									"isMandatory":getMandatoryFromMethodArgumentImplementation(c.componentImplementation, iMethodName, attributeImplementation),
									"scope":methodArgument.scope,
									"path":getAttributeGroupFromAttribute(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
									"selectionPath":getAttributeGroupForSelection(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
									"alias":getAttributeAlias(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
									"attributeRelationship":attributeImplementation.attribute.idref.attributeRelationship,
									"attributeType":attributeImplementation.attribute.idref.type
								}]>
								<#break>
							</#if>
						</#list>
					<#else>
						<#-- retrieve attributes via protected method and attributeImplementation -->
						<#list common.listMethodArgumentImplementationsAA(c.componentImplementation, iMethodName) as methodArgumentImplementation>
							<#if methodArgumentImplementation.attributeImplementation?exists && methodArgumentImplementation.attributeImplementation.idref==attributeImplementation>
								<#if methodArgumentImplementation.attributeImplementation.idref.attribute?exists>
									<#local attributesList=attributesList+[{
										"componentName":c.componentName,
										"componentPublicName":c.componentPublicName,
										"componentImplementation":c.componentImplementation, 
										"attributeName":methodArgumentImplementation.attributeImplementation.idref.attribute.idref.name, 
										"attributeImplementation":methodArgumentImplementation.attributeImplementation.idref,
										"defaultVal":protected.getDefaultValueFromMethodArgumentImplementation(methodArgumentImplementation),
										"isMandatory":common.getIsMandatoryFromMethodArgumentImplementation(methodArgumentImplementation),
										"scope":methodArgumentImplementation.scope,
										"path":getAttributeGroupFromAttribute(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
										"selectionPath":getAttributeGroupForSelection(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
										"alias":getAttributeAlias(c.componentImplementation.component.idref,attributeImplementation.attribute.idref),
										"attributeRelationship":attributeImplementation.attribute.idref.attributeRelationship,
										"attributeType":attributeImplementation.attribute.idref.type
									}]>
									<#break>
								</#if>
							</#if>
						</#list>
					</#if>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return attributesList>
</#function>

<#macro initListPublicAttributes>
	<#global attributesListPublStruct=[]>
</#macro>

<#macro resetListPublicAttributes>
	<#assign attributesListPublStruct=[]>
</#macro>

<#function listPublicAttributesScoped iScope iMethodName iComponentName iobject>
	<#list attributesListPublStruct as a>
		<#if iMethodName=a.methodName && iComponentName==a.componentName>
			<#switch iScope>
				<#case "inout">
					<#return a.inout>
				<#case "in">
					<#return a.in>
				<#case "out">
					<#return a.out>
			</#switch>
		</#if>
	</#list>
	<#local attributesList=listPublicAttributes0(iMethodName, iComponentName, iobject)>
	<#local attributesInputList=[]>
	<#local attributesOutputList=[]>
	<#list attributesList as a>
		<#switch a.scope>
			<#case "inout">
				<#local attributesInputList=attributesInputList+[a]>
				<#local attributesOutputList=attributesOutputList+[a]>
				<#break>
			<#case "in">
				<#local attributesInputList=attributesInputList+[a]>
				<#break>
			<#case "out">
				<#local attributesOutputList=attributesOutputList+[a]>
				<#break>
		</#switch>
	</#list>
	<#assign attributesListPublStruct=attributesListPublStruct+[{
			"methodName":iMethodName,
			"componentName":iComponentName,
			"inout":attributesList,
			"in":attributesInputList,
			"out":attributesOutputList
		}]>
	<#switch iScope>
		<#case "inout">
			<#return attributesList>
		<#case "in">
			<#return attributesInputList>
		<#case "out">
			<#return attributesOutputList>
	</#switch>
	<#return []>
</#function>

<#function listPublicAttributes iMethodName iComponentName="" iobject=object>
<#-- lists all public attributes from a certain component used in a certain method -->
	<@common.checkCancel/>
	<#return listPublicAttributesScoped("inout", iMethodName, iComponentName, iobject)>
</#function>

<#function listPublicInputAttributes iMethodName iComponentName="">
<#-- lists all public input attributes from a certain component used in a certain method -->
	<@common.checkCancel/>
	<#return listPublicAttributesScoped("in", iMethodName, iComponentName, object)>
</#function>

<#function listPublicOutputAttributes iMethodName iComponentName="">
<#-- lists all public output attributes from a certain component used in a certain method -->
	<@common.checkCancel/>
	<#return listPublicAttributesScoped("out", iMethodName, iComponentName, object)>
</#function>

<#function attrNotPresent iList iattr>
	<#list iList as la>
		<#if la.componentName==iattr.componentName &&
			 la.attributeName==iattr.attributeName>
			<#return false>
		</#if>
	</#list>
	<#return true>
</#function>

<#function listAllPublicAttributes iComponentName="" iObject=object>
<#-- this function replaces the calls to listPublicOutputAttributes("List") -->
<#-- List all method arguments and return a single list. -->
	<#list attributesListAllPublStruct as l>
		<#if l.componentName == iComponentName>
			<#return l.attrList>
		</#if>
	</#list>

	<#local attrList= listPublicAttributes("List", iComponentName, iObject)>
	<#list public.listPublicAttributes("Show", iComponentName, iObject) as a>
		<#if attrNotPresent(attrList, a)>
			<#local attrList=attrList+[a]>
		</#if>
	</#list>

	<#assign attributesListAllPublStruct=attributesListAllPublStruct+[{
			"componentName":iComponentName,
			"attrList":attrList
		}]>

	<#return attrList>
</#function>

<#function listIdentifiers iMethodName iComponentName iobject=object iContainer=[]>
	<#list listPublicComponents(iMethodName, iobject) as c>
		<#if c.componentName==iComponentName>
			<#list listPublicAttributes(iMethodName,c.componentName, iobject) as a>
				<#if common.getIsIdentifier(a.attributeImplementation)>
					<#local iContainer=[a]+iContainer>
				</#if>
			</#list>
			<#if c.parentComponentName!="">
				<#local iContainer=listIdentifiers(iMethodName,c.parentComponentName, iobject, iContainer)>
			</#if>
		</#if>		
	</#list>
	<#return iContainer>
</#function>

<#function listAllIdentifiers iComponentName iobject=object iContainer=[]>
	<#list listAllPublicComponents(iobject) as c>
		<#if c.componentName==iComponentName>
			<#list listAllPublicAttributes(c.componentName, iobject) as a>
				<#if common.getIsIdentifier(a.attributeImplementation)>
					<#local iContainer=[a]+iContainer>
				</#if>
			</#list>
			<#if c.parentComponentName!="">
				<#local iContainer=listAllIdentifiers(c.parentComponentName, iobject, iContainer)>
			</#if>
		</#if>		
	</#list>
	<#return iContainer>
</#function>

<#macro insertParentIndentifiers iMethodName iComponentName>
	<#list listParentIndentifiers(iMethodName, iComponentName) as i>
		${i.parentComponentName}.${i.attributeName}.select = true
	</#list>
</#macro>

<#function listParentIndentifiers iMethodName iComponentName>
	<#local parentIdentifierList=[]>
	<#list listPublicComponents(iMethodName) as cp>
		<#if cp.componentName == iComponentName>
			<#list listIdentifiers(iMethodName, cp.parentComponentName) as a>
				<#local parentIdentifierList=parentIdentifierList+[{
					"parentComponentName":a.componentName,
					"attributeName":a.attributeName
				}]>
			</#list>
		</#if>
	</#list>
	<#return parentIdentifierList>
</#function>

<#macro insertAllParentIndentifiers iComponentName>
	<#list listAllParentIndentifiers(iComponentName) as i>
		${i.parentComponentName}.${i.attributeName}.select = true
	</#list>
</#macro>

<#function listAllParentIndentifiers iComponentName>
	<#local parentIdentifierList=[]>
	<#list listAllPublicComponents() as cp>
		<#if cp.componentName == iComponentName>
			<#list listAllIdentifiers(cp.parentComponentName) as a>
				<#local parentIdentifierList=parentIdentifierList+[{
					"parentComponentName":a.componentName,
					"attributeName":a.attributeName,
					"componentPublicName":common.getComponentPublicName(a.componentImplementation),
					"componentName":a.componentName
				}]>
			</#list>
		</#if>
	</#list>
	<#return parentIdentifierList>
</#function>

<#function hasPublicInputDataArguments iMethodName>
	<#list listMethodArguments(iMethodName) as methodArgument>
		<#if ((methodArgument.type=="attribute") && (methodArgument.scope=="in" || methodArgument.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#list common.listMethodArgumentImplementations(iMethodName) as methodArgumentImplementation>
		<#-- type is unavailable for methodArgumentImplementation,
			a protected methodArgumentImplementation is always of the type "attribute" -->
		<#if (methodArgumentImplementation.scope=="in" || methodArgumentImplementation.scope=="inout")>
			<#return true>
		</#if>	
	</#list>	
	<#return false>
</#function>

<#function hasPublicInputArguments iMethodName>
	<#list listMethodArguments(iMethodName) as methodArgument>
		<#if ((methodArgument.scope=="in" || methodArgument.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#list common.listMethodArgumentImplementations(iMethodName) as methodArgumentImplementation>
		<#if ((methodArgumentImplementation.scope=="in" || methodArgumentImplementation.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#return false>
</#function>

<#function hasPublicOutputDataArguments iMethodName>
	<#list listMethodArguments(iMethodName) as methodArgument>
		<#if ((methodArgument.type=="attribute") && (methodArgument.scope=="out" || methodArgument.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#list common.listMethodArgumentImplementations(iMethodName) as methodArgumentImplementation>
		<#-- type is unavailable for methodArgumentImplementation,
			a protected methodArgumentImplementation is always of the type "attribute" -->
		<#if (methodArgumentImplementation.scope=="out" || methodArgumentImplementation.scope=="inout")>
			<#return true>
		</#if>	
	</#list>
	<#return false>
</#function>

<#function hasPublicOutputArguments iMethodName>
	<#list listMethodArguments(iMethodName) as methodArgument>
		<#if ((methodArgument.scope=="out" || methodArgument.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#list common.listMethodArgumentImplementations(iMethodName) as methodArgumentImplementation>
		<#if ((methodArgumentImplementation.scope=="out" || methodArgumentImplementation.scope=="inout"))>
			<#return true>
		</#if>	
	</#list>
	<#return false>
</#function>

<#function hasPublicOutputDataArgumentsByComponent iMethodName iComponentName>
	<#list listPublicAttributes(iMethodName, iComponentName) as a>
		<#if (a.scope=="out"||a.scope=="inout")>
			<#return true>
		</#if>	
	</#list>
	<#return false>
</#function>

<#function hasPublicInputDataArgumentsByComponent iMethodName iComponentName>
	<#list listPublicAttributes(iMethodName, iComponentName) as a>
		<#if (a.scope=="in"||a.scope=="inout")>
			<#return true>
		</#if>	
	</#list>
	<#return false>
</#function>

<#--
	|* Filtering duplicate components and attributes
	|*
	|* Example:
	|*	Component structure
	|*		  A
	|*		 / \
	|*		C   B
	|*		   / \
	|*		  C   A
	|*
	|*	Existing attributes:
	|*	A.x A.y
	|*	A.B.x
	|*	A.C.x, A.C.y
	|*	A.B.C.x, A.B.C.z
	|*	A.B.A.x, A.B.A.z
	|*
	|*	To be generated:
	|*
	|*	case "A.x":
	|*	case A.x:(skipped)
	|*		ok
	|*	case "A.y":
	|*	case A.y:(skipped)
	|*		ok
	|*	case "A.B.x":
	|*	case "B.x":
	|*		ok
	|*	case "A.C.x":
	|*	case C.x:(skipped)
	|*		ok
	|*	case "A.C.y":
	|*	case "C.y":
	|*		ok
	|*	case "A.B.C.x":
	|*	case C.x:(skipped)
	|*		ok
	|*	case "A.B.C.z":
	|*	case "C.z":
	|*		ok
	|*	case "A.B.A.x":
	|*	case A.x:(skipped)
	|*		ok
	|*	case "A.B.A.z":
	|*	case "A.z":
	|*		ok
	|*
	|*	case C.x:
	|*		error
	|*
	|*	Note: 
	|*	Selections with a subcomponent in the full path are
	|*	always allowed.
	-->
<#macro initDuplicatesList>
	<#global duplicatesList=[]>
	<#global caseFound=false>
</#macro>

<#macro resetDuplicatesList>
	<#assign duplicatesList=[]>
	<#assign caseFound=false>
</#macro>

<#macro setDuplicatesList iDuplicatesList>
	<#assign duplicatesList=iDuplicatesList>
</#macro>

<#function getDuplicatesList>
	<#return duplicatesList>
</#function>

<#macro insertCase iComponent iSubSelection="">
	<#assign caseFound=false>
	<#local pathSelection="${public.getPublicPath(iComponent.componentName)}${iSubSelection}">
	<#local selection="${iComponent.componentPublicName}${iSubSelection}">
	<#if pathSelection!=selection>
		<#if !duplicateFound(pathSelection)>
			<#assign caseFound=true>
	case "${pathSelection}":	
		</#if>
	</#if>
	<#if !duplicateFound(selection)>
		<#assign caseFound=true>
	case "${selection}":	
	</#if>
</#macro>

<#function duplicateFound iSelection="">
	<#local found=false>
	<#list duplicatesList as d>
		<#if d.selection==iSelection>
			<#local found=true>
			<#break>
		</#if>
	</#list>
	<#return found>
</#function>

<#function generateDuplicatesSelectionPath>
	<#-- Important Note:
		This function is used in protected.st.query generated 
		function get.AttributeData.${methodName} and in
		public.sb.main generated function set.ComponentAttributeData. 
		When changing the case structure of function 
		get.AttributeData.${methodName} or set.ComponentAttributeData
		always implement these changes also in this function		
		-->
	<#local caseList=[]>
	<#local duplicateList=[]>
	<#list public.listAllPublicAttributes() as a>
		<#local caseList=addCaseList(caseList, a.componentName, a.componentPublicName, a.selectionPath)/>
	</#list>
	<#local previousCase="">
	<#list caseList?sort_by("selection") as cl>
		<#if cl.selection==previousCase && cl.componentPublicname!=names.businessInterfaceName>	
			<#local duplicateList=duplicateList+[cl]>			
		</#if>
		<#local previousCase=cl.selection>
	</#list>
	<#return duplicateList>
</#function>

<#function addCaseList iCaseList iComponentName iComponentPublicName iSelectionPath="">
	<#local caseList=iCaseList+[{"selection":"${iComponentPublicName}.${iSelectionPath}",
								"component":iComponentName,
								"componentPublicname":iComponentPublicName,
								"path":"${iComponentPublicName}.${iSelectionPath}"}]>
	<#if iComponentPublicName!=getPublicPath(iComponentName)>
		<#local caseList=caseList+[{"selection":"${getPublicPath(iComponentName)}.${iSelectionPath}",
									"component":iComponentName,
									"componentPublicname":iComponentPublicName,
									"path":"${getPublicPath(iComponentName)}.${iSelectionPath}"}]>
	</#if>
	<#return caseList>
</#function>

<#function hasDuplicateComponent iComponentName iSelection="">
	<#if names.businessInterfaceName==iComponentName>
		<#-- toplevel component skip -->
		<#return false>
	</#if>
	<#list listAllPublicComponents() as ic>
		<#if ic.componentName==iComponentName>
			<#list listAllPublicComponents() as c>
				<#if ic.componentImplementation.component.idref!=c.componentImplementation.component.idref && ic.componentPublicName==c.componentPublicName>
					<#if "${c.componentPublicName}"==iSelection>
						<#return true>
					</#if>
				</#if>
			</#list>
		</#if>
	</#list>
	<#return false>
</#function>

<#function isValidQualifier iAttributeName>
	<#list public.listAllPublicAttributes() as qa>
		<#if iAttributeName==qa.attributeName>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function hasPublicInputTextArgumentsByComponent iMethodName iComponentName>
	<#list public.listPublicInputAttributes(iMethodName, iComponentName) as a>
		<#if common.isTextDatatype(common.getDatatypeFromAttributeImplementation(a.attributeImplementation))>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function hasPublicOutputTextArgumentsByComponent iMethodName iComponentName>
	<#list public.listPublicOutputAttributes(iMethodName, iComponentName) as a>
		<#if common.isTextDatatype(common.getDatatypeFromAttributeImplementation(a.attributeImplementation))>
			<#return true>
		</#if>
	</#list>
	<#return false>
</#function>

<#function processingOrder imethodImplementation>
	<#-- First fixed values for standard methods-->
	<#if common.getNameFromMethodImplementation(imethodImplementation) == "Change" ||
		 common.getNameFromMethodImplementation(imethodImplementation) == "Create" >
		  <#return "TOP_DOWN">
	</#if>
	<#if common.getNameFromMethodImplementation(imethodImplementation) == "Delete" >
		  <#return "BOTTOM_UP">
	</#if>
	<#if imethodImplementation.processingOrder=="topDown">
		<#return "TOP_DOWN">
	<#elseif imethodImplementation.processingOrder=="bottomUp">
		<#return "BOTTOM_UP">
	</#if>
	<#return "BATCH">
</#function>

<#function hasBooleanFacets iDatatype>
	<#local hasyes=false>
	<#local hasno=false>
	<#list iDatatype.facet as facet>
		<#if facet.type=="enumeration">
			<#if facet.value=="Yes" || facet.value=="yes" || facet.value=="True" || facet.value=="true">
				<#local hasyes=true>
			<#else>
				<#if facet.value=="No" || facet.value=="no" || facet.value=="False" || facet.value=="false">
					<#local hasno=true>
				<#else>
					<#return false>
				</#if>
			</#if>
		<#else>
			<#return false>
		</#if>
	</#list>
	<#return hasyes && hasno>
</#function>

<#function getCustomerDataLocation iComponent>
	<#if iComponent.customerDataLocation?has_content>
		<#assign attr=iComponent.customerDataLocation.idref>
		<#return {"name":getAttributeAlias(iComponent, attr), "searchString":getAttributeGroupFromAttribute(iComponent,attr)}>
	</#if>
	<#return {"name":"", "searchString":""}>
</#function>

<#function hasCustomerDataLocation iComponent>
	<#if iComponent.customerDataLocation?has_content>
		<#return true>
	</#if>
	<#return false>
</#function>

<#macro convertToDomain iComponentName iAttributeName iDatatype iPrimitiveDatatype iArrayPart = "" iArrayPartValue = "">
	<#if common.hasEnumerations(iDatatype)>
		<#if iPrimitiveDatatype=="boolean">
			<#if !hasBooleanFacets(iDatatype)>
				${logger.error(object,"Conversion error (to domain): Public datatype of ${iComponentName}.${iAttributeName} is boolean while its protected datatype ${common.getDatatypeName(iDatatype)} does not have boolean facets.")}
			</#if>
	if strip$(tolower$(i.value${iArrayPartValue})) = "true" then
			<#list iDatatype.facet as facet>
				<#if facet.value=="Yes" || facet.value=="yes" || facet.value=="True" || facet.value=="true">
		l.${iAttributeName}${iArrayPart} = ${common.getDatatypeName(iDatatype)}.${facet.value}
				</#if>
			</#list>
	else
			<#list iDatatype.facet as facet>
				<#if facet.value=="No" || facet.value=="no" || facet.value=="False" || facet.value=="false">
		l.${iAttributeName}${iArrayPart} = ${common.getDatatypeName(iDatatype)}.${facet.value}
				</#if>
			</#list>
	endif
		<#else>
	long enum.long

	if isspace(i.value${iArrayPartValue}) then
		dal.set.error.message("tlbctsb0003", "${iComponentName}.${iAttributeName}")
		return(DALHOOKERROR)
	endif
	enum.long = rdi.ctoe("${common.getDatatypeName(iDatatype)}", i.value${iArrayPartValue})
	if enum.long < 1 then
		dal.set.error.message("tlbctsb0002", strip$(i.value${iArrayPartValue}),
			"${common.getDatatypeName(iDatatype)}")
		return(DALHOOKERROR)
	endif
	l.${iAttributeName}${iArrayPart} = ltoe(enum.long)
		</#if>
	<#else>
		<#if common.isTextDatatype(iDatatype)>
			<#assign primDatatype="text">				
		<#else>
			<#assign primDatatype=iPrimitiveDatatype>
		</#if>
		<#switch primDatatype>
			<#case "string">
			<#case "anyURI">
			<#case "duration">
			<#case "Name">
	long	l, conv, retv
	temp.value${iArrayPart} = i.value${iArrayPart}
	<#-- Alignment (tt.align.according.domain) cannot be done here,
	     because if we right-align using variable temp.value it will be right-aligned on 1024 characters,
	     so when assigning to the correct variable (e.g. having length 12) the string will be empty.
	     For that reason it is done at a later stage (in public.sb.main.ftl). -->
	retv = rdi.domain.string( "${common.getDatatypeName(iDatatype)}", l, conv )
	on case conv
	case RDI.UPPER:
		temp.value${iArrayPart} = toupper$(temp.value${iArrayPart})
		break
	case RDI.LOWER:
		temp.value${iArrayPart} = tolower$(temp.value${iArrayPart})
		break
	case RDI.NONE:
	endcase
				<#break>
			<#case "byte">
			<#case "int">
			<#case "integer">
			<#case "negativeInteger">
			<#case "nonNegativeInteger">
			<#case "nonPositiveInteger">
			<#case "normalizedString">
			<#case "positiveInteger">
			<#case "short">			
			<#case "unsignedByte">
			<#case "unsignedInt">
			<#case "unsignedLong">
			<#case "unsignedShort">
			<#case "long">
			<#case "text"><#-- virtual type!-->
			<#case "anyType">
	l.${iAttributeName}${iArrayPart} = lval(i.value${iArrayPartValue})
				<#break>
			<#case "decimal">
			<#case "double">
			<#case "float">
	l.${iAttributeName}${iArrayPart} = val(i.value${iArrayPartValue})
				<#break>
			<#case "date">
	RETIFNOK(tlbct.dll1000.string.to.date(i.value${iArrayPartValue}, l.${iAttributeName}${iArrayPart}))
				<#break>
			<#case "time">
			<#case "dateTime">
	RETIFNOK(tlbct.dll1000.string.to.UTC(i.value${iArrayPartValue}, l.${iAttributeName}${iArrayPart}))
				<#break>
			<#case "boolean">				
	l.${iAttributeName}${iArrayPart} = (strip$(tolower$(i.value${iArrayPartValue})) = "true")
				<#break>
			<#case "base64Binary">		
			<#case "ENTITIES">
			<#case "ENTITY">
			<#case "gDay">
			<#case "gMonth">
			<#case "gMonthDay">
			<#case "gYear">
			<#case "gYearMonth">
			<#case "hexBinary">
			<#case "ID">
			<#case "IDREF">
			<#case "IDREFS">
			<#case "language">
			<#case "NCName">
			<#case "NMTOKEN">
			<#case "NMTOKENS">
			<#case "NOTATION">
			<#case "QName">
			<#case "token">
				<#break>
		</#switch>
	</#if>
<#-- text not yet supported -->
</#macro>

<#macro convertFromDomain iComponentName iAttributeName iDatatype iPrimitiveDatatype iArrayPart = "" iArrayPartValue = "">
	<#if common.hasEnumerations(iDatatype)>
		<#if iPrimitiveDatatype=="boolean">
			<#if !hasBooleanFacets(iDatatype)>
				${logger.error(object,"Conversion error (from domain): Public datatype of ${iComponentName}.${iAttributeName} is boolean while its protected datatype ${common.getDatatypeName(iDatatype)} does not have boolean facets.")}
			</#if>
			<#list iDatatype.facet as facet>
				<#if facet.value=="Yes" || facet.value=="yes" || facet.value=="True" || facet.value=="true">
	if l.${iAttributeName}${iArrayPart} = ${common.getDatatypeName(iDatatype)}.${facet.value} then
		o.value${iArrayPartValue} = "true"
	else
		o.value${iArrayPartValue} = "false"
	endif
				</#if>
			</#list>
		<#else>
	o.value${iArrayPartValue} = rdi.etoc$("${common.getDatatypeName(iDatatype)}", etol(l.${iAttributeName}${iArrayPart}))
		</#if>
	<#else>
		<#if common.isTextDatatype(iDatatype)>
			<#assign primDatatype="text">				
		<#else>
			<#assign primDatatype=iPrimitiveDatatype>
		</#if>
		<#switch primDatatype>
			<#case "string">
			<#case "anyURI">
			<#case "duration">
			<#case "Name">
				<#if object.removeLeadingSpaces?exists && object.removeLeadingSpaces>
	o.value${iArrayPartValue} = trim$(l.${iAttributeName}${iArrayPart})
				<#else>
	o.value${iArrayPartValue} = l.${iAttributeName}${iArrayPart}
				</#if>
				<#break>
			<#case "byte">
			<#case "int">
			<#case "integer">
			<#case "negativeInteger">
			<#case "nonNegativeInteger">
			<#case "nonPositiveInteger">
			<#case "normalizedString">
			<#case "positiveInteger">
			<#case "short">			
			<#case "unsignedByte">
			<#case "unsignedInt">
			<#case "unsignedLong">
			<#case "unsignedShort">
			<#case "long">
			<#case "text"><#-- virtual type!-->
			<#case "anyType">
	o.value${iArrayPartValue} = str$(l.${iAttributeName}${iArrayPart})
				<#break>
			<#case "decimal">
			<#case "double">
			<#case "float">
	o.value${iArrayPartValue} = str$(l.${iAttributeName}${iArrayPart})
				<#break>
			<#case "date">
	RETIFNOK(tlbct.dll1000.date.to.string(l.${iAttributeName}${iArrayPart}, o.value${iArrayPartValue}))	
				<#break>
			<#case "time">
			<#case "dateTime">
	RETIFNOK(tlbct.dll1000.utc.to.string(l.${iAttributeName}${iArrayPart}, o.value${iArrayPartValue}))		
				<#break>
			<#case "boolean">
	if l.${iAttributeName} = 0 then
		o.value${iArrayPartValue} = "false"
	else
		o.value${iArrayPartValue} = "true"
	endif
				<#break>
			<#case "base64Binary">
			<#case "ENTITIES">
			<#case "ENTITY">
			<#case "gDay">
			<#case "gMonth">
			<#case "gMonthDay">
			<#case "gYear">
			<#case "gYearMonth">
			<#case "hexBinary">
			<#case "ID">
			<#case "IDREF">
			<#case "IDREFS">
			<#case "language">
			<#case "NCName">
			<#case "NMTOKEN">
			<#case "NMTOKENS">
			<#case "NOTATION">
			<#case "QName">
			<#case "token">
				<#break>
		</#switch>
	</#if>
<#-- text not yet supported -->
</#macro>

<#macro generateAnchorReplacement iComponentName iSubComponentName iIndent=true>
	<#if iIndent>
		<#assign indent = "				"><#--#four tabs-->
	<#else>
		<#assign indent = "			"><#--#three tabs-->
	</#if>
${indent}| Replace placeholder for component ${iSubComponentName} by content of tmp.node
${indent}positionNode = xmlFindFirst(ANCHOR_MARKER & "${iSubComponentName}",
${indent}		Response.${iComponentName}Node)
${indent}ret = xmlInsert(positionNode,
${indent}		xmlGetFirstChild(tmp.node),
${indent}		xmlGetLastChild(tmp.node))
${indent}ret = xmlDelete(positionNode)
</#macro>
