OSDN Git Service

"https://svn.sourceforge.jp/svnroot/ea2ddl" にプロジェクト "ea2ddl-dao" を共用
[ea2ddl/ea2ddl.git] / ea2ddl-dao / src / main / java / jp / sourceforge / ea2ddl / dao / allcommon / s2dao / internal / rshandler / InternalBeanListMetaDataResultSetHandler.java
1 package jp.sourceforge.ea2ddl.dao.allcommon.s2dao.internal.rshandler;\r
2 \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
10 \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
20 \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
24 \r
25 /**\r
26  * @author DBFlute(AutoGenerator)\r
27  */\r
28 @SuppressWarnings("unchecked")\r
29 public class InternalBeanListMetaDataResultSetHandler extends InternalAbstractBeanMetaDataResultSetHandler {\r
30 \r
31         // ===================================================================================\r
32     //                                                                         Constructor\r
33     //                                                                         ===========\r
34     /**\r
35          * @param beanMetaData Bean meta data. (NotNull)\r
36      * @param rowCreator Row creator. (NotNull)\r
37      * @param relationRowCreator Relation row creator. (NotNul)\r
38      */\r
39     public InternalBeanListMetaDataResultSetHandler(BeanMetaData beanMetaData, RowCreator rowCreator, RelationRowCreator relationRowCreator) {\r
40         super(beanMetaData, rowCreator, relationRowCreator);\r
41     }\r
42         \r
43         // ===================================================================================\r
44     //                                                                              Handle\r
45     //                                                                              ======\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
52 \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
57         {\r
58             final boolean emptyRelation = isSelectedForeignInfoEmpty();\r
59             final boolean hasOSC = hasOutsideSqlContext();\r
60             final boolean specifiedOutsideSql = isSpecifiedOutsideSql();\r
61 \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
66         }\r
67 \r
68         while (rs.next()) {\r
69                         if (columnNames == null) {\r
70                             columnNames = createColumnNames(rs.getMetaData());\r
71                         }\r
72             if (propertyCache == null) {\r
73                 propertyCache = createPropertyCache(columnNames);\r
74             }\r
75 \r
76             // Create row instance of base table by row property cache.\r
77             final Object row = createRow(rs, propertyCache);\r
78 \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
83                 postCreateRow(row);\r
84                 list.add(row);\r
85                 continue;\r
86             }\r
87 \r
88             if (relationPropertyCache == null) {\r
89                 relationPropertyCache = createRelationPropertyCache(columnNames);\r
90             }\r
91             if (relRowCache == null) {\r
92                 relRowCache = new RelationRowCache(relSize);\r
93             }\r
94             for (int i = 0; i < relSize; ++i) {\r
95                 final RelationPropertyType rpt = getBeanMetaData().getRelationPropertyType(i);\r
96                 if (rpt == null) {\r
97                     continue;\r
98                 }\r
99 \r
100                 // Do only selected foreign property for performance if condition-bean exists.\r
101                 if (hasCB && !hasSelectedForeignInfo(buildRelationNoSuffix(rpt))) {\r
102                     continue;\r
103                 }\r
104 \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
115                         }\r
116                     }\r
117                 }\r
118                 if (relationRow != null) {\r
119                     final PropertyDesc pd = rpt.getPropertyDesc();\r
120                     pd.setValue(row, relationRow);\r
121                 }\r
122             }\r
123             postCreateRow(row);\r
124             list.add(row);\r
125         }\r
126         return list;\r
127     }\r
128 \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
138             } else {\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
143                 } else {\r
144                     return null;\r
145                 }\r
146             }\r
147             final Object value = valueType.getValue(rs, columnName);\r
148             if (value == null) {\r
149                 return null;\r
150             }\r
151             relKeyValues.put(columnName, value);\r
152             keyList.add(value);\r
153         }\r
154         if (keyList.size() > 0) {\r
155             Object[] keys = keyList.toArray();\r
156             return new RelationKey(keys);\r
157         } else {\r
158             return null;\r
159         }\r
160     }\r
161     \r
162     // ===================================================================================\r
163     //                                                                       Assist Helper\r
164     //                                                                       =============\r
165     protected boolean hasConditionBean() {\r
166         return ConditionBeanContext.isExistConditionBeanOnThread();\r
167     }\r
168 \r
169     protected boolean isSelectedForeignInfoEmpty() {\r
170         if (!hasConditionBean()) {\r
171             return true;\r
172         }\r
173         ConditionBean cb = ConditionBeanContext.getConditionBeanOnThread();\r
174         if (cb.getSqlClause().isSelectedForeignInfoEmpty()) {\r
175             return true;\r
176         }\r
177         return false;\r
178     }\r
179 \r
180     /**\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
185      */\r
186     protected boolean hasSelectedForeignInfo(String relationNoSuffix) {\r
187         final ConditionBean cb = ConditionBeanContext.getConditionBeanOnThread();\r
188         if (cb.getSqlClause().hasSelectedForeignInfo(relationNoSuffix)) {\r
189             return true;\r
190         }\r
191         return false;\r
192     }\r
193 \r
194     /**\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
198      */\r
199     protected String buildRelationNoSuffix(RelationPropertyType rpt) {\r
200         return "_" + rpt.getRelationNo();\r
201     }\r
202 \r
203     protected boolean hasOutsideSqlContext() {\r
204         return OutsideSqlContext.isExistOutsideSqlContextOnThread();\r
205     }\r
206 \r
207     protected boolean isSpecifiedOutsideSql() {\r
208         if (!hasOutsideSqlContext()) {\r
209             return false;\r
210         }\r
211         final OutsideSqlContext context = OutsideSqlContext.getOutsideSqlContextOnThread();\r
212         return context.isSpecifiedOutsideSql();\r
213     }\r
214 }\r