com.pureinfo.studio.db.xls2srm.impl.XlsImportRunner.java Source code

Java tutorial

Introduction

Here is the source code for com.pureinfo.studio.db.xls2srm.impl.XlsImportRunner.java

Source

/**
 * PureInfo Quake
 * @(#)XlsImportRunner.java   1.0 2005-9-20
 * 
 * Copyright(c) 2004-2005, PureInfo Information Technology Corp. Ltd. 
 * All rights reserved, see the license file.
 * 
 * www.pureinfo.com.cn
 */

package com.pureinfo.studio.db.xls2srm.impl;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.dom4j.Element;

import com.pureinfo.ark.content.ArkContentHelper;
import com.pureinfo.ark.content.domain.IContentMgr;
import com.pureinfo.ark.content.model.ArkContent;
import com.pureinfo.dolphin.DolphinHelper;
import com.pureinfo.dolphin.context.LocalContextHelper;
import com.pureinfo.dolphin.mapping.EntityMetadata;
import com.pureinfo.dolphin.mapping.PropertyMetadata;
import com.pureinfo.dolphin.model.DolphinObject;
import com.pureinfo.dolphin.model.DolphinUtil;
import com.pureinfo.dolphin.model.IObjects;
import com.pureinfo.dolphin.persister.ISession;
import com.pureinfo.dolphin.persister.IStatement;
import com.pureinfo.force.PureFactory;
import com.pureinfo.force.PureSystem;
import com.pureinfo.force.encrypt.PasswordEncrypter;
import com.pureinfo.force.exception.PureException;
import com.pureinfo.force.lang.NumberUtil;
import com.pureinfo.force.lang.StrUtil;
import com.pureinfo.force.object.DataTypes;
import com.pureinfo.force.xml.XMLUtil;
import com.pureinfo.importer.ref.IImportorRef;
import com.pureinfo.srm.SRMConstants;
import com.pureinfo.srm.xls2srm.model.Xls2srmForm;
import com.pureinfo.studio.db.xls2srm.IConvert2RelativeTable;
import com.pureinfo.studio.db.xls2srm.ImportReturnData;

/**
 * <P>
 * Created on 2005-9-20 13:17:26 <BR>
 * Last modified on 2005-9-20
 * </P>
 * XlsImportRunner: export SRMUser from old RWSK database.
 * 
 * @author Why
 * @version 1.0, 2005-9-20
 * @since Quake 1.0
 */
public class XlsImportRunner {
    // logger
    private final static Logger logger = Logger.getLogger(XlsImportRunner.class.getName());

    private EntityMetadata m_entityMetadata;

    // connection provider
    private String m_sProvider;

    // configuration
    private Element m_xmlConfig;

    private List m_returnData = new ArrayList();

    private List m_returnDataTitles = new ArrayList();

    private List m_returnDataRelatedPropties = new ArrayList();

    // runtime cache
    private ISession m_sessionFrom;

    private ISession m_sessionTo;

    /**
     * Constructor
     */
    public XlsImportRunner() {
        super();
    }

    /**
     * Constructor
     * 
     * @param _sProvider
     *            connection provider
     */
    public XlsImportRunner(String _sProvider) {
        this.setProvider(_sProvider);
    }

    /**
     * Returns the provider.
     * 
     * @return the provider.
     */
    public String getProvider() {
        return m_sProvider;
    }

    /**
     * Sets the provider.
     * 
     * @param _sProvider
     *            the provider to set.
     */
    public void setProvider(String _sProvider) {
        m_sProvider = _sProvider;
    }

    public void config(Element _xmlConfig) throws PureException {
        m_xmlConfig = _xmlConfig;
        String sClass = m_xmlConfig.attributeValue("class");
        m_entityMetadata = DolphinHelper.lookupEntityMetadataByName(sClass, true);
    }

    public void clear() {
        if (m_sessionFrom != null) {
            m_sessionFrom.closeQuietly(System.err);
        }
        if (m_sessionTo != null) {
            m_sessionTo.closeQuietly(System.err);
        }
    }

    /**
     * 
     * @throws Exception
     */
    public int run(String _sFileName, List _errorDataList, List _repeatList) throws PureException {

        return run(_sFileName, _errorDataList, _repeatList, false, Xls2srmForm.JUSTFORCHECK);
    }

