Quantcast
Channel: Ashish Awasthi's Blog
Viewing all 165 articles
Browse latest View live

Get Installed Printer List using Java, Print a file with default Printer

$
0
0



This post shows that how can we get installed printers list using PrintServiceLookup class


Implementations of this class provide lookup services for print services






package client;

importjavax.print.PrintService;
importjavax.print.PrintServiceLookup;

publicclassGetInstalledPrinters{

publicstaticvoidmain(String[] args){
String defPrinter;

PrintService[] printService = PrintServiceLookup.lookupPrintServices(null,null);

System.out.println("List of Installed Printers- ");
for(int i =0; i < printService.length; i++){
String printerName = printService[i].getName();
System.out.println(i +1+". "+ printerName);
}

defPrinter = PrintServiceLookup.lookupDefaultPrintService().getName();
System.out.println("\nDefault Printer Name - "+ defPrinter);
}
}


Print File with Default Printer-



package client;

importjava.awt.Desktop;

importjava.io.File;
importjava.io.IOException;

publicclassDesktopPrint{
publicDesktopPrint(){
super();
}
publicstaticvoidmain(String[] args){
Desktop desktop = Desktop.getDesktop();
try{
desktop.print(new File("D:/Export.txt"));
}catch(IOException e){
e.printStackTrace();
}
}
}



ADF Basics: Duplicate Record Validation Using Model Level Business Rules

$
0
0

Hello All

Hope you all are doing well :)

When we are creating any data entry form , at that time preventing duplicate entries for some of attributes is very basic validation requirement .

Suppose We are creating a form to make new Departments entry and  there should not be two departments with same name so for this type of validation we need not to write single line of code in Oracle ADF as there are predefined business rules for basic validation



In this post I am discussing how to apply model level business rule for duplicate record validation, Here I am using Departments table of HR Schema to create business components (EO,VO)


Open EntityObject and create a alternate key for DepartmentName attribute, On this alternate key we will apply business rule


Click on Buisness Rules tab, Select DepartmentsEO and Click on Green plus icon


Select Unique Key Validation in type for Alternate Key


Go to Failure Handling tab and put a message that you want to appear in case of validation failure


Now drop Departments ViewObject on page as form from data control and drop createInsert operation as button and set autoSubmit true for DepartmentName attribute (to post it's value to model for immediate validation)

<af:panelBoxtext="Duplicate Record Validation"id="pb1"showDisclosure="false"background="medium"
inlineStyle="width:550px;"ramp="highlight">
<f:facetname="toolbar">
<af:buttonactionListener="#{bindings.CreateInsert.execute}"text="CreateInsert"
disabled="#{!bindings.CreateInsert.enabled}"id="b1"/>
</f:facet>
<af:panelFormLayoutid="pfl1">
<af:inputTextvalue="#{bindings.DepartmentId.inputValue}"
label="#{bindings.DepartmentId.hints.label}"
required="#{bindings.DepartmentId.hints.mandatory}"
columns="#{bindings.DepartmentId.hints.displayWidth}"
maximumLength="#{bindings.DepartmentId.hints.precision}"
shortDesc="#{bindings.DepartmentId.hints.tooltip}"id="it1"
contentStyle="width:150px;">
<f:validatorbinding="#{bindings.DepartmentId.validator}"/>
<af:convertNumbergroupingUsed="false"pattern="#{bindings.DepartmentId.format}"/>
</af:inputText>
<af:inputTextvalue="#{bindings.DepartmentName.inputValue}"
label="#{bindings.DepartmentName.hints.label}"
required="#{bindings.DepartmentName.hints.mandatory}"
columns="#{bindings.DepartmentName.hints.displayWidth}"
maximumLength="#{bindings.DepartmentName.hints.precision}"
shortDesc="#{bindings.DepartmentName.hints.tooltip}"id="it2"
contentStyle="width:150px;"autoSubmit="true">
<f:validatorbinding="#{bindings.DepartmentName.validator}"/>
</af:inputText>
<af:inputTextvalue="#{bindings.ManagerId.inputValue}"
label="#{bindings.ManagerId.hints.label}"
required="#{bindings.ManagerId.hints.mandatory}"
columns="#{bindings.ManagerId.hints.displayWidth}"
maximumLength="#{bindings.ManagerId.hints.precision}"
shortDesc="#{bindings.ManagerId.hints.tooltip}"id="it3"
contentStyle="width:150px;">
<f:validatorbinding="#{bindings.ManagerId.validator}"/>
<af:convertNumbergroupingUsed="false"pattern="#{bindings.ManagerId.format}"/>
</af:inputText>
<af:inputTextvalue="#{bindings.LocationId.inputValue}"
label="#{bindings.LocationId.hints.label}"
required="#{bindings.LocationId.hints.mandatory}"
columns="#{bindings.LocationId.hints.displayWidth}"
maximumLength="#{bindings.LocationId.hints.precision}"
shortDesc="#{bindings.LocationId.hints.tooltip}"id="it4"
contentStyle="width:150px;">
<f:validatorbinding="#{bindings.LocationId.validator}"/>
<af:convertNumbergroupingUsed="false"pattern="#{bindings.LocationId.format}"/>
</af:inputText>
</af:panelFormLayout>
</af:panelBox>

Click on CreateInsert button and add a duplicate DepartmentName and this is the output


Sample ADF Application (Jdev 12.1.3)- Download

Cheers :) Happy Learning

Uploading mulitiple files to server path in Oracle ADF using af:inputFile

$
0
0


Hello All :)

Previously I have posted about uploading and downloading files from server path (Refer this post for more clarification), In that post I have described the process of uploading single file at a time but sometimes we need to upload multiple files at a time and for that requirement we can use same code with little modification


So In this post we'll see that how can we upload multiple files at a time using af:inputFile, Here I am using same sample application that is used in previous post



Default inputFile source looks like this

<af:inputFilelabel="Select"id="if1"valueChangeListener="#{viewScope.FileUploadDownloadBean.uploadFileVCE}"
autoSubmit="true"/>



To enable multiple files selection in af:inputFile we have to set some properties


<af:inputFilelabel="Select"id="if1"
valueChangeListener="#{viewScope.FileUploadDownloadBean.uploadFileVCE}"
autoSubmit="true"rows="5"maximumFiles="5"/>

and what rows and maximumFiles properties means ?

rowsintYesan attribute that determines the number of rows in the file list. There will be a scrollbar which will be displayed when the number of files exceeds this number.

maximumFilesintYesan attribute that is used to restrict the number of files a user can upload. If the user tries to upload more files than specified in maximumFiles then an error is returned. If maximumFiles is less than 1 then the number of files is unlimited.

After setting these properties inputFile looks like this


Now UI part is done , next is code part so to get and upload multiples files from client we have to use a List data structure and then in value change listener we'll traverse that List and upload all files to server path.

ValueChangeListener of af:inputFile- 



/*****Generic Method to Get BindingContainer**/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
* Generic Method to execute operation
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;

}

/**Method to Upload Multiple Files ,called on ValueChangeEvent of inputFile
* @param vce
*/
publicvoiduploadFileVCE(ValueChangeEvent vce){
if(vce.getNewValue()!=null){
//Get File Object from VC Event
List<UploadedFile> lf =(List<UploadedFile>) vce.getNewValue();

//Traverse over file list to upload all files
for(UploadedFile fileVal : lf){
//Method to check if this file is uploaded previously or not
OperationBinding duplOb = executeOperation("checkDuplicateFile");
duplOb.getParamsMap().put("fileNm", fileVal.getFilename());
duplOb.execute();
if(duplOb.getResult()!=null&&"Y".equalsIgnoreCase(duplOb.getResult().toString())){

System.out.println("Called");
//Upload File to path- Return actual server path
String path = uploadFile(fileVal);
System.out.println(fileVal.getContentType());
//Method to insert data in table to keep track of uploaded files
OperationBinding ob = executeOperation("setFileData");
ob.getParamsMap().put("name", fileVal.getFilename());
ob.getParamsMap().put("path", path);
ob.getParamsMap().put("contTyp", fileVal.getContentType());
ob.execute();

}
}
// Reset inputFile component after upload
ResetUtils.reset(vce.getComponent());
}
}

AMImpl Method to check duplicate file-


/**Method to check for duplicate files
* @param fileNm
* @return
*/
public String checkDuplicateFile(String fileNm){
ViewObject fileVo =this.getFileUpdDwn1();
Row duplFile[]= fileVo.getFilteredRows("FileName", fileNm);
if(duplFile.length>0){
return"N";
}else{
return"Y";
}
}

For other methods and DB table refer previous post Uploading and downloading files from absolute server path
So All done for multiple files upload now run and check application



Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :)  Happy Learning

