42
42
import org .springframework .util .StringUtils ;
43
43
44
44
/**
45
- * Class to manage context metadata used for the configuration and execution of the call.
45
+ * Class to manage context meta-data used for the configuration
46
+ * and execution of a stored procedure call.
46
47
*
47
48
* @author Thomas Risberg
48
49
* @author Juergen Hoeller
@@ -81,13 +82,13 @@ public class CallMetaDataContext {
81
82
// Indicates whether this procedure's return value should be included
82
83
private boolean returnValueRequired = false ;
83
84
84
- // Should we access call parameter meta data info or not
85
+ // Should we access call parameter meta- data info or not
85
86
private boolean accessCallParameterMetaData = true ;
86
87
87
88
// Should we bind parameter by name
88
89
private boolean namedBinding ;
89
90
90
- // The provider of call meta data
91
+ // The provider of call meta- data
91
92
private CallMetaDataProvider metaDataProvider ;
92
93
93
94
@@ -204,14 +205,14 @@ public boolean isReturnValueRequired() {
204
205
}
205
206
206
207
/**
207
- * Specify whether call parameter metadata should be accessed.
208
+ * Specify whether call parameter meta-data should be accessed.
208
209
*/
209
210
public void setAccessCallParameterMetaData (boolean accessCallParameterMetaData ) {
210
211
this .accessCallParameterMetaData = accessCallParameterMetaData ;
211
212
}
212
213
213
214
/**
214
- * Check whether call parameter metadata should be accessed.
215
+ * Check whether call parameter meta-data should be accessed.
215
216
*/
216
217
public boolean isAccessCallParameterMetaData () {
217
218
return this .accessCallParameterMetaData ;
@@ -235,8 +236,8 @@ public boolean isNamedBinding() {
235
236
236
237
237
238
/**
238
- * Initialize this class with metadata from the database.
239
- * @param dataSource the DataSource used to retrieve metadata
239
+ * Initialize this class with meta-data from the database.
240
+ * @param dataSource the DataSource used to retrieve meta-data
240
241
*/
241
242
public void initializeMetaData (DataSource dataSource ) {
242
243
this .metaDataProvider = CallMetaDataProviderFactory .createMetaDataProvider (dataSource , this );
@@ -258,7 +259,8 @@ public SqlParameter createReturnResultSetParameter(String parameterName, RowMapp
258
259
return new SqlOutParameter (parameterName , this .metaDataProvider .getRefCursorSqlType (), rowMapper );
259
260
}
260
261
else {
261
- throw new InvalidDataAccessApiUsageException ("Return of a ResultSet from a stored procedure is not supported." );
262
+ throw new InvalidDataAccessApiUsageException (
263
+ "Return of a ResultSet from a stored procedure is not supported" );
262
264
}
263
265
}
264
266
}
@@ -275,7 +277,7 @@ public String getScalarOutParameterName() {
275
277
if (this .outParameterNames .size () > 1 ) {
276
278
logger .warn ("Accessing single output value when procedure has more than one output parameter" );
277
279
}
278
- return (this .outParameterNames .size () > 0 ? this .outParameterNames .get (0 ) : null );
280
+ return (! this .outParameterNames .isEmpty () ? this .outParameterNames .get (0 ) : null );
279
281
}
280
282
}
281
283
@@ -287,8 +289,8 @@ public List<SqlParameter> getCallParameters() {
287
289
}
288
290
289
291
/**
290
- * Process the list of parameters provided, and if procedure column metadata is used,
291
- * the parameters will be matched against the metadata information and any missing
292
+ * Process the list of parameters provided, and if procedure column meta-data is used,
293
+ * the parameters will be matched against the meta-data information and any missing
292
294
* ones will be automatically included.
293
295
* @param parameters the list of parameters to use as a base
294
296
*/
@@ -297,7 +299,7 @@ public void processParameters(List<SqlParameter> parameters) {
297
299
}
298
300
299
301
/**
300
- * Reconcile the provided parameters with available metadata and add new ones where appropriate.
302
+ * Reconcile the provided parameters with available meta-data and add new ones where appropriate.
301
303
*/
302
304
protected List <SqlParameter > reconcileParameters (List <SqlParameter > parameters ) {
303
305
final List <SqlParameter > declaredReturnParams = new ArrayList <SqlParameter >();
@@ -306,9 +308,9 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
306
308
List <String > outParamNames = new ArrayList <String >();
307
309
List <String > metaDataParamNames = new ArrayList <String >();
308
310
309
- // Get the names of the meta data parameters
311
+ // Get the names of the meta- data parameters
310
312
for (CallParameterMetaData meta : this .metaDataProvider .getCallParameterMetaData ()) {
311
- if (meta .getParameterType () != DatabaseMetaData . procedureColumnReturn ) {
313
+ if (! meta .isReturnParameter () ) {
312
314
metaDataParamNames .add (meta .getParameterName ().toLowerCase ());
313
315
}
314
316
}
@@ -328,15 +330,12 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
328
330
declaredParams .put (paramNameToMatch , param );
329
331
if (param instanceof SqlOutParameter ) {
330
332
outParamNames .add (paramName );
331
- if (isFunction () && !metaDataParamNames .contains (paramNameToMatch )) {
332
- if (!returnDeclared ) {
333
- if (logger .isDebugEnabled ()) {
334
- logger .debug ("Using declared out parameter '" + paramName +
335
- "' for function return value" );
336
- }
337
- setFunctionReturnName (paramName );
338
- returnDeclared = true ;
333
+ if (isFunction () && !metaDataParamNames .contains (paramNameToMatch ) && !returnDeclared ) {
334
+ if (logger .isDebugEnabled ()) {
335
+ logger .debug ("Using declared out parameter '" + paramName + "' for function return value" );
339
336
}
337
+ setFunctionReturnName (paramName );
338
+ returnDeclared = true ;
340
339
}
341
340
}
342
341
}
@@ -345,7 +344,6 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
345
344
346
345
List <SqlParameter > workParams = new ArrayList <SqlParameter >();
347
346
workParams .addAll (declaredReturnParams );
348
-
349
347
if (!this .metaDataProvider .isProcedureColumnMetaDataUsed ()) {
350
348
workParams .addAll (declaredParams .values ());
351
349
return workParams ;
@@ -363,12 +361,11 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
363
361
paramNameToCheck = this .metaDataProvider .parameterNameToUse (meta .getParameterName ()).toLowerCase ();
364
362
}
365
363
String paramNameToUse = this .metaDataProvider .parameterNameToUse (meta .getParameterName ());
366
- if (declaredParams .containsKey (paramNameToCheck ) ||
367
- (meta .getParameterType () == DatabaseMetaData .procedureColumnReturn && returnDeclared )) {
364
+ if (declaredParams .containsKey (paramNameToCheck ) || (meta .isReturnParameter () && returnDeclared )) {
368
365
SqlParameter param ;
369
- if (meta .getParameterType () == DatabaseMetaData . procedureColumnReturn ) {
366
+ if (meta .isReturnParameter () ) {
370
367
param = declaredParams .get (getFunctionReturnName ());
371
- if (param == null && getOutParameterNames ().size () > 0 ) {
368
+ if (param == null && ! getOutParameterNames ().isEmpty () ) {
372
369
param = declaredParams .get (getOutParameterNames ().get (0 ).toLowerCase ());
373
370
}
374
371
if (param == null ) {
@@ -392,23 +389,24 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
392
389
}
393
390
}
394
391
else {
395
- if (meta .getParameterType () == DatabaseMetaData .procedureColumnReturn ) {
392
+ if (meta .isReturnParameter ()) {
393
+ // DatabaseMetaData.procedureColumnReturn or possibly procedureColumnResult
396
394
if (!isFunction () && !isReturnValueRequired () &&
397
395
this .metaDataProvider .byPassReturnParameter (meta .getParameterName ())) {
398
396
if (logger .isDebugEnabled ()) {
399
- logger .debug ("Bypassing metadata return parameter for '" + meta .getParameterName () + "'" );
397
+ logger .debug ("Bypassing meta-data return parameter for '" + meta .getParameterName () + "'" );
400
398
}
401
399
}
402
400
else {
403
- String returnNameToUse =( StringUtils . hasLength ( meta . getParameterName ()) ?
404
- paramNameToUse : getFunctionReturnName ());
401
+ String returnNameToUse =
402
+ ( StringUtils . hasLength ( meta . getParameterName ()) ? paramNameToUse : getFunctionReturnName ());
405
403
workParams .add (this .metaDataProvider .createDefaultOutParameter (returnNameToUse , meta ));
406
404
if (isFunction ()) {
407
405
setFunctionReturnName (returnNameToUse );
408
406
outParamNames .add (returnNameToUse );
409
407
}
410
408
if (logger .isDebugEnabled ()) {
411
- logger .debug ("Added metadata return parameter for '" + returnNameToUse + "'" );
409
+ logger .debug ("Added meta-data return parameter for '" + returnNameToUse + "'" );
412
410
}
413
411
}
414
412
}
@@ -417,22 +415,22 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
417
415
workParams .add (this .metaDataProvider .createDefaultOutParameter (paramNameToUse , meta ));
418
416
outParamNames .add (paramNameToUse );
419
417
if (logger .isDebugEnabled ()) {
420
- logger .debug ("Added metadata out parameter for '" + paramNameToUse + "'" );
418
+ logger .debug ("Added meta-data out parameter for '" + paramNameToUse + "'" );
421
419
}
422
420
}
423
421
else if (meta .getParameterType () == DatabaseMetaData .procedureColumnInOut ) {
424
422
workParams .add (this .metaDataProvider .createDefaultInOutParameter (paramNameToUse , meta ));
425
423
outParamNames .add (paramNameToUse );
426
424
if (logger .isDebugEnabled ()) {
427
- logger .debug ("Added metadata in out parameter for '" + paramNameToUse + "'" );
425
+ logger .debug ("Added meta-data in- out parameter for '" + paramNameToUse + "'" );
428
426
}
429
427
}
430
428
else {
431
429
if (this .limitedInParameterNames .isEmpty () ||
432
430
limitedInParamNamesMap .containsKey (paramNameToUse .toLowerCase ())) {
433
431
workParams .add (this .metaDataProvider .createDefaultInParameter (paramNameToUse , meta ));
434
432
if (logger .isDebugEnabled ()) {
435
- logger .debug ("Added metadata in parameter for '" + paramNameToUse + "'" );
433
+ logger .debug ("Added meta-data in parameter for '" + paramNameToUse + "'" );
436
434
}
437
435
}
438
436
else {
@@ -456,7 +454,7 @@ else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
456
454
*/
457
455
public Map <String , Object > matchInParameterValuesWithCallParameters (SqlParameterSource parameterSource ) {
458
456
// For parameter source lookups we need to provide case-insensitive lookup support
459
- // since the database metadata is not necessarily providing case sensitive parameter names.
457
+ // since the database meta-data is not necessarily providing case sensitive parameter names.
460
458
Map <String , String > caseInsensitiveParameterNames =
461
459
SqlParameterSourceUtils .extractCaseInsensitiveParameterNames (parameterSource );
462
460
@@ -471,31 +469,37 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
471
469
}
472
470
if (parameterName != null ) {
473
471
if (parameterSource .hasValue (parameterName )) {
474
- matchedParameters .put (parameterName , SqlParameterSourceUtils .getTypedValue (parameterSource , parameterName ));
472
+ matchedParameters .put (parameterName ,
473
+ SqlParameterSourceUtils .getTypedValue (parameterSource , parameterName ));
475
474
}
476
475
else {
477
476
String lowerCaseName = parameterName .toLowerCase ();
478
477
if (parameterSource .hasValue (lowerCaseName )) {
479
- matchedParameters .put (parameterName , SqlParameterSourceUtils .getTypedValue (parameterSource , lowerCaseName ));
478
+ matchedParameters .put (parameterName ,
479
+ SqlParameterSourceUtils .getTypedValue (parameterSource , lowerCaseName ));
480
480
}
481
481
else {
482
482
String englishLowerCaseName = parameterName .toLowerCase (Locale .ENGLISH );
483
483
if (parameterSource .hasValue (englishLowerCaseName )) {
484
- matchedParameters .put (parameterName , SqlParameterSourceUtils .getTypedValue (parameterSource , englishLowerCaseName ));
484
+ matchedParameters .put (parameterName ,
485
+ SqlParameterSourceUtils .getTypedValue (parameterSource , englishLowerCaseName ));
485
486
}
486
487
else {
487
488
String propertyName = JdbcUtils .convertUnderscoreNameToPropertyName (parameterName );
488
489
if (parameterSource .hasValue (propertyName )) {
489
- matchedParameters .put (parameterName , SqlParameterSourceUtils .getTypedValue (parameterSource , propertyName ));
490
+ matchedParameters .put (parameterName ,
491
+ SqlParameterSourceUtils .getTypedValue (parameterSource , propertyName ));
490
492
}
491
493
else {
492
494
if (caseInsensitiveParameterNames .containsKey (lowerCaseName )) {
493
495
String sourceName = caseInsensitiveParameterNames .get (lowerCaseName );
494
- matchedParameters .put (parameterName , SqlParameterSourceUtils .getTypedValue (parameterSource , sourceName ));
496
+ matchedParameters .put (parameterName ,
497
+ SqlParameterSourceUtils .getTypedValue (parameterSource , sourceName ));
495
498
}
496
499
else {
497
- logger .warn ("Unable to locate the corresponding parameter value for '" + parameterName +
498
- "' within the parameter values provided: " + caseInsensitiveParameterNames .values ());
500
+ logger .warn ("Unable to locate the corresponding parameter value for '" +
501
+ parameterName + "' within the parameter values provided: " +
502
+ caseInsensitiveParameterNames .values ());
499
503
}
500
504
}
501
505
}
@@ -521,6 +525,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
521
525
if (!this .metaDataProvider .isProcedureColumnMetaDataUsed ()) {
522
526
return inParameters ;
523
527
}
528
+
524
529
Map <String , String > callParameterNames = new HashMap <String , String >(this .callParameters .size ());
525
530
for (SqlParameter parameter : this .callParameters ) {
526
531
if (parameter .isInputValueProvided ()) {
@@ -531,6 +536,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
531
536
}
532
537
}
533
538
}
539
+
534
540
Map <String , Object > matchedParameters = new HashMap <String , Object >(inParameters .size ());
535
541
for (String parameterName : inParameters .keySet ()) {
536
542
String parameterNameToMatch = this .metaDataProvider .parameterNameToUse (parameterName );
@@ -539,18 +545,19 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
539
545
if (logger .isDebugEnabled ()) {
540
546
Object value = inParameters .get (parameterName );
541
547
if (value instanceof SqlParameterValue ) {
542
- value = ((SqlParameterValue )value ).getValue ();
548
+ value = ((SqlParameterValue ) value ).getValue ();
543
549
}
544
550
if (value != null ) {
545
- logger .debug ("Unable to locate the corresponding IN or IN-OUT parameter for \" " + parameterName +
546
- "\" in the parameters used: " + callParameterNames .keySet ());
551
+ logger .debug ("Unable to locate the corresponding IN or IN-OUT parameter for \" " +
552
+ parameterName + "\" in the parameters used: " + callParameterNames .keySet ());
547
553
}
548
554
}
549
555
}
550
556
else {
551
557
matchedParameters .put (callParameterName , inParameters .get (parameterName ));
552
558
}
553
559
}
560
+
554
561
if (matchedParameters .size () < callParameterNames .size ()) {
555
562
for (String parameterName : callParameterNames .keySet ()) {
556
563
String parameterNameToMatch = this .metaDataProvider .parameterNameToUse (parameterName );
@@ -561,6 +568,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
561
568
}
562
569
}
563
570
}
571
+
564
572
if (logger .isDebugEnabled ()) {
565
573
logger .debug ("Matching " + inParameters .keySet () + " with " + callParameterNames .values ());
566
574
logger .debug ("Found match for " + matchedParameters .keySet ());
@@ -581,11 +589,11 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
581
589
}
582
590
583
591
/**
584
- * Build the call string based on configuration and metadata information.
592
+ * Build the call string based on configuration and meta-data information.
585
593
* @return the call string to be used
586
594
*/
587
595
public String createCallString () {
588
- String callString ;
596
+ StringBuilder callString ;
589
597
int parameterCount = 0 ;
590
598
String catalogNameToUse ;
591
599
String schemaNameToUse ;
@@ -601,34 +609,36 @@ public String createCallString() {
601
609
catalogNameToUse = this .metaDataProvider .catalogNameToUse (getCatalogName ());
602
610
schemaNameToUse = this .metaDataProvider .schemaNameToUse (getSchemaName ());
603
611
}
612
+
604
613
String procedureNameToUse = this .metaDataProvider .procedureNameToUse (getProcedureName ());
605
614
if (isFunction () || isReturnValueRequired ()) {
606
- callString = "{? = call " +
607
- (StringUtils .hasLength (catalogNameToUse ) ? catalogNameToUse + "." : "" ) +
608
- (StringUtils .hasLength (schemaNameToUse ) ? schemaNameToUse + "." : "" ) +
609
- procedureNameToUse + "(" ;
615
+ callString = new StringBuilder (). append ( "{? = call " ).
616
+ append (StringUtils .hasLength (catalogNameToUse ) ? catalogNameToUse + "." : "" ).
617
+ append (StringUtils .hasLength (schemaNameToUse ) ? schemaNameToUse + "." : "" ).
618
+ append ( procedureNameToUse ). append ( "(" ) ;
610
619
parameterCount = -1 ;
611
620
}
612
621
else {
613
- callString = "{call " +
614
- (StringUtils .hasLength (catalogNameToUse ) ? catalogNameToUse + "." : "" ) +
615
- (StringUtils .hasLength (schemaNameToUse ) ? schemaNameToUse + "." : "" ) +
616
- procedureNameToUse + "(" ;
622
+ callString = new StringBuilder (). append ( "{call " ).
623
+ append (StringUtils .hasLength (catalogNameToUse ) ? catalogNameToUse + "." : "" ).
624
+ append (StringUtils .hasLength (schemaNameToUse ) ? schemaNameToUse + "." : "" ).
625
+ append ( procedureNameToUse ). append ( "(" ) ;
617
626
}
627
+
618
628
for (SqlParameter parameter : this .callParameters ) {
619
- if (!( parameter .isResultsParameter () )) {
629
+ if (!parameter .isResultsParameter ()) {
620
630
if (parameterCount > 0 ) {
621
- callString += ", " ;
631
+ callString . append ( ", " ) ;
622
632
}
623
633
if (parameterCount >= 0 ) {
624
- callString += createParameterBinding (parameter );
634
+ callString . append ( createParameterBinding (parameter ) );
625
635
}
626
636
parameterCount ++;
627
637
}
628
638
}
629
- callString += ")}" ;
639
+ callString . append ( ")}" ) ;
630
640
631
- return callString ;
641
+ return callString . toString () ;
632
642
}
633
643
634
644
/**
@@ -638,12 +648,7 @@ public String createCallString() {
638
648
* @since 4.2
639
649
*/
640
650
protected String createParameterBinding (SqlParameter parameter ) {
641
- if (isNamedBinding ()) {
642
- return parameter .getName () + " => ?" ;
643
- }
644
- else {
645
- return "?" ;
646
- }
651
+ return (isNamedBinding () ? parameter .getName () + " => ?" : "?" );
647
652
}
648
653
649
654
}
0 commit comments