One Star

dynamic rule

I need to have a rule like this
id,name,sex,age,old
1,anil,M,40,false
rule:
if(age>60){
set old = true
}

can this be done using talend?
it is a conditional setting or replacing of values. To make this condition static is possible using the various components like treplace, tsearch etc.
But what i need is for the rule to be dynamic.

Can someone help on this? is there a way to do this? does somebody else face the same issue?
7 REPLIES
One Star

Re: dynamic rule

just a clarification the
data
id,name etc. is the row in a csv file.
One Star

Re: dynamic rule

Depends of what you mean by a dynamic rule. Can you explain more or give some exemple?
One Star

Re: dynamic rule

yes sure..
my dynamic rule would do hypothetically this
update delimitedFile.csv set old=true where age>60
this would be what i would like to do but
old=true
&
age>60
would be something that is passed as a context.rule or a context variable.
This is very easy to do on a table.. the problem is in my case the data is not in a table and i want to run this on a delimited file.
One Star

Re: dynamic rule

If you're familiar with Java Collections, the following blog post could be re-worked to store an 'age > 60' rule in a spreadsheet paired with a flag value 'true'.
http://bekwam.blogspot.com/2011/03/regex-lookup-table-with-talend-open.html
The benefit of the spreadsheet approach is that it can handle bands of ages rather than a binary flag.
The post creates a Java Map of rules. The rules are applied to a data flow using a tJavaRow. In the tJavaRow, several of the output row fields are assigned input row fields directly. For one of the output row fields (VALUE), the assignment is based on looking up a rule from the Java Map and computing it against the input (SYSTEM_FUND_SOURCE_NM.matches(key)).
To adapt this to your case, you would define a spreadsheet record 'age/60/true'. In the tJavaRow, you'd look up this rule and compare input_row.age > key. If the condition is not met, default to 'false'.
One Star

Re: dynamic rule

i had seen this post, but the only problem in this case is
i need to map age condition to this. if i need to write this in java it would mean something like this
if condition.split("/").equals(age)
input_row.age

if condition.split("/").equals(sex)
input_row.sex
if condition.split("/").equals(name)
input_row.name
if condition.split("/").equals(old)
input_row.old
and this just makes up for the condition... then comes the replacement part...
where again same number of conditions....
and my delim file is 160 columns... and that too there are 6 diff kinds of delim file with diff column names....
One Star

Re: dynamic rule

Do you expect rules for each of the 160 fields?
If not, you can use the "Sync columns" and "Generate code" buttons on the tJavaRow to map the 159 non-age fields without much effort.
Then, at the base of the generated field assignments in the tJavaRow, add in the special processing (the java.util.Map lookup) for 'age'.
One Star

Re: dynamic rule

The following is the code i used to solve my requirement, this doesn't solve nested conditions but simple && an d || conditions are solved.....
input rule list would be like ths...
"TRGT_VAR_COMP|>|6.0|float,NAME|==|job_type_sam|string,START_DATE|<|11/02/2012|date,SPLIT|==|world|string--REPLACE--ID|6,SPLIT|SABA--REPLACE--&&"

String[] ruleArray = context.ruleList.split("--RULES--");

for (String conditionArrayElet : ruleArray) {
String conditionList = conditionArrayElet.split("--REPLACE--");
// "ID|==|1,ORG_NO|!=|1,SPLIT|==|world";
String replaceList = conditionArrayElet.split("--REPLACE--");
String operator = conditionArrayElet.split("--REPLACE--");
// "ID|5,ORG_NO|replacedOrgNo,SPLIT|SABA";
String[] conditionArr = conditionList.split(",");
String[] replaceArr = replaceList.split(",");
List<Boolean> founds = new ArrayList<Boolean>();
for (String condition : conditionArr) {
if (condition.split("\\|").equals("float")) {
Float firstElet = (Float) (row1.getClass().getField((condition.split("\\|")).trim()).get(row1));
Float secondElet = Float.parseFloat(condition.split("\\|"));
if (condition.split("\\|").equals("<")) {
if (firstElet < secondElet) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals(">")) {
if (firstElet > secondElet) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals("==")) {
if (firstElet == secondElet) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals("!=")) {
if (!firstElet.equals(secondElet)) {
founds.add(true);
} else {
founds.add(false);
}
}
} else if (condition.split("\\|").equals("date")) {
Date firstElet =
(Date) (row1.getClass().getField((condition.split("\\|")).trim()).get(row1));
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date secondElet = format.parse(condition.split("\\|"));
// System.out.println(firstElet);
// System.out.println(secondElet);
if (condition.split("\\|").equals("<")) {
if (firstElet.before(secondElet)) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals(">")) {
if (firstElet.after(secondElet)) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals("==")) {
if (firstElet.equals(secondElet)) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals("!=")) {
if (!firstElet.equals(secondElet)) {
founds.add(true);
} else {
founds.add(false);
}
}
} else {
if (condition.split("\\|").equals("==")) {
if (row1.getClass().getField((condition.split("\\|")).trim()).get(row1).equals(
(condition.split("\\|")).trim())) {
founds.add(true);
} else {
founds.add(false);
}
} else if (condition.split("\\|").equals("!=")) {
if (row1.getClass().getField((condition.split("\\|")).trim()).get(row1).equals(
(condition.split("\\|")).trim())) {
founds.add(false);
} else {
founds.add(true);
}
}
}
}
if (founds.size() > 0) {
boolean found = founds.get(0);
if (operator.equals("&&")) {
for (Boolean boolean1 : founds) {
found = boolean1 && found;
}
} else {
for (Boolean boolean1 : founds) {
found = boolean1 || found;
}
}
// there are multiple conditions joined by and, so we need to look at the output condition
if (found) {
for (String replace : replaceArr) {
if (row1.getClass().getField(replace.split("\\|")).get(row1) instanceof Float) {
Float replaceFloat = Float.parseFloat(replace.split("\\|"));
row1.getClass().getField(replace.split("\\|")).set(row1, replaceFloat);
} else if (row1.getClass().getField(replace.split("\\|")).get(row1) instanceof Date) {
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date replaceDate = format.parse(replace.split("\\|"));
row1.getClass().getField(replace.split("\\|")).set(row1, replaceDate);
} else {
row1.getClass().getField(replace.split("\\|")).set(row1, replace.split("\\|"));
}
}
}
}
// row2Struct row3 = new row2Struct();
// The row1 is modified need to write it into row2
Field[] fields = row1.getClass().getFields();
for (Field field : fields) {
Object fieldValue = row1.getClass().getField(field.getName()).get(row1);
row3.getClass().getField(field.getName()).set(row3, fieldValue);
}
// System.out.println(row2);
}