OSDN Git Service

DBFlute-0.9.3に更新
[ea2ddl/ea2ddl.git] / ea2ddl-gen / dbflute / templates / om / csharp / allcommon / s2dao / S2DaoMetaDataFactoryImpl.vmnet
1 \r
2 using System;\r
3 using System.Data;\r
4 using System.Collections;\r
5 using System.Reflection;\r
6 using System.Text;\r
7 \r
8 using Seasar.Framework.Util;\r
9 using Seasar.Extension.ADO;\r
10 using Seasar.Extension.ADO.Impl;\r
11 using Seasar.Dao;\r
12 using Seasar.Dao.Impl;\r
13 \r
14 using ${glPackageBaseCommonCBean};\r
15 using ${glPackageBaseCommonDBMeta};\r
16 using ${glPackageBaseCommonJavaLike};\r
17 using ${glPackageBaseCommonS2DaoInternalRsHandler};\r
18 \r
19 namespace ${glPackageBaseCommonS2Dao} {\r
20 \r
21     public class ${glS2DaoMetaDataFactoryImpl} : Seasar.Dao.IDaoMetaDataFactory {\r
22 \r
23         // ===============================================================================\r
24         //                                                                      Definition\r
25         //                                                                      ==========\r
26         private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);\r
27 \r
28         // ===============================================================================\r
29         //                                                                       Attribute\r
30         //                                                                       =========\r
31         private readonly Hashtable _daoMetaDataCache = new Hashtable();\r
32         protected readonly IDataSource _dataSource;\r
33         protected readonly ICommandFactory _commandFactory;\r
34         protected readonly IDataReaderFactory _dataReaderFactory;\r
35         protected readonly IAnnotationReaderFactory _readerFactory;\r
36         protected IDatabaseMetaData _dbMetaData;\r
37         protected string _sqlFileEncoding = Encoding.Default.WebName;\r
38         protected string[] _insertPrefixes;\r
39         protected string[] _updatePrefixes;\r
40         protected string[] _deletePrefixes;\r
41                 protected Map<Type, IBeanMetaData> _beanMetaDataCacheMap = new HashMap<Type, IBeanMetaData>();\r
42 \r
43         // ===============================================================================\r
44         //                                                                     Constructor\r
45         //                                                                     ===========\r
46         public ${glS2DaoMetaDataFactoryImpl}(IDataSource dataSource,\r
47             ICommandFactory commandFactory, IAnnotationReaderFactory readerFactory,\r
48             IDataReaderFactory dataReaderFactory) {\r
49             _dataSource = dataSource;\r
50             _commandFactory = commandFactory;\r
51             _readerFactory = readerFactory;\r
52             _dataReaderFactory = dataReaderFactory;\r
53         }\r
54 \r
55         // ===============================================================================\r
56         //                                                                  Implementation\r
57         //                                                                  ==============\r
58         public IDaoMetaData GetDaoMetaData(Type daoType) {\r
59             lock (this) {\r
60                 string key = daoType.FullName;\r
61                 IDaoMetaData dmd = (IDaoMetaData)_daoMetaDataCache[key];\r
62                 if (dmd != null) {\r
63                     return dmd;\r
64                 }\r
65                 if (_log.IsDebugEnabled) {\r
66                     _log.Debug("...Creating daoMetaData for '" + daoType.Name + "'.");\r
67                 }\r
68                 dmd = CreateDaoMetaData(daoType);\r
69                 _daoMetaDataCache[key] = dmd;\r
70                 return dmd;\r
71             }\r
72         }\r
73 \r
74         protected virtual IDaoMetaData CreateDaoMetaData(Type daoType) {\r
75             ${glS2DaoMetaDataExtension} dmd = NewDaoMetaDataExtension();\r
76             dmd.DaoType = daoType;\r
77             dmd.DataSource = _dataSource;\r
78             dmd.CommandFactory = _commandFactory;\r
79             dmd.DataReaderFactory = _dataReaderFactory;\r
80             dmd.DataReaderHandlerFactory = CreateInternalDataReaderHandlerFactory();\r
81             dmd.AnnotationReaderFactory = _readerFactory;\r
82             if (_dbMetaData == null) {\r
83                 _dbMetaData = new DatabaseMetaDataImpl(_dataSource);\r
84             }\r
85             dmd.DatabaseMetaData = _dbMetaData;\r
86             if (_sqlFileEncoding != null) {\r
87                 dmd.SqlFileEncoding = _sqlFileEncoding;\r
88             }\r
89             if (_insertPrefixes != null) {\r
90                 dmd.InsertPrefixes = _insertPrefixes;\r
91             }\r
92             if (_updatePrefixes != null) {\r
93                 dmd.UpdatePrefixes = _updatePrefixes;\r
94             }\r
95             if (_deletePrefixes != null) {\r
96                 dmd.DeletePrefixes = _deletePrefixes;\r
97             }\r
98                         dmd.BeanMetaDataCacheMap = _beanMetaDataCacheMap;\r
99             dmd.Initialize();\r
100             return dmd;\r
101         }\r
102 \r
103         protected virtual ${glS2DaoMetaDataExtension} NewDaoMetaDataExtension() {\r
104             return new ${glS2DaoMetaDataExtension}();\r
105         }\r
106 \r
107         protected virtual InternalDataReaderHandlerFactory CreateInternalDataReaderHandlerFactory() {\r
108             return new InternalDataReaderHandlerFactory();\r
109         }\r
110 \r
111         // ===============================================================================\r
112         //                                                                        Accessor\r
113         //                                                                        ========\r
114         public IDatabaseMetaData DBMetaData {\r
115             set { _dbMetaData = value; }\r
116         }\r
117 \r
118         public string[] InsertPrefixes {\r
119             set { _insertPrefixes = value; }\r
120         }\r
121 \r
122         public string[] UpdatePrefixes {\r
123             set { _updatePrefixes = value; }\r
124         }\r
125 \r
126         public string[] DeletePrefixes {\r
127             set { _deletePrefixes = value; }\r
128         }\r
129 \r
130         public string SqlFileEncoding {\r
131             set { _sqlFileEncoding = value; }\r
132         }\r
133     }\r
134 \r
135     // ===================================================================================\r
136     //                                                                           Procedure\r
137     //                                                                           =========\r
138     public class InternalProcedureMetaData {\r
139         protected String _procedureName;\r
140         protected LinkedHashMap<String, InternalProcedureParameterType> parameterTypeMap = new LinkedHashMap<String, InternalProcedureParameterType>();\r
141         protected Type _returnType;\r
142         public InternalProcedureMetaData(String procedureName) {\r
143             _procedureName = procedureName;\r
144         }\r
145         public String ProcedureName { get {\r
146             return _procedureName;\r
147         } set {\r
148             _procedureName = value;\r
149         }}\r
150         public InternalProcedureParameterType GetParameterType(int index) {\r
151             return parameterTypeMap.get(index);\r
152         }\r
153         public InternalProcedureParameterType GetParameterType(String parameterName) {\r
154             return parameterTypeMap.get(parameterName.ToLower());\r
155         }\r
156         public int ParameterTypeSize { get {\r
157             return parameterTypeMap.size();\r
158         }}\r
159         public bool HasReturnParameterType { get {\r
160             return _returnType != null;\r
161         }}\r
162         public Type ReturnParameterType { get {\r
163             return _returnType;\r
164         }}\r
165         public void AddParameterType(InternalProcedureParameterType parameterType) {\r
166             String name = parameterType.ParameterName;\r
167             parameterTypeMap.put(name.ToLower(), parameterType);\r
168             if (parameterType.IsReturnType) {\r
169                 _returnType = parameterType.ParameterPropertyType;\r
170             }\r
171         }\r
172     }\r
173 \r
174     public class InternalProcedureParameterType {\r
175         protected String _parameterName;\r
176         protected PropertyInfo _parameterProperty;\r
177         protected Type _parameterPropertyType;\r
178         protected ParameterDirection _parameterDirectionType;\r
179         protected bool _inType;\r
180         protected bool _outType;\r
181         protected bool _returnType;\r
182         public InternalProcedureParameterType(String parameterName, PropertyInfo parameterProperty) {\r
183             _parameterName = parameterName;\r
184             _parameterProperty = parameterProperty;\r
185             _parameterPropertyType = parameterProperty.PropertyType;\r
186         }\r
187         public Object GetValue(Object dto) {\r
188             return _parameterProperty.GetValue(dto, null);\r
189         }\r
190         public void SetValue(Object dto, Object value) {\r
191             _parameterProperty.SetValue(dto, value, null);\r
192         }\r
193         public String ParameterName { get { return _parameterName; } }\r
194         public PropertyInfo ParameterProperty { get { return _parameterProperty; } }\r
195         public Type ParameterPropertyType { get { return _parameterPropertyType; } }\r
196         public ParameterDirection ParameterDirectionType { get { return _parameterDirectionType; } set { _parameterDirectionType = value; } }\r
197         public bool IsInType { get { return _inType; } set { _inType = value; } }\r
198         public bool IsOutType { get { return _outType; } set { _outType = value; } }\r
199         public bool IsReturnType { get { return _returnType; } set { _returnType = value; } }\r
200     }\r
201 \r
202     public class InternalProcedureMetaDataFactory {\r
203         protected InternalFieldProcedureAnnotationReader _annotationReader = new InternalFieldProcedureAnnotationReader();\r
204         public InternalProcedureMetaData CreateProcedureMetaData(String procedureName, Type pmbType) {\r
205             InternalProcedureMetaData metaData = new InternalProcedureMetaData(procedureName);\r
206             if (pmbType == null) {\r
207                 return metaData;\r
208             } else {\r
209                 if (!IsDtoType(pmbType)) {\r
210                     throw new IllegalStateException("The pmb type is Not DTO type: " + pmbType.Name);\r
211                 }\r
212             }\r
213             RegisterParameterType(metaData, pmbType, pmbType.GetProperties());\r
214             return metaData;\r
215         }\r
216         protected void RegisterParameterType(InternalProcedureMetaData metaData, Type pmbType, PropertyInfo[] properties) {\r
217             foreach (PropertyInfo property in properties) {\r
218                 InternalProcedureParameterType ppt = GetProcedureParameterType(pmbType, property);\r
219                 if (ppt == null) {\r
220                     continue;\r
221                 }\r
222                 metaData.AddParameterType(ppt);\r
223             }\r
224         }\r
225         protected InternalProcedureParameterType GetProcedureParameterType(Type pmbType, PropertyInfo property) {\r
226             InternalProcedureParameterInfo info = _annotationReader.GetProcedureParameter(pmbType, property);\r
227             if (info == null) {\r
228                 return null;\r
229             }\r
230             String name = info.ParameterName;\r
231             String type = info.ParameterType;\r
232             type = type.ToLower();\r
233             InternalProcedureParameterType ppt = new InternalProcedureParameterType(name, property);\r
234             if (type.Equals("in")) {\r
235                 ppt.IsInType = true;\r
236                 ppt.ParameterDirectionType = ParameterDirection.Input;\r
237             } else if (type.Equals("out")) {\r
238                 ppt.IsOutType = true;\r
239                 ppt.ParameterDirectionType = ParameterDirection.Output;\r
240             } else if (type.Equals("inout")) {\r
241                 ppt.IsInType = true;\r
242                 ppt.IsOutType = true;\r
243                 ppt.ParameterDirectionType = ParameterDirection.InputOutput;\r
244             } else if (type.Equals("return")) {\r
245                 ppt.IsOutType = true;\r
246                 ppt.IsReturnType = true;\r
247                 ppt.ParameterDirectionType = ParameterDirection.ReturnValue;\r
248             } else {\r
249                 throw new IllegalStateException("The parameter type is wrong: type=" + type);\r
250             }\r
251             return ppt;\r
252         }\r
253         protected bool IsDtoType(Type clazz) {\r
254             return true; // No check because no time.\r
255         }\r
256     }\r
257 \r
258     public class InternalFieldProcedureAnnotationReader {\r
259         protected String PROCEDURE_PARAMETER_SUFFIX;\r
260         public InternalFieldProcedureAnnotationReader() {\r
261             PROCEDURE_PARAMETER_SUFFIX = "_PROCEDURE_PARAMETER";\r
262         }\r
263         public InternalProcedureParameterInfo GetProcedureParameter(Type pmbType, PropertyInfo property) {\r
264             String propertyName = property.Name;\r
265             String annotationName = InitUncap(propertyName) + PROCEDURE_PARAMETER_SUFFIX;\r
266             FieldInfo field = pmbType.GetField(annotationName, BindingFlags.Public | BindingFlags.Static);\r
267             if (field != null) {\r
268                 String annotationValue = (String)field.GetValue(null);\r
269                 InternalProcedureParameterInfo info = new InternalProcedureParameterInfo();\r
270                 String[] values = annotationValue.Split(',');\r
271                 if (values.Length != 2) {\r
272                     String msg = "The value of annotation is wrong.";\r
273                     msg = msg + " You should set '[parameterName], [parameterType]'.";\r
274                     msg = msg + " But: annotation=" + annotationName + " value=" + annotationValue;\r
275                     throw new IllegalStateException(msg);\r
276                 }\r
277                 info.ParameterName = values[0].Trim();\r
278                 info.ParameterType = values[1].Trim();\r
279                 return info;\r
280             } else {\r
281                 return null;\r
282             }\r
283         }\r
284         protected String InitUncap(String str) {\r
285             return str.Substring(0, 1).ToLower() + str.Substring(1);\r
286         }\r
287     }\r
288 \r
289     public class InternalProcedureParameterInfo {\r
290         protected String _parameterName;\r
291         protected String _parameterType;\r
292         public String ParameterName { get { return _parameterName; } set { _parameterName = value; } }\r
293         public String ParameterType { get { return _parameterType; } set { _parameterType = value; } }\r
294     }\r
295 \r
296     // ===================================================================================\r
297     //                                                                         Row Creator\r
298     //                                                                         ===========\r
299     public class InternalRowCreator : RowCreatorImpl {\r
300 \r
301         protected ${glDBMetaInterfaceName} _dbmeta;\r
302         public ${glDBMetaInterfaceName} DBMeta { set { _dbmeta = value; } }\r
303 \r
304         public static InternalRowCreator CreateInternalRowCreator(Type beanClass) {\r
305             InternalRowCreator rowCreator = new InternalRowCreator();\r
306             if (beanClass != null) {\r
307                 rowCreator.DBMeta = FindDBMetaByClass(beanClass);\r
308             }\r
309             return rowCreator;\r
310         }\r
311 \r
312         protected static ${glDBMetaInterfaceName} FindDBMetaByClass(Type beanClass) {\r
313             Object instance = NewInstance(beanClass);\r
314             if (!(instance is ${glEntityInterfaceName})) {\r
315                 return null;\r
316             }\r
317             return ((${glEntityInterfaceName})instance).DBMeta;\r
318         }\r
319 \r
320         protected static Object NewInstance(Type clazz) {\r
321             return ClassUtil.NewInstance(clazz);\r
322         }\r
323 \r
324         public override Object CreateRow(IDataReader reader, IColumnMetaData[] columns, Type beanType) {\r
325             Object row;\r
326             ${glDBMetaInterfaceName} dbmeta;\r
327             if (_dbmeta != null) {\r
328                 dbmeta = _dbmeta;\r
329                 row = dbmeta.NewEntity();\r
330             } else {\r
331                 row = NewBean(beanType);\r
332                 dbmeta = FindDBMeta(row);\r
333             }\r
334             if (dbmeta != null) {\r
335                 foreach (IColumnMetaData column in columns) {\r
336                     Object value = column.ValueType.GetValue(reader, column.ColumnName);\r
337                                 if (dbmeta.HasEntityPropertySetupper(column.PropertyInfo.Name)) {\r
338                                     dbmeta.SetupEntityProperty(column.PropertyInfo.Name, row, value);\r
339                                         continue;\r
340                     }\r
341                     column.PropertyInfo.SetValue(row, value, null);\r
342                 }\r
343             } else {\r
344                 foreach (IColumnMetaData column in columns) {\r
345                     Object value = column.ValueType.GetValue(reader, column.ColumnName);\r
346                     column.PropertyInfo.SetValue(row, value, null);\r
347                 }\r
348             }\r
349             return row;\r
350         }\r
351 \r
352                 public static ${glDBMetaInterfaceName} FindDBMeta(Object row) {\r
353                     return DBMetaCacheHandler.FindDBMeta(row);\r
354         }\r
355 \r
356                 public static ${glDBMetaInterfaceName} FindDBMeta(Type rowType, String tableName) {\r
357                     return DBMetaCacheHandler.FindDBMeta(rowType, tableName);\r
358         }\r
359     }\r
360 \r
361         public class DBMetaCacheHandler {\r
362             protected static readonly String DBMETA_CACHE_KEY = "df:DBMetaCache";\r
363                 \r
364                 public static ${glDBMetaInterfaceName} FindDBMeta(Object row) {\r
365                     if (!(row is ${glEntityInterfaceName})) {\r
366                             return null;\r
367                         }\r
368                         ${glEntityInterfaceName} entity = (${glEntityInterfaceName})row;\r
369             ${glDBMetaInterfaceName} dbmeta = FindCachedDBMeta(entity.GetType());\r
370                         if (dbmeta != null) {\r
371                             return dbmeta;\r
372                         }\r
373             dbmeta = entity.DBMeta;\r
374             CacheDBMeta(entity, dbmeta);\r
375                     return dbmeta;\r
376         }\r
377         \r
378         public static ${glDBMetaInterfaceName} FindDBMeta(Type rowType, String tableName) {\r
379             ${glDBMetaInterfaceName} dbmeta = FindCachedDBMeta(rowType);\r
380             if (dbmeta != null) {\r
381                 return dbmeta;\r
382             }\r
383             try {\r
384                 dbmeta = ${glDBMetaInstanceHandlerName}.FindDBMeta(tableName);\r
385             } catch (DBMetaNotFoundException) {\r
386                 return null;\r
387             }\r
388             CacheDBMeta(rowType, dbmeta);\r
389             return dbmeta;\r
390         }\r
391 \r
392         protected static ${glDBMetaInterfaceName} FindCachedDBMeta(Type rowType) {\r
393             System.Collections.Generic.IDictionary<Type, ${glDBMetaInterfaceName}> dbmetaCache = FindDBMetaCache();\r
394             if (dbmetaCache == null) {\r
395                 dbmetaCache = new System.Collections.Generic.Dictionary<Type, ${glDBMetaInterfaceName}>();\r
396                 ${glInternalMapContextName}.SetObject(DBMETA_CACHE_KEY, dbmetaCache);\r
397             }\r
398             if (dbmetaCache.ContainsKey(rowType)) {\r
399                 return dbmetaCache[rowType];\r
400             }\r
401             return null;\r
402         }\r
403         \r
404         protected static void CacheDBMeta(${glEntityInterfaceName} entity, ${glDBMetaInterfaceName} dbmeta) {\r
405             CacheDBMeta(entity.GetType(), dbmeta);\r
406         }\r
407         \r
408         protected static void CacheDBMeta(Type type, ${glDBMetaInterfaceName} dbmeta) {\r
409             System.Collections.Generic.IDictionary<Type, ${glDBMetaInterfaceName}> dbmetaCache = FindDBMetaCache();\r
410             dbmetaCache.Add(type, dbmeta);\r
411         }\r
412         \r
413         protected static System.Collections.Generic.IDictionary<Type, ${glDBMetaInterfaceName}> FindDBMetaCache() {\r
414             return (System.Collections.Generic.IDictionary<Type, ${glDBMetaInterfaceName}>)${glInternalMapContextName}.GetObject(DBMETA_CACHE_KEY);\r
415         }\r
416         }\r
417         \r
418     public class InternalRelationRowCreator : RelationRowCreatorImpl {\r
419 \r
420         protected override void SetupRelationKeyValue(RelationRowCreationResource res) {\r
421             IRelationPropertyType rpt = res.RelationPropertyType;\r
422             IBeanMetaData bmd = rpt.BeanMetaData;\r
423             ${glDBMetaInterfaceName} dbmeta = FindDBMeta(bmd.BeanType, bmd.TableName);\r
424             for (int i = 0; i < rpt.KeySize; ++i) {\r
425                 String columnName = rpt.GetMyKey(i) + res.BaseSuffix;\r
426 \r
427                 if (!res.ContainsColumnName(columnName)) {\r
428                     continue;\r
429                 }\r
430                 if (!res.HasRowInstance()) {\r
431                     Object row;\r
432                     if (dbmeta != null) {\r
433                         row = dbmeta.NewEntity();\r
434                     } else {\r
435                         row = NewRelationRow(rpt);\r
436                     }\r
437                     res.Row = row;\r
438                 }\r
439                 if (!res.ContainsRelKeyValueIfExists(columnName)) {\r
440                     continue;\r
441                 }\r
442                 Object value = res.ExtractRelKeyValue(columnName);\r
443                 if (value == null) {\r
444                     continue;\r
445                 }\r
446 \r
447                 String yourKey = rpt.GetYourKey(i);\r
448                 IPropertyType pt = bmd.GetPropertyTypeByColumnName(yourKey);\r
449                 PropertyInfo pi = pt.PropertyInfo;\r
450                 pi.SetValue(res.Row, value, null);\r
451                 continue;\r
452             }\r
453         }\r
454 \r
455         protected Object CreateRelationRowInstance(${glDBMetaInterfaceName} dbmeta) {\r
456             if (dbmeta != null) {\r
457                 return dbmeta.NewEntity();\r
458             }\r
459             return null;\r
460         }\r
461 \r
462         protected ${glDBMetaInterfaceName} FindDBMeta(Type rowType, String tableName) {\r
463             return ${glInternalRowCreator}.FindDBMeta(rowType, tableName);\r
464         }\r
465 \r
466         protected override void SetupRelationAllValue(RelationRowCreationResource res) {\r
467             System.Collections.Generic.IDictionary<String, IPropertyType> propertyCacheElement = res.ExtractPropertyCacheElement();\r
468             System.Collections.Generic.ICollection<String> columnNameCacheElementKeySet = propertyCacheElement.Keys;\r
469             foreach (String columnName in columnNameCacheElementKeySet) {\r
470                 IPropertyType pt = propertyCacheElement[columnName];\r
471                 res.CurrentPropertyType = pt;\r
472                 if (!IsValidRelationPerPropertyLoop(res)) {\r
473                     res.ClearRowInstance();\r
474                     return;\r
475                 }\r
476                 SetupRelationProperty(res);\r
477             }\r
478             if (!IsValidRelationAfterPropertyLoop(res)) {\r
479                 res.ClearRowInstance();\r
480                 return;\r
481             }\r
482             res.ClearValidValueCount();\r
483             if (res.HasNextRelationProperty() && (HasConditionBean(res) || res.HasNextRelationLevel())) {\r
484                 SetupNextRelationRow(res);\r
485             }\r
486         }\r
487 \r
488         protected override void RegisterRelationValue(RelationRowCreationResource res, String columnName) {\r
489             IPropertyType pt = res.CurrentPropertyType;\r
490             Object value = null;\r
491             if (res.ContainsRelKeyValueIfExists(columnName)) {\r
492                 value = res.ExtractRelKeyValue(columnName);\r
493             } else {\r
494                 IValueType valueType = pt.ValueType;\r
495                 value = valueType.GetValue(res.DataReader, columnName);\r
496             }\r
497             if (value != null) {\r
498                 res.IncrementValidValueCount();\r
499                                 ${glDBMetaInterfaceName} dbmeta = FindDBMeta(res.Row);\r
500                                 String propertyName = pt.PropertyName;\r
501                                 if (dbmeta != null && dbmeta.HasEntityPropertySetupper(propertyName)) {\r
502                                     dbmeta.SetupEntityProperty(propertyName, res.Row, value);\r
503                             } else {\r
504                     PropertyInfo pd = pt.PropertyInfo;\r
505                     pd.SetValue(res.Row, value, null);\r
506                                 }\r
507             }\r
508         }\r
509                 \r
510                 protected ${glDBMetaInterfaceName} FindDBMeta(Object row) {\r
511                     return ${glInternalRowCreator}.FindDBMeta(row);\r
512         }\r
513                 \r
514         protected override void SetupPropertyCache(RelationRowCreationResource res) {\r
515             // - - - - - - - - - - - \r
516             // Recursive Call Point!\r
517             // - - - - - - - - - - -\r
518             res.InitializePropertyCacheElement();\r
519 \r
520             // Do only selected foreign property for performance if condition-bean exists.\r
521             if (HasConditionBean(res) && !HasSelectedForeignInfo(res)) {\r
522                 return;\r
523             }\r
524 \r
525             // Set up property cache about current beanMetaData.\r
526             IBeanMetaData nextBmd = res.GetRelationBeanMetaData();\r
527             for (int i = 0; i < nextBmd.PropertyTypeSize; ++i) {\r
528                 IPropertyType pt = nextBmd.GetPropertyType(i);\r
529                 res.CurrentPropertyType = pt;\r
530                 if (!IsTargetProperty(res)) {\r
531                     continue;\r
532                 }\r
533                 SetupPropertyCacheElement(res);\r
534             }\r
535 \r
536             // Set up next relation.\r
537             if (res.HasNextRelationProperty() && (HasConditionBean(res) || res.HasNextRelationLevel())) {\r
538                 res.BackupRelationPropertyType();\r
539                 res.IncrementCurrentRelationNestLevel();\r
540                 try {\r
541                     SetupNextPropertyCache(res, nextBmd);\r
542                 } finally {\r
543                     res.RestoreRelationPropertyType();\r
544                     res.DecrementCurrentRelationNestLevel();\r
545                 }\r
546             }\r
547         }\r
548 \r
549         protected override bool IsTargetProperty(RelationRowCreationResource res) {\r
550             IPropertyType pt = res.CurrentPropertyType;\r
551             if (!pt.PropertyInfo.CanWrite) {\r
552                 return false;\r
553             }\r
554             if (typeof(System.Collections.Generic.IList<>).IsAssignableFrom(pt.PropertyInfo.GetType())) {\r
555                 return false;\r
556             }\r
557             return true;\r
558         }\r
559 \r
560         protected override bool IsCreateDeadLink() {\r
561             return false;\r
562         }\r
563 \r
564         protected override int GetLimitRelationNestLevel() {\r
565             return 2;\r
566         }\r
567 \r
568         protected bool HasConditionBean(RelationRowCreationResource res) {\r
569             return ${glConditionBeanContextName}.IsExistConditionBeanOnThread();\r
570         }\r
571 \r
572         protected bool HasSelectedForeignInfo(RelationRowCreationResource res) {\r
573             ${glConditionBeanInterfaceName} cb = ${glConditionBeanContextName}.GetConditionBeanOnThread();\r
574             if (cb.SqlClause.hasSelectedForeignInfo(res.RelationNoSuffix)) {\r
575                 return true;\r
576             }\r
577             return false;\r
578         }\r
579     }\r
580 \r
581     // ===================================================================================\r
582     //                                                                 Data Reader Handler\r
583     //                                                                 ===================\r
584     public class InternalDataReaderHandlerFactory : IDataReaderHandlerFactory {\r
585         public virtual IDataReaderHandler GetResultSetHandler(Type beanType, IBeanMetaData bmd, MethodInfo mi) {\r
586             Type retType = mi.ReturnType;\r
587             if (typeof(DataSet).IsAssignableFrom(retType)) {\r
588                 return CreateBeanDataSetMetaDataDataReaderHandler(bmd, retType);\r
589             } else if (typeof(DataTable).IsAssignableFrom(retType)) {\r
590                 return CreateBeanDataTableMetaDataDataReaderHandler(bmd, retType);\r
591             } else if (retType.IsArray) {\r
592                 Type elementType = retType.GetElementType();\r
593                 if (AssignTypeUtil.IsSimpleType(elementType)) {\r
594                     return CreateObjectArrayDataReaderHandler(elementType);\r
595                 } else {\r
596                     return CreateBeanArrayMetaDataDataReaderHandler(bmd);\r
597                 }\r
598             } else if (AssignTypeUtil.IsList(retType)) {\r
599                 if (AssignTypeUtil.IsSimpleType(beanType)) {\r
600                     return CreateObjectListDataReaderHandler();\r
601                 } else {\r
602                     return CreateBeanListMetaDataDataReaderHandler(bmd);\r
603                 }\r
604             } else if (IsBeanTypeAssignable(beanType, retType)) {\r
605                 return CreateBeanMetaDataDataReaderHandler(bmd);\r
606             } else if (AssignTypeUtil.IsGenericList(retType)) {\r
607                 Type elementType = retType.GetGenericArguments()[0];\r
608                 if (AssignTypeUtil.IsSimpleType(elementType)) {\r
609                     return CreateObjectGenericListDataReaderHandler(elementType);\r
610                 } else {\r
611                     return CreateBeanGenericListMetaDataDataReaderHandler(bmd);\r
612                 }\r
613             } else {\r
614                 return CreateObjectDataReaderHandler();\r
615             }\r
616         }\r
617 \r
618         protected virtual IDataReaderHandler CreateObjectGenericListDataReaderHandler(Type elementType) {\r
619             return new ObjectGenericListDataReaderHandler(elementType);\r
620         }\r
621 \r
622         protected virtual IDataReaderHandler CreateObjectListDataReaderHandler() {\r
623             return new ObjectListDataReaderHandler();\r
624         }\r
625 \r
626         protected virtual IDataReaderHandler CreateObjectArrayDataReaderHandler(Type elementType) {\r
627             return new ObjectArrayDataReaderHandler(elementType);\r
628         }\r
629 \r
630         protected virtual IDataReaderHandler CreateBeanDataSetMetaDataDataReaderHandler(IBeanMetaData bmd, Type returnType) {\r
631             return new BeanDataSetMetaDataDataReaderHandler(returnType);\r
632         }\r
633 \r
634         protected virtual IDataReaderHandler CreateBeanDataTableMetaDataDataReaderHandler(IBeanMetaData bmd, Type returnType) {\r
635             return new BeanDataTableMetaDataDataReaderHandler(returnType);\r
636         }\r
637 \r
638         protected virtual IDataReaderHandler CreateBeanListMetaDataDataReaderHandler(IBeanMetaData bmd) {\r
639             return new BeanListMetaDataDataReaderHandler(bmd, CreateRowCreator(), CreateRelationRowCreator());\r
640         }\r
641 \r
642         protected virtual IDataReaderHandler CreateBeanMetaDataDataReaderHandler(IBeanMetaData bmd) {\r
643             return new BeanMetaDataDataReaderHandler(bmd, CreateRowCreator(), CreateRelationRowCreator());\r
644         }\r
645 \r
646         // DBFlute Target (but unused actually)\r
647         protected virtual IDataReaderHandler CreateBeanArrayMetaDataDataReaderHandler(IBeanMetaData bmd) {\r
648             InternalRowCreator rowCreator = CreateInternalRowCreator(bmd);\r
649             InternalRelationRowCreator relationRowCreator = CreateInternalRelationRowCreator(bmd);\r
650             return new ${glInternalBeanArrayMetaDataResultSetHandler}(bmd, rowCreator, relationRowCreator);\r
651         }\r
652 \r
653         // DBFlute Target\r
654         protected virtual IDataReaderHandler CreateBeanGenericListMetaDataDataReaderHandler(IBeanMetaData bmd) {\r
655             InternalRowCreator rowCreator = CreateInternalRowCreator(bmd);\r
656             InternalRelationRowCreator relationRowCreator = CreateInternalRelationRowCreator(bmd);\r
657             return new ${glInternalBeanGenericListMetaDataResultSetHandler}(bmd, rowCreator, relationRowCreator);\r
658         }\r
659 \r
660         protected virtual IDataReaderHandler CreateObjectDataReaderHandler() {\r
661             return new ObjectDataReaderHandler();\r
662         }\r
663 \r
664         protected virtual IRowCreator CreateRowCreator() {\r
665             return CreateInternalRowCreator(null);\r
666         }\r
667 \r
668         protected virtual IRelationRowCreator CreateRelationRowCreator() {\r
669             return CreateInternalRelationRowCreator(null);\r
670         }\r
671 \r
672         protected virtual bool IsBeanTypeAssignable(Type beanType, Type type) {\r
673             return beanType.IsAssignableFrom(type) || type.IsAssignableFrom(beanType);\r
674         }\r
675 \r
676         protected InternalRowCreator CreateInternalRowCreator(IBeanMetaData bmd) {\r
677             Type clazz = bmd != null ? bmd.BeanType : null;\r
678             return InternalRowCreator.CreateInternalRowCreator(clazz);\r
679         }\r
680 \r
681         protected InternalRelationRowCreator CreateInternalRelationRowCreator(IBeanMetaData bmd) {\r
682             return new InternalRelationRowCreator(); // Not yet implemented about performance tuning!\r
683         }\r
684     }\r
685 }