package org.hibernate.tool.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; public class MetadataHelper { public static Metadata getMetadata(Configuration configuration) { Metadata result = getMetadataFromMethod(configuration); if (result == null) { result = getMetadataFromField(configuration); } if (result == null) { result = buildFromMetadataSources(configuration); } return result; } public static MetadataSources getMetadataSources(Configuration configuration) { MetadataSources result = null; Field metadataSourcesField = getField("metadataSources", configuration); if (metadataSourcesField != null) { try { metadataSourcesField.setAccessible(true); result = (MetadataSources)metadataSourcesField.get(configuration); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } } if (result == null) { result = new MetadataSources(); } return result; } private static Metadata buildFromMetadataSources(Configuration configuration) { MetadataSources metadataSources = getMetadataSources(configuration); StandardServiceRegistryBuilder builder = configuration.getStandardServiceRegistryBuilder(); builder.applySettings(configuration.getProperties()); StandardServiceRegistry serviceRegistry = builder.build(); return metadataSources.buildMetadata(serviceRegistry); } private static Metadata getMetadataFromField(Configuration configuration) { Metadata result = null; Field metadataField = getField("metadata", configuration); if (metadataField != null) { try { metadataField.setAccessible(true); result = (Metadata)metadataField.get(configuration); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } } return result; } private static Metadata getMetadataFromMethod(Configuration configuration) { Metadata result = null; Method metadataMethod = getMethod("getMetadata", configuration); if (metadataMethod != null) { try { metadataMethod.setAccessible(true); result = (Metadata)metadataMethod.invoke( configuration, new Object[] {}); } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { throw new RuntimeException(e); } } return result; } private static Field getField(String fieldName, Object target) { Field result = null; Class<?> clazz = target.getClass(); while (clazz != null) { try { result = clazz.getDeclaredField(fieldName); // if it exists, exit the while loop break; } catch (NoSuchFieldException e) { // if it doesn't exist, look in the superclass clazz = clazz.getSuperclass(); } catch (SecurityException e) { throw new RuntimeException(e); } } return result; } private static Method getMethod(String methodName, Object target) { Method result = null; Class<?> clazz = target.getClass(); try { result = clazz.getMethod(methodName, new Class[] {}); } catch (NoSuchMethodException | SecurityException e1) { // ignore; } return result; } }