|
11 | 11 | import java.util.Collections;
|
12 | 12 | import java.util.HashSet;
|
13 | 13 | import java.util.Iterator;
|
| 14 | +import java.util.Locale; |
14 | 15 | import java.util.Map;
|
15 | 16 | import java.util.Set;
|
16 | 17 | import java.util.StringTokenizer;
|
|
31 | 32 | import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
32 | 33 | import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
33 | 34 | import org.hibernate.boot.spi.ClassLoaderAccess;
|
| 35 | +import org.hibernate.boot.spi.SessionFactoryOptions; |
34 | 36 | import org.hibernate.cfg.Environment;
|
35 | 37 | import org.hibernate.dialect.Dialect;
|
36 | 38 | import org.hibernate.engine.config.spi.ConfigurationService;
|
@@ -77,10 +79,9 @@ public static void validateSuppliedFactory(Object object) {
|
77 | 79 |
|
78 | 80 | @SuppressWarnings("UnusedDeclaration")
|
79 | 81 | public static void activate(ActivationContext activationContext) {
|
80 |
| - final ConfigurationService cfgService = activationContext.getServiceRegistry().getService( ConfigurationService.class ); |
81 | 82 | final ValidatorFactory factory;
|
82 | 83 | try {
|
83 |
| - factory = getValidatorFactory( cfgService.getSettings() ); |
| 84 | + factory = getValidatorFactory( activationContext ); |
84 | 85 | }
|
85 | 86 | catch (IntegrationException e) {
|
86 | 87 | if ( activationContext.getValidationModes().contains( ValidationMode.CALLBACK ) ) {
|
@@ -112,7 +113,7 @@ public static void applyCallbackListeners(ValidatorFactory validatorFactory, Act
|
112 | 113 | // de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
|
113 | 114 | // asks for it
|
114 | 115 | if ( cfgService.getSettings().get( Environment.CHECK_NULLABILITY ) == null ) {
|
115 |
| - activationContext.getSessionFactory().getSettings().setCheckNullability( false ); |
| 116 | + activationContext.getSessionFactory().getSessionFactoryOptions().setCheckNullability( false ); |
116 | 117 | }
|
117 | 118 |
|
118 | 119 | final BeanValidationEventListener listener = new BeanValidationEventListener(
|
@@ -151,7 +152,10 @@ private static void applyRelationalConstraints(ValidatorFactory factory, Activat
|
151 | 152 | activationContext.getMetadata().getEntityBindings(),
|
152 | 153 | cfgService.getSettings(),
|
153 | 154 | activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect(),
|
154 |
| - new ClassLoaderAccessImpl( null, activationContext.getServiceRegistry().getService( ClassLoaderService.class ) ) |
| 155 | + new ClassLoaderAccessImpl( |
| 156 | + null, |
| 157 | + activationContext.getServiceRegistry().getService( ClassLoaderService.class ) |
| 158 | + ) |
155 | 159 | );
|
156 | 160 | }
|
157 | 161 |
|
@@ -303,16 +307,17 @@ private static void applySQLCheck(Column col, String checkConstraint) {
|
303 | 307 | col.setCheckConstraint( checkConstraint );
|
304 | 308 | }
|
305 | 309 |
|
| 310 | + @SuppressWarnings("unchecked") |
306 | 311 | private static boolean applyNotNull(Property property, ConstraintDescriptor<?> descriptor) {
|
307 | 312 | boolean hasNotNull = false;
|
308 | 313 | if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
|
309 | 314 | // single table inheritance should not be forced to null due to shared state
|
310 | 315 | if ( !( property.getPersistentClass() instanceof SingleTableSubclass ) ) {
|
311 | 316 | //composite should not add not-null on all columns
|
312 | 317 | if ( !property.isComposite() ) {
|
313 |
| - final Iterator<Selectable> iter = property.getColumnIterator(); |
314 |
| - while ( iter.hasNext() ) { |
315 |
| - final Selectable selectable = iter.next(); |
| 318 | + final Iterator<Selectable> itr = property.getColumnIterator(); |
| 319 | + while ( itr.hasNext() ) { |
| 320 | + final Selectable selectable = itr.next(); |
316 | 321 | if ( Column.class.isInstance( selectable ) ) {
|
317 | 322 | Column.class.cast( selectable ).setNullable( false );
|
318 | 323 | }
|
@@ -371,10 +376,8 @@ private static void applyLength(Property property, ConstraintDescriptor<?> descr
|
371 | 376 | }
|
372 | 377 |
|
373 | 378 | /**
|
374 |
| - * @param associatedClass |
375 |
| - * @param propertyName |
376 |
| - * @return the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is |
377 |
| - * <code>null</code>. If propertyName is <code>null</code> or empty, the IdentifierProperty is returned |
| 379 | + * Locate the property by path in a recursive way, including IdentifierProperty in the loop if propertyName is |
| 380 | + * {@code null}. If propertyName is {@code null} or empty, the IdentifierProperty is returned |
378 | 381 | */
|
379 | 382 | private static Property findPropertyByName(PersistentClass associatedClass, String propertyName) {
|
380 | 383 | Property property = null;
|
@@ -434,30 +437,81 @@ private static Property findPropertyByName(PersistentClass associatedClass, Stri
|
434 | 437 | return property;
|
435 | 438 | }
|
436 | 439 |
|
437 |
| - private static ValidatorFactory getValidatorFactory(Map<Object, Object> properties) { |
438 |
| - ValidatorFactory factory = null; |
439 |
| - if ( properties != null ) { |
440 |
| - Object unsafeProperty = properties.get( FACTORY_PROPERTY ); |
441 |
| - if ( unsafeProperty != null ) { |
442 |
| - try { |
443 |
| - factory = ValidatorFactory.class.cast( unsafeProperty ); |
444 |
| - } |
445 |
| - catch ( ClassCastException e ) { |
446 |
| - throw new IntegrationException( |
447 |
| - "Property " + FACTORY_PROPERTY |
448 |
| - + " should contain an object of type " + ValidatorFactory.class.getName() |
449 |
| - ); |
450 |
| - } |
451 |
| - } |
| 440 | + private static ValidatorFactory getValidatorFactory(ActivationContext activationContext) { |
| 441 | + // IMPL NOTE : We can either be provided a ValidatorFactory or make one. We can be provided |
| 442 | + // a ValidatorFactory in 2 different ways. So here we "get" a ValidatorFactory in the following order: |
| 443 | + // 1) Look into SessionFactoryOptions.getValidatorFactoryReference() |
| 444 | + // 2) Look into ConfigurationService |
| 445 | + // 3) build a new ValidatorFactory |
| 446 | + |
| 447 | + // 1 - look in SessionFactoryOptions.getValidatorFactoryReference() |
| 448 | + ValidatorFactory factory = resolveProvidedFactory( activationContext.getSessionFactory().getSessionFactoryOptions() ); |
| 449 | + if ( factory != null ) { |
| 450 | + return factory; |
452 | 451 | }
|
453 |
| - if ( factory == null ) { |
454 |
| - try { |
455 |
| - factory = Validation.buildDefaultValidatorFactory(); |
456 |
| - } |
457 |
| - catch ( Exception e ) { |
458 |
| - throw new IntegrationException( "Unable to build the default ValidatorFactory", e ); |
459 |
| - } |
| 452 | + |
| 453 | + // 2 - look in ConfigurationService |
| 454 | + factory = resolveProvidedFactory( activationContext.getServiceRegistry().getService( ConfigurationService.class ) ); |
| 455 | + if ( factory != null ) { |
| 456 | + return factory; |
| 457 | + } |
| 458 | + |
| 459 | + // 3 - build our own |
| 460 | + try { |
| 461 | + return Validation.buildDefaultValidatorFactory(); |
| 462 | + } |
| 463 | + catch ( Exception e ) { |
| 464 | + throw new IntegrationException( "Unable to build the default ValidatorFactory", e ); |
| 465 | + } |
| 466 | + } |
| 467 | + |
| 468 | + private static ValidatorFactory resolveProvidedFactory(SessionFactoryOptions options) { |
| 469 | + final Object validatorFactoryReference = options.getValidatorFactoryReference(); |
| 470 | + |
| 471 | + if ( validatorFactoryReference == null ) { |
| 472 | + return null; |
| 473 | + } |
| 474 | + |
| 475 | + try { |
| 476 | + return ValidatorFactory.class.cast( validatorFactoryReference ); |
| 477 | + } |
| 478 | + catch ( ClassCastException e ) { |
| 479 | + throw new IntegrationException( |
| 480 | + String.format( |
| 481 | + Locale.ENGLISH, |
| 482 | + "ValidatorFactory reference (provided via %s) was not castable to %s : %s", |
| 483 | + SessionFactoryOptions.class.getName(), |
| 484 | + ValidatorFactory.class.getName(), |
| 485 | + validatorFactoryReference.getClass().getName() |
| 486 | + ) |
| 487 | + ); |
460 | 488 | }
|
461 |
| - return factory; |
| 489 | + } |
| 490 | + |
| 491 | + @SuppressWarnings("unchecked") |
| 492 | + private static ValidatorFactory resolveProvidedFactory(ConfigurationService cfgService) { |
| 493 | + return cfgService.getSetting( |
| 494 | + FACTORY_PROPERTY, |
| 495 | + new ConfigurationService.Converter<ValidatorFactory>() { |
| 496 | + @Override |
| 497 | + public ValidatorFactory convert(Object value) { |
| 498 | + try { |
| 499 | + return ValidatorFactory.class.cast( value ); |
| 500 | + } |
| 501 | + catch ( ClassCastException e ) { |
| 502 | + throw new IntegrationException( |
| 503 | + String.format( |
| 504 | + Locale.ENGLISH, |
| 505 | + "ValidatorFactory reference (provided via `%s` setting) was not castable to %s : %s", |
| 506 | + FACTORY_PROPERTY, |
| 507 | + ValidatorFactory.class.getName(), |
| 508 | + value.getClass().getName() |
| 509 | + ) |
| 510 | + ); |
| 511 | + } |
| 512 | + } |
| 513 | + }, |
| 514 | + null |
| 515 | + ); |
462 | 516 | }
|
463 | 517 | }
|
0 commit comments