10
10
11
11
import org .apache .ibatis .binding .MapperRegistry ;
12
12
import org .apache .ibatis .builder .CacheRefResolver ;
13
+ import org .apache .ibatis .builder .ResultMapResolver ;
13
14
import org .apache .ibatis .builder .xml .XMLStatementBuilder ;
14
15
import org .apache .ibatis .cache .Cache ;
15
16
import org .apache .ibatis .cache .decorators .FifoCache ;
@@ -76,23 +77,18 @@ public class Configuration {
76
77
protected final InterceptorChain interceptorChain = new InterceptorChain ();
77
78
protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry ();
78
79
protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry ();
79
- protected final Map <String , MappedStatement > mappedStatements = new StrictMap <String , MappedStatement >(
80
- "Mapped Statements collection" );
81
- protected final Map <String , Cache > caches = new StrictMap <String , Cache >(
82
- "Caches collection" );
83
- protected final Map <String , ResultMap > resultMaps = new StrictMap <String , ResultMap >(
84
- "Result Maps collection" );
85
- protected final Map <String , ParameterMap > parameterMaps = new StrictMap <String , ParameterMap >(
86
- "Parameter Maps collection" );
87
- protected final Map <String , KeyGenerator > keyGenerators = new StrictMap <String , KeyGenerator >(
88
- "Key Generators collection" );
80
+ protected final Map <String , MappedStatement > mappedStatements = new StrictMap <String , MappedStatement >("Mapped Statements collection" );
81
+ protected final Map <String , Cache > caches = new StrictMap <String , Cache >("Caches collection" );
82
+ protected final Map <String , ResultMap > resultMaps = new StrictMap <String , ResultMap >("Result Maps collection" );
83
+ protected final Map <String , ParameterMap > parameterMaps = new StrictMap <String , ParameterMap >("Parameter Maps collection" );
84
+ protected final Map <String , KeyGenerator > keyGenerators = new StrictMap <String , KeyGenerator >("Key Generators collection" );
89
85
90
86
protected final Set <String > loadedResources = new HashSet <String >();
91
- protected final Map <String , XNode > sqlFragments = new StrictMap <String , XNode >(
92
- "XML fragments parsed from previous mappers" );
87
+ protected final Map <String , XNode > sqlFragments = new StrictMap <String , XNode >("XML fragments parsed from previous mappers" );
93
88
94
89
protected final Collection <XMLStatementBuilder > incompleteStatements = new LinkedList <XMLStatementBuilder >();
95
90
protected final Collection <CacheRefResolver > incompleteCacheRefs = new LinkedList <CacheRefResolver >();
91
+ protected final Collection <ResultMapResolver > incompleteResultMaps = new LinkedList <ResultMapResolver >();
96
92
/**
97
93
* A map holds cache-ref relationship. The key is the namespace that
98
94
* references a cache bound to another namespace and the value is the
@@ -106,19 +102,13 @@ public Configuration(Environment environment) {
106
102
}
107
103
108
104
public Configuration () {
109
- typeAliasRegistry .registerAlias ("JDBC" ,
110
- JdbcTransactionFactory .class .getName ());
111
- typeAliasRegistry .registerAlias ("MANAGED" ,
112
- ManagedTransactionFactory .class .getName ());
113
- typeAliasRegistry .registerAlias ("JNDI" ,
114
- JndiDataSourceFactory .class .getName ());
115
- typeAliasRegistry .registerAlias ("POOLED" ,
116
- PooledDataSourceFactory .class .getName ());
117
- typeAliasRegistry .registerAlias ("UNPOOLED" ,
118
- UnpooledDataSourceFactory .class .getName ());
119
-
120
- typeAliasRegistry
121
- .registerAlias ("PERPETUAL" , PerpetualCache .class .getName ());
105
+ typeAliasRegistry .registerAlias ("JDBC" , JdbcTransactionFactory .class .getName ());
106
+ typeAliasRegistry .registerAlias ("MANAGED" , ManagedTransactionFactory .class .getName ());
107
+ typeAliasRegistry .registerAlias ("JNDI" , JndiDataSourceFactory .class .getName ());
108
+ typeAliasRegistry .registerAlias ("POOLED" , PooledDataSourceFactory .class .getName ());
109
+ typeAliasRegistry .registerAlias ("UNPOOLED" , UnpooledDataSourceFactory .class .getName ());
110
+
111
+ typeAliasRegistry .registerAlias ("PERPETUAL" , PerpetualCache .class .getName ());
122
112
typeAliasRegistry .registerAlias ("FIFO" , FifoCache .class .getName ());
123
113
typeAliasRegistry .registerAlias ("LRU" , LruCache .class .getName ());
124
114
typeAliasRegistry .registerAlias ("SOFT" , SoftCache .class .getName ());
@@ -158,9 +148,7 @@ public void setLazyLoadingEnabled(boolean lazyLoadingEnabled) {
158
148
try {
159
149
Resources .classForName ("net.sf.cglib.proxy.Enhancer" );
160
150
} catch (Throwable e ) {
161
- throw new IllegalStateException (
162
- "Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath." ,
163
- e );
151
+ throw new IllegalStateException ("Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath." , e );
164
152
}
165
153
}
166
154
this .lazyLoadingEnabled = lazyLoadingEnabled ;
@@ -258,35 +246,23 @@ public MetaObject newMetaObject(Object object) {
258
246
return MetaObject .forObject (object , objectFactory , objectWrapperFactory );
259
247
}
260
248
261
- public ParameterHandler newParameterHandler (MappedStatement mappedStatement ,
262
- Object parameterObject , BoundSql boundSql ) {
263
- ParameterHandler parameterHandler = new DefaultParameterHandler (
264
- mappedStatement , parameterObject , boundSql );
265
- parameterHandler = (ParameterHandler ) interceptorChain
266
- .pluginAll (parameterHandler );
249
+ public ParameterHandler newParameterHandler (MappedStatement mappedStatement , Object parameterObject , BoundSql boundSql ) {
250
+ ParameterHandler parameterHandler = new DefaultParameterHandler (mappedStatement , parameterObject , boundSql );
251
+ parameterHandler = (ParameterHandler ) interceptorChain .pluginAll (parameterHandler );
267
252
return parameterHandler ;
268
253
}
269
254
270
- public ResultSetHandler newResultSetHandler (Executor executor ,
271
- MappedStatement mappedStatement , RowBounds rowBounds ,
272
- ParameterHandler parameterHandler , ResultHandler resultHandler ,
273
- BoundSql boundSql ) {
274
- ResultSetHandler resultSetHandler = mappedStatement .hasNestedResultMaps () ? new NestedResultSetHandler (
275
- executor , mappedStatement , parameterHandler , resultHandler , boundSql ,
276
- rowBounds ) : new FastResultSetHandler (executor , mappedStatement ,
277
- parameterHandler , resultHandler , boundSql , rowBounds );
278
- resultSetHandler = (ResultSetHandler ) interceptorChain
279
- .pluginAll (resultSetHandler );
255
+ public ResultSetHandler newResultSetHandler (Executor executor , MappedStatement mappedStatement , RowBounds rowBounds , ParameterHandler parameterHandler ,
256
+ ResultHandler resultHandler , BoundSql boundSql ) {
257
+ ResultSetHandler resultSetHandler = mappedStatement .hasNestedResultMaps () ? new NestedResultSetHandler (executor , mappedStatement , parameterHandler , resultHandler , boundSql ,
258
+ rowBounds ) : new FastResultSetHandler (executor , mappedStatement , parameterHandler , resultHandler , boundSql , rowBounds );
259
+ resultSetHandler = (ResultSetHandler ) interceptorChain .pluginAll (resultSetHandler );
280
260
return resultSetHandler ;
281
261
}
282
262
283
- public StatementHandler newStatementHandler (Executor executor ,
284
- MappedStatement mappedStatement , Object parameterObject ,
285
- RowBounds rowBounds , ResultHandler resultHandler ) {
286
- StatementHandler statementHandler = new RoutingStatementHandler (executor ,
287
- mappedStatement , parameterObject , rowBounds , resultHandler );
288
- statementHandler = (StatementHandler ) interceptorChain
289
- .pluginAll (statementHandler );
263
+ public StatementHandler newStatementHandler (Executor executor , MappedStatement mappedStatement , Object parameterObject , RowBounds rowBounds , ResultHandler resultHandler ) {
264
+ StatementHandler statementHandler = new RoutingStatementHandler (executor , mappedStatement , parameterObject , rowBounds , resultHandler );
265
+ statementHandler = (StatementHandler ) interceptorChain .pluginAll (statementHandler );
290
266
return statementHandler ;
291
267
}
292
268
@@ -407,13 +383,13 @@ public void addMappedStatement(MappedStatement ms, String databaseId) {
407
383
if (previous == null || previous .getDatabaseId () == null ) {
408
384
mappedStatements .put (ms .getId (), ms );
409
385
}
410
- }
386
+ }
411
387
} else {
412
- mappedStatements .put (ms .getId (), ms );
388
+ mappedStatements .put (ms .getId (), ms );
413
389
}
414
390
}
415
391
}
416
-
392
+
417
393
public void addMappedStatement (MappedStatement ms ) {
418
394
addMappedStatement (ms , null );
419
395
}
@@ -444,12 +420,19 @@ public void addIncompleteCacheRef(CacheRefResolver incompleteCacheRef) {
444
420
incompleteCacheRefs .add (incompleteCacheRef );
445
421
}
446
422
423
+ public Collection <ResultMapResolver > getIncompleteResultMaps () {
424
+ return incompleteResultMaps ;
425
+ }
426
+
427
+ public void addIncompleteResultMap (ResultMapResolver resultMapResolver ) {
428
+ incompleteResultMaps .add (resultMapResolver );
429
+ }
430
+
447
431
public MappedStatement getMappedStatement (String id ) {
448
432
return this .getMappedStatement (id , true );
449
433
}
450
434
451
- public MappedStatement getMappedStatement (String id ,
452
- boolean validateIncompleteStatements ) {
435
+ public MappedStatement getMappedStatement (String id , boolean validateIncompleteStatements ) {
453
436
if (validateIncompleteStatements ) {
454
437
buildAllStatements ();
455
438
}
@@ -486,7 +469,7 @@ public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
486
469
return mapperRegistry .getMapper (type , sqlSession );
487
470
}
488
471
489
- public boolean hasMapper (Class type ) {
472
+ public boolean hasMapper (Class <?> type ) {
490
473
return mapperRegistry .hasMapper (type );
491
474
}
492
475
@@ -505,6 +488,12 @@ public void addCacheRef(String namespace, String referencedNamespace) {
505
488
* statement validation.
506
489
*/
507
490
protected void buildAllStatements () {
491
+ if (!incompleteResultMaps .isEmpty ()) {
492
+ synchronized (incompleteResultMaps ) {
493
+ // This always throws a BuilderException.
494
+ incompleteResultMaps .iterator ().next ().resolve ();
495
+ }
496
+ }
508
497
if (!incompleteCacheRefs .isEmpty ()) {
509
498
synchronized (incompleteCacheRefs ) {
510
499
// This always throws a BuilderException.
@@ -537,10 +526,8 @@ protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) {
537
526
Object value = entry .getValue ();
538
527
if (value instanceof ResultMap ) {
539
528
ResultMap entryResultMap = (ResultMap ) value ;
540
- if (!entryResultMap .hasNestedResultMaps ()
541
- && entryResultMap .getDiscriminator () != null ) {
542
- Collection <String > discriminatedResultMapNames = entryResultMap
543
- .getDiscriminator ().getDiscriminatorMap ().values ();
529
+ if (!entryResultMap .hasNestedResultMaps () && entryResultMap .getDiscriminator () != null ) {
530
+ Collection <String > discriminatedResultMapNames = entryResultMap .getDiscriminator ().getDiscriminatorMap ().values ();
544
531
if (discriminatedResultMapNames .contains (rm .getId ())) {
545
532
entryResultMap .forceNestedResultMaps ();
546
533
}
@@ -553,12 +540,10 @@ protected void checkGloballyForDiscriminatedNestedResultMaps(ResultMap rm) {
553
540
// Slow but a one time cost. A better solution is welcome.
554
541
protected void checkLocallyForDiscriminatedNestedResultMaps (ResultMap rm ) {
555
542
if (!rm .hasNestedResultMaps () && rm .getDiscriminator () != null ) {
556
- for (Map .Entry entry : rm .getDiscriminator ().getDiscriminatorMap ()
557
- .entrySet ()) {
543
+ for (Map .Entry entry : rm .getDiscriminator ().getDiscriminatorMap ().entrySet ()) {
558
544
String discriminatedResultMapName = (String ) entry .getValue ();
559
545
if (hasResultMap (discriminatedResultMapName )) {
560
- ResultMap discriminatedResultMap = resultMaps
561
- .get (discriminatedResultMapName );
546
+ ResultMap discriminatedResultMap = resultMaps .get (discriminatedResultMapName );
562
547
if (discriminatedResultMap .hasNestedResultMaps ()) {
563
548
rm .forceNestedResultMaps ();
564
549
break ;
@@ -568,8 +553,7 @@ protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) {
568
553
}
569
554
}
570
555
571
- protected static class StrictMap <J extends String , K extends Object > extends
572
- HashMap <J , K > {
556
+ protected static class StrictMap <J extends String , K extends Object > extends HashMap <J , K > {
573
557
574
558
private String name ;
575
559
@@ -595,8 +579,7 @@ public StrictMap(String name, Map<? extends J, ? extends K> m) {
595
579
596
580
public K put (J key , K value ) {
597
581
if (containsKey (key ))
598
- throw new IllegalArgumentException (name
599
- + " already contains value for " + key );
582
+ throw new IllegalArgumentException (name + " already contains value for " + key );
600
583
if (key .contains ("." )) {
601
584
final String shortKey = getShortName (key );
602
585
if (super .get (shortKey ) == null ) {
@@ -611,15 +594,11 @@ public K put(J key, K value) {
611
594
public K get (Object key ) {
612
595
K value = super .get (key );
613
596
if (value == null ) {
614
- throw new IllegalArgumentException (name
615
- + " does not contain value for " + key );
597
+ throw new IllegalArgumentException (name + " does not contain value for " + key );
616
598
}
617
599
if (value instanceof Ambiguity ) {
618
- throw new IllegalArgumentException (
619
- ((Ambiguity ) value ).getSubject ()
620
- + " is ambiguous in "
621
- + name
622
- + " (try using the full name including the namespace, or rename one of the entries)" );
600
+ throw new IllegalArgumentException (((Ambiguity ) value ).getSubject () + " is ambiguous in " + name
601
+ + " (try using the full name including the namespace, or rename one of the entries)" );
623
602
}
624
603
return value ;
625
604
}
0 commit comments