    /**
     * 
     * @throws Exception
     */
    public int run(String _sFileName, List _errorDataList, List _repeatList, boolean _bBreakenIfError,
            int _nChooseIfRepeat) throws PureException {

        if (m_xmlConfig == null) {
            throw new PureException(PureException.SETTING_MISSING, "please call config() first");
        }

        long lStart = System.currentTimeMillis();
        IObjects objs = null;
        DolphinObject oldObj, newObj;
        Class clazz = m_entityMetadata.getEntityClass();
        int nCount = 1;

        try {
            prepare();

            objs = this.loadOld(_sFileName);

            String sViewProperty = m_xmlConfig.attributeValue("view-property");
            if (sViewProperty == null || (sViewProperty = sViewProperty.trim()).length() == 0) {
                sViewProperty = "ID";
            } else {
                sViewProperty = sViewProperty.toUpperCase();
            }

            while ((oldObj = objs.next()) != null) {
                List errorDataEachList = new ArrayList();
                StringBuffer error = new StringBuffer();

                if (checkObjIsNull(oldObj, sViewProperty))
                    continue;

                oldObj = ChangePropertysToString(oldObj, sViewProperty);

                System.out.println("[" + nCount + "]to process " + clazz.getName() + "-"
                        + oldObj.getPropertyAsString(sViewProperty) + "... ");
                //it will be checked in the last,so at the beganning ,we will
                // new an instance.
                newObj = (DolphinObject) clazz.newInstance();

                beforeCopy(newObj);

                copy(oldObj, newObj, errorDataEachList);

                if (errorDataEachList != null) {
                    if (errorDataEachList.size() > 0) {
                        error.append("" + nCount + ":");
                        for (int i = 0; i < errorDataEachList.size(); i++) {
                            error.append(errorDataEachList.get(i));
                        }
                    }
                    errorDataEachList.clear();
                }

                convert(oldObj, newObj, errorDataEachList, _nChooseIfRepeat);

                if (errorDataEachList != null) {
                    if (errorDataEachList.size() > 0) {
                        if (error.length() <= 0)
                            error.append("" + nCount + ":");
                        for (int i = 0; i < errorDataEachList.size(); i++) {
                            error.append(errorDataEachList.get(i) + ",");
                        }
                    }
                    errorDataEachList.clear();
                }

                String errorEach = (error.length() > 0 ? error.toString() : "");

                fill(oldObj, newObj, _nChooseIfRepeat);

                //====wind.li@2007-04-29
                //=====BEGIN===========
                errorDataEachList = checkMaybeRequiredCells(oldObj);

                if (errorDataEachList != null) {
                    for (int i = 0; i < errorDataEachList.size(); i++) {
                        error.append("" + nCount + ":").append(errorDataEachList.get(i) + "");
                    }
                    errorDataEachList.clear();
                }
                //====END===========

                conversAuthors2insideAuthorInfo(newObj, oldObj);

                if (errorDataEachList == null)
                    errorDataEachList = new ArrayList();
                beforeSave(newObj, errorDataEachList);

                if (errorDataEachList != null) {
                    for (int i = 0; i < errorDataEachList.size(); i++) {
                        String errorElement = errorDataEachList.get(i).toString();
                        if (errorEach.indexOf(errorElement) > 0) {
                            errorDataEachList.remove(errorElement);
                        }
                    }
                }
                if (errorDataEachList != null) {
                    if (errorDataEachList.size() > 0) {
                        if (error.length() <= 0)
                            error.append("" + nCount + ":");
                        for (int i = 0; i < errorDataEachList.size(); i++) {
                            error.append(errorDataEachList.get(i) + " ");
                        }
                    }
                    errorDataEachList.clear();
                }

                convert2RelatedTable(newObj, oldObj, true, errorDataEachList, Xls2srmForm.COVERDATAWHENREPEAT);
                if (errorDataEachList != null) {
                    if (errorDataEachList.size() > 0) {
                        if (error.length() <= 0)
                            error.append("" + nCount + ":");
                        for (int i = 0; i < errorDataEachList.size(); i++) {
                            error.append(errorDataEachList.get(i));
                        }
                    }
                    errorDataEachList.clear();
                }

                if (error.length() > 0) {
                    _errorDataList.add(error.toString());
                }

                if (error.length() > 0) {
                    error.setLength(0);
                    if (_bBreakenIfError) {
                        logger.debug("" + nCount + "");
                        break;
                    }

                    // logger.debug("" + nCount + "");
                    nCount++;
                    continue;

                }
                error.setLength(0);

                if (_nChooseIfRepeat == Xls2srmForm.JUSTFORCHECK) {
                    //newObj = makeNewObject2(clazz, newObj,
                    // Xls2srmForm.COVERDATAWHENREPEAT);
                } else {
                    newObj = makeNewObject2(clazz, newObj, _nChooseIfRepeat);
                }
                if (newObj == null) {
                    if (_nChooseIfRepeat == Xls2srmForm.MERGEDATAWHENREPEAT) {
                        _repeatList.add("" + nCount + "!");
                    } else {
                        _repeatList.add("" + nCount + "!");
                    }
                    nCount++;
                    continue;
                }

                if (_nChooseIfRepeat != Xls2srmForm.JUSTFORCHECK) {

                    save(newObj);

                    convert2RelatedTable(newObj, oldObj, false, errorDataEachList, _nChooseIfRepeat);
                }

                // wind.li@2007-05-08 
                // BEGIN:
                List[] data = (List[]) newObj.getProperty("list");
                if (data != null && data.length > 0) {
                    boolean bReturn = false;
                    for (int i = 0; i < data.length; i++) {
                        if (data[i] != null || data[i].size() > 1) {
                            bReturn = true;
                            break;
                        }
                    }
                    int nId = newObj.getIntProperty("id", 0);
                    if (bReturn && nId > 0) {
                        DolphinObject obj = new DolphinObject();
                        obj.setProperty("id", nId);
                        //                        System.out.println("id:" + newObj.getIntProperty("id", 0));
                        obj.setProperty("data", data);
                        m_returnData.add(obj);
                    }
                }
                // END

                nCount++;

            } // endwhile
            lastUpdate();

            long lEnd = System.currentTimeMillis();
            System.out.println(clazz.getName() + ": all finished - time used: " + (lEnd - lStart) + "ms");
        } catch (Exception ex) {
            throw new PureException(PureException.DATABASE_ACCESS, "class=" + clazz.getName(), ex);
        } finally {
            if (objs != null)
                objs.clear();
        }
        return nCount - 1;
    }

    // =========================================================================
    // inside logic

    /**
     * @param _sOldObj
     * @param _sViewProperty
     * @throws PureException
     */
    private boolean checkObjIsNull(DolphinObject _sOldObj, String _sViewProperty) throws PureException {

        _sOldObj.removeProperty(_sViewProperty);
        Iterator itr = _sOldObj.getProperties(false).entrySet().iterator();
        Object oKey, oValue = null;
        boolean bIsNull = true;
        while (itr.hasNext()) {
            Map.Entry entry = (Map.Entry) itr.next();
            oKey = entry.getKey();
            oValue = _sOldObj.getProperty(oKey.toString());

            if (oValue != null) {

                bIsNull = false;

            }
        }
        return bIsNull;

    }

