@ATTRIBUTE function in Groovy – Quick Tip # 3


If you have not read the post on @UDA function in Groovy, please do that now 🙂

This post is a follow up to what we did with UDAs. The culprit today is @ATTRIBUTE, BSO calc scripts, and DATA Map.

If you take a look at Data Map member selection, you will find that there is no option to push data using ATTRIBUTEs.

I decided to use Groovy and override the member selection while performing the data map execution.

Now with attributes, there is no inbuilt function like getMembersWithUda. I was expecting something like getMembersWithAttributeDimension. Nope not there, so let’s create our function, shall we?

Groovy for getMemberWithAttributeDimension

We need first to find the Base dimension (line8); once we got that information, it is time for finding out the Attribute dimension (line 9).

I wrote that as a function so that you can reuse this any time you want.

The next step is to find out all the level 0 members of the dimension.

Note: you need to change the evaluation function if the attributes are assigned at a higher level.

Line 12, gives a list of all level 0 members of the dimension you are requesting.

It is now time to find out whether those members are associated with the provided attribute.

This one had me for quite a while. If you look at the definition for getAttributeValue, you will see that this function returns a null if a member is not tagged with a specific attribute.

NPE (null pointer expression) is a PITA, so I decided to use Groovy safe navigation “?.” and to my surprise, that didn’t work!!!

I was not impressed with my code and later figured out that I had to use two safe navigation.

So my code looked like the following.

lvl0Mbrs.findAll{it.getAttributeValue(attrDim)?.name?.equalsIgnoreCase(attrValue)}.collect{fixValues(it)}

That doesn’t feel right; why do I need to see if the name was null. I wanted to know more 🙂

Here is my theory, I get it that some members may not have attributes associated so the AttributeMember can be null. However, once it finds the attribute member, it must have a name!!! Are you with me so far?

With that information and feel that I found something terrible with the Groovy API, I reached out to Ujwala, who is one of the brains behind EPBCS Groovy 🙂

She immediately responded, saying that “There is nothing wrong with the API.” Groovy somehow wants or expects the safe navigation for the name too.

She said do not use .equals or .equalsIgnoreCase, use == instead. She did send me a link that explains the difference between both.

If you are interested in knowing, here is the link that she shared.

I’m more in love with Groovy.

Here is the full code; I did use it as a function so that you can use it repeatedly.

I can say getMembersWithAttributeDimension(app, cube, “Entity”, “Color”, “Red”) and getMembersWithAttributeDimension(app, cube, “Entity”, “Color”, “Blue”), I don’t need to write the code again and again and again 🙂

def app=operation.application
def cube=app.getCube("AMER_PLN")

println getMembersWithAttributeDimension(app, cube, "Entity", "Color", "Blue").collect{fixValues(it)}

def getMembersWithAttributeDimension(Application app, Cube cube, String dimName, String attrDimName, String attrValue ){

    def baseDim=app.getDimension(dimName, cube)
    def attrDim=baseDim.getAttributeDimensions().find{it.name == attrDimName}

	// Get all level 0 members of the dimension
    def lvl0Mbrs = baseDim.getEvaluatedMembers("""Lvl0Descendants($dimName)""" as String, cube)
	// return  all members that are associated with the attribute value
    lvl0Mbrs.findAll{it.getAttributeValue(attrDim)?.name == attrValue}
	
}

There we go, we got all the members that are associated with color Blue.

Groovy code for @ATTRIBUTE AND @RELATIVE

It is a similar code, the only difference; you pass the parent name to the function so that it can expand based on the function you are using.

def app=operation.application
def cube=app.getCube("AMER_PLN")

println getMembersWithAttributeDimension(app, cube, "Entity", "Color", "Blue").collect{fixValues(it)}

def getMembersWithAttributeDimension(Application app, Cube cube, String dimName, String parentName, String attrDimName, String attrValue ){

    def baseDim=app.getDimension(dimName, cube)
    def attrDim=baseDim.getAttributeDimensions().find{it.name == attrDimName}

	// Get all level 0 members of the dimension
    def lvl0Mbrs = baseDim.getEvaluatedMembers("""Lvl0Descendants($parentName)""" as String, cube)
	// return  all members that are associated with the attribute value
    lvl0Mbrs.findAll{it.getAttributeValue(attrDim)?.name == attrValue}
	
}

Leave a comment

Your email address will not be published. Required fields are marked *