All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.tool.internal.reveng.RevengMetadataBuilder Maven / Gradle / Ivy

There is a newer version: 7.0.0.Beta1
Show newest version
/*
 * Created on 2004-11-23
 *
 */
package org.hibernate.tool.internal.reveng;


import java.util.Properties;

import org.hibernate.boot.Metadata;
import org.hibernate.boot.internal.BootstrapContextImpl;
import org.hibernate.boot.internal.InFlightMetadataCollectorImpl;
import org.hibernate.boot.internal.MetadataBuilderImpl.MetadataBuildingOptionsImpl;
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
import org.hibernate.boot.internal.MetadataImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataBuildingOptions;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.mapping.Table;
import org.hibernate.tool.api.reveng.RevengDialect;
import org.hibernate.tool.api.reveng.RevengDialectFactory;
import org.hibernate.tool.api.reveng.RevengStrategy;
import org.hibernate.tool.internal.reveng.binder.BinderContext;
import org.hibernate.tool.internal.reveng.binder.RootClassBinder;
import org.hibernate.tool.internal.reveng.reader.DatabaseReader;
import org.jboss.logging.Logger;


/**
 * @author max
 * @author koen
 */
public class RevengMetadataBuilder {
	
	
	public static RevengMetadataBuilder create(
			Properties properties, 
			RevengStrategy reverseEngineeringStrategy) {
		return new RevengMetadataBuilder(properties, reverseEngineeringStrategy);
	}
	
	private static final Logger LOGGER = Logger.getLogger(RevengMetadataBuilder.class);

	private final Properties properties;
	private final MetadataBuildingContext metadataBuildingContext;	
	private final InFlightMetadataCollectorImpl metadataCollector;	
	private final RevengStrategy revengStrategy;
	private final BinderContext binderContext;
	
	private final StandardServiceRegistry serviceRegistry;
	
	private RevengMetadataBuilder(
			Properties properties,
			RevengStrategy reverseEngineeringStrategy) {
		this.properties = properties;
		this.revengStrategy = reverseEngineeringStrategy;
		this.serviceRegistry = new StandardServiceRegistryBuilder()
				.applySettings(properties)
				.build();
		MetadataBuildingOptionsImpl metadataBuildingOptions = 
				new MetadataBuildingOptionsImpl(serviceRegistry);	
		BootstrapContextImpl bootstrapContext = new BootstrapContextImpl(
				serviceRegistry, 
				metadataBuildingOptions);
		metadataBuildingOptions.setBootstrapContext(bootstrapContext);
		this.metadataCollector = 
				new InFlightMetadataCollectorImpl(
						bootstrapContext,
						metadataBuildingOptions);
		handleTypes(bootstrapContext, metadataBuildingOptions);
		this.metadataBuildingContext = new MetadataBuildingContextRootImpl(
				"tools", 
				bootstrapContext, 
				metadataBuildingOptions, 
				metadataCollector, 
				null);
		this.binderContext = BinderContext
				.create(
						metadataBuildingContext, 
						metadataCollector, 
						reverseEngineeringStrategy, 
						properties);
	}

	public Metadata build() {
		Metadata result = createMetadata();		
        createPersistentClasses(readFromDatabase()); 
		return result;
	}
	
	private MetadataImpl createMetadata() {
		MetadataImpl result = metadataCollector.buildMetadataInstance(metadataBuildingContext);
		result.getTypeConfiguration().scope(metadataBuildingContext);		
		return result;
	}
	
	private RevengMetadataCollector readFromDatabase() {
		RevengDialect mdd = RevengDialectFactory
				.createMetaDataDialect(
						serviceRegistry.getService(JdbcServices.class).getDialect(), 
						properties );
	    DatabaseReader reader = DatabaseReader.create(properties,revengStrategy,mdd, serviceRegistry);
	    RevengMetadataCollector revengMetadataCollector = new RevengMetadataCollector(metadataBuildingContext);
        reader.readDatabaseSchema(revengMetadataCollector);
        return revengMetadataCollector;
	}
	
	// TODO: this naively just create an entity per table
	// should have an opt-out option to mark some as helper tables, subclasses etc.
	/*if(table.getPrimaryKey()==null || table.getPrimaryKey().getColumnSpan()==0) {
	    log.warn("Cannot create persistent class for " + table + " as no primary key was found.");
        continue;
        // TODO: just create one big embedded composite id instead.
    }*/
	private void createPersistentClasses(RevengMetadataCollector revengMetadataCollector) {
		RootClassBinder rootClassBinder = RootClassBinder.create(binderContext);
		for (Table table : metadataCollector.collectTableMappings()) {
			if(table.getColumnSpan()==0) {
				LOGGER.warn("Cannot create persistent class for " + table + " as no columns were found.");
				continue;
			}
			if(revengStrategy.isManyToManyTable(table)) {
				LOGGER.debug( "Ignoring " + table + " as class since rev.eng. says it is a many-to-many" );
				continue;
			}	    	
			rootClassBinder.bind(table, revengMetadataCollector);
		}		
		metadataCollector.processSecondPasses(metadataBuildingContext);	
	}
	
	
	private static void handleTypes(BootstrapContext bootstrapContext, MetadataBuildingOptions options) {
		Dialect dialect = options.getServiceRegistry().getService( JdbcServices.class ).getDialect();
		dialect.contributeTypes( () -> bootstrapContext.getTypeConfiguration(), options.getServiceRegistry() );
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy