DXL:Cannot assign to an attribute some properties found in history - ibm-doors

DXL, ibm DOORS
Looping through module, then through every object history, I am trying to assign to "_Owner" attribute the author from obj history who modified last time "_ReqStatus" attribute, if "_Owner" is empty.
This is what I tried:
Module m = current
History h
HistoryType ht
Object o
string attributName
string authorName
string newOwner
noError()
for o in entire m do {
for h in o do
{
string owner = ""
attributName=""
attributName = h.attrName
authorName=""
owner = o."_Owner"
if isDeleted(o) then continue
if((attributName=="_ReqStatus"))
{
authorName=h.author
//print authorName
//print "\n"
if(null owner)
{
print identifier(o)
print "\n"
newOwner = authorName
print newOwner"\n"
owner = newOwner
print owner
break
}
}
}
}
ErrMess = lastError()
The output for print owner is as expected. My problem is that in-DOORS attribute is not filling at all with any value.
_Owner attribute type is Ennumeration and attribute properties look like this, but I don't know if it matters:
"_Owner" attr properties

When you assign string owner = o."_Owner", the variable owner is not a handle to the object attribute itself, but the content of o's "_Owner" attribute is copied to owner. So, in your later recalculation owner = newOwner, you only change that variable and not the attribute. Try o."_Owner" = newOwner instead.

Related

How to call a value in map element only when it matches another var

I am using the Terraform provider mrparkers/keycloak to attempt to assign Keycloak groups a list of users.
The snippet below creates realms, groups, and users correctly, but I am stumped on the final line for calling a list of users which should belong to the group being looped through.
Anything to point me in the right direction would be hugely appreciated. :)
vars
variable "realms" {
description = "realms"
type = set(string)
default = ["mrpc"]
}
variable "mrpc-groups" {
type = map(object({
name = string
realm = string
members = set(string)
}))
default = {
"0" = {
realm = "mrpc"
name = "mrpc-admins"
members = ["hellfire", "hellfire2"]
},
"1" = {
realm = "mrpc"
name = "mrpc-mods"
members = ["hellfire2"]
}
}
}
variable "mrpc-users" {
type = map(object({
username = string
email = string
first_name = string
last_name = string
realm = string
}))
default = {
"0" = {
realm = "mrpc"
username = "hellfire"
email = "bla#bla.bla"
first_name = "hell"
last_name = "fire"
}
"1" = {
realm = "mrpc"
username = "hellfire2"
email = "bla2#bla.bla"
first_name = "hell2"
last_name = "fire2"
}
}
}
resources
resource "keycloak_realm" "realm" {
for_each = var.realms
realm = each.value
}
resource "keycloak_group" "group" {
for_each = var.mrpc-groups
realm_id = each.value["realm"]
name = each.value["name"]
depends_on = [keycloak_realm.realm]
}
resource "keycloak_user" "user" {
for_each = var.mrpc-users
realm_id = each.value["realm"]
username = each.value["username"]
email = each.value["email"]
first_name = each.value["first_name"]
last_name = each.value["last_name"]
}
resource "keycloak_group_memberships" "group_members" {
for_each = keycloak_group.group
realm_id = each.value["realm_id"]
group_id = each.value["name"]
members = [ "hellfire2" ]
# i want this to be var.mrpc-groups.*.members (* used incorrectly here i think)
# if
# var.mrpc-groups.*.name == each.value["name"]
#
# so that the correct member list in the vars is used when the matching group is being looped over
# any method to get the final outcome is good :)
}
We can use the distinct and flatten functions in conjunction with a for expression within a list constructor to solve this:
distinct(flatten([for key, attrs in var.mrpc_groups : attrs.members]))
As tested locally, this will return the following for your values exactly as requested in the question indicated by var.mrpc-groups.*.members:
members = [
"hellfire",
"hellfire2",
]
The for expression iterates through the variable mrpc_groups map and returns the list(string) value assigned to the members key within each group's key value pairs. The lambda/closure scope variables are simply key and attrs because the context is unclear to me, so I was unsure what a more descriptive name would be.
The returned structure would be a list where each element would be the list assigned to the members key (i.e. [["hellfire", "hellfire2"], ["hellfire2"]]). We use flatten to flatten the list of lists into a single list comprised of the elements of each nested list.
There would still be duplicates in this flattened list, and therefore we use the distinct function to return a list comprised of only unique elements.
For the additional question about assigning the members associated with the group at the current iteration, we can simply implement the following:
members = flatten([for key, attrs in var.mrpc_groups : attrs.members if attrs.name == each.value["name"]])
This will similarly iterate through the map variable of var.mrpc_groups, and construct a list of the members list filtered to only the group matching the name of the current group iterated through keycloak_group.group. We then flatten again because it is also a nested list similar to the first question and answer.
Note that for this additional question it would be easier for you in general and for this answer if you restructured the variable keys to be the name of the group instead of as a nested key value pair.

How can I handle un object via its reference groovy?

def c = Service1.search(params)
String filename = 'FILE.csv'
def lines = c.collect {
String k = it[1]
[k[0..10], it[0]].join(',')
} as List<String>
each Item 'it' is an object like com.pakage1#123fgdg.. so it shows me an error that i can't get it[1], how i can get the value from this objects thank you .
it is an object . Suppose your class has a property named email.so can get value by using it.email. when you iterate over list it works like this .

Groovy: Dynamic nested properties [duplicate]

I am wondering if I can pass variable to be evaluated as String inside gstring evaluation.
simplest example will be some thing like
def var ='person.lName'
def value = "${var}"
println(value)
I am looking to get output the value of lastName in the person instance. As a last resort I can use reflection, but wondering there should be some thing simpler in groovy, that I am not aware of.
Can you try:
def var = Eval.me( 'new Date()' )
In place of the first line in your example.
The Eval class is documented here
edit
I am guessing (from your updated question) that you have a person variable, and then people are passing in a String like person.lName , and you want to return the lName property of that class?
Can you try something like this using GroovyShell?
// Assuming we have a Person class
class Person {
String fName
String lName
}
// And a variable 'person' stored in the binding of the script
person = new Person( fName:'tim', lName:'yates' )
// And given a command string to execute
def commandString = 'person.lName'
GroovyShell shell = new GroovyShell( binding )
def result = shell.evaluate( commandString )
Or this, using direct string parsing and property access
// Assuming we have a Person class
class Person {
String fName
String lName
}
// And a variable 'person' stored in the binding of the script
person = new Person( fName:'tim', lName:'yates' )
// And given a command string to execute
def commandString = 'person.lName'
// Split the command string into a list based on '.', and inject starting with null
def result = commandString.split( /\./ ).inject( null ) { curr, prop ->
// if curr is null, then return the property from the binding
// Otherwise try to get the given property from the curr object
curr?."$prop" ?: binding[ prop ]
}

DXL ignoring the error if an attribute doesn't exist in a module

I am writing some DXL for use as a DXL column that for each object in a module, looks at the in-links and returns the link name. Then if the link name starts with "verif", it will get the object text from an attribute "TestResultFloating" in the linked module and show it in the current module, in the DXL column.
The problem I will have when I use this on the whole database (currently I am just using a sandbox) is that some of the modules linked through the "verif" link module will not contain the "TestResultFloating" attribute. For these I would like to oppress the 'unknown Object attribute (TestResultFloating)' error and instead display something like N/A for that Object in the current module.
Below is my code that currently works as long as the "TestResultFloating" attribute is present in the linked module, but will throw the error if the attribute is not present.
ModName_ mSrc
Object o = current
Object nObject
Object oSrc, oDest
LinkRef lr = null
Link l = null
string linkname = ""
string attrbName = "TestResultFloating"
for mSrc in (obj <- "*") do {
if (!open(mSrc)) {
read(fullName(mSrc), true)
}
}
for l in (obj <- "*") do {
oSrc = source(l)
linkname = name(module(l))
string linkmodname = upper(linkname[0:4])
if(linkmodname == "VERIF") {
string objText = oSrc."TestResultFloating"
display(objText)
}
}
I tried one way of doing it which I got from the dxl reference manual which was to check whether the attribute exists and then do the operation. This is what I added but it doesn't seem to work, I still get the same error "unknown Object attribute (TestResultFloating)"
What I tried is shown below:
if(linkmodname == "VERIF") {
if(exists attribute "TestResultFloating"){
string objText = oSrc."TestResultFloating"
display(objText)
}
else {
display("N/A")
}
}
Please also note that i'm very new to DOORS and DXL so if I am doing something drastically wrong or I am asking a simple question please forgive me.
There is a utility function called string probeAttr_(Object o, string attrName) that can be used for getting an attribute value if you are not sure whether the attribute is readable or whether it even exists.
This function and a lot of similar functions tailored for different circumstances can be found in the file "c:\Program Files\IBM\Rational\DOORS\9.6\lib\dxl\utils\attrutil.inc"

How would I find the text of a node that has a specific value for an attribute in groovy?

I'm using XMLSlurper. My code is below (but does not work). The problem is that it fails when it hits a node that does not have the attribute "id". How do I account for this?
//Parse XML
def page = new XmlSlurper(false,false).parseText(xml)
//Now save the value of the proper node to a property (this fails)
properties[ "finalValue" ] = page.find {
it.attributes().find { it.key.equalsIgnoreCase( 'id' ) }.value == "myNode"
};
I just need to account for nodes without "id" attribute so it doesn't fail. How do I do that?
You could alternatively use the GPath notation, and check if "#id" is empty first.
The following code snippet finds the last element (since the id attribute is "B" and the value is also "bizz", it prints out "bizz" and "B").
def xml = new XmlSlurper().parseText("<foo><bar>bizz</bar><bar id='A'>bazz</bar><bar id='B'>bizz</bar></foo>")
def x = xml.children().find{!it.#id.isEmpty() && it.text()=="bizz"}
println x
println x.#id
Apprently I can get it to work when I simply use depthFirst. So:
properties[ "finalValue" ] = page.depthFirst().find {
it.attributes().find { it.key.equalsIgnoreCase( 'id' ) }.value == "myNode"
};

Resources