Working with blob data in Java

In this post let’s take a requirement that we read a pdf file from java code and store it into database and then from another java class we read that blob data from database and store it as a pdf file.

A little introduction about how java handles io streams: In Java it has two variety of streams to handle io, one for binary data(image, pdf, video, audio) and another for text data.  When we are handling with binary data then we should use binary stream classes to handle them (the class names which ends with Stream are used to handle binary data).

Classes to use when working with binary data: InputStream, OutputStream, BufferedInputStream, BufferedOutputStream, FileInputStream, FileOutputStream.

Classes to use when working with text data & inputs from keyboard: InputStreamReader, OutputStreamWriter, BufferedReader, BufferedWriter, FileReader, FileWriter.

1. Create table with blob column:

create table emps(empId int primary key,empFile blob);

2. Insert data into table (blob column) [Here inserting is done using java code by reading data from a file]

package upload;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class Pdf_insert{
static String url = "jdbc:oracle:thin:@localhost:1521:XE";
static String username = "HR";
static String password = "hr";
public static void main(String[] args) throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url, username, password);
String sql = "insert into emps (empid,empfile) values (?,?)";
//String sql = "update emps set empfile = ? where empid = 100";
File blob = new File("D:\\small.pdf");
FileInputStream in = new FileInputStream(blob);
//InputStream in  = new ByteArrayInputStream(blob.getBytes()); // if blob is a string not a file (eg: blob = "hexdata");
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setInt(1, 100);
stmt.setBinaryStream(2, in, (int)blob.length());
stmt.executeUpdate();
in.close();
conn.close();
}}

3. Read data from table (blob column) and generate pdf file from that data.

package upload;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Pdf_read
{
 static String url = "jdbc:oracle:thin:@punitp406381d:1521:XE";
 static String username = "HR";
 static String password = "hr";
 static int BUFFER_SIZE = 4096;

 public static void main(String[] args) throws Exception
 {
 Class.forName("oracle.jdbc.driver.OracleDriver");
 Connection conn = DriverManager.getConnection(url, username, password);
 String sql = "SELECT empfile FROM emps where empId = '100'";
 PreparedStatement stmt = conn.prepareStatement(sql);
 ResultSet resultSet = stmt.executeQuery();

 if (resultSet.next()) {
 System.out.println("if");
 Blob blob = resultSet.getBlob("empfile");
 InputStream inputStream = blob.getBinaryStream();
 OutputStream outputStream = new FileOutputStream("D:\\ourFile.pdf");

 int bytesRead = -1;
 byte[] buffer = new byte[BUFFER_SIZE];
 while ((bytesRead = inputStream.read(buffer)) != -1) {
 outputStream.write(buffer, 0, bytesRead);
 }
 inputStream.close();
 outputStream.close();
 System.out.println("File is saved");
 }
 conn.close();
 }
}

 

Let’s have a look at few more examples.

Below code used when you have a hex string and you need to generate a file from it.


package upload;

import java.io.FileOutputStream;

public class pdf_insert
{
static String hex = "255044462D312E32200D0A25E2E3CFD30D0A200D0A392030206F626A0D0A3C3C0D0A2F4C656E677468203130203020520D0A2F46696C746572202F466C6174654465636F6465200D0A3E3E0D0A73747265616D0D0A4889CD90D14AC33014869F20EFF07BA7B266E7244D93ED6ED216062D148D82901B115B266A658AE2DBDBA40CF17E822417C9C9FF7DC9C98517AC496A05ABACCC73C0978210C77E8058D6042D5D2CF78224591B97F7D329FC274EAB7508AD31219C84C05619D93F9FC13F0A9E62315262629CD289C948B25BB99954443A239E26D8ADD9CC58AEA6F80F69E7BB24716E66AC83BF1B8605B65DBBC0F5CBEEE361FFB67BFFC2D8A3899BD7717C4AAA4C73115D9951D21449B8AC196AEE8425AF8C39D8E960DFE0A6BABCC555BB691A74658D7ADB249B92DA16BF1A4F6542C6C492D2AFE1B852E5FE407ADC97FAF3FF67AABCF8063CF5A1AA0D0A656E6473747265616D0D0A656E646F626A0D0A31302030206F626A0D0A3234360D0A656E646F626A0D0A342030206F626A0D0A3C3C0D0A2F54797065202F506167650D0A2F506172656E742035203020520D0A2F5265736F7572636573203C3C0D0A2F466F6E74203C3C0D0A2F4630203620302052200D0A2F4631203720302052200D0A3E3E0D0A2F50726F635365742032203020520D0A3E3E0D0A2F436F6E74656E74732039203020520D0A3E3E0D0A656E646F626A0D0A362030206F626A0D0A3C3C0D0A2F54797065202F466F6E740D0A2F53756274797065202F54727565547970650D0A2F4E616D65202F46300D0A2F42617365466F6E74202F417269616C0D0A2F456E636F64696E67202F57696E416E7369456E636F64696E670D0A3E3E0D0A656E646F626A0D0A372030206F626A0D0A3C3C0D0A2F54797065202F466F6E740D0A2F53756274797065202F54727565547970650D0A2F4E616D65202F46310D0A2F42617365466F6E74202F426F6F6B416E74697175612C426F6C640D0A2F4669727374436861722033310D0A2F4C61737443686172203235350D0A2F576964746873205B20373530203235302032373820343032203630362035303020383839203833332032323720333333203333332034343420363036203235302033333320323530200D0A323936203530302035303020353030203530302035303020353030203530302035303020353030203530302032353020323530203630362036303620363036200D0A34343420373437203737382036363720373232203833332036313120353536203833332038333320333839203338392037373820363131203130303020383333200D0A38333320363131203833332037323220363131203636372037373820373738203130303020363637203636372036363720333333203630362033333320363036200D0A353030203333332035303020363131203434342036313120353030203338392035353620363131203333332033333320363131203333332038383920363131200D0A353536203631312036313120333839203434342033333320363131203535362038333320353030203535362035303020333130203630362033313020363036200D0A373530203530302037353020333333203530302035303020313030302035303020353030203333332031303030203631312033383920313030302037353020373530200D0A37353020373530203237382032373820353030203530302036303620353030203130303020333333203939382034343420333839203833332037353020373530200D0A363637203235302032373820353030203530302036303620353030203630362035303020333333203734372034333820353030203630362033333320373437200D0A353030203430302035343920333631203336312033333320353736203634312032353020333333203336312034383820353030203838392038393020383839200D0A34343420373738203737382037373820373738203737382037373820313030302037323220363131203631312036313120363131203338392033383920333839200D0A333839203833332038333320383333203833332038333320383333203833332036303620383333203737382037373820373738203737382036363720363131200D0A363131203530302035303020353030203530302035303020353030203737382034343420353030203530302035303020353030203333332033333320333333200D0A333333203535362036313120353536203535362035353620353536203535362035343920353536203631312036313120363131203631312035353620363131200D0A353536205D0D0A2F456E636F64696E67202F57696E416E7369456E636F64696E670D0A2F466F6E7444657363726970746F722038203020520D0A3E3E0D0A656E646F626A0D0A382030206F626A0D0A3C3C0D0A2F54797065202F466F6E7444657363726970746F720D0A2F466F6E744E616D65202F426F6F6B416E74697175612C426F6C640D0A2F466C6167732031363431380D0A2F466F6E7442426F78205B202D323530202D323630203132333620393330205D0D0A2F4D697373696E675769647468203735300D0A2F5374656D56203134360D0A2F5374656D48203134360D0A2F4974616C6963416E676C6520300D0A2F436170486569676874203933300D0A2F58486569676874203635310D0A2F417363656E74203933300D0A2F44657363656E74203236300D0A2F4C656164696E67203231300D0A2F4D6178576964746820313033300D0A2F4176675769647468203436300D0A3E3E0D0A656E646F626A0D0A322030206F626A0D0A5B202F504446202F5465787420205D0D0A656E646F626A0D0A352030206F626A0D0A3C3C0D0A2F4B696473205B3420302052205D0D0A2F436F756E7420310D0A2F54797065202F50616765730D0A2F4D65646961426F78205B203020302036313220373932205D0D0A3E3E0D0A656E646F626A0D0A312030206F626A0D0A3C3C0D0A2F43726561746F722028313732352E666D290D0A2F4372656174696F6E446174652028312D4A616E2D332031383A3135504D290D0A2F5469746C652028313732352E504446290D0A2F417574686F722028556E6B6E6F776E290D0A2F50726F647563657220284163726F6261742050444657726974657220332E303220666F722057696E646F7773290D0A2F4B6579776F7264732028290D0A2F5375626A6563742028290D0A3E3E0D0A656E646F626A0D0A332030206F626A0D0A3C3C0D0A2F50616765732035203020520D0A2F54797065202F436174616C6F670D0A2F44656661756C7447726179203131203020520D0A2F44656661756C7452474220203132203020520D0A3E3E0D0A656E646F626A0D0A31312030206F626A0D0A5B2F43616C477261790D0A3C3C0D0A2F5768697465506F696E74205B302E39353035203120312E30383931205D0D0A2F47616D6D6120302E32343638200D0A3E3E0D0A5D0D0A656E646F626A0D0A31322030206F626A0D0A5B2F43616C5247420D0A3C3C0D0A2F5768697465506F696E74205B302E39353035203120312E30383931205D0D0A2F47616D6D61205B302E3234363820302E3234363820302E32343638205D0D0A2F4D6174726978205B302E3433363120302E3232323520302E3031333920302E3338353120302E3731363920302E3039373120302E3134333120302E3036303620302E37313431205D0D0A3E3E0D0A5D0D0A656E646F626A0D0A787265660D0A302031330D0A3030303030303030303020363535333520660D0A30303030303032313732203030303030206E0D0A30303030303032303436203030303030206E0D0A30303030303032333633203030303030206E0D0A30303030303030333735203030303030206E0D0A30303030303032303830203030303030206E0D0A30303030303030353138203030303030206E0D0A30303030303030363333203030303030206E0D0A30303030303031373630203030303030206E0D0A30303030303030303231203030303030206E0D0A30303030303030333532203030303030206E0D0A30303030303032343630203030303030206E0D0A30303030303032353438203030303030206E0D0A747261696C65720D0A3C3C0D0A2F53697A652031330D0A2F526F6F742033203020520D0A2F496E666F2031203020520D0A2F4944205B3C34373134393531303433336464343838326630356638633132343232333733343E3C34373134393531303433336464343838326630356638633132343232333733343E5D0D0A3E3E0D0A7374617274787265660D0A323732360D0A2525454F460D0A";
public static void main(String[] args) throws Exception
{
String str = "";
for(int i=0;i<hex.length();i+=2)
{
String s = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(s, 16);
str = str + (char) decimal;
}
System.out.println("str:"+str);
FileOutputStream fos = new FileOutputStream("D:\\sampleFile.pdf");
int i = 0;
while (i < str.length()) {
fos.write(str.charAt(i));
i++;
}
fos.close();
}
}

For this example reference:

https://stackoverflow.com/questions/13990941/how-to-convert-hex-string-to-java-string

Other References:

http://www.codejava.net/java-se/file-io/how-to-read-and-write-binary-files-in-java

 

Note: For online conversion of hex to binary, vice versa you can check below site

http://tomeko.net/online_tools/hex_to_file.php?lang=en

Hope you enjoyed the post!

Advertisements

String & Math functions in Java

Math functions:

java.lang.Math class contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.

Math.min(num1, num2):

float minVal = Math.min(float a, float b);   
// data types allowed: int, long, float, double.

Math.max(num1, num2):

float maxVal = Math.max(float a, float b);  
// data types allowed: int, long, float, double.

Math.random(): This method returns a pseudo-random number of double data type greater than or equal to 0.0 and less than 1.0.

double randomVal = Math.random();  
// data type returns is double (o/p: 0.15726642068533314)

Math.sqrt(num1): This method returns the square root of a number.

double sqrtVal1 = Math.sqrt(25); // data type returns is double.
double sqrtVal2 = Math.sqrt(10); 
(o/p: 5.0)
(o/p: 3.1622776601683795)

Math.cbrt(num1): This method returns the square root of a number.

double sqrtVal1 = Math.cbrt(27); // data type returns is double.
double sqrtVal2 = Math.cbrt(125); 
(o/p: 3.0)
(o/p: 5.0)

Math.round(num1):

float roundVal = Math.round(float a); 
// data types allowed: float, double

Math.floor(num1): This method returns the floor value of given number.

double sqrtVal1 = Math.floor(27.89034); // data type returns is double.
(o/p: 27.0)

Math.ceil(num1): This method returns the ceiling value of given number.

double sqrtVal1 = Math.ceil(27.89034); // data type returns is double.
(o/p: 28.0)

String functions/Methods:

java.lang.String class provides 40+ methods to work with the strings.

A sample java class is also given at the bottom, for a better understanding of string functions.

equals(Str), equalsIgnoreCase(): To compare two strings. Returns true/false.

System.out.println("ravi".equals("ravi"));   // true 
System.out.println("ravi".equals("raviteja")); // false

compareTo(), compareToIgnoreCase(): To compare two strings. Returns true/false.

System.out.println("ravi".compareTo("ravi")); // 0
System.out.println("ravi".compareTo(null)); // NullPointerException

Note: For comparing two strings use the equals() method. comapreTo() method can also be used, but prefer to use equals() method as compareTo() method throws NullPointerException when comparing string with another string with null value.

contentEquals(Str): To compare a string with String Buffer.

String str1 = "StringValue";
StringBuffer str2 = new StringBuffer( "StringBuffer");
System.out.println(str1.contentEquals(str2 ));   // false

contains(Str): To check if the string contains the given string value.

String str1 = "StringValue";
String str2 = "Val";
System.out.println(str1.contains(str2));   // true

length(): To find the length of a given string.

String str1 = "StringValue"; 
str1.length(); // o/p: 11  
[Note that an array length can be found using 'arr.length;']

trim(): It’ll trim the white spaces at leading and trailing of given string.

String str1 = "     StringValue  ";  
str1.trim();  // o/p: StringValue

valueOf():  Irrespective of the data type by using this method you can convert any data type variable to string variable.

String str1 = String.valueOf(anyDataType_value);  // o/p: string format

substring(int beginIndex), substring(int beginIndex, int endIndex):  Used to get the required substring from the given string using given beginIndex, endIndex values.  Here you have to notice one thing that when beginIndex and endIndex are given, the result will include the char at start Index value and excludes (won’t include) the char endIndex value of string.

String str1 = "StringValue"
str1.substring(3);  // o/p: ingValue
str1.substring(3,8); // o/p: ingVa

split(String regex), split(String regex, int limit):  Splits the string as per given regular expression. The result will be stored as an array. You can pass the limit value also, which will splits the given string into given limit values.

 String Str = new String("Welcome-to-Hyderabad");
 String[] splitVals = Str.split("-");
 System.out.println(":"+Arrays.toString(splitVals)); 
 o/p: [Welcome, to, Hyderabad]
 
 String Str = new String("Welcome-to-Hyderabad-City");
 String[] splitVals = Str.split("-",2);
 String[] splitVals = Str.split("-",4);
 System.out.println(":"+Arrays.toString(splitVals)); 
 o/p: [Welcome, to-Hyderabad-City]
 o/p: [Welcome, to, Hyderabad, City]  

matches(String regex):  returns true if the given string matches with the given regular expression.

 String Str = "Welcome to Hyderabad City";
 System.out.println(Str.matches("(.*)Hyderabad(.*)"));  // o/p: true
 System.out.println(Str.matches("(.*)Hyderabad"));  //o/p: false

concat(Str):  returns true if the given string matches with the given regular expression.

 String Str = "Welcome to";
 System.out.println(Str.concat("Hyderabad"));
 // o/p: Welcome to Hyderabad

chatAt(int index):  returns the character present in the given string at specified location index. The return type will character.

 String Str = "Welcome to";
 char result = Str.charAt(5);
 System.out.println(result);  // o/p: m
Note: If char contains int value, use below way to convert char to int.
String Str = "137654";
int num= Character.getNumericValue(Str.charAt(3));
System.out.println(num); // o/p: 6

Arrays In Java

You already know that Array is a container which stores multiple values and the length of array will be fixed during declaration itself.

In this post let’s discuss Arrays of single dimensional, multi dimensional, Array’s functions etc.

One dimensional Array:  

long type:   long[] lng_arr = new long[3];
String type: String[] str_arr = new String[3];

similarly we can have arrays of other data types also. [byte[] anArrayOfBytes; short[]  anArrayOfShorts;  long[] anArrayOfLongs; float[] anArrayOfFloats;  double[] anArrayOfDoubles;  boolean[] anArrayOfBooleans;
char[] anArrayOfChars; String[] anArrayOfStrings;

Below is how we insert values to Array.

lng_arr[0] = 123; lng_arr[1] = 342; lng_arr[2] = 23;
str_arr [0] = "This"; str_arr [1] = "is"; str_arr [2] = "java_post"; 

You can also insert values to Array like given below. [giving values at the time of declaration itself]

long[] lng_arr = {123, 342, 23};
String[] str_arr = {"This", "is", "java_post"};

Now let’s see how we can print entire array itself. [using Arrays.toString(arr) we can achieve this]. For multi dimensional arrays we should use  Arrays.deepToString(arr).

System.out.println("lng_arr :"+lng_arr);  o/p: [J@3d04a311
System.out.println("lng_arr :"+Arrays.toString(lng_arr)); o/p: [123, 342, 23]
System.out.println("str_arr :"+Arrays.toString(str_arr)); o/p: [This,  is,  java_post]

Now let’s print single required value from the array: (for printing single value from the array, using of Arrays.toString(arr) is not required, which is used to print entire array in string foramt.

System.out.println("lng_arr[0] :"+lng_arr[0]);  o/p: 123
System.out.println("str_arr[2]:"+str_arr[2]);  o/p: java_post

Multi dimensional Array:  

long type:   long[][] lng_arr = new long[3][2];  
// [[a1, b1], [a2, b2], [a3, b3]]
(3 * 2) matrix would be like given below.
[a1, b1]
[a2, b2]
[a3, b3]
where [0][0] = a1;  [0][1] = b1;  [1][0] = a2;  [1][1] = b2;  [2][0] = a3;  [2][1] = b3; 

String type: String[][] str_arr = new String[2][3];  
// [[a1, b1,c1], [a2, b2, c2]]

similarly we can have arrays of other data types also. [byte[][] anArrayOfBytes; short[][]  anArrayOfShorts;  long[][] anArrayOfLongs; float[][] anArrayOfFloats;  double[][] anArrayOfDoubles;  boolean[][] anArrayOfBooleans;
char[][] anArrayOfChars; String[][] anArrayOfStrings;

Below is how we insert values to Array.

lng_arr[0][0] = 123;   lng_arr[0][1] = 342;    lng_arr[1][0] = 23;  lng_arr[1][1] = 223;  lng_arr[2][0] = 13;     lng_arr[2][1] = 323; 

str_arr [0][0] = “Mr. “;  str_arr [0][1] = “Mrs. “;    str_arr [0][2] = “Ms. “;  str_arr [1][0] = “Swamy “;  str_arr [1][1] = “Kumar”;    str_arr [1][2] = “Sita”; 

You can also insert values to Array like given below. [giving values at the time of declaration itself]

long[][] lng_arr = {{123, 342}, {23, 223}, {13, 323}};
String[][] str_arr = {{"Mr. ", "Mrs. ","Ms. "},{"Swamy","Kumar","Sita"}};

Now let’s see how we can print entire array itself. [using Arrays.deepToString(arr) we can achieve this].

System.out.println("lng_arr :"+Arrays.deepToString(lng_arr ));  
o/p: [[123, 342], [23,223], [13,323]]

System.out.println("str_arr :"+Arrays.deepToString(str_arr )); 
o/p: [[Mr. , Mrs. , Ms], [Swamy, Kumar, Sita]]

Now let’s print single required value from the array: (for printing single value from the array, using of Arrays.toString(arr) is not required, which is used to print entire array in string foramt.

System.out.println("lng_arr[0][1]:"+lng_arr[0][1]);  o/p: 342
System.out.println("str_arr[1][2]:"+str_arr[1][2]);  o/p:  sita

Arrays functions:  

Sort:   Sorting of Array can be achieved using Arrays.sort() method.

Given your array like below

long[] lng_arr = {18, 13, 23, 16, 20};
Arrays.sort(lng_arr);  
System.out.println("lng_arr:"+  Arrays.toString(lng_arr));  
o/p:  [13, 16, 18, 20, 23]

Sort some portion of Array: 

Sorting of Array can be achieved using Arrays.sort() method.

Given your array like below

long[] lng_arr = {18, 13, 23, 16, 20, 34, 12, 7};
Arrays.sort(lng_arr, 2, 5);  
System.out.println("lng_arr:"+  Arrays.toString(lng_arr)); 
o/p:  [18, 13, 16, 20, 23, 34  ,12, 7]

Get a value from array at specified index:

long[] lng_arr1 = {18, 13, 23, 16, 20, 34, 12, 7};
System.out.println(lng_arr1[4]);  // o/p:  20

Note: For list you need to use the get function.
List<Long> lst = new List<>();  
lst.add(27); lst.add(34); lst.add(23);
lst.get(1); //o/p: 34

To Print Entire Array: use Arrays.toString for one dimensional array and use  Arrays.deepToString for multi dimensional arrays and arrays converted from list.

long[] lng_arr1 = {18, 13, 23, 16, 20};
long[][] lng_arr2 = {{123, 342}, {23, 223}, {13, 323}};
System.out.println(Arrays.toString(lng_arr1)); 
System.out.println(Arrays.deepToString(lng_arr2));  
o/p:  [18, 13, 23, 16, 20]
[[123, 342], [23,223], [13,323]]

length: use length to find the length of an array.

long[] lng_arr = {18, 13, 23, 16, 20};
System.out.println(lng_arr.length);   o/p:  5

Note: To find the length of a list use size function.
List<Long> lst = new List<>();  
lst.add(27); lst.add(34); lst.add(23); 
lst.size(); //o/p: 3

To find the length of a string use length() function.
String val = "ravi";
System.out.println(val.length()); //o/p: 4

Happy Coding !

 

 

While loop in SOA

In this post let’s see how we can use While loop in SOA BPEL.

In the example below, we pass input as a number (n) and the response would be sum of all numbers till n (0+1+…n).

  • Create SOA Application (SOA_Appln)
  • Create SOA Project (SOAproj_While)
  • Create BPEL (Synchronous BPEL 2.0)
  • Edit the XSD like below.

 

  • Create two scope variables at BPEL scope level (‘sum’, ‘i’) of type ‘xml schema simple type – int’.

  • Now add Assign activity below receive activity and double click on it. drag an expression and give the value 0 and map it to the scope variable ‘sum’ which we created before. similarly create another expression, give value as 0 and map it to scope variable ‘i’.

  • Now drag the while activity below the Assign1 activity.  Double click on it and give the condition as ($i < $inputVariable.payload/client:input) which means while this condition satisfies the loop will be executed.

  • Now we need to increment the value right, so drag the assign activity inside while loop and double click on it.  drag the expression builder and give the value as $i+1 and map it to scope variable ‘i’. similarly again drag expression builder and give value as $i+$sum and map it to scope variable ‘$sum’ which means we are summing the sum value with the current loop count. (If loop is 4 then sum would be sum+4. Till the loop3, sum will be 1+2+3 =>6. So at loop4 sum would be sum+4 => 6+4 => 10.

  • We are done with the while loop. After the loop exits, now we need to assign the final sum value which we stored in the scope variable ‘sum’ to the output variable. So create an assign activity after while loop and double click on it.

  • The final BPEL will look like below.

  • Deploy the application to SOA server.
  • Let’s test the project. Give input as ‘4’ and the output would be ’10’.

Happy Looping 🙂

 

AM Service Interface (Expose ADF BC as web services/ service Enabled data objects SDOs)

======================================================
PART – 1:
AppModule Service Interface webservice genearation [Expose ADF BC as SDOs service enabled daat objects]:
-> create ADF application with business components (EO, VO, AM)
-> write two custom methods in AppModuleImpl class and expose those methods to Client Interface.
-> double click AM -> Service Interface tab -> you can see three sections ‘service Interface for custom methods’, ‘service interface for view instances’, ‘Genearated files for Service interface’.
-> select required methods/view Instances of datamodel in respective sections. When you select a view instance, operations for that view isntance are displayed jsut beside to it and we can select what operations to enable for the view instance [oeprations as ‘update’ to edit the record of that view instance, ‘Find’ to retrieve the records from that view instance, Create, Delete, Merge, GetByKey, Process, etc..].
-> After selection, under AM a folder named ‘service interface’ will be created which contains webservice artifacts [AppModuleService.java, AppModuleServiceImpl.java, AppModuleService.wsdl, AppModuleService.xsd]
-> Deployment: create deployment profile for ‘[Business Components Service Interface]’. deploy [check Model projetc is checked and under which both ‘common’, ‘middletier’ selected for integrated weblogic, and only ‘middletier’ selected for deployment on servers]
-> Test the webservices from Weblogic EM console like the same way you test SOA webservices.
======================================================
Sample custom methods which you can expose in AM:
public void updateSalary(Number employeeId, Number salary){
Key key = new Key(new Object[] {employeeId});
Row row = this.getEmployeesView1().getRow(key);
row.setAttribute(“Salary”, salary);

try{
this.getDBTransaction().commit();
}
catch(Exception ex){
ex.printStackTrace();
}
// The above methods accepts EmpId, Salary as input and updates the salary for the given EmpId in DB
======================================================
Note: we need Oracle web services manager to define the security policy for AppModule Webservices(according to documentation B31974-05 section 11.2.13). So need to license Oracle SOA suite cos webservices manager comes under SOA suite. So without using SOA, if you want to expose webservice from ADF business components you can not proivde security to them.
These exposed websrevices will creates new AM configuration and uses AppModule pool for DB connection when invoked.
======================================================
References:
http://andrejusb.blogspot.in/2009/08/web-service-interface-for-adf-bc.html

For secured WS you can check this post – http://andrejusb.blogspot.com/2012/11/adf-mobile-secured-web-service-access.html This is about ADF Mobile, but Web Service part is about secured AM Web Service
====================================================== ======================================================
====================================================== ======================================================
====================================================== ======================================================
PART – 2:
In above we have exposed the ADF Business component services as webservice (service enabled data objects/SDO).
Now we can consume those ADF BC services from SOA applicaiton or from another ADF application also.
Now we are discussing on How to consume remote ADF BC services[AM methods, VOs] which are exposed as webservice in other ADF applicaiton.

Create a new ADF applicaiton. [In this applicaiton we create Service Enable Entity Objects, whcih means EOs are created based on SDOs (service enabled objects)]
create Entity object-> when creating EO uncheck defalut datasource selection ‘DB schema object’, check ‘Service Interface’, give the WSDL URL and select the Service ViewInstance from dropdown.
Run the AM, now you can create a record, update record, delete record.
EO based on remote VO exposed though webservice (Service enabled EOs) will be similar to EO based on DB. But Joins doesn’t work for this EO when you create EO based on VO exposed as webservice.
We can declare Business Events on Service-Enabled Entity Objects, it works same as declared on normal Entity Object.
You can see the attributes but you can see the query, as this EO will get data dynamically as this is based on webservice.
So this is how you can crete a EO from a VO based on remote applicaiton which is exposed through webservice.
Deployment: Here first you need to add the ‘applnname_common.jar’ library of exposed applicaion to this consuming applicaiton.
Give the service connection information in connectons.xml. Now you can deploy and test from EM console.
Note: The operations which you select for a view isntance during exposing AM, those will only be available for applications when consuming them.
———————————–
References: http://andrejusb.blogspot.in/2009/08/service-enabled-entity-objects-in.html
====================================================== ======================================================
====================================================== ======================================================
====================================================== ======================================================
PART – 3:
Creating Business Event and subscribing to that event in Oralce SOA.
Busieness Events allows the loose coupling. Busieness Events can be created from ADF BC or from SOA.
These Business Events can be subscribed in SOA composite using Mediator.

References:
http://andrejusb.blogspot.in/2009/08/business-events-and-adf-business.html
http://biemond.blogspot.in/2008/05/events-in-adf-bc-and-handled-by-soa.html

————–

-> Oracle ADF Functional Patterns and Best Practices
http://www.oracle.com/technetwork/developer-tools/adf/index-100668.html

-> Customizing and Personalizing an Application
http://docs.oracle.com/cd/E18941_01/tutorials/jdtut_11r2_18/jdtut_11r2_18.html

-> Oracle Fusion Applications
12c: https://docs.oracle.com/applications/falcm12/OADEE/title.htm
11.1.8: https://docs.oracle.com/cd/E48434_01/fusionapps.1118/e15524/gs_gs_e.htm#CDEHADGG

 

ADF Customization

================== Customization: ========================

-> Oracle ADF allows us to create customizable web applications.
-> customizable applications means there will be one base application. On top of that application we develop multiple versions of application using multiple customizable layers and their contexts.
-> One customization layer can have multiple customization contexts (values)
-> At a time only one customizable layer value (context) will be applied on the base application (we can give one cust layer as default in properties file). Note that all the customization layers can be applied but only one context from each layer.
-> We select one customizable layer’s context from the ‘customization context window’ and we can work on the base application.
-> Similarly we can select another customizable layer’s context and work on the base application. Here you need to note that the customizations that you have done in one customizable layer’s context won’t appear in other customizable layer’s context.
Customization layers could be: ‘industry’. ‘site’Customization contrexts could be (need to input like below in proeprties file) industry=financial #industry=healthcare #site=remoteoffices site=headquarters So from the above settings if we run the application industry cust layer’s financial context will be applied on base appln along with site cust layer’s headquarters context.
How to do it? ‘Open Jdeveloepr with Default Role’
-> prerequisite: create one sample ADF web applicaiton.
-> 1) Create Customization Layers in ‘customizationLayerValues.xml’ file (which is present under <JDEVELOPER_HOME>/jdeveloper/jdev) This applies to all applications.If you want to aplly these customization layers to only this applicaiton then open adf-config.xml and udner the MDS tab, click on the link ‘Configure Design Time customizations’ which creates a file ‘customizationLayerValues.xml’ under ApplicaitonResources -> MDS DT  [Create cust layers as ‘site’, ‘industry’]
-> 2) Now define the Customization Contexts for each customization layer. So create a proeprties file ‘customization.proeprties’ under the modal project and give entries like below. industry=financial #industry=healthcare #site=remoteoffices site=headquarters

-> 3) Now create the customization class for each Customization Layer. [SiteCC, IndustryCC]. paste the belwo code into these class files. These classes will pick up the properties file and applies the customization layer’s context on the base applicaiton.
-> 4) Now defiene the created customization classes in adf-config.xml file under MDS tab.
-> 5) right click on viewContrller project -> ADF View -> check ‘Enable Seeded customizations’.
-> 6) Now work on Taskflows and UI. #So far we discussed about base applicaiton. #Now we disucss how to customize this base appln.
-> 7) Close Jdev and Reopen with ‘Fusion  apps developer Role/ Fusion apps Admstr Customization Role’ to start customization.
-> 8) First open with ‘Fusion  apps developer Role’ and create a ‘Fusion Apps customization application’. Name: XxCustomizationDemoApplicationpackage prefix: com.oracleDeployed EAR: baseAppln.earNext  -> Project Name: XxCustomizationDemoProject -> FinishThe created application contains Project ‘XxCustomizationDemoProject’ and folders under it are ‘Appln sources’,’Resources’,’Web content’.The base applicaton war files are available under ‘Application Resources ->  customizable Archive -> Base Appln Archive’.
-> 9) Now close and Reopen jdev with ‘Fusion apps Admstr Customization Role’.Now select the customization layer and its context. These latyers and their contexts are defined in the base application.For Fusion SCM we have the below cust layers.Global -> value/context: GlobalSite -> value/context: Site
-> 10) Under Application Resources -> customizable Archive -> Base Appln Archive ->  Right click and Filter.search for the jspff page/ taskflow (that should present in base applicaiton).Now under  ‘Base Appln Archive’ you can see only filtered files. Right click on that file and click on ‘customize’ option.It’ll promt to Add library. click on Add Library. When you do this under the project a folder ‘ADF Library Customizations’ will be created. And under this folder you see the page/taskflow which you selected to customize. [Note: the page/taskflow will be maintained its full path as in base applicaiton under the ‘ADF Library Customizations’ folder]-> Now you can customize the jsff page. [its not editable and only properties can be modified from property inspector]when you customize any component, under the project a folder ‘ADF Library Customization Sources’ will be created. Under this folder you can see the page which you customized with XML extension (eg: Invoicecreate.jsff.xml) The original full path of the page wil be maintained and under that path again few folders will be created (mdssys -> cust -> Global/Site (cust layer) -> GLOBAL/SITE (cust context) -> Invoicecreate.jsff.xmlFor any New component (jsff page, taskflow, VO etc) you need to switch to ‘Fusion  apps developer Role’.
cont…
=================================================

-> Let’s take an example. Create a base application with ‘EmplApp’ and create business comopnents (EmployeeEO, DeptEO, LocationEO, EmployeeVO, AM). -> Now create a view (employees.jsf) and display the Employee details like a form.So far we have developed the base application.

-> Now suppose our requirement is one customizable layer (LocationLayer) we want to show employee details as table with attributes only related to location.->  Now suppose our requirement is one customizable layer (DepartmentLayer) we want to show employee details as table with attributes only related to department.
-> To fulfill above requirement first we need to close jdev. And reopen with customization role.

-> Now right click on viewcontroller project and select ADF View -> Enable Seeded customizations.

-> Give entries of the requried customization layers in the customizationLayerValues.xml file (which is present under <JDEVELOPER_HOME>/jdeveloper/jdev) This applies to all applications. If you want to aplly these customization layers to only this applicaiton then open adf-config.xml and udner the MDS tab, click on the link ‘Configure Design Time customizations’ which creates a file ‘customizationLayerValues.xml’ under ApplicaitonResources -> MDS DT

-> Now we created customization layers, so we need to define them in the proeprties file. create a properties file in the Modal project ‘customization.proeprties’.  In the properties file define the different contexts to a single cutomization layer.

=====================================

 

Bounded Task flow ‘Transaction’ & ‘Share DC’ properties

-> Data Control scope [Shared/Isolated] & Transaction Options:
If bounded taskflow Overview -> behavior -> check box ‘shared data controls with calling Tf’ is Not checked means that this taskflow get its own data control frame. means having Isolated data controls.
If the property is checked means BTF uses the parent page(calling page) datacontrol frame instead creatig a new one.

Refer- Share data controls behavior [same data to be displayed on base page and region present it]:
https://tompeez.wordpress.com/2012/07/27/jdeveloper-adf-carefully-select-the-data-control-scope-of-bounded-task-flows/

Refer- (Transaction optios& datacontrol scope options): http://www.oracle.com/technetwork/developer-tools/adf/learnmore/adf-task-flow-trans-fund-v1-0-1723395.pdf?bcsi_scan_510c2960d4f4e50e=5IfxgIvC5gAAdZN467HNcuezvLAFAAAA7KQgLA==&bcsi_scan_filename=adf-task-flow-trans-fund-v1-0-1723395.pdf

Eg: Let’s take a basepage and display departments as readonly table. Keep two buttons to call two different bounded taskflows. for BTF1 keep the datacontrols scope proeprty to ‘shared’. So when you navigatte from basepage to BTF1 on click of button1 then the row selection in basePage will be maintained here also. Now chagne row and navigate back to basePage, again the row selection is mainainted. This is because by keeping the option to ‘shared’ will use the same datacontrol instance/frame.
Now for BTF2 keep the datacontrol proeprty to ‘isolated’ and call this BTF2 on click on button2 from base page. when you naviagate from basePage to BTF2 row selection is not maintained. Now chagne row and naviagate back to the basePagea again you can see row selection in basePage is different from selected row in BTF2. Beacause we set the datacontrol option to Isolated, it creaetd two different datacontrol instances for basepage and BTF2. [BTF2 is not using the basepage instance]
Note: 1)In above example the transaction property is left default which is “<No Controller Transaction>”
2) You can have N number BTF calling chain having datacontrol option as isolated/shared for each.
eg: UnboundedTF -> BTF1(shared) -> BTF2(isolated) -> BTF3(isolated) -> BTF4(shared)
In the above flow BTF1 uses the UTF’s datacontrol instacne (for matching datacontrols metadata)
BTF2 creates its new datacontrol instacne.
BTF3 creates its new datacontrol instacne.
BTF4 uses the BTF3’s datacontrol instacne (for matching datacontrols metadata)
3) if base page has Employee table and it is calling a BTF whose data control property is ‘shared’ and which has a page showing Departments table. Here though you set datacontrol property to ‘shared’ for BTF, as there are no datacontrol in BTF which present in basePage, a new datacontrol instance/frame will be created for the BTF.
We need to undertand from here is that datacontrol can be shared only if the metadata of datacontrol is same in current page and calling BTF. datacontrols meta data is present in page definition files.
4) (Not sure, mostly correct) Now let’s take another example, base page showing employees table and it is calling a BTF whose datacontrols property is set to ‘shared’ and which is having a page showing ‘Employees table’ and ‘departments’ table and ‘Jobs’ table. Now in this case only employees datacontrols are sahred and when you navigate from base page to BTF you can see the row selection will be maintained. but for deaprtments, jobs datacontrols it creates a new datacontrolFrame/ datacontrol instance as the department datacontrol, jobs datacontrol metadata is not present in parent page. the created dataControlFrame has datacontrols of departments, jobs only. Employees datacontrol will be taken from the existing dataControlFrame

5) So far we discussed about this property (Share data control with calling TF) behavior when navigating from one UBT/BTF to other BTF.
But this can also be used when you have differnt BTFs and they are present in a page as regions. If you set ‘shared data control with calling TF’ property to both the TFs present in the page then, selecting in one TFs table/row will be also change the current row in otehr TF if both have common data controls.

->
Transaction Options:
bounded taskflow Overview -> behavior -> Transaction drop down
‘No Controller Transaction’
‘Always Begin New Transaction’
‘Always Use the Existing Transaction’
‘Use the Existing Transaction If Possible’

Note: 1) Is transaction is open/Not for a datacontrol frame will be known to the framework by using method ‘ DataControlFrame.getOpenTransactionName()’
2) DataControlFrame also contains commit(), rollback() methods. Note that these are not the data control’s associated commit and rollback operations. DataControlFrame contains many datacontrols and the commit/rollbak methods in it applies to all the datacontrols in it.


Always Begin New Transaction:
Transaction (Always Begin New Transaction) + Datacontrol Scope (Isolated) => Valid
Transaction (Always Begin New Transaction) + Datacontrol Scope (Shared ) => throw error “ADFC-00020 + Task flow ‘<name>’ requires a new transaction, but a transaction is already open on the frame” at runtime.

If this option is set then, TF must call a Taskflow Return activity with ‘End Transaction’ property to ‘Commit/Rollback’ options.

Always Use the Existing Transaction:
Transaction (Always Use Existing Transaction) + Datacontrol Scope (Shared) => Valid
Transaction (Always Use Existing Transaction) + Datacontrol Scope (Isolated) => throw error “ADFC-00006: Existing
transaction is required when calling task flow <task flow name>” at runtime.

If this option is set then, TF SHOULD NOT call a Taskflow Return activity with End Transaction property to ‘Commit/Rollback’ options. If you do so, at design time only the return activity will be flagged as error and agt run time they’ll be ignored. You can set the return activity ‘End Transaction’ property to ‘None’.

Use the Existing Transaction If Possible: [If you are not sure about parent transaction, choose this option]
Transaction (Use Existing Transaction if Possible) + Datacontrol Scope (Isolated) == Transaction (Always Begin New Transaction) + Datacontrol Scope (Isolated)
Transaction (Use Existing Transaction if Possible) + Datacontrol Scope (Shared) (If datacontrol frame of parent has Open the transaction) then == Always Use Existing Transaction + Shared
Transaction (Use Existing Transaction if Possible) + Datacontrol Scope (Shared) (If datacontrol frame of parent has not Not Open the transaction) then == Always Begin New Transaction + Shared

Let’s see an example (here arrow (->) means navigaiton (calling))
UTF -> BTF1 (TXN-exisitng) -> BTF2 (TXN-New) -> BTF3 (TXN-New) -> BTF4 (TXN-exisitng)

BTF1: it uses exisitng transaction. uses same AM instance of UTF. [I assume dataControl proeprty is shared]
BTF2: it begins new transaction. new AM isntance created. so it must call taskflow return with End transaction prperty as Commit/Rollback [I assume dataControl proeprty is Isolated]
BTF3: it begins new transaction. new AM isntance created. so it must call taskflow return with End transaction prperty as Commit/Rollback [I assume dataControl proeprty is Isolated]
BTF4: it uses exisitng transaction of UTF. Here you can not set ‘End Transaction’ property of taskflow return activity to commit/rollback. it should be default (none). Once control is returned to UTF then from there you can commit/rollback.
When you commit int UTF now, then data changed in UTF& BTF4 will get committed. (BTF2, BTF3 data has to be committed there itself).
If you do not set the Transaction property to the BTF then Transaction will not be started. And if perform any transaction events, then you get run time exception.
————————————–
-> <No Controller Transaction>: The called bounded task flow does not participate in any transaction management.
-> Always Use Existing Transaction: When called, the bounded task flow participates in an existing transaction already in progress.
-> Use Existing Transaction If Possible: When called, the bounded task flow either participates in an existing transaction if one exists, or starts a new transaction upon entry of the bounded task flow if one doesn’t exist.
-> Always Begin New Transaction: A new transaction starts when the bounded task flow is entered, regardless of whether or not a transaction is in progress. The new transaction completes when the bounded task flow exits.
————————————–
Programatically call a DataControl frame and commit one datacontrol in it.

BindingContext bc = BindingContext.getCurrent();
String dcfName = bindingContext.getCurrentDataControlFrame();
DataControlFrame dcf = bc.findDataControlFrame(dfcName);
dcf.commit(); // or dcf.rollback();
——————————————–

References:

http://www.oracle.com/technetwork/developer-tools/adf/learnmore/adf-task-flow-trans-fund-v1-0-1723395.pdf?bcsi_scan_510c2960d4f4e50e=MK7LAETxsnA5rjnzFCVS1zXfnVgHAAAA/0s/QA==&bcsi_scan_filename=adf-task-flow-trans-fund-v1-0-1723395.pdf