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

org.hibernate.testing.boot.ExtraJavaServicesClassLoaderService Maven / Gradle / Ivy

/*
 * SPDX-License-Identifier: LGPL-2.1-or-later
 * Copyright Red Hat Inc. and Hibernate Authors
 */
package org.hibernate.testing.boot;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;

/**
 * @author Steve Ebersole
 */
public class ExtraJavaServicesClassLoaderService extends ClassLoaderServiceImpl {
	private final List> extraJavaServices;

	public ExtraJavaServicesClassLoaderService(List> extraJavaServices) {
		this.extraJavaServices = extraJavaServices;
	}

	@Override
	public  Collection loadJavaServices(Class serviceContract) {
		final Collection baseServices = super.loadJavaServices( serviceContract );
		final List services = new ArrayList<>( baseServices );

		applyExtraJavaServices( serviceContract, services );

		return services;
	}

	private  void applyExtraJavaServices(Class serviceContract, List services) {
		extraJavaServices.forEach(
				(javaServiceDescriptor) -> {
					if ( serviceContract.isAssignableFrom( javaServiceDescriptor.role ) ) {
						try {
							final Object serviceInstance = javaServiceDescriptor.impl.getDeclaredConstructor().newInstance();
							//noinspection unchecked
							services.add( (S) serviceInstance );
						}
						catch (NoSuchMethodException | IllegalAccessException e) {
							throw new RuntimeException( "Unable to access constructor for specified 'extra' Java service : " + javaServiceDescriptor.impl.getName(), e );
						}
						catch (InstantiationException | InvocationTargetException e) {
							throw new RuntimeException( "Unable to instantiate specified 'extra' Java service : " + javaServiceDescriptor.impl.getName(), e );
						}
					}
				}
		);
	}

	public static class JavaServiceDescriptor {
		private final Class role;
		private final Class impl;

		public JavaServiceDescriptor(Class role, Class impl) {
			this.role = role;
			this.impl = impl;
		}

		public Class getRole() {
			return role;
		}

		public Class getImpl() {
			return impl;
		}
	}
}