Tuesday, November 19, 2013

ADF Naming Standards

Naming Standards are very important to organize the code, especially when you are working with large scale applications. Below are the naming conventions based on JUST my past experience


Business Components

  Entity                                  - Suffix with 'EO' - example : EmployeeEO
  Updateable View Object      - Suffix with 'VO' - example : EmployeeVO
  Programmatic View Object  - Suffix with 'TRVO' example : EmployeeTRVO
  ReadOnly View Object        -  Suffix with 'ROVO' example : EmployeeROVO
  List of Values View Object  -  Suffix with 'LOV' example : GenderLOV
  View Link                            - Suffix with 'VL' example : EmployeeDepartmentVL
   Association                         - Suffix with 'Assoc' Example : EmployeeDepartmentAssoc
  View Accessor                    - Suffix with 'VA' Example :  EmployeeNameVA
  Application Module               - Suffix with 'Service' example : EmployeeService

Packaging

Entities                            :     com.<application>.<project>.model.entities
Updateable View Object :     com.<application>.<project>.model.queries    
Application Module         :      com.<application>.<project>.model.services           
Programmatic View Object :     com.<application>.<project>.model.trvo
View Link                          :    com.<application>.<project>.model.vl
Association                        :    com.<application>.<project>.model.assoc
Read only View Object      :    com.<application>.<project>.model.readonly

Application Naming 
- Giver proper name to application , For eg : EmployeeMgmt, CustomerMgmt, VendorMgmt, etc.. The name of the application should be meaningful with respect to the functionality

Project Naming
 - Give meaningful name to each project you create in any application
 - Model Project :
   Example : EmployeeModel, CustomerModel,VendorModel - All the model projects suffix with 'Model'
- View Controller Project : 
 Example : EmployeeUI, CustomerUI, VendorUI - This project holds all the User Interface related components such as .jsff, jspx, xml, etc..

Web Service Projects
 Example : EmployeeWSService, CustomerWSService, VendorWSService - All these projects contains the web services related.

- Web Service Proxies
Example : EmployeeWSProxies, VendorWSProxies, CustomerWSProxies - All these projects contains the web service proxy related files.

Friday, November 15, 2013

Invoke Stored procedure (PL/SQL) and function using ADF

This blog explains about invoking PL/SQL Stored procedure using ADF


       

   public class PrintAndApplyServicesImpl extends ApplicationModuleImpl implements PrintAndApplyServices {
    /**
     * This is the default constructor (do not remove).
     */
    public PrintAndApplyServicesImpl() {
    }

    /**
     *This method takes the lot number as the input and gives the lot details as the output
     * @param pLotNumber
     * @return
     */

    public LotDetailsDTO getLotDetails(String pLotNumber) {
        //List lotDetailsList = new ArrayList();
        LotDetailsDTO lotInformation = new LotDetailsDTO();
        CallableStatement callableStatement = null;
        try {
            ResultSet rs = null;
             callableStatement = getDBTransaction().createCallableStatement("begin  " + "XHL_PRINT_APPLY_PKG.GET_LPN_INFO(?,?);" +  "end;", 0);                  
            // register the input parameter
            callableStatement.setString(1, pLotNumber);
           // register the out parameter
            callableStatement.registerOutParameter(2, OracleTypes.ARRAY, "ITEM_TAB_RESULT");
            // execute the statement
            callableStatement.execute();
            Array outArray = (Array)callableStatement.getArray(2);
            rs = outArray.getResultSet();
            while (rs.next()) {
                Struct row = (Struct)rs.getObject(2);
                if(row!=null) {
                    System.out.println("length"+row.getAttributes().length);
                    Object[] cols = row.getAttributes();
                    lotInformation.setBatchNumber((String)cols[0]);
                    //System.out.println(lotInformation.getBatchNumber());
                    lotInformation.setItemDescription((String)cols[1]);
                    lotInformation.setItemCode((String)cols[2]);
                    lotInformation.setRevision((String)cols[3]);
                    lotInformation.setLotNumber((String)cols[4]);
                    lotInformation.setTransactionQuantity((String)cols[5]);
                    lotInformation.setExpirationDate((String)cols[6]);
                    lotInformation.setUserName((String)cols[7]);
                    lotInformation.setPalletQuantity((String)cols[8]);
                    lotInformation.setPalletNumber((String)cols[9]);
                    lotInformation.setTransactionDate((String)cols[10]);
                    lotInformation.setTransactionId((String)cols[11]);
                    lotInformation.setBatchId((String)cols[12]);
                    lotInformation.setPrintStatus((String)cols[13]);
                    lotInformation.setExpiration((String)cols[14]);
                    lotInformation.setCurrentDate((String)cols[15]);
                    lotInformation.setGrossWeight((String)cols[16]);
                    lotInformation.setPalletHeight((String)cols[17]);
                    lotInformation.setPalletLength((String)cols[18]);
                    lotInformation.setPalletWidth((String)cols[19]);
                    lotInformation.setVolume((String)cols[20]);
                    lotInformation.setConcatCode((String)cols[21]);
                    lotInformation.setReponseStatus((String)cols[22]);
                    lotInformation.setResponseMessage((String)cols[23]);
                    for(Object col : cols) {
                        System.out.println(col);
                    }
                }
            }
                //lot.setItemDescription(rs.getString(2));
            if (callableStatement != null) {
                callableStatement.close();
            }
        } catch (Exception e) {
                e.printStackTrace();
        }
        return lotInformation;
    }
}
 

Tuesday, November 12, 2013

Generate PDF of a Table using ADF

How to download Oracle ADF tables in PDF format


          At this task we are going to convert ADF BC tables into PDF files and make it downloadable to users. It looks like very easy but it is not. To successfully complete this task I had to use several libraries such as apache fop library.
 
  • What is Apache FOP library.....??



          FOP stands for Formatting Object Processor. Apache FOP is a Java application which reads a Formatting Object (FO) tree and renders the resulting pages to a specific output. Currently supported outputs are:
           PDF, PS, PCL, AFP, XML, Print, AWT and PNG, and to a lesser extend RFT and TXT.
          Developers use Apache FOP libraries to change the output file format very commonly because it’s free and open source. You can download the Apache FOP library as a JAR file from the below link. (There are different links to download FOP.jar; but most of the jar files do not contain all the libraries required for this conversion.)


  •  How to convert ADF BC tables into PDF files
 
           If we try to analyse the process goes here we can simply represent it as below.

          First of all we want to get the table data and write it into a XML file. We can do it through JDeveloper framework. There is an inbuilt method called “printXML” at ViewObjectImpl class. It will generate the XML to the VO data. So if we can access the ViewObjectImpl class anyway we can generate the XML file. <VO>Impl class is a one which extends the ViewObjectImpl class. So we can generate the <VO>Impl class and generate the XML file.

  • Implement the <VO>Impl and <Application_Module>Impl classes for your MODEL project. (We need those method at those classes to generate the XML file.)
    (<VO>.xml à Java à Java Classes à click on "pencil" icon.)

  • Create a Java class at “View Controller” project to create a managed-bean. We are going to do all the coding inside this bean. All the required codes are mentioned at the end of this article.
     
  • We can access the <VO>Impl class through this path:
    (FacesContext à ExternalContext à AdfFacesContext à HttpServletRequest à BindingContext à DCDataControl à ApplicationModule à AppModuleImpl à ViewObjectImpl)
     
  • When we are creating the Node object we have two options. You can select the one which suits your requirement. (refer code while "// Print the XML" )
    Parameter
    Description
    XML_OPT_ALL_ROWS
    All rows will be rendered in XML
    XML_OPT_ASSOC_CONSISTENT
    attribute accessors that return a RowSet should set the AssociationConsistent flag on, so that new (unposted) rows for the RowSet are also included in the output.
    XML_OPT_CHANGES_ONLY
    For internal framework use only.
    XML_OPT_LIMIT_RANGE
    Rows in the current range will be rendered in XML
  • Then we have to generate the PDF using  a style sheet. Before genarate PDF files you should have to build the style sheet. Then we can generate the output file using FOP libraries (we can select the output format). Output format depends on the MimeConstant you select. There are several output formats supported by FOP libraries as follows. (refer code while "// Generate PDF" )

    MIME Constant
    Output Format
    MIME_PDF
    pdf
    MIME_PLAIN_TEXT
    txt
    MIME_PNG
    png
    MIME_FOP_AREA_TREE
    xml
    MIME_POSTSCRIPT
    ps
    MIME_AFP
    afp
    MIME_TIFF
    tiff
  •   
  • Then insert a Command Button next to your ADF BC table. Create a web page backing bean and write an Action Method. Then set that action method as the “action” property of the created command button. Inside the action method we have to write some codes which will make the generated pdf file to be downloadable.
     
  • When user press the command button pdf file shold be generated and downloadable. To do that  we have to go through the Context layers of the framework, get the http servlet response and set the content type of the response.
     
  • Here we have set the content type as “application/pdf” because we have generated a pdf file. That parameter depends on your file type. (refer code while "// download the PDF" )

      
All the required codes are given below.....

 
// Access the <VO>Impl
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
AdfFacesContext context = AdfFacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
BindingContext ctx = DCUtil.getBindingContext(request);
DCDataControl dc = ctx.findDataControl("AppModuleDataControl");
ApplicationModule service = (ApplicationModule)dc.getDataProvider();
ApplicationModule am = service.findApplicationModule("AppModule");
AppModuleImpl amImpl = (AppModuleImpl)am;
ViewObjectImpl VOImlp = (EmpVOImpl)amImpl.findViewObject("EmpVO1");
HashMap viewDefMap = new HashMap();

// Print the XML
Node n = VOImlp.writeXML(XMLInterface.XML_OPT_ALL_ROWS, viewDefMap);
java.io.File file = new java.io.File(<path to save XML file>);
PrintWriter output = null;
try {  output = new java.io.PrintWriter(file);
          ((XMLNode)n).print(output);
} catch (Exception e) { System.out.println(e.getMessage());
} finally {
try {output.close(); } catch (Exception e) { System.out.println(e.getMessage()); } } }

// Generate PDF
File xmlfile = new File(<path to generated XML file>);
File xsltfile = new File(<path to styleSheet>);
File pdffile = new File(<path to save PDF file>);
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
TransformerFactory factory = new TransformerFactoryImpl();
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
transformer.setParameter("versionParam", "2.0");
Source src = new StreamSource(xmlfile);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} finally { out.close(); }

// download the PDF
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse)externalContext.getResponse();
File file = new File(dir1, pdffile1);
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
          response.reset();
          response.setContentType("application/pdf");
          response.setContentLength((int)file.length());
response.setHeader("Content-disposition","inline;filename=\""+pdffile1+"\"");
output = new BufferedOutputStream(response.getOutputStream(),DEFAULT_BUFFER_SIZE);
          byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
          int length;
          while ((length = input.read(buffer)) > 0) {
              output.write(buffer, 0, length); }
          output.flush(); } finally { close(output); close(input); }
facesContext.responseComplete();

   USEFULL SITE relating to this

Monday, November 11, 2013

Scopes in ADF

Scopes in Fusion Web Applications


Scope indicates life time of an object. In ADF and JSF it is possible to define backing beans with particular scope.

Types of Scopes

There are seven types of scopes in a Fusion web application:

Scopes listed below in descending order with first one having longest life time and last one lowest life time.

Application scope -> Session scope ->Page flow scope  -> View scope ->Request scope ->Backing  bean scope
  • Application scope: An application scope object is available for the duration of the application and is shared among users. This scope may be used to hold static objects that are the same for all users.
  • Session scope: The object is available for the duration of the session, which is user instance-specific. A use case for a session scope bean is a user info bean that stores information about a user, which is read from the database or an LDAP server, to avoid unnecessary queries.
  • Page flow scope (Task flow scope): A pageFlow scope exists for each task flow instance and has a lifespan between request and session scope. The lifetime of the scope spans across all pages in a bounded task flow.
  • Request scope: The object is available from the time an HTTP request is made until a response is sent back to the client. From another perspective, a request scope starts with a request to be issued from one view to another for navigation cases that don't perform a redirect but a default server-side forward. The scope spans across all non-view activities that follow the view of interest to the next view activity.
  • Backing bean scope: The backing bean scope is comparable to the request scope, with the difference in that it exists for a specific client component. In general, all managed beans used in reusable components should be configured to backingBean scope. For example, bounded task flows that are designed to be regions on a page should use the backingBean scope if more than one instance of the task flow is expected to be on a single page.
  • View scope (Page Scope): The object is available until the view ID for the current view activity changes. This becomes handy when you use partial page rendering. If you have a dependent list box, you might send a server request to refresh the list box. When a response is returned, the request scope will be gone but the view scope will be still there. Therefore, view scope can be used to store data when partial rendering request comes back. The view scope exists not only for views that are rendered by JSPX pages, but also for views rendered by page fragments, as is the case in task flows that are built to execute in a region. The view scope of the parent page is not accessible from components added to a page fragement in a region, and the view scope of a view in a region is not accessible for the parent page.
  • None:  When you create objects (such as a managed bean) that require you to define a scope, you can set the scope to none, meaning that it will not live within any particular scope, but will instead be instantiated each time it is referenced. You should set a bean's scope to none when it is referenced by another bean.
Out of these View scope, Backing bean scope and page flow scope are ADF specific. Rest comes with JSF. This is the reason you must define ADF specific scoped backing beans ether in "adf-config.xml" or task flow. You access objects in those scopes via expression language with scope qualification. For instance, to reference the aaBean managed bean from viewScope scope, your expression would be
#{viewScope .aaBean }.
When working in ADF its always recommended to define backing beans in  ether "adf-config.xml" or task flow files.

References

  1. Oracle Fusion Developer Guide by Frank Nimphius and Lynn Munsinger
  2. Creating and Using Managed Beans (if you use ADF Faces components in a standard JSF application)
  3. Using a Managed Bean in a Fusion Web Application (if you use Oracle ADF Model data binding and ADF Controller)
  4. JavaServer Faces (JSF) Tutorial
  5. Backing Bean in JSF Tutorial
  6. Managed Beans in Oracle Fusion Web Applications