2013年5月22日星期三

ADF_224:ADF Mobile 11.1.2.4 Samples 介绍(10):HR

开发运行环境:JDeveloper 11.1.2.4 + Android SDK r21.1

HR演示了实际应用中最常用的CRUD功能的实现,它使用了一个本地的SQLite数据库保存数据。
HR还展示了iPhone和iPad两种界面,它们使用的是同一个数据模型层。

知识点:

1. List功能的实现
(1)按lastname的首字母分段显示
(2)并且在每个首字母项上有数量统计显示
(3)不是一次Load所有的行,会在最下面显示:Load More Rows.....

List.amx主要代码:
<amx:listView id="listView1" var="row" value="#{bindings.employees.collectionModel}"
            fetchSize="#{bindings.employees.rangeSize}" collapsibleDividers="true" showDividerCount="true"
            dividerMode="firstLetter" dividerAttribute="lastName"
            inlineStyle="position:absolute;top:50px;bottom:0;left:0;right:0">
  <amx:listItem id="listItem1" action="#{viewScope.ListBean.GetAction}" showLinkIcon="#{!row.showDelete}"
                shortDesc="Employee List Item">
      <amx:tableLayout id="tld1" width="100%" shortDesc="Emp Table Layout">
          <amx:rowLayout id="rld1">
              <amx:cellFormat id="cfdi" rowSpan="2" width="44px" halign="center" shortDesc="Emp Cell format">
                  <amx:image id="imaged1" source="#{row.pic}"
                             inlineStyle="height:34px;width:34px;margin-top:4px" shortDesc="Employee Image"/>
              </amx:cellFormat>
              <amx:cellFormat id="cfd1" width="100%" height="28px" shortDesc="Emp Cell Format">
                  <amx:outputText value=" #{row.firstName} #{row.lastName}" id="outputText2"/>
              </amx:cellFormat>
          </amx:rowLayout>
          <amx:rowLayout id="rld2">
              <amx:cellFormat id="cfd2" width="100%" height="12px" shortDesc="Emp Cell Format">
                  <amx:outputText id="title" value="#{row.job.title}"
                                  styleClass="adfmf-listItem-captionText"/>
              </amx:cellFormat>
          </amx:rowLayout>
      </amx:tableLayout>
      <amx:commandButton id="commandButton1" text="Delete" styleClass="adfmf-commandButton-alert"
                         rendered="#{row.showDelete}" actionListener="#{bindings.DeleteEmployee.execute}"
                         inlineStyle="position:absolute;margin:5px;right:0;top:0;" shortDesc="Delete Button"/>
      <amx:setPropertyListener from="#{row.rowKey}" to="#{bindings.deleteEmpNo.inputValue}" type="swipeRight"
                               id="spl3"/>
      <amx:actionListener id="al1" type="swipeRight" binding="#{bindings.ShowDeleteButton.execute}"/>
      <amx:setPropertyListener from="#{row.rowKey}" to="#{bindings.currentEmp.inputValue}" id="spl4"/>
      <amx:actionListener id="al2" binding="#{bindings.ClearDeleteButton.execute}"/>
      <amx:setPropertyListener from="#{false}" to="#{bindings.newEmp.inputValue}" id="spl5"/>
  </amx:listItem>
</amx:listView>

可以看出:
(1)集合数据是来自EmployeeList.java中的employees对象,即getEmployees()返回的对象。
(2)点击某一项,传递当前行的rowkey给下个页面。
(3)向右滑动某一项,显示删除按钮,组件的显示与隐藏逻辑如下:

<amx:cellFormat id="cf4" width="48px" halign="center" shortDesc="Cell">
    <amx:commandButton id="cb1" actionListener="#{bindings.Execute.execute}" shortDesc="Search Link"
                       icon="/images/search_36.png">
        <amx:setPropertyListener id="spl6" from="#{true}" to="#{pageFlowScope.HRBean.searchOn}"/>
    </amx:commandButton>
</amx:cellFormat>
<amx:cellFormat id="cf1" shortDesc="ClearFilter Cell" width="48px" halign="center"
                rendered="#{bindings.filter.inputValue ne '' and pageFlowScope.HRBean.searchOn}">
    <amx:commandButton id="cb2" shortDesc="ClearFilter Button"
                       actionListener="#{bindings.Execute.execute}" icon="/images/clear_36.png"
                       styleClass="adfmf-commandButton-alert">
        <amx:setPropertyListener id="spl2" from="#{}" to="#{bindings.filter.inputValue}"/>
        <amx:setPropertyListener id="spl7" from="#{false}" to="#{pageFlowScope.HRBean.searchOn}"/>
    </amx:commandButton>
