1 package jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.rshandler;
\r
3 import java.util.ArrayList;
\r
4 import java.util.HashMap;
\r
5 import java.util.List;
\r
6 import java.util.Map;
\r
7 import java.util.Set;
\r
8 import java.sql.ResultSet;
\r
9 import java.sql.SQLException;
\r
11 import org.seasar.framework.beans.PropertyDesc;
\r
12 import org.seasar.extension.jdbc.PropertyType;
\r
13 import org.seasar.extension.jdbc.ValueType;
\r
14 import org.seasar.dao.BeanMetaData;
\r
15 import org.seasar.dao.RelationPropertyType;
\r
16 import org.seasar.dao.RelationRowCreator;
\r
17 import org.seasar.dao.RowCreator;
\r
18 import org.seasar.dao.impl.RelationKey;
\r
19 import org.seasar.dao.impl.RelationRowCache;
\r
21 import jp.sourceforge.ea2ddl.dao.allcommon.cbean.ConditionBean;
\r
22 import jp.sourceforge.ea2ddl.dao.allcommon.cbean.ConditionBeanContext;
\r
23 import jp.sourceforge.ea2ddl.dao.allcommon.cbean.outsidesql.OutsideSqlContext;
\r
26 * @author DBFlute(AutoGenerator)
\r
28 @SuppressWarnings("unchecked")
\r
29 public class InternalBeanListMetaDataResultSetHandler extends InternalAbstractBeanMetaDataResultSetHandler {
\r
31 // ===================================================================================
\r
35 * @param beanMetaData Bean meta data. (NotNull)
\r
36 * @param rowCreator Row creator. (NotNull)
\r
37 * @param relationRowCreator Relation row creator. (NotNul)
\r
39 public InternalBeanListMetaDataResultSetHandler(BeanMetaData beanMetaData, RowCreator rowCreator, RelationRowCreator relationRowCreator) {
\r
40 super(beanMetaData, rowCreator, relationRowCreator);
\r
43 // ===================================================================================
\r
46 public Object handle(ResultSet rs) throws SQLException {
\r
47 // Lazy initialization because if the result is zero, the resources are unused.
\r
48 Set columnNames = null; // Set<String(columnName)>
\r
49 Map propertyCache = null; // Map<String(columnName), PropertyType>
\r
50 Map relationPropertyCache = null; // Map<String(relationNoSuffix), Map<String(columnName), PropertyType>>
\r
51 RelationRowCache relRowCache = null;
\r
53 final List list = new ArrayList();
\r
54 final int relSize = getBeanMetaData().getRelationPropertyTypeSize();
\r
55 final boolean hasCB = hasConditionBean();
\r
56 final boolean skipRelationLoop;
\r
58 final boolean emptyRelation = isSelectedForeignInfoEmpty();
\r
59 final boolean hasOSC = hasOutsideSqlContext();
\r
60 final boolean specifiedOutsideSql = isSpecifiedOutsideSql();
\r
62 // If it has condition-bean that has no relation to get
\r
63 // or it has outside-sql context that is specified-outside-sql,
\r
64 // they are unnecessary to do relation loop!
\r
65 skipRelationLoop = (hasCB && emptyRelation) || (hasOSC && specifiedOutsideSql);
\r
69 if (columnNames == null) {
\r
70 columnNames = createColumnNames(rs.getMetaData());
\r
72 if (propertyCache == null) {
\r
73 propertyCache = createPropertyCache(columnNames);
\r
76 // Create row instance of base table by row property cache.
\r
77 final Object row = createRow(rs, propertyCache);
\r
79 // If it has condition-bean that has no relation to get
\r
80 // or it has outside-sql context that is specified-outside-sql,
\r
81 // they are unnecessary to do relation loop!
\r
82 if (skipRelationLoop) {
\r
88 if (relationPropertyCache == null) {
\r
89 relationPropertyCache = createRelationPropertyCache(columnNames);
\r
91 if (relRowCache == null) {
\r
92 relRowCache = new RelationRowCache(relSize);
\r
94 for (int i = 0; i < relSize; ++i) {
\r
95 final RelationPropertyType rpt = getBeanMetaData().getRelationPropertyType(i);
\r
100 // Do only selected foreign property for performance if condition-bean exists.
\r
101 if (hasCB && !hasSelectedForeignInfo(buildRelationNoSuffix(rpt))) {
\r
105 final Map relKeyValues = new HashMap();
\r
106 final RelationKey relKey = createRelationKey(rs, rpt, columnNames, relKeyValues);
\r
107 Object relationRow = null;
\r
108 if (relKey != null) {
\r
109 relationRow = relRowCache.getRelationRow(i, relKey);
\r
110 if (relationRow == null) { // when no cache
\r
111 relationRow = createRelationRow(rs, rpt, columnNames, relKeyValues, relationPropertyCache);
\r
112 if (relationRow != null) {
\r
113 relRowCache.addRelationRow(i, relKey, relationRow);
\r
114 postCreateRow(relationRow);
\r
118 if (relationRow != null) {
\r
119 final PropertyDesc pd = rpt.getPropertyDesc();
\r
120 pd.setValue(row, relationRow);
\r
123 postCreateRow(row);
\r
129 protected RelationKey createRelationKey(ResultSet rs, RelationPropertyType rpt, Set columnNames, Map relKeyValues) throws SQLException {
\r
130 final List keyList = new ArrayList();
\r
131 final BeanMetaData bmd = rpt.getBeanMetaData();
\r
132 for (int i = 0; i < rpt.getKeySize(); ++i) {
\r
133 final ValueType valueType;
\r
134 String columnName = rpt.getMyKey(i);
\r
135 if (columnNames.contains(columnName)) {
\r
136 final PropertyType pt = getBeanMetaData().getPropertyTypeByColumnName(columnName);
\r
137 valueType = pt.getValueType();
\r
139 final PropertyType pt = bmd.getPropertyTypeByColumnName(rpt.getYourKey(i));
\r
140 columnName = pt.getColumnName() + buildRelationNoSuffix(rpt);
\r
141 if (columnNames.contains(columnName)) {
\r
142 valueType = pt.getValueType();
\r
147 final Object value = valueType.getValue(rs, columnName);
\r
148 if (value == null) {
\r
151 relKeyValues.put(columnName, value);
\r
152 keyList.add(value);
\r
154 if (keyList.size() > 0) {
\r
155 Object[] keys = keyList.toArray();
\r
156 return new RelationKey(keys);
\r
162 // ===================================================================================
\r
165 protected boolean hasConditionBean() {
\r
166 return ConditionBeanContext.isExistConditionBeanOnThread();
\r
169 protected boolean isSelectedForeignInfoEmpty() {
\r
170 if (!hasConditionBean()) {
\r
173 ConditionBean cb = ConditionBeanContext.getConditionBeanOnThread();
\r
174 if (cb.getSqlClause().isSelectedForeignInfoEmpty()) {
\r
181 * Has it selected foreign information?
\r
182 * You should call hasConditionBean() before calling this!
\r
183 * @param relationNoSuffix The suffix of relation NO. (NotNull)
\r
184 * @return Determination.
\r
186 protected boolean hasSelectedForeignInfo(String relationNoSuffix) {
\r
187 final ConditionBean cb = ConditionBeanContext.getConditionBeanOnThread();
\r
188 if (cb.getSqlClause().hasSelectedForeignInfo(relationNoSuffix)) {
\r
195 * Build the string of relation No suffix.
\r
196 * @param rpt The property type of relation. (NotNull)
\r
197 * @return The string of relation No suffix. (NotNull)
\r
199 protected String buildRelationNoSuffix(RelationPropertyType rpt) {
\r
200 return "_" + rpt.getRelationNo();
\r
203 protected boolean hasOutsideSqlContext() {
\r
204 return OutsideSqlContext.isExistOutsideSqlContextOnThread();
\r
207 protected boolean isSpecifiedOutsideSql() {
\r
208 if (!hasOutsideSqlContext()) {
\r
211 final OutsideSqlContext context = OutsideSqlContext.getOutsideSqlContextOnThread();
\r
212 return context.isSpecifiedOutsideSql();
\r