1- from typing import TYPE_CHECKING
2-
31from pyxform import constants as const
4- from pyxform .elements import action
5- from pyxform .entities .label import Label
62from pyxform .section import Section
73from pyxform .survey_element import SURVEY_ELEMENT_FIELDS
8- from pyxform .utils import combine_lists , node
9-
10- if TYPE_CHECKING :
11- from pyxform .survey import Survey
12-
4+ from pyxform .survey_elements .attribute import Attribute
5+ from pyxform .survey_elements .label import Label
6+ from pyxform .utils import combine_lists
137
148EC = const .EntityColumns
15- ENTITY_EXTRA_FIELDS = (const .PARAMETERS ,)
9+ ENTITY_EXTRA_FIELDS = (const .CHILDREN ,)
1610ENTITY_FIELDS = (* SURVEY_ELEMENT_FIELDS , * ENTITY_EXTRA_FIELDS )
11+ CHILD_TYPES = {"label" : Label , "attribute" : Attribute }
1712
1813
1914class EntityDeclaration (Section ):
@@ -40,109 +35,13 @@ class EntityDeclaration(Section):
4035 def get_slot_names () -> tuple [str , ...]:
4136 return ENTITY_FIELDS
4237
43- def __init__ (self , name : str , type : str , parameters : dict , ** kwargs ):
38+ def __init__ (self , name : str , type : str , ** kwargs ):
4439 super ().__init__ (name = name , type = type , ** kwargs )
45- self .parameters : dict = parameters
46- self .children : list [Label ] | None = None
40+ self .children : list [Label | Attribute ] = []
4741
48- choices = combine_lists (
42+ children = combine_lists (
4943 a = kwargs .pop ("children" , None ), b = kwargs .pop (const .CHILDREN , None )
5044 )
51- if choices :
52- self .children = [Label ( name = "label" , ** c ) for c in choices ]
45+ if children :
46+ self .children = [CHILD_TYPES [ c [ "type" ]]( ** c ) for c in children ]
5347 self ._link_children ()
54- else :
55- self .children = []
56-
57- def xml_instance (self , survey : "Survey" , ** kwargs ):
58- parameters = self .parameters
59-
60- attributes = {
61- EC .DATASET .value : parameters .get (EC .DATASET , "" ),
62- "id" : "" ,
63- }
64-
65- entity_id_expression = parameters .get (EC .ENTITY_ID , None )
66- create_condition = parameters .get (EC .CREATE_IF , None )
67- update_condition = parameters .get (EC .UPDATE_IF , None )
68-
69- if entity_id_expression :
70- attributes ["update" ] = "1"
71- attributes ["baseVersion" ] = ""
72- attributes ["trunkVersion" ] = ""
73- attributes ["branchId" ] = ""
74-
75- if create_condition or (not update_condition and not entity_id_expression ):
76- attributes ["create" ] = "1"
77-
78- return super ().xml_instance (survey = survey , ** attributes )
79-
80- def xml_bindings (self , survey : "Survey" ):
81- """
82- See the class comment for an explanation of the logic for generating bindings.
83- """
84- parameters = self .parameters
85- entity_id_expression = parameters .get (EC .ENTITY_ID , None )
86- create_condition = parameters .get (EC .CREATE_IF , None )
87- update_condition = parameters .get (EC .UPDATE_IF , None )
88-
89- if create_condition :
90- yield self ._get_bind_node (survey , create_condition , "/@create" )
91-
92- yield self ._get_id_bind_node (survey , entity_id_expression )
93-
94- if update_condition :
95- yield self ._get_bind_node (survey , update_condition , "/@update" )
96-
97- if entity_id_expression :
98- dataset_name = parameters .get (EC .DATASET , "" )
99- entity = f"instance('{ dataset_name } ')/root/item[name={ entity_id_expression } ]"
100- yield self ._get_bind_node (survey , f"{ entity } /__version" , "/@baseVersion" )
101- yield self ._get_bind_node (
102- survey , f"{ entity } /__trunkVersion" , "/@trunkVersion"
103- )
104- yield self ._get_bind_node (survey , f"{ entity } /__branchId" , "/@branchId" )
105-
106- for e in self .iter_descendants ():
107- if e is not self :
108- yield from e .xml_bindings (survey = survey )
109-
110- def _get_id_bind_node (self , survey , entity_id_expression ):
111- extra_attrs = {}
112-
113- if entity_id_expression :
114- extra_attrs ["calculate" ] = survey .insert_xpaths (
115- text = entity_id_expression , context = self
116- )
117-
118- return node (
119- const .BIND ,
120- nodeset = f"{ self .get_xpath ()} /@id" ,
121- type = "string" ,
122- readonly = "true()" ,
123- ** extra_attrs ,
124- )
125-
126- def xml_actions (self , survey : "Survey" , in_repeat : bool = False ):
127- if self .parameters .get (EC .CREATE_IF , None ) or not self .parameters .get (
128- EC .ENTITY_ID , None
129- ):
130- if in_repeat :
131- setvalue_action = action .ActionLibrary .setvalue_new_repeat .value
132- else :
133- setvalue_action = action .ActionLibrary .setvalue_first_load .value
134-
135- yield action .ACTION_CLASSES [setvalue_action .name ](
136- ref = f"{ self .get_xpath ()} /@id" ,
137- event = action .Event (setvalue_action .event ),
138- value = "uuid()" ,
139- ).node ()
140-
141- def _get_bind_node (self , survey , expression , destination ):
142- return node (
143- const .BIND ,
144- nodeset = f"{ self .get_xpath ()} { destination } " ,
145- calculate = survey .insert_xpaths (text = expression , context = self ),
146- type = "string" ,
147- readonly = "true()" ,
148- )
0 commit comments