</amx:cellFormat>


2. Filter功能的实现
(1)输入查询关键字后,点击查询按钮会调用EmployeeList.java中的Execute方法。
(2)同时会显示,清除查询关键字按钮。
(3)当查询结果为0时,会使用rendered="#{bindings.employeeCount.inputValue eq 0}",显示“没有符合条件的数据”。


4. Metris功能的实现
这种布局方式的实现如下:
(1)使用tableLayout显示Tab。
(2)点击Tab,传递当前Tab值到ManagedBean的相应属性中。
(3)使用panelSplitter显示每个Tab中的内容,属性selectedItem="#{pageFlowScope.HRBean.metrictab}",即指向ManagedBean的相应属性。


5. Detail功能的实现


(1)Directs的右上角的数字是使用 styleClass="hr-reportcount"实现的。
其在hr.css的定义如下:
.hr-reportcount {
    color: white;
    background-color: red;
    position: absolute;
    top: 45px;
    right: 2px;  
    font-size: 11px;
    font-weight: bold;
    padding: 0 2px !important;
    border-radius: 5px;
}
(2)点击当前员工,向左滑动看前一个员工,向右滑动看后一个员工
(3)点击当前员工,按住不动,或者点击右上角的按钮,都会在底部弹出一个popup窗口。
你可以给这个员工打电话,发短信......


6. EmployeeList.java 代码,全部的CRUD的操作就定义在这个类中。

package HR;

import application.DBConnectionFactory;

import application.LifeCycleListenerImpl;

import com.sun.util.logging.Level;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import java.util.ArrayList;
import java.util.List;

import oracle.adf.model.datacontrols.device.DeviceManager;

import oracle.adf.model.datacontrols.device.DeviceManagerFactory;

import oracle.adfmf.framework.api.AdfmfJavaUtilities;
import oracle.adfmf.framework.exception.AdfException;
import oracle.adfmf.java.beans.PropertyChangeListener;
import oracle.adfmf.java.beans.PropertyChangeSupport;
import oracle.adfmf.java.beans.ProviderChangeListener;
import oracle.adfmf.java.beans.ProviderChangeSupport;
import oracle.adfmf.util.Utility;
import oracle.adfmf.util.logging.Trace;


public class EmployeeList {
    private static List s_employees = null;
    private Employee editEmployee = new Employee();
    private transient ProviderChangeSupport providerChangeSupport = new ProviderChangeSupport(this);
    private boolean newEmp = false;
    private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
    private int employeeCount = -1;
    private int deleteEmpNo = 0;
    private int currentEmp = 0;
    private String filter = "";
    private String apppath = AdfmfJavaUtilities.getDirectoryPathRoot(AdfmfJavaUtilities.ApplicationDirectory);
    private static final String NOPIC = "/images/missingEmployee_120.png";
    private static final int ALLRECORDS = -1;
    private static final String SORTLNAME = "LAST_NAME";
    private static final String SORTIDDESC = "EMPLOYEE_ID DESC";
    private static final String SORTID = "EMPLOYEE_ID";