    /**
     * @param _sOldObj
     * @param _sViewProperty
     * @throws PureException
     */
    private DolphinObject ChangePropertysToString(DolphinObject _sOldObj, String _sViewProperty)
            throws PureException {

        _sOldObj.removeProperty(_sViewProperty);
        Iterator itr = _sOldObj.getProperties(false).entrySet().iterator();
        Object oKey, oValue = null;
        while (itr.hasNext()) {
            Map.Entry entry = (Map.Entry) itr.next();
            oKey = entry.getKey();
            oValue = _sOldObj.getProperty(oKey.toString());

            if (oValue != null) {

                if (oValue instanceof Double) {
                    oValue = NumberUtil.format(((Number) oValue), "#");
                    logger.debug(":" + oValue);
                }

                if (oValue instanceof Date) {
                    Date datDate = (Date) oValue;
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    oValue = new String(format.format(datDate));
                    logger.debug(":" + oValue);
                }

                if (oValue instanceof Long) {
                    oValue = NumberUtil.format(((Number) oValue), "#");
                    logger.debug(":" + oValue);
                }

                if (oValue instanceof Boolean) {
                    if (oValue.equals(Boolean.FALSE))
                        oValue = "false";

                    if (oValue.equals(Boolean.TRUE))
                        oValue = "true";

                    logger.debug(":" + oValue);
                }

                _sOldObj.setProperty(oKey.toString(), oValue);
            }
        }
        return _sOldObj;

    }

    /**
     * @param _newObj
     * @param _oldObj
     * @throws Exception
     */
    private void conversAuthors2insideAuthorInfo(DolphinObject _newObj, DolphinObject _oldObj) throws Exception {
        Element convert = m_xmlConfig.element("data");
        List properties = convert.element("convert").elements();
        Element element;
        String sFrom, value, sProvider = null;

        for (int i = 0; i < properties.size(); i++) {

            element = (Element) properties.get(i);
            sProvider = element.attributeValue("provider");
            if (sProvider == null || (!(sProvider.equals("authors2insideAuthorInfoForHonor")
                    || (sProvider.equals("authors2insideAuthorInfo")))))
                continue;
            // to input the productId infor just for honor
            //            if (_oldObj.hasProperty(sProductName.toUpperCase()) &&
            // sProvider.equals("authors2insideAuthorInfoForHonor")) {
            //                Object _ProductIdValue =
            // this.lookupRefValue("SRM_PRJ_PRODUCT.PRODUCT_ID", _oldObj
            //                        .getProperty(sProductName.toUpperCase()), "PRODUCT_NAME");
            //                if (_ProductIdValue != null) _newObj.setProperty("productId",
            // _ProductIdValue);
            //                _newObj.setProperty("productId", 0);
            //            }
            //to convert the insideauthor information!

            sFrom = element.attributeValue("from").toUpperCase();

            if (!_oldObj.hasProperty(sFrom)) {
                continue;
                // throw new PureException(PureException.PROPERTY_NOTFOUND,
                // sFrom);
            }

            // else

            value = _oldObj.getStrProperty(sFrom);
            String[] perValue = value.split(PureSystem.getProperty("srm.xls2srm.split.authors"));
            _newObj.setProperty("authorsNum", perValue.length);

            int authorNamePos = perValue[0].indexOf(PureSystem.getProperty("srm.xls2srm.split.authorType.began"));

            if (authorNamePos >= 0) {
                _newObj.setProperty("authorName", perValue[0].substring(0, authorNamePos));
                _newObj.setProperty("authorId", 0);
                if (perValue[0].endsWith(PureSystem.getProperty("srm.xls2srm.exunit") + ""
                        + PureSystem.getProperty("srm.xls2srm.split.authorType.end"))) {
                    _newObj.setProperty("authorType", SRMConstants.PRODUCT_AUTHOR_TYPE_EXTERNAL);
                } else {
                    if (perValue[0].endsWith(PureSystem.getProperty("srm.xls2srm.student") + ""
                            + PureSystem.getProperty("srm.xls2srm.split.authorType.end"))) {
                        _newObj.setProperty("authorType", SRMConstants.PRODUCT_AUTHOR_TYPE_STUDENT);
                    } else {
                        logger.debug("unknow author Type");
                    }
                }
            } else {
                _newObj.setProperty("authorName", perValue[0]);
                Object authorId = this.lookupRefValue("srm_auth_user.USER_ID", perValue[0], "TRUE_NAME");
                if (authorId != null) {
                    _newObj.setProperty("authorId", authorId);
                    _newObj.setProperty("authorType", SRMConstants.PRODUCT_AUTHOR_TYPE_TEACHER);
                } else {
                    _newObj.setProperty("authorId", new Integer(0));
                    _newObj.setProperty("authorType", SRMConstants.PRODUCT_AUTHOR_TYPE_EXTERNAL);
                }
            }

            try {
                for (int j = 0; j < perValue.length; j++) {
                    String perUnitValue = perValue[j];
                    int pos = perUnitValue.indexOf(PureSystem.getProperty("srm.xls2srm.split.authorType.began"));

                    if (pos > 0) {
                        continue;
                    }
                    int count = j + 1;

                    Object authorId = this.lookupRefValue("srm_auth_user.USER_ID", perUnitValue, "TRUE_NAME");
                    if (authorId != null) {
                        _newObj.setProperty("insideAuthorNo", count);
                        _newObj.setProperty("insideAuthorId", authorId);
                        break;
                    }
                }
            } catch (Exception ex) {
                throw new PureException(PureException.INVALID_VALUE,
                        "convert " + sFrom + "[" + perValue.toString() + "] to " + "insideAuthorInfo", ex);
            }
        }

    }

    /**
     * @param _sNewObj
     * @throws PureException
     */
    private void convert2RelatedTable(DolphinObject _newObj, DolphinObject _oldObj, boolean _bCheck,
            List _errorDataEachList, int _nChooseIfRepeat) throws PureException {

        Element convert = m_xmlConfig.element("data");
        List properties = convert.element("convert").elements();
        Element element;
        // Element element =convert.element("convert");
        String sFrom, sClass, sId, sRelativeFrom, sRelativeTo, sRef, sFk, sRelativeInterface;
        for (int i = 0; i < properties.size(); i++) {

            element = (Element) properties.get(i);
            String sProvider = element.attributeValue("provider");
            if (sProvider == null || sProvider.equals("authors2insideAuthorInfoForHonor")
                    || sProvider.equals("authors2insideAuthorInfo") || sProvider.equals("to"))
                continue;
            sFrom = element.attributeValue("from").toUpperCase();
            sRelativeInterface = element.attributeValue("provider");
            sClass = element.attributeValue("relativeClass");
            sId = element.attributeValue("relativeId");
            sRelativeFrom = element.attributeValue("relativeFrom");
            sRelativeTo = element.attributeValue("relativeTo");
            sRef = element.attributeValue("ref");
            sFk = element.attributeValue("fk");

            //          to convert property value
            if (!_oldObj.hasProperty(sFrom)) {
                continue;
                // throw new PureException(PureException.PROPERTY_NOTFOUND,
                // sFrom);
            }

            // else
            try {
                Class clazz = Class.forName(sClass);
                IConvert2RelativeTable conv2relative = (IConvert2RelativeTable) PureFactory
                        .getBean(sRelativeInterface);
                if (_bCheck) {
                    conv2relative.check(sFrom, _oldObj.getProperty(sFrom), sRef, sFk, _errorDataEachList);
                } else {
                    if (_nChooseIfRepeat == Xls2srmForm.COVERDATAWHENREPEAT) {
                        conv2relative.delete(_newObj, sId, clazz);
                    }
                    conv2relative.save(_newObj, _oldObj.getProperty(sFrom), clazz, sId, sRelativeFrom, sRelativeTo,
                            sRef, sFk);
                }
            } catch (Exception ex) {
                throw new PureException(PureException.INVALID_VALUE,
                        "convert " + sFrom + "[" + _oldObj.getProperty(sFrom) + "] to " + sClass, ex);
            }
        }
    }

    private DolphinObject makeNewObject2(Class _clazz, DolphinObject _newObj, int _nChooseIfRepeat)
            throws Exception {
        DolphinObject newObj = null;
        boolean bStringProperty;
        String strSQL = m_xmlConfig.elementTextTrim("match-properties");
        if (strSQL != null && strSQL.length() > 0) {
            StringTokenizer st = new StringTokenizer(strSQL, ",", false);
            StringBuffer sbuff = new StringBuffer("select * from {this} where ");
            int startlength = sbuff.length();
            boolean allNull;
            try {
                String sValue;
                while (st.hasMoreElements()) {
                    sValue = (String) st.nextElement();
                    if (_newObj.getProperty(sValue) != null) {
                        sbuff.append("{this.");
                        sbuff.append(sValue);
                        sbuff.append("}=");
                        bStringProperty = _newObj.getProperty(sValue) instanceof String
                                || _newObj.getProperty(sValue) instanceof Date;
                        if (bStringProperty)
                            sbuff.append("'");
                        sbuff.append(_newObj.getPropertyAsString(sValue));
                        if (bStringProperty)
                            sbuff.append("'");
                        sbuff.append(" and ");
                    }
                }
                allNull = startlength == sbuff.length();
                int nLength = sbuff.length() - 5;
                sbuff.setLength(nLength);
                strSQL = sbuff.toString();
            } finally {
                sbuff.setLength(0);
            }
            if (!allNull) {
                logger.debug("to find existing object: " + strSQL);
                ISession session = getSession();
                IStatement query = session.createQuery(strSQL, _clazz, 1);
                IObjects objs = null;
                try {
                    objs = query.executeQuery();
                    newObj = objs.next();
                } finally {
                    DolphinHelper.clear(objs, query);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("existing object: " + newObj);
                }
            }
        }

        if (newObj == null) {
            newObj = _newObj;
        } else {

            switch (_nChooseIfRepeat) {
            // 
            case Xls2srmForm.NEWDATAWHENREPEAT:
                newObj = _newObj;
                break;
            // 
            case Xls2srmForm.LEAPDATAWHENREPEAT:
                newObj = null;
                break;
            //     
            case Xls2srmForm.COVERDATAWHENREPEAT:
                String sExcludeProps = m_xmlConfig.elementTextTrim("exclude-props-overrite");
                if (sExcludeProps == null || sExcludeProps.length() == 0) {
                    DolphinUtil.copyUpdateableProperties(_newObj, newObj);
                } else {
                    Iterator iter = _newObj.getProperties(false).entrySet().iterator();
                    sExcludeProps = ',' + sExcludeProps + ',';
                    while (iter.hasNext()) {
                        Map.Entry entry = (Map.Entry) iter.next();
                        String sName = (String) entry.getKey();
                        if (entry.getValue() != null && sExcludeProps.indexOf("," + sName + ",") < 0) {
                            newObj.setProperty(sName, entry.getValue());
                        }
                    }
                }
                break;
            // 
            case Xls2srmForm.MERGEDATAWHENREPEAT: {
                String strMatchSQL = m_xmlConfig.elementTextTrim("merge-properties");
                if (strMatchSQL != null && strMatchSQL.length() > 0) {
                    StringTokenizer st2 = new StringTokenizer(strMatchSQL, ",", false);
                    String sValue2;
                    while (st2.hasMoreElements()) {
                        sValue2 = (String) st2.nextElement();
                        if (_newObj.getProperty(sValue2) != null) {
                            newObj.setProperty(sValue2, _newObj.getProperty(sValue2));
                        }
                    }
                }
                //newObj.update();
                break;
            }
            default:
                throw new PureException(PureException.INVALID_VALUE, "");
            }

        }
        return newObj;

    }

    private ISession getSession() throws Exception {
        if (m_sessionFrom == null) {
            m_sessionFrom = LocalContextHelper.currentSession(m_sProvider);
        }
        return m_sessionFrom;
    }

    private void prepare() throws Exception {
        this.executeSQLElement("prepare");
    }

    /**
     * Loads the old objects collection.
     * 
     * @return the old objects collection
     * @throws Exception
     */
    private IObjects loadOld(String _sFileName) throws PureException {
        XlsObjectsImpl objs = new XlsObjectsImpl(_sFileName);

        return objs;
    }

