com.pureinfo.studio.db.export.InsertSQLDumper.java Source code

Java tutorial

Introduction

Here is the source code for com.pureinfo.studio.db.export.InsertSQLDumper.java

Source

/**
 * PureInfo Quake
 * @(#)InsertSQLDumper.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.export;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;

import com.pureinfo.dolphin.DolphinConstants;
import com.pureinfo.dolphin.DolphinHelper;
import com.pureinfo.dolphin.mapping.EntityMetadata;
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.container.NameRegister;
import com.pureinfo.force.exception.PureException;
import com.pureinfo.force.lang.NullUtil;
import com.pureinfo.force.lang.StrConvertor;
import com.pureinfo.force.lang.StrUtil;
import com.pureinfo.force.xml.XMLUtil;

/**
 * <P>
 * Created on 2005-9-20 13:17:26 <BR>
 * Last modified on 2005-9-20
 * </P>
 * InsertSQLDumper: dump insert SQL script.
 * 
 * @author Why
 * @version 1.0, 2005-9-20
 * @since Quake 1.0
 */
public class InsertSQLDumper {
    public static String PROVIDER_FROM = "PureServer.RWSK";

    public static String PROVIDER_TO = "Local";

    //=========================================================================
    //special reference

    private final static int REF_UNKNOWN = 0;

    private final static int REF_BOOL2INTSTR = 1;

    private final static int REF_STR2INT = 2;

    private final static int REF_FLOAT2DOUBLE = 3;

    private final static NameRegister s_refNames = new NameRegister();
    static {
        s_refNames.register("#bool2IntStr", REF_BOOL2INTSTR);
        s_refNames.register("#str2int", REF_STR2INT);
        s_refNames.register("#float2double", REF_FLOAT2DOUBLE);
    }

    //configuration
    private Element m_xmlConfig;

    //runtime cache
    private ISession m_sessionFrom;

    private ISession m_sessionTo;

    private EntityMetadata m_entityMetadata;

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

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

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

    /**
     * 
     * @throws Exception
     */
    public String run() 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();

        StringBuffer sbuff = new StringBuffer();
        String sResult;
        try {
            prepare();

            objs = this.loadOld();
            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) {
                newObj = (DolphinObject) clazz.newInstance();
                System.out.print("to process " + clazz.getName() + "-" + oldObj.getPropertyAsString(sViewProperty)
                        + "...  ");
                copy(oldObj, newObj);
                convert(oldObj, newObj);
                fill(newObj);

                sResult = save(newObj);
                sbuff.append(sResult).append("\n");

                System.out.println("OK!");
            } //endwhile
            lastUpdate();

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

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

    private ISession getSessionFrom() throws Exception {
        if (m_sessionFrom == null) {
            m_sessionFrom = DolphinHelper.createSession(PROVIDER_FROM);
        }
        return m_sessionFrom;
    }

    private ISession getSessionTo() throws Exception {
        if (m_sessionTo == null) {
            m_sessionTo = DolphinHelper.createSession(PROVIDER_TO);
        }
        return m_sessionTo;
    }

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

    /**
     * Loads the old objects collection.
     * 
     * @return the old objects collection
     * @throws Exception
     */
    private IObjects loadOld() throws Exception {
        String strSQL = m_xmlConfig.elementText("sql");
        ISession session = this.getSessionFrom();
        IStatement query = session.createQuery(strSQL, DolphinObject.class, DolphinConstants.MAXSIZE_UNLIMITED);
        try {
            return query.executeQuery();
        } finally {
            query.clear();
        }
    }

    /**
     * Copys the properties form the old object.
     * 
     * @param _oldObj
     * @param _newObj
     * @throws Exception
     */
    private void copy(DolphinObject _oldObj, DolphinObject _newObj) throws Exception {
        List properties = m_xmlConfig.element("copy").elements();
        Element element;
        String sFrom, sTo;
        for (int i = 0; i < properties.size(); i++) {
            element = (Element) properties.get(i);
            sFrom = element.attributeValue("from").toUpperCase();
            sTo = element.attributeValue("to");
            if (_newObj.getProperty(sTo) == null) {
                if (!m_entityMetadata.hasProperty(sTo)) {
                    throw new PureException(PureException.INVALID_VALUE, "property not found: [" + sTo + "]");
                }
                _newObj.setProperty(sTo, _oldObj.getRequiredProperty(sFrom));
            }
        }
    }

    /**
     * Converts the properties whose type are different from SRM.
     * 
     * @param _oldObj
     * @param _newObj
     * @throws Exception
     */
    private void convert(DolphinObject _oldObj, DolphinObject _newObj) throws Exception {
        IStatement query = null;
        Element element;
        String sFrom, sTo, sRef, sProvider, sForeignKey;
        Object value;

        List properties = m_xmlConfig.element("convert").elements();
        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");

            //to convert property value
            if (!_oldObj.hasProperty(sFrom)) {
                throw new PureException(PureException.PROPERTY_NOTFOUND, sFrom);
            }
            if (_newObj.getProperty(sTo) != null)
                continue; //skip

            //else
            if (sRef.charAt(0) != '#') {
                sProvider = element.attributeValue("provider");
                sForeignKey = element.attributeValue("fk");
                value = this.lookupRefValue(sRef, _oldObj.getProperty(sFrom), sProvider, sForeignKey);
            } else { //special reference
                int nRef = s_refNames.lookup(sRef, REF_UNKNOWN);
                switch (nRef) {
                case REF_BOOL2INTSTR:
                    value = _oldObj.getBoolProperty(sFrom, false) ? "1" : "0";
                    break;
                case REF_STR2INT:
                    value = _oldObj.getStrProperty(sFrom);
                    if (value != null) {
                        value = Integer.valueOf((String) value);
                    }
                    break;
                case REF_FLOAT2DOUBLE:
                    value = _oldObj.getProperty(sFrom);
                    if (value != null) {
                        value = Double.valueOf(value.toString());
                    }
                    break;
                default:
                    throw new PureException(PureException.INVALID_VALUE, "unknow ref: " + sRef);
                }//end case
            } //endif

            if (!m_entityMetadata.hasProperty(sTo)) {
                throw new PureException(PureException.INVALID_VALUE, "property not found: [" + sTo + "]");
            }
            _newObj.setProperty(sTo, value);
        } //endfor

        if (query != null)
            query.clear();
    }

    private Object lookupRefValue(String _sRef, Object _oKey, String _sProvider, 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) {
            strSQL += "'" + StrUtil.sqlEncode(((String) _oKey).replaceAll("[{:}]*", "")) + "'";
        } else {
            strSQL += _oKey.toString();
        }

        //to execute query
        ISession session;
        if (_sProvider != null && _sProvider.equalsIgnoreCase("to")) {
            session = this.getSessionTo();
        } else {
            session = this.getSessionFrom();
        }

        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");
    }

    /**
     * Fills the properties which are required not null in SRM.
     * 
     * @param _newObj
     * @throws Exception
     */
    private void fill(DolphinObject _newObj) throws Exception {
        List properties = m_xmlConfig.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));
            }

            sValue = element.attributeValue("value");
            if (sValue == null) {
                throw new PureException(PureException.SETTING_MISSING,
                        "property value in fill-" + i + ": " + XMLUtil.toString(element));
            }

            if (_newObj.getProperty(sName) == null) {
                if (!m_entityMetadata.hasProperty(sName)) {
                    throw new PureException(PureException.INVALID_VALUE, "property not found: [" + 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 String save(DolphinObject _newObj) throws Exception {
        StringBuffer sbuff = new StringBuffer();
        StringBuffer sbuffValues = new StringBuffer();
        try {
            String sTable = m_xmlConfig.attributeValue("table");
            sbuff.append("INSERT INTO ").append(sTable).append('(');

            Iterator itr = _newObj.getProperties(false).entrySet().iterator();
            Object oValue;
            String sValue;
            while (itr.hasNext()) {
                Map.Entry entry = (Map.Entry) itr.next();

                if (sbuffValues.length() > 0) {
                    sbuff.append(',');
                    sbuffValues.append(',');
                }

                sbuff.append((String) entry.getKey());

                oValue = NullUtil.unmaskNull(entry.getValue());
                if (oValue == null) {
                    sbuffValues.append("null");
                } else {
                    if (oValue instanceof Boolean) {
                        sValue = ((Boolean) oValue).booleanValue() ? "1" : "0";
                    } else {
                        sValue = StrConvertor.objToStr(oValue);
                    }

                    if (oValue instanceof Number) {
                        sbuffValues.append(sValue);
                    } else {
                        sValue = StrUtil.sqlEncode(sValue.trim());
                        sValue = StrUtil.escapeEncode(sValue);
                        sbuffValues.append('\'').append(sValue).append('\'');
                    }
                }
            } //endwhile
            sbuff.append(") VALUES (").append(sbuffValues).append(");");

            //to save
            System.out.println(sbuff.toString());
            return sbuff.toString();
        } 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;
        } finally {
            sbuff.setLength(0);
            sbuffValues.setLength(0);
        }
    }

    /**
     * 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.getSessionTo();
        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));
        }
    }

}