com.devonfw.cobigen.impl.model.ModelBuilderImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
A Code-based incremental Generator
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(this.trigger.getType());
InputValidator.validateTriggerInterpreter(triggerInterpreter, this.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(this.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(this.generatorInput, this.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;
}
}