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

com.devonfw.cobigen.impl.model.ModelBuilderImpl Maven / Gradle / Ivy

There is a newer version: 2021.12.006
Show newest version
package com.devonfw.cobigen.impl.model;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.devonfw.cobigen.api.constants.ConfigurationConstants;
import com.devonfw.cobigen.api.exception.CobiGenRuntimeException;
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.api.extension.InputReader;
import com.devonfw.cobigen.api.extension.MatcherInterpreter;
import com.devonfw.cobigen.api.extension.ModelBuilder;
import com.devonfw.cobigen.api.extension.TriggerInterpreter;
import com.devonfw.cobigen.impl.config.entity.Template;
import com.devonfw.cobigen.impl.config.entity.Trigger;
import com.devonfw.cobigen.impl.config.entity.VariableAssignment;
import com.devonfw.cobigen.impl.config.entity.Variables;
import com.devonfw.cobigen.impl.config.reader.CobiGenPropertiesReader;
import com.devonfw.cobigen.impl.extension.PluginRegistry;
import com.devonfw.cobigen.impl.validator.InputValidator;
import com.google.common.collect.Maps;

/**
 * The {@link ModelBuilderImpl} is responsible to create the object models for a given object. Therefore, it
 * uses {@link TriggerInterpreter} plug-in extensions to query available {@link InputReader}s and
 * {@link MatcherInterpreter}s
 */
public class ModelBuilderImpl implements ModelBuilder {

    /** Namespace of the context and CobiGen variables retrieved by cobigen-core */
    public static final String NS_VARIABLES = "variables";

    /** Input object for which a new object model should be created */
    private Object generatorInput;

    /** Trigger, which has been activated for the given input */
    private Trigger trigger;

    /**
     * Creates a new {@link ModelBuilderImpl} instance for the given properties
     * @param generatorInput
     *            object for which a new object model should be created
     * @param trigger
     *            which has been activated for the given input
     */
    public ModelBuilderImpl(Object generatorInput, Trigger trigger) {
        if (generatorInput == null || trigger == null || trigger.getMatcher() == null) {
            throw new IllegalArgumentException(
                "Cannot create Model from input == null || trigger == null || trigger.getMatcher() == null");
        }
        this.generatorInput = generatorInput;
        this.trigger = trigger;
    }

    /**
     * Creates a new model by trying to retrieve the corresponding {@link TriggerInterpreter} from the plug-in
     * registry
     * @return the created model
     * @throws InvalidConfigurationException
     *             if there are {@link VariableAssignment}s, which could not be resolved
     */
    @Override
    public Map createModel() throws InvalidConfigurationException {
        TriggerInterpreter triggerInterpreter = PluginRegistry.getTriggerInterpreter(trigger.getType());
        InputValidator.validateTriggerInterpreter(triggerInterpreter, trigger);
        return createModel(triggerInterpreter);
    }

    /**
     * Creates a new model by using the given {@link TriggerInterpreter} to retrieve the {@link InputReader}
     * and {@link MatcherInterpreter} from.
     * @param triggerInterpreter
     *            to be used
     * @return the created model
     * @throws InvalidConfigurationException
     *             if there are {@link VariableAssignment}s, which could not be resolved
     */
    @Override
    public Map createModel(TriggerInterpreter triggerInterpreter) throws InvalidConfigurationException {
        Map model = new HashMap<>(triggerInterpreter.getInputReader().createModel(generatorInput));
        return model;
    }

    /**
     * Enriches the model by the context variables of the trigger.
     * @param model
     *            to be enriched
     * @param triggerInterpreter
     *            {@link TriggerInterpreter} to resolve the variables
     * @param template
     *            the internal {@link Template} representation
     * @param targetRootPath
     *            root path template destinations should be resolved against
     * @return the adapted model reference.
     */
    public Map enrichByContextVariables(Map model,
        TriggerInterpreter triggerInterpreter, Template template, Path targetRootPath) {
        Map variables = Maps.newHashMap();
        Map contextVariables =
            new ContextVariableResolver(generatorInput, trigger).resolveVariables(triggerInterpreter).asMap();
        Map templateProperties = template.getVariables().asMap();
        Properties targetCobiGenProperties = CobiGenPropertiesReader.load(targetRootPath);
        // if there are properties overriding each other, throw an exception for better usability.
        // This is most probably a not intended mechanism such that we simply will not support it.
        Set intersection = new HashSet<>(contextVariables.keySet());
        intersection.retainAll(templateProperties.keySet());
        Set intersection2 = new HashSet<>(contextVariables.keySet());
        intersection2.retainAll(targetCobiGenProperties.keySet());
        if (!intersection.isEmpty() || !intersection2.isEmpty()) {
            throw new CobiGenRuntimeException("There are conflicting variables coming from the context configuration "
                + "as well as coming from the " + ConfigurationConstants.COBIGEN_PROPERTIES + " file. "
                + "This is most probably an unintended behavior and thus is not supported. The following variables are "
                + "declared twice (once in " + ConfigurationConstants.CONTEXT_CONFIG_FILENAME + " and once in "
                + ConfigurationConstants.COBIGEN_PROPERTIES + " file): " + Arrays.toString(intersection.toArray()));
        }
        variables.putAll(contextVariables);
        variables.putAll(templateProperties);
        variables.putAll(new Variables(targetCobiGenProperties).asMap());
        model.put(NS_VARIABLES, variables);
        return model;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy