how to deal with complex branching in iReport or Jasper - jasper-reports

I need to fill a field in a report based on the end result of a complex branching statement. How do I do this in iReport? The report needs to show a different string depending on what is in different fields in the database. Do I make a really complex SQL statement? Do I use variables?
So, for instance,
If field x=1
IF y=1
IF z=1
Field should read A
If x=1
IF y=1
IF z=2
Field should read B

You could do something similar to the following:
( $F{staff_type} == null ? new String("") :
( $F{staff_type}.equalsIgnoreCase("Permanent") ? new String("1") :
( $F{staff_type}.equalsIgnoreCase("Non-permanent") ? new String("2") : new String("")
)))
Basically, you need to use nested condition expressions.

in the textfieldexpression write an expression like this
(($F{PAYMENTMODE}.equals("CS")) ? "Cash":($F{PAYMENTMODE}.equals("CQ"))? "Cheque":"Bank")e

I think the easiest way to do this would be to have the field(s) filled by a parameter passed from the backing bean. The jdbc connection is created in the bean and passed to the report, it should be relatively easy to access the field or fields you need and run the data through a method which determines the branching outcome. Assign the outcome to the parameter and pass it to the report in the jasperParameter variable of JasperFillManager.fillReport(file, parameters, jdbcConnection).

Usually, I handle all the programming logic before passing the data to the Jasper Report Engine, but in some cases, post-processing or post-checking is required. If it is that scenario and If I had MANY cases (strings) to check, I would code a 'Jasper Report Scriptlet' and handle that logic there (so that the code/report is readable and maintainable and also for code reuse). If it is just 2 or 3 strings to check, I would use the 'Ternary' operator.
If you want to use report scriptlet, create a scriptlet class (or use an existing one), code a method to handle this logic (Ex: 'checkString' method) and put $P{REPORT_SCRIPTLET}.checkString(someString) in the TextField's expression.

Related

Apache AGE - Creating Functions With Multiple Parameters

I was looking inside the create_vlabel function and noted that to get the graph_name and label_name it is used graph_name = PG_GETARG_NAME(0) and label_name = PG_GETARG_NAME(1). Since these two variables are also passed as parameters, I was thinking that, if I wanted to add one more parameter to this function, then I would need to use PG_GETARG_NAME(2) to get this parameter and use it in the function's logic. Is my assumption correct or do I need to do more tweaks to do this?
You are correct, but you also need to change the function signature in the "age--1.2.0.sql" file, updating the arguments:
CREATE FUNCTION ag_catalog.create_vlabel(graph_name name, label_name name, type new_argument)
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';
Note that all arguments come as a "Datum" struct, and PG_GETARG_NAME automatically converts it to a "Name" struct. If you need an argument as int32, for example, you should use PG_GETARG_INT32(index_of_the_argument), for strings, PG_GETARG_CSTRING(n), and so on.
Yes, your assumption is correct. If you want to add an additional parameter to the create_vlabel function in PostgreSQL, you can retrieve the value of the third argument using PG_GETARG_NAME(2). Keep in mind that you may need to make additional modifications to the function's logic to handle the new parameter correctly.
The answers given by Fahad Zaheer and Marco Souza are correct, but you can also create a Variadic function, with which you could have n number of arguments but one drawback is that you would have to check the type yourself. You can find more information here. You can also check many Apache Age functions made this way e.g agtype_to_int2.

Drools : applying same rules on all attributes

I am new to Drools, we are trying to create basic validation rules like a NULL check, etc. using the Drools n Scala framework.
I have a source file which has 200 attributes, need to apply NULL-check rule on all these attributes,
is there any easy way to do this? or do I need to create 200 rules for each attribute?
Thanks in advance.
Assuming you have a POJO ("plain old java object", getters/setters and some private variables to hold values) or modern java Records (effectively the same thing), then the answer is no: you need separate rules. For this scenario, the only way to check that field "name" is null is to actually assert against that field like this:
rule "example - name is null"
when
ExampleObject( name == null )
then
System.out.println("Name is null.");
end
However there exist other data structures -- for example, Map and its sibling types -- where you can reference the fields by name. In this case you could theoretically iterate through all of the field names and find the one whose value is empty.
So, for example, Map has a keySet() method which returns a set of fields -- you could iterate through this keyset and for each key check that there is a non-null value present in the map.
rule "example with map"
when
$map: Map()
$keys: Set() from $map.keySet()
$key: String() from $keys
String( this == null ) from $map.get($key)
// or this might work, not sure if the "this" keyword allows this syntax:
// Map( this[$key] == null ) from $map
then
System.out.println($key + " is missing/null");
end
This would require converting your Java object into a Map before passing into the rules.
However I DO NOT RECOMMEND this approach. Maps are extremely un-performant in rules because of how they serialize/deserialize. You will use a ton of unnecessary heap when firing them. If you look at how a HashMap serializes, for example, by peeking at its source code you'll see that it actually contains a bunch of "child" data structures like entryset and keyset and things like that. When using "new", those child structures are only initialized if and when you need them; but when serializing/deserializing, they're created immediately even if you don't need them.
Another solution would be to use Java reflection to get the list of declared field names, and then iterate through those names using reflection to get the value out for that field. In your place I'd do this in Java (reflection is problematic enough without trying to do it in Drools) and then if necessary invoke such a utility function from Drools.

simple math issue

I'm trying to modify an existing JasperReports template for an invoice. I would like to do some simple math in one field, i.e. calcultate the tax from an existing gross value. The gross value is represented by a parameter $P{prevAdvanceLine1Sum} and in the next field I would like to simply divide this value by a number (in my case 1.23).
Can you give me the expression I should use and what expression class to set?
You can either use simple arithmetic operators (like " / " in this case. See example here: EL Basic Arithmetic), or use the pre-defined methods provided by iReports. Which means, right-click upon the TextField and select Edit Expression. Then select the divide() method.
So the two methods would be:
1. $P{prevAdvanceLine1Sum / 1.23}
2. $P{prevAdvanceLine1Sum}.divide( 1.23 )

Progress 4GL Performance Gains By Avoiding Database Write Operation

At my company we've recently been working on a modification to an existing program that used the following logic to perform some database field assignments:
db-buffer1.field1 = if db-buffer1.field1 <> db-buffer2.field2
then db-buffer2.field2
else db-buffer1.field1
I'm not 100% sure of the original programmer's intention here. Can anyone help me understand the value in comparing whether or not the field values are different before deciding whether to assign the new field?
If the comparison is 'false' and we end up assigning db-buffer1.field1 = db-buffer1.field1 do we avoid a write operation on the database?
Also note that this example is part of a larger ASSIGN statement that contains several fields running similar assignment/comparison logic. Does that have any effect on the value of this additional code? (i.e. Do all comparisons in the ASSIGN statement have to succeed in order to avoid a DB write?)
An "IF function" on the right hand side of an expression is a lot like a "ternary operator" in C or Javascript (the "?:" construct).
It only impacts the portion of the ASSIGN that it is part of. When I write code using those I always encase it in parens to make it clear. Like so:
assign
a = ( if x = y then b else c )
z = 2
.
Whether or not a WRITE happens depends a lot on the rest of the code.
Judging only by this snippet you are going to write SOMETHING (at least logically). db-buffer.field1 is going to get a value assigned to it regardless. The IF logic on the right-hand side is just picking if it will be field1 or field2. In the case that boils down to field1 = field1 you might hope that some lower layer will optimize the write out of existence. I don't see your Progress version posted but if it is v9 or better then it may very well be optimized away. (Prior to v9 it would not have been.)
If you really want to "avoid the write" at the application level you should code it like this:
if field1 <> field2 then
assign
field1 = field2
.
This form does not use the IF function, it is just a normal IF ... THEN statement. It is much clearer and it does not depend on optimizations at a lower level. Of course the snippet shown is said to be part of a larger ASSIGN -- so it may or may not be sensible to break it out and write it as I've shown. But it would be worth thinking about.
It appears that the programmer is checking if field1 is not equal to field2 go ahead and update it.
They might as well simply use the following since either way the field is being assigned:
assign db-buffer1.field1 = db-buffer2.field2.
When using the ASSIGN statement (recommended always), from a logical perspective you have to keep in mind that each line is assigned separately.
Tom has a great answer here that gives more information regarding efficiency/history of the ASSIGN statement.
I would be very interested in seeing the rest of the assign statement, but I would also get rid of the if logic in this case as it adds no value, just and extra instruction. As Terry stated above
ASSIGN db-buffer1.field1 = db-buffer2.field2.

Function returning 2 types based on input in Perl. Is this a good approach?

i have designed a function which can return 2 different types based on the input parameters
ex: &Foo(12,"count") -> returns record count from DB for value 12
&Foo(12,"details") -> returns resultset from DB for value 12 in hash format
My question is is this a good approach? in C# i can do it with function overload.
Please think what part of your code gets easier by saying
Foo(12, "count")
instead of
Foo_count(12)
The only case I can think of is when the function name ("count") itself is input data. And even then do you probably want to perform some validation on that, maybe by means of a function table lookup.
Unless this is for an intermediate layer that just takes a command name and passes it on, I'd go with two separate functions.
Also, the implementation of the Foo function would look at the command name and then just split into a private function for every command anyway, right?
additionally you might consider the want to make foo return the details if you wanted a list.
return wantarray ? ($num, #details) : $num;