    public void addPropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.removePropertyChangeListener(l);
    }

    public void addProviderChangeListener(ProviderChangeListener l) {
        providerChangeSupport.addProviderChangeListener(l);
    }

    public void removeProviderChangeListener(ProviderChangeListener l) {
        providerChangeSupport.removeProviderChangeListener(l);
    }

    public EmployeeList() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "EmployeeList",
                  "!!!!!!!!!!!!!!!!!In the EmployeeList constructor!!!!!!!!!!!!!!!!!!!!!!!!!");
        if (s_employees == null) {
            s_employees = new ArrayList();
            Execute();
        }
    }

    public Employee[] getEmployees() {
        Employee e[] = null;

        e = (Employee[])s_employees.toArray(new Employee[s_employees.size()]);

        return e;
    }

    public void setEmployeeCount(int employeeCount) {
        int oldEmployeeCount = this.employeeCount;
        this.employeeCount = employeeCount;
        propertyChangeSupport.firePropertyChange("employeeCount", oldEmployeeCount, employeeCount);
    }

    public int getEmployeeCount() {
        return s_employees.size();
    }

    public void setFilter(String filter) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "setFilter",
                  "##############Filter = " + filter);
        String oldFilter = this.filter;
        this.filter = filter;
        propertyChangeSupport.firePropertyChange("filter", oldFilter, filter);
    }

    public String getFilter() {
        return filter;
    }

    public void setCurrentEmp(int currentEmp) {
        int oldCurrentEmp = this.currentEmp;
        this.currentEmp = currentEmp;
        propertyChangeSupport.firePropertyChange("currentEmp", oldCurrentEmp, currentEmp);
    }

    public int getCurrentEmp() {
        return currentEmp;
    }

    public void setNewEmp(boolean newEmp) {
        this.newEmp = newEmp;
    }

    public boolean getNewEmp() {
        return newEmp;
    }

    public void setEditEmployee(Employee editEmployee) {
        this.editEmployee.copy(editEmployee);
    }

    public Employee getEditEmployee() {
        return editEmployee;
    }

    public void setDeleteEmpNo(int deleteEmpNo) {
        int oldDeleteEmpNo = this.deleteEmpNo;
        this.deleteEmpNo = deleteEmpNo;
        propertyChangeSupport.firePropertyChange("deleteEmpNo", oldDeleteEmpNo, deleteEmpNo);
    }

    public int getDeleteEmpNo() {
        return deleteEmpNo;
    }


    ///////////////////////////////////
    //      Utility Methods - Begin
    ///////////////////////////////////

    public Employee getEmployeeById(int empId) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "getEmployeeById",
                  "##############Inside getEmployeeById");
        Employee e = null;

        ArrayList tempEmps = new ArrayList();
        tempEmps = selectEmpsFromDB("EMPLOYEE_ID = " + empId, SORTLNAME, 1);
        if (tempEmps.size() > 0) {
            e = (Employee)tempEmps.get(0);
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "getEmployeeById",
                  "##############getEmployeeById completed");
        return e;
    }

    public ArrayList getEmployeeReports(int empId) {
        ArrayList reports = null;
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "getEmployeeReports",
                  "##############Inside getEmployeeReports");

        reports = selectEmpsFromDB("MANAGER_ID = " + empId, SORTLNAME, ALLRECORDS);
        if(reports == null) {
            reports = new ArrayList();
        }
     
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "getEmployeeReports",
                  "##############getEmployeeReports completed");

        return reports;
    }

    public int getEmployeeReportCount(int empId) {
        int reportCount = 0;

        ArrayList reports = getEmployeeReports(empId);
        reportCount = reports.size();
     
        return reportCount;
    }

    private boolean UpdateReportingToMgr(Employee emp) {
        boolean ret = true;
        Employee[] reports = emp.getReports();
        int mgrID = emp.getManagerId();
        int count = reports.length;
        for (int x = 0; x < count; x++) {
            reports[x].setManagerId(mgrID);
            ret = UpdateEmpToDB(reports[x]);
            if (!ret) {
                break;
            }
        }
        return ret;
    }


    public void calculateMinMaxValues(Employee currEmp) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "calculateMinMaxValues",
                  "##############Inside calculateMinMaxValues");

        ArrayList empsInOrg = new ArrayList();
        empsInOrg = selectEmpsFromDB("DEPARTMENT_ID = " + currEmp.getDepartmentId(), SORTLNAME, ALLRECORDS);

        int count = empsInOrg.size();
        for (int x = 0; x < count; x++) {
            Employee e = (Employee)empsInOrg.get(x);
            double salary = e.getSalary();
            if (e.getDepartmentId() == currEmp.getDepartmentId()) {
                if (salary > currEmp.maxOrgSalary) {
                    currEmp.maxOrgSalary = salary;
                }
                if (salary < currEmp.minOrgSalary) {
                    currEmp.minOrgSalary = salary;
                }
            }
        }
        if (currEmp.maxOrgSalary == currEmp.minOrgSalary) {
            currEmp.minOrgSalary = 0;
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "calculateMinMaxValues",
                  "##############calculateMinMaxValues completed");
    }
    ///////////////////////////////////
    //      Utility Methods - End
    ///////////////////////////////////


    ///////////////////////////////////
    //        DC Methods - Begin
    ///////////////////////////////////

    public void Execute() {
        s_employees.clear();
        String filter = getFilter();
        String whereClause = "";
        if (filter.length() > 0) {
            whereClause += "FIRST_NAME LIKE '%" + filter + "%' OR LAST_NAME LIKE '%" + filter + "%'";
        }
        s_employees = selectEmpsFromDB(whereClause, SORTLNAME, ALLRECORDS);

        providerChangeSupport.fireProviderRefresh("employees");
    }

    public void AddEmployee() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "AddEmployee",
                  "##############Adding Employee");
        int maxId = 0;
        ArrayList lastEmp = new ArrayList();
        lastEmp = selectEmpsFromDB("", SORTIDDESC, 1);
        if (lastEmp.size() > 0) {
            Employee e = (Employee)lastEmp.get(0);
            maxId = e.getId();
        }

        int minId = 0;
        ArrayList firstEmp = new ArrayList();
        firstEmp = selectEmpsFromDB("", SORTID, 1);
        if (firstEmp.size() > 0) {
            Employee e = (Employee)firstEmp.get(0);
            minId = e.getId();
        }
        setEditEmployee(new Employee(maxId + 1, "", "", "", "", new Date(System.currentTimeMillis()), "AD_ASST", 0, 0,
                                     minId, 10, NOPIC, false));
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "AddEmployee",
                  "##############Adding completed");
    }

    public void EditEmployee(int id) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "EditEmployee",
                  "##############Editing Employee");
        int count = getEmployeeCount();
        for (int x = 0; x < count; x++) {
            Employee e = (Employee)s_employees.get(x);
            if (e.id == id) {
                Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "EditEmployee",
                          "##############Found Employee to edit");
                setEditEmployee(e);
                break;
            }
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "EditEmployee",
                  "##############Editing completed");
    }

    public void SaveEmployee() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                  "##############Saving Employee");
        if (newEmp) {
            if (AddEmpToDB()) {
                Employee newEmployee = new Employee(editEmployee);
                Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                          "##############Inserting Employee");
                s_employees.add(0, newEmployee);
                providerChangeSupport.fireProviderCreate("employees", newEmployee.getKey(), newEmployee);
                Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                          "##############Employee inserted");
            }
        } else {
            int count = getEmployeeCount();
            for (int x = 0; x < count; x++) {
                Employee e = (Employee)s_employees.get(x);
                if (e.id == editEmployee.id) {
                    Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                              "##############Found Employee to update");
                    if (UpdateEmpToDB(editEmployee)) {
                        e.copy(editEmployee);
                        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                                  "##############Employee" + e.getFirstName() + " " + e.getLastName() + " Updated");
                        setEditEmployee(e);
                        break;
                    }
                }
            }
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "SaveEmployee",
                  "##############Saving completed");
    }

    public void DeleteEmployee(int id) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmployee",
                  "##############Inside DeleteEmployee");
        int count = getEmployeeCount();
        for (int x = 0; x < count; x++) {
            Employee e = (Employee)s_employees.get(x);
            if (e.id == id) {
                Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmployee",
                          "##############Found Employee to delete");
                if (UpdateReportingToMgr(e)) {
                    if (DeleteEmpFromDB(id)) {
                        setDeleteEmpNo(0);
                        s_employees.remove(x);
                        providerChangeSupport.fireProviderDelete("employees", e.getKey());

                        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmployee",
                                  "##############Employee deleted");
                        break;
                    }
                }
            }
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmployee",
                  "##############DeleteEmployee completed");
    }

    public void fetchPicture() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "savePicture",
                  "##############Inside savePicture");

        DeviceManager dm = DeviceManagerFactory.getDeviceManager();
        int source = dm.CAMERA_SOURCETYPE_CAMERA;

        // If we're in the simulator on iOS, then we'll use the photolibrary
        if (dm.getName().indexOf("Simulator") != -1) {
            source = dm.CAMERA_SOURCETYPE_PHOTOLIBRARY;
        }

        String inFile =
            dm.getPicture(25, dm.CAMERA_DESTINATIONTYPE_FILE_URI, source, false, dm.CAMERA_ENCODINGTYPE_PNG, 56, 55);

        if (inFile != null && inFile.length() > 0) {
            editEmployee.setPic(inFile);
        }
    }


    public void clearPicture() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "clearPicture",
                  "##############Inside clearPicture");

        String picpath = apppath + "/" + editEmployee.getId() + ".png";
        File f = new File(picpath);
        if (f.exists()) {
            f.delete();
        }

        editEmployee.setPic(NOPIC);
    }

    // This method iterates though the collection and turns off any delete buttons except the row swiped

    public void ShowDeleteButton(int id) {
        Employee e = null;
        int count = getEmployeeCount();
        for (int x = 0; x < count; x++) {
            e = (Employee)s_employees.get(x);
            if (e.getId() == id) {
                e.setShowDelete(true);
            } else if (e.isShowDelete()) {
                e.setShowDelete(false);
            }
        }
    }

    // This method clears all delete buttons.  We do this when a delete button exists but someone taps on another row

    public void ClearDeleteButton() {
        Employee e = null;
        int count = getEmployeeCount();
        for (int x = 0; x < count; x++) {
            e = (Employee)s_employees.get(x);
            if (e.isShowDelete()) {
                e.setShowDelete(false);
            }
        }
    }
 
    public void exportContact() {
        AdfException e = new AdfException("Function Not Implemented",AdfException.WARNING);
        throw e;
    }

    ///////////////////////////////////
    //        DC Methods - End
    ///////////////////////////////////


    ///////////////////////////////////
    //    Database Methods - Begin
    ///////////////////////////////////

    private ArrayList selectEmpsFromDB(String filter, String order, int maxRecords) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "selectEmpsFromDB",
                  "##############Inside selectEmpsFromDB");
        ArrayList empList = new ArrayList();

        try {
            Connection conn = DBConnectionFactory.getConnection();
            conn.setAutoCommit(false);
            String select = "SELECT * FROM EMPLOYEES";
            if (filter.length() > 0) {
                select += " WHERE " + filter;
            }
            if (order.length() > 0) {
                select += " ORDER BY " + order;
            }
            if (maxRecords != ALLRECORDS) {
                select += " lIMIT " + maxRecords;
            }
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "selectEmpsFromDB",
                      "##############" + select);
            PreparedStatement pStmt = conn.prepareStatement(select);
            ResultSet rs = pStmt.executeQuery();
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "selectEmpsFromDB",
                      "!!!!!!!!!!!!!!!!!Query Executed!!!!!!!!!!!!!!!!!!!!!!!!!");
            while (rs.next()) {
                int id = rs.getInt("EMPLOYEE_ID");
                String first = rs.getString("FIRST_NAME");
                String last = rs.getString("LAST_NAME");
                String email = rs.getString("EMAIL");
                String phone = rs.getString("PHONE_NUMBER");
                Date hireDate = rs.getDate("HIRE_DATE");
                if (hireDate == null) {
                    hireDate = new Date(0);
                }
             
             
                String jobId = rs.getString("JOB_ID");
                double salary = getDouble(rs, "SALARY");
                double commPct = getDouble(rs, "COMMISSION_PCT");
                int mgrId = rs.getInt("MANAGER_ID");
                int deptId = rs.getInt("DEPARTMENT_ID");
                String emppic = NOPIC;

                String picpath = apppath + "/" + id + ".png";
                File f = new File(picpath);
                if (f != null && f.exists()) {
                    emppic = "file://" + picpath + "?" + System.currentTimeMillis();
                } else {
                    byte[] b = rs.getBytes("PIC");
                    if (b != null && b.length > 0) {
                        FileOutputStream out = new FileOutputStream(picpath);
                        out.write(b);
                        out.close();
                        emppic = "file://" + picpath + "?" + System.currentTimeMillis();
                    }
                }
             
                Employee e =
                    new Employee(id, first, last, email, phone, hireDate, jobId, salary, commPct, mgrId, deptId, emppic,
                                 false);
                empList.add(e);
            }
            rs.close();
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "selectEmpsFromDB",
                      "##############selectEmpsFromDB completed");
        } catch (SQLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "selectEmpsFromDB",
                      "##############Exception:  " + e.getMessage());
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "selectEmpsFromDB",
                      "##############Exception:  " + e.getMessage());
        }
     
        return empList;
    }

    public boolean AddEmpToDB() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "AddEmpToDB",
                  "##############Inside AddEmpToDB");
        boolean ret = false;

        try {
            Connection conn = DBConnectionFactory.getConnection();
            conn.setAutoCommit(false);
            String insertSQL =
                "Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (?,?,?,?,?,?,?,?,?,?,?)";

            PreparedStatement pStmt = conn.prepareStatement(insertSQL);
            pStmt.setInt(1, editEmployee.getId());
            pStmt.setString(2, editEmployee.getFirstName());
            pStmt.setString(3, editEmployee.getLastName());
            pStmt.setString(4, editEmployee.getEmail());
            pStmt.setString(5, editEmployee.getPhoneNumber());
            pStmt.setDate(6, editEmployee.getHireDate());
            pStmt.setString(7, editEmployee.getJobId());
            pStmt.setDouble(8, editEmployee.getSalary());
            pStmt.setDouble(9, editEmployee.getCommissionPct());
            pStmt.setInt(10, editEmployee.getManagerId());
            pStmt.setInt(11, editEmployee.getDepartmentId());
            pStmt.execute();
            conn.commit();
            ret = true;
            savePictureToDB();
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "AddEmpToDB",
                      "##############AddEmpToDB completed");
        } catch (SQLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "AddEmpToDB",
                      "##############Exception:  " + e.getMessage());
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "AddEmpToDB",
                      "##############Exception:  " + e.getMessage());
        }

        return ret;
    }

    public boolean UpdateEmpToDB(Employee emp) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "UpdateEmpToDB",
                  "##############Inside UpdateEmpToDB");
        boolean ret = false;

        try {
            Connection conn = DBConnectionFactory.getConnection();
            conn.setAutoCommit(false);
            String updateSQL =
                "UPDATE EMPLOYEES SET FIRST_NAME=?,LAST_NAME=?,EMAIL=?,PHONE_NUMBER=?,HIRE_DATE=?,JOB_ID=?,SALARY=?,COMMISSION_PCT=?,MANAGER_ID=?,DEPARTMENT_ID=? WHERE EMPLOYEE_ID=?";

            PreparedStatement pStmt = conn.prepareStatement(updateSQL);
            pStmt.setString(1, emp.getFirstName());
            pStmt.setString(2, emp.getLastName());
            pStmt.setString(3, emp.getEmail());
            pStmt.setString(4, emp.getPhoneNumber());
            pStmt.setDate(5, emp.getHireDate());
            pStmt.setString(6, emp.getJobId());
            pStmt.setDouble(7, emp.getSalary());
            pStmt.setDouble(8, emp.getCommissionPct());
            pStmt.setInt(9, emp.getManagerId());
            pStmt.setInt(10, emp.getDepartmentId());
            pStmt.setInt(11, emp.getId());
            pStmt.execute();
            conn.commit();
            ret = true;
            savePictureToDB();
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "UpdateEmpToDB",
                      "##############UpdateEmpToDB completed");
        } catch (SQLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "UpdateEmpToDB",
                      "##############Exception:  " + e.getMessage());
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "UpdateEmpToDB",
                      "##############Exception:  " + e.getMessage());
        }

        return ret;
    }

    public boolean DeleteEmpFromDB(int id) {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmpFromDB",
                  "##############Inside DeleteEmpFromDB");
        boolean ret = false;

        try {
            Connection conn = DBConnectionFactory.getConnection();
            conn.setAutoCommit(false);
            String updateSQL = "DELETE FROM EMPLOYEES WHERE EMPLOYEE_ID=?";

            PreparedStatement pStmt = conn.prepareStatement(updateSQL);
            pStmt.setInt(1, id);
            pStmt.execute();
            conn.commit();
            ret = true;
            Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "DeleteEmpFromDB",
                      "##############DeleteEmpFromDB completed");
        } catch (SQLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "DeleteEmpFromDB",
                      "##############Exception:  " + e.getMessage());
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "DeleteEmpFromDB",
                      "##############Exception:  " + e.getMessage());
        }

        return ret;
    }

    public void savePictureToDB() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, EmployeeList.class, "savePicture",
                  "##############Inside savePicture");
        try {

            Connection conn;
            conn = DBConnectionFactory.getConnection();
            conn.setAutoCommit(false);
            String sql = "UPDATE EMPLOYEES SET PIC=? WHERE EMPLOYEE_ID=?";
            PreparedStatement pStmt = conn.prepareStatement(sql);

            String inFile = editEmployee.getPic();
            if (inFile.compareTo(NOPIC) == 0) {
                pStmt.setNull(1, Types.NULL);
            } else {
                URL u = new URL(inFile);
                FileInputStream in = new FileInputStream(u.getPath());
                byte[] b = new byte[in.available()];
                in.read(b);
                pStmt.setBytes(1, b);
                in.close();
            }
            pStmt.setInt(2, editEmployee.getId());
            pStmt.execute();
            conn.commit();

        } catch (MalformedURLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "savePictureToDB",
                      "##############Exception:  " + e.getMessage());
        } catch (IOException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "savePictureToDB",
                      "##############Exception:  " + e.getMessage());
        } catch (SQLException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "savePictureToDB",
                      "##############Exception:  " + e.getMessage());
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "savePictureToDB",
                      "##############Exception:  " + e.getMessage());
        }
    }

    ///////////////////////////////////
    //    Database Methods - End
    ///////////////////////////////////
    private double getDouble(ResultSet rs, String column) throws SQLException {
        if(rs != null) {
            String temp = rs.getString(column);
         
            if(Utility.isNotEmpty(temp)) {
                return Double.parseDouble(temp);
            }
        }
        return 0.0d;
    }

}

7. HRBean.java 代码

package mobile;

import application.LifeCycleListenerImpl;

import com.sun.util.logging.Level;

import javax.el.MethodExpression;

import javax.el.ValueExpression;

import oracle.adfmf.amx.event.ActionEvent;
import oracle.adfmf.amx.event.SelectionEvent;
import oracle.adfmf.framework.api.AdfmfJavaUtilities;
import oracle.adfmf.java.beans.PropertyChangeListener;
import oracle.adfmf.java.beans.PropertyChangeSupport;
import oracle.adfmf.util.Utility;
import oracle.adfmf.util.logging.Trace;

public class HRBean {
    private String detailtab = "profile";
    private String metrictab = "salary";
    private String orgtab = "byname";
    private boolean searchOn = false;
    private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    public HRBean() {
    }

    public void DeleteHandler(ActionEvent actionEvent) {
        try {
        ValueExpression ve1 =
            AdfmfJavaUtilities.getValueExpression("#{bindings.currentEmp.inputValue}", Integer.class);
        Integer currentEmp = (Integer)ve1.getValue(AdfmfJavaUtilities.getAdfELContext());

        ValueExpression ve2 =
            AdfmfJavaUtilities.getValueExpression("#{bindings.deleteEmpNo.inputValue}", Integer.class);
        Integer deleteNo = (Integer)ve2.getValue(AdfmfJavaUtilities.getAdfELContext());

        MethodExpression me1 =
            AdfmfJavaUtilities.getMethodExpression("#{bindings.DeleteEmployee.execute}", Object.class,
                                                   new Class[] { });
        me1.invoke(AdfmfJavaUtilities.getAdfELContext(), new Object[] { });

        if (currentEmp.intValue() == deleteNo.intValue()) {
            MethodExpression me2 =
                AdfmfJavaUtilities.getMethodExpression("#{bindings.Previous.execute}", Object.class, new Class[] { });
            me2.invoke(AdfmfJavaUtilities.getAdfELContext(), new Object[] { });
        }
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "savePictureToDB",
                      "##############Exception:  " + e.getMessage());
        }

    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        propertyChangeSupport.removePropertyChangeListener(l);
    }

    public void setDetailtab(String detailtab) {
        String oldDetailtab = this.detailtab;
        this.detailtab = detailtab;
        propertyChangeSupport.firePropertyChange("detailtab", oldDetailtab, detailtab);
    }

    public String getDetailtab() {
        return detailtab;
    }

    public void setMetrictab(String metrictab) {
        String oldMetrictab = this.metrictab;
        this.metrictab = metrictab;
        propertyChangeSupport.firePropertyChange("metrictab", oldMetrictab, metrictab);
    }

    public String getMetrictab() {
        return metrictab;
    }

    public void setOrgtab(String orgtab) {
        String oldOrgtab = this.orgtab;
        this.orgtab = orgtab;
        propertyChangeSupport.firePropertyChange("orgtab", oldOrgtab, orgtab);
    }

    public String getOrgtab() {
        return orgtab;
    }

    public void setSearchOn(boolean searchOn) {
        boolean oldSearchOn = this.searchOn;
        this.searchOn = searchOn;
        propertyChangeSupport.firePropertyChange("searchOn", oldSearchOn, searchOn);
    }

    public boolean isSearchOn() {
        return searchOn;
    }

    public void orgMapSelectionHandler(SelectionEvent selectionEvent) {
        MethodExpression me = AdfmfJavaUtilities.getMethodExpression("#{bindings.setCurrentRowWithKeyValue.execute}", Object.class, new Class[] {});
        me.invoke(AdfmfJavaUtilities.getAdfELContext(), new Object[] {});
    }

    public void exportContactHandler(ActionEvent actionEvent) {
        // Add event code here...
    }
}

