Java tutorial
/** * Copyright (C) 2015-2016 OurBeehive(http://ourbeehive.github.io/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * Project Name: MyBatisPioneer * File Name: ResultMapBuilder.java * Package Name: org.ourbeehive.mbp.builder * * Date: Jan 20, 2016 * Author: Sericloud * */ package org.ourbeehive.mbp.builder; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.ourbeehive.mbp.exception.AppException; import org.ourbeehive.mbp.lang.JavaSrcElm; import org.ourbeehive.mbp.model.ant.MapperArtifact; import org.ourbeehive.mbp.model.ant.MapperProfile; import org.ourbeehive.mbp.model.ant.RelConfig; import org.ourbeehive.mbp.model.ant.ResultMapConfig; import org.ourbeehive.mbp.model.ant.SingleMapperProfile; import org.ourbeehive.mbp.model.db.OrmColumn; import org.ourbeehive.mbp.model.db.OrmTable; import org.ourbeehive.mbp.model.mybatis3.Collection; import org.ourbeehive.mbp.model.mybatis3.Mapper; import org.ourbeehive.mbp.model.mybatis3.ObjectFactory; import org.ourbeehive.mbp.model.mybatis3.Result; import org.ourbeehive.mbp.model.mybatis3.ResultMap; import org.ourbeehive.mbp.register.CtxCacheFacade; import org.ourbeehive.mbp.register.OneToOneIdx; import org.ourbeehive.mbp.util.ExceptionUtil; import org.ourbeehive.mbp.util.JavaFormatter; import org.ourbeehive.mbp.util.MapperFormatter; import org.ourbeehive.mbp.util.ProfileHelper; public class ResultMapBuilder { private static Logger logger = Logger.getLogger(ResultMapBuilder.class); private ObjectFactory mapperObjFactory; SelectBuilder selectBuilder; public ResultMapBuilder(ObjectFactory mapperObjFactory) { this.mapperObjFactory = mapperObjFactory; selectBuilder = new SelectBuilder(mapperObjFactory); } public void buildAllResultMap(Mapper mapper, MapperProfile mapperProfile) throws AppException { try { // The list of SingleMapperProfile. List<SingleMapperProfile> singleMapperProfileList = mapperProfile.getSingleMapperProfile(); MapperArtifact mapperArtifact = null; List<ResultMapConfig> resultMapConfigList = null; ResultMapConfig resultMapConfig = null; // String className = null; String tableName = null; String tableAlias = null; // TODO 2016.1.22 Pioneer ??single /**?for * ?single?mapper * ????singlenamespacemapper **/ for (SingleMapperProfile singleMapperProfile : singleMapperProfileList) { // The list of ResultMapConfig in SingleMapperProfile. resultMapConfigList = singleMapperProfile.getResultMapConfig(); mapperArtifact = singleMapperProfile.getMapperArtifact(); // Build all resultMap. for (int i = 0; i < resultMapConfigList.size(); i++) { // Get class name and table name. resultMapConfig = resultMapConfigList.get(i); // className = resultMapConfig.getClassName(); tableName = resultMapConfig.getTableName(); tableAlias = resultMapConfig.getTableAlias(); if (StringUtils.isNotBlank(tableAlias) == true) { logger.info("RESULTMAP: Handle \"resultMapConfig\" for table \"" + tableName + "(" + tableAlias + ").\""); } else { logger.info("RESULTMAP: Handle \"resultMapConfig\" for table \"" + tableName + "\"."); } /* * //TODO 2016.1.22 Pioneer ??vo select * ???????singleMapperProfile? * **/ // Map DB table and column into VO class. CtxCacheFacade.addVoClass(mapperProfile, resultMapConfig); // Create 'select' element with id: 'countBySqlClause'. selectBuilder.buildCountRootTableBySql(mapper, mapperProfile, mapperArtifact, resultMapConfig); // Create 'resultMap' element with id: 'select<Root Table Name>ResultMap'. buildRootTableResultMap(mapper, mapperProfile, mapperArtifact, resultMapConfig); // Create 'select' element with id: 'select<Root Table Name>ByPK'. selectBuilder.buildSelectRootTableByPK(mapper, mapperProfile, mapperArtifact, resultMapConfig); // Create 'select' element with id: 'select<Root Table Name>BySqlClause'. selectBuilder.buildSelectRootTableBySql(mapper, mapperProfile, mapperArtifact, resultMapConfig); // Build all oneToOne statements. buildTopLevelJoinStmt(mapper, mapperProfile, mapperArtifact, resultMapConfig); } } } catch (Throwable t) { t.printStackTrace(); ExceptionUtil.handleException(t, logger); } } private void buildRootTableResultMap(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig resultMapConfig) throws AppException { try { // The expected 'id' of 'resultMap'. String voSimpleName = JavaFormatter.getVoSimpleName(resultMapConfig, false); String resultMapId = MapperFormatter.getResultMapIdOfRootTab(resultMapConfig); logger.debug("RESULTMAP: Prepare to build resultMap with id '" + resultMapId + "'."); // Lookup 'resultMap' element with full id containing name space. ResultMap resultMap = CtxCacheFacade.lookupResultMap(mapperArtifact, resultMapId); if (resultMap != null) { return; } // The list of ResultMap. List<ResultMap> resultMapList = mapper.getResultMap(); // Initiate blank 'resultMap' element. resultMap = mapperObjFactory.createResultMap(); resultMapList.add(resultMap); // Register the new 'resultMap' element. CtxCacheFacade.addResultMap(mapperArtifact, resultMapId, resultMap); // Populate the 'id' attribute for resultMap with value '<Root Table Name>ResultMap'. resultMap.setId(resultMapId); // Populate the 'class' attribute for resultMap. String className = resultMapConfig.getClassName(); resultMap.setType(className); populateResultMap(resultMap, mapperProfile, resultMapConfig, null, voSimpleName); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // <ancesResultMapConfig> // ....<descOneToOne> // ........<descResultMapConfig> // ............<descOneToMany /> // ........</descResultMapConfig> // ....</descOneToOne> // ....<descOneToMany /> // </ancesResultMapConfig> // private void buildOtoResultMap(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig, List<OneToOneIdx> descOtoIdxList, String resultMapId) throws AppException { try { // The expected 'id' of 'resultMap'. if (resultMapId == null) { resultMapId = MapperFormatter.getResultMapIdOfMultiTab(ancesResultMapConfig, descOtoIdxList); } logger.debug("RESULTMAP: Prepare to build resultMap with id '" + resultMapId + "'."); // Lookup 'resultMap' element with 'id'. ResultMap resultMap = CtxCacheFacade.lookupResultMap(mapperArtifact, resultMapId); if (resultMap != null) { return; } // The list of ResultMap. List<ResultMap> resultMapList = mapper.getResultMap(); // Initiate blank 'resultMap' element. resultMap = mapperObjFactory.createResultMap(); resultMapList.add(resultMap); // Register the new 'resultMap' element. CtxCacheFacade.addResultMap(mapperArtifact, resultMapId, resultMap); // Populate the 'id' attribute for resultMap with value '<Root Table Name>ResultMap'. resultMap.setId(resultMapId); // Populate the 'class' attribute for ResultMap. String ancesClassName = ancesResultMapConfig.getClassName(); resultMap.setType(ancesClassName); String voSimpleName = JavaFormatter.getVoSimpleName(ancesResultMapConfig, false); populateResultMap(resultMap, mapperProfile, ancesResultMapConfig, null, voSimpleName); // If contain one to many association, then claim internal select. List<RelConfig> descOtmList = ancesResultMapConfig.getOneToMany(); if (descOtmList != null && descOtmList.size() != 0) { claimIntnlSelect(resultMap, mapperProfile, mapperArtifact, ancesResultMapConfig, null); } // Prepare to populate 'result' elements for oneToOne association. OneToOneIdx descOtoIdx = null; String refToSon = null; ResultMapConfig descResultMapConfig = null; for (int i = 0; i < descOtoIdxList.size(); i++) { // Get attributes of every descendant 'resultMapConfig' element. descOtoIdx = descOtoIdxList.get(i); refToSon = descOtoIdx.getOneToOne().getRefToSon(); descResultMapConfig = descOtoIdx.getOneToOne().getResultMapConfig(); // populateResultMap(resultMap, mapperProfile, ancesResultMapConfig, descOtoIdx, descOtoIdx.getAttrNameChain()); populateResultMap(resultMap, mapperProfile, ancesResultMapConfig, descOtoIdx, refToSon); // If contain one to many association, then claim internal // select. descOtmList = descResultMapConfig.getOneToMany(); if (descOtmList != null && descOtmList.size() != 0) { logger.debug( "CLAIM INTERNAL SELECT: one to many " + "association exist, claim internal select."); claimIntnlSelect(resultMap, mapperProfile, mapperArtifact, null, descOtoIdx); } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // Inside 'fatherResultMapConfig': // <fatherResultMapConfig> // ....<sonOneToMany> // ........<sonResultMapConfig /> // ....</sonOneToMany> // </fatherResultMapConfig> // private void buildIntnlOtmResultMap(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, RelConfig sonOtmConfig) throws AppException { try { // The expected 'id' of 'resultMap'. String listOfSon = sonOtmConfig.getListOfSon(); ResultMapConfig sonResultMapConfig = sonOtmConfig.getResultMapConfig(); String resultMapId = MapperFormatter.getResultMapIdOfIntnlOtm(mapperProfile, mapperArtifact, sonResultMapConfig, listOfSon); logger.debug("RESULTMAP: Prepare to build resultMap with id '" + resultMapId + "'."); // Lookup 'resultMap' element with 'id'. ResultMap resultMap = CtxCacheFacade.lookupResultMap(mapperArtifact, resultMapId); if (resultMap != null) { return; } // The list of ResultMap. List<ResultMap> resultMapList = mapper.getResultMap(); // Initiate blank 'resultMap' element. resultMap = mapperObjFactory.createResultMap(); resultMapList.add(resultMap); // Register the new 'resultMap' element. CtxCacheFacade.addResultMap(mapperArtifact, resultMapId, resultMap); // Populate the 'id' attribute for resultMap with value '<Root Table Name>ResultMap'. resultMap.setId(resultMapId); // Populate the 'parameterType' attribute for ResultMap. String sonClassName = sonResultMapConfig.getClassName(); resultMap.setType(sonClassName); String voSimpleName = JavaFormatter.getVoSimpleName(sonResultMapConfig, false); populateResultMap(resultMap, mapperProfile, sonResultMapConfig, null, voSimpleName); // Claim internal select. claimIntnlSelect(resultMap, mapperProfile, mapperArtifact, sonResultMapConfig, null); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Handle 'oneToOne' under top 'resultMapConfig'. // // From top 'resultMapConfig': // <ancesResultMapConfig> // ....<descOneToOne> <<-- // ........<descResultMapConfig> // ........</descResultMapConfig> // ....</descOneToOne> // </ancesResultMapConfig> // private void buildTopLevelJoinStmt(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig ancesResultMapConfig) throws AppException { try { logger.debug("Execute 'buildTopLevelJoinStmt' from the top 'resultMapConfig'"); // ??ResultMapConfig?Oto // Get all of the oneToOne resultMapConfig. List<OneToOneIdx> descOtoIdxList = new ArrayList<OneToOneIdx>(); computeOtoIndex(descOtoIdxList, ancesResultMapConfig, null, ancesResultMapConfig.getClassName(), null); // Oto?Otm // Create oneToOne 'resultMap' element, and mark the needed internal oneToMany result map inside the created oneToOne 'resultMap'. buildOtoResultMap(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList, null); // Otm--------->2016 01 26 // Build all needed oneToMany statements for these oneToOne statements. buildIntnlStmts(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList); // Build multi-table select by PK, including oneToOne or oneToMany selectBuilder.buildMultiTabSelectByPK(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList); // Build multi-table select by SqlClause, including oneToOne or oneToMany. selectBuilder.buildMultiTabSelectBySql(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList); // Build multi-table select by SqlClause, including oneToOne or oneToMany. selectBuilder.buildMultiTabCountBySql(mapper, mapperProfile, mapperArtifact, ancesResultMapConfig, descOtoIdxList); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Handle secondary 'oneToOne' under higher 'oneToMany'. // // From higher 'oneToMany': // <fatherResultMapConfig> // ....<sonOneToMany> // ........<sonResultMapConfig> // ............<descOneToOne> <<-- // ................<descResultMapConfig> // ................</descResultMapConfig> // ............</descOneToOne> // ........</sonResultMapConfig> // ........<fatherAttr /> // ....</sonOneToMany> // </fatherResultMapConfig> // private void buildSecJoinStmt(Mapper mapper, String selectId, String resultMapId, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig fatherResultMapConfig, RelConfig sonOtmConfig) throws AppException { try { logger.debug("Execute 'buildSecJoinStmt' from higher 'oneToMany'."); // Get 'resultMapConfig' under higher oneToMany RelConfig. ResultMapConfig sonResultMapConfig = sonOtmConfig.getResultMapConfig(); List<OneToOneIdx> descOtoIdxList = new ArrayList<OneToOneIdx>(); computeOtoIndex(descOtoIdxList, sonResultMapConfig, null, sonResultMapConfig.getClassName(), null); // Create oneToOne 'resultMap' element. buildOtoResultMap(mapper, mapperProfile, mapperArtifact, sonResultMapConfig, descOtoIdxList, resultMapId); // Build all needed oneToMany statements for these oneToOne statements. buildIntnlStmts(mapper, mapperProfile, mapperArtifact, sonResultMapConfig, descOtoIdxList); // Build internal oneToOne select with given 'selectId' and 'resultMapId'. selectBuilder.buildIntnlSelectOto(mapper, mapperProfile, mapperArtifact, fatherResultMapConfig, sonOtmConfig, descOtoIdxList, selectId, resultMapId); } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // <fatherResultMapConfig> // ....<fatherOneToOne> // ........<sonResultMapConfig> // ............<sonOneToOne /> // ........</sonResultMapConfig> // ....</fatherOneToOne> // ....<fatherOneToOne> // ........<sonResultMapConfig> // ............<sonOneToOne /> // ........</sonResultMapConfig> // ....</fatherOneToOne> // </fatherResultMapConfig> private void computeOtoIndex(List<OneToOneIdx> otoIndexList, ResultMapConfig fatherResultMapConfig, OneToOneIdx ancesOtoIndex, String fullClassNameChain, String simpleClassNameChain) throws AppException { try { logger.debug("COMPUTE OTO: Begin to compute oneToOne association."); String selectStatement = fatherResultMapConfig.getSelectStmt(); if (StringUtils.isNotBlank(selectStatement) == true) { logger.debug("STATEMENT: Compute selectStatement '" + selectStatement + "'"); } OneToOneIdx fatherOtoIdx = null; List<RelConfig> fatherOtoList = fatherResultMapConfig.getOneToOne(); RelConfig fatherOto = null; ResultMapConfig sonResultMapConfig = null; String sonClassName = null; String sonAttrName = null; String sonTableName = null; String sonTableAlias = null; List<RelConfig> sonOtoList = null; // If 'fatherResultMapConfig' has more than one oneToOne association, then every one of them has peer. boolean hasPeer = fatherOtoList.size() > 1 ? true : false; int fatherOtoIdxLoc = otoIndexList.size() - 1; for (int i = 0; i < fatherOtoList.size(); i++) { // Record the father of current oneToOne association. fatherOtoIdx = new OneToOneIdx(); fatherOtoIdx.setFatherOtoIndex(ancesOtoIndex); // ?? fatherOtoIdx.setFatherOtoIndexLoc(fatherOtoIdxLoc); // ?Oto // Register 'fatherOneToOne' into otoIndexList. otoIndexList.add(fatherOtoIdx); // list // Set other attributes for 'fatherOtoIdx'. fatherOto = fatherOtoList.get(i); // ??ResultMapConfig fatherOtoIdx.setOneToOne(fatherOto); // ? fatherOtoIdx.setHasPeer(hasPeer); // ? // ?[XXDto.]XXvo.XXvo if (simpleClassNameChain == null) { sonAttrName = fatherOto.getRefToSon(); fatherOtoIdx.setAttrNameChain(sonAttrName); } else { sonAttrName = simpleClassNameChain + JavaSrcElm.DOT + fatherOto.getRefToSon(); fatherOtoIdx.setAttrNameChain(sonAttrName); } // ??OtoResultMapConfig sonResultMapConfig = fatherOto.getResultMapConfig(); sonTableName = sonResultMapConfig.getTableName(); sonTableAlias = sonResultMapConfig.getTableAlias(); sonClassName = fullClassNameChain + JavaSrcElm.DOT + fatherOto.getRefToSon(); fatherOtoIdx.setFatherTableName(fatherResultMapConfig.getTableName()); fatherOtoIdx.setFatherTableAlias(fatherResultMapConfig.getTableAlias()); fatherOtoIdx.setSonTableName(sonResultMapConfig.getTableName()); fatherOtoIdx.setSonTableAlias(sonResultMapConfig.getTableAlias()); // Log the registration of 'fatherOneToOne'. if (StringUtils.isNotBlank(sonTableAlias) == true) { logger.debug("REGISTER: Register an OTO association into otoIndexList. " + "className = \"" + sonClassName + "\", tableName = \"" + sonTableName + "(" + sonTableAlias + ")\"."); } else { logger.debug("REGISTER: Register an OTO association into otoIndexList. " + "className = \"" + sonClassName + "\", tableName = \"" + sonTableName + "\"."); } logger.debug("JUDGE PEER: Current OTO association has peer '" + hasPeer + "'"); // ??OtoOto?? // Get son oneToOne association. sonOtoList = sonResultMapConfig.getOneToOne(); // If having son oneToOne association. if (sonOtoList != null && sonOtoList.size() != 0) { // Invoke recursively to find all descendant oneToOne associations computeOtoIndex(otoIndexList, sonResultMapConfig, fatherOtoIdx, sonClassName, sonAttrName); } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // <ancesResultMapConfig> // ....<descOneToOne /> // </ancesResultMapConfig> // private void populateResultMap(ResultMap resultMap, MapperProfile mapperProfile, ResultMapConfig ancesResultMapConfig, OneToOneIdx descOneToOneIdx, String attrNameChain) throws AppException { try { // If the given oneToOne is not null, then consider it as current resultMapConfig. // String ancesClassName = ancesResultMapConfig.getClassName(); RelConfig descOneToOne = null; ResultMapConfig currResultMapConfig = null; // String refToSon = null; if (descOneToOneIdx != null) { descOneToOne = descOneToOneIdx.getOneToOne(); currResultMapConfig = descOneToOne.getResultMapConfig(); // refToSon = descOneToOne.getRefToSon(); } else { currResultMapConfig = ancesResultMapConfig; } String tableName = currResultMapConfig.getTableName(); String tableAlias = currResultMapConfig.getTableAlias(); // Find OrmTable according to the table name. OrmTable ormTable = CtxCacheFacade.lookupOrmTable(tableName); if (ormTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + tableName); return; } List<Result> resultList = resultMap.getResult(); Result result = null; OrmColumn ormColumn = null; String columnName = null; String attrName = null; // OrmAttr ormAttr = null; logger.debug("ATTR NAME CHAIN: The given attrNameChain is: " + attrNameChain); if (attrNameChain == null) { attrNameChain = ""; } else { attrNameChain = attrNameChain + JavaSrcElm.DOT; } HashSet<String> includedAttrs = ProfileHelper.getIncludedAttrName(currResultMapConfig); HashSet<String> excludedAttrs = ProfileHelper.getExcludedAttrName(currResultMapConfig); // Populate 'result' elements according to the the ClassEntity definition. List<OrmColumn> ormColumnList = ormTable.getColumnList(); for (int i = 0; i < ormColumnList.size(); i++) { // Check inclusion and exclusion, inclusion take higher preference. ormColumn = ormColumnList.get(i); columnName = ormColumn.getName(); // Translate column name to java attribute name. attrName = JavaFormatter.getJavaStyle(columnName, false); if (includedAttrs.size() != 0) { if (includedAttrs.contains(attrName) == false) { logger.debug("EXCLUDE ATTRIBUTE: Property '" + attrName + "' is NOT in the inclusion list, skipped."); continue; } } else if (excludedAttrs.size() != 0) { if (excludedAttrs.contains(attrName) == true) { logger.debug("EXCLUDE ATTRIBUTE: Property '" + attrName + "' is in the exclusion list, skipped."); continue; } } result = mapperObjFactory.createResult(); result.setProperty(attrNameChain + attrName); result.setColumn(MapperFormatter.getColumnAlias(mapperProfile, tableName, tableAlias, columnName)); result.setJdbcType(ormColumn.getJdbcTypeName()); resultList.add(result); logger.debug("FIND MAPPING: Find mapping between attribute '" + attrNameChain + attrName + "' and column '" + columnName + "'"); } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Get attributes from 'fatherResultMapConfig' or 'fatherOtoIdx'. // // From 'fatherResultMapConfig': // <fatherResultMapConfig> // ....<sonOneToMany /> // </fatherResultMapConfig> // // From 'fatherOtoIdx': // <fatherOneToOne> // ....<fatherResultMapConfig /> // ........<sonOneToMany /> // </fatherOneToOne> // private void claimIntnlSelect(ResultMap resultMap, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig fatherResultMapConfig, OneToOneIdx fatherOtoIdx) throws AppException { try { String fatherTableName = null; String fatherTableAlias = null; List<RelConfig> sonOneToManyList = null; // If the given 'fatherResultMapConfig' is not null, then get attributes from it. if (fatherResultMapConfig != null) { fatherTableName = fatherResultMapConfig.getTableName(); fatherTableAlias = fatherResultMapConfig.getTableAlias(); sonOneToManyList = fatherResultMapConfig.getOneToMany(); } // If the given 'fatherResultMapConfig' is null, then get attributes from 'fatherOtoIdx'. else if (fatherOtoIdx != null) { RelConfig fatherOneToOne = fatherOtoIdx.getOneToOne(); fatherResultMapConfig = fatherOneToOne.getResultMapConfig(); fatherTableName = fatherResultMapConfig.getTableName(); fatherTableAlias = fatherResultMapConfig.getTableAlias(); sonOneToManyList = fatherResultMapConfig.getOneToMany(); } else { throw new IllegalArgumentException( "'ancesResultMapConfig' and 'otoIndex' " + "could not be null simultaneously."); } // Find OrmTable according to the table name. OrmTable fatherTable = CtxCacheFacade.lookupOrmTable(fatherTableName); if (fatherTable == null) { logger.error("!!! NO TABLE !!!: No table found with table name: " + fatherTableName); return; } // Prepare to claim internal select for every oneToMany association. RelConfig sonOneToMany = null; ResultMapConfig sonResultMapConfig = null; String listOfSon = null; String sonClassName = null; String fatherAttrName = null; String fatherColumnName = null; OrmColumn fatherColumn = null; // String attrAlias = null; String columnAlias = null; List<Collection> collectionList = resultMap.getCollection(); Collection collection = null; // Result result = null; for (int i = 0; i < sonOneToManyList.size(); i++) { sonOneToMany = sonOneToManyList.get(i); sonResultMapConfig = sonOneToMany.getResultMapConfig(); sonClassName = sonResultMapConfig.getClassName(); listOfSon = sonOneToMany.getListOfSon(); fatherAttrName = sonOneToMany.getFatherAttr(); fatherColumnName = JavaFormatter.getDbStyle(fatherAttrName); fatherColumn = fatherTable.getColumnIdx().get(fatherColumnName); if (fatherColumn != null) { collection = mapperObjFactory.createCollection(); columnAlias = MapperFormatter.getColumnAlias(mapperProfile, fatherTableName, fatherTableAlias, fatherColumnName); collection.setProperty(listOfSon); collection.setOfType(sonClassName); collection.setColumn(columnAlias); collection.setSelect(MapperFormatter.getSelIdOfIntnlOtm(mapperProfile, mapperArtifact, sonResultMapConfig, listOfSon, false)); collectionList.add(collection); logger.info("FIND MAPPING: Find mapping between attribute '" + listOfSon + "' and column '" + columnAlias + "'"); } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // // Handle 'oneToMany' directly under 'fatherResultMapConfig', and those under 'sonOtoIndexList'. // // Inside 'fatherResultMapConfig': // <fatherResultMapConfig> // ....<sonOneToMany> // ........<sonResultMapConfig> // ............<descOneToOne /> // ............<descOneToMany> // ................<descResultMapConfig /> // ...........</descOneToMany> // ........</sonResultMapConfig> // ....</sonOneToMany> // ....<sonOneToOne> // ........<sonResultMapConfig> // ............<descOneToMany> // ................<descResultMapConfig> // ....................<descOneToOne /> // ................</descResultMapConfig> // ...........</descOneToMany> // ........</sonResultMapConfig> // ....</sonOneToOne> // ....<sonOneToOne /> // </fatherResultMapConfig> // private void buildIntnlStmts(Mapper mapper, MapperProfile mapperProfile, MapperArtifact mapperArtifact, ResultMapConfig fatherResultMapConfig, List<OneToOneIdx> sonOtoIndexList) throws AppException { try { //add base CtxCacheFacade.addDtoAttr(mapperProfile, mapperArtifact, fatherResultMapConfig.getClassName(), fatherResultMapConfig.getTableName(), null, null, false, null); // Handle 'oneToMany' directly under 'fatherResultMapConfig'. List<RelConfig> sonOneToManyList = fatherResultMapConfig.getOneToMany(); RelConfig sonOneToMany = null; String listOfSon = null; ResultMapConfig sonResultMapConfig = null; List<RelConfig> descOneToOneList = null; List<RelConfig> descOneToManyList = null; String selectId = null; String resultMapId = null; if (sonOneToManyList != null) { for (int i = 0; i < sonOneToManyList.size(); i++) { // If there is oneToOne association under 'sonResultMapConfig', then handle them. sonOneToMany = sonOneToManyList.get(i); sonResultMapConfig = sonOneToMany.getResultMapConfig(); descOneToOneList = sonResultMapConfig.getOneToOne(); descOneToManyList = sonResultMapConfig.getOneToMany(); //TODO add oneToMany list attr to dto CtxCacheFacade.addDtoAttr(mapperProfile, mapperArtifact, fatherResultMapConfig.getClassName(), fatherResultMapConfig.getTableName(), sonOneToMany.getListOfSon(), sonResultMapConfig.getTableName(), true, sonResultMapConfig.getClassName()); if (descOneToOneList != null && descOneToOneList.size() != 0) { logger.debug( "OTO in OTM: Found OTO in OTM, need build addtional " + "one to one statements."); // Use the mandatory 'id' for private 'select'. listOfSon = sonOneToMany.getListOfSon(); selectId = MapperFormatter.getSelIdOfIntnlOtm(mapperProfile, mapperArtifact, sonResultMapConfig, listOfSon, false); // Use the mandatory 'id' for private 'resultMap'. resultMapId = MapperFormatter.getResultMapIdOfIntnlOtm(mapperProfile, mapperArtifact, sonResultMapConfig, listOfSon); buildSecJoinStmt(mapper, selectId, resultMapId, mapperProfile, mapperArtifact, fatherResultMapConfig, sonOneToMany); } // If there is oneToMany association under 'sonResultMapConfig', then handle them. else if (descOneToManyList != null && descOneToManyList.size() != 0) { logger.debug( "OTM in OTM: Found OTM in OTM, need build addtional " + "one to many statements."); buildIntnlOtmResultMap(mapper, mapperProfile, mapperArtifact, sonOneToMany); selectBuilder.buildIntnlSelectOneTable(mapper, mapperProfile, mapperArtifact, null, null, fatherResultMapConfig, sonOneToMany); buildIntnlStmts(mapper, mapperProfile, mapperArtifact, sonResultMapConfig, new ArrayList<OneToOneIdx>()); } // If there is neither oneToOne nor oneToMany association under 'sonResultMapConfig'. else { buildIntnlOtmResultMap(mapper, mapperProfile, mapperArtifact, sonOneToMany); selectBuilder.buildIntnlSelectOneTable(mapper, mapperProfile, mapperArtifact, null, null, fatherResultMapConfig, sonOneToMany); } } } // Handle all of 'oneToMany' inside 'sonOtoIndexList'. OneToOneIdx sonOtoIndex = null; RelConfig sonOneToOne = null; // OrmClass sonOrmClass = null; RelConfig descOneToMany = null; ResultMapConfig descResultMapConfig = null; if (sonOtoIndexList != null) { for (int i = 0; i < sonOtoIndexList.size(); i++) { sonOtoIndex = sonOtoIndexList.get(i); sonOneToOne = sonOtoIndex.getOneToOne(); sonResultMapConfig = sonOneToOne.getResultMapConfig(); descOneToManyList = sonResultMapConfig.getOneToMany(); //TODO add oneToOne attr to dto CtxCacheFacade.addDtoAttr(mapperProfile, mapperArtifact, fatherResultMapConfig.getClassName(), fatherResultMapConfig.getTableName(), sonOneToOne.getRefToSon(), sonResultMapConfig.getTableName(), false, sonResultMapConfig.getClassName()); // Because current 'sonResultMapConfig' is defined inside oneToOne association, so its 'className' attribute is null and should // be set. // sonOrmClass = CtxCacheFacade.getOrmClass(fatherResultMapConfig.getClassName(), sonOtoIndex); // sonResultMapConfig.setClassName(sonOrmClass.getFullName()); if (descOneToManyList != null) { for (int j = 0; j < descOneToManyList.size(); j++) { descOneToMany = descOneToManyList.get(j); // If there is oneToOne association inside 'descOneToMany', then handle oneToOne firstly. descResultMapConfig = descOneToMany.getResultMapConfig(); descOneToOneList = descResultMapConfig.getOneToOne(); //TODO add oneTo many attr to Dto CtxCacheFacade.addDtoAttr(mapperProfile, mapperArtifact, fatherResultMapConfig.getClassName(), fatherResultMapConfig.getTableName(), descOneToMany.getListOfSon(), descResultMapConfig.getTableName(), true, descResultMapConfig.getClassName()); if (descOneToOneList != null && descOneToOneList.size() != 0) { logger.debug("OTO in OTM: Found OTO in OTM, need build addtional " + "one to one statements."); // Use the mandatory 'id' for private 'select'. listOfSon = descOneToMany.getListOfSon(); selectId = MapperFormatter.getSelIdOfIntnlOtm(mapperProfile, mapperArtifact, descResultMapConfig, listOfSon, false); // Use the mandatory 'id' for oneToOneResultMap. resultMapId = MapperFormatter.getResultMapIdOfIntnlOtm(mapperProfile, mapperArtifact, descResultMapConfig, listOfSon); buildSecJoinStmt(mapper, selectId, resultMapId, mapperProfile, mapperArtifact, sonResultMapConfig, descOneToMany); } else { buildIntnlOtmResultMap(mapper, mapperProfile, mapperArtifact, descOneToMany); selectBuilder.buildIntnlSelectOneTable(mapper, mapperProfile, mapperArtifact, fatherResultMapConfig, sonOtoIndex, null, descOneToMany); } } } } } } catch (Throwable t) { ExceptionUtil.handleException(t, logger); } } // private void cacheClassConst(MapperProfile mapperProfile, String ancesClassName, OneToOneIdx descOtoIdx, String tableName, String tableAlias) // throws AppException { // // try { // // String dtoDomainName = getClassDomainName(ancesClassName); // String constantName = null; // if (descOtoIdx != null) { // String attrNameChain = descOtoIdx.getAttrNameChain(); // attrNameChain = StringUtils.replace(attrNameChain, JavaSrcElm.DOT, JavaSrcElm.UNDER_LINE); // constantName = dtoDomainName + JavaSrcElm.UNDER_LINE + attrNameChain; // } else { // constantName = dtoDomainName; // } // // String constantValue = null; // if (StringUtils.isNotBlank(tableAlias) == true) { // constantValue = tableAlias; // } else { // constantValue = MapperFormatter.getTableShortName(tableName); // } // // logger.debug("CACHE CONST: " + "Prepare to cache '" + constantName + " = " + constantValue + "'"); // // // Get settings for ClassConstant. // AllMapperProfile allMapperProfile = mapperProfile.getAllMapperProfile(); // ComnArtifact comnArtifact = allMapperProfile.getComnArtifact(); // // String constPkg = comnArtifact.getConstPkg(); // String classFullName = comnArtifact.getClassConst(); // // ClassAnalyzer classAnalyzer = new ClassAnalyzer(); // classAnalyzer.cacheConst(classFullName, constantName, constantValue); // // } catch (Throwable t) { // throw new AppException(t); // } // // } // private void cacheAttrConst(MapperProfile mapperProfile, String propName, String columnName) throws AppException { // // try { // // // logger.debug("CACHE CONST: Prepare to cache '" + propName + " = " // // + columnName + "'"); // // // Get settings for ClassConstant. // AllMapperProfile allMapperProfile = mapperProfile.getAllMapperProfile(); // ComnArtifact comnArtifact = allMapperProfile.getComnArtifact(); // String classFullName = comnArtifact.getAttrConst(); // // ClassAnalyzer classAnalyzer = new ClassAnalyzer(); // classAnalyzer.cacheConst(classFullName, propName, columnName); // // } catch (Throwable t) { // throw new AppException(t); // } // // } // private String getClassDomainName(String classFullName) { // // int rightFirst = classFullName.lastIndexOf(JavaSrcElm.DOT); // String dtoPkg = classFullName.substring(0, rightFirst); // String classSimpleName = classFullName.substring(rightFirst + 1, classFullName.length()); // // // Skip 'dto' in package name. // int rightSecond = dtoPkg.lastIndexOf(JavaSrcElm.DOT); // String domainPkg = classFullName.substring(0, rightSecond); // int rightThird = domainPkg.lastIndexOf(JavaSrcElm.DOT); // String domainName = domainPkg.substring(rightThird + 1, domainPkg.length()); // // // Return domainName and shortName. // return domainName + JavaSrcElm.UNDER_LINE + classSimpleName; // // } }