≡ Menu

Working with Conditions in ITK code

Share the knowledge

Previously, I’ve addressed the basic question, what are conditions? and how they are used in the BMIDE. Today I’m going to talk about how I’m finding them to be a useful programming aid. By incorporating Teamcenter’s Conditions in ITK code you can make your ITK code simpler, more flexible, and easier to maintain.

A great advantage of Conditions is that they allow you to access an objects properties without writing any ITK code. Now I am perfectly comfortable writing ITK, but I also appreciate that when you have to build and deploy DLLs to update your system that the maintenance effort is not trivial. Any opportunity I have to get TC to behave the way I need it to without having to write code is a good thing.

ITK, To get the job done

Of course, the truth of the matter is that you often have to write ITK get the job done, because let’s face it, ITK gives you the power to redefine and extend Teamcenter. In my ITK code I often find that I need to check the state of an object in order to determine what needs to happen next. For example, is the dataset checked in? Is the revision statused? What is the owning group? In Teamcenter Engineering I would have to write code to access the property values I wanted and then code up the evaluations themselves. And if I somehow made a mistake in my code or if the requirements changed I would have to update my code and rebuild and re-deploy the DLL. For example, if it was someday decided that it wasn’t sufficient to simply test if a revision was statused or not and instead I had to test if it specifically had statusA or statusB, then that would require a code change.

Advantages of using Conditions in ITK

Conditions allow for a better solution. First, I can define a Condition in the BMIDE that does the appropriate check:

isStatusCorrect(ItemRevision rev) := 
    rev.last_release_status.name = "Approved"

and then use that condition in my code:

    CE_find_condition("isStatusCorrect", &condition); 
    CE_evaluate_condition(condition, 1, &revision, &result); 
    // do something with result...

More compact

The first advantage is that writing the code to do the same evaluation the the condition does with the expression rev.last_release_status.name = "Approved" would take several lines of ITK. First you would have to retrieve the last_release_status property of the revision object, then you’d check whether or not the status returned was NULLTAG, meaning the revision has no status, then if it wasn’t NULLTAG you’d have to get the name property from the status object, and finally compare that value to the string “Approved”. If you assume that the number of bugs in a program is proportional to the number of lines of code, then a one line expression is quite an improvement over the half dozen or so lines of code you’d need to do the check with ITK.

BMIDE validation of expression

The second advantage is that it is entirely possible to write ITK code that compiles and build perfectly, and yet is fatally flawed. For example, if you asked for the “latest_release_status” property instead of the “last_release_status”, your code would appear to be fine but fail at runtime. However, when you create conditions the BMIDE knows what attributes are available to you at each step of the expression. When you type the period after “rev” it’ll offer you all the legal property names you can choose at that point. And if you do manually enter in a property name that is incorrect it’ll flag the expression as incorrect and not let you save it to the template.

Now, granted, when you do write the ITK code you have to get the name of your condition correct, but that’s only one potential failure point as opposed to the two in my example — one when you look up the “last_release_status” attribute, another when you look up the value of the “name” attribute.

Live update fixes

Finally, let’s see what happens when someday the requirements change. Say, for example, that the requirement that the revision have the Approved status is changed to say that the status can be either Approved OR Frozen. To update the condition you’d merely need someone to update the condition like so:

isStatusCorrect(ItemRevision rev) := 
    rev.last_release_status.name = "Approved" 
    OR 
    rev.last_release_status.name = "Frozen"

That’s a task that any BMIDE administrator can do without anyone needing to make any changes to the ITK code. If you’re familiar with the classic template design pattern you’ll recognize that that’s essentially what we’ve used; the ITK defines the skeleton of the algorithm and the conditions implement key bits of functionality.

  • Narasimha

    Scott,

    Excellent Post.

    I liked three things

    1) Got to know how to use Condition related ITK APIS.
    2) “number of bugs in a program is proportional to the number of lines of code”, very true statement.
    3) Accomodating changes

    Regards,
    Narasimha

    • Scott

      Thank you, I’m glad you found it useful. Stay tuned — Monday’s post will cover some of the problems and shortcomings I’ve found with Conditions that you should watch out for.

  • Raj

    Nice learning

  • Pradeep Peter

    Scott,

    Nice article , I guess this way one can make the code more configurabale. Do you know if this way of evaluating the condition has any performance overhead?

    Thanks,
    Pradeep Peter

    • Scott

      Thank you, it’s a fair question and honestly I don’t know the answer. I believe that Conditions use an evaluation engine called CLIPS (I guess this is a link to it, or something based on it: http://clipsrules.sourceforge.net, which from the little I’ve heard is optimized for this type of thing.

      But, regardless, my 2¢ is that for what I do, it doesn’t matter much one way or the other. I’m writing code that a user might use once or twice a day to validate an assembly. If one method takes 1 second and another takes 1.5 seconds, I’m not going to lose sleep over it. Getting the code right and being able to maintain it, those are my main concerns.

      And for what it’s worth, I hammer the CE API pretty heavily in the unit test harness I run to verify I have them working correctly. I spend a lot more time logging into Teamcenter and building my test data than I do evaluating the conditions. I don’t think it’s an issue.

      Still, I might must make the comparison of straight ITK vs. ITK+Conditions the subject of a future post. Thanks in advance for the idea :-)

  • Suyog

    The same conditions I can apply by Query builder also and write an find query api.Can u Please explain the difference between the two?

    • Scott

      1) Queries are used to retrieve objects from the database, Conditions are used to evaluate something about their state.
      2) Conditions are part of the data model and maintained in the BMIDE. There are places in the data model which use Conditions. Example: you can specify which naming rule applies based on a Condition. Queries are created through the rich client (RAC)

      Does that answer your question?

      I have not used the Query API very often because usually the standard ITK calls, such as ITEM_find_item() or ITEM_find_rev(), have been sufficient for most of my needs, although I can easily imagine use cases where It’d be handy to invoke a query. For example, if I wanted to run a nightly batch job on all revisions released with a particular status within the past 24 hours.

  • Pingback: What's wrong with Conditions?()

Optimization WordPress Plugins & Solutions by W3 EDGE