package nc
.md
.persist
.framework
.imp
;
import java
.util
.ArrayList
;
import java
.util
.Arrays
;
import java
.util
.Collection
;
import java
.util
.HashMap
;
import java
.util
.HashSet
;
import java
.util
.List
;
import java
.util
.Map
;
import java
.util
.Set
;
import nc
.bs
.logging
.Logger
;
import nc
.bs
.ml
.NCLangResOnserver
;
import nc
.jdbc
.framework
.mapping
.MappingMeta
;
import nc
.md
.common
.AssociationKind
;
import nc
.md
.data
.access
.NCObject
;
import nc
.md
.innerservice
.MDQueryService
;
import nc
.md
.model
.IAssociation
;
import nc
.md
.model
.IAttribute
;
import nc
.md
.model
.IBean
;
import nc
.md
.model
.IBusinessEntity
;
import nc
.md
.model
.ICardinality
;
import nc
.md
.model
.IForeignKey
;
import nc
.md
.model
.MetaDataException
;
import nc
.md
.model
.MetaDataRuntimeException
;
import nc
.md
.util
.MDUtil
;
import nc
.vo
.jcom
.lang
.StringUtil
;
import nc
.vo
.pub
.CircularlyAccessibleValueObject
;
final class VOQueryPersister {
private IBusinessEntity relatedEntity
= null
;
private boolean ignoreDrEqual1
= false;
private final static String FIRST_ORDERPATH_KEY
= "@@@";
private Collection
<MappingMeta> relatedMetas
= null
;
private Map
<String, String> relatedTableAliasMap
= new HashMap<String, String>();
private MDMultiTableDAO dao
= null
;
public VOQueryPersister(IBusinessEntity entity
) {
initPersister(entity
);
}
public VOQueryPersister(IBusinessEntity entity
, boolean ignoreDrEqual1
) {
initPersister(entity
);
this.ignoreDrEqual1
= ignoreDrEqual1
;
}
public VOQueryPersister(String voFullClassName
) {
IBean bean
= null
;
try {
bean
= MDQueryService
.lookupMDQueryService()
.getBeanByFullClassName(voFullClassName
);
} catch (MetaDataException e
) {
Logger
.error(NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voPersister-0000")
+ voFullClassName
, e
);
}
if (bean
== null
)
throw new MetaDataRuntimeException(
NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voQueryPersister-0000")
+ voFullClassName
);
initPersister(bean
);
}
public VOQueryPersister(String voFullClassName
, boolean ignoreDrEqual1
) {
this(voFullClassName
);
this.ignoreDrEqual1
= ignoreDrEqual1
;
}
private void initPersister(IBean bean
) {
relatedEntity
= (IBusinessEntity
) bean
;
if (relatedEntity
== null
)
throw new MetaDataRuntimeException(
NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voPersister-0001"));
if (!MDUtil
.isEntityType(relatedEntity
))
throw new MetaDataRuntimeException(
NCLangResOnserver
.getInstance().getStrByID("mdbusi", "mdPersistUtil-0001")
+ bean
.getFullName());
relatedMetas
= MDPersistUtil
.getMappingDataOfBeanWithExtendTable(
relatedEntity
, null
).values();
for (MappingMeta meta
: relatedMetas
) {
relatedTableAliasMap
.put(meta
.getTableName(), meta
.getTableName());
}
dao
= new MDMultiTableDAO(relatedEntity
, relatedMetas
,
relatedTableAliasMap
);
}
protected NCObject
queryBillImp(String billPK
, boolean bLazyLoad
)
throws MetaDataException
{
NCObject resNCObj
= null
;
try {
Object resVO
= dao
.retrieveByPK(billPK
,ignoreDrEqual1
);
if (resVO
== null
)
return null
;
resNCObj
= NCObject
.newInstance(relatedEntity
, resVO
);
if (!bLazyLoad
)
queryChildrenVOSByParentObjs(new NCObject[] { resNCObj
},
bLazyLoad
, null
, null
);
} catch (Exception e
) {
Logger
.error("fail to query data", e
);
throw new MetaDataException(
"operation failed** baseDao.retrieveByPK," + e
.getMessage());
}
return resNCObj
;
}
protected Collection
<NCObject> queryBillsImp(String
[] billPKs
,
String
[] subEntityName
) throws MetaDataException
{
return queryBillsImp(billPKs
, false, subEntityName
);
}
protected Collection
<NCObject> queryBillsImp(String
[] pks
, boolean bLazyLoad
)
throws MetaDataException
{
return queryBillsImp(pks
, bLazyLoad
, null
);
}
private Collection
<NCObject> queryBillsImp(String
[] pks
, boolean bLazyLoad
,
String
[] subEntityName
) throws MetaDataException
{
Collection
<NCObject> results
= null
;
try {
Collection resVOs
= dao
.retrieveByPKS(pks
, null
, ignoreDrEqual1
);
if (resVOs
== null
|| resVOs
.size() == 0)
return null
;
NCObject
[] parentNVOs
= new NCObject[resVOs
.size()];
int i
= 0;
for (Object curvo
: resVOs
) {
parentNVOs
[i
++] = NCObject
.newInstance(relatedEntity
, curvo
);
}
if (!bLazyLoad
) {
queryChildrenVOSByParentObjs(parentNVOs
, bLazyLoad
, null
, null
,
subEntityName
);
}
results
= Arrays
.asList(parentNVOs
);
} catch (Exception e
) {
Logger
.error("operation failed", e
);
throw new MetaDataException(
"operation failed : baseDao.retrieveByPKS,"
+ e
.getMessage());
}
return results
;
}
protected NCObject
[] queryBillsImp(String
[] pks
, String
[] filtAttrNames
,
boolean bLazyLoad
) throws MetaDataException
{
final String
[] fields
= filtAttrNames
;
NCObject
[] results
= null
;
try {
Collection resVOs
= dao
.retrieveByPKS(pks
, fields
, ignoreDrEqual1
);
if (resVOs
== null
|| resVOs
.size() == 0)
return new NCObject[pks
.length
];
List
<NCObject> resultList
= new ArrayList<NCObject>();
Map
<String, NCObject> resultMap
= new HashMap<String, NCObject>();
for (Object curvo
: resVOs
) {
NCObject ncObj
= NCObject
.newInstance(relatedEntity
, curvo
);
resultMap
.put((String
) ncObj
.getAttributeValue(relatedEntity
.getKeyAttribute()), ncObj
);
}
queryChildrenVOSByParentObjs(
resultMap
.values().toArray(new NCObject[0]), bLazyLoad
,
null
, null
);
for (String pk
: pks
) {
resultList
.add(resultMap
.get(pk
));
}
results
= resultList
.toArray(new NCObject[0]);
} catch (Exception e
) {
Logger
.error("operation failed", e
);
throw new MetaDataException(
"operation failed : MDMultiTableDAO.retrieveByClouse,"
+ e
.getMessage());
}
return results
;
}
protected NCObject
[] queryBillsImp(String whereCondStr
,
String
[] sunEntityPaths
, String
[] orderPaths
)
throws MetaDataException
{
if (sunEntityPaths
== null
|| sunEntityPaths
.length
== 0) {
return queryBillsImp(null
, whereCondStr
, true, sunEntityPaths
,
orderPaths
);
}
return queryBillsImp(null
, whereCondStr
, false, sunEntityPaths
,
orderPaths
);
}
protected NCObject
[] queryBillsImp(String whereCondStr
, boolean bLazyLoad
,
String
[] orderPaths
) throws MetaDataException
{
return queryBillsImp(null
, whereCondStr
, bLazyLoad
, null
, orderPaths
);
}
public NCObject
[] queryBillsImp(String
[] tableNames
, String whereCondStr
,
boolean bLazyLoad
, String
[] orderPaths
) throws MetaDataException
{
Map
<String, String> tableNameMap
= new HashMap<String, String>();
for (MappingMeta meta
: relatedMetas
) {
tableNameMap
.put(meta
.getTableName(), meta
.getTableName());
}
for (String name
: tableNames
) {
tableNameMap
.put(name
, name
);
}
return queryBillsImp(tableNameMap
, whereCondStr
, bLazyLoad
, null
,
orderPaths
);
}
protected NCObject
[] queryBillsImp(String fromTableSql
,
String whereCondStr
, boolean bLazyLoad
, String
[] orderPaths
)
throws MetaDataException
{
Map
<String, String> tableNameMap
= new HashMap<String, String>();
for (MappingMeta meta
: relatedMetas
) {
tableNameMap
.put(meta
.getTableName(), meta
.getTableName());
}
if (!StringUtil
.isEmptyWithTrim(fromTableSql
)) {
String
[] fromTables
= fromTableSql
.trim().split(",");
for (String tablePart
: fromTables
) {
String
[] tableParts
= tablePart
.trim().split("(\\s)+");
if (tableParts
!= null
&& tableParts
.length
> 0) {
String tableName
= tableParts
[0];
String tableAlias
= null
;
if (tableParts
.length
== 2) {
tableAlias
= tableParts
[1];
}
tableNameMap
.put(tableName
, tableAlias
);
}
}
}
return queryBillsImp(tableNameMap
, whereCondStr
, bLazyLoad
, null
,
orderPaths
);
}
private NCObject
[] queryBillsImp(Map
<String, String> tableAliasMap
,
String whereCondStr
, boolean bLazyLoad
, String
[] sunEntityPaths
,
String
[] orderPaths
) throws MetaDataException
{
if(whereCondStr
== null
){
whereCondStr
= "";
}
if (tableAliasMap
== null
) {
tableAliasMap
= relatedTableAliasMap
;
}
Map
<String
, List
<String>> pathMap
= getOrderMap(orderPaths
);
NCObject
[] results
= null
;
try {
if (ignoreDrEqual1
)
whereCondStr
= whereCondStr
+ " and isnull("
+ tableAliasMap
.get(relatedEntity
.getTable().getName())
+ ".dr,0)=0 ";
String orderPath
= "";
if (pathMap
.containsKey(FIRST_ORDERPATH_KEY
)) {
orderPath
= getOrderSqlPath(pathMap
.get(FIRST_ORDERPATH_KEY
));
pathMap
.remove(FIRST_ORDERPATH_KEY
);
whereCondStr
+= orderPath
;
}
MDMultiTableDAO dao
= new MDMultiTableDAO(relatedEntity
,
relatedMetas
, tableAliasMap
);
Collection resVOs
= dao
.retrieveByClouse(whereCondStr
);
if (resVOs
== null
|| resVOs
.size() == 0)
return null
;
results
= new NCObject[resVOs
.size()];
int i
= 0;
for (Object curvo
: resVOs
) {
results
[i
++] = NCObject
.newInstance(relatedEntity
, curvo
);
}
queryChildrenVOSByParentObjs(results
, bLazyLoad
, pathMap
, "",
sunEntityPaths
);
} catch (Exception e
) {
Logger
.error("operation failed", e
);
throw new MetaDataException(
"operation failed : baseDao.retrieveByPK,"
+ e
.getMessage());
}
return results
;
}
protected NCObject
[] queryBillsImp(String whereCondStr
,
String
[] filtAttrNames
, boolean bLazyLoad
) throws MetaDataException
{
NCObject
[] results
= null
;
try {
if (ignoreDrEqual1
)
whereCondStr
= whereCondStr
+ " and isnull("
+ relatedTableAliasMap
.get(relatedEntity
.getTable()
.getName()) + ".dr,0)=0 ";
Collection resVOs
= dao
.retrieveByClouse(whereCondStr
,
filtAttrNames
, false);
if (resVOs
== null
|| resVOs
.size() == 0)
return null
;
results
= new NCObject[resVOs
.size()];
int i
= 0;
for (Object curvo
: resVOs
) {
results
[i
++] = NCObject
.newInstance(relatedEntity
, curvo
);
}
queryChildrenVOSByParentObjs(results
, bLazyLoad
, null
, null
);
} catch (Exception e
) {
Logger
.error("operation failed", e
);
throw new MetaDataException(
"operation failed && baseDao.retrieveByPK,"
+ e
.getMessage());
}
return results
;
}
private void queryChildrenVOSByParentObjs(NCObject
[] parentObjs
,
boolean bLazyload
, Map
<String
, List
<String>> orderPathMap
,
String orderPath
) throws MetaDataException
{
queryChildrenVOSByParentObjs(parentObjs
, bLazyload
, orderPathMap
,
orderPath
, null
);
}
private void queryChildrenVOSByParentObjs(NCObject
[] parentObjs
,
boolean bLazyload
, Map
<String
, List
<String>> orderPathMap
,
String orderPath
, String
[] subEntityName
) throws MetaDataException
{
if (orderPathMap
== null
) {
orderPathMap
= new HashMap<String
, List
<String>>();
}
if (bLazyload
)
return;
if (parentObjs
== null
|| parentObjs
.length
== 0)
return;
IBusinessEntity parentEntity
= (IBusinessEntity
) parentObjs
[0]
.getRelatedBean();
resolveCompositeAssocations(parentObjs
, bLazyload
, parentEntity
,
orderPathMap
, orderPath
, subEntityName
);
resolveRelationAsscocations(parentObjs
, bLazyload
, parentEntity
,
orderPathMap
, orderPath
);
}
private void resolveRelationAsscocations(NCObject
[] parentObjs
,
boolean bLazyload
, IBusinessEntity parentEntity
,
Map
<String
, List
<String>> orderPathMap
, String orderPath
)
throws MetaDataException
{
List
<IAssociation> relationAsses
= parentEntity
.getAssociationsByKind(
AssociationKind
.Relation
, ICardinality
.ASS_ALL
);
if (relationAsses
!= null
&& relationAsses
.size() > 0) {
for (IAssociation association
: relationAsses
) {
if (association
.getEndCardinality().endsWith("1"))
resolveOne2OneRelation(association
, parentObjs
,
parentEntity
, bLazyload
, orderPathMap
, orderPath
);
else
Logger
.warn(NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voQueryPersister-0001"));
}
}
}
private void resolveOne2OneRelation(IAssociation association
,
NCObject
[] parentObjs
, IBusinessEntity parentEntity
,
boolean bLazyload
, Map
<String
, List
<String>> orderPathMap
,
String orderPath
) throws MetaDataException
{
IAttribute startAttr
= association
.getStartAttribute();
if (MDUtil
.isRefType(startAttr
.getDataType()))
return;
if (startAttr
.isCalculation())
return;
IBusinessEntity childEntity
= (IBusinessEntity
) association
.getEndBean();
if (startAttr
!= null
&& childEntity
!= null
) {
String pkOfChild
= childEntity
.getTable().getPrimaryKeyName();
String mockFKAttrName
= MDUtil
.getPKFieldNameOfAttribute(startAttr
);
HashSet
<String> pkinChildSet
= new HashSet<String>();
for (int i
= 0; i
< parentObjs
.length
; i
++) {
CircularlyAccessibleValueObject curVO
= (CircularlyAccessibleValueObject
) parentObjs
[i
]
.getModelConsistObject();
if (curVO
!= null
&& curVO
.getAttributeValue(mockFKAttrName
) != null
) {
pkinChildSet
.add(curVO
.getAttributeValue(mockFKAttrName
)
.toString());
}
}
String whereStr
= null
;
if (pkinChildSet
.size() > 0) {
whereStr
= "(";
whereStr
+= childEntity
.getTable().getName() + "." + pkOfChild
+ " in (";
whereStr
+= StringUtil
.getUnionStr(
(String
[]) pkinChildSet
.toArray(new String[0]), ",",
"'") + ") )";
if (ignoreDrEqual1
)
whereStr
= whereStr
+ " and isnull("
+ childEntity
.getTable().getName() + ".dr,0)=0";
}
if (orderPathMap
.containsKey(orderPath
)) {
whereStr
+= getOrderSqlPath(orderPathMap
.get(orderPath
));
orderPathMap
.remove(orderPath
);
}
Collection
<MappingMeta> mapData
= MDPersistUtil
.getMappingDataOfBeanWithExtendTable(childEntity
,
parentEntity
).values();
Collection results
= null
;
try {
MDMultiTableDAO dao
= new MDMultiTableDAO(childEntity
, mapData
);
results
= dao
.retrieveByClouse(whereStr
);
} catch (Exception e
) {
Logger
.error("error", e
);
throw new MetaDataException("operation failed!"
+ e
.getMessage());
}
if (results
!= null
&& results
.size() > 0) {
Map
<String, CircularlyAccessibleValueObject> resmap
= new HashMap<String, CircularlyAccessibleValueObject>();
for (Object obj
: results
) {
CircularlyAccessibleValueObject element
= (CircularlyAccessibleValueObject
) obj
;
resmap
.put(MDPersistUtil
.getPrimaryKeyValue(element
),
element
);
}
for (int i
= 0; i
< parentObjs
.length
; i
++) {
CircularlyAccessibleValueObject curVO
= (CircularlyAccessibleValueObject
) parentObjs
[i
]
.getModelConsistObject();
if (curVO
== null
)
continue;
CircularlyAccessibleValueObject childVO
= resmap
.get(curVO
.getAttributeValue(mockFKAttrName
));
if (childVO
!= null
)
parentObjs
[i
].setAttributeValue(startAttr
,
NCObject
.newInstance(childEntity
, childVO
));
}
if (!bLazyload
) {
}
}
}
}
private void resolveCompositeAssocations(NCObject
[] parentObjs
,
boolean bLazyload
, IBusinessEntity parentEntity
,
Map
<String
, List
<String>> orderPathMap
, String curPathFromRoot
,
String
[] subEntityNames
) throws MetaDataException
{
List
<IAssociation> compositeAsses
= parentEntity
.getAssociationsByKind(
AssociationKind
.Composite
, ICardinality
.ASS_ALL
);
if (compositeAsses
== null
|| compositeAsses
.size() == 0) {
return;
}
Set
<String> subPathSet
= new HashSet<String>();
boolean needSubEntityFilter
= false;
if (subEntityNames
!= null
&& subEntityNames
.length
> 0) {
needSubEntityFilter
= true;
for (String subPath
: subEntityNames
) {
subPathSet
.add(subPath
);
}
}
for (IAssociation association
: compositeAsses
) {
String orderPathTemp
= curPathFromRoot
;
IAttribute compAttr
= association
.getStartAttribute();
final IBusinessEntity childEntity
= (IBusinessEntity
) association
.getEndBean();
if (compAttr
== null
|| compAttr
.isCalculation()
|| childEntity
== null
) {
continue;
}
if (needSubEntityFilter
&& !subPathSet
.contains(compAttr
.getName())) {
continue;
}
String childPathFromRoot
= StringUtil
.isEmptyWithTrim(curPathFromRoot
) ? compAttr
.getName()
: curPathFromRoot
+ "." + compAttr
.getName();
String orderSqlPath
= "";
if (orderPathMap
.containsKey(childPathFromRoot
)) {
List
<String> orderPathList
= orderPathMap
.get(childPathFromRoot
);
orderSqlPath
= getOrderSqlPath(orderPathList
);
orderPathMap
.remove(childPathFromRoot
);
}
List
<String> pkvalues
= new ArrayList<String>();
for (int i
= 0; i
< parentObjs
.length
; i
++) {
CircularlyAccessibleValueObject curVO
= (CircularlyAccessibleValueObject
) parentObjs
[i
]
.getModelConsistObject();
if (curVO
== null
)
continue;
pkvalues
.add(MDPersistUtil
.getPrimaryKeyValue(curVO
));
}
IForeignKey foreignKey
= parentEntity
.getTable()
.getForeignKeieFromSubTable(
childEntity
.getTable().getName());
if (foreignKey
== null
)
throw new MetaDataException(NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voQueryPersister-0002")
+ childEntity
.getTable().getName() + NCLangResOnserver
.getInstance().getStrByID("mdbusi", "voQueryPersister-0003")
+ parentEntity
.getTable().getName());
final String parentKeyInChild
= foreignKey
.getStartColumn()
.getName();
final Collection
<MappingMeta> mapData
= MDPersistUtil
.getMappingDataOfBeanWithExtendTable(childEntity
,
parentEntity
).values();
String pkFieldName
= childEntity
.getTable().getName() + "."
+ parentKeyInChild
;
MDMultiTableDAO childDAO
= new MDMultiTableDAO(childEntity
, mapData
);
Collection results
= childDAO
.retrieveByPKS(pkFieldName
,
(String
[]) pkvalues
.toArray(new String[0]), null
,
ignoreDrEqual1
, orderSqlPath
);
Map
<String
, List
<NCObject>> childvosMap
= new HashMap<String
, List
<NCObject>>();
if (results
!= null
&& results
.size() > 0) {
List
<NCObject> childNCObjsList
= new ArrayList<NCObject>();
for (Object cvoObj
: results
) {
CircularlyAccessibleValueObject cvo
= (CircularlyAccessibleValueObject
) cvoObj
;
NCObject newObj
= NCObject
.newInstance(childEntity
, cvo
);
childNCObjsList
.add(newObj
);
}
if (!bLazyload
)
queryChildrenVOSByParentObjs(
(NCObject
[]) childNCObjsList
.toArray(new NCObject[0]),
bLazyload
, orderPathMap
, orderPathTemp
);
for (NCObject ncObj
: childNCObjsList
) {
CircularlyAccessibleValueObject cvo
= (CircularlyAccessibleValueObject
) ncObj
.getContainmentObject();
String parentKeyValue
= (String
) cvo
.getAttributeValue(parentKeyInChild
);
List
<NCObject> ncObjList
= childvosMap
.get(parentKeyValue
);
if (ncObjList
== null
) {
ncObjList
= new ArrayList<NCObject>();
childvosMap
.put(parentKeyValue
, ncObjList
);
}
ncObjList
.add(ncObj
);
}
}
for (int i
= 0; i
< parentObjs
.length
; i
++) {
CircularlyAccessibleValueObject curVO
= (CircularlyAccessibleValueObject
) parentObjs
[i
]
.getModelConsistObject();
if (curVO
== null
)
continue;
Object childValues
= childvosMap
.get(MDPersistUtil
.getPrimaryKeyValue(curVO
));
if (childValues
!= null
) {
if (association
.getEndCardinality().endsWith("n"))
parentObjs
[i
].setAttributeValue(compAttr
, childValues
);
else {
List
<NCObject> ncObjList
= (List
<NCObject>) childValues
;
if (ncObjList
!= null
&& ncObjList
.size() > 0)
parentObjs
[i
].setAttributeValue(compAttr
,
ncObjList
.get(0));
}
}
}
}
}
private String
getOrderSqlPath(List
<String> orderPathList
) {
String orderSqlPath
= "";
for (String orderTemp
: orderPathList
) {
orderSqlPath
+= orderTemp
+ ",";
}
orderSqlPath
= " order by "
+ orderSqlPath
.substring(0, orderSqlPath
.length() - 1) + " ";
return orderSqlPath
;
}
private Map
<String
, List
<String>> getOrderMap(String
[] orderPaths
) {
Map
<String
, List
<String>> pathMap
= new HashMap<String
, List
<String>>();
if (orderPaths
!= null
&& orderPaths
.length
> 0) {
for (String orderPath
: orderPaths
) {
if (!StringUtil
.isEmptyWithTrim(orderPath
)) {
String tableName
= relatedEntity
.getAttributeByPath(orderPath
).getTable().getName();
String
[] paths
= StringUtil
.split(orderPath
, ".");
if (paths
.length
== 1) {
tableName
= relatedTableAliasMap
.get(tableName
);
}
String value
= paths
[paths
.length
- 1];
String key
= orderPath
.substring(0, orderPath
.length()
- value
.length());
if (StringUtil
.isEmptyWithTrim(key
)) {
key
= FIRST_ORDERPATH_KEY
;
} else {
key
= key
.substring(0, key
.length() - 1);
}
if (!pathMap
.containsKey(key
)) {
List
<String> pathList
= new ArrayList<String>();
pathMap
.put(key
, pathList
);
}
String salOrderVaule
= tableName
+ "." + value
;
pathMap
.get(key
).add(salOrderVaule
);
}
}
}
return pathMap
;
}
}
调用:
public Collection
queryBillOfVOByCond(Class
voClass, String whereCondStr
, boolean ignoreDrEqual1
, boolean bLazyLoad
, String
[] orderPaths
) throws MetaDataException
{
NCObject
[] ncObjs
= new VOQueryPersister(voClass
.getName(), gnoreDrEqual1
).queryBillsImp( whereCondStr
, bLazyLoad
, orderPaths
);
List resList
= new ArrayList();
if (ncObjs
!= null
) {
for (int i
= 0; i
< ncObjs
.length
; i
++) {
resList
.add(ncObjs
[i
].getContainmentObject());
}
}
return resList
;
}