ADF Basics: Duplicate Record Validation Using Custom Java Method

$
0
0

Hello All

Recently I have posted about duplicate record validation using model level business rules (Unique Key Validation) but sometimes we need to check some more conditions or we have some other logic that should be checked before validating the input then in that case we can write custom java method in model (Application Module Impl class) and call it in bean validator using binding layer


So In this post I am showing how to validate duplicate record using custom java method, Here I am using Departments table of HR Schema to create business components (EO,VO)


Open Application Module , create Application Module Impl class and method to check duplicate department name



/**Custom Java Method to validate department name**/
public String deptNameValidator(String deptNm){
ViewObject vo =this.getDepartments1();
//Create RowSetIterator of ViewObject
RowSetIterator rsi = vo.createRowSetIterator(null);
//Get current row of viewObject
Row cRow = vo.getCurrentRow();
int count =0;
String departmentName ="";
//Iterate over viewObject to check duplicate record
while(rsi.hasNext()){
Row r = rsi.next();
//Check all rows other than current row
if(!r.equals(cRow)&& r.getAttribute("DepartmentName")!=null){

departmentName = r.getAttribute("DepartmentName").toString();
if(deptNm.equalsIgnoreCase(departmentName)){
count = count +1;
}
}
}
rsi.closeRowSetIterator();
if(count >0){
return"Y";
}else{
return"N";
}
}

and created a bean validator for Department Name attribute

<af:inputTextvalue="#{bindings.DepartmentName.inputValue}"
label="#{bindings.DepartmentName.hints.label}"
required="#{bindings.DepartmentName.hints.mandatory}"
columns="#{bindings.DepartmentName.hints.displayWidth}"
maximumLength="#{bindings.DepartmentName.hints.precision}"
shortDesc="#{bindings.DepartmentName.hints.tooltip}"id="it2"
contentStyle="width:150px;"autoSubmit="true"
validator="#{viewScope.DuplicateRecordBean.departmentNameValidator}">
<f:validatorbinding="#{bindings.DepartmentName.validator}"/>
</af:inputText>

and code for bean validator in managed bean is

/**Method to get BindingContainer of current view port
* @return
*/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}


/**
* Generic Method to execute operation
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;

}

/**Validator to check duplicate department name.
* @param facesContext
* @param uIComponent
* @param object
*/
publicvoiddepartmentNameValidator(FacesContext facesContext, UIComponent uIComponent, Object object){
if(object !=null){
String currency = object.toString();
OperationBinding ob = executeOperation("deptNameValidator");
ob.getParamsMap().put("deptNm", currency);
ob.execute();

if(ob.getResult()!=null){
String flag = ob.getResult().toString();

if("Y".equalsIgnoreCase(flag)){
thrownewValidatorException(new FacesMessage("Duplicate Record",
"This Department Name exists in Database"));
}
}
}
}

Now run and check application -

Sample ADF Application (Jdeveloper 12.1.3)-Download
Cheers :) Happy Learning

Import data from XLS and XLSX (Excel) to ADF Table Using Apache POI

$
0
0
ADF provides feature to export data to excel using export collection listener with just one click but there is no built in feature to upload data from excel file to ADF table

For this requirement we have to use some other API and Apache POI is best for excel communication, In this post I am going to discuss about uploading excel (XLS and XLSX) file data to ADF table



Apache POI provides HSFF and XSFF to read ,create and modify spreadsheets.
You can download POI jars from The APACHE Software Foundation or from here
Next step is to create a Fusion Web Application, prepared model using Employees table of HR Schema



Create a page and drop an af:inputFile component and employees viewObject as table on page, create value change listener (to read and upload data to table from excel file) for inputFile in managed bean

<af:inputFilelabel="Select File"id="if1"
valueChangeListener="#{viewScope.UploadExcelBean.uploadFileVCE}"
autoSubmit="true"
labelStyle="font-weight:bold;color:navy;"/>

Create component binding of Employees table in managed bean and use these java methods

//Component Binding of af:table
private RichTable empTable;

publicvoidsetEmpTable(RichTable empTable){
this.empTable= empTable;
}

public RichTable getEmpTable(){
return empTable;
}

ValueChangeListener for af:inputFile-


/**Method to upload XLS/XLSX file and read data from table
* @param valueChangeEvent
*/
publicvoiduploadFileVCE(ValueChangeEvent valueChangeEvent){
UploadedFile file =(UploadedFile) valueChangeEvent.getNewValue();

try{
//Check if file is XLSX
if(file.getContentType().equalsIgnoreCase("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")||
file.getContentType().equalsIgnoreCase("application/xlsx")){

readNProcessExcelx(file.getInputStream());//for xlsx

}
//Check if file is XLS
elseif(file.getContentType().equalsIgnoreCase("application/vnd.ms-excel")){

if(file.getFilename().toUpperCase().endsWith(".XLS")){
readNProcessExcel(file.getInputStream());//for xls
}

}else{
FacesMessage msg =new FacesMessage("File format not supported.-- Upload XLS or XLSX file");
msg.setSeverity(FacesMessage.SEVERITY_WARN);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
AdfFacesContext.getCurrentInstance().addPartialTarget(empTable);

}catch(IOException e){
// TODO
}
}

Helper Method to execute OperationBinding-


/**Method to get Binding Container of current view port
* @return
*/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

/**
* Generic Method to execute operation
* */
public OperationBinding executeOperation(String operation){
OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
return createParam;

}

Method to read and upload Excel(.XLS) file-


/**Method to read xls file and upload to table.
* @param xls
* @throws IOException
*/
publicvoidreadNProcessExcel(InputStream xls)throws IOException {

CollectionModel cModel =(CollectionModel) empTable.getValue();
JUCtrlHierBinding tableBinding =(JUCtrlHierBinding) cModel.getWrappedData();
DCIteratorBinding iter = tableBinding.getDCIteratorBinding();

//Use HSSFWorkbook for XLS file
HSSFWorkbook WorkBook =null;

int sheetIndex =0;

try{
WorkBook =new HSSFWorkbook(xls);
}catch(IOException e){
System.out.println("Exception : "+ e);
}

HSSFSheet sheet = WorkBook.getSheetAt(sheetIndex);

Integer skipRw =1;
Integer skipcnt =1;
Integer sno =1;

//Iterate over excel rows
for(Row tempRow : sheet){
System.out.println(skipcnt +"--"+ skipRw);
if(skipcnt > skipRw){//skip first n row for labels.
//Create new row in table
executeOperation("CreateInsert").execute();
//Get current row from iterator
oracle.jbo.Row row = iter.getNavigatableRowIterator().getCurrentRow();

int Index =0;
//Iterate over row's columns
for(int column =0; column < tempRow.getPhysicalNumberOfCells(); column++){
Cell MytempCell = tempRow.getCell(column);
if(MytempCell !=null){
Index = MytempCell.getColumnIndex();
}else{
Index++;
}
if(Index ==0){
row.setAttribute("EmployeeId", MytempCell.getNumericCellValue());

}elseif(Index ==1){
row.setAttribute("FirstName", MytempCell.getStringCellValue());

}elseif(Index ==2){
row.setAttribute("LastName", MytempCell.getStringCellValue());

}elseif(Index ==3){
row.setAttribute("Email", MytempCell.getStringCellValue());

}elseif(Index ==4){
row.setAttribute("PhoneNumber", MytempCell.getNumericCellValue());

}elseif(Index ==5){
java.util.Date date = MytempCell.getDateCellValue();
DateFormat dateFormat =new SimpleDateFormat("MM/dd/yyyy");
String date1 = dateFormat.format(date);

try{
date = dateFormat.parse(date1);
}catch(ParseException e){
}
java.sql.Date sqlDate =new java.sql.Date(date.getTime());
oracle.jbo.domain.Date jboDate =new oracle.jbo.domain.Date(sqlDate);
row.setAttribute("HireDate", jboDate);

}elseif(Index ==6){
row.setAttribute("JobId", MytempCell.getStringCellValue());

}elseif(Index ==7){
row.setAttribute("Salary", MytempCell.getNumericCellValue());

}elseif(Index ==8){
row.setAttribute("CommissionPct", MytempCell.getNumericCellValue());

}elseif(Index ==9){
row.setAttribute("ManagerId", MytempCell.getNumericCellValue());

}elseif(Index ==10){
row.setAttribute("DepartmentId", MytempCell.getNumericCellValue());

}
}
sno++;
}
skipcnt++;
}
//Execute table viewObject
executeOperation("Execute").execute();
}

Method to read and upload data from Excel (.XLSX) file-


/**
* Method to read xlsx file and upload to table.
* @param myxls
* @throws IOException
*/
publicvoidreadNProcessExcelx(InputStream xlsx)throws IOException {

CollectionModel cModel =(CollectionModel) empTable.getValue();

JUCtrlHierBinding tableBinding =(JUCtrlHierBinding) cModel.getWrappedData();
//Acess the ADF iterator binding that is used with ADF table binding
DCIteratorBinding iter = tableBinding.getDCIteratorBinding();

//Use XSSFWorkbook for XLS file
XSSFWorkbook WorkBook =null;
int sheetIndex =0;

try{
WorkBook =new XSSFWorkbook(xlsx);
}catch(IOException e){

}
XSSFSheet sheet = WorkBook.getSheetAt(sheetIndex);

Integer skipRw =1;
Integer skipcnt =1;

//Iterate over excel rows
for(Row tempRow : sheet){

if(skipcnt > skipRw){//skip first n row for labels.
//Create new row in table
executeOperation("CreateInsert").execute();
//Get current row from iterator
oracle.jbo.Row row = iter.getNavigatableRowIterator().getCurrentRow();
int Index =0;
//Iterate over row's columns
for(int column =0; column < tempRow.getPhysicalNumberOfCells(); column++){

Cell MytempCell = tempRow.getCell(column);
if(MytempCell !=null){
Index = MytempCell.getColumnIndex();
}else{
Index++;
}
if(Index ==0){
row.setAttribute("EmployeeId", MytempCell.getNumericCellValue());

}elseif(Index ==1){
row.setAttribute("FirstName", MytempCell.getStringCellValue());

}elseif(Index ==2){
row.setAttribute("LastName", MytempCell.getStringCellValue());

}elseif(Index ==3){
row.setAttribute("Email", MytempCell.getStringCellValue());

}elseif(Index ==4){
row.setAttribute("PhoneNumber", MytempCell.getNumericCellValue());

}elseif(Index ==5){
java.util.Date date = MytempCell.getDateCellValue();
DateFormat dateFormat =new SimpleDateFormat("MM/dd/yyyy");
String date1 = dateFormat.format(date);

try{
date = dateFormat.parse(date1);
}catch(ParseException e){
}
java.sql.Date sqlDate =new java.sql.Date(date.getTime());
oracle.jbo.domain.Date jboDate =new oracle.jbo.domain.Date(sqlDate);
row.setAttribute("HireDate", jboDate);

}elseif(Index ==6){
row.setAttribute("JobId", MytempCell.getStringCellValue());

}elseif(Index ==7){
row.setAttribute("Salary", MytempCell.getNumericCellValue());

}elseif(Index ==8){
row.setAttribute("CommissionPct", MytempCell.getNumericCellValue());

}elseif(Index ==9){
row.setAttribute("ManagerId", MytempCell.getNumericCellValue());

}elseif(Index ==10){
row.setAttribute("DepartmentId", MytempCell.getNumericCellValue());

}
}
}
skipcnt++;
}
}

Created two Excel files with Sample data

XLS File-
 XLSX File


Now run and check application


All Done :)
Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

