ENTERPRISE

Microsoft Dynamic AX 2009 : Reflection APIs (part 3) - Treenodes API

11/16/2013 2:36:13 AM

3. Treenodes API

The two reflection APIs discussed so far both have limitations. The table data API can reflect only on the existence of elements and a small subset of element metadata. The dictionary API can reflect in a type-safe manner but only on the element types that are exposed through this API.

The treenodes API can reflect on everything, but as always, power comes at a cost. The tree-nodes API is harder to use than the other reflection APIs discussed. It can cause memory and performance problems, and it isn’t type-safe.

static void findInventoryClasses(Args _args)
{
TreeNode classesNode = TreeNode::findNode(@'\Classes');
TreeNodeIterator iterator = ClassesNode.AOTiterator();
TreeNode classNode = iterator.next();
ClassName className;

while (classNode)
{
className = classNode.treeNodeName();
if (strStartsWith(className, 'Invent'))
info(strfmt("%1", className));

classNode = iterator.next();
}
}


First, notice how you find a node in the AOT based on the path as a literal. The AOT macro contains definitions for the primary AOT paths.

If you stay at the class level in the AOT, you don’t encounter problems—but be careful if you go any deeper. Tree nodes in MorphX contain data that the Dynamics AX runtime doesn’t manage, and nodes’ memory isn’t automatically deallocated. For each parent node that is expanded, you should call the TreenodeReleasedoTreeNode method on the SysBpCheck class. method to free the memory. For an example of this, see the

The following small job prints the source code for the doTreeNode method by calling the AOTgetSource method on the treenode object for the doTreeNode method.

static void printSourceCode(Args _args)
{
TreeNode treeNode =
TreeNode::findNode(@'\Classes\SysBpCheck\doTreeNode');
;
info(treeNode.AOTgetSource());
}


The treenodes API provides access to the source code of nodes in the AOT. You can use the class ScannerClass to turn the string that contains the source code into a sequence of compilable tokens.

The following code revises the preceding example to find mandatory fields on the table CustTable.

static void mandatoryFieldsOnCustTable(Args _args)
{
TreeNode fieldsNode = TreeNode::findNode(
@'\Data Dictionary\Tables\CustTable\Fields');

TreeNode field = fieldsNode.AOTfirstChild();

while (field)
{
if (field.AOTgetProperty('Mandatory') == 'Yes')
info(field.treeNodeName());

field = field.AOTnextSibling();
}
}


Notice the alternate way of looping over subnodes. Both this and the iterator approach work equally well. The only way to determine whether a field is mandatory with this API is to know that your node models a field and that field nodes have a property named Mandatory, which is set to Yes (not to True) for mandatory fields.

Use the Properties macro when referring to property names. It contains text definitions for all property names. By using this macro, you avoid using literal names, as in the reference to Mandatory in the preceding example.

Unlike the dictionary API, which can’t reflect all elements, the treenodes API reflects everything. The SysDictMenu class exploits this fact, providing a type-safe way to reflect on menus and menu items by wrapping information provided by the treenodes API in a type-safe API. The following job prints the structure of the MainMenu menu, which typically is shown in the navigation pane.

static void printMainMenu(Args _args)
{
void reportLevel(SysDictMenu _sysDictMenu)
{
SysMenuEnumerator enumerator;

if (_sysDictMenu.isMenuReference() ||
_sysDictMenu.isMenu())
{
setPrefix(_sysDictMenu.label());
enumerator = _sysDictMenu.getEnumerator();
while (enumerator.moveNext())
reportLevel(enumerator.current());
}
else
info(_sysDictMenu.label());
}

reportLevel(SysDictMenu::newMainMenu());
}


Notice how the setPrefix function is used to capture the hierarchy and how the reportLevel function is called recursively.

The treenodes API also allows you to reflect on forms and reports, as well as their structure, properties, and methods. The Compare tool in MorphX uses this API to compare any node with any other node. The SysTreeNode class contains a TreeNode class and implements a cascade of interfaces, which makes TreeNode classes consumable for the Compare tool and the Version Control tool. The SysTreeNode class also contains a powerful set of static methods.

The TreeNode class is actually the base class of a larger hierarchy. You can cast instances to specialized TreeNode classes that provide more specific functionality. The hierarchy isn’t fully consistent for all nodes. You can browse the hierarchy in the AOT by clicking System Documentation, clicking Classes, right-clicking TreeNode, pointing to Add-Ins, and then clicking Application Hierarchy.

The xUtil classes shown in the table data API examples contain methods for transitioning between the class paradigm of TreeNode classes and the table paradigm of UtilElements tables. Here is an example.

TreeNode node1 = TreeNode::findNode(@'\Data Dictionary\Tables\CustTable');
UtilElements utilElements = xUtilElements::findTreeNode(custTableNode);
TreeNode node2 = xUtilElements::getNodeInTree(utilElements);


Although we’ve covered only the reflection functionality of the treenodes API, you can use the API just as you would use the AOT designer. You can create new elements and modify properties and source code. The Wizard Wizard uses the treenodes API to generate the project, form, and class implementing the wizard functionality. You can also compile and get layered nodes and nodes from the Old application folder (located in Program Files\ Microsoft Dynamics AX\5.0\Application\Appl\DynamicsAx1\Old). The capabilities that go beyond reflection are very powerful, but proceed with great care. Obtaining information in a non-type-safe manner requires caution, but writing in a non-type-safe manner can lead to cataclysmic situations.

Other  
  •  Microsoft Dynamic AX 2009 : Reflection System Functions
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 4)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 3)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 2)
  •  Microsoft Enterprise Library : Banishing Validation Complication - Diving in With Some Simple Examples (part 1)
  •  Microsoft Enterprise Library : Banishing Validation Complication - How Do I Use The Validation Block?
  •  Microsoft Enterprise Library : Banishing Validation Complication - What Does the Validation Block Do? (part 2)
  •  Microsoft Enterprise Library : Banishing Validation Complication - What Does the Validation Block Do? (part 1)
  •  Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 4) - Refreshing the Cache, Loading the Cache
  •  Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 3) - Removing Items from and Flushing the Cache
  •  
    Top 10
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    3 Tips for Maintaining Your Cell Phone Battery (part 1) - Charge Smart
    OPEL MERIVA : Making a grand entrance
    FORD MONDEO 2.0 ECOBOOST : Modern Mondeo
    BMW 650i COUPE : Sexy retooling of BMW's 6-series
    BMW 120d; M135i - Finely tuned
    PHP Tutorials : Storing Images in MySQL with PHP (part 2) - Creating the HTML, Inserting the Image into MySQL
    PHP Tutorials : Storing Images in MySQL with PHP (part 1) - Why store binary files in MySQL using PHP?
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS