Inside the Studio: DD Classes and Create New Wizards (part 3)
by
, 25-Nov-2009 at 08:09 AM (2973 Views)
In the previous article I explained how to access the workspace paths in a Create New wizard. The information is retrieved via the Studio Workspace file (.sws) that is passed to the wizard via a temporary config file. Accessing the wizard's temporary config file is explained in part one of this series.
In this article I will talk about the DDClassList temporary file that is also created before the wizard is launched. The DDClassList file contains information about each data dictionary class that is used in the current workspace. The name and location of this file is also located in the temporary config file which is passed to the wizard.
Disclaimer: The information presented here describes implementation details that are undocumented and are internal to the Studio. Feel free to use this information as you require but at your own risk. Data Access does not pretend to support these techniques and reserves the right to change the way this works at their discretion.
The DDClassList File
The name and location of the file containing the list of data dictionary classes can is stored in the [DDClassList] section of the temp Config file that is passed to your Create New wizard. An explanation this temp Config file and how to read its contents can be found in Part One of this series.
The DDClassList file is an XML document with the following node structure....Code:[DDClassList] File=C:\Users\John-h\AppData\Local\Temp\DF5085.tmp
where...Code:<WizardDataDictionaryList> <DDClasses> <DDClass> <tableNumber> <tableName> <className> <classFile>
<WizardDataDictionaryList> is the xml document's root node.
<DDClasses> this node contains a collection of DDClass nodes.
<DDClass> contains information about one data dictionary class.
<tableNumber> stores the table number from filelist.cfg of the table that the data dictionary class is bound to.
<tableName> stores the table name of the table that the data dictionary class is bound to.
<className> stores the name of the data dictionary class.
<classFile> stores the filename where the class is declared.
This information can be used by your wizards to create data dictionary objects of the correct class for selected tables. Below is a subset of the DClassList xml file generated from the Order Entry sample workspace.
Reading the DDClassList xml FileCode:<WizardDataDictionaryList xmlns="http://www.dataaccess.com/VisualDataFlex/2008/WizardDataDictionaryList/"> <DDClasses> <DDClass> <tableNumber>22</tableNumber> <tableName>Invt</tableName> <className>Invt_DataDictionary</className> <classFile>Invt.DD</classFile> </DDClass> <DDClass> <tableNumber>25</tableNumber> <tableName>Customer</tableName> <className>Customer_DataDictionary</className> <classFile>Customer.DD</classFile> </DDClass> <DDClass> <tableNumber>30</tableNumber> <tableName>OrderHea</tableName> <className>OrderHea_DataDictionary</className> <classFile>OrderHea.DD</classFile> </DDClass> <DDClass> <tableNumber>31</tableNumber> <tableName>OrderDtl</tableName> <className>OrderDtl_DataDictionary</className> <classFile>OrderDtl.DD</classFile> </DDClass> </DDClasses> </WizardDataDictionaryList>
The example below demonstrates how you can extract a data dictionary class list data from the xml file.
Because the XML document uses a namespace (xmlns=xxx) we must use the dedicated namespace handling cXMLDOMDocument functions to parse the XML. To do this we must pass the namespace string to each function call.Code:Use FlexML.pkg Struct tDDClass Integer tableNumber String tableName String className String classFile End_Struct Function GetDDClassList String sXMLFile Returns tDDClass[] Handle hoXML hoRoot hoDDClassList hoDDClass Handle hoAttributeCollection hoAttribute Integer i iAttribute icAttribute Boolean bOK String sNameSpace sAttribute tDDClass[] DDClassList // Create an XML document object and parse the DDClassList xml file.... Get Create (RefClass(cXMLDOMDocument)) to hoXML // Get Create U_cXMLDOMDocument to hoXML // prior to VDF 15.1 you must write it this way Set psDocumentName of hoXML to sXMLFile Set pbAsync of hoXML to False Set pbValidateOnParse of hoXML to True Get LoadXMLDocument of hoXML to bOK Move 0 to i If (bOK) Begin // Get the root node <WizardDataDictionaryList>.... Get DocumentElement of hoXML to hoRoot If (hoRoot <> 0) Begin // Get the namespace string.... Get AttributeNodes of hoRoot to hoAttributeCollection Move "" to sNameSpace If (hoAttributeCollection <> 0) Begin Get NodeListLength of hoAttributeCollection to icAttribute For iAttribute from 0 to (icAttribute - 1) // we are searching for the "xmlns" attribute.... Get CollectionNode of hoAttributeCollection iAttribute to hoAttribute Get psNodeName of hoAttribute to sAttribute If (Uppercase(sAttribute) = "XMLNS") Begin Get psText of hoAttribute to sNameSpace End Send Destroy to hoAttribute Loop Send Destroy to hoAttributeCollection End // Get the <DDClasses> node.... Get ChildElementNS of hoRoot sNameSpace "DDClasses" to hoDDClassList If (hoDDClassList <> 0) Begin // Iterate each <DDClass> node in <DDClassList>.... Get ChildElementNS of hoDDClassList sNameSpace "DDClass" to hoDDClass While (hoDDClass <> 0) // retrieve the actual DDClass data.... Get ChildElementValueNS of hoDDClass sNamespace "tableNumber" to DDClassList[i].tableNumber Get ChildElementValueNS of hoDDClass sNamespace "tableName" to DDClassList[i].tableName Get ChildElementValueNS of hoDDClass sNamespace "className" to DDClassList[i].className Get ChildElementValueNS of hoDDClass sNamespace "classFile" to DDClassList[i].classFile Increment i // Get the next sibling <DDClass>. This function destroys the // passed object handle and returns a handle to it's sibling Get NextElementNS of hoDDClass sNameSpace "DDClass" to hoDDClass Loop Send Destroy to hoDDClassList End Send Destroy to hoRoot End End Send Destroy to hoXML Function_Return DDClassList End_Function // GetDDClassList
We could hard-code the string since we know what it is ("http://www.dataaccess.com/VisualDataFlex/2008/WizardDataDictionaryList/"), but I decided to make the function a little bit more flexible. It reads the attribute list of the root node to get the namespace string.
The function returns an array of type tDDClass containing all the DD class information from the XML document.
In the next and final part in this series I will describe how your Create New wizard can write data back into the temporary config file to instruct the Studio to perform different operations with the files you have created.