Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1452 Implemented new configuration reader to read the template sets #1504

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,7 @@ public static List<Path> getJarFiles(Path templatesDirectory) {
* @param templatesDirectory directory where the templates are located
* @return file of the jar downloaded or null if it was not found
*
* @deprecated use getJarFiles instead
*/
@Deprecated
public static File getJarFile(boolean isSource, File templatesDirectory) {

File[] jarFiles;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.nio.file.Paths;
import java.util.Map;

import com.devonfw.cobigen.api.constants.ConfigurationConstants;
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.impl.config.entity.Trigger;
import com.devonfw.cobigen.impl.extension.PluginRegistry;
Expand All @@ -16,8 +17,8 @@
*/
public class ConfigurationHolder {

/** Cached templates configurations. Configuration File URI -> Trigger ID -> configuration instance */
private Map<Path, Map<String, TemplatesConfiguration>> templatesConfigurations = Maps.newHashMap();
/** Cached templates configurations. Trigger ID -> Configuration File URI -> configuration instance */
private Map<String, Map<Path, TemplatesConfiguration>> templatesConfigurations = Maps.newHashMap();

/** Cached context configuration */
private ContextConfiguration contextConfiguration;
Expand Down Expand Up @@ -75,15 +76,16 @@ public Path getConfigurationPath() {
*/
public TemplatesConfiguration readTemplatesConfiguration(Trigger trigger) {

Path configRoot = readContextConfiguration().getConfigRootforTrigger(trigger.getId());
Path templateFolder = Paths.get(trigger.getTemplateFolder());
if (!this.templatesConfigurations.containsKey(templateFolder)) {
this.templatesConfigurations.put(templateFolder, Maps.<String, TemplatesConfiguration> newHashMap());
if (!this.templatesConfigurations.containsKey(trigger.getId())) {
this.templatesConfigurations.put(trigger.getId(), Maps.<Path, TemplatesConfiguration> newHashMap());
GuentherJulian marked this conversation as resolved.
Show resolved Hide resolved

TemplatesConfiguration config = new TemplatesConfiguration(this.configurationPath, trigger, this);
this.templatesConfigurations.get(templateFolder).put(trigger.getId(), config);
TemplatesConfiguration config = new TemplatesConfiguration(configRoot, trigger, this);
this.templatesConfigurations.get(trigger.getId()).put(templateFolder, config);
}

return this.templatesConfigurations.get(templateFolder).get(trigger.getId());
return this.templatesConfigurations.get(trigger.getId()).get(templateFolder);
}

/**
Expand All @@ -99,4 +101,16 @@ public ContextConfiguration readContextConfiguration() {
}
return this.contextConfiguration;
}

/**
* @return return if the template folder structure consists of template sets or if the old structure is used
*/
public boolean isTemplateSetConfiguration() {

if (this.configurationPath.toUri().getScheme().equals("jar")
|| !this.configurationPath.getFileName().toString().equals(ConfigurationConstants.TEMPLATE_SETS_FOLDER)) {
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.impl.config.entity.Trigger;
import com.devonfw.cobigen.impl.config.reader.AbstractContextConfigurationReader;
import com.devonfw.cobigen.impl.config.reader.ContextConfigurationAnalyzer;
import com.devonfw.cobigen.impl.config.reader.ContextConfigurationReader;
import com.devonfw.cobigen.impl.config.reader.ContextConfigurationReaderFactory;
import com.devonfw.cobigen.impl.config.reader.ContextConfigurationSetReader;

/**
* The {@link ContextConfiguration} is a configuration data wrapper for all information about templates and the target
Expand All @@ -27,6 +29,11 @@ public class ContextConfiguration {
*/
private Path configurationPath;

/**
* The reader to read the context.xml files
*/
private AbstractContextConfigurationReader contextConfigurationReader;

/**
* Creates a new {@link ContextConfiguration} with the contents initially loaded from the context.xml
*
Expand All @@ -47,10 +54,12 @@ public ContextConfiguration(Path configRoot) throws InvalidConfigurationExceptio
*/
private void readConfiguration(Path configRoot) throws InvalidConfigurationException {

AbstractContextConfigurationReader reader = ContextConfigurationAnalyzer.getReader(configRoot);
if (this.contextConfigurationReader == null) {
this.contextConfigurationReader = ContextConfigurationReaderFactory.getReader(configRoot);
}

this.configurationPath = reader.getContextRoot();
this.triggers = reader.loadTriggers();
this.configurationPath = this.contextConfigurationReader.getContextRoot();
this.triggers = this.contextConfigurationReader.loadTriggers();
}

/**
Expand Down Expand Up @@ -96,4 +105,16 @@ public Path getConfigurationPath() {
return this.configurationPath;
}

/**
* @param triggerId the trigger id to get the config root directory for
* @return the {@link Path} of the config root directory of the trigger
*/
public Path getConfigRootforTrigger(String triggerId) {

if (this.contextConfigurationReader instanceof ContextConfigurationReader) {
return this.contextConfigurationReader.getContextRoot();
GuentherJulian marked this conversation as resolved.
Show resolved Hide resolved
}
return ((ContextConfigurationSetReader) this.contextConfigurationReader).getConfigRootForTrigger(triggerId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
Expand All @@ -21,13 +18,11 @@
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.devonfw.cobigen.api.constants.ConfigurationConstants;
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.api.util.ExceptionUtil;
import com.devonfw.cobigen.api.util.JvmUtil;
import com.devonfw.cobigen.impl.config.constant.ContextConfigurationVersion;
import com.devonfw.cobigen.impl.config.constant.MavenMetadata;
import com.devonfw.cobigen.impl.config.constant.WikiConstants;
import com.devonfw.cobigen.impl.config.entity.ContainerMatcher;
import com.devonfw.cobigen.impl.config.entity.Matcher;
import com.devonfw.cobigen.impl.config.entity.Trigger;
Expand All @@ -36,18 +31,17 @@
import com.devonfw.cobigen.impl.config.versioning.VersionValidator;
import com.devonfw.cobigen.impl.config.versioning.VersionValidator.Type;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.UnmarshalException;
import jakarta.xml.bind.Unmarshaller;

/** The {@link ContextConfigurationReader} reads the context xml */
public class AbstractContextConfigurationReader {
public abstract class AbstractContextConfigurationReader {

/** Map with XML Nodes 'context' of the context.xml files */
private Map<Path, ContextConfiguration> contextConfigurations;
protected Map<Path, ContextConfiguration> contextConfigurations;

/** Paths of the context configuration files */
protected List<Path> contextFiles;
Expand All @@ -66,73 +60,6 @@ public AbstractContextConfigurationReader(Path configRoot) throws InvalidConfigu
if (configRoot == null) {
throw new IllegalArgumentException("Configuration path cannot be null.");
}

this.contextFiles = new ArrayList<>();

// use old context.xml in templates root
Path contextFile = configRoot.resolve(ConfigurationConstants.CONTEXT_CONFIG_FILENAME);

if (!Files.exists(contextFile)) {
// if no context.xml is found in the root folder search in src/main/templates
configRoot = configRoot.resolve(ConfigurationConstants.TEMPLATE_RESOURCE_FOLDER);
contextFile = configRoot.resolve(ConfigurationConstants.CONTEXT_CONFIG_FILENAME);
if (!Files.exists(contextFile)) {

this.contextFiles = loadContextFilesInSubfolder(configRoot);

if (this.contextFiles.isEmpty()) {
throw new InvalidConfigurationException(contextFile, "Could not find any context configuration file.");
}

} else {
this.contextFiles.add(contextFile);
// check if conflict with old and modular configuration exists

if (!loadContextFilesInSubfolder(configRoot).isEmpty())
throw new InvalidConfigurationException(contextFile,
"You are using an old configuration of the templates in addition to new ones. Please make sure this is not the case as both at the same time are not supported. For more details visit this wiki page: "
+ WikiConstants.WIKI_UPDATE_OLD_CONFIG);

}
} else {
this.contextFiles.add(contextFile);
}

this.contextRoot = configRoot;

readConfiguration();
}

/**
* search for configuration Files in the subfolders of configRoot
*
* @param configRoot root directory of the configuration
* @throws InvalidConfigurationException if the configuration is not valid against its xsd specification
*/
protected List<Path> loadContextFilesInSubfolder(Path configRoot) {

List<Path> contextPaths = new ArrayList<>();

List<Path> templateDirectories = new ArrayList<>();

try (Stream<Path> files = Files.list(configRoot)) {
files.forEach(path -> {
if (Files.isDirectory(path)) {
templateDirectories.add(path);
}
});
} catch (IOException e) {
throw new InvalidConfigurationException(configRoot, "Could not read configuration root directory.", e);
}

for (Path file : templateDirectories) {
Path contextPath = file.resolve(ConfigurationConstants.CONTEXT_CONFIG_FILENAME);
if (Files.exists(contextPath)) {
contextPaths.add(contextPath);
}
}

return contextPaths;
}

/**
Expand Down Expand Up @@ -215,31 +142,15 @@ protected void readConfiguration() {
*
* @return a {@link List} containing all the {@link Trigger}s
*/
public Map<String, Trigger> loadTriggers() {

Map<String, Trigger> triggers = Maps.newHashMap();
for (Path contextFile : this.contextConfigurations.keySet()) {
ContextConfiguration contextConfiguration = this.contextConfigurations.get(contextFile);
for (com.devonfw.cobigen.impl.config.entity.io.Trigger t : contextConfiguration.getTrigger()) {
// templateFolder property is optional in schema version 2.2. If not set take the path of the context.xml file
String templateFolder = t.getTemplateFolder();
if (templateFolder.isEmpty() || templateFolder.equals("/")) {
templateFolder = contextFile.getParent().getFileName().toString();
}
triggers.put(t.getId(), new Trigger(t.getId(), t.getType(), templateFolder,
Charset.forName(t.getInputCharset()), loadMatchers(t), loadContainerMatchers(t)));
}
}
return triggers;
}
abstract public Map<String, Trigger> loadTriggers();

/**
* Loads all {@link Matcher}s of a given {@link com.devonfw.cobigen.impl.config.entity.io.Trigger}
*
* @param trigger {@link com.devonfw.cobigen.impl.config.entity.io.Trigger} to retrieve the {@link Matcher}s from
* @return the {@link List} of {@link Matcher}s
*/
private List<Matcher> loadMatchers(com.devonfw.cobigen.impl.config.entity.io.Trigger trigger) {
protected List<Matcher> loadMatchers(com.devonfw.cobigen.impl.config.entity.io.Trigger trigger) {

List<Matcher> matcher = new LinkedList<>();
for (com.devonfw.cobigen.impl.config.entity.io.Matcher m : trigger.getMatcher()) {
Expand All @@ -254,7 +165,7 @@ private List<Matcher> loadMatchers(com.devonfw.cobigen.impl.config.entity.io.Tri
* @param trigger {@link com.devonfw.cobigen.impl.config.entity.io.Trigger} to retrieve the {@link Matcher}s from
* @return the {@link List} of {@link Matcher}s
*/
private List<ContainerMatcher> loadContainerMatchers(com.devonfw.cobigen.impl.config.entity.io.Trigger trigger) {
protected List<ContainerMatcher> loadContainerMatchers(com.devonfw.cobigen.impl.config.entity.io.Trigger trigger) {

List<ContainerMatcher> containerMatchers = Lists.newLinkedList();
for (com.devonfw.cobigen.impl.config.entity.io.ContainerMatcher cm : trigger.getContainerMatcher()) {
Expand All @@ -270,7 +181,8 @@ private List<ContainerMatcher> loadContainerMatchers(com.devonfw.cobigen.impl.co
* from
* @return the {@link List} of {@link Matcher}s
*/
private List<VariableAssignment> loadVariableAssignments(com.devonfw.cobigen.impl.config.entity.io.Matcher matcher) {
protected List<VariableAssignment> loadVariableAssignments(
com.devonfw.cobigen.impl.config.entity.io.Matcher matcher) {

List<VariableAssignment> variableAssignments = new LinkedList<>();
for (com.devonfw.cobigen.impl.config.entity.io.VariableAssignment va : matcher.getVariableAssignment()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,69 @@
package com.devonfw.cobigen.impl.config.reader;

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Map;

import com.devonfw.cobigen.api.constants.ConfigurationConstants;
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.impl.config.entity.Trigger;
import com.devonfw.cobigen.impl.config.entity.io.ContextConfiguration;
import com.google.common.collect.Maps;

/** The {@link ContextConfigurationReader} reads the context xml */
public class ContextConfigurationReader extends AbstractContextConfigurationReader {

/**
* The constructor.
*
* @param configRoot
* @throws InvalidConfigurationException
* @param configRoot the config root directory
* @throws InvalidConfigurationException if the configuration is not valid
*/
public ContextConfigurationReader(Path configRoot) throws InvalidConfigurationException {

super(configRoot);

this.contextFiles = new ArrayList<>();

// use old context.xml in templates root (CobiGen_Templates)
Path contextFile = configRoot.resolve(ConfigurationConstants.CONTEXT_CONFIG_FILENAME);

if (!Files.exists(contextFile)) {
// if no context.xml is found in the root folder search in src/main/templates
configRoot = configRoot.resolve(ConfigurationConstants.TEMPLATE_RESOURCE_FOLDER);
contextFile = configRoot.resolve(ConfigurationConstants.CONTEXT_CONFIG_FILENAME);
if (!Files.exists(contextFile)) {
throw new InvalidConfigurationException(contextFile, "Could not find any context configuration file.");
} else {
this.contextFiles.add(contextFile);
}
} else {
this.contextFiles.add(contextFile);
}

this.contextRoot = configRoot;

readConfiguration();
}

@Override
public Map<String, Trigger> loadTriggers() {

Map<String, Trigger> triggers = Maps.newHashMap();
for (Path contextFile : this.contextConfigurations.keySet()) {
ContextConfiguration contextConfiguration = this.contextConfigurations.get(contextFile);
for (com.devonfw.cobigen.impl.config.entity.io.Trigger t : contextConfiguration.getTrigger()) {
// templateFolder property is optional in schema version 2.2. If not set take the path of the context.xml file
String templateFolder = t.getTemplateFolder();
if (templateFolder.isEmpty() || templateFolder.equals("/")) {
templateFolder = contextFile.getParent().getFileName().toString();
}
triggers.put(t.getId(), new Trigger(t.getId(), t.getType(), templateFolder,
Charset.forName(t.getInputCharset()), loadMatchers(t), loadContainerMatchers(t)));
}
}
return triggers;
}
}
Loading