Friday, May 25, 2018

X++ list and rename AOT objects (Part II)

This post shows how to list and rename AOT objects. For example, if you need to find all objects whose name and properties start with "ABC", and then replace it with "XYZ".

Part II : Rename the ABC objects to XYZ objects
To be written.


Code
Description
// Description: This job will find and rename AOT objects from the innermost to outermost
// Date:        25.05.2018
//
// Parameter
//  1) data range --> utilid.recordType == UtilElementType::Table
//  2) date range --> utilId.name like 'aaaaaaTable*'
//  3) From       --> "ABC"
//  4) To         --> "XYZ"
static void Job10(Args _args)
{
    TreeNode treeParentNode; //= TreeNode::findNode(@'\Data Dictionary\Tables\aaaaaaTable');
    int      i=0;
    boolean  IsParentNeededToSave;
    UtilIdElements  utilId;


    void saveAndRelease(TreeNode _treeNode)
    {
        _treeNode.AOTsave();
        _treeNode.treeNodeRelease();
        _treeNode = null;
    }

    void findAndRenameProperties(str      _prefix,
                                 TreeNode _treeNode)
    {
        str 255      treeNodeName;//TreeNodeName treeNodeName;
        str          strProperties,
                     strNewProperties,
                     path;
        ;

        treeNodeName = _treeNode.treeNodeName();
        path = _treeNode.treeNodePath();
        //info(strfmt("%1%2", _prefix, treeNodeName));

        strProperties = _treeNode.AOTgetProperties();
        if (strScan(strProperties, "#ABC", 1, strLen(strProperties)))
        {
            strNewProperties = strReplace(strProperties, "#ABC", "#XYZ");

            while (strScan(strNewProperties, "#ABC", 1, strLen(strNewProperties)))
            {
                strNewProperties = strReplace(strNewProperties, "#ABC", "#XYZ");
            }

            _treeNode.AOTsetProperties(strNewProperties);
            saveAndRelease(_treeNode);
            IsParentNeededToSave = true;

            //info(strfmt("%1%2", _prefix, treeNodeName));
            //info(strfmt("%1%2", _prefix, strProperties));
            //info(strfmt("%1%2", _prefix, strNewProperties));
        }
    }

    void processChildNode(TreeNode _treeNode)
    {
        TreeNode  childNode;
        Str       strPrefix = "";
        int       j;
        ;

        // Find first child
        childNode = _treeNode.AOTfirstChild();
        while (childNode)
        {
            i++;
            strPrefix = "";

            // Recursive
            processChildNode(childNode);

            // Find and rename properties
            for (j=1; j<=i; j++)
                strPrefix += "====";
            findAndRenameProperties(strPrefix, childNode);

            i--;

            // Find next child
            childNode = childNode.AOTnextSibling();
        }

    }
    ;

    // Process
    while select utilId
        where utilid.recordType == UtilElementType::Table
           && utilId.name like 'aaaaaaTable*'
    {
        treeParentNode = xUtilIdElements::getNode(utilId);

        if (treeParentNode)
        {
            // Init parent save flag
            IsParentNeededToSave = false;

            // Process children
            processChildNode(treeParentNode);

            // Find and rename properties
            findAndRenameProperties("", treeParentNode);

            // Check if save change is needed
            if (IsParentNeededToSave)
                saveAndRelease(treeParentNode);

        }
    }

    info("done");
}
To be written

X++ list and rename AOT objects (Part I)

This post shows how to list and rename AOT objects. For example, if you need to find all objects whose name and properties start with "ABC", and then replace it with "XYZ".

Part I : List the ABC objects
Actually you might not need to find by this way because you can do it by search feature on AOT. I post this here as it's a good example. The job will pick a node in AOT, then travel through all its sub nodes. The purpose is to find out "ABC" metadata.


To make it easy and can see the result. I change the requirement a bit. All below jobs will be written to find "Phone" in Table Address.


(**Many thanks for the great knowledge from the reference URLs. I put it at the bottom. Until next post!)


Example1 - Simple. Travel only 2 depth steps in table Address.

