diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e51410fe..f647e938c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ - Invoke later slow operation `ImpEx Column values Highlight` [#835](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/835) - Omit slow operation on `HybrisWritingAccessProvider` [#846](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/846) - Added custom icon for `buildcallbacks.xml` file [#850](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/850) +- Simplify `HybrisWritingAccessProvider` logic due slow operations [#851](https://github.com/epam/sap-commerce-intellij-idea-plugin/pull/851) ## [2023.3.0] diff --git a/gradle.properties b/gradle.properties index 35388fd28..03ad4b6d7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -42,20 +42,20 @@ intellij.jvm.args=-ea -Xms512m -Xmx3G -XX:MaxMetaspaceSize=400m intellij.update.since.until.build=true intellij.plugin.name=SAP-Commerce-Developers-Toolset -intellij.plugin.version=2023.3.0 -intellij.plugin.since.build=233.11799.196 +intellij.plugin.version=2023.3.1 +intellij.plugin.since.build=233.11799.241 intellij.plugin.until.build=233.* intellij.type=IU -intellij.version=LATEST-EAP-SNAPSHOT -#intellij.version=233.11799.196 +#intellij.version=LATEST-EAP-SNAPSHOT +intellij.version=233.11799.241 intellij.download.sources=true # Plugin Verifier integration -> https://github.com/JetBrains/intellij-plugin-verifier # https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl # See https://jb.gg/intellij-platform-builds-list for available build versions # EAP snapshots -> https://www.jetbrains.com/intellij-repository/snapshots -plugin.verifier.ide.versions=IU-233.11799.196 +plugin.verifier.ide.versions=IU-233.11799.241 # Plugin Dependencies -> https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_dependencies.html # Platform explorer (Plugin) -> https://plugins.jetbrains.com/intellij-platform-explorer/extensions diff --git a/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.java b/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.java deleted file mode 100644 index 9c7e2950d..000000000 --- a/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of "SAP Commerce Developers Toolset" plugin for Intellij IDEA. - * Copyright (C) 2014-2016 Alexander Bartash - * Copyright (C) 2019-2023 EPAM Systems and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.intellij.idea.plugin.hybris.project.providers; - -import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent; -import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.WritingAccessProvider; -import com.intellij.util.ObjectUtils; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -public class HybrisWritingAccessProvider extends WritingAccessProvider { - - /** - * VirtualFile's marked with tis key are ignored by this provider. - * This is needed to allow controlled refactoring for the generated bean classes (which are normally read-only) - */ - public static final Key KEY_TEMPORARY_WRITABLE = Key.create( - HybrisWritingAccessProvider.class.getName() + "TemporaryWritable"); - - private final Project myProject; - - @NotNull - public static HybrisWritingAccessProvider getInstance(@NotNull final Project project) { - return EP.getExtensions(project).stream() - .map(o -> ObjectUtils.tryCast(o, HybrisWritingAccessProvider.class)) - .filter(Objects::nonNull) - .findAny() - .orElseThrow(IllegalStateException::new); - } - - public HybrisWritingAccessProvider(@NotNull final Project project) { - myProject = project; - } - - @NotNull - @Override - public Collection requestWriting(final Collection files) { - final List writingDenied = new ArrayList<>(); - for (VirtualFile file : files) { - if (isFileReadOnly(file)) { - writingDenied.add(file); - } - } - return writingDenied; - } - - @Override - public boolean isPotentiallyWritable(@NotNull final VirtualFile file) { - return !isFileReadOnly(file); - } - - /** - * Requests to temporary ignore the read-only status provided by this provider. - * Does nothing if read-only status is for some other reason - */ - public void markTemporaryWritable(@NotNull VirtualFile vFile) { - if (vFile.isValid() && !isPotentiallyWritable(vFile)) { - vFile.putUserData(KEY_TEMPORARY_WRITABLE, true); - } - } - - /** - * Clears any possible flag marked by {@link #markTemporaryWritable(VirtualFile)} call - */ - public static void unmarkTemporaryWritable(@NotNull VirtualFile vFile) { - if (vFile.isValid()) { - vFile.putUserData(KEY_TEMPORARY_WRITABLE, null); - } - } - - protected boolean isFileReadOnly(@NotNull final VirtualFile file) { - if (isTemporarilyWritable(file)) { - return false; - } - - return Optional.ofNullable(ModuleUtil.findModuleForFile(file, myProject)) - .map(module -> HybrisProjectSettingsComponent.getInstance(myProject) - .getModuleSettings(module) - .getReadonly() - ) - .orElse(false); - } - - private boolean isTemporarilyWritable(@NotNull final VirtualFile vFile) { - final Boolean excluded = vFile.getUserData(KEY_TEMPORARY_WRITABLE); - return excluded != null && excluded; - } - -} diff --git a/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.kt b/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.kt new file mode 100644 index 000000000..c360a2d60 --- /dev/null +++ b/src/com/intellij/idea/plugin/hybris/project/providers/HybrisWritingAccessProvider.kt @@ -0,0 +1,43 @@ +/* + * This file is part of "SAP Commerce Developers Toolset" plugin for Intellij IDEA. + * Copyright (C) 2014-2016 Alexander Bartash + * Copyright (C) 2019-2023 EPAM Systems and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.intellij.idea.plugin.hybris.project.providers + +import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.WritingAccessProvider + +class HybrisWritingAccessProvider(private val myProject: Project) : WritingAccessProvider() { + + private val ootbReadOnlyMode = HybrisProjectSettingsComponent.getInstance(myProject).state.importOotbModulesInReadOnlyMode + + override fun requestWriting(files: Collection) = files + .filter { isFileReadOnly(it) } + .toMutableSet() + + override fun isPotentiallyWritable(file: VirtualFile) = !isFileReadOnly(file) + + private fun isFileReadOnly(file: VirtualFile): Boolean { + if (!ootbReadOnlyMode) return false + if (!file.isWritable) return true + + return file.path.contains("hybris/bin") + && !file.path.contains("hybris/bin/custom") + } +} diff --git a/src/com/intellij/idea/plugin/hybris/startup/HybrisIntelliLangStartupActivity.kt b/src/com/intellij/idea/plugin/hybris/startup/HybrisIntelliLangStartupActivity.kt index de9ed8a08..ff4cac13c 100644 --- a/src/com/intellij/idea/plugin/hybris/startup/HybrisIntelliLangStartupActivity.kt +++ b/src/com/intellij/idea/plugin/hybris/startup/HybrisIntelliLangStartupActivity.kt @@ -21,6 +21,7 @@ import com.intellij.idea.plugin.hybris.common.HybrisConstants import com.intellij.idea.plugin.hybris.flexibleSearch.FlexibleSearchLanguage import com.intellij.idea.plugin.hybris.polyglotQuery.PolyglotQueryLanguage import com.intellij.idea.plugin.hybris.settings.HybrisProjectSettingsComponent +import com.intellij.openapi.application.ModalityState import com.intellij.openapi.application.ReadAction import com.intellij.openapi.project.Project import com.intellij.openapi.startup.ProjectActivity @@ -28,11 +29,11 @@ import com.intellij.patterns.PsiJavaPatterns import com.intellij.psi.JavaPsiFacade import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.searches.ClassInheritorsSearch +import com.intellij.util.concurrency.AppExecutorUtil import org.intellij.plugins.intelliLang.Configuration import org.intellij.plugins.intelliLang.inject.config.InjectionPlace import org.intellij.plugins.intelliLang.inject.java.InjectionCache import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport -import java.util.concurrent.Callable /** * TODO: reset Injection Cache on CRUD operation on classes related to FlexibleSearchQuery @@ -43,34 +44,32 @@ class HybrisIntelliLangStartupActivity : ProjectActivity { if (!HybrisProjectSettingsComponent.getInstance(project).isHybrisProject()) return ReadAction - .nonBlocking( - Callable { - with(InjectionCache.getInstance(project).xmlIndex) { - add(HybrisConstants.CLASS_NAME_FLEXIBLE_SEARCH_QUERY) - addAll(findCustomExtensionsOfTheFlexibleSearch(project)) - } + .nonBlocking> { findCustomExtensionsOfTheFlexibleSearch(project) } + .finishOnUiThread(ModalityState.defaultModalityState()) { + with(InjectionCache.getInstance(project).xmlIndex) { + add(HybrisConstants.CLASS_NAME_FLEXIBLE_SEARCH_QUERY) + addAll(it) + } - val targetLanguages = setOf(FlexibleSearchLanguage.INSTANCE.id, PolyglotQueryLanguage.instance.id) + val targetLanguages = setOf(FlexibleSearchLanguage.INSTANCE.id, PolyglotQueryLanguage.instance.id) - // TODO: replace with pattern declared in the XML file once https://youtrack.jetbrains.com/issue/IDEA-339624/ will be resolved. - // com.intellij.patterns.compiler.PatternCompiler cannot parse primitive booleans required by the pattern - Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID) - .filter { targetLanguages.contains(it.injectedLanguageId) } - .forEach { - val injectionPlaces = it.injectionPlaces.toMutableSet() - val psiParameterInjectionPlace = InjectionPlace( - PsiJavaPatterns.psiParameter().ofMethod( - PsiJavaPatterns.psiMethod().definedInClass(PsiJavaPatterns.psiClass().inheritorOf(false, HybrisConstants.CLASS_FQN_FLEXIBLE_SEARCH_QUERY)) - ), - true - ) - injectionPlaces.add(psiParameterInjectionPlace) - it.setInjectionPlaces(*injectionPlaces.toTypedArray()) - } - } - ) - .inSmartMode(project) - .executeSynchronously(); + // TODO: replace with pattern declared in the XML file once https://youtrack.jetbrains.com/issue/IDEA-339624/ will be resolved. + // com.intellij.patterns.compiler.PatternCompiler cannot parse primitive booleans required by the pattern + Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID) + .filter { targetLanguages.contains(it.injectedLanguageId) } + .forEach { + val injectionPlaces = it.injectionPlaces.toMutableSet() + val psiParameterInjectionPlace = InjectionPlace( + PsiJavaPatterns.psiParameter().ofMethod( + PsiJavaPatterns.psiMethod().definedInClass(PsiJavaPatterns.psiClass().inheritorOf(false, HybrisConstants.CLASS_FQN_FLEXIBLE_SEARCH_QUERY)) + ), + true + ) + injectionPlaces.add(psiParameterInjectionPlace) + it.setInjectionPlaces(*injectionPlaces.toTypedArray()) + } + } + .submit(AppExecutorUtil.getAppExecutorService()) } private fun findCustomExtensionsOfTheFlexibleSearch(project: Project) = (JavaPsiFacade.getInstance(project)