    /**
     * @param _sHeads
     * @throws PureException
     */
    private List checkExcelHead(String[] _sHeads) throws PureException {

        List needHeadList = new ArrayList();
        List sHeadList = new ArrayList();
        List lostHeadList = new ArrayList();
        String _sRequiredCells;
        String[] _sRequiredCellsSplit;
        try {

            _sRequiredCells = m_xmlConfig.elementTextTrim("required-cells");
            logger.debug(_sRequiredCells);
            _sRequiredCellsSplit = StrUtil.split(_sRequiredCells, ",");
            for (int i = _sRequiredCellsSplit.length - 1; i > 0; i--) {
                logger.debug(_sRequiredCellsSplit[i]);
                needHeadList.add(_sRequiredCellsSplit[i]);
            }

            for (int i = _sHeads.length - 1; i >= 0; i--) {
                sHeadList.add(_sHeads[i]);
            }

            for (int i = needHeadList.size(); i > 0; i--) {
                if (!sHeadList.contains(needHeadList.get(i - 1))) {
                    lostHeadList.add(needHeadList.get(i - 1));
                }
            }

            return lostHeadList;
        } finally {
            if (needHeadList != null)
                needHeadList.clear();
            if (sHeadList != null)
                sHeadList.clear();
        }
    }

    /**
     * wind.li@2007-04-29
     * 
     * 
     * 
     * @return
     */
    private List checkMaybeRequiredCells(DolphinObject _old) throws PureException {
        Element element = m_xmlConfig.element("maybe-required-cells");
        if (element == null)
            return null;
        List cells = element.elements();
        if (cells == null)
            return null;
        Element ele;
        List lostCellList = new ArrayList();
        for (Iterator iter = cells.iterator(); iter.hasNext();) {
            ele = (Element) iter.next();
            Element eleCellName = ele.element("name");
            if (eleCellName == null) {
                throw new PureException(PureException.PROPERTY_VALUE_REQUIRED, "<cell><name>");
            }
            String sCellName = eleCellName.getTextTrim();

            Element eleConditions = ele.element("conditions");
            if (eleConditions == null) {
                if (_old.getProperty(sCellName) == null) {
                    lostCellList.add(sCellName);
                    continue;
                }
            }
            List conditions = eleConditions.elements("condition");
            if (conditions == null || conditions.size() == 0) {
                if (_old.getProperty(sCellName) == null) {
                    lostCellList.add(sCellName);
                    continue;
                }
            }
            for (Iterator iter2 = conditions.iterator(); iter2.hasNext();) {
                Element condition = (Element) iter2.next();
                Element eleCell = condition.element("cell");
                if (eleCell == null) {
                    throw new PureException(PureException.PROPERTY_VALUE_REQUIRED,
                            "<cell>(name = " + sCellName + ")<condition><cell>");
                }
                Element eleOperator = condition.element("operator");
                if (eleOperator == null) {
                    throw new PureException(PureException.PROPERTY_VALUE_REQUIRED,
                            "<cell>(name = " + sCellName + ")<condition><operator>");
                }
                Element eleValue = condition.element("value");
                if (eleValue == null) {
                    throw new PureException(PureException.PROPERTY_VALUE_REQUIRED,
                            "<cell>(name = " + sCellName + ")<condition><value>");
                }
                String sCell = eleCell.getTextTrim();
                String sOperator = eleOperator.getTextTrim().toUpperCase();
                String sValue = eleValue.getTextTrim();
                String sCellValue = _old.getPropertyAsString(sCell);
                if (sCellValue != null && sCellValue.trim().length() > 0) {
                    if ("IN".equals(sOperator)) {
                        if (sValue != null && sValue.indexOf("," + sCellValue + ",") != -1) {
                            if (_old.getProperty(sCellName) == null) {
                                lostCellList.add(sCellName);
                                continue;
                            }
                        }
                    }
                    if ("EQUAL".equals(sOperator)) {
                        if (sValue != null && sValue.equals(sCellValue)) {
                            if (_old.getProperty(sCellName) == null) {
                                lostCellList.add(sCellName);
                                continue;
                            }
                        }
                    }
                }
            }
        }

        return lostCellList;
    }

    private void beforeCopy(DolphinObject _newObj) {
        Element data = m_xmlConfig.element("data");
        Element beforeCopy = data.element("before-copy");
        if (beforeCopy == null)
            return;
        List properties = beforeCopy.elements();
        for (Iterator iter = properties.iterator(); iter.hasNext();) {
            Element element = (Element) iter.next();
            String sType = element.attributeValue("type");
            if ("int".equals(sType)) {
                _newObj.setProperty(element.attributeValue("name"),
                        Integer.parseInt(element.attributeValue("value")));
            } else {
                _newObj.setProperty(element.attributeValue("name"), element.attributeValue("value"));
            }
        }
    }

    /**
     * Copys the properties form the old object.
     * 
     * @param _oldObj
     * @param _newObj
     * @throws Exception
     */
    private void copy(DolphinObject _oldObj, DolphinObject _newObj, List _errorCopyList) throws Exception {
        Element copy = m_xmlConfig.element("data");
        List properties = copy.element("copy").elements();
        Element element;
        String sFrom, sTo, sReg = null, sValidatorDesc = null;
        String sValue;
        boolean bBool = false, bPassword = false;
        PropertyMetadata property = null;
        for (int i = 0; i < properties.size(); i++) {
            bBool = false;
            bPassword = false;
            element = (Element) properties.get(i);
            sTo = element.attributeValue("to");
            if (!isPropertySet(_newObj, sTo)) {
                property = m_entityMetadata.lookupPropertyByName(sTo, true);
                // skip the property which is not updateable when inserting
                if (_newObj.isValidInstance()) {

                    if (!property.isUpdateable()) {
                        continue;
                    }
                }
                sReg = property.getValidator4Java();
                sValidatorDesc = property.getValidatorDesc();

                if (sReg == null) {
                    if (element.attributeValue("format") != null
                            && element.attributeValue("format").equals("int")) {
                        sReg = "[0-9]+(.[0-9]+)?";
                        sValidatorDesc = "";
                    }
                    if (element.attributeValue("format") != null
                            && element.attributeValue("format").equals("date")) {
                        sReg = "[0-9]{1,4}\\-[0-9]{1,2}\\-[0-9]{1,2}";
                        sValidatorDesc = ":1949-10-1";
                    }

                }

                if (element.attributeValue("format") != null && element.attributeValue("format").equals("bool")) {
                    bBool = true;
                }

                if (element.attributeValue("format") != null
                        && element.attributeValue("format").equals("#password2str")) {
                    bPassword = true;
                }

                sFrom = element.attributeValue("from").toUpperCase();

                sValue = _oldObj.getPropertyAsString(sFrom);

                if (sValue != null) {
                    if (DataTypes.DATE == property.getDataType()) {
                        if (sValue.length() > 10) {
                            sValue = sValue.substring(0, 10);
                        }
                    }

                    if (sReg != null) {
                        if ((sValue.length() > 0) && (!sValue.matches(sReg))) {
                            _errorCopyList.add(element.attributeValue("from") + ":" + sValue + "1"
                                    + (sValidatorDesc == null ? "" : sValidatorDesc + ";"));
                            continue;
                        }
                    }

                    if (bBool) {
                        logger.debug("boolean");

                        if (sValue.equals(""))
                            sValue = "true";

                        if (sValue.equals(""))
                            sValue = "false";
                    }

                    if (bPassword)
                        sValue = PasswordEncrypter.encode(sValue);

                    sValue = StrUtil.sqlEncode(sValue);

                    try {
                        boolean bInt = DataTypes.isInteger(m_entityMetadata.getProperty(sTo, true).getDataType());
                        if (bInt) {
                            int nValue = (int) Double.parseDouble(sValue);
                            _newObj.setProperty(sTo, nValue);
                        } else {
                            DolphinUtil.setPropertyWithString(_newObj, m_entityMetadata, sTo, sValue);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        _errorCopyList.add("" + element.attributeValue("from") + ":" + sValue + ""
                                + (sValidatorDesc == null ? "" : sValidatorDesc + ";"));
                        continue;
                    }
                }
            }
        }
    }

    /**
     * Returns <code>true</code> if the specified property has been set.
     * 
     * @param _obj
     *            a dolphin object
     * @param _sProperty
     *            property name
     * @return <code>true</code> if the specified property has been set;
     *         <code>false</code>, otherwise.
     */
    public static boolean isPropertySet(DolphinObject _obj, String _sProperty) {
        if (_obj.isValidInstance()) {
            return _obj.getNewProperty(_sProperty) != null;
        }
        // else
        return _obj.getProperty(_sProperty) != null;
    }

    /**
     * Converts the properties whose type are different from SRM.
     * 
     * @param _oldObj
     * @param _newObj
     * @throws Exception
     */
    private boolean convert(DolphinObject _oldObj, DolphinObject _newObj, List _errorDataList, int _nChooseIfRepeat)
            throws Exception {
        Element convert = m_xmlConfig.element("data");
        List properties = convert.element("convert").elements();
        Element element;
        String sFrom, sTo, sRef, sForeignKey;
        Object value = null;
        boolean bConvertError = false;
        for (int i = 0; i < properties.size(); i++) {
            element = (Element) properties.get(i);
            sFrom = element.attributeValue("from").toUpperCase();
            sTo = element.attributeValue("to");
            sRef = element.attributeValue("ref");
            if ("@".equals(sFrom)) {
                if ("true".equals(PureSystem.getRequiredProperty("srm.org.has-institute"))) {
                    sFrom = PureSystem.getProperty("srm.org.institute-title");
                }
            }

            if ("@".equals(sFrom)) {
                sFrom = PureSystem.getProperty("srm.org.rescenter-title");
            }

            if (element.attributeValue("provider") != null) {
                if (sRef != null && sRef.charAt(0) == '#') {
                    // if ( _nChooseIfRepeat != Xls2srmForm.JUSTFORCHECK
                    IImportorRef ref = (IImportorRef) PureFactory.getBean(sRef.substring(1));
                    value = ref.convert(_oldObj, _newObj, sFrom, String.valueOf(_nChooseIfRepeat), null,
                            LocalContextHelper.currentSession("Local"), m_entityMetadata,
                            m_xmlConfig.elementTextTrim("match-properties"), m_xmlConfig.attributeValue("temp"));
                    _newObj.setProperty(sTo, value);
                    continue;
                }

                // wind.li@2007-05-08 
                // BEGIN
                if (sRef != null && sRef.charAt(0) == '$') {
                    ImportReturnData returnData = (ImportReturnData) PureFactory.getBean(sRef.substring(1));
                    returnData.run(_oldObj, _newObj, sFrom);
                }
                // END
                continue;
            }
            // to convert property value
            if (!_oldObj.hasProperty(sFrom)) {
                continue;
                // throw new PureException(PureException.PROPERTY_NOTFOUND,
                // sFrom);
            }
            if (sTo != null && isPropertySet(_newObj, sTo))
                continue; // skip

            // else
            try {

                sForeignKey = element.attributeValue("fk");

                value = this.lookupRefValue(sRef, _oldObj.getProperty(sFrom), sForeignKey, sFrom, _errorDataList);

                if (value == null) {
                    bConvertError = true;
                }

                if (value != null && sTo != null) {
                    _newObj.setProperty(sTo, value);
                }

            } catch (Exception ex) {
                throw new PureException(PureException.INVALID_VALUE,
                        "convert " + sFrom + "[" + value + "] to " + sTo, ex);
            }

        }

        return bConvertError;
    }

    protected Object lookupRefValue(String _sRef, Object _oKey, String _sForeignKey) throws Exception {
        if (_oKey == null)
            return null;

        // to analyze
        int nPos = _sRef.indexOf('.');
        String sRefTable = _sRef.substring(0, nPos);
        String sRefField = _sRef.substring(nPos + 1);

        // to construct SQL
        String fk = (_sForeignKey != null && (_sForeignKey = _sForeignKey.trim()).length() > 0) ? _sForeignKey
                : "ID";
        String strSQL = "SELECT " + sRefField + " AS VALUE FROM " + sRefTable + " WHERE " + fk + "=";
        if (_oKey instanceof String) {
            String _sValue = (String) _oKey;
            _sValue = StrUtil.sqlEncode(_sValue);
            strSQL += "'" + _sValue + "'";
        } else {
            strSQL += _oKey.toString().trim();
        }

        // to execute query
        ISession session = this.getSession();
        IStatement query = session.createQuery(strSQL, DolphinObject.class, 1);
        IObjects results = query.executeQuery();

        // to fetch the result
        DolphinObject result = results.next();
        results.clear();
        query.clear();

        // to return
        return result == null ? null : result.getProperty("VALUE");
    }

    private Object lookupRefValue(String _sRef, Object _oKey, String _sForeignKey, String _sPropertyName,
            List _list) throws Exception {
        if (_oKey == null || _oKey.toString().length() == 0)
            return null;

        // to analyze
        int nPos = _sRef.indexOf('.');
        String sRefTable = _sRef.substring(0, nPos);
        String sRefField = _sRef.substring(nPos + 1);

        // to construct SQL
        String fk = (_sForeignKey != null && (_sForeignKey = _sForeignKey.trim()).length() > 0) ? _sForeignKey
                : "ID";
        String strSQL = "SELECT " + sRefField + " AS VALUE FROM " + sRefTable + " WHERE " + fk + "=";
        String _sKey;
        if (_oKey instanceof String) {
            String _sValue = (String) _oKey;
            _sValue = StrUtil.sqlEncode(_sValue);
            strSQL += "'" + _sValue + "'";
        } else {
            _sKey = _oKey.toString();
            strSQL += _sKey.trim();
        }

        // to execute query
        ISession session = this.getSession();
        IStatement query = session.createQuery(strSQL, DolphinObject.class, 1);
        IObjects results = query.executeQuery();

        // to fetch the result
        DolphinObject result = results.next();
        results.clear();
        query.clear();

        // to return
        if (result == null) {
            _list.add(_sPropertyName + "\"" + _oKey.toString() + "\"");
        }
        return result == null ? null : result.getProperty("VALUE");
    }

    /**
     * Fills the properties which are required not null in SRM.
     * 
     * @param _newObj
     * @throws Exception
     */
    private void fill(DolphinObject _oldObj, DolphinObject _newObj, int _nChooseIfRepeat) throws Exception {
        Element fill = m_xmlConfig.element("data");
        List properties = fill.element("fill").elements();
        Element element;
        String sName, sValue;
        for (int i = 0; i < properties.size(); i++) {
            element = (Element) properties.get(i);
            sName = element.attributeValue("name");
            if (sName == null) {
                throw new PureException(PureException.SETTING_MISSING,
                        "property name in fill-" + i + ": " + XMLUtil.toString(element));
            }

            // skip the property which is not updateable
            if (_newObj.isValidInstance()) {
                PropertyMetadata property = m_entityMetadata.lookupPropertyByName(sName, true);
                if (!property.isUpdateable()) {
                    continue; // skip
                }
            }

            sValue = element.attributeValue("value");
            if (sValue == null) {
                throw new PureException(PureException.SETTING_MISSING,
                        "property value in fill-" + i + ": " + XMLUtil.toString(element));
            }
            // ref:
            String sRef = element.attributeValue("ref");
            if (sRef != null && sRef.startsWith("#")) {
                IImportorRef ref = (IImportorRef) PureFactory.getBean(sRef.substring(1));
                _newObj.setProperty(element.attributeValue("name"),
                        ref.convert(_oldObj, _newObj, null, String.valueOf(_nChooseIfRepeat), null,
                                LocalContextHelper.currentSession("Local"), m_entityMetadata, null, null));
            }

            if (!isPropertySet(_newObj, sName)) {
                if (sValue.length() > 0 && sValue.charAt(0) == '@') {
                    // to fill with a specified property
                    sValue = sValue.substring(1); // trim '@'
                    _newObj.setProperty(sName, _newObj.getProperty(sValue));
                } else {
                    // to fill with a constant
                    DolphinUtil.setPropertyWithString(_newObj, m_entityMetadata, sName, sValue);
                }
            }
        }
    }

    /**
     * Saves the new object into SRM database.
     * 
     * @param _newObj
     * @throws Exception
     */
    private void save(DolphinObject _newObj) throws Exception {

        ArkContent obj = (ArkContent) _newObj;

        IContentMgr mgr = ArkContentHelper.getContentMgrOf(_newObj.getClass());

        try {
            mgr.save(obj);
        } catch (Exception ex) {
            Iterator itr = _newObj.getProperties(false).entrySet().iterator();
            Object oValue;
            while (itr.hasNext()) {
                Map.Entry entry = (Map.Entry) itr.next();
                oValue = entry.getValue();
                System.out.println(entry.getKey() + "=" + oValue);
            }
            throw ex;
        }
    }

    /**
     * Saves the new object into SRM database.
     * 
     * @param _newObj
     * @throws Exception
     */
    private boolean beforeSave(DolphinObject _newObj, List _errorDataList) throws Exception {

        List requiredList = new ArrayList();

        List containList = new ArrayList();

        List lostList = new ArrayList();

        boolean bError = false;

        try {
            Iterator itr = _newObj.getProperties(false).entrySet().iterator();
            Object oKey = null;
            while (itr.hasNext()) {
                Map.Entry entryContain = (Map.Entry) itr.next();
                oKey = entryContain.getKey();
                containList.add(oKey);
            }

            PropertyMetadata propertyMetadata, propertyMetadata1;

            Iterator itrRequied = m_entityMetadata.getProperties().entrySet().iterator();

            while (itrRequied.hasNext()) {
                Map.Entry entry = (Map.Entry) itrRequied.next();
                propertyMetadata = m_entityMetadata.lookupPropertyByName(entry.getKey().toString(), true);
                if (!propertyMetadata.isNullable()) {
                    if (!(entry.getKey().equals("createTime") || entry.getKey().equals("id"))) {
                        requiredList.add(entry.getKey());
                    }
                }
            }

            // wind.li@2007-05-09
            // BEGIN
            Element requiredProps = m_xmlConfig.element("required-properties");
            if (requiredProps != null) {
                String sValue = requiredProps.getTextTrim();
                if (sValue.length() > 0) {
                    String[] arrProps = StrUtil.split(sValue, ",");
                    for (int i = 0; i < arrProps.length; i++) {
                        String sName = arrProps[i];
                        if (!requiredList.contains(sName)) {
                            requiredList.add(sName);
                        }
                    }
                }
            }
            // END

            for (int i = requiredList.size(); i > 0; i--) {
                if (!containList.contains(requiredList.get(i - 1))) {
                    lostList.add(requiredList.get(i - 1));
                }
            }

            if (lostList.size() > 0) {
                bError = true;
                for (int i = lostList.size(); i > 0; i--) {
                    propertyMetadata1 = m_entityMetadata.lookupPropertyByName(lostList.get(i - 1).toString(), true);
                    _errorDataList.add(propertyMetadata1.getDesc().toUpperCase());
                }
            }
        } catch (Exception ex) {
            throw ex;
        } finally {
            if (requiredList != null)
                requiredList.clear();
            if (containList != null)
                containList.clear();
            if (lostList != null)
                lostList.clear();

        }

        return bError;
    }

    /**
     * Updates the imported data at last.
     * 
     * @throws Exception
     */
    private void lastUpdate() throws Exception {
        this.executeSQLElement("last-update");
    }

    private void executeSQLElement(String _sName) throws Exception {
        Element ele = m_xmlConfig.element(_sName);
        if (ele == null || "false".equals(ele.attributeValue("enabled"))) {
            return;
        }

        // else
        List eleSQLs = ele.elements("sql");
        if (eleSQLs.isEmpty())
            return;

        // else, to execute the SQLs
        String strSQL;
        ISession session = this.getSession();
        for (int i = 0; i < eleSQLs.size(); i++) {
            strSQL = ((Element) eleSQLs.get(i)).getTextTrim();
            try {
                System.out.println("to execute: " + strSQL);
                IStatement statement = session.createStatement(strSQL);
                this.registerAlias(statement, ele.elements("alias"));
                statement.executeUpdate();
                statement.clear();
            } catch (Exception ex) {
                throw new PureException(PureException.DATABASE_ACCESS, strSQL, ex);
            }
        }
    }

    /**
     * Registers alias for statement.
     * 
     * @param _statement
     * @param _aliasElements
     * @throws Exception
     */
    private void registerAlias(IStatement _statement, List _aliasElements) throws Exception {
        _statement.registerAlias("this", m_entityMetadata.getEntityClass());

        Element eleAlias;
        String sAlias, sClassName;
        for (int i = 0; i < _aliasElements.size(); i++) {
            eleAlias = (Element) _aliasElements.get(i);
            sAlias = eleAlias.attributeValue("name");
            sClassName = eleAlias.attributeValue("class");
            _statement.registerAlias(sAlias, Class.forName(sClassName));
        }
    }

    /**
     * @param _sString
     * @throws PureException
     * @throws IOException
     * @throws FileNotFoundException
     */
    public List check(String _sFileName) throws PureException, FileNotFoundException, IOException {

        POIFSFileSystem fs;
        HSSFSheet m_sheet = null;
        FileInputStream fileInputStream = new FileInputStream(_sFileName);
        String[] m_heads;

        fs = new POIFSFileSystem(fileInputStream);
        HSSFWorkbook wb = new HSSFWorkbook(fs);
        m_sheet = wb.getSheetAt(0);
        HSSFRow row = m_sheet.getRow(0);
        HSSFCell cell;

        // TITLE
        // BY lily
        List list = new ArrayList(row.getLastCellNum());
        for (int i = 0; i < row.getLastCellNum(); i++) {
            cell = row.getCell((short) i);
            if (cell == null) {
                break;
            }
            list.add(cell.getStringCellValue().trim());
        }
        m_heads = new String[list.size()];
        list.toArray(m_heads);
        list.clear();
        fileInputStream.close();
        return checkExcelHead(m_heads);

    }

    public List getReturnData() {
        return m_returnData;
    }

    /**
     * properties
     * 
     * @return
     */
    public List getReturnDataViewProperties() {
        Element data = m_xmlConfig.element("data");
        if (data != null) {
            Element convert = data.element("convert");
            if (convert != null) {
                List properties = convert.elements();
                Element element;
                String sRef, sViewProperties, sProperty;
                for (int i = 0; i < properties.size(); i++) {
                    element = (Element) properties.get(i);
                    sRef = element.attributeValue("ref");
                    if (element.attributeValue("provider") != null) {
                        if (sRef != null && sRef.charAt(0) == '$') {
                            List list = new ArrayList();
                            sViewProperties = element.attributeValue("view-properties");
                            if (sViewProperties != null && sViewProperties.trim().length() > 0) {
                                list = StrUtil.splitToList(sViewProperties, ',');
                            }
                            m_returnDataTitles.add(list);
                            sProperty = element.attributeValue("relative-property");
                            m_returnDataRelatedPropties.add(sProperty);
                        }
                    }
                }
            }
        }
        return m_returnDataTitles;
    }

    /**
     * propertyprojectId
     * 
     * @return
     */
    public List getReturnDataRelatedPropties() {
        return m_returnDataRelatedPropties;
    }

    /** properties */
    public List getViewSelfProperties() {
        Element ele = m_xmlConfig.element("view-self-properties");
        if (ele == null)
            return null;
        String sValue = ele.getTextTrim();
        return StrUtil.splitToList(sValue, ',');
    }
}