Passing a bind variable to view accessor conditionally - groovy

I am new to Adf and i have got a requirement. I have a VO(VO1) which has a View Accessor(PVA) for linking another VO(VO2).
This VO2 is related to flex fields(I am not completely aware of it). But it has something to do with code_combinations table.
Now this view accessor is having a bind variable called 'Bind_ExtraWhereClause' which is of type 'String' and has the following groovy expression in it:
"\${COMBINATION_TABLE}.ACCOUNT_TYPE = 'L' AND \${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'"
This expression is used for validation purpose.
I don't know exact point during runtime when this view accessor is getting executed. Now i need to change the above bind variable groovy expression to this "\${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'" based on a condition in my code.
How can i achieve that?
I have already tried to implement the following two methods:
1) created a transient attribute in VO1 called checkflag of type string and setting this checkflag in my code to either of following values "YES" or "NO". then i edited the bind variable groovy expression like this:
checkflag!="YES"?return "\${COMBINATION_TABLE}.ACCOUNT_TYPE = 'L' AND \${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'":return "\${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'"
so when checkflag is "NO", it takes first condition and when its "YES", it takes the second condition.
2)I cleared the Bind_ExtraWhereClause value from the VA and tried to populate it from VOROWIMPL in the getPVA() method as follows:
public RowSet getPVA(){
RowSet rs = (RowSet)getAttributeInternal(PVA);
if("NO".equals(checkflag)){ rs.setNameWhereClauseParam("Bind_ExtraWhereClause","\${COMBINATION_TABLE}.ACCOUT_TYPE = 'L' AND \${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'");}
else{rs.setNameWhereClauseParam("Bind_ExtraWhereClause","\${COMBINATION_TABLE}.SUMMARY_FLAG != 'Y' AND \${COMBINATION_TABLE}.DETAIL_POSTING_ALLOWED_FLAG = 'Y' AND \${COMBINATION_TABLE}.ENABLED_FLAG = 'Y'");}
rs.executeQuery();
return rs;
}
Unfortunately, both the approaches didn't help me.

I am not sure I understand 100% what are you trying to achieve, but it looks like you need a dynamic view link condition.
Instead of trying to change the view link expression, use instead a transient field in VO1, but this time use an SQL Expression as Default Value.
You need to start thinking about it differently: instead of making your view link dynamic, move the dynamic logic on Query level - by using SQL Calculated attributes.

Related

How do you create scalar arrays/lists in Terraform?

myvar should be a list of security groups.
variable "myvar" {
default = null
}
If users specify it that list is concatenated with the default security group (pulled in from the data source).
If it's not specified just use the default security group.
This is not working:
local {
test = var.myvar != null ? concat(tolist(data.aws_security_group.data.id), var.myvar) : tolist(data.aws_security_group.data.id)
}
But this does work:
aaa = var.myvar != null ? concat(["aaaa"], ["bbbbb","ccccccc"]) : ["aaaa"]
So how to I convert a string to a scalar array/list? It seems like that's what Terraform needs and tolist() is not working.
Based on the given requirements, I think the most straightforward solution would be to set the default for the variable to [] and avoid the need for conditionals at all:
variable "additional_security_group_ids" {
type = list(string)
default = []
}
locals {
security_group_ids = concat(
[data.aws_security_group.default.id],
var.additional_security_group_ids,
)
}
Concatenating an empty list just produces the same list, so leaving the variable unset in the above would cause local.security_group_ids to contain only the default security group id.
Setting the default to null is useful when the absence of a value for that variable disables some feature entirely, or if the logic you need can't be conveniently expressed via defaults, but I'd always recommend using specific default values where possible because the result will tend to be easier to read and understand for future maintainers.
Is this what you're looking for?
value = var.myvar != null ? concat([data.aws_security_group.data.id], var.myvar) : [data.aws_security_group.data.id]
Proposing this as answer, but hoping there is a less crazy way
local {
test = var.myvar != null ? flatten(concat(tolist([data.aws_security_group.data.id]), [var.myvar])) : tolist([data.aws_security_group.data.id])
}

Ternary conditional logic in Karate with undefined variable

I have a Karate feature file, let's called it A.feature, that is intended to be re-used by other feature files. By using shared scope, A.feature can use some variables, for instance the country, defined in the calling feature file. I want these parameters to be optional, but with a default value defined in A.feature. To do that I'm using ternary conditional logic, for instance:
* def myCountry = (country ? country : 'us')
However when country is not defined, a
ReferenceError: "country" is not defined
is thrown.
Does anybody have any idea how to resolve that, or if there is a Nashorn or Karate bug ?
If you want the complete stacktrace let me know.
This will work:
* def country = typeof country == 'undefined' ? 'us' : country
EDIT - Karate now has a convenient API to do this:
* def country = karate.get('country', 'us')
A simpler way is to use default values:
* def country = karate.get('country', 'us')

