Java tutorial
/** * 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)); } } }