Passing data from tJavaRow to tJava in Talend - java

I'm using Talend for an integration, I'm wondering it is it possible to pass data from tJavaRow to tJava components.
For example:
tJavaRow component:
String check = input_row.foo;
if( check.contains("Yes")){
String ret = "OK";
return ret;
}
tJava component:
System.out.println(ret);
Is there a way to print ret, which is a result of a computation of a previous component inside a next component?

The solution is to use the globalMap or a tSetGlobalMap
globalMap.put("ret", ret);
and recover it with
globalMap.get("ret");
/!\ IMPORTANT /!\
But note that if you use a tJava in a main flow like
tRowGenerator > row1 > tJava > row2> tLogRow
tRowGenerator generating 10 rows for 1 to 10
tJava like System.out.println("foo");
tLogRow print the numeric value
The output will be
foo
1
2
3
4
5
6
7
8
9
10
The code in tJava is only executed once before the first row is even generated. Checking the generated code, you can see
System.out.println("foo");
....
for(int i = 0; i < 10; i++){
logrow.print(i);
}

Related

How should i send data to java method from mapping with Odi12c

Recently I started working with Odi12c procedures, until now there was only work with mappings. Now, I have a mapping with different tables and joins, and I need to do calculations by columns. For that, I must use a java method, so I have something like this:
public void static List<Map<String, String>> seg( List<Map<String, String>> comp) {
for (Map<String, String> map : comp) {
if (total > 0 && min1 != min1_fin) {
rest = total - min1;
total-=min1;
map.replace("min1_fin",rest);
map.replace("total",total);
} else {a= true}
if (a) { //(operation for next column)
if (total > 0 && min2 != min2_fin) {
rest = total - min2;
.
..
...
}
return comp;
}
My list:
KEY TOTAL MIN1 MIN2 MIN1_FIN MIN2_FIN
------ -------- -------- ------- --------- ----------
1 35,14 61,85 91,85 0 0
1 35,14 8,09 58,32 0 0
2 85,67 6 6 0 0
2 85,67 67,6 71,47 0 0
I have thought about putting everything in a package and my code in a procedure directly or in a jar and calling it (I still don't know how).
But is it possible to do that? How can I send the data to my java method that way and read it when I return?
Using Java to do the transformation is not the best pattern if the result needs to be stored in a database. Doing it in SQL will be much more efficient.
Anyway, if you really want to use Java you can pass data from the Source command to the Target command of any Procedure step or KM step by binding it. Here is the doc about it : https://docs.oracle.com/cd/E15586_01/integrate.1111/e12643/procedures.htm#CHDGDJGB
Make sure to select the "Multi-Connections" checkbox in the definition of the Produre. The data will pass though the execution agent.

How to use JMenuItems to display integers on seperate lines in a JTextArea?

I'm using a JMenu (named Count) with four JMenuItems (named Inc, Dec, Reset, Quit). When I click on any of the menuitems I want it to display the integer in the JTextArea. For example, everytime I click on Inc it should show the integers vertically listed starting from 0. The issue right now is that when I press the Dec menuitem its not taking the last number listed.
I tried to use the getText method but I keep getting a NumberFormatException and saying that the input string is a bunch of numbers e.g.:
0
1
2
3
4
From what I can tell, I am aware that I need to be able to keep track of the last number in a way that all menuitems (aside from the quit menuitem) can access it and change it. I just have no idea how to do it.
Here is one of the ways that I've tried where it gives me the error I mentioned above.
//newLine = "\n";
public void actionPerformed(ActionEvent ae) {
String ac = ae.getActionCommand();
if(ac.equals("Inc")) {
jta.append(count + newLine);
count++;
}
else if(ac.equals("Dec")) {
count = Integer.parseInt(jta.getText());
countText = Integer.toString(count);
jta.append(countText + newLine);
count--;
}
else if(ac.equals("Reset")) {
jta.selectAll();
jta.replaceSelection("0");
count = 0;
}
else if(ac.equals("Quit")) {
System.exit(0);
}
}
I was expecting
0
1
2
3
4
3
2
1
to be displayed in the TextArea when I click on Inc and Dec
But instead its just
0
1
2
3
4
and then I get a NumberFormatException saying that the input string is:
0
1
2
3
4
If possible, I would like the input string to be just the last integer in the textarea.
I hope this makes sense. This is my first time making a post on stackoverflow.
When you get the text, it has returned "0 1 2 3 4" which cannot be parsed an integer, therefore the exception.
If you want to get the last integer in the text field, you need to retrieve the text and find the substring that represents the last integer. Look at the javadocs for String, especially the lastIndexOf(), split(), and substring() methods.
If you have placed each integer on a separate line, and have kept track of the last number entered in an instance variable "count", then you just need to call jta.append( (count-1) + newLine); without having to retrieve the text at all.
Note that your code does not save the last number entered - it saves (last+1)

Drawing a program graph: What line is visited after a conditional or loop is not called?

Just wanted to check whether the way I am thinking is correct.
Here is an example method:
1 public static boolean isCircle (int M, int m) {
2 boolean result = false;
3 if (M == m & M > 0 & m > 0) {
4 result = true;
5 }
6 return result;
7 }
If I was to draw a program graph of this method (each line being a node, their path being edges) with variables that do not satisfy the conditional e.g. M = 1, m = 0. Would the program go from line 3 -> line 6, or from line 3 -> line 5 (end of the conditional).
I would think line 3 to line 6 but am unsure.
It would jump to 6 since that is the next instruction.
the closing } isn't literally part of the program, but closes
a block, so it doesn't do anything on it's own.
See this post for the bytecode that might make it clear.
http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html#if_else
As you can see there, the closing bracket doesn't get translated, so it doesn't exist. It signals end of block, but isn't part of execution.
It depends. Most debuggers in IDE's put the execution marker at the beginning of the line that it's about to execute. After executing the conditional in line 3 which evaluates to false, the next meaningful line to execute is line 6.
However, consider this code:
1 public static boolean isCircle (int M, int m) {
2 boolean result = false;
3 if (M == m & M > 0 & m > 0) {
4 result = true;
5 } else printf("false!");
6 return result;
7 }
If execution jumped to 6, that would imply that the printf was executed as part of the conditional, which would be frustrating for debugging.
You can verify this behavior with the debugger in any IDE. You may find one or two IDE's that put the execution at the beginning of the next statement (line 6), but in the case where there is something else to execute on line 5 besides the }, I'd hope it'd pause the execution before jumping over that line.
Any debugger worth its salt will ignore lines that don't have any meaning (whitespace, comments, open/close brackets), but pause at the beginning of each meaningful line so you can evaluate variables, set new breakpoints, etc.

Fill squares in Sudoku board using recursion

I'm trying to create a program that reads a sudoku board from a txt file and finds possible solution(s) to the board.
I've created objects of each square and added them to a 2d-array:
(This board have 28 different solutions)
001003
000000
000020
260000
000300
300102
I have successfully added the squares to corresponding column, row and box. But I'm having trouble with my recursive method that tries to find possible solution(s) of the board and add each solutions to a container in a different class that uses nodes to keep track of all the solutions. The method in my container class should take Square[][] squares as parameters.
I start the recursive method off with:
squares[0][0].fillInRemainingOfBoard();
from another class called Board.
My recursive method that is supposed to check all the squares looks like this:
protected void fillInRemainingOfBoard() {
// If Square is not '0' in the txt file it goes in here
if(this instanceof SquareDone) {
// If next != null it goes in here.
if(next != null) {
next.fillInRemainingOfBoard();
}
// If the square is empty it goes in here
} else if(this instanceof SquareEmpty) {
if(next != null) {
// Searching for possible numbers for square
// Rows, Column and Box have the same length;
//thats why row.getLength() in for-loop
for(int i=1; i<=row.getLength(); i++) {
// Set new value to square if this is true,
// then move on to next square
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
} else {
for(int i=1; i<=row.get(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
// No next.fillInRemainingOfBoard() here because it's the last square
}
}
}
}
}
I have a super-class for the rows, columns and boxes which holds the variables and methods for the subclasses. The method that checks for legal values looks like this:
public boolean getLegal(int square) {
for(int i=0; i<rkb.length; i++) {
if(rute == rkb[i].getVerdi()) {
return false;
}
}
return true;
}
My output of this looks like this
4 2 1 5 6 3
5 3 6 2 1 4
1 4 3 6 2 5
2 6 5 4 3 1
6 1 4 3 5 0
3 0 0 1 0 2
So my question is: Why is my code not adding values to each square and how can I save a solution and send them to another class, then start over and check for more solutions?
The reason why its not adding value to each square, is because the algorithm is incorrect. As you can see from position [5][4] of your array, value by line 2 and value by column should be 6. Meaning the algorithm messed up previous values and cannot find further ones.
I suspect this happens because in part of your code bellow, setNewValue(i) is set for the last solution found, but the if statement may find multiple solutions in the beginning of the program, as not many squares are filled, and not always the last solution is the good one.
if(next != null) {
for(int i=1; i<=row.getLength(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
To solve this, you should store all values that match the if statement and figure out how to use them later. (maybe skip the current cell if it has more then 1 solution and come back to it later)
This is just my hypothesis, but you can use a debugger to see if this is truly the problem
Here is a fast implementation of Sudoku Solver which I implemented a couple of years back.
https://gist.github.com/dapurv5/e636c85a5a85cd848ca2
You might want to read about Minimum Remaining Value heuristic. This is one of the standard ways to solve a CSP (Constraint Satisfaction Problem)

Java string split function acting strange

I am noticing strange behaviour when using the split() method in Java.
I have a string as follows: 0|1|2|3|4|5|6|7|8|9|10
String currentString[] = br.readLine().split("\\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This will produce the desired results:
Length: 11
0
1
2
3
4
5
6
7
8
9
10
However if I receive the string: 0|1|2|3|4|5|6|7|8||
I get the following results:
Length: 8
0
1
2
3
4
5
6
7
8
The final 2 empties are omitted. I need the empties to be kept. Not sure what i am doing wrong. I have also tried using the split in this manner as well. ...split("\\|",-1);
but that returns the entire string with a length of 1.
Any help would be greatly appreciated!
The default behavior of split is to not return empty tokens (because of a zero limit). Use the two parameter split method with a limit of -1 will give you all empty tokens in the return.
UPDATE:
Test code as follows:
public class Test {
public static void main(String[] args) {
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|", -1);
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){ System.out.println(currentString[i]); }
}
}
Output as follows:
Length:11
0
1
2
3
4
5
6
7
8
--- BLANK LINE --
--- BLANK LINE --
The "--- BLANK LINE --" is put in by me to show that the return is blank. It is blank once for the empty token after 8| and once for the empty trailing token after the last |.
Hope this clears things up.
String.split() is weird.
Its extreme weirdness, in this and other ways, are some of the reasons why we made Splitter.
It has less surprising behavior and lots of flexibility.
My Java is a little bit rusty, but shouldn't it be:
String currentString[] = "0|1|2|3|4|5|6|7|8||".split("\\|");
System.out.println("Length:"+currentString.length);
for(int i = 0; i < currentString.length; i++)
{
System.out.println(currentString[i]);
}
IMO, I think this is the default behavior of split, Anyway please try this:
String currentString[] = br.readLine().replace("||","| |").split("\|");
System.out.println("Length:"+currentString.length);
for(int i=0;i < currentString.length;i++){
System.out.println(currentString[i]);
}
This has not been tested yet, but i think this should do the trick.
You need to use indexOf() and then substring() for this to work. I don't think you can empty string by using split() only.
Please check the following code, I used your solution, it works:
public class SplitTest
{
public static void main(String[] args)
{
String text = "0|1|2|3|4|5|6|7|8||";
String pattern = "\\|";
String [] array = text.split(pattern, -1);
System.out.println("array length:" + array.length);
for(int i=0; i&lt array.length; i++)
System.out.print(array[i]+ " ");
}
}
output is:
array length:11
0 1 2 3 4 5 6 7 8

Categories

Resources