Core Data predicate for any row of the associated entity

In the following I will describe a simplification of my Core Data schema that I am pretty sure to be equivalent to my real situation.
I have two entity First and Second linked by a many-to-many relationship r.
Second has got two Boolean attribute, let us call it take and you_should_not_take.
I want to make a query that select a row of First iff it exits an associated row of Second for with take = true.
I have tried this predicate:
NSPredicate(format: "ANY (%K == YES && %K == NO)", "r.take","r.you_should_not_take")
but Core Data gives me the following error: "[General] Unable to parse the format string".
Maybe I have to use this:
NSPredicate(format: "((ANY %K == YES) && (ANY %K == NO))", "r.take","r.you_should_not_take")
but I am afraid that this last query will select a row of First iff it exists a row x of Second for which x.take == YES && it exists a row y if Second for which y.you_should_not_take == NO, with no guarantee that x == y.
An SQL query would be very simple to be made, but I am not so experienced with Core Data, so while I will try some more queries (and I will test if the second query does what I think it does) I have also asked here hoping the answer would be as simple as in SQL.
To select all First objects which are related to (at least one) Second object for which take==true and you_should_not_take==false you have
to use a SUBQUERY. Something like (untested):
SUBQUERY(r, $x, $x.take == YES AND $x.you_should_not_take == NO).#count > 0

Drools update nested member attribute

I'm facing a problem while using Drools.
I try to update an attribute from a nested member. The update seems to work, but the when clause do not consider it.
I have 2 Obj object, sharing the same Cpt object.
Cpt cpt = new Cpt();
Obj obj1 = new Obj("obj1");
obj1.setComposant("R2");
obj1.counter = cpt;
Obj obj2 = new Obj("obj2");
obj2.setComposant("R2");
obj2.counter = cpt;
kSession.insert(obj2);
kSession.insert(obj1);
My rule is define as:
rule "R2"
when
m : Obj(composant == "R2" && counter.value == 0)
then
System.out.println(m.getName() + " " + m.getCounter().getValue());
m.getCounter().increment();
end
I was expecting Obj1 to match the when clause, then update the value of the counter (from 0 to 1). So the Obj2 should not match the where clause.
But in fact, it does, even if the display is as I expected :
obj1 0
obj2 1
Can someone explain me what am I doing wrong ?
All reactions of the Drools Rule Engine with respect to changes in the set of facts require to be notified by using one of the extensions for the Right Hand Side language. You need to call update(f) for the modified fact object f, or you may use the modify(f){...} statement.
However... Changing a contained object X via the reference from fact A and telling the Engine that fact A has been modified will not make it see that fact B, also referencing X, has been changed as well.
This is where you should reconsider your design. Is it really necessary to have an X shared via references from A and B? Or: what about making X a fact and updating it? The latter may mean that you have to rewrite your rules, making the relation between Obj and Cpt visible on the left hand side. But, in my experience, it is usually better to have this than some complex mechanism propagating update notifications from some joint contained object to its parents.
Edit What I mean by "making the relation visible" is shown by the rule below:
rule "R2"
when
Obj(composant == "R2", $counter: counter )
$c: Cpt( this == $counter, value == 0)
then
modify( $c ){ increment() }
end

getSubmittedValue() vs. getValue()

Is that correct:
When I query a value before validation (or if validation failed) I have to use getSubmittedValue();. Once the value is validated, even if I query it in another validation later in the page/control I have to use .getValue(); since getSubmittedValue(); returns null after successful validation?
This xsnippet makes it easier to handle this. It allows you to just call getComponentValue("inputText1") to get either value or submittedValue.
Here's the function for reference:
function getComponentValue(id){
  var field = getComponent(id);
  var value = field.getSubmittedValue();
  if( null == value ){
         // else not yet submitted
         value = field.getValue();
  }
 
  return value
}
There's a slightly easier way: if you're just expecting a simple single-value String, just call:
var compare = firstField.getValueAsString();
Otherwise, call:
var compare = com.ibm.xsp.util.FacesUtil.convertValue(facesContext, firstField);
The former calls the latter anyway, but is obviously a terser syntax. This does what you're looking for and more:
If the value hasn't yet been validated, returns the submitted value
If validation has already passed, returns the value after it's already been processed by any converters and / or content filters, so particularly in cases where you're trying to compare two field values, this should ensure that both values have been properly trimmed, etc., and is therefore less likely to return a false positive than just comparing the raw submitted values.
Found the answer here. So when you want to ensure that 2 text fields have the same value (use case: please repeat your email) and the first box already has a validation that might fail, you need to use submittedValue unless it is null, then you use the value. Code in the validation expression for the second field looks like this:
var firstField = getComponent("inputText1");
var compare = firstField.getSubmittedValue() || firstField.getValue();
compare == value;
You have to love it.

Resources