Using external XML file as list resource bundle in ADF Application

$
0
0

Hello All

In this post I am talking about using external XML file as list resource bundle in ADF Application

Using this approach we need not to hard code component's label and messages , all labels and messages will be read from XML file and no need to open application to change any resource , In short we can update resources without compiling and redeploying application

A resource bundle contains a number of named resources, where the data type of the named resources is String. Resource bundles can be either Java classes, property files, or XLIFF (XML Localization Interchange File Format ) files.

Let's implement this, Created model using Departments table of HR Schema


Right click on viewController project and go to properties , Select Resource Bundle, Change default project bundle name to listresourcebundle.view.bundle.Resource and check Automatically Synchronize Bundle checkbox



Now click on Ok button of Project Properties dialog and click yes on the popup dialog to change bundle name


After changing default resource bundle name , Open faces-config.xml file (Under WEB-INF Folder)

Go to Application tab and add a line in Resource Bundle Section, In Base Name put the whole bundle name and in Var Name use any string that will be further used to fetch resource values 


Create a page in viewController project and drop Departments viewObject as af:table on page and to create Resource Bundle Java class select any column of af:table and Select Text Resource in Header Text property


You can see a Resource.java class in created in viewController project


Now create List Resource XML file in this format


<?xml version="1.0" encoding="windows-1252" ?>
<bundle>
<label>
<key>RES.1</key>
<value>Department Id</value>
</label>
<label>
<key>RES.2</key>
<value>Department Name</value>
</label>
<label>
<key>RES.3</key>
<value>Manager Id</value>
</label>
<label>
<key>RES.4</key>
<value>Location Id</value>
</label>
</bundle>

Saved this file as Resource_En.xml in D drive of my system, Now see the code of Resource.java file to process and read resource values from this XML file
The java.util.ListResourceBundle class manages resources in a name and value array. Each java.util.ListResourceBundle class is contained within a Java class file


package listresourcebundle.view.bundle;

importjava.io.File;

importjava.util.ListResourceBundle;

importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.parsers.DocumentBuilderFactory;

importorg.w3c.dom.Document;
importorg.w3c.dom.Element;
importorg.w3c.dom.Node;
importorg.w3c.dom.NodeList;

publicclassResourceextends ListResourceBundle {

//Path to XML Resource File
private String Res_path ="D://Resource_En.xml";

//Initialize an Object Array to hold label and key values
publicResource(){
for(int i =0; i <5000; i++){
contents[i][0]="";
contents[i][1]="";
}
}

privatestaticfinal Object[][] contents =new Object[5000][2];

/**Method to process XML file and get key and value of resource and put that in array
* @return
*/
public Object[][]getContents(){
try{

File file =new File(Res_path);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("label");

for(int temp =0; temp < nList.getLength(); temp++){
Node nNode = nList.item(temp);
if(nNode.getNodeType()== Node.ELEMENT_NODE){

Element eElement =(Element) nNode;
contents[temp][0]= getTagValue("key", eElement);
contents[temp][1]= getTagValue("value", eElement);
}
}
}catch(Exception e){
e.printStackTrace();
}
return contents;
}

privatestatic String getTagValue(String sTag, Element eElement){
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = nlList.item(0);
return nValue.getNodeValue();
}
}

Now configuration part is done and to apply resources in page , Select column and go to header text property and from expression builder select var name from Faces' Resource Bundles and put respective key in single quote like this


Repeat this step for all columns


Now run and check application, All labels are fetched from XML file


Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

Export ViewObject data to PDF file using Apache PDFBox

$
0
0
Hello All
Hope you all are doing well :)

This post is about exporting view object data in a pdf file directly from af:table , export to excel is built in feature of ADF but exporting data in PDF requires little bit of extra effort
So here for this requirement I am using Apache PDFBox library , previously I have posted about using this API to create PDF file from text data
I know many of you will not visit that link ;) So a quick overview



What is Apache PDFBox


The Apache PDFBox library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command line utilities.

Let's implement this

  • Create a Fusion Web Application and prepare model using Departments table of HR Schema


  • Add PDFBox jar to view controller project


  • Drop Departments view object as table on page and add two buttons to Export All Rows and Export Selected Row


  • Now see the managed bean code that exports viewObject data to PDF file , Idea is to add viewObject data in a multi dimensional array and then iterate over array to draw a table in pdf Go through the comments to understand code part

Packages and Helper method-


importjava.io.IOException;

importjavax.faces.event.ActionEvent;

importoracle.adf.model.BindingContext;
importoracle.adf.model.binding.DCIteratorBinding;

importoracle.binding.BindingContainer;

importoracle.jbo.Row;
importoracle.jbo.RowSetIterator;
importoracle.jbo.ViewObject;

importorg.apache.pdfbox.exceptions.COSVisitorException;
importorg.apache.pdfbox.pdmodel.PDDocument;
importorg.apache.pdfbox.pdmodel.PDPage;
importorg.apache.pdfbox.pdmodel.edit.PDPageContentStream;
importorg.apache.pdfbox.pdmodel.font.PDType1Font;

/**
* Generic Method to call operation binding**/
public BindingContainer getBindingsCont(){
return BindingContext.getCurrent().getCurrentBindingsEntry();
}

Method to Export All Rows of ViewObject to PDF-


