Skip to content

Commit

Permalink
refactoring configuration reader
Browse files Browse the repository at this point in the history
  • Loading branch information
maybeec committed Aug 2, 2023
1 parent f1fe140 commit 32c3ab1
Show file tree
Hide file tree
Showing 35 changed files with 946 additions and 1,604 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,13 @@ public static String downloadJarFromURL(String downloadURL, Path templateSetDire

HttpURLConnection conn;
try {
conn = initializeConnection(downloadURL.toString());
conn = initializeConnection(downloadURL);
try (InputStream inputStream = conn.getInputStream()) {

fileName = conn.getURL().getFile().substring(conn.getURL().getFile().lastIndexOf("/") + 1);
Path file = downloaded.resolve(fileName);
Path targetPath = file;
if (!Files.exists(file)) {
Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
Files.copy(inputStream, file, StandardCopyOption.REPLACE_EXISTING);
}
}
conn.disconnect();
Expand All @@ -133,14 +132,13 @@ public static String downloadJarFromURL(String downloadURL, Path templateSetDire
/**
* Downloads the latest devon4j templates
*
* @param isDownloadSource true if downloading source jar file
* @param isDownloadSource true if downloading source jar file
* @param templatesDirectory directory where the templates jar are located
* @return fileName Name of the file downloaded
*/
public static String downloadLatestDevon4jTemplates(boolean isDownloadSource, File templatesDirectory) {
public static void downloadLatestDevon4jTemplates(boolean isDownloadSource, File templatesDirectory) {

return downloadJar(TemplatesJarConstants.DEVON4J_TEMPLATES_GROUPID,
TemplatesJarConstants.DEVON4J_TEMPLATES_ARTIFACTID, "LATEST", isDownloadSource, templatesDirectory);
downloadJar(TemplatesJarConstants.DEVON4J_TEMPLATES_GROUPID,
TemplatesJarConstants.DEVON4J_TEMPLATES_ARTIFACTID, "LATEST", isDownloadSource, templatesDirectory);
}

/**
Expand Down Expand Up @@ -203,8 +201,8 @@ private static Set<MavenCoordinate> getMatchingTemplates(List<MavenCoordinate> m
HashSet<MavenCoordinate> existingTemplates = new HashSet<>();

for (MavenCoordinate mavenCoordinate : mavenCoordinates) {
try {
if (Files.list(path).anyMatch(f -> (f.getFileName().toString().contains(mavenCoordinate.getArtifactId())))) {
try (Stream<Path> directory = Files.list(path)){
if (directory.anyMatch(f -> (f.getFileName().toString().contains(mavenCoordinate.getArtifactId())))) {
existingTemplates.add(mavenCoordinate);
}
} catch (IOException e) {
Expand Down Expand Up @@ -233,7 +231,7 @@ private static boolean isJarOutdated(File jarFile, String mavenUrl, boolean isDo

String fileName = jarFile.getPath().substring(jarFile.getPath().lastIndexOf(File.separator) + 1);
Matcher m = matchJarVersion(fileName, isDownloadSource);
if (m.find() == false || m.group(2).isEmpty()) {
if (!m.find() || m.group(2).isEmpty()) {
// Maybe the jar is corrupted, let's update it
return true;
} else {
Expand All @@ -247,15 +245,15 @@ private static boolean isJarOutdated(File jarFile, String mavenUrl, boolean isDo
m = matchJarVersion(latestJar, isDownloadSource);
}

if (m.find() == false || m.group(2).isEmpty()) {
if (!m.find() || m.group(2).isEmpty()) {
return false;
}
// Split the version number because it contains dots e.g. 3.1.0
int[] versionNumbersLatest = Arrays.stream(m.group(2).split("\\.")).mapToInt(Integer::parseInt).toArray();

for (int i = 0; i < versionNumbersLatest.length; i++) {
if (versionNumbersLatest[i] > versionNumbers[i]) {
if (isDownloadSource == false) {
if (!isDownloadSource) {
// we now need to download the latest sources
downloadLatestDevon4jTemplates(true, templatesDirectory);
}
Expand Down Expand Up @@ -285,8 +283,7 @@ private static Matcher matchJarVersion(String fileName, boolean isDownloadSource
}

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(lowercaseName);
return m;
return p.matcher(lowercaseName);
}

/**
Expand Down Expand Up @@ -318,23 +315,17 @@ private static HttpURLConnection initializeConnection(String mavenUrl)
public static List<Path> getJarFiles(Path templatesDirectory) {

ArrayList<Path> jarPaths = new ArrayList<>();

try (Stream<Path> files = Files.list(templatesDirectory)) {
files.forEach(path -> {
if (path.toString().endsWith(".jar")) {
if (path.endsWith(".jar")) {
jarPaths.add(path);
}
});
} catch (IOException e) {
throw new CobiGenRuntimeException("Could not read configuration root directory.", e);
}

if (!jarPaths.isEmpty()) {
return jarPaths;
} else {
// There are no jars downloaded
return jarPaths;
}
return jarPaths;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion cobigen/cobigen-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@
</executions>
<configuration>
<extension>true</extension>
<bindingDirectory>${basedir}/src/main/resources/schema</bindingDirectory>
<!--<bindingDirectory>${basedir}/src/main/resources/schema</bindingDirectory>-->
</configuration>
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ public static CobiGen create(URI configFileOrFolder) throws InvalidConfiguration
/**
* Creates a new {@link CobiGen} while searching a valid configuration at the given path
*
* @param configFileOrFolder the root folder containing the context.xml and all templates, configurations etc.
* @return a new instance of {@link CobiGen}
* @throws InvalidConfigurationException if the context configuration could not be read properly.
*/
Expand Down Expand Up @@ -95,8 +94,6 @@ public static CobiGen create(URI configFileOrFolder, boolean allowMonolithicConf
BeanFactory beanFactory = new BeanFactory();
beanFactory.addManuallyInitializedBean(configurationHolder);
CobiGen createBean = beanFactory.createBean(CobiGen.class);
// Notifies all plugins of new template root path
PluginRegistry.notifyPlugins(configurationHolder.getConfigurationPath());

if (!allowMonolithicConfiguration && !configurationHolder.isTemplateSetConfiguration()) {
throw new DeprecatedMonolithicConfigurationException(Paths.get(configFileOrFolder));
Expand All @@ -106,7 +103,7 @@ public static CobiGen create(URI configFileOrFolder, boolean allowMonolithicConf
ConfigurationProperties config = configurationHolder.getConfigurationProperties();
// if installed template sets property was not empty, install found template sets
if (!config.getTemplateSetsInstalled().isEmpty()) {
Path templatesLocation = configurationHolder.getConfigurationPath();
Path templatesLocation = Paths.get(configurationHolder.getConfigurationLocation());
List<String> downloadUrls = ArtifactRetriever.retrieveTemplateSetJarDownloadURLs(config.getGroupIds(),
config.getTemplateSetsInstalled());
for (String downloadUrl : downloadUrls) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,57 @@

import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.devonfw.cobigen.api.constants.ConfigurationConstants;
import com.devonfw.cobigen.api.exception.InvalidConfigurationException;
import com.devonfw.cobigen.api.util.CobiGenPaths;
import com.devonfw.cobigen.impl.config.entity.Trigger;
import com.devonfw.cobigen.impl.extension.PluginRegistry;
import com.devonfw.cobigen.impl.config.reader.ConfigurationReader;
import com.devonfw.cobigen.impl.config.reader.ConfigurationReaderFactory;
import com.devonfw.cobigen.impl.config.reader.TemplateSetsConfigReader;
import com.devonfw.cobigen.impl.util.ConfigurationFinder;
import com.devonfw.cobigen.impl.util.FileSystemUtil;
import com.google.common.collect.Maps;

/**
* Cached in-memory CobiGen configuration.
*/
public class ConfigurationHolder {

/** Logger instance */
private static final Logger LOG = LoggerFactory.getLogger(ConfigurationHolder.class);

/** 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;
/**
* Cached templates configurations. Trigger ID -> Configuration instance
*/
private final Map<String, TemplatesConfiguration> templatesConfigurations = new HashMap<>();

/** Cached templateSet configuration */
private TemplateSetConfiguration templateSetConfiguration;
/**
* Cached context configuration
*/
private final ContextConfiguration contextConfiguration;

/** Root path of the configuration */
private Path configurationPath;
/**
* The OS filesystem path of the configuration
*/
private final URI configurationLocation;

/** The OS filesystem path of the configuration */
private URI configurationLocation;
/** Configuration properties */
private final ConfigurationProperties configurationProperties;

/** Location where the properties are saved */
private ConfigurationProperties configurationProperties;
private final ConfigurationReader configurationReader;

/**
* Creates a new {@link ConfigurationHolder} which serves as a cache for CobiGen's external configuration.
*
* @param configurationLocation the OS Filesystem path of the configuration location.
* @param configurationLocation the OS file system path of the configuration location.
*/
public ConfigurationHolder(URI configurationLocation) {

this.configurationLocation = configurationLocation;
this.configurationPath = FileSystemUtil.createFileSystemDependentPath(configurationLocation);
this.configurationReader = ConfigurationReaderFactory.create(configurationLocation);
this.contextConfiguration = this.configurationReader.readContextConfiguration();

this.configurationProperties = ConfigurationFinder.retrieveCobiGenProperties(
CobiGenPaths.getCobiGenHomePath().resolve(ConfigurationConstants.COBIGEN_CONFIG_FILE));

// updates the root template path and informs all of its observers
PluginRegistry.notifyPlugins(this.configurationPath);
}

/**
* @return templateSetConfiguration
*/
public TemplateSetConfiguration getTemplateSetConfiguration() {

return this.templateSetConfiguration;
}

/**
Expand Down Expand Up @@ -95,138 +81,38 @@ public URI getConfigurationLocation() {
}

/**
* @return the path within the configuration. Might be a different file system than OS in case of a .jar configuration
*/
public Path getConfigurationPath() {

return this.configurationPath;
}

/**
* Reads the {@link TemplatesConfiguration} from cache or from file if not present in cache.
* Search for the location of the Java utils
*
* @param trigger to get matcher declarations from
* @return the {@link TemplatesConfiguration}
* @throws InvalidConfigurationException if the configuration is not valid
*/
public TemplatesConfiguration readTemplatesConfiguration(Trigger trigger) {

Path configRoot = readContextConfiguration().retrieveConfigRootByTrigger(trigger.getId());
Path templateFolder = Paths.get(trigger.getTemplateFolder());

if (!this.templatesConfigurations.containsKey(trigger.getId())) {

TemplatesConfiguration config;

if (isTemplateSetConfiguration()) {

List<TemplatesConfiguration> templatesConfigurations = getTemplateSetConfiguration()
.getTemplatesConfigurations();

for (TemplatesConfiguration configurations : templatesConfigurations) {
Trigger localTrigger = configurations.getTrigger();
if (localTrigger.equals(trigger)) {
return configurations;
}
}

}
config = new TemplatesConfiguration(configRoot, trigger, this);

this.templatesConfigurations.put(trigger.getId(), Maps.<Path, TemplatesConfiguration> newHashMap());

this.templatesConfigurations.get(trigger.getId()).put(templateFolder, config);
}

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

/**
* @return templatesConfigurations
* @return the {@link Path} of the location of the util classes or null if no location was found
*/
public Map<String, Map<Path, TemplatesConfiguration>> getTemplatesConfigurations() {
public List<Path> getUtilsLocation(Trigger trigger) {

return this.templatesConfigurations;
return List.of(getTemplatesConfiguration(trigger).getConfigRoot());
}

/**
* Reads the {@link ContextConfiguration} from cache or from file if not present in cache.
*
* @return the {@link ContextConfiguration}
* @throws InvalidConfigurationException if the configuration is not valid
*/
public ContextConfiguration readContextConfiguration() {

if (this.contextConfiguration == null) {
if (isTemplateSetConfiguration()) {
if (this.templateSetConfiguration == null) {
this.templateSetConfiguration = new TemplateSetConfiguration(this.configurationPath);

}
return new ContextConfiguration(
this.templateSetConfiguration.getTemplateSetConfigurationReader().getContextConfiguration(),
this.configurationPath, this, this.templateSetConfiguration.getTriggers());

} else {
public Trigger getTrigger(String s) {

this.contextConfiguration = new ContextConfiguration(this.configurationPath);
}
}

return this.contextConfiguration;
return this.contextConfiguration.getTrigger(s);
}

/**
* Checks if this this a template set configuration or a templates configuration (true if templateSetConfiguraion)
*
* @return true if the template folder structure consists of template sets or false if the monolithic structure is
* used.
*/
public boolean isTemplateSetConfiguration() {
public TemplatesConfiguration getTemplatesConfiguration(Trigger trigger) {

// TODO: Replace with a better logic for template set detection later f.e. groupid, see:
// https://github.com/devonfw/cobigen/issues/1660
if (this.configurationPath.toUri().getScheme().equals("jar")
|| !this.configurationPath.getFileName().toString().equals(ConfigurationConstants.TEMPLATE_SETS_FOLDER)) {
return false;
if (this.templatesConfigurations.containsKey(trigger.getId())) {
return this.templatesConfigurations.get(trigger.getId());
}
return true;

TemplatesConfiguration templatesConfiguration = this.configurationReader
.readTemplatesConfiguration(trigger.getId());
this.templatesConfigurations.put(trigger.getId(), templatesConfiguration);
return templatesConfiguration;
}

/**
* Search for the location of the Java utils
*
* @return the {@link Path} of the location of the util classes or null if no location was found
*/
public List<Path> getUtilsLocation() {

List<Path> utilsLocationPaths = new ArrayList<>();
if (isTemplateSetConfiguration()) {
List<Trigger> triggers = readContextConfiguration().getTriggers();

for (Trigger trigger : triggers) {
Path configLocation = readContextConfiguration().retrieveTemplateSetUtilsLocationByTrigger(trigger.getId());
utilsLocationPaths.add(configLocation);
}
} else {
utilsLocationPaths.add(Paths.get(this.configurationLocation));
}
public ContextConfiguration getContextConfiguration() {

return utilsLocationPaths;
return this.contextConfiguration;
}

/**
* Retrieves a template set configuration within a map of template sets by its template set folder path
*
* @param templateSetConfigurations Cached templateSet configurations
* @param templateSetFolder folder where to get the specific configuration from
* @return the {@link TemplateSetConfiguration} instance saved in the given map
*/
public TemplateSetConfiguration retrieveTemplateSetConfiguration(
Map<Path, TemplateSetConfiguration> templateSetConfigurations, Path templateSetFolder) {
public boolean isTemplateSetConfiguration() {

return templateSetConfigurations.get(templateSetFolder);
return this.configurationReader instanceof TemplateSetsConfigReader;
}

}
Loading

0 comments on commit 32c3ab1

Please sign in to comment.