目前分類:JAVA - ADF (3)

瀏覽方式: 標題列表 簡短摘要

上篇 ADF Table : Row selection using checkboxes 覺得那樣作有點麻煩, 經過思考及整理後, 覺得下列作法較佳:

 

前置作業:

1. 使用 Table: USERS 來作示範

CREATE TABLE "USERS"(
      "USERNAME" VARCHAR2(15 BYTE) NOT NULL  PRIMARY KEY ENABLE ,
    "NAME"     VARCHAR2(255 BYTE) NOT NULL ENABLE,
    "PASSWORD" VARCHAR2(15 BYTE) NOT NULL ENABLE
  )

 

Step 01:

建立的 EO (Entity Objects): UsersEO 自行加入一個暫時記錄資料(transient attribute)的欄位 Selected , Type: Boolean, 因不需回寫 Table, 所以將屬性 Persistent 拿掉

TableCheckboxSelect_EO.png 

Step 02: 建立 VO: UsersVO,並加入三個 function 於 UsersVOImpl 中: selectAll(), deSelectAll(), deleteSelectedRows()

TableCheckbox_bestSolution_01.png

import com.wei.model.vo.common.UsersVO;

import oracle.jbo.Row;
import oracle.jbo.RowSet;
import oracle.jbo.RowSetIterator;
import oracle.jbo.server.ViewObjectImpl;
// ---------------------------------------------------------------------
// ---    File generated by Oracle ADF Business Components Design Time.
// ---    Fri Jun 13 15:21:46 CST 2014
// ---    Custom code may be added to this class.
// ---    Warning: Do not modify method signatures of generated methods.
// ---------------------------------------------------------------------
public class UsersVOImpl extends ViewObjectImpl implements UsersVO {
    /**
     * This is the default constructor (do not remove).
     */
    public UsersVOImpl() {
    }

    public void selectAll(){
        RowSetIterator row =  this.getRowSetIterator();
        row.reset();
        if (row.first() != null) {
            Row r = row.first();
            r.setAttribute("Selected", true);
        }
        while(row.hasNext()){
            Row r = row.next();
            r.setAttribute("Selected", true);
        }
        
    }
    public void deSelectAll(){
        RowSetIterator row =  this.getRowSetIterator();
        row.reset();
        if (row.first() != null) {
            Row r = row.first();
            r.setAttribute("Selected", false);
        }
        while(row.hasNext()){
            Row r = row.next();
            r.setAttribute("Selected", false);
        }
        
    }    
    public void deleteSelectedRows() {        
        Row[] selectedRowsToDelete = this.getFilteredRows("Selected",true);
        if (selectedRowsToDelete.length>0){
            for ( Row row: selectedRowsToDelete) {                
                row.remove();
            }
        }
        this.executeQuery();
        this.getDBTransaction().commit(); //直接刪除資料
    }
}

 

Step 03: 將自建的 function 註冊, 以便轉換可使用的 method

TableCheckbox_bestSolution_02.png

 

Step 04: 將註冊好的 method 拖拉至 tableCheckBoxSelect.jspx 中使用.

TableCheckbox_bestSolution_03.png

 

執行的結果如下, 這樣是不是很簡便呢?

TableCheckbox_bestSolution_04.png  

 參考文件:

http://docs.oracle.com/cd/B14099_19/web.1012/b14022/overview-summary.html
https://java.net/projects/smuenchadf/pages/ADFSamples

http://jdevadf.oracle.com/

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

From: Polin Wei

在Table的作業中, 常會有將所有筆數全選( Select All Rows)的需求, 在 ADF 的 Table 要實現這樣的效果卻有點難(好難搞的 ADF....) , Google 一下查到一些高手的作法, 整理如下.

前置作業:

1. 使用 Table: USERS 來作示範

CREATE TABLE "USERS"(
      "USERNAME" VARCHAR2(15 BYTE) NOT NULL  PRIMARY KEY ENABLE ,
    "NAME"     VARCHAR2(255 BYTE) NOT NULL ENABLE,
    "PASSWORD" VARCHAR2(15 BYTE) NOT NULL ENABLE
  )

 

2. 建立一個 JavaBean: UsersTableBean

package com.wei.bean;

import com.wei.utils.ADFUtils;

import java.util.ArrayList;

import javax.faces.event.ValueChangeEvent;

import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.component.rich.data.RichTable;

import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.render.ClientEvent;

import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;

import org.apache.myfaces.trinidad.model.CollectionModel;
import org.apache.myfaces.trinidad.model.RowKeySet;
import org.apache.myfaces.trinidad.model.RowKeySetImpl;

public class UsersTableBean {
    private RowKeySet selectedRows;
    private RichTable table;
    private static final String ITERATOR_NAME = "UsersVO1Iterator";

    public UsersTableBean() {
        super();
    }