Code
Result
static void Job10(Args _args)
{
    TreeNode         treeParentNode = TreeNode::findNode(@'\Data Dictionary\Tables\Address');
    TreeNode         treeChildLv01Node,
                     treeChildLv02Node;

    void printNameAndProperties(str      _prefix,
                                TreeNode _treeNode)
    {
        TreeNodeName treeNodeName;
        str          strProperties;
        ;

        treeNodeName = _treeNode.treeNodeName();
        info(strfmt("%1%2", _prefix, treeNodeName));

        strProperties = _treeNode.AOTgetProperties();
        if (strScan(strProperties, "#Phone", 1, strLen(strProperties)))
            info(strfmt("%1%2", _prefix, strProperties));
    }
    ;

    if (treeParentNode)
    {
        // Display Name and Properties
        printNameAndProperties("", treeParentNode);

        // First child
        treeChildLv01Node = treeParentNode.AOTfirstChild();
        while (treeChildLv01Node)
        {
            // Display Name and Properties
            printNameAndProperties("Lv01--", treeChildLv01Node);

            // First child
            treeChildLv02Node = treeChildLv01Node.AOTfirstChild();
            while (treeChildLv02Node)
            {
                // Display Name and Properties
                printNameAndProperties("Lv02----", treeChildLv02Node);

                // Next child
                treeChildLv02Node = treeChildLv02Node.AOTnextSibling();
            }

            // Next child
            treeChildLv01Node = treeChildLv01Node.AOTnextSibling();
        }

    } //treeParentNode

}



Example2 - Recursive. Now, we can travel through all depth steps in table Address.

Code
Result
static void Job10(Args _args)
{
    TreeNode treeParentNode = TreeNode::findNode(@'\Data Dictionary\Tables\Address');

    void printNameAndProperties(str      _prefix,
                                TreeNode _treeNode)
    {
        str 255      treeNodeName;//TreeNodeName treeNodeName;
        str          strProperties;
        ;

        treeNodeName = _treeNode.treeNodeName();
        info(strfmt("%1%2", _prefix, treeNodeName));

        strProperties = _treeNode.AOTgetProperties();
        if (strScan(strProperties, "#Phone", 1, strLen(strProperties)))
            info(strfmt("%1%2", _prefix, strProperties));
    }

    void writeChildNode(TreeNode _treeNode)
    {
        TreeNode  childNode;
        ;
   
        // Find first child
        childNode = _treeNode.AOTfirstChild();
        while (childNode)
        {
            // Display Name and Properties
            printNameAndProperties("", childNode);
       
            // Recursive
            writeChildNode(childNode);
       
            // Find next child
            childNode = childNode.AOTnextSibling();
        }
    }
    ;

    if (treeParentNode)
    {
        // Display Name and Properties
        printNameAndProperties("", treeParentNode);

        // Write children
        writeChildNode(treeParentNode);

    } //treeParentNode

}



Example3 - The last example of this chapter. Recursive with some decoration indent.

Code
Result
static void Job10(Args _args)
{
    TreeNode treeParentNode = TreeNode::findNode(@'\Data Dictionary\Tables\Address');
    int i=0;

    void printNameAndProperties(str      _prefix,
                                TreeNode _treeNode)
    {
        str 255      treeNodeName;//TreeNodeName treeNodeName;
        str          strProperties;
        ;

        treeNodeName = _treeNode.treeNodeName();
        info(strfmt("%1%2", _prefix, treeNodeName));

        strProperties = _treeNode.AOTgetProperties();
        if (strScan(strProperties, "#Phone", 1, strLen(strProperties)))
            info(strfmt("%1%2", _prefix, strProperties));
    }
  
    void writeChildNode(TreeNode _treeNode)
    {
        TreeNode  childNode;
        Str       strPrefix = "";
        int       j;
        ;
      
        // Find first child
        childNode = _treeNode.AOTfirstChild();
        while (childNode)
        {
            i++;
            strPrefix = "";
          
            // Display Name and Properties
            for (j=1; j<=i; j++)
                strPrefix += "====";
            printNameAndProperties(strPrefix, childNode);
          
            // Recursive
            writeChildNode(childNode);
          
            i--;
          
            // Find next child
            childNode = childNode.AOTnextSibling();
        }

    }
    ;

    if (treeParentNode)
    {
        // Display Name and Properties
        printNameAndProperties("", treeParentNode);

        // Write children
        writeChildNode(treeParentNode);

    } //treeParentNode

}


References:
http://programming4.us/enterprise/21620.aspx