From dde54d7f2d5a81c32537c8834d6b3ac8fd45b554 Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Thu, 21 Dec 2023 15:33:32 +0100 Subject: [PATCH 1/7] Add JDK Modules Export to JUnit Test to run Integration Tests via IDE Signed-off-by: Stefan Kruk --- .../plugin/hybris/common/HybrisConstants.kt | 3 ++ .../HybrisJUnitExtension.java | 52 ++++++++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt index eff285bf0..62e686f47 100644 --- a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt +++ b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt @@ -183,6 +183,8 @@ object HybrisConstants { const val PROPERTY_LANG_PACKS = "lang.packs" const val PROPERTY_IMPEX_HEADER_REPLACEMENT = "impex.header.replacement" + const val PROPERTY_STANDALONE_JDKMODULESEXPORTS = "standalone.jdkmodulesexports"; + const val DEFAULT_LANGUAGE_ISOCODE = "en" const val DEFAULT_DEPLOYMENT_TABLENAME_MAXLENGTH = 24 @@ -265,6 +267,7 @@ object HybrisConstants { const val HYBRIS_DATA_DIR_ENV = "HYBRIS_DATA_DIR" const val IMPORT_OVERRIDE_FILENAME = "hybris4intellij.properties" const val GROUP_OVERRIDE_KEY = "group.override" + const val ADVANCED_PROPERTIES_FILE = "advanced.properties" const val CLASS_FQN_ITEM_ROOT = "de.hybris.platform.core.model.ItemModel" const val CLASS_FQN_ENUM_ROOT = "de.hybris.platform.core.HybrisEnumValue" diff --git a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java index 90361d70a..5d1097a54 100644 --- a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java +++ b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java @@ -25,23 +25,31 @@ import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.junit.JUnitConfiguration; +import com.intellij.idea.plugin.hybris.project.configurators.impl.DefaultAntConfigurator; import com.intellij.idea.plugin.hybris.project.utils.HybrisRootUtil; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettings; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import static com.intellij.idea.plugin.hybris.common.HybrisConstants.HYBRIS_DATA_DIRECTORY; -import static com.intellij.idea.plugin.hybris.common.HybrisConstants.HYBRIS_DATA_DIR_ENV; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.StringTokenizer; + +import static com.intellij.idea.plugin.hybris.common.HybrisConstants.*; public class HybrisJUnitExtension extends RunConfigurationExtension { + private static final Logger LOG = Logger.getInstance(DefaultAntConfigurator.class); + @Override - public > void updateJavaParameters( - final T configuration, final JavaParameters params, final RunnerSettings runnerSettings - ) throws ExecutionException { + public > void updateJavaParameters(final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) throws ExecutionException { if (runnerSettings != null || !isApplicableFor(configuration)) { return; } @@ -61,13 +69,42 @@ public > void updateJavaParameters( if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { final HybrisProjectSettings settings = HybrisProjectSettingsComponent.getInstance(project).getState(); - final String hybrisDataDirPath = FileUtil.toCanonicalPath( - project.getBasePath() + '/' + settings.getHybrisDirectory() + '/' + HYBRIS_DATA_DIRECTORY); + final String hybrisDataDirPath = FileUtil.toCanonicalPath(project.getBasePath() + '/' + settings.getHybrisDirectory() + '/' + HYBRIS_DATA_DIRECTORY); if (hybrisDataDirPath != null) { params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); } } + addJdkPropertiesIfNecessary(vmParameters, project); + } + + private void addJdkPropertiesIfNecessary(final ParametersList params, final Project project) { + final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); + if (platformRootDirectory != null) { + final File advanedProperties = new File(platformRootDirectory.getPath() + "/resources", ADVANCED_PROPERTIES_FILE); + if (advanedProperties.exists()) { + final Properties properties = new Properties(); + try (final InputStream in = new FileInputStream(advanedProperties)) { + properties.load(in); + final String property = properties.getProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); + if (property != null && !property.trim().isEmpty()) { + final StringTokenizer tokenizer = new StringTokenizer(property.trim()); + while (tokenizer.hasMoreTokens()) { + final String newParam = tokenizer.nextToken().replaceAll("\"", ""); + addVmParameterIfNotExist(params, newParam); + } + } + } catch (IOException e) { + LOG.error("Cannot read advanced.properties File"); + } + } + } + } + + private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { + if (vmParameters.getParameters().stream().noneMatch(param -> param.startsWith(newParam))) { + vmParameters.add(newParam); + } } @Override @@ -78,5 +115,4 @@ public boolean isApplicableFor(@NotNull final RunConfigurationBase configuration final Project project = configuration.getProject(); return HybrisProjectSettingsComponent.getInstance(project).isHybrisProject(); } - } From ec4d75736fd3bee656dc4aaccff9811c3cdf37cc Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Fri, 22 Dec 2023 07:30:05 +0100 Subject: [PATCH 2/7] Load JDK Export Properties via Properties Service --- CHANGELOG.md | 5 ++ CONTRIBUTING.md | 3 +- .../plugin/hybris/common/HybrisConstants.kt | 1 - .../HybrisJUnitExtension.java | 49 ++++++------------- 4 files changed, 22 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a607fcf7c..c83eeee83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [2023.3.3] + +### `Tests` enhancements +- Add JDK Export Properties to JUnit Tests to run Integration Tests[#864](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/864) + ## [2023.3.2] ### `Project Import` enhancements diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a8713e20..0732bfa78 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,4 +40,5 @@ - Rustam Burmenskyi - Oleksandr Dihtiar - Andrei Lisetskii -- Eugeni Kalenchuk \ No newline at end of file +- Eugeni Kalenchuk +- Stefan Kruk \ No newline at end of file diff --git a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt index 62e686f47..0098e1c19 100644 --- a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt +++ b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt @@ -267,7 +267,6 @@ object HybrisConstants { const val HYBRIS_DATA_DIR_ENV = "HYBRIS_DATA_DIR" const val IMPORT_OVERRIDE_FILENAME = "hybris4intellij.properties" const val GROUP_OVERRIDE_KEY = "group.override" - const val ADVANCED_PROPERTIES_FILE = "advanced.properties" const val CLASS_FQN_ITEM_ROOT = "de.hybris.platform.core.model.ItemModel" const val CLASS_FQN_ENUM_ROOT = "de.hybris.platform.core.HybrisEnumValue" diff --git a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java index 5d1097a54..67103e713 100644 --- a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java +++ b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java @@ -25,40 +25,33 @@ import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.junit.JUnitConfiguration; -import com.intellij.idea.plugin.hybris.project.configurators.impl.DefaultAntConfigurator; import com.intellij.idea.plugin.hybris.project.utils.HybrisRootUtil; +import com.intellij.idea.plugin.hybris.properties.PropertiesService; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettings; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.lang.properties.IProperty; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; import java.util.StringTokenizer; import static com.intellij.idea.plugin.hybris.common.HybrisConstants.*; public class HybrisJUnitExtension extends RunConfigurationExtension { - private static final Logger LOG = Logger.getInstance(DefaultAntConfigurator.class); - @Override public > void updateJavaParameters(final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) throws ExecutionException { if (runnerSettings != null || !isApplicableFor(configuration)) { return; } final Project project = configuration.getProject(); + final PropertiesService propertiesService = PropertiesService.getInstance(project); final ParametersList vmParameters = params.getVMParametersList(); - if (!vmParameters.hasParameter("-ea")) { - vmParameters.add("-ea"); - } + addVmParameterIfNotExist(vmParameters, "-ea"); + if (vmParameters.getParameters().stream().noneMatch(param -> param.startsWith("-Dplatformhome="))) { final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); @@ -66,6 +59,7 @@ public > void updateJavaParameters(final T con vmParameters.add("-Dplatformhome=" + platformRootDirectory.getPath()); } } + if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { final HybrisProjectSettings settings = HybrisProjectSettingsComponent.getInstance(project).getState(); @@ -75,34 +69,21 @@ public > void updateJavaParameters(final T con params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); } } - addJdkPropertiesIfNecessary(vmParameters, project); - } - private void addJdkPropertiesIfNecessary(final ParametersList params, final Project project) { - final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); - if (platformRootDirectory != null) { - final File advanedProperties = new File(platformRootDirectory.getPath() + "/resources", ADVANCED_PROPERTIES_FILE); - if (advanedProperties.exists()) { - final Properties properties = new Properties(); - try (final InputStream in = new FileInputStream(advanedProperties)) { - properties.load(in); - final String property = properties.getProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); - if (property != null && !property.trim().isEmpty()) { - final StringTokenizer tokenizer = new StringTokenizer(property.trim()); - while (tokenizer.hasMoreTokens()) { - final String newParam = tokenizer.nextToken().replaceAll("\"", ""); - addVmParameterIfNotExist(params, newParam); - } - } - } catch (IOException e) { - LOG.error("Cannot read advanced.properties File"); - } + + final IProperty macroProperty = propertiesService.findMacroProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); + if (macroProperty != null && macroProperty.getValue() != null) { + final String value = macroProperty.getValue(); + final StringTokenizer tokenizer = new StringTokenizer(value.trim()); + while (tokenizer.hasMoreTokens()) { + final String newParam = tokenizer.nextToken().replaceAll("\"", ""); + addVmParameterIfNotExist(vmParameters, newParam); } } } private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { - if (vmParameters.getParameters().stream().noneMatch(param -> param.startsWith(newParam))) { + if (!vmParameters.hasParameter(newParam)) { vmParameters.add(newParam); } } From 13da70de4125f1af272dfdef5701a2d908a5e90c Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Fri, 22 Dec 2023 10:53:43 +0100 Subject: [PATCH 3/7] Improve handling of Hybris Properties --- .../hybris/properties/PropertiesService.kt | 2 - .../properties/impl/PropertiesServiceImpl.kt | 180 ++++++++++-------- .../HybrisJUnitExtension.java | 7 +- ...loperSpecificProjectSettingsComponent.java | 3 +- 4 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/com/intellij/idea/plugin/hybris/properties/PropertiesService.kt b/src/com/intellij/idea/plugin/hybris/properties/PropertiesService.kt index fc93c018e..2a7c5bda4 100644 --- a/src/com/intellij/idea/plugin/hybris/properties/PropertiesService.kt +++ b/src/com/intellij/idea/plugin/hybris/properties/PropertiesService.kt @@ -37,6 +37,4 @@ interface PropertiesService { @JvmStatic fun getInstance(project: Project): PropertiesService? = project.getService(PropertiesService::class.java) } - - fun getProperty(key: String): IProperty? } \ No newline at end of file diff --git a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt index 7f7da8d46..0a2c67024 100644 --- a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt +++ b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt @@ -29,6 +29,7 @@ import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.FileTypeIndex @@ -47,8 +48,7 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { private val optionalPropertiesFilePattern = Pattern.compile("([1-9]\\d)-(\\w*)\\.properties") override fun getLanguages(): Set { - val languages = findMacroProperty(HybrisConstants.PROPERTY_LANG_PACKS) - ?.value + val languages = findProperty(HybrisConstants.PROPERTY_LANG_PACKS) ?.split(",") ?.map { it.trim() } ?: emptyList() @@ -64,14 +64,14 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { override fun containsLanguage(language: String, supportedLanguages: Set) = supportedLanguages .contains(language.lowercase()) - override fun findAutoCompleteProperties(query: String): List = findAllProperties() - .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } - override fun getProperty(key: String): IProperty? = findAllProperties() - .firstOrNull { it.key != null && it.key == key } + override fun findProperty(key: String): String? = findAllProperties().filter { it.key == key }.map { it.value }.firstOrNull() + + override fun findAutoCompleteProperties(query: String): List = findAllIProperties() + .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } override fun findMacroProperty(query: String): IProperty? { - val allProps = findAllProperties() + val allProps = findAllIProperties() if (allProps.isEmpty()) { return null; } @@ -83,49 +83,8 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { return filteredProps.reduce { one, two -> if (one.key!!.length > two.key!!.length) one else two } } - override fun findProperty(query: String): String? = findMacroProperty(query) - ?.value - ?.replace("\\", "") - - private fun resolvePropertyValue(value: String?): String { - return resolvePropertyValue(value, HashMap()) - } - - private fun resolvePropertyValue(value: String?, resolvedProperties: MutableMap): String { - if (value == null) { - return "" - } - var index = 0 - val sb = StringBuilder() - while (index != -1) { - val startIndex = value.indexOf(nestedPropertyPrefix, index) - val endIndex = value.indexOf(nestedPropertySuffix, startIndex) - if (startIndex != -1 && endIndex != -1) { - sb.append(value, index, startIndex) - val propertyKey = value.substring(startIndex + nestedPropertyPrefix.length, endIndex) - var resolvedValue: String? = resolvedProperties[propertyKey] - if (resolvedValue != null) { - sb.append(resolvedValue) - } else { - val property = findMacroProperty(propertyKey) - if (property != null) { - resolvedValue = resolvePropertyValue(property.value) - sb.append(resolvedValue) - resolvedProperties[propertyKey] = resolvedValue - } else { - sb.append(nestedPropertyPrefix).append(propertyKey).append(nestedPropertySuffix) - } - } - index = endIndex + 1 - } else { - sb.append(value, index, value.length) - index = startIndex - } - } - return sb.toString() - } - private fun findAllProperties(): List { + private fun findAllIProperties(): List { val result = LinkedHashMap() val configModule = obtainConfigModule() ?: return emptyList() val platformModule = obtainPlatformModule() ?: return emptyList() @@ -134,6 +93,9 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { var advancedPropsFile: PropertiesFile? = null var localPropsFile: PropertiesFile? = null + var propertieFiles = ArrayList(); + + // Ignore Order and production.properties for now as `developer.mode` should be set to true for development anyway FileTypeIndex.getFiles(PropertiesFileType.INSTANCE, scope) .mapNotNull { PsiManager.getInstance(project).findFile(it) } .mapNotNull { it as? PropertiesFile } @@ -142,52 +104,114 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { "env.properties" -> envPropsFile = file "advanced.properties" -> advancedPropsFile = file "local.properties" -> localPropsFile = file - else -> { - for (property in file.properties) { - if (property.key != null) { - result[property.key!!] = property - } - } - } + "project.properties" -> propertieFiles.add(file) } } - addPropertyFile(result, envPropsFile) - addPropertyFile(result, advancedPropsFile) - addPropertyFile(result, localPropsFile) - val optDir = result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR] - addOptionalConfiguration(result, optDir) + envPropsFile?.let { propertieFiles.add(0, it) } + advancedPropsFile?.let { propertieFiles.add(1, it) } + localPropsFile?.let { propertieFiles.add(it) } + + propertieFiles.forEach { file -> addPropertyFile(result, file) } + + loadHybrisRuntimeProperties(result) + loadHybrisOptionalConfigDir(result) return ArrayList(result.values) } + private fun findAllProperties(): LinkedHashMap { + + val result = LinkedHashMap() + findAllIProperties().forEach { property -> + property.value?.let { + result[property.key!!] = it + } + } + + replacePlaceholders(result) + return result + } - private fun addOptionalConfiguration(result: LinkedHashMap, optDir: IProperty?) { - if (optDir == null) { - return + private fun replacePlaceholders(result: LinkedHashMap) { + result.forEach { key, value -> + if (value.contains(nestedPropertyPrefix)) { + replacePlaceholder(result, key, value); + } } - val dir = File(optDir.value) - if (!dir.isDirectory) { - return + } + + private fun replacePlaceholder(result: LinkedHashMap, key: String, value: String) { + val pattern = Pattern.compile("\\$\\{[^\\}]*\\}") + val matcher = pattern.matcher(value) + matcher?.let { + while (it.find()) { + val placeholder: String = it.group() + val nestedKey: String = placeholder.substring(nestedPropertyPrefix.length, placeholder.length - nestedPropertySuffix.length) + val nestedValue: String? = result[nestedKey] + nestedValue?.let { + var newValue = nestedValue + if (nestedValue.contains(nestedPropertyPrefix)) { + replacePlaceholder(result, nestedKey, nestedValue) + newValue = result[nestedKey] + } + + result[key] = value.replace(placeholder, newValue ?: "") + } + } } - val matchedFiles = dir.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } - ?: return - val propertyFiles = TreeMap() - Arrays.stream(matchedFiles).forEach { file -> propertyFiles[file.name] = file } - - propertyFiles.values.forEach { file -> - val virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file) - if (virtualFile == null || !virtualFile.exists()) { + } + + private fun loadHybrisOptionalConfigDir(result: LinkedHashMap) { + var optDir = result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR]?.value + + val envOptConfigDir = System.getenv("HYBRIS_OPT_CONFIG_DIR") + if (envOptConfigDir != null) { + optDir = envOptConfigDir; + } + + optDir?.let { + val dir = File(it) + if (!dir.isDirectory) { return } - val psiFile = PsiManager.getInstance(project).findFile(virtualFile) - if (psiFile is PropertiesFile) { - addPropertyFile(result, psiFile as PropertiesFile?) + + val matchedFiles = dir.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } + ?: return + val propertyFiles = TreeMap() + Arrays.stream(matchedFiles).forEach { file -> propertyFiles[file.name] = file } + + propertyFiles.values.forEach { file -> + addPropertyFile(result, toPropertiesFile(file)) + } + } + } + + private fun loadHybrisRuntimeProperties(result: LinkedHashMap) { + val envVar: String = System.getenv("HYBRIS_RUNTIME_PROPERTIES") ?: "" + if (!envVar.isBlank()) { + var propertiesFile = File(envVar); + propertiesFile?.let { file: File -> + addPropertyFile(result, toPropertiesFile(file)) } + } } + private fun toPropertiesFile(file: File): PropertiesFile? { + val virtualFile: VirtualFile? = LocalFileSystem.getInstance().findFileByIoFile(file) + if (virtualFile == null || !virtualFile.exists()) { + return null + } + val psiFile: PsiFile? = PsiManager.getInstance(project).findFile(virtualFile) + if (psiFile is PropertiesFile) { + return psiFile + } + return null + } + + private fun addPropertyFile(result: LinkedHashMap, propertiesFile: PropertiesFile?) { if (propertiesFile == null) { return diff --git a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java index 67103e713..13c61d3c6 100644 --- a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java +++ b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java @@ -71,10 +71,9 @@ public > void updateJavaParameters(final T con } - final IProperty macroProperty = propertiesService.findMacroProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); - if (macroProperty != null && macroProperty.getValue() != null) { - final String value = macroProperty.getValue(); - final StringTokenizer tokenizer = new StringTokenizer(value.trim()); + final String property = propertiesService.findProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); + if (property != null) { + final StringTokenizer tokenizer = new StringTokenizer(property.trim()); while (tokenizer.hasMoreTokens()) { final String newParam = tokenizer.nextToken().replaceAll("\"", ""); addVmParameterIfNotExist(vmParameters, newParam); diff --git a/src/com/intellij/idea/plugin/hybris/settings/HybrisDeveloperSpecificProjectSettingsComponent.java b/src/com/intellij/idea/plugin/hybris/settings/HybrisDeveloperSpecificProjectSettingsComponent.java index b68709421..61908a71a 100644 --- a/src/com/intellij/idea/plugin/hybris/settings/HybrisDeveloperSpecificProjectSettingsComponent.java +++ b/src/com/intellij/idea/plugin/hybris/settings/HybrisDeveloperSpecificProjectSettingsComponent.java @@ -180,8 +180,7 @@ public void saveRemoteConnectionSettingsList( private static String getPropertyOrDefault(final Project project, final String key, final String fallback) { return Optional.ofNullable(PropertiesService.getInstance(project)) - .map(it -> it.getProperty(key)) - .map(IProperty::getValue) + .map(it -> it.findProperty(key)) .orElse(fallback); } } From ffabdac165c712bf2dfe49b13aeebae72ca61eac Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Fri, 22 Dec 2023 14:53:31 +0100 Subject: [PATCH 4/7] Refactor PropertiesServiceImpl and prevent endless Recursion --- .idea/codeStyles/codeStyleConfig.xml | 2 +- .../plugin/hybris/common/HybrisConstants.kt | 10 +- .../DebugRunConfigurationConfigurator.java | 4 +- .../impl/DefaultJavaCompilerConfigurator.java | 4 +- .../impl/DefaultSpringConfigurator.kt | 4 +- .../DefaultHybrisProjectDescriptor.java | 4 +- .../impl/DefaultHybrisProjectService.java | 2 +- .../properties/impl/PropertiesServiceImpl.kt | 205 ++++++++---------- .../HybrisJUnitExtension.java | 105 +++++---- 9 files changed, 168 insertions(+), 172 deletions(-) diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index 79ee123c2..a55e7a179 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,5 +1,5 @@ - \ No newline at end of file diff --git a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt index 0098e1c19..6c458db63 100644 --- a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt +++ b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt @@ -303,13 +303,17 @@ object HybrisConstants { const val LIB_DIRECTORY = "lib" const val BIN_DIRECTORY = "bin" const val RESOURCES_DIRECTORY = "resources" - const val LOCAL_PROPERTIES = "local.properties" - const val PROJECT_PROPERTIES = "project.properties" + const val LOCAL_PROPERTIES_FILE = "local.properties" + const val PROJECT_PROPERTIES_FILE = "project.properties" + const val ENV_PROPERTIES_FILE = "env.properties" + const val ADVANCED_PROPERTIES_FILE = "advanced.properties" const val SPRING_WEB_FILE_SET_NAME = "web application context" const val APPLICATION_CONTEXT_SPRING_FILES = "application-context" const val ADDITIONAL_WEB_SPRING_CONFIG_FILES = "additionalWebSpringConfigs" const val GLOBAL_CONTEXT_SPRING_FILES = "global-context" - const val HYBRIS_CONFIG_DIR_KEY = "HYBRIS_CONFIG_DIR" + const val HYBRIS_CONFIG_DIR_ENV = "HYBRIS_CONFIG_DIR" + const val HYBRIS_RUNTIME_PROPERTIES_ENV = "HYBRIS_RUNTIME_PROPERTIES" + const val HYBRIS_OPT_CONFIG_DIR_ENV = "HYBRIS_OPT_CONFIG_DIR" const val HYBRIS_API_VERSION_KEY = "version.api" const val HYBRIS_VERSION_KEY = "version" const val JAVADOC_FALLBACK_URL = "https://help.sap.com/docs/SAP_COMMERCE/c5613bd3cc9942efb74d017b40eb0892/179bbc9b35274d7ca784e46b3beb40b2.html" diff --git a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DebugRunConfigurationConfigurator.java b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DebugRunConfigurationConfigurator.java index 1570991e4..dd10a3134 100644 --- a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DebugRunConfigurationConfigurator.java +++ b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DebugRunConfigurationConfigurator.java @@ -95,7 +95,7 @@ private String getDebugPort( ) { final var commonIdeaService = CommonIdeaService.getInstance(); final ConfigModuleDescriptor configDescriptor = hybrisProjectDescriptor.getConfigHybrisModuleDescriptor(); - String port = findPortProperty(configDescriptor, HybrisConstants.LOCAL_PROPERTIES, cache); + String port = findPortProperty(configDescriptor, HybrisConstants.LOCAL_PROPERTIES_FILE, cache); if (port != null) { return port; @@ -103,7 +103,7 @@ private String getDebugPort( final PlatformModuleDescriptor platformDescriptor = commonIdeaService.getPlatformDescriptor(hybrisProjectDescriptor); if (platformDescriptor != null) { - port = findPortProperty(platformDescriptor, HybrisConstants.PROJECT_PROPERTIES, cache); + port = findPortProperty(platformDescriptor, HybrisConstants.PROJECT_PROPERTIES_FILE, cache); if (port != null) { return port; diff --git a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultJavaCompilerConfigurator.java b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultJavaCompilerConfigurator.java index 1385530d0..a68ca082d 100644 --- a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultJavaCompilerConfigurator.java +++ b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultJavaCompilerConfigurator.java @@ -63,11 +63,11 @@ private static String findBuildCompilerProperty( final ConfigModuleDescriptor configDescriptor = descriptor.getConfigHybrisModuleDescriptor(); if (configDescriptor != null) { - propertyFiles.add(new File(configDescriptor.getModuleRootDirectory(), HybrisConstants.LOCAL_PROPERTIES)); + propertyFiles.add(new File(configDescriptor.getModuleRootDirectory(), HybrisConstants.LOCAL_PROPERTIES_FILE)); } final PlatformModuleDescriptor platformDescriptor = descriptor.getPlatformHybrisModuleDescriptor(); propertyFiles.add(new File(platformDescriptor.getModuleRootDirectory(), HybrisConstants.ADVANCED_PROPERTIES)); - propertyFiles.add(new File(platformDescriptor.getModuleRootDirectory(), HybrisConstants.PROJECT_PROPERTIES)); + propertyFiles.add(new File(platformDescriptor.getModuleRootDirectory(), HybrisConstants.PROJECT_PROPERTIES_FILE)); return cache.findPropertyInFiles(propertyFiles, HybrisConstants.PROPERTY_BUILD_COMPILER); } diff --git a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultSpringConfigurator.kt b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultSpringConfigurator.kt index fb355d775..204f8b049 100644 --- a/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultSpringConfigurator.kt +++ b/src/com/intellij/idea/plugin/hybris/project/configurators/impl/DefaultSpringConfigurator.kt @@ -72,7 +72,7 @@ class DefaultSpringConfigurator : SpringConfigurator { moduleDescriptor.addSpringFile(advancedProperties.absolutePath) hybrisProjectDescriptor.configHybrisModuleDescriptor - ?.let { File(it.moduleRootDirectory, HybrisConstants.LOCAL_PROPERTIES) } + ?.let { File(it.moduleRootDirectory, HybrisConstants.LOCAL_PROPERTIES_FILE) } ?.let { moduleDescriptor.addSpringFile(it.absolutePath) } } @@ -120,7 +120,7 @@ class DefaultSpringConfigurator : SpringConfigurator { moduleDescriptor: YRegularModuleDescriptor ) { val projectProperties = Properties() - val propFile = File(moduleDescriptor.moduleRootDirectory, HybrisConstants.PROJECT_PROPERTIES) + val propFile = File(moduleDescriptor.moduleRootDirectory, HybrisConstants.PROJECT_PROPERTIES_FILE) moduleDescriptor.addSpringFile(propFile.absolutePath) try { projectProperties.load(propFile.inputStream()) diff --git a/src/com/intellij/idea/plugin/hybris/project/descriptors/DefaultHybrisProjectDescriptor.java b/src/com/intellij/idea/plugin/hybris/project/descriptors/DefaultHybrisProjectDescriptor.java index dd0c6bcdf..a6ca9aa5e 100644 --- a/src/com/intellij/idea/plugin/hybris/project/descriptors/DefaultHybrisProjectDescriptor.java +++ b/src/com/intellij/idea/plugin/hybris/project/descriptors/DefaultHybrisProjectDescriptor.java @@ -254,7 +254,7 @@ private File getExpectedConfigDir(final PlatformModuleDescriptor platformHybrisM if (!expectedConfigDir.isDirectory()) { return null; } - final File propertiesFile = new File(expectedConfigDir, HybrisConstants.LOCAL_PROPERTIES); + final File propertiesFile = new File(expectedConfigDir, HybrisConstants.LOCAL_PROPERTIES_FILE); if (!propertiesFile.exists()) { return expectedConfigDir; } @@ -266,7 +266,7 @@ private File getExpectedConfigDir(final PlatformModuleDescriptor platformHybrisM return expectedConfigDir; } - String hybrisConfig = (String) properties.get(HybrisConstants.HYBRIS_CONFIG_DIR_KEY); + String hybrisConfig = (String) properties.get(HybrisConstants.HYBRIS_CONFIG_DIR_ENV); if (hybrisConfig == null) { return expectedConfigDir; } diff --git a/src/com/intellij/idea/plugin/hybris/project/services/impl/DefaultHybrisProjectService.java b/src/com/intellij/idea/plugin/hybris/project/services/impl/DefaultHybrisProjectService.java index 8b35d8224..c7c697dcc 100644 --- a/src/com/intellij/idea/plugin/hybris/project/services/impl/DefaultHybrisProjectService.java +++ b/src/com/intellij/idea/plugin/hybris/project/services/impl/DefaultHybrisProjectService.java @@ -40,7 +40,7 @@ public boolean isConfigModule(@NotNull final File file) { Validate.notNull(file); return new File(file, HybrisConstants.LOCAL_EXTENSIONS_XML).isFile() - && new File(file, HybrisConstants.LOCAL_PROPERTIES).isFile(); + && new File(file, HybrisConstants.LOCAL_PROPERTIES_FILE).isFile(); } @Override diff --git a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt index 0a2c67024..f589a6b5e 100644 --- a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt +++ b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt @@ -19,6 +19,12 @@ package com.intellij.idea.plugin.hybris.properties.impl import com.intellij.idea.plugin.hybris.common.HybrisConstants +import com.intellij.idea.plugin.hybris.common.HybrisConstants.ADVANCED_PROPERTIES_FILE +import com.intellij.idea.plugin.hybris.common.HybrisConstants.ENV_PROPERTIES_FILE +import com.intellij.idea.plugin.hybris.common.HybrisConstants.HYBRIS_OPT_CONFIG_DIR_ENV +import com.intellij.idea.plugin.hybris.common.HybrisConstants.HYBRIS_RUNTIME_PROPERTIES_ENV +import com.intellij.idea.plugin.hybris.common.HybrisConstants.LOCAL_PROPERTIES_FILE +import com.intellij.idea.plugin.hybris.common.HybrisConstants.PROJECT_PROPERTIES_FILE import com.intellij.idea.plugin.hybris.common.yExtensionName import com.intellij.idea.plugin.hybris.properties.PropertiesService import com.intellij.lang.properties.IProperty @@ -29,7 +35,6 @@ import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.FileTypeIndex @@ -49,26 +54,29 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { override fun getLanguages(): Set { val languages = findProperty(HybrisConstants.PROPERTY_LANG_PACKS) - ?.split(",") - ?.map { it.trim() } - ?: emptyList() + ?.split(",") + ?.map { it.trim() } + ?: emptyList() val uniqueLanguages = languages.toMutableSet() uniqueLanguages.add(HybrisConstants.DEFAULT_LANGUAGE_ISOCODE) return uniqueLanguages - .map { it.lowercase() } - .toSet() + .map { it.lowercase() } + .toSet() } override fun containsLanguage(language: String, supportedLanguages: Set) = supportedLanguages - .contains(language.lowercase()) + .contains(language.lowercase()) - override fun findProperty(key: String): String? = findAllProperties().filter { it.key == key }.map { it.value }.firstOrNull() + override fun findProperty(key: String): String? = findAllProperties() + .filter { it.key == key } + .map { it.value } + .firstOrNull() override fun findAutoCompleteProperties(query: String): List = findAllIProperties() - .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } + .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } override fun findMacroProperty(query: String): IProperty? { val allProps = findAllIProperties() @@ -93,26 +101,26 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { var advancedPropsFile: PropertiesFile? = null var localPropsFile: PropertiesFile? = null - var propertieFiles = ArrayList(); + var propertiesFiles = ArrayList(); // Ignore Order and production.properties for now as `developer.mode` should be set to true for development anyway FileTypeIndex.getFiles(PropertiesFileType.INSTANCE, scope) - .mapNotNull { PsiManager.getInstance(project).findFile(it) } - .mapNotNull { it as? PropertiesFile } - .forEach { file -> - when (file.name) { - "env.properties" -> envPropsFile = file - "advanced.properties" -> advancedPropsFile = file - "local.properties" -> localPropsFile = file - "project.properties" -> propertieFiles.add(file) + .mapNotNull { PsiManager.getInstance(project).findFile(it) } + .mapNotNull { it as? PropertiesFile } + .forEach { file -> + when (file.name) { + ENV_PROPERTIES_FILE -> envPropsFile = file + ADVANCED_PROPERTIES_FILE -> advancedPropsFile = file + LOCAL_PROPERTIES_FILE -> localPropsFile = file + PROJECT_PROPERTIES_FILE -> propertiesFiles.add(file) + } } - } - envPropsFile?.let { propertieFiles.add(0, it) } - advancedPropsFile?.let { propertieFiles.add(1, it) } - localPropsFile?.let { propertieFiles.add(it) } + envPropsFile?.let { propertiesFiles.add(0, it) } + advancedPropsFile?.let { propertiesFiles.add(1, it) } + localPropsFile?.let { propertiesFiles.add(it) } - propertieFiles.forEach { file -> addPropertyFile(result, file) } + propertiesFiles.forEach { file -> addPropertyFile(result, file) } loadHybrisRuntimeProperties(result) loadHybrisOptionalConfigDir(result) @@ -120,99 +128,74 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { return ArrayList(result.values) } - private fun findAllProperties(): LinkedHashMap { - - val result = LinkedHashMap() - findAllIProperties().forEach { property -> - property.value?.let { - result[property.key!!] = it + private fun findAllProperties(): LinkedHashMap = findAllIProperties() + .filter { it.value != null && it.key != null } + .associateTo(LinkedHashMap()) { it.key!! to it.value!! } + .let { properties -> + properties.filter { it.value.contains(nestedPropertyPrefix) } + .forEach { replacePlaceholder(properties, it.key, HashSet()) } + return properties } - } - replacePlaceholders(result) + private fun replacePlaceholder(result: LinkedHashMap, key: String, visitedProperties: MutableSet) { - return result - } + var lastIndex = 0 - private fun replacePlaceholders(result: LinkedHashMap) { - result.forEach { key, value -> - if (value.contains(nestedPropertyPrefix)) { - replacePlaceholder(result, key, value); - } - } - } + val value = result[key] ?: "" + var replacedValue = value - private fun replacePlaceholder(result: LinkedHashMap, key: String, value: String) { - val pattern = Pattern.compile("\\$\\{[^\\}]*\\}") - val matcher = pattern.matcher(value) - matcher?.let { - while (it.find()) { - val placeholder: String = it.group() - val nestedKey: String = placeholder.substring(nestedPropertyPrefix.length, placeholder.length - nestedPropertySuffix.length) - val nestedValue: String? = result[nestedKey] - nestedValue?.let { - var newValue = nestedValue - if (nestedValue.contains(nestedPropertyPrefix)) { - replacePlaceholder(result, nestedKey, nestedValue) - newValue = result[nestedKey] - } + while (true) { + val startIndex = value.indexOf(nestedPropertyPrefix, lastIndex) + val endIndex = value.indexOf(nestedPropertySuffix, startIndex + 1) + lastIndex = endIndex + nestedPropertyPrefix.length - result[key] = value.replace(placeholder, newValue ?: "") - } - } - } - } - - private fun loadHybrisOptionalConfigDir(result: LinkedHashMap) { - var optDir = result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR]?.value + if (startIndex == -1 || endIndex == -1) + break - val envOptConfigDir = System.getenv("HYBRIS_OPT_CONFIG_DIR") - if (envOptConfigDir != null) { - optDir = envOptConfigDir; - } - - optDir?.let { - val dir = File(it) - if (!dir.isDirectory) { - return - } - - val matchedFiles = dir.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } - ?: return - val propertyFiles = TreeMap() - Arrays.stream(matchedFiles).forEach { file -> propertyFiles[file.name] = file } - - propertyFiles.values.forEach { file -> - addPropertyFile(result, toPropertiesFile(file)) - } - } - } + val placeHolder = value.substring(startIndex, endIndex + nestedPropertySuffix.length) + val nestedKey = placeHolder.substring(nestedPropertyPrefix.length, placeHolder.length - nestedPropertySuffix.length) + if (visitedProperties.contains(nestedKey)) + continue + visitedProperties.add(nestedKey) + val nestedValue: String? = result[nestedKey] + nestedValue?.let { + var newValue = it + if (it.contains(nestedPropertyPrefix)) { + replacePlaceholder(result, nestedKey, visitedProperties) + newValue = result[nestedKey] ?: "" + } - private fun loadHybrisRuntimeProperties(result: LinkedHashMap) { - val envVar: String = System.getenv("HYBRIS_RUNTIME_PROPERTIES") ?: "" - if (!envVar.isBlank()) { - var propertiesFile = File(envVar); - propertiesFile?.let { file: File -> - addPropertyFile(result, toPropertiesFile(file)) + if (!newValue.contains(nestedPropertyPrefix)) { + replacedValue = replacedValue.replace(placeHolder, newValue) + } } } + result[key] = replacedValue; } - private fun toPropertiesFile(file: File): PropertiesFile? { - val virtualFile: VirtualFile? = LocalFileSystem.getInstance().findFileByIoFile(file) - if (virtualFile == null || !virtualFile.exists()) { - return null - } - val psiFile: PsiFile? = PsiManager.getInstance(project).findFile(virtualFile) - if (psiFile is PropertiesFile) { - return psiFile - } - return null - } - - - private fun addPropertyFile(result: LinkedHashMap, propertiesFile: PropertiesFile?) { + private fun loadHybrisOptionalConfigDir(result: MutableMap) = (System.getenv(HYBRIS_OPT_CONFIG_DIR_ENV) + ?: result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR]?.value) + ?.let { File(it) } + ?.takeIf { it.isDirectory } + ?.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } + ?.associateByTo(TreeMap()) { it.name } + ?.values + ?.mapNotNull { toPropertiesFile(it) } + ?.forEach { addPropertyFile(result, it) } + + private fun loadHybrisRuntimeProperties(result: MutableMap) = System.getenv(HYBRIS_RUNTIME_PROPERTIES_ENV) + ?.takeIf { it.isNotBlank() } + ?.let { File(it) } + ?.let { toPropertiesFile(it) } + ?.let { addPropertyFile(result, it) } + + private fun toPropertiesFile(file: File) = LocalFileSystem.getInstance().findFileByIoFile(file) + ?.takeIf { it.exists() } + ?.let { PsiManager.getInstance(project).findFile(it) } + ?.let { it as? PropertiesFile } + + private fun addPropertyFile(result: MutableMap, propertiesFile: PropertiesFile?) { if (propertiesFile == null) { return } @@ -225,21 +208,21 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { private fun createSearchScope(configModule: Module, platformModule: Module): GlobalSearchScope { val projectPropertiesScope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.everythingScope(project), PropertiesFileType.INSTANCE) - .filter { it.name == "project.properties" } - val envPropertiesScope = platformModule.moduleContentScope.filter { it.name == "env.properties" } - val advancedPropertiesScope = platformModule.moduleContentScope.filter { it.name == "advanced.properties" } - val localPropertiesScope = configModule.moduleContentScope.filter { it.name == "local.properties" } + .filter { it.name == "project.properties" } + val envPropertiesScope = platformModule.moduleContentScope.filter { it.name == ENV_PROPERTIES_FILE } + val advancedPropertiesScope = platformModule.moduleContentScope.filter { it.name == ADVANCED_PROPERTIES_FILE } + val localPropertiesScope = configModule.moduleContentScope.filter { it.name == LOCAL_PROPERTIES_FILE } return projectPropertiesScope.or(envPropertiesScope.or(advancedPropertiesScope.or(localPropertiesScope))) } private fun obtainConfigModule() = ModuleManager.getInstance(project) - .modules - .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_CONFIG } + .modules + .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_CONFIG } private fun obtainPlatformModule() = ModuleManager.getInstance(project) - .modules - .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_PLATFORM } + .modules + .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_PLATFORM } fun GlobalSearchScope.filter(filter: (VirtualFile) -> Boolean) = object : DelegatingGlobalSearchScope(this) { override fun contains(file: VirtualFile): Boolean { diff --git a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java index 13c61d3c6..8c2f715f5 100644 --- a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java +++ b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java @@ -18,6 +18,8 @@ package com.intellij.idea.plugin.hybris.runConfigurations; +import static com.intellij.idea.plugin.hybris.common.HybrisConstants.*; + import com.intellij.execution.ExecutionException; import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.configurations.JavaParameters; @@ -29,70 +31,77 @@ import com.intellij.idea.plugin.hybris.properties.PropertiesService; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettings; import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent; -import com.intellij.lang.properties.IProperty; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; - import java.util.StringTokenizer; - -import static com.intellij.idea.plugin.hybris.common.HybrisConstants.*; +import org.jetbrains.annotations.NotNull; public class HybrisJUnitExtension extends RunConfigurationExtension { - @Override - public > void updateJavaParameters(final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) throws ExecutionException { - if (runnerSettings != null || !isApplicableFor(configuration)) { - return; - } - final Project project = configuration.getProject(); - final PropertiesService propertiesService = PropertiesService.getInstance(project); - final ParametersList vmParameters = params.getVMParametersList(); - - addVmParameterIfNotExist(vmParameters, "-ea"); - - if (vmParameters.getParameters().stream().noneMatch(param -> param.startsWith("-Dplatformhome="))) { - final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); - - if (platformRootDirectory != null) { - vmParameters.add("-Dplatformhome=" + platformRootDirectory.getPath()); - } - } + @Override + public > void updateJavaParameters( + final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) + throws ExecutionException { + if (runnerSettings != null || !isApplicableFor(configuration)) { + return; + } + final Project project = configuration.getProject(); + final ParametersList vmParameters = params.getVMParametersList(); - if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { - final HybrisProjectSettings settings = HybrisProjectSettingsComponent.getInstance(project).getState(); + addVmParameterIfNotExist(vmParameters, "-ea"); - final String hybrisDataDirPath = FileUtil.toCanonicalPath(project.getBasePath() + '/' + settings.getHybrisDirectory() + '/' + HYBRIS_DATA_DIRECTORY); + if (vmParameters.getParameters().stream() + .noneMatch(param -> param.startsWith("-Dplatformhome="))) { + final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); - if (hybrisDataDirPath != null) { - params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); - } - } + if (platformRootDirectory != null) { + vmParameters.add("-Dplatformhome=" + platformRootDirectory.getPath()); + } + } + if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { + final HybrisProjectSettings settings = + HybrisProjectSettingsComponent.getInstance(project).getState(); + + final String hybrisDataDirPath = + FileUtil.toCanonicalPath( + project.getBasePath() + + '/' + + settings.getHybrisDirectory() + + '/' + + HYBRIS_DATA_DIRECTORY); + + if (hybrisDataDirPath != null) { + params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); + } + } - final String property = propertiesService.findProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); - if (property != null) { - final StringTokenizer tokenizer = new StringTokenizer(property.trim()); - while (tokenizer.hasMoreTokens()) { - final String newParam = tokenizer.nextToken().replaceAll("\"", ""); - addVmParameterIfNotExist(vmParameters, newParam); - } + final PropertiesService propertiesService = PropertiesService.getInstance(project); + if (propertiesService != null) { + final String property = propertiesService.findProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); + if (property != null) { + final StringTokenizer tokenizer = new StringTokenizer(property.trim()); + while (tokenizer.hasMoreTokens()) { + final String newParam = tokenizer.nextToken().replaceAll("\"", ""); + addVmParameterIfNotExist(vmParameters, newParam); } + } } + } - private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { - if (!vmParameters.hasParameter(newParam)) { - vmParameters.add(newParam); - } + private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { + if (!vmParameters.hasParameter(newParam)) { + vmParameters.add(newParam); } + } - @Override - public boolean isApplicableFor(@NotNull final RunConfigurationBase configuration) { - if (!(configuration instanceof JUnitConfiguration)) { - return false; - } - final Project project = configuration.getProject(); - return HybrisProjectSettingsComponent.getInstance(project).isHybrisProject(); + @Override + public boolean isApplicableFor(@NotNull final RunConfigurationBase configuration) { + if (!(configuration instanceof JUnitConfiguration)) { + return false; } + final Project project = configuration.getProject(); + return HybrisProjectSettingsComponent.getInstance(project).isHybrisProject(); + } } From 426d908d1a196b50e037b9b7d59c7b1878edea44 Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Sat, 23 Dec 2023 07:52:06 +0100 Subject: [PATCH 5/7] Fix Code Formatting --- .idea/codeStyles/codeStyleConfig.xml | 2 +- .../properties/impl/PropertiesServiceImpl.kt | 92 +++++++++---------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index a55e7a179..79ee123c2 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,5 +1,5 @@ - \ No newline at end of file diff --git a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt index f589a6b5e..5c14e530e 100644 --- a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt +++ b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt @@ -54,29 +54,29 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { override fun getLanguages(): Set { val languages = findProperty(HybrisConstants.PROPERTY_LANG_PACKS) - ?.split(",") - ?.map { it.trim() } - ?: emptyList() + ?.split(",") + ?.map { it.trim() } + ?: emptyList() val uniqueLanguages = languages.toMutableSet() uniqueLanguages.add(HybrisConstants.DEFAULT_LANGUAGE_ISOCODE) return uniqueLanguages - .map { it.lowercase() } - .toSet() + .map { it.lowercase() } + .toSet() } override fun containsLanguage(language: String, supportedLanguages: Set) = supportedLanguages - .contains(language.lowercase()) + .contains(language.lowercase()) override fun findProperty(key: String): String? = findAllProperties() - .filter { it.key == key } - .map { it.value } - .firstOrNull() + .filter { it.key == key } + .map { it.value } + .firstOrNull() override fun findAutoCompleteProperties(query: String): List = findAllIProperties() - .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } + .filter { it.key != null && it.key!!.contains(query) || query.isBlank() } override fun findMacroProperty(query: String): IProperty? { val allProps = findAllIProperties() @@ -105,16 +105,16 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { // Ignore Order and production.properties for now as `developer.mode` should be set to true for development anyway FileTypeIndex.getFiles(PropertiesFileType.INSTANCE, scope) - .mapNotNull { PsiManager.getInstance(project).findFile(it) } - .mapNotNull { it as? PropertiesFile } - .forEach { file -> - when (file.name) { - ENV_PROPERTIES_FILE -> envPropsFile = file - ADVANCED_PROPERTIES_FILE -> advancedPropsFile = file - LOCAL_PROPERTIES_FILE -> localPropsFile = file - PROJECT_PROPERTIES_FILE -> propertiesFiles.add(file) - } + .mapNotNull { PsiManager.getInstance(project).findFile(it) } + .mapNotNull { it as? PropertiesFile } + .forEach { file -> + when (file.name) { + ENV_PROPERTIES_FILE -> envPropsFile = file + ADVANCED_PROPERTIES_FILE -> advancedPropsFile = file + LOCAL_PROPERTIES_FILE -> localPropsFile = file + PROJECT_PROPERTIES_FILE -> propertiesFiles.add(file) } + } envPropsFile?.let { propertiesFiles.add(0, it) } advancedPropsFile?.let { propertiesFiles.add(1, it) } @@ -129,13 +129,13 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { } private fun findAllProperties(): LinkedHashMap = findAllIProperties() - .filter { it.value != null && it.key != null } - .associateTo(LinkedHashMap()) { it.key!! to it.value!! } - .let { properties -> - properties.filter { it.value.contains(nestedPropertyPrefix) } - .forEach { replacePlaceholder(properties, it.key, HashSet()) } - return properties - } + .filter { it.value != null && it.key != null } + .associateTo(LinkedHashMap()) { it.key!! to it.value!! } + .let { properties -> + properties.filter { it.value.contains(nestedPropertyPrefix) } + .forEach { replacePlaceholder(properties, it.key, HashSet()) } + return properties + } private fun replacePlaceholder(result: LinkedHashMap, key: String, visitedProperties: MutableSet) { @@ -175,25 +175,25 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { } private fun loadHybrisOptionalConfigDir(result: MutableMap) = (System.getenv(HYBRIS_OPT_CONFIG_DIR_ENV) - ?: result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR]?.value) - ?.let { File(it) } - ?.takeIf { it.isDirectory } - ?.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } - ?.associateByTo(TreeMap()) { it.name } - ?.values - ?.mapNotNull { toPropertiesFile(it) } - ?.forEach { addPropertyFile(result, it) } + ?: result[HybrisConstants.PROPERTY_OPTIONAL_CONFIG_DIR]?.value) + ?.let { File(it) } + ?.takeIf { it.isDirectory } + ?.listFiles { _, name -> optionalPropertiesFilePattern.matcher(name).matches() } + ?.associateByTo(TreeMap()) { it.name } + ?.values + ?.mapNotNull { toPropertiesFile(it) } + ?.forEach { addPropertyFile(result, it) } private fun loadHybrisRuntimeProperties(result: MutableMap) = System.getenv(HYBRIS_RUNTIME_PROPERTIES_ENV) - ?.takeIf { it.isNotBlank() } - ?.let { File(it) } - ?.let { toPropertiesFile(it) } - ?.let { addPropertyFile(result, it) } + ?.takeIf { it.isNotBlank() } + ?.let { File(it) } + ?.let { toPropertiesFile(it) } + ?.let { addPropertyFile(result, it) } private fun toPropertiesFile(file: File) = LocalFileSystem.getInstance().findFileByIoFile(file) - ?.takeIf { it.exists() } - ?.let { PsiManager.getInstance(project).findFile(it) } - ?.let { it as? PropertiesFile } + ?.takeIf { it.exists() } + ?.let { PsiManager.getInstance(project).findFile(it) } + ?.let { it as? PropertiesFile } private fun addPropertyFile(result: MutableMap, propertiesFile: PropertiesFile?) { if (propertiesFile == null) { @@ -208,7 +208,7 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { private fun createSearchScope(configModule: Module, platformModule: Module): GlobalSearchScope { val projectPropertiesScope = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.everythingScope(project), PropertiesFileType.INSTANCE) - .filter { it.name == "project.properties" } + .filter { it.name == "project.properties" } val envPropertiesScope = platformModule.moduleContentScope.filter { it.name == ENV_PROPERTIES_FILE } val advancedPropertiesScope = platformModule.moduleContentScope.filter { it.name == ADVANCED_PROPERTIES_FILE } val localPropertiesScope = configModule.moduleContentScope.filter { it.name == LOCAL_PROPERTIES_FILE } @@ -217,12 +217,12 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { } private fun obtainConfigModule() = ModuleManager.getInstance(project) - .modules - .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_CONFIG } + .modules + .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_CONFIG } private fun obtainPlatformModule() = ModuleManager.getInstance(project) - .modules - .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_PLATFORM } + .modules + .firstOrNull { it.yExtensionName() == HybrisConstants.EXTENSION_NAME_PLATFORM } fun GlobalSearchScope.filter(filter: (VirtualFile) -> Boolean) = object : DelegatingGlobalSearchScope(this) { override fun contains(file: VirtualFile): Boolean { From 7260cc156897736a080a916c5c7434e9a43e3305 Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Sat, 23 Dec 2023 08:11:40 +0100 Subject: [PATCH 6/7] Add Support for Environment Properties with Hybris Prefix --- CHANGELOG.md | 3 ++- .../idea/plugin/hybris/common/HybrisConstants.kt | 1 + .../properties/impl/PropertiesServiceImpl.kt | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c83eeee83..4fd191aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ ## [2023.3.3] ### `Tests` enhancements -- Add JDK Export Properties to JUnit Tests to run Integration Tests[#864](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/864) +- Add JDK Export Properties to JUnit Tests to run Integration Tests [#864](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/864) +- Load Properties from Files and Environment [#864](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/864) ## [2023.3.2] diff --git a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt index 6c458db63..287628d72 100644 --- a/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt +++ b/src/com/intellij/idea/plugin/hybris/common/HybrisConstants.kt @@ -182,6 +182,7 @@ object HybrisConstants { const val PROPERTY_OPTIONAL_CONFIG_DIR = "hybris.optional.config.dir" const val PROPERTY_LANG_PACKS = "lang.packs" const val PROPERTY_IMPEX_HEADER_REPLACEMENT = "impex.header.replacement" + const val PROPERTY_ENV_PROPERTY_PREFIX = "env.properties.prefix" const val PROPERTY_STANDALONE_JDKMODULESEXPORTS = "standalone.jdkmodulesexports"; diff --git a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt index 5c14e530e..b94d8cdb9 100644 --- a/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt +++ b/src/com/intellij/idea/plugin/hybris/properties/impl/PropertiesServiceImpl.kt @@ -19,6 +19,7 @@ package com.intellij.idea.plugin.hybris.properties.impl import com.intellij.idea.plugin.hybris.common.HybrisConstants +import com.intellij.idea.plugin.hybris.common.HybrisConstants.PROPERTY_ENV_PROPERTY_PREFIX import com.intellij.idea.plugin.hybris.common.HybrisConstants.ADVANCED_PROPERTIES_FILE import com.intellij.idea.plugin.hybris.common.HybrisConstants.ENV_PROPERTIES_FILE import com.intellij.idea.plugin.hybris.common.HybrisConstants.HYBRIS_OPT_CONFIG_DIR_ENV @@ -132,11 +133,26 @@ class PropertiesServiceImpl(val project: Project) : PropertiesService { .filter { it.value != null && it.key != null } .associateTo(LinkedHashMap()) { it.key!! to it.value!! } .let { properties -> + addEnvironmentProperties(properties) properties.filter { it.value.contains(nestedPropertyPrefix) } .forEach { replacePlaceholder(properties, it.key, HashSet()) } return properties } + private fun addEnvironmentProperties(properties: MutableMap) { + properties[PROPERTY_ENV_PROPERTY_PREFIX]?.let { prefix -> + System.getenv() + .filter { it.key.startsWith(prefix) } + .forEach() { + val envPropertyKey = it.key.substring(prefix.length) + val key = envPropertyKey.replace("__", "##") + .replace("_",".") + .replace("##","_") + properties[key] = it.value + } + } + } + private fun replacePlaceholder(result: LinkedHashMap, key: String, visitedProperties: MutableSet) { var lastIndex = 0 From 50a4e01c56a3510637ee1ad33b0421b729a980de Mon Sep 17 00:00:00 2001 From: Stefan Kruk Date: Sat, 23 Dec 2023 11:47:30 +0100 Subject: [PATCH 7/7] Fix Code Formatting --- .../HybrisJUnitExtension.java | 110 +++++++++--------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java index 8c2f715f5..5e0785b45 100644 --- a/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java +++ b/src/com/intellij/idea/plugin/hybris/runConfigurations/HybrisJUnitExtension.java @@ -34,74 +34,76 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; + import java.util.StringTokenizer; + import org.jetbrains.annotations.NotNull; public class HybrisJUnitExtension extends RunConfigurationExtension { - @Override - public > void updateJavaParameters( - final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) - throws ExecutionException { - if (runnerSettings != null || !isApplicableFor(configuration)) { - return; - } - final Project project = configuration.getProject(); - final ParametersList vmParameters = params.getVMParametersList(); + @Override + public > void updateJavaParameters( + final T configuration, final JavaParameters params, final RunnerSettings runnerSettings) + throws ExecutionException { + if (runnerSettings != null || !isApplicableFor(configuration)) { + return; + } + final Project project = configuration.getProject(); + final ParametersList vmParameters = params.getVMParametersList(); - addVmParameterIfNotExist(vmParameters, "-ea"); + addVmParameterIfNotExist(vmParameters, "-ea"); - if (vmParameters.getParameters().stream() - .noneMatch(param -> param.startsWith("-Dplatformhome="))) { - final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); + if (vmParameters.getParameters().stream() + .noneMatch(param -> param.startsWith("-Dplatformhome="))) { + final VirtualFile platformRootDirectory = HybrisRootUtil.findPlatformRootDirectory(project); - if (platformRootDirectory != null) { - vmParameters.add("-Dplatformhome=" + platformRootDirectory.getPath()); - } - } + if (platformRootDirectory != null) { + vmParameters.add("-Dplatformhome=" + platformRootDirectory.getPath()); + } + } - if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { - final HybrisProjectSettings settings = - HybrisProjectSettingsComponent.getInstance(project).getState(); - - final String hybrisDataDirPath = - FileUtil.toCanonicalPath( - project.getBasePath() - + '/' - + settings.getHybrisDirectory() - + '/' - + HYBRIS_DATA_DIRECTORY); - - if (hybrisDataDirPath != null) { - params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); - } - } + if (!params.getEnv().containsKey(HYBRIS_DATA_DIR_ENV)) { + final HybrisProjectSettings settings = + HybrisProjectSettingsComponent.getInstance(project).getState(); + + final String hybrisDataDirPath = + FileUtil.toCanonicalPath( + project.getBasePath() + + '/' + + settings.getHybrisDirectory() + + '/' + + HYBRIS_DATA_DIRECTORY); + + if (hybrisDataDirPath != null) { + params.addEnv(HYBRIS_DATA_DIR_ENV, hybrisDataDirPath); + } + } - final PropertiesService propertiesService = PropertiesService.getInstance(project); - if (propertiesService != null) { - final String property = propertiesService.findProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); - if (property != null) { - final StringTokenizer tokenizer = new StringTokenizer(property.trim()); - while (tokenizer.hasMoreTokens()) { - final String newParam = tokenizer.nextToken().replaceAll("\"", ""); - addVmParameterIfNotExist(vmParameters, newParam); + final PropertiesService propertiesService = PropertiesService.getInstance(project); + if (propertiesService != null) { + final String property = propertiesService.findProperty(PROPERTY_STANDALONE_JDKMODULESEXPORTS); + if (property != null) { + final StringTokenizer tokenizer = new StringTokenizer(property.trim()); + while (tokenizer.hasMoreTokens()) { + final String newParam = tokenizer.nextToken().replaceAll("\"", ""); + addVmParameterIfNotExist(vmParameters, newParam); + } + } } - } } - } - private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { - if (!vmParameters.hasParameter(newParam)) { - vmParameters.add(newParam); + private void addVmParameterIfNotExist(ParametersList vmParameters, String newParam) { + if (!vmParameters.hasParameter(newParam)) { + vmParameters.add(newParam); + } } - } - @Override - public boolean isApplicableFor(@NotNull final RunConfigurationBase configuration) { - if (!(configuration instanceof JUnitConfiguration)) { - return false; + @Override + public boolean isApplicableFor(@NotNull final RunConfigurationBase configuration) { + if (!(configuration instanceof JUnitConfiguration)) { + return false; + } + final Project project = configuration.getProject(); + return HybrisProjectSettingsComponent.getInstance(project).isHybrisProject(); } - final Project project = configuration.getProject(); - return HybrisProjectSettingsComponent.getInstance(project).isHybrisProject(); - } }