    public void setSelectedRows(RowKeySet selectedRows) {
        this.selectedRows = selectedRows;
    }

    public RowKeySet getSelectedRows() {
        if (selectedRows == null) {
            selectedRows = new RowKeySetImpl();
            CollectionModel collectionModel =
                (CollectionModel)getTable().getValue();
            selectedRows.setCollectionModel(collectionModel);
        }

        return selectedRows;
    }

    public void setTable(RichTable table) {
        this.table = table;
    }

    public RichTable getTable() {
        return table;
    }

    public void rowSelected(ClientEvent clientEvent) {
        refreshSelectedRows();
        AdfFacesContext.getCurrentInstance().addPartialTarget(getTable());

    }

    public void selectAll(ValueChangeEvent valueChangeEvent) {
        DCIteratorBinding it = ADFUtils.findIterator(ITERATOR_NAME);
        RowSetIterator rit = it.getRowSetIterator();
        rit.reset();
        if (valueChangeEvent.getNewValue() != null) {
            Boolean selectAll =
                Boolean.parseBoolean(valueChangeEvent.getNewValue().toString());
            if (rit.first() != null) {
                Row r = rit.first();
                r.setAttribute("Selected", selectAll);
            }
            while (rit.hasNext()) {
                Row r = rit.next();
                if (r != null) {
                    r.setAttribute("Selected", selectAll);
                }
            }
        }

        refreshSelectedRows();
        it.executeQuery();
    }

    private void refreshSelectedRows() {
        getSelectedRows().clear();

        DCIteratorBinding it = ADFUtils.findIterator(ITERATOR_NAME);
        RowSetIterator rit = it.getRowSetIterator();
        rit.reset();

        if (rit.first() != null) {
            Row r = rit.first();
            if (r.getAttribute("Selected") != null) {
                makeRowSelected(r);
            }
        }
        while (rit.hasNext()) {
            Row r = rit.next();
            if (r.getAttribute("Selected") != null) {
                makeRowSelected(r);
            }
        }

    }

    private void makeRowSelected(Row r) {
        Boolean selected = (Boolean)r.getAttribute("Selected");
        if (selected) {
            ArrayList keyList = new ArrayList();
            keyList.add(r.getKey());
            getSelectedRows().add(keyList);
        }
    }

}

 

Step 01:

建立的 EO (Entity Objects): USERSEO 自行加入一個暫時記錄資料(transient attribute)的欄位 Selected , Type: Boolean, 因不需回寫 Table, 所以將屬性 Persistent 拿掉

TableCheckboxSelect_EO.png  

 

Step 02: 建立一個檔案 tableCheckBoxSelect.jspx , 將 UserVO1 拖拉進來,並選轉換為ADF Table 物件


 TableCheckboxSelect_tableProperty.png  
 

Section Attribute Value
Common Id t1
  rowSelection multiple
Behavior partialTriggers selectAll
Advanced binding #{viewScope.UsersTableBean.table}
  selectedRowKeys #{viewScope.UsersTableBean.selectedRows}

 

Step 03: 再將 Selected 欄位 Convert To CheckBox

TableCheckboxSelect_ConvertToCheckbox.png  

在作 Convert 時, 可以挑選要 Binding 的資料來源, 原則上不需變動

TableCheckboxSelect_ConvertToCheckbox_Binding.png

最後確認時, 是告知轉換成 Checkbox 時, 這兩個欄位屬性: MaximumLength、Columns會被移除

TableCheckboxSelect_ConvertToCheckbox_Confirm.png  

在 Headline 加入 SelectBooleanCheckbox 元件

TableCheckboxSelect_HeadlineAddCheckbox.png  

 

Section Attribute Value
Common Id selectAll
  Width 30
Behavior autoSubmit true
  valueChangeListener #{viewScope.UsersTableBean.selectAll}

 

這是方法之一, 但第一次選擇時 Table 裡的每一個ROW 的 checkBox 卻沒有被打勾, 這未解決......

 

 參考:

http://www.gebs.ro/blog/oracle/oracle-adf-row-selection-using-checkboxes/

http://www.oracle.com/technetwork/developer-tools/adf/learnmore/34-extra-arguments-to-javascript-169176.pdf

http://docs.oracle.com/cd/E16764_01/web.1111/b31973/af_event.htm

http://docs.oracle.com/cd/B14099_19/web.1012/b14022/overview-summary.html

http://jdevadf.oracle.com

 Section 5.3.1, "How to Return the Original Source of the Event.

文章標籤

MIS 發表在 痞客邦 留言(0) 人氣()

環境:

ADF version: 11.1.1.6.0
Oracle EBS version: R12.2.3

程式的目的在於取得 EBS 登入時的使用者相關資訊。整個程式架構如下圖:

ADF_Integrate_EBS_01.png  

 

 