8. LifeCycleListenerImpl.java 代码,在应用首次启动时,调用copyDB()拷贝数据库文件HR.db

package application;

import com.sun.util.logging.Level;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;
import java.util.List;

import javax.el.ValueExpression;

import oracle.adfmf.application.LifeCycleListener;
import oracle.adfmf.framework.api.AdfmfJavaUtilities;
import oracle.adfmf.util.Utility;
import oracle.adfmf.util.logging.Trace;

public class LifeCycleListenerImpl implements LifeCycleListener {
    public LifeCycleListenerImpl() {
    }

    /**
     * The start method will be called at the start of the application. Only the
     * Application Lifecycle Event listener will be called on start up.
     */
    public void start() {
        Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "start",
                  "##############App Start");
        try {
            Statement stat = DBConnectionFactory.getConnection().createStatement();
            ResultSet rs = stat.executeQuery("SELECT PIC FROM EMPLOYEES;");
        } catch (SQLException e) {
            // if the error message is "out of memory",
            // it probably means no database file is found
            Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "start",
                      "##############Database does not exist, creating it");
            //            InitDB();
            copyDB();
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "start",
                      "##############Exception:  " + e.getMessage());
        }
        Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "start",
                  "##############App Start Complete");
    }

    /**
     * The stop method will be called at the termination of the application. Only
     * the Application Lifecycle Event listener will be called on start up.
     *
     * NOTE: Depending on how the application is being shutdown, this method may
     * or may not be called. Features should save off their state in the deactivate
     * handler.
     */
    public void stop() {
        // Add code here...
    }

    /**
     * The activate method will be called when the feature is activated. The
     * Application Lifecycle Event listener will be called on application
     * being started and resumed.
     */
    public void activate() {
        // Add code here...
    }

    /**
     * The deactivate method will be called when the feature is deactivated. The
     * Application Lifecycle Event listener will be called on application
     * being hibernated.
     */
    public void deactivate() {
        // Add code here...
    }

    private void copyDB() {
        try {
            Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "copyDB",
                      "##############copyDB Start");
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            InputStream in = cl.getResourceAsStream(".adf/META-INF/HR.db");
            String outFile =
                AdfmfJavaUtilities.getDirectoryPathRoot(AdfmfJavaUtilities.ApplicationDirectory) + "/HR.db";

            // blank out the DB file if its already there before we copy it.
            // We do this in a scoped section so that the File goes out of scope and releases itself
            {
                File f = new File(outFile);
                if( f!= null && f.exists() ) {
                    f.createNewFile();
                }
            }
             
            FileOutputStream out = new FileOutputStream(outFile);

            int b;
            do {
                b = in.read();
                if (b != -1) {
                    out.write(b);
                }
            } while (b != -1);
            in.close();
            out.close();

            Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "InitDB",
                      "##############InitDB Complete");
        } catch (FileNotFoundException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "copyDB",
                      "##############Exception:  " + e.getMessage());
        } catch (IOException e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "copyDB",
                      "##############Exception:  " + e.getMessage());
        }

    }

    private void InitDB() {
        try {
            Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "InitDB",
                      "##############initDB Start");
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            InputStream is = cl.getResourceAsStream(".adf/META-INF/hr.sql");
            if (is == null) {
                Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "InitDB",
                          "##############Could not look up : /META-INF/hr.sql");
                return;
            }

            BufferedReader bReader = new BufferedReader(new InputStreamReader(is));
            List stmts = new ArrayList();
            String strstmt = "";
            String ln = bReader.readLine();
            while (ln != null) {
                if (ln.startsWith("REM") || ln.startsWith("COMMIT")) {
                    ln = bReader.readLine();
                    continue;
                }
                strstmt = strstmt + ln;
                if (strstmt.endsWith(";")) {
                    Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "InitDB",
                              "##############" + strstmt);
                    stmts.add(strstmt);
                    strstmt = "";
                    ln = bReader.readLine();
                    continue;
                }
                ln = bReader.readLine();

            }

            DBConnectionFactory.getConnection().setAutoCommit(false);
            for (int i = 0; i < stmts.size(); i++) {
                Statement pStmt = DBConnectionFactory.getConnection().createStatement();
                pStmt.executeUpdate((String)stmts.get(i));

            }
            DBConnectionFactory.getConnection().commit();
            Trace.log(Utility.ApplicationLogger, Level.INFO, LifeCycleListenerImpl.class, "InitDB",
                      "##############InitDB Complete");
        } catch (Exception e) {
            Trace.log(Utility.ApplicationLogger, Level.SEVERE, LifeCycleListenerImpl.class, "InitDB",
                      "##############Exception:  " + e.getMessage());
        }

    }

}

9. DBConnectionFactory.java 代码,数据库连接工厂,获取数据库连接

package application;

import java.sql.Connection;
import java.sql.SQLException;

import oracle.adfmf.framework.api.AdfmfJavaUtilities;

public class DBConnectionFactory {
    public DBConnectionFactory() {
        super();
    }
    
    protected static Connection conn = null;

    public static Connection getConnection() throws Exception {
        if (conn == null) {
            try {
                // create a database connection
                String Dir = AdfmfJavaUtilities.getDirectoryPathRoot(AdfmfJavaUtilities.ApplicationDirectory);
                String connStr = "jdbc:sqlite:" + Dir + "/HR.db";
                conn = new SQLite.JDBCDataSource(connStr).getConnection();
            } catch (SQLException e) {
                // if the error message is "out of memory",
                // it probably means no database file is found
                System.err.println(e.getMessage());
            }
        }
        return conn;
    }
    
}

没有评论: