// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputConfiguration.java
// public class RuleInputConfiguration {
//     private final String ruleInputName;
//     private final IInputValueBuilder inputValueBuilder;
// 
//     public RuleInputConfiguration(String ruleInputName, IInputValueBuilder inputValueBuilder) {
//         this.ruleInputName = ruleInputName;
//         this.inputValueBuilder = inputValueBuilder;
//     }
// 
//     public String getRuleInputName() {
//         return ruleInputName;
//     }
// 
//     public IInputValueBuilder getInputValueBuilder() {
//         return inputValueBuilder;
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputConfigurator.java
// public class RuleInputConfigurator {
//     private final Map<String, RuleInputConfiguration> configMap = new ConcurrentHashMap<>();
// 
//     public void addConfiguration(RuleInputConfiguration config) throws Exception {
//         RuleInputConfiguration existingConfig = configMap.get(config.getRuleInputName());
//         if (existingConfig != null) {
//             throw new Exception("Config already present for input name " + config.getRuleInputName());
//         } else {
//             configMap.put(config.getRuleInputName(), config);
//         }
//     }
// 
//     public RuleInputConfiguration getConfig(String ruleInputName) {
//         return this.configMap.get(ruleInputName);
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputValueFactory.java
// public class RuleInputValueFactory {
//     private static RuleInputValueFactory INSTANCE;
//     private final Map<String, IInputValueBuilder> builderMap;
//     private static final Logger LOGGER = LoggerFactory.getLogger(RuleInputValueFactory.class);
// 
//     private RuleInputValueFactory() {
//         LOGGER.info("Initializing input data type factory...");
//         this.builderMap = new ConcurrentHashMap<>();
//         LOGGER.info("Input data type factory initialized");
//     }
// 
//     public static RuleInputValueFactory getInstance() {
//         if (INSTANCE == null) {
//             INSTANCE = new RuleInputValueFactory();
//         }
// 
//         return INSTANCE;
//     }
// 
//     public IInputValue buildRuleInputVaue(String ruleInputName, String rawValue) {
// 
//         IInputValueBuilder builder = builderMap.get(ruleInputName);
//         if (builder == null) {
//             throw new IllegalArgumentException("No input value builder registered for input " + ruleInputName);
//         } else {
//             return builder.build(rawValue);
//         }
//     }
// 
//     public void registerRuleInputBuilder(String ruleInputName, IInputValueBuilder builder) {
//         builderMap.put(ruleInputName, builder);
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/value/DefaultDataType.java
// public enum DefaultDataType {
//     NUMBER,
//     DATE,
//     STRING
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/value/defaults/DefaultBuilderRegistry.java
// public class DefaultBuilderRegistry {
//     private final Map<String, IInputValueBuilder> builderRegister;
//     private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuilderRegistry.class);
// 
//     public DefaultBuilderRegistry() {
//         LOGGER.info("Initializing default builder registry...");
// 
//         this.builderRegister = new ConcurrentHashMap<>();
//         this.builderRegister.put("STRING", new DefaultStringInputBuilder());
//         this.builderRegister.put("DATE", new DefaultDateInputBuilder());
//         this.builderRegister.put("NUMBER", new DefaultNumberInputBuilder());
//     }
// 
//     public IInputValueBuilder getDefaultBuilder(String dataType) {
//         return this.builderRegister.get(dataType);
//     }
// }


import com.github.kislayverma.rulette.core.ruleinput.RuleInputConfiguration;
import com.github.kislayverma.rulette.core.ruleinput.RuleInputConfigurator;
import com.github.kislayverma.rulette.core.ruleinput.RuleInputValueFactory;
import com.github.kislayverma.rulette.core.ruleinput.value.DefaultDataType;
import com.github.kislayverma.rulette.core.ruleinput.value.defaults.DefaultBuilderRegistry;
import java.util.List;
package com.github.kislayverma.rulette.core.metadata;


/**
 * This class represents the rule systems entity model.
 */
public class RuleSystemMetaData {
    private final DefaultBuilderRegistry BUILDER_REGISTRY = new DefaultBuilderRegistry();

    private final String ruleSystemName;
    private final String tableName;
    private final List<RuleInputMetaData> inputColumnList;
    private final String uniqueIdColumnName;
    private final String uniqueOutputColumnName;

    public RuleSystemMetaData(
            String ruleSystemName,
            String tableName,
            String uniqueIdColName,
            String uniqueOutputColName,
            List<RuleInputMetaData> inputs) {
        this.ruleSystemName = ruleSystemName;
        this.tableName = tableName;
        this.uniqueIdColumnName = uniqueIdColName;
        this.uniqueOutputColumnName = uniqueOutputColName;
        this.inputColumnList = inputs;
    }

    /**
     * This method loads default configuration for all rule inputs if no custom override 
     * is given (in which case it overrides the defaults).
     * Input and output columns always get default configuration.
     * 
     * @param configuration Custom configuration for rule inputs
     */
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputConfiguration.java
// public class RuleInputConfiguration {
//     private final String ruleInputName;
//     private final IInputValueBuilder inputValueBuilder;
// 
//     public RuleInputConfiguration(String ruleInputName, IInputValueBuilder inputValueBuilder) {
//         this.ruleInputName = ruleInputName;
//         this.inputValueBuilder = inputValueBuilder;
//     }
// 
//     public String getRuleInputName() {
//         return ruleInputName;
//     }
// 
//     public IInputValueBuilder getInputValueBuilder() {
//         return inputValueBuilder;
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputConfigurator.java
// public class RuleInputConfigurator {
//     private final Map<String, RuleInputConfiguration> configMap = new ConcurrentHashMap<>();
// 
//     public void addConfiguration(RuleInputConfiguration config) throws Exception {
//         RuleInputConfiguration existingConfig = configMap.get(config.getRuleInputName());
//         if (existingConfig != null) {
//             throw new Exception("Config already present for input name " + config.getRuleInputName());
//         } else {
//             configMap.put(config.getRuleInputName(), config);
//         }
//     }
// 
//     public RuleInputConfiguration getConfig(String ruleInputName) {
//         return this.configMap.get(ruleInputName);
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/RuleInputValueFactory.java
// public class RuleInputValueFactory {
//     private static RuleInputValueFactory INSTANCE;
//     private final Map<String, IInputValueBuilder> builderMap;
//     private static final Logger LOGGER = LoggerFactory.getLogger(RuleInputValueFactory.class);
// 
//     private RuleInputValueFactory() {
//         LOGGER.info("Initializing input data type factory...");
//         this.builderMap = new ConcurrentHashMap<>();
//         LOGGER.info("Input data type factory initialized");
//     }
// 
//     public static RuleInputValueFactory getInstance() {
//         if (INSTANCE == null) {
//             INSTANCE = new RuleInputValueFactory();
//         }
// 
//         return INSTANCE;
//     }
// 
//     public IInputValue buildRuleInputVaue(String ruleInputName, String rawValue) {
// 
//         IInputValueBuilder builder = builderMap.get(ruleInputName);
//         if (builder == null) {
//             throw new IllegalArgumentException("No input value builder registered for input " + ruleInputName);
//         } else {
//             return builder.build(rawValue);
//         }
//     }
// 
//     public void registerRuleInputBuilder(String ruleInputName, IInputValueBuilder builder) {
//         builderMap.put(ruleInputName, builder);
//     }
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/value/DefaultDataType.java
// public enum DefaultDataType {
//     NUMBER,
//     DATE,
//     STRING
// }
// 
// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/ruleinput/value/defaults/DefaultBuilderRegistry.java
// public class DefaultBuilderRegistry {
//     private final Map<String, IInputValueBuilder> builderRegister;
//     private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuilderRegistry.class);
// 
//     public DefaultBuilderRegistry() {
//         LOGGER.info("Initializing default builder registry...");
// 
//         this.builderRegister = new ConcurrentHashMap<>();
//         this.builderRegister.put("STRING", new DefaultStringInputBuilder());
//         this.builderRegister.put("DATE", new DefaultDateInputBuilder());
//         this.builderRegister.put("NUMBER", new DefaultNumberInputBuilder());
//     }
// 
//     public IInputValueBuilder getDefaultBuilder(String dataType) {
//         return this.builderRegister.get(dataType);
//     }
// }


// Path: rulette-core/src/main/java/com/github/kislayverma/rulette/core/metadata/RuleSystemMetaData.java
import com.github.kislayverma.rulette.core.ruleinput.RuleInputConfiguration;
import com.github.kislayverma.rulette.core.ruleinput.RuleInputConfigurator;
import com.github.kislayverma.rulette.core.ruleinput.RuleInputValueFactory;
import com.github.kislayverma.rulette.core.ruleinput.value.DefaultDataType;
import com.github.kislayverma.rulette.core.ruleinput.value.defaults.DefaultBuilderRegistry;
import java.util.List;

package com.github.kislayverma.rulette.core.metadata;


/**
 * This class represents the rule systems entity model.
 */
public class RuleSystemMetaData {
    private final DefaultBuilderRegistry BUILDER_REGISTRY = new DefaultBuilderRegistry();

    private final String ruleSystemName;
    private final String tableName;
    private final List<RuleInputMetaData> inputColumnList;
    private final String uniqueIdColumnName;
    private final String uniqueOutputColumnName;

    public RuleSystemMetaData(
            String ruleSystemName,
            String tableName,
            String uniqueIdColName,
            String uniqueOutputColName,
            List<RuleInputMetaData> inputs) {
        this.ruleSystemName = ruleSystemName;
        this.tableName = tableName;
        this.uniqueIdColumnName = uniqueIdColName;
        this.uniqueOutputColumnName = uniqueOutputColName;
        this.inputColumnList = inputs;
    }

    /**
     * This method loads default configuration for all rule inputs if no custom override 
     * is given (in which case it overrides the defaults).
     * Input and output columns always get default configuration.
     * 
     * @param configuration Custom configuration for rule inputs
     */
    public void applyCustomConfiguration(RuleInputConfigurator configuration) {