ADF 的程式面:

Step 01: 在 ViewController 依序建立 Java Class:ConnectionProvider、EBizUtil、EBSWrapperFilter、以及存取使用者資訊的 Java Bean: UserInfo

資料的

ConnectionProvider.java

package com.oracle.view;

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class ConnectionProvider {
    private static DataSource ebsDS = null;
    static{
        try {
            Context ctx = new InitialContext();
            ebsDS = (DataSource) ctx.lookup("jdbc/TEST32");
            
            // your datasource jndi name as defined during configuration
            if (ctx != null)
                ctx.close();
            
        } catch (Exception e) {
            // TODO: Add catch code
            //ne.printStackTrace(); //ideally you should log it
            throw new RuntimeException(e);
            // means jndi setup is not correct or doesn't exist
        }
    }
    
    private ConnectionProvider() {
        super();
    }
    

   public static Connection getConnection() throws SQLException{
        if (ebsDS == null)
            throw new IllegalStateException("AppsDatasource is not properly initialized or available");
        return ebsDS.getConnection();
    }
 
    
}

PS: 在 EBS 環境中是以 jdbc 的模式取得資料庫連線,可以進入 weblogic 的 Services-> Data Sources 查看,如:EBSDataSource 的 JNDI: jdbc/TEST32 ,並可以得知要佈署到那一個主機上:oacore_cluster1

ADF_Integrate_EBS_06.png  

 

EBizUtil.java

package com.oracle.view;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.apps.fnd.ext.common.EBiz;


public class EBizUtil {
    public EBizUtil() {
        super();
    }
    private static final Logger logger = Logger.getLogger(EBizUtil.class.getName());
    private static EBiz INSTANCE = null;
    static {
        Connection connection = null;
        try {
            connection = ConnectionProvider.getConnection();
            // DO NOT hard code applServerID for a real application
            // Get applServerID as CONTEXT-PARAM from web.xml or elsewhere
            INSTANCE = new EBiz(connection, "F1CB87199593E5F4E0431F030A0AD0AB31310251131793525291714692481335");
        } catch (SQLException e) {
            logger.log(Level.SEVERE, "SQLException while creating EBiz instance -->", e);
            throw new RuntimeException(e);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Exception while creating EBiz instance -->", e);
            throw new RuntimeException(e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static EBiz getEBizInstance() {
        return INSTANCE;
    }    
    
}

PS: APPL_SERVER_ID 可以到 EBS APP Server 路徑下的 $INST_TOP/appl/fnd/12.0.0/secure/TEST32.dbc 取得
Server ID :
APPL_SERVER_ID=F1CB87199593E5F4E0431F030A0AD0AB31310251131793525291714692481335

EBSWrapperFilter.java

package com.oracle.view;

import java.io.IOException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import oracle.apps.fnd.ext.common.AppsRequestWrapper;
import oracle.apps.fnd.ext.common.AppsRequestWrapper.WrapperException;

public class EBSWrapperFilter implements Filter {
    public EBSWrapperFilter() {
        super();
    }


    private static final Logger logger = Logger.getLogger(EBSWrapperFilter.class.getName());
    
    public void init(FilterConfig filterConfig) {
        logger.info("Filter initialized ");
    }

    public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain) throws IOException,ServletException {
        AppsRequestWrapper wrapper = null;
        logger.info("-current URI =" + ((HttpServletRequest)request).getRequestURI());

        try {
            
            wrapper = new AppsRequestWrapper((HttpServletRequest)request, (HttpServletResponse)response, ConnectionProvider.getConnection(), EBizUtil.getEBizInstance());
            
        } catch (WrapperException e2) {
            logger.log(Level.SEVERE, "WrapperException error encountered ", e2);
            throw new ServletException(e2);
        } catch (SQLException e2) {
            logger.log(Level.SEVERE, "SQLException error encountered ", e2);
            throw new ServletException(e2);
        }
        try {
            logger.info("Created AppsRequestWrapper object." + " Continuing the filter chain.");
            chain.doFilter(wrapper, response);
            logger.info("- the filter chain ends");
        } finally {
            //AppsRequestWrapper caches a connection internally.
            //AppsRequestWrapper.getConnection()--returns this connection this connection can be used in doGet()/doPost() service layer
            //whenever our application requires a connection in order to service the current request.
            //When AppsRequestWrapper instance is in use, this connection should not be closed by other code.
            //At this point, we are done using AppsRequestWrapper instance so, as good practice, we are going to close (release) this connection now.
            if (wrapper != null) {
                try {
                    logger.info("- releasing the connection attached to the" + " current AppsRequestWrapper instance ");
                    wrapper.getConnection().close();
                } catch (SQLException e3) {
                    logger.log(Level.WARNING, "SQLException error while closing connection--", e3);
                    throw new ServletException(e3);
                }
            }
            wrapper = null;
        }
    }

    public void destroy() {
        logger.info("Filter destroyed ");
    }
}

 

UserInfo.java

package com.oracle.bean;

import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import oracle.apps.fnd.ext.common.AppsRequestWrapper;
import oracle.apps.fnd.ext.common.Session;

public class UserInfo {
    private String user;
    private String userInfo;

    public UserInfo() {
        super();
    }


    public void setUser(String user) {
        this.user = user;
    }

    public String getUser() {
        return user;
    }


    public void beforePhase(PhaseEvent phaseEvent) {
        // Add event code here...
        AppsRequestWrapper wrappedRequest =
            (AppsRequestWrapper)FacesContext.getCurrentInstance().getExternalContext().getRequest();

        Session session = wrappedRequest.getAppsSession();

        setUser(session.getUserName());

        Map columns = session.getInfo();
        StringBuffer temp = new StringBuffer();
        temp.append("<table>");
        for (Object key : columns.keySet()) {
            temp.append("<tr>");
            temp.append("<td>");
            temp.append(key);
            temp.append("</td>");
            temp.append("<td>");
            temp.append(columns.get(key));
            temp.append("</td>");
            temp.append("</tr>");
        }
        temp.append("</table>");

        setUserInfo(temp.toString());

    }

    public void setUserInfo(String userInfo) {
        this.userInfo = userInfo;
    }

    public String getUserInfo() {
        return userInfo;
    }
}

 

Step 02:在 adfc-config.xml 建立 view: userInfo.jspx 及 設定 Managed Beans

userInfo.jspx

版面:PageGroupLayout :layout = vertical
      OutPutText:value="Hello #{pageFlowScope.userInfoBean.user}!!"
          inlineStyle="font-size:medium; color:Red;"
      Separator
       OutPutText:value="#User Info:<br>#{pageFlowScope.userInfoBean.userInfo}"
           escape="false"
                  inlineStyle="font-size:medium;"

  ADF_Integrate_EBS_03.png

 

Managed BeansuserInfoBean

  ADF_Integrate_EBS_02.png

 

Step 03: 設定 userInfo.jspx 的 beforePhase

ADF_Integrate_EBS_04.png  

這是在 UserInfo.java 的一段程式

    public void beforePhase(PhaseEvent phaseEvent) {
        // Add event code here...
        AppsRequestWrapper wrappedRequest =
            (AppsRequestWrapper)FacesContext.getCurrentInstance().getExternalContext().getRequest();

        Session session = wrappedRequest.getAppsSession();

        setUser(session.getUserName());

        Map columns = session.getInfo();
        StringBuffer temp = new StringBuffer();
        temp.append("<table>");
        for (Object key : columns.keySet()) {
            temp.append("<tr>");
            temp.append("<td>");
            temp.append(key);
            temp.append("</td>");
            temp.append("<td>");
            temp.append(columns.get(key));
            temp.append("</td>");
            temp.append("</tr>");
        }
        temp.append("</table>");

        setUserInfo(temp.toString());

    }

 

Step 04 : web.xml 中設定 Filters

ADF_Integrate_EBS_05.png  

 

Oracle EBS 上的設定:

Step 01: 設定 Function : Menu: Responsibiliey:

Function: WEI_ADFLAB_USERINFO

Function WEI_ADFLAB_USERINFO
Properties-Type External ADF Application
WebHTML-HTML Call GWY.jsp?targetPage=faces/userInfo
   

 ADF_Integrate_EBS_07.png  

ADF_Integrate_EBS_08.png

 

Menu:WEI_LAB_MENU

ADF_Integrate_EBS_09.png  

 

Responsibility: WEI Labs

ADF_Integrate_EBS_10.png  
  

Step 02: Responsibility: Functional Administrator 上的設定

a. Core Services → Profiles → Code: FND_EXTERNAL_ADF_URL → Go

b. 然後點選External ADF Application URL 後按 Define Profile Values

ADF_Integrate_EBS_11.png  

 

a. 點選Define Profile Values → Responsibility
b. 選擇 Responsibility & Value
c. Value:  客製程式在 weblogic 的路徑,如: http://lnxap104:7214/LAB_EBS-ViewController-context-root/ ,最後要加 /
d. 按 Update

ADF_Integrate_EBS_12.png  

一個Responsibility只能綁定一個程式的root,所以如果有多個功能,可能要放在同一包應用程式裡面。也有其它使用者在問此問題,但現在並沒有進一步的解法。例如: Oracle論壇,其他使用者提問的 >> 問題
 

Step 03: 清除 Caching Framework & Testing

ADF_Integrate_EBS_12-1.png

ADF_Integrate_EBS_13.png  

 

 

 

 

文章標籤

MIS 發表在 痞客邦 留言(1) 人氣()