/**Method to export all rows of viewObject to PDF
* @param actionEvent
* @throws IOException
*/
publicvoidexportAllRowsToPdfAction(ActionEvent actionEvent)throws IOException {
//Create new PDF Document
PDDocument document =new PDDocument();
PDPage page =new PDPage();
document.addPage(page);
PDPageContentStream contentStream =new PDPageContentStream(document, page);

//Get the iterator of af:table on page
DCIteratorBinding iter =(DCIteratorBinding) getBindingsCont().get("DepartmentsVO1Iterator");
//No of total rows+ 1 for array sizing
int totRows =((int) iter.getEstimatedRowCount())+1;
//Here 4 is the number of columns
String[][] content =new String[totRows][4];

int column =4;
//Set header text in first row of table in PDF
content[0][0]="Department Id";
content[0][1]="Department Name";
content[0][2]="Manager Id";
content[0][3]="Location Id";

//Get viewObject from iterator and Iterate over it to add all data in array
ViewObject vo = iter.getViewObject();
RowSetIterator rsi = vo.createRowSetIterator(null);
int i =1;
while(rsi.hasNext()){
Row nextRow = rsi.next();

for(int j =0; j < column; j++){
System.out.println(i +""+ j);
if(j ==0&& nextRow.getAttribute("DepartmentId")!=null){
content[i][j]= nextRow.getAttribute("DepartmentId").toString();
}
if(j ==1&& nextRow.getAttribute("DepartmentName")!=null){
content[i][j]= nextRow.getAttribute("DepartmentName").toString();
}
if(j ==2&& nextRow.getAttribute("ManagerId")!=null){
content[i][j]= nextRow.getAttribute("ManagerId").toString();
}
if(j ==3&& nextRow.getAttribute("LocationId")!=null){
content[i][j]= nextRow.getAttribute("LocationId").toString();
}
}
i++;
}
rsi.closeRowSetIterator();
//Write data to PDF
writeToPdf(contentStream, content);

contentStream.close();
try{
//Save generated pdf document in a drive
document.save("D:\\Departments.pdf");
}catch(COSVisitorException e){
}
}

Method to Export Selected Row of ViewObject to PDF-


/**Method to export selected row to PDF
* @param actionEvent
* @throws IOException
*/
publicvoidexportCurRowToPdfAction(ActionEvent actionEvent)throws IOException {
//Create new PDF Document
PDDocument document =new PDDocument();
PDPage page =new PDPage();
document.addPage(page);
PDPageContentStream contentStream =new PDPageContentStream(document, page);

//Get the iterator of af:table on page
DCIteratorBinding iter =(DCIteratorBinding) getBindingsCont().get("DepartmentsVO1Iterator");
//Define the array for two rows only
String[][] data =new String[2][4];

//Set header text in first row of table in PDF
data[0][0]="Department Id";
data[0][1]="Department Name";
data[0][2]="Manager Id";
data[0][3]="Location Id";

//Get current row of Iterator and insert data in array
Row row = iter.getCurrentRow();

if(row.getAttribute("DepartmentId")!=null){
data[1][0]= row.getAttribute("DepartmentId").toString();
}
if(row.getAttribute("DepartmentName")!=null){
data[1][1]= row.getAttribute("DepartmentName").toString();
}
if(row.getAttribute("ManagerId")!=null){
data[1][2]= row.getAttribute("ManagerId").toString();
}
if(row.getAttribute("LocationId")!=null){
data[1][3]= row.getAttribute("LocationId").toString();
}
//Write data to PDF
writeToPdf(contentStream, data);

contentStream.close();
try{
//Save generated pdf document in a drive
document.save("D:\\Departments.pdf");
}catch(COSVisitorException e){
}
}

Method to draw table in PDF -


/**Method to draw table on pdf using array of data
* @param page
* @param contentStream
* @param y
* @param margin
* @param content
* @throws IOException
*/
publicstaticvoidwriteToPdf(PDPageContentStream contentStream, String[][] data)throws IOException {
finalint rows = data.length;
finalint cols = data[0].length;

//Height for each row
finalfloat rowHeight =20f;
//Width of table drawn
finalfloat tableWidth =550;

//Total table height
finalfloat tableHeight = rowHeight * rows;
//Width of each column
finalfloat colWidth = tableWidth /(float) cols;
finalfloat cellMargin =5f;
//Margin from left
float margin =20;
//Margin from top (Increase value to decrease margin)
float y =750;
//draw the rows
float anoy = y;

for(int i =0; i <= rows; i++){
contentStream.drawLine(margin, anoy, margin + tableWidth, anoy);
anoy -= rowHeight;
}

//Draw the columns
float anox = margin;
for(int i =0; i <= cols; i++){
contentStream.drawLine(anox, y, anox, y - tableHeight);
anox += colWidth;
}

//Setting for font and size
contentStream.setFont(PDType1Font.COURIER_BOLD,10);

float textx = margin + cellMargin;
float texty = y -15;
for(int i =0; i < data.length; i++){
for(int j =0; j < data[i].length; j++){
if(data[i][j]!=null){
String text = data[i][j];

contentStream.beginText();
contentStream.moveTextPositionByAmount(textx, texty);
contentStream.drawString(text);
contentStream.endText();
textx += colWidth;
}
}
texty -= rowHeight;
textx = margin + cellMargin;
}
}

All Done :) Now run and check application



Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

Change live application language/resource in Oracle ADF, Change XML Resource file at runtime

$
0
0

Hello All

I have posted about using external XML file as List resource bundle earlier , the aim of resource file is to read application static text from some source so that we can change that without compiling and redeploying application

Next requirement is to change application language , sometimes we need support multiple langauge in ADF application and it requires change in all static text so for this I am going to use separate XML resource file for different language and in this post I'll show that how to update resource file in a live running application



Here I am using same sample application and after adding resource for English language , added a list on page to select language


created a value change listener in managed bean for this list

<af:selectOneChoicelabel="Select Language"id="soc1"autoSubmit="true"
valueChangeListener="#{ResourceManagerBean.changeLanguageVCE}"
contentStyle="width:100px;">
<af:selectItemlabel="English"value="English"id="si1"/>
<af:selectItemlabel="French"value="French"id="si2"/>
<af:selectItemlabel="Dutch"value="Dutch"id="si3"/>
</af:selectOneChoice>

Here ResourceManagerBean is a session scope bean , Initialized a session scope variable that holds the path of resource file and on value change listener of choice list I'll change path of resource file on basis of selected language

In this demo I am using 3 XML resource files for 3 different languages (English, French and Dutch)
User will select any language from the list and resource values will be read from respective resource file after a page refresh and clearing resource cache


Managed Bean Code-



importjava.io.Serializable;

importjava.util.ResourceBundle;

importjavax.faces.application.ViewHandler;
importjavax.faces.component.UIViewRoot;
importjavax.faces.context.FacesContext;
importjavax.faces.event.ValueChangeEvent;

importjavax.servlet.http.HttpSession;

publicclassResourceManagerBeanimplements Serializable {

//String variable to hold locale
private String appLocale;

publicvoidsetAppLocale(String appLocale){
this.appLocale= appLocale;
}

public String getAppLocale(){
return appLocale;
}
publicResourceManagerBean(){
//Take a session variable to put resource file path
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =(HttpSession) fc.getExternalContext().getSession(true);
session.setAttribute("resName","D://Resource_En.xml");
}

/**Method to forcefully refresh page
*/
protectedvoidrefreshPage(){

FacesContext fctx = FacesContext.getCurrentInstance();
String page = fctx.getViewRoot().getViewId();
ViewHandler ViewH = fctx.getApplication().getViewHandler();
UIViewRoot UIV = ViewH.createView(fctx, page);
UIV.setViewId(page);
fctx.setViewRoot(UIV);

}

/**Method to change app language by changing locale and XML resource file of application
* @param vce
*/
publicvoidchangeLanguageVCE(ValueChangeEvent vce){
if(vce.getNewValue()!=null){
if("English".equalsIgnoreCase(vce.getNewValue().toString())){
//Change application locale to English
setAppLocale("en");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =(HttpSession) fc.getExternalContext().getSession(true);
session.setAttribute("resName","D://Resource_En.xml");

}elseif("French".equalsIgnoreCase(vce.getNewValue().toString())){
//Change application locale to French
setAppLocale("fr");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =(HttpSession) fc.getExternalContext().getSession(true);
session.setAttribute("resName","D://Resource_fr.xml");

}elseif("Dutch".equalsIgnoreCase(vce.getNewValue().toString())){
//Change application locale to Dutch (Netherland)
setAppLocale("nl");
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session =(HttpSession) fc.getExternalContext().getSession(true);
session.setAttribute("resName","D://Resource_nl.xml");

}
//Clear Resource Bundle cache to load Resource.java file again
ResourceBundle bundle = ResourceBundle.getBundle("listresourcebundle.view.bundle.Resource");
bundle.clearCache();

//Refresh Page after changing resource file
refreshPage();
}
}
}

Small change in Resource.java file , Now it reads Resource file path from session scope variable that is initialized in managed bean

Resource.java file-



importjava.io.File;

importjava.util.ListResourceBundle;

importjavax.el.ELContext;
importjavax.el.ExpressionFactory;
importjavax.el.ValueExpression;

importjavax.faces.application.Application;
importjavax.faces.context.FacesContext;

importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.parsers.DocumentBuilderFactory;

importorg.w3c.dom.Document;
importorg.w3c.dom.Element;
importorg.w3c.dom.Node;
importorg.w3c.dom.NodeList;

publicclassResourceextends ListResourceBundle {

//Path to XML Resource File
private String Res_path =
    resolvEl("#{sessionScope.resName}");

//Initialize an Object Array to hold label and key values
publicResource(){
for(int i =0; i <5000; i++){
contents[i][0]="";
contents[i][1]="";
}
}

privatestaticfinal Object[][] contents =new Object[5000][2];

/**Method to process XML file and get key and value of resource and put that in array
* @return
*/
public Object[][]getContents(){
try{
System.out.println("Resource path is- "+ Res_path);
File file =new File(Res_path);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("label");

for(int temp =0; temp < nList.getLength(); temp++){
Node nNode = nList.item(temp);
if(nNode.getNodeType()== Node.ELEMENT_NODE){

Element eElement =(Element) nNode;
contents[temp][0]= getTagValue("key", eElement);
contents[temp][1]= getTagValue("value", eElement);
}
}
}catch(Exception e){
e.printStackTrace();
}
return contents;
}

privatestatic String getTagValue(String sTag, Element eElement){
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = nlList.item(0);
return nValue.getNodeValue();
}

public String resolvEl(String data){
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = fc.getELContext();
ValueExpression valueExp = elFactory.createValueExpression(elContext, data, Object.class);
Object expVal = valueExp.getValue(elContext);
String Message ="D:\\Resource_En.xml";
if(expVal !=null){
Message = expVal.toString();
}

return Message;
}
}

Next step is to refer page locale from managed bean , Open page and in structure window select f:view tag (container tag for all components used on page)


 Refer locale property to bean variable


All Done :) Run and Check Application



Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

Get Facebook profile detail using restfb Graph API in Java & ADF

$
0
0

Facebook is most popular social networking sites now a days and influencing our life in all aspect. Facebook gives us option to use it's Graph API to access it's features programmatically, The Graph API is primary way to read and write to facebook social graph using Access Tokens

In this post I am talking about how to access Facebook profile detail using restfb graph API . So First we need to know about Acsess Tokens


What docs says- 


When someone connects with an app using Facebook Login, the app will be able to obtain an access token which provides temporary, secure access to Facebook APIs.

An access token is an opaque string that identifies a user, app, or Page and can be used by the app to make graph API calls
The token includes information about when the token will expire and which app generated the token. Because of privacy checks, the majority of API calls on Facebook need to include an access token.


restfb Graph API-


RestFB is a simple and flexible Facebook Graph API client written in Java.It is open source software and simplifies code for you , It provides default implementation for all components . We need to access it's methods and customized it

Let's start with getting access token for our application
Open Graph API Explorer , You'll see a input text there to enter token



As we don't have any token so we need to generate one , click on Get token - Get User Access Token, It'll open a dialog asking permissions
See here I have requested for following permissions to get user profile


Click on Get Access Token button and allow facebook to give these permissions and continue


It'll generate a temporary Access Token, that'll be used to connect facebook


Now created a fusion web application , added two input text to enter AccessToken and Id and a button to submit data


Download restfb jar file and add it to view controller project


Created component binding for both input text and output text (to show response) in managed bean, See managed bean code

Packages Used-


importcom.restfb.DefaultFacebookClient;
importcom.restfb.FacebookClient;
importcom.restfb.types.User;

importjavax.faces.event.ActionEvent;

importoracle.adf.view.rich.component.rich.input.RichInputText;
importoracle.adf.view.rich.component.rich.output.RichOutputFormatted;

Component Binding to get and set page data-


//Component Binding for ID field
private RichInputText idBind;
//Component binding for AccessToken field
private RichInputText fbTokenBind;
//Component Binding for response output text
private RichOutputFormatted reponseBind;


publicvoidsetIdBind(RichInputText idBind){
this.idBind= idBind;
}

public RichInputText getIdBind(){
return idBind;
}

publicvoidsetFbTokenBind(RichInputText fbTokenBind){
this.fbTokenBind= fbTokenBind;
}

public RichInputText getFbTokenBind(){
return fbTokenBind;
}

publicvoidsetReponseBind(RichOutputFormatted reponseBind){
this.reponseBind= reponseBind;
}

public RichOutputFormatted getReponseBind(){
return reponseBind;
}

Method to connect Facebook and access profile detail-


/**Method to connect facebook and access profile details
* @param actionEvent
*/
publicvoidfetchInfo(ActionEvent actionEvent){
//Get Access Token
String accessToken = fbTokenBind.getValue().toString();
//Get Id
String id = idBind.getValue().toString();
//Initiate facebook client for accessToken
fbClient =new DefaultFacebookClient(accessToken);
//Get User
User user = fbClient.fetchObject("me", User.class);
//Get Profile details (We can get only permissible object) using User Object
reponseBind.setValue("Name- "+ user.getName()+"<br>Gender- "+ user.getGender()+"<br>DOB- "+
user.getBirthday()+"<br>Bio- "+ user.getBio()+"<br>Status- "+
user.getRelationshipStatus()+"<br>Religion- "+ user.getReligion()+"<br>Websites- "+
user.getWebsite()+"<br> Hometown- "+ user.getHometownName());

}


Now run application and enter UserId and AccessToken that we generated earlier, Click on Fetch button and profile details is on page :)



Sample ADF Application (Jdeveloper 12.1.3)- Download
Cheers :) Happy Learning

Post Status on Facebook Timeline using restfb Graph API in ADF & Java

$
0
0
Hello All

Previous post was about generating temporary access token and using it get Facebook profile detail usinf restfb Graph API , Go through previous post before this as graph api basics are described in that post

Now In this post I am talking about posting facebook status update so for this I am extending same sample application

There are two type of facebook status , first is simple text status and second one is with text with some website url. 

So Added two new af:inputText (for text status and url) and a button to post status on faceook timeline


Next step is to get access token with a new permission publish_actions to post to facebook


Allow Graph API to post on facebook for you


See Managed Bean Code

Component Bindings in Managed Bean-



//Component binding for status inputText
private RichInputText statusBind;
//Component binding for website url inputText
private RichInputText linkBind;

publicvoidsetStatusBind(RichInputText statusBind){
this.statusBind= statusBind;
}

public RichInputText getStatusBind(){
return statusBind;
}

publicvoidsetLinkBind(RichInputText linkBind){
this.linkBind= linkBind;
}

public RichInputText getLinkBind(){
return linkBind;
}

Method to post status on Facebook-


/**Method to post facebook status on your timeline
* @param actionEvent
*/
publicvoidpostFacebookStatusAction(ActionEvent actionEvent){
//Get Access Token
String accessToken = fbTokenBind.getValue().toString();
//Get Id
String id = idBind.getValue().toString();

System.out.println(accessToken +""+ id);
//Initiate facebook client for accessToken
fbClient =new DefaultFacebookClient(accessToken);
//If status is with some url
if(statusBind.getValue()!=null&& linkBind.getValue()!=null){
fbClient.publish(id +"/feed", FacebookType.class, Parameter.with("message", statusBind.getValue()),
Parameter.with("link", linkBind.getValue()));
}
//If it is simple text status
elseif(statusBind.getValue()!=null){
fbClient.publish(id +"/feed", FacebookType.class, Parameter.with("message", statusBind.getValue()));
}
}

Now run application and pust status without url at first



Click on post button and check in Facebook timeline, and you can see that status shows that it is posted using Graph Api Explorer


Now check second case - Facebook status with a web url



On timeline status is posted with weblink preview



Sample ADF Application (Jdeveloper 12.1.3) - Download

Cheers :) Happy Learning

Post to Facebook Page Wall using restfb Graph API in ADF & Java

$
0
0

This is next post working with Facebook Graph API series, Previously I have posted about gettting access token and use it to get Facebook Profile detail and Posting status on your Facebook Timeline using restfb Facebook Graph API

Go through previous posts for better understanding of this blog post

Now this post is about Facebook Pages , Facebook Page is a way to connect people to promote your brand, website, business, cause etc. This post uses no new code , Posting on pages is same as updating status on Facebook Timeline .

The only difference is of access tokens, For Timeline status posting we use User Aceess Token but for managing pages we need to use Page Access Token .

Open Grpah API Explorer and Click on Get Page Access Token



When we ask for Page Access Token, Graph API asks permission to manage pages


Next step is to click on Get User Access Token for some more permissions


As our requirement is to post on pages so for that we need to grant permission for this- publish_pages


Grant permission to Graph API to publish as pages


After this a token is generatd that is user access token with permissions of manageing and publishing as pages
Change in GET Request and write me/accountsto get details of all pages managed by you



Here you can see different access token and id for each page Now use access token and id of any page to post status


Check after clicking on Post button and see on Page


If you want to post on your page wall under visitors post using your name then use User Acees Token and Page Id (ID of page on that you want to post) to post 

Cheers :) Happy Learning

Generate permanent Facebook Page Access Token to access Graph API

$
0
0

Hello All,
Hope you are doing well

Earlier I have posted about using facebook graph api to get profile information, post status on facebook timeline and post as facebook page.

To Access Facebook graph API we need to use Access Token and each access token has it's expiry time (temporary access tokens) but to build an application we need a permanent access token so that our app doesn't stop working after a time and it is not very easy to get a permanent access token , there are some steps you need to follow to get one



Create a simple Website Facebook App (If you don't have one)


Go to Register and Configure an App and learn how to create a app then go to All Apps and add a new app

Generate Short lived Access Token


Select the app from application dropdown list


Click on Get Token --> Get User Access Token , In select permissions popup check manage_pages and click Get Access Token
Now you can see short lived access token appears in Access Token field


Generate Long lived Access Token


For this we need AppId and App Secret, Go to My Apps page and Open App and copy AppId and App Secret


Now make a GET request from your browser to get long lived access token

https://graph.facebook.com/v2.8/oauth/access_token?grant_type=fb_exchange_token&client_id=app_id&client_secret=app_secret&fb_exchange_token=short_lived_token

it'll return a long lived access token, 



you can check it's expiration time in Access Token Debugger 

Generate Permanent Access Token


Make a GET request to 

https://graph.facebook.com/v2.8/me/accounts?access_token=long_lived_access_token

It'll return a array of data[] that has permanent access token for all pages that you manage

Cheers :) Happy Learning

Post to twitter using Twitter4J API in Oracle ADF and Java

$
0
0

Hello All

In this post I am talking about how to post a tweet on your twitter timeline using Twitter4J Java API in your Oracle ADF Application
Using this API makes the process very simple , For accessing twitter we need Twitter API keys, It is called Consumer Key and Access Token

For this you need a twitter account and then follow these steps




Create a Twitter App


Go to Twitter Apps , Click on Create New App


Fill basic details as Application Name, Description and Website


Go to Permissions tab of app and allow access to Read, Write and Access direct messages



Now go to Keys and Access Tokens tab of app and note down Consumer key and Consumer Secret 


and there is a button to create Access Token  too (We will need it later)



Create Application to Tweet using Twitter4J API


Create a Fusion Web Application and attach twitter4j-core-4.0.4.jar to viewController project and create a page with one input text and a button

<af:panelFormLayoutid="pfl1">
<af:inputTextlabel="Your Text"id="it1"rows="3"contentStyle="width:350px;font-weight:bold;"
labelStyle="font-weight:bold;font-size:medium;color:#167bb9;"
binding="#{viewScope.TweetUsingJavaAPIBean.tweetTextBind}"/>
<af:linkid="l1"icon="#{resource['images:tweet-button-2015.png']}"
actionListener="#{viewScope.TweetUsingJavaAPIBean.postTweetAction}"/>
</af:panelFormLayout>

looks like this on page


Now see managed bean code that posts tweet

importjavax.faces.application.FacesMessage;
importjavax.faces.context.FacesContext;
importjavax.faces.event.ActionEvent;

importoracle.adf.view.rich.component.rich.input.RichInputText;

importtwitter4j.Twitter;
importtwitter4j.TwitterException;
importtwitter4j.TwitterFactory;

importtwitter4j.auth.AccessToken;

publicclassTweetUsingJavaAPIBean{

//Component Binding of input text
private RichInputText tweetTextBind;

publicvoidsetTweetTextBind(RichInputText tweetTextBind){
this.tweetTextBind= tweetTextBind;
}

public RichInputText getTweetTextBind(){
return tweetTextBind;
}

publicTweetUsingJavaAPIBean(){
}

// Put your app consumer key, secret and access token , secret here
privatestaticfinal String consumerKey ="K************X";
privatestaticfinal String consumerSecret ="u******************************RrD";
privatestaticfinal String token ="4876****************************************7Vlg";
privatestaticfinal String tokenSecret ="H2u***********************************y9";

/**Method to post tweet using Twitter4J API
* @param actionEvent
*/
publicvoidpostTweetAction(ActionEvent actionEvent){
if(tweetTextBind.getValue()!=null){
try{
Twitter twitter =new TwitterFactory().getInstance();

twitter.setOAuthConsumer(consumerKey, consumerSecret);
AccessToken accessToken =new AccessToken(token, tokenSecret);

twitter.setOAuthAccessToken(accessToken);

twitter.updateStatus(tweetTextBind.getValue().toString());


}catch(TwitterException te){
te.printStackTrace();
}
}else{
FacesMessage errMsg =new FacesMessage("Tweet Can't be empty");
errMsg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(tweetTextBind.getClientId(), errMsg);
}
}
}

Now run and check application


 On Twitter Timeline


Sample ADF Application- Download

Cheers :) Happy Learning

Send Direct Message to followers using Twiter4J API in Oracle ADF and Java

$
0
0

My previous post was about tweeting using Twitter4J API from Oracle ADF Application . Twitter4J is a Java API that simplifies accessting twitter features in our application easily

In this I am going to show how to send DM (Direct Message) to anyone using their twitter handle and for this we need to use same consumer key, secret and access token, secret (How to access all these is described in previous post)



So Now we have all the keys and secrets now I have added one more input text in same application to input user's twitter handle and a button to send message


and believe me this is really simple , see the code in managed bean to send DM

importjavax.faces.application.FacesMessage;
importjavax.faces.context.FacesContext;
importjavax.faces.event.ActionEvent;

importoracle.adf.view.rich.component.rich.input.RichInputText;

importtwitter4j.Twitter;
importtwitter4j.TwitterException;
importtwitter4j.TwitterFactory;

importtwitter4j.auth.AccessToken;

publicclassTweetUsingJavaAPIBean{

//Component Binding of input text
private RichInputText tweetTextBind;
//Component Binding of twitter handle input text
private RichInputText twitterHandleBind;

publicvoidsetTweetTextBind(RichInputText tweetTextBind){
this.tweetTextBind= tweetTextBind;
}

public RichInputText getTweetTextBind(){
return tweetTextBind;
}

publicTweetUsingJavaAPIBean(){
}

//Put your app consumer key, secret and access token , secret here
privatestaticfinal String consumerKey ="K*******************X";
privatestaticfinal String consumerSecret ="u**************************************nRrD";
privatestaticfinal String token ="4*********************************************************7Vlg";
privatestaticfinal String tokenSecret ="H**************************************dy9";



/**Send direct message to your followers using their twitter handle
* @param actionEvent
*/
publicvoidsendDMTwitterAction(ActionEvent actionEvent){
if(twitterHandleBind.getValue()!=null&& tweetTextBind.getValue()!=null){
Twitter twitter =new TwitterFactory().getInstance();
twitter.setOAuthConsumer(consumerKey, consumerSecret);
AccessToken accessToken =new AccessToken(token, tokenSecret);
twitter.setOAuthAccessToken(accessToken);
try{
twitter.sendDirectMessage(twitterHandleBind.getValue().toString(), tweetTextBind.getValue().toString());
}catch(TwitterException e){
e.printStackTrace();
}
}else{
FacesMessage errMsg =new FacesMessage("Please Enter Twitter Handle and Text Message");
errMsg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, errMsg);
}
}

publicvoidsetTwitterHandleBind(RichInputText twitterHandleBind){
this.twitterHandleBind= twitterHandleBind;
}

public RichInputText getTwitterHandleBind(){
return twitterHandleBind;
}
}

Now just run and check application


and in Twitter DM Box we can check it



Cheers :) Happy Learning 

  By the way My Twitter Handle is - ;)

Fetch Tweets of a User using Twitter4J API and show in af:table in ADF & Java

$
0
0

In the previous blogs we learned about posting tweets on twitter timeline using Twitter4J API and sending direct meaages to followers using same API

This post is next in the series and about fetching a user tweets and showing in ADF Table , For this requirement we need to use same Consumer Key+ Secret and Access Token+Secret (Refer previous posts for this)

And In same way after authentication we can fetch a user tweets by using it's twitter handle. So for this requirement I have added a button to fetch tweets and a POJO based table to show fetched tweets in page

See the code to fetch tweets using user's twitter handle and it's retweets and favourites count, We can get tweets by passing page number as parameter and it returns a list of tweets




//ArrayList to poplate data in af:table
List<TweetList> tweets =new ArrayList();

publicvoidsetTweets(List<TweetList> tweets){
this.tweets= tweets;
}

public List<TweetList>getTweets(){
return tweets;
}


/**Send direct message to your followers using their twitter handle
* @param actionEvent
*/
publicvoidretrieveTweetsFromTimeline(ActionEvent actionEvent){
if(twitterHandleBind.getValue()!=null){
try{
//Get Twitter Factory instance
Twitter twitter =new TwitterFactory().getInstance();
//Authorize app using consumer key and secret and Access token,Secret
twitter.setOAuthConsumer(consumerKey, consumerSecret);
AccessToken accessToken =new AccessToken(token, tokenSecret);
twitter.setOAuthAccessToken(accessToken);

//First param of Paging() is the page number, and in same way we can get tweets for all pages
Paging paging =new Paging(1,100);
//Put all tweets in a list
List<Status> statuses;

statuses = twitter.getUserTimeline(twitterHandleBind.getValue().toString(), paging);
//Iterate over list to get tweet text and other properties and add to list
for(Status status : statuses){
tweets.add(new TweetList(status.getText(), status.getRetweetCount(), status.getFavoriteCount()));

}
}catch(TwitterException e){
}
}else{
FacesMessage errMsg =new FacesMessage("Please Enter Twitter Handle to fetch tweets");
errMsg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, errMsg);
}
}

Now to show these tweets in af:table we need a POJO class to capture all columns of af:table
For detailed post - Populate af:table programmatically from managead bean using POJO

publicclassTweetList{

publicTweetList(String tweetText,int rtCnt,int fvrtCnt){
super();
this.tweetText= tweetText;
this.rtCnt= rtCnt;
this.fvrtCnt= fvrtCnt;
}

//Tweet
private String tweetText;
//Retweet Count
privateint rtCnt;
//Favourite Count
privateint fvrtCnt;

publicvoidsetRtCnt(int rtCnt){
this.rtCnt= rtCnt;
}

publicintgetRtCnt(){
return rtCnt;
}

publicvoidsetFvrtCnt(int fvrtCnt){
this.fvrtCnt= fvrtCnt;
}

publicintgetFvrtCnt(){
return fvrtCnt;
}


publicvoidsetTweetText(String tweetText){
this.tweetText= tweetText;
}

public String getTweetText(){
return tweetText;
}
}

All done now run and check application


Sample ADF Application- Download
Cheers :) Happy Learning

ADF Basics: Tip for not showing record in dependent lov

$
0
0

Hello All

Recently I have seen a question on OTN forum - Question on cascading LOV

It was about cascading lovs in ADF
Suppose we have 2 dependent LOVs and requirement is that 2nd lov should not show any data until first one is selected , this is very simple and common use case but for beginners it's a tedious task

So I thought to write it here to help others



Let's see how to implement this

Here I am using Employees and Departments viewObject to create LOVs and Employees lov is dependent on Departments . I have a dual VO where I have to apply these LOVs

Hope you all know how to create a LOV :)
Created two LOVs on EmpId and DeptId




Now to make Employees Lov dependent on Departments, created a view Cirteria in EmployeesVO to filter Employees list using selected DepartmentId


and then pass bind variable value from view accessor to filter employees list using selected Department Id



Now run and check application module, You can see by default all Employees appears if you don't select a Department

Now requirement is to not show any employee until a department is selected, To do this go to Employees ViewObject and Open view criteria and select viewCritieriaItem tag in xml source and change this property


Set GenerateIsNullClauseForBindVars to false to check that if there is null value in bind var then data will not be filtered


After changing XML source is this

<ViewCriteriaItem
Name="DepartmentId"
ViewAttribute="DepartmentId"
Operator="="
Conjunction="AND"
Value=":BindDeptId"
IsBindVarValue="true"
Required="Optional"
GenerateIsNullClauseForBindVars="false"/>

Now run and check application module again


Cheers :) Happy Learning

OTN Question: Not able to see last record in af:table when using icons (May be a bug)

$
0
0

Hello All

This post is about a problem that occurs sometimes in af:table when we use icon in any column, I am not sure that it is a bug or not but sometimes table is not fully stretched on first load and last row doesn't appear properly on page but after refreshing page again problem is solved.



Recently I have seen a question on OTN forum about this and sharing that information here so that if anyone is facing same problem then look into it



So if you have to show specific number of rows and if you are facing this problem then set autoHeightRows property to -1 and set height in inlineStyle property of af:table

Check OTN Thread - Missing Last Record in ADF Table

Cheers :) Happy Learning

Uploading and downloading files from database (BLOB) in Oracle ADF (12.1.3)

$
0
0
Hello all

This post is about a very simple requirement -file handling (uploading and downloading various types of file) in ADF and it is needed very often to store file in absolute server path (actual path) and download from there and I have posted about that previously

Uploading and downloading files from absolute server path

Now this post is about uploading and saving file in database BLOB column and downloading from there
See step by step implementation -



  • Created a simple table in HR schema to store uploaded file name ,path ,content type and file in BLOB column
  • See sql script for this table-

    CREATETABLE FILE_UPD_DWN  
    (
    FILE_NAME VARCHAR2(50 BYTE),
    PATH VARCHAR2(100 BYTE),
    CONTENT_TYPE VARCHAR2(500 BYTE),
    IMAGE_FILE BLOB
    )


  • Then prepare model using this table and drop on page as af:table, and an af:inputFile component to select and upload file 

  • Then create a ValueChangeListener on inputFile component to create new row in table and upload file to database

  • Packages Used


    importjava.io.BufferedInputStream;
    importjava.io.IOException;
    importjava.io.InputStream;
    importjava.io.OutputStream;

    importjava.sql.SQLException;

    importjava.util.List;

    importjavax.faces.context.FacesContext;
    importjavax.faces.event.ValueChangeEvent;

    importoracle.adf.model.BindingContext;
    importoracle.adf.model.binding.DCIteratorBinding;
    importoracle.adf.view.rich.util.ResetUtils;

    importoracle.binding.BindingContainer;
    importoracle.binding.OperationBinding;

    importoracle.jbo.ViewObject;
    importoracle.jbo.domain.BlobDomain;

    importorg.apache.myfaces.trinidad.model.UploadedFile;

    importupddwd.model.view.FileUpdDwnVORowImpl;


    Bean method to upload file in database


    /**Method to upload file in Database
    * @return
    */
    public String UploadFileActionToDB(UploadedFile file){
    UploadedFile myfile = file;
    if(myfile !=null){
    //Get current row of viewObject using iterator
    DCIteratorBinding imageIter =(DCIteratorBinding) getBindingsCont().get("FileUpdDwn1Iterator");
    ViewObject vo = imageIter.getViewObject();
    FileUpdDwnVORowImpl curRow =(FileUpdDwnVORowImpl) vo.getCurrentRow();

    try{
    //Save image in Blob column in database
    curRow.setImageFile(createBlobDomain(myfile));

    }catch(Exception ex){
    System.out.println("Exception-"+ ex);
    }

    }
    returnnull;
    }

    /**Method to create blobdomain for uploaded file
    * */
    private BlobDomain createBlobDomain(UploadedFile file){
    InputStream in =null;
    BlobDomain blobDomain =null;
    OutputStream out =null;

    try{
    in = file.getInputStream();

    blobDomain =new BlobDomain();
    out = blobDomain.getBinaryOutputStream();
    byte[] buffer =newbyte[8192];
    int bytesRead =0;

    while((bytesRead = in.read(buffer,0,8192))!=-1){
    out.write(buffer,0, bytesRead);
    }

    in.close();

    }catch(IOException e){
    e.printStackTrace();
    }catch(SQLException e){
    e.fillInStackTrace();
    }

    return blobDomain;
    }


    AMImpl method to insert record in DB table for new file


    /**Method to set file path and name
    * @param name
    * @param path
    */
    publicvoidsetFileData(String name, String path, String contTyp){
    ViewObject fileVo =this.getFileUpdDwn1();
    Row newRow = fileVo.createRow();
    newRow.setAttribute("FileName", name);
    newRow.setAttribute("Path", path);
    newRow.setAttribute("ContentType", contTyp);
    fileVo.insertRow(newRow);
    }

    AMImpl method to check for duplicate file record in DB table


    /**Method to check for duplicate files
    * @param fileNm
    * @return
    */
    public String checkDuplicateFile(String fileNm){
    ViewObject fileVo =this.getFileUpdDwn1();
    Row duplFile[]= fileVo.getFilteredRows("FileName", fileNm);
    if(duplFile.length>0){
    return"N";
    }else{
    return"Y";
    }
    }

    ValueChangeListener to execute all methods


    /**
    * Generic Method to execute operation
    * */
    public OperationBinding executeOperation(String operation){
    OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
    return createParam;
    }

    /**Method to Upload Multiple Files to DB ,called on ValueChangeEvent of inputFile
    * @param vce
    */
    publicvoiduploadFileVCE(ValueChangeEvent vce){
    if(vce.getNewValue()!=null){
    //Get File Object from VC Event
    List<UploadedFile> lf =(List<UploadedFile>) vce.getNewValue();

    //Traverse over file list to upload all files
    for(UploadedFile fileVal : lf){
    //Method to check if this file is uploaded previously or not
    OperationBinding duplOb = executeOperation("checkDuplicateFile");
    duplOb.getParamsMap().put("fileNm", fileVal.getFilename());
    duplOb.execute();
    if(duplOb.getResult()!=null&&"Y".equalsIgnoreCase(duplOb.getResult().toString())){

    //Method to insert data in table to keep track of uploaded files
    OperationBinding ob = executeOperation("setFileData");
    ob.getParamsMap().put("name", fileVal.getFilename());
    ob.getParamsMap().put("path","DB");
    ob.getParamsMap().put("contTyp", fileVal.getContentType());
    ob.execute();
    //Upload and Save file to DB
    UploadFileActionToDB(fileVal);
    //Commit the transaction
    executeOperation("Commit").execute();
    //Execute ViewObjecy
    executeOperation("Execute").execute();
    }
    }
    // Reset inputFile component after upload
    ResetUtils.reset(vce.getComponent());
    }
    }


  • Now run and check application , Drop single or multiple files in af:inputFile component


  • Check in DB table, all records are saved with file in BLOB :)


  • I have seen that developers often use servlet to download and open file in browser window using HTTP response , but no need to to do this as ADF provides built in component for this <af:fileDownloadActionListener> that automatically generate http response

  • Now Upload part is complete , for download functionality added a link in table column and dropped an af:fileDownloadActionListener inside link and set properties for DownloadActionListener



  • See Download Listener Code

  • /**Method to download file from actual path
    * @param facesContext
    * @param outputStream
    */
    publicvoiddownloadFileListener(FacesContext facesContext, OutputStream outputStream)throws IOException {

    DCIteratorBinding imageIter =(DCIteratorBinding) getBindingsCont().get("FileUpdDwn1Iterator");
    ViewObject vo = imageIter.getViewObject();
    FileUpdDwnVORowImpl curRow =(FileUpdDwnVORowImpl) vo.getCurrentRow();

    BlobDomain blob = curRow.getImageFile();
    BufferedInputStream in =null;

    in =new BufferedInputStream(blob.getBinaryStream());

    int b;
    byte[] buffer =newbyte[10240];
    while((b = in.read(buffer,0,10240))!=-1){
    outputStream.write(buffer,0, b);
    }
    outputStream.close();
    }
Sample ADF Application- Download
Cheers :) Happy Learning

ADF Basics| Tip to Hide af:inputListOfValues search popup at runtime

$
0
0
Hello All

Previously I have posted about a requiremnt of  hiding af:inputListOfValues search icon using CSS
ADF Skinning | Hiding search icon of af:inputListOfValues using CSS & StyleClass

In that solution search icon doesn't appear on page but it is a part of JSF component tree so when user press TAB+SPACE after entering a value in lov component then search popup appears on screen as this action invokes search icon click event

Recently a Friend of mine came across another requirement that was not showing lov popup at all as only autoSuggest behavior was required , so for this first way is to use autoSuggest behavior in an af:inputText compoent using Lov bindings and second way is to short circuit component life cycle



Suppose you have created lov on department name attribute

Enter some value and press TAB+SPACE



LOV search popup appears with some results 

Now to short-circuit JSF life cycle we'll use

FacesContext.getCurrentInstance().responseComplete();

responseComplete indicates that you have already handeled the response and JSF need not to reponse and lifecycle will skip to response as soon as current processing ends and final view of page is created as per JSF component tree

So create launchPopupListener method for LOV in managed bean and write this single line of code

af:inputListOfValues XML source on page


<af:inputListOfValuesid="deptNameTransId"
popupTitle="Search and Select: #{bindings.DeptNameTrans.hints.label}"
value="#{bindings.DeptNameTrans.inputValue}"
label="Department"
model="#{bindings.DeptNameTrans.listOfValuesModel}"
required="#{bindings.DeptNameTrans.hints.mandatory}"
columns="#{bindings.DeptNameTrans.hints.displayWidth}"
shortDesc="#{bindings.DeptNameTrans.hints.tooltip}"
launchPopupListener="#{viewScope.InputLovBean.lovLaunchPopupListener}"
autoSubmit="true"contentStyle="width:300px;font-weight:bold;padding:2px;">
<f:validatorbinding="#{bindings.DeptNameTrans.validator}"/>
<af:autoSuggestBehaviorsuggestedItems="#{bindings.DeptNameTrans.suggestedItems}"/>
</af:inputListOfValues>

LaunchPopupListener code in managed bean


/**Mehtod to handle launchEvent of Lov Popup
* @param launchPopupEvent
*/
publicvoidlovLaunchPopupListener(LaunchPopupEvent launchPopupEvent){
//responseComplete indicates that you have already handeled the response
//and JSF need not to reponse and lifecycle will skip to response as soon as
//current processing ends and final view of page is created as per
//JSF component tree
FacesContext.getCurrentInstance().responseComplete();
}

Cheers :) Happy Learning

Oracle ADF Best Practices, Mistakes and Worst Pracitces

$
0
0

In this post I am putting some practices and that we should follow while using Oracle Application Development Framework for development




  • Call database (PL/SQL) function and procedure in model layer and then access in managed bean using page level bindings
    ADF Basics: Call PL/SQL Stored function in ADF Application
  • Use Exception Handler in Taskflow where required
    Global Exception Handler for ADF Task Flow Method Calls
  • Some ADF Component use animation for rendering like table, tree, popup. Consider animation-enabled false for better performance
    This can be controlled through ADF Skin
  • Ensure that each EnityObject/ ViewObject must have a primary key




  • Configure resource bundle before creating business components
    Using external XML file as list resource bundle in ADF Application
  • Avoid code duplication, Use utility classes instead - ADFUtil, JSFUtil etc
    ADF and JSF Utils Clasees
  • Avoid using editable tables, Use forms to edit data of tables
  • Avoid editable primary key attribute
  • Close iterators after use
  • Use ADF Logger instead of System.out.println
  • Choose bean scope carefully , lots of problem occurs due to wrong bean scope
    Memory Scope For ADF Managed Beans-As per Fusion Developer guide
  • Don't use getDBTransaction().postChanges unless you have a commit operation in same request
  • Check for null values instead of using try/catch block everywhere
  • Avoid circular dependency of list of values
  • Use createRowSetIterator() for view object programmatic iteration instead of using AllRowsInRange
  • Always use readOnly viewObject for view based or reference data, This helps in performance as it avoids EntityCache
  • Write business logic in model level implementation classes as AMImpl/VOImpl and call those methods in bean using binding layer
    ADF Basics: How to invoke model layer methods from managed bean (Best Practice to write business logic in ADF)
  • Implement bean serialization for applicationScope, sessionScope, pageFlowScope beans 
  • ADF Faces requires only one root component per fragment
  • Ensure uniqueness of taskflow name, managed bean name and application module name in entire application
  • Always check for null values while calculating transient attributes default values
  • Don't write bulky and unnecessary code in accessors of components or attributes as accessors are called multiple times so it'll affect performance
  • Catch Jbo Exceptions while calling pl/sql functions/procedure and show as a message on page instead of showing ADF/DB generated messages
  • To apply validation and autoSuggest like feature in search form use custom search instead of af:query component
  • Ensure that component bindings should be in a request scoped bean not greater than that
  • Instead of using setWhereClause() use query based bind variable to improve performance
  • Use basic tuning in ViewObjects to fetch rows from DB to improve performance
  • Don't set immediate true for editable input components
  • Don't use cached application module reference in bean instead of caching, look for AM when required as it is a pooled resource that's why it is never guaranteed that you will get same AM instance over a period of time. You'll end up getting lots of Null Pointer Exceptions

Viewing all 165 articles
Browse latest View live