/* Hibernate, Relational Persistence for Idiomatic Java * * SPDX-License-Identifier: LGPL-2.1-or-later * Copyright: Red Hat Inc. and Hibernate Authors */ package org.hibernate.reactive.id.impl; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.id.Configurable; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.SelectGenerator; import org.hibernate.id.SequenceGenerator; import org.hibernate.id.enhanced.DatabaseStructure; import org.hibernate.id.enhanced.SequenceStructure; import org.hibernate.id.enhanced.SequenceStyleGenerator; import org.hibernate.id.enhanced.TableGenerator; import org.hibernate.id.enhanced.TableStructure; import org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory; import org.hibernate.reactive.id.ReactiveIdentifierGenerator; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.type.Type; import java.util.Properties; /** * @author Gavin King */ public class ReactiveIdentifierGeneratorFactory extends DefaultIdentifierGeneratorFactory { private ServiceRegistryImplementor serviceRegistry; @Override public void injectServices(ServiceRegistryImplementor serviceRegistry) { super.injectServices(serviceRegistry); this.serviceRegistry = serviceRegistry; } @Override public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config) { Object generator; try { Class<?> clazz = getIdentifierGeneratorClass( strategy ); generator = clazz.getDeclaredConstructor().newInstance(); } catch ( Exception e ) { final String entityName = config.getProperty( IdentifierGenerator.ENTITY_NAME ); throw new MappingException( String.format( "Could not instantiate id generator [entity-name=%s]", entityName ), e ); } if ( generator instanceof Configurable) { ( (Configurable) generator ).configure( type, config, serviceRegistry ); } IdentifierGenerator result; if ( generator instanceof IdentifierGenerator ) { result = augmentWithReactiveGenerator( (IdentifierGenerator) generator, type, config, serviceRegistry ); } else if ( generator instanceof ReactiveIdentifierGenerator) { result = new ReactiveGeneratorWrapper<>( (ReactiveIdentifierGenerator<?>) generator ); } else { final String entityName = config.getProperty( IdentifierGenerator.ENTITY_NAME ); throw new MappingException( String.format( "Not an id generator [entity-name=%s]", entityName ) ); } if ( result instanceof Configurable) { ( (Configurable) result ).configure( type, config, serviceRegistry ); } return result; } private static IdentifierGenerator augmentWithReactiveGenerator(IdentifierGenerator generator, Type type, Properties params, ServiceRegistryImplementor serviceRegistry) { ReactiveIdentifierGenerator<?> reactiveGenerator; if (generator instanceof SequenceStyleGenerator) { DatabaseStructure structure = ((SequenceStyleGenerator) generator).getDatabaseStructure(); if (structure instanceof TableStructure) { reactiveGenerator = new TableReactiveIdentifierGenerator(true); } else if (structure instanceof SequenceStructure) { reactiveGenerator = new SequenceReactiveIdentifierGenerator(); } else { throw new IllegalStateException("unknown structure type"); } } else if (generator instanceof TableGenerator) { reactiveGenerator = new TableReactiveIdentifierGenerator(false); } else if (generator instanceof SequenceGenerator) { reactiveGenerator = new SequenceReactiveIdentifierGenerator(); } else if (generator instanceof SelectGenerator) { //TODO: this is easy to fix! throw new HibernateException("SelectGenerator is not yet supported in Hibernate Reactive"); } else { //nothing to do return generator; } ((Configurable) reactiveGenerator).configure( type, params, serviceRegistry ); return new ReactiveGeneratorWrapper<>( reactiveGenerator, generator ); } }