<commit_before>package org.unix4j.builder;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.unix4j.command.Command;
import org.unix4j.command.CommandInterface;

public class GenericCommandBuilder {
	
	public static <B extends CommandBuilder> B createCommandBuilder(Class<B> commandBuilderInterface, CommandInterface<? extends Command<?>>... commandFactories) {
		return createCommandBuilder(commandBuilderInterface, new DefaultCommandBuilder(), commandFactories);
	}
	@SuppressWarnings("unchecked")
	public static <B extends CommandBuilder> B createCommandBuilder(Class<B> commandBuilderInterface, DefaultCommandBuilder defaultCommandBuilder, CommandInterface<? extends Command<?>>... commandFactories) {
		if (commandBuilderInterface.isInterface()) {
			return (B) Proxy.newProxyInstance(GenericCommandBuilder.class.getClassLoader(), new Class[] {commandBuilderInterface}, new GenericCommandHandler<B>(commandBuilderInterface, defaultCommandBuilder, commandFactories));
		}
		throw new IllegalArgumentException(commandBuilderInterface.getName() + " must be an interface");
	}

	private static class GenericCommandHandler<B extends CommandBuilder> implements InvocationHandler {
		private final DefaultCommandBuilder defaultCommandBuilder;
		private final Map<MethodSignature, Object> signatureToTarget = new HashMap<GenericCommandBuilder.MethodSignature, Object>();
		public GenericCommandHandler(Class<B> commandBuilderInterface, DefaultCommandBuilder defaultCommandBuilder, CommandInterface<? extends Command<?>>... commandFactories) {
			this.defaultCommandBuilder = defaultCommandBuilder;
			final Map<MethodSignature, Object> factoryMethods = new HashMap<GenericCommandBuilder.MethodSignature, Object>();
			addSignatures(factoryMethods, defaultCommandBuilder);
			for (int i = 0; i < commandFactories.length; i++) {
				addSignatures(factoryMethods, commandFactories[i]);
			}
			for (final Method method : defaultCommandBuilder.getClass().getMethods()) {
				final MethodSignature signature = new MethodSignature(method);
				signatureToTarget.put(signature, defaultCommandBuilder);
			}
			for (final Method method : commandBuilderInterface.getMethods()) {
				final MethodSignature signature = new MethodSignature(method);
				final Object factory = factoryMethods.get(signature);
				if (factory == null) {
					throw new IllegalArgumentException("No factory method found for method " + signature + " defined in interface " + commandBuilderInterface.getName());
				}
				final Object otherFactory = signatureToTarget.get(signature);
				if (otherFactory == null) {
					signatureToTarget.put(signature, factory);
				} else {
					if (factory != otherFactory) {
						throw new IllegalArgumentException("method " + signature + " exist in " + otherFactory.getClass().getName() + " and also in " + factory.getClass().getName());
					}
				}
			}
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			final MethodSignature signature = new MethodSignature(method);
			final Object target = signatureToTarget.get(signature);
			if (target != null) {
				Object result = signature.invoke(target, args);
				if (result instanceof Command) {
					result = defaultCommandBuilder.join((Command<?>)result);
				}
				if (result instanceof DefaultCommandBuilder) {
					result = proxy;
				}
				return result;<commit_msg>minor fix when returning proxy instance for generic command builder<commit_after>package org.unix4j.builder;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.unix4j.command.Command;
import org.unix4j.command.CommandInterface;

public class GenericCommandBuilder {
	
	public static <B extends CommandBuilder> B createCommandBuilder(Class<B> commandBuilderInterface, CommandInterface<? extends Command<?>>... commandFactories) {
		return createCommandBuilder(commandBuilderInterface, new DefaultCommandBuilder(), commandFactories);
	}
	@SuppressWarnings("unchecked")
	public static <B extends CommandBuilder> B createCommandBuilder(Class<B> commandBuilderInterface, DefaultCommandBuilder defaultCommandBuilder, CommandInterface<? extends Command<?>>... commandFactories) {
		if (commandBuilderInterface.isInterface()) {
			return (B) Proxy.newProxyInstance(GenericCommandBuilder.class.getClassLoader(), new Class[] {commandBuilderInterface}, new GenericCommandHandler<B>(commandBuilderInterface, defaultCommandBuilder, commandFactories));
		}
		throw new IllegalArgumentException(commandBuilderInterface.getName() + " must be an interface");
	}

	private static class GenericCommandHandler<B extends CommandBuilder> implements InvocationHandler {
		private final DefaultCommandBuilder defaultCommandBuilder;
		private final Map<MethodSignature, Object> signatureToTarget = new HashMap<GenericCommandBuilder.MethodSignature, Object>();
		public GenericCommandHandler(Class<B> commandBuilderInterface, DefaultCommandBuilder defaultCommandBuilder, CommandInterface<? extends Command<?>>... commandFactories) {
			this.defaultCommandBuilder = defaultCommandBuilder;
			final Map<MethodSignature, Object> factoryMethods = new HashMap<GenericCommandBuilder.MethodSignature, Object>();
			addSignatures(factoryMethods, defaultCommandBuilder);
			for (int i = 0; i < commandFactories.length; i++) {
				addSignatures(factoryMethods, commandFactories[i]);
			}
			for (final Method method : defaultCommandBuilder.getClass().getMethods()) {
				final MethodSignature signature = new MethodSignature(method);
				signatureToTarget.put(signature, defaultCommandBuilder);
			}
			for (final Method method : commandBuilderInterface.getMethods()) {
				final MethodSignature signature = new MethodSignature(method);
				final Object factory = factoryMethods.get(signature);
				if (factory == null) {
					throw new IllegalArgumentException("No factory method found for method " + signature + " defined in interface " + commandBuilderInterface.getName());
				}
				final Object otherFactory = signatureToTarget.get(signature);
				if (otherFactory == null) {
					signatureToTarget.put(signature, factory);
				} else {
					if (factory != otherFactory) {
						throw new IllegalArgumentException("method " + signature + " exist in " + otherFactory.getClass().getName() + " and also in " + factory.getClass().getName());
					}
				}
			}
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			final MethodSignature signature = new MethodSignature(method);
			final Object target = signatureToTarget.get(signature);
			if (target != null) {
				Object result = signature.invoke(target, args);
				if (result instanceof Command) {
					result = defaultCommandBuilder.join((Command<?>)result);
				}
				if (result == defaultCommandBuilder) {
					result = proxy;
				}
				return result;
{'fraction_non_alphanumeric': 0.09733036707452725, 'fraction_numerical': 0.0011123470522803114, 'mean_word_length': 5.697392923649907, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2367759', 'n_tokens_mistral': 1971, 'n_tokens_neox': 1742, 'n_words': 467}