diff --git a/README.adoc b/README.adoc
index af1ce970..5ffd15a1 100644
--- a/README.adoc
+++ b/README.adoc
@@ -224,7 +224,7 @@ or use the https://repo.spring.io/javaformat-eclipse-update-site/[update site].
=== IntelliJ IDEA
The IntelliJ IDEA plugin provides custom formatter support for IntelliJ IDEA.
-The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script.
+The plugin is automatically activated whenever the Maven or Gradle plugins are discovered in a project build script or if a `.springjavaformatconfig` file.
A Spring Java Format icon (image:spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/spring-javaformat/formatOn.png[title="Icon"]) will also be displayed in the status bar to indicate the formatter is active.
You can use the standard `code` -> `reformat code` action to format the code.
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
index 88ddb665..5b0b83d1 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/pom.xml
@@ -12,15 +12,10 @@
Spring JavaFormat IntelliJ IDEA Plugin
${basedir}/../..
- 11
+ 17
-
- io.spring.javaformat
- spring-javaformat-formatter
- ${project.version}
-
io.spring.javaformat
spring-javaformat-formatter-eclipse-runtime
@@ -32,6 +27,11 @@
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ ${project.version}
+
io.spring.javaformat
@@ -41,14 +41,20 @@
provided
- io.spring.javaformat.intellij.idea
+ org.jetbrains
annotations
+ 13.0
+ provided
+
+
+ io.spring.javaformat.intellij.idea
+ app
${project.version}
provided
io.spring.javaformat.intellij.idea
- platform-api
+ jps-model
${project.version}
provided
@@ -66,7 +72,7 @@
io.spring.javaformat.intellij.idea
- idea
+ util_rt
${project.version}
provided
@@ -78,7 +84,7 @@
io.spring.javaformat.intellij.idea
- maven-server-api
+ maven-server
${project.version}
provided
@@ -110,6 +116,18 @@
picocontainer
provided
+
+ org.jetbrains.kotlinx
+ kotlinx-coroutines-core
+ 1.6.4
+ provided
+
+
+ it.unimi.dsi
+ fastutil
+ 8.5.11
+ provided
+
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java
deleted file mode 100644
index 79a76382..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormat.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import com.intellij.ide.plugins.IdeaPluginDescriptor;
-import com.intellij.ide.plugins.PluginManagerCore;
-import com.intellij.ide.util.PropertiesComponent;
-import com.intellij.openapi.application.ApplicationInfo;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.PluginDescriptor;
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.serviceContainer.ComponentManagerImpl;
-import org.picocontainer.MutablePicoContainer;
-
-import io.spring.format.formatter.intellij.codestyle.SpringCodeStyleManager;
-import io.spring.format.formatter.intellij.codestyle.monitor.FileMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.GradleMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.MavenMonitor;
-import io.spring.format.formatter.intellij.codestyle.monitor.Monitors;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
-
-/**
- * Spring Java Format IntelliJ support added to a {@link Project}.
- *
- * @author Phillip Webb
- */
-public class SpringFormat {
-
- private static final String CODE_STYLE_MANAGER_KEY = CodeStyleManager.class.getName();
-
- private static final String ACTIVE_PROPERTY = SpringFormat.class.getName() + ".ACTIVE";
-
- private static final Logger logger = Logger.getInstance(SpringFormat.class);
-
- private final Project project;
-
- private final StatusIndicator statusIndicator;
-
- private final Lock lock = new ReentrantLock();
-
- private Monitors monitors;
-
- private PropertiesComponent properties;
-
- protected SpringFormat(Project project) {
- logger.info("Initializing Spring Format for project " + project.getName());
- this.project = project;
- this.statusIndicator = new StatusIndicator(project);
- this.properties = PropertiesComponent.getInstance(project);
- if (this.properties.getBoolean(ACTIVE_PROPERTY, false)) {
- update(State.ACTIVE);
- }
- this.monitors = new Monitors(this.project, this::update, FileMonitor.factory(), MavenMonitor.factory(),
- GradleMonitor.factory());
- Disposer.register(project, this::dispose);
- }
-
- private void dispose() {
- if (this.monitors != null) {
- this.monitors.stop();
- this.monitors = null;
- }
- }
-
- private void update(State state) {
- logger.info("Updating state of " + this.project.getName() + " to " + state);
- this.lock.lock();
- try {
- CodeStyleManager manager = CodeStyleManager.getInstance(this.project);
- if (manager == null) {
- logger.warn("Unable to find exiting CodeStyleManager");
- return;
- }
- if (state == State.ACTIVE && !(manager instanceof SpringCodeStyleManager)) {
- logger.debug("Enabling SpringCodeStyleManager");
- registerCodeStyleManager(new SpringCodeStyleManager(manager));
- this.properties.setValue(ACTIVE_PROPERTY, true);
- }
- if (state == State.NOT_ACTIVE && (manager instanceof SpringCodeStyleManager)) {
- logger.debug("Disabling SpringCodeStyleManager");
- registerCodeStyleManager(((SpringCodeStyleManager) manager).getDelegate());
- this.properties.setValue(ACTIVE_PROPERTY, false);
- }
- ApplicationManager.getApplication().invokeLater(() -> this.statusIndicator.update(state));
- }
- finally {
- this.lock.unlock();
- }
- }
-
- private void registerCodeStyleManager(CodeStyleManager manager) {
- if (ApplicationInfo.getInstance().getBuild().getBaselineVersion() >= 193) {
- IdeaPluginDescriptor plugin = PluginManagerCore.getPlugin(PluginId.getId("spring-javaformat"));
- try {
- ((ComponentManagerImpl) this.project).registerServiceInstance(CodeStyleManager.class, manager, plugin);
- }
- catch (NoSuchMethodError ex) {
- Method method = findRegisterServiceInstanceMethod(this.project.getClass());
- invokeRegisterServiceInstanceMethod(manager, plugin, method);
- }
- }
- else {
- MutablePicoContainer container = (MutablePicoContainer) this.project.getPicoContainer();
- container.unregisterComponent(CODE_STYLE_MANAGER_KEY);
- container.registerComponentInstance(CODE_STYLE_MANAGER_KEY, manager);
- }
- }
-
- private Method findRegisterServiceInstanceMethod(Class> projectClass) {
- if (projectClass != null) {
- Method[] methods = projectClass.getDeclaredMethods();
- for (Method method : methods) {
- if (method.getName().equals("registerServiceInstance") && method.getParameterCount() == 3) {
- if (PluginDescriptor.class.isAssignableFrom(method.getParameterTypes()[2])) {
- return method;
- }
- }
- }
- return findRegisterServiceInstanceMethod(projectClass.getSuperclass());
- }
- return null;
- }
-
- private void invokeRegisterServiceInstanceMethod(CodeStyleManager manager, IdeaPluginDescriptor plugin,
- Method method) {
- if (method == null) {
- throw new IllegalStateException("Unsupported IntelliJ IDEA version");
- }
- method.setAccessible(true);
- try {
- method.invoke(this.project, manager, plugin);
- }
- catch (Exception ex) {
- throw new IllegalStateException(ex);
- }
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java
deleted file mode 100644
index c133d872..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManager.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-
-import com.intellij.formatting.FormattingMode;
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.psi.codeStyle.DocCommentSettings;
-import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.ThrowableRunnable;
-
-/**
- * {@link CodeStyleManager} implementation that delegates all calls.
- *
- * @author Phillip Webb
- */
-public class DelegatingCodeStyleManager extends CodeStyleManager implements FormattingModeAwareIndentAdjuster {
-
- private final CodeStyleManager delegate;
-
- public DelegatingCodeStyleManager(CodeStyleManager delegate) {
- this.delegate = delegate;
- }
-
- public CodeStyleManager getDelegate() {
- return this.delegate;
- }
-
- @Override
- public int getSpacing(PsiFile file, int offset) {
- return this.delegate.getSpacing(file, offset);
- }
-
- @Override
- public int getMinLineFeeds(PsiFile file, int offset) {
- return this.delegate.getMinLineFeeds(file, offset);
- }
-
- @Override
- public void runWithDocCommentFormattingDisabled(PsiFile file, Runnable runnable) {
- this.delegate.runWithDocCommentFormattingDisabled(file, runnable);
- }
-
- @Override
- public DocCommentSettings getDocCommentSettings(PsiFile file) {
- return this.delegate.getDocCommentSettings(file);
- }
-
- @Override
- public Project getProject() {
- return this.delegate.getProject();
- }
-
- @Override
- public PsiElement reformat(PsiElement element) throws IncorrectOperationException {
- return this.delegate.reformat(element);
- }
-
- @Override
- public PsiElement reformat(PsiElement element, boolean canChangeWhiteSpacesOnly)
- throws IncorrectOperationException {
- return this.delegate.reformat(element, canChangeWhiteSpacesOnly);
- }
-
- @Override
- public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset)
- throws IncorrectOperationException {
- return this.delegate.reformatRange(element, startOffset, endOffset);
- }
-
- @Override
- public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset,
- boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException {
- return this.delegate.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly);
- }
-
- @Override
- public void reformatText(PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException {
- this.delegate.reformatText(file, startOffset, endOffset);
- }
-
- @Override
- public void reformatText(PsiFile file, Collection extends TextRange> ranges) throws IncorrectOperationException {
- this.delegate.reformatText(file, ranges);
- }
-
- @Override
- public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) throws IncorrectOperationException {
- this.delegate.reformatTextWithContext(file, info);
- }
-
- @Override
- public void adjustLineIndent(PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException {
- this.delegate.adjustLineIndent(file, rangeToAdjust);
- }
-
- @Override
- public int adjustLineIndent(PsiFile file, int offset) throws IncorrectOperationException {
- return this.delegate.adjustLineIndent(file, offset);
- }
-
- @Override
- public int adjustLineIndent(Document document, int offset) {
- return this.delegate.adjustLineIndent(document, offset);
- }
-
- @Override
- @Deprecated
- public boolean isLineToBeIndented(PsiFile file, int offset) {
- return this.delegate.isLineToBeIndented(file, offset);
- }
-
- @Override
- public String getLineIndent(PsiFile file, int offset) {
- return this.delegate.getLineIndent(file, offset);
- }
-
- @Override
- public String getLineIndent(Document document, int offset) {
- return this.delegate.getLineIndent(document, offset);
- }
-
- @Override
- public String getLineIndent(PsiFile file, int offset, FormattingMode mode) {
- return this.delegate.getLineIndent(file, offset, mode);
- }
-
- @Override
- @Deprecated
- public com.intellij.psi.codeStyle.Indent getIndent(String text, FileType fileType) {
- return this.delegate.getIndent(text, fileType);
- }
-
- @Override
- @Deprecated
- public String fillIndent(com.intellij.psi.codeStyle.Indent indent, FileType fileType) {
- return this.delegate.fillIndent(indent, fileType);
- }
-
- @Override
- @Deprecated
- public com.intellij.psi.codeStyle.Indent zeroIndent() {
- return this.delegate.zeroIndent();
- }
-
- @Override
- public void reformatNewlyAddedElement(ASTNode block, ASTNode addedElement) throws IncorrectOperationException {
- this.delegate.reformatNewlyAddedElement(block, addedElement);
- }
-
- @Override
- public boolean isSequentialProcessingAllowed() {
- return this.delegate.isSequentialProcessingAllowed();
- }
-
- @Override
- public void performActionWithFormatterDisabled(Runnable r) {
- this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public void performActionWithFormatterDisabled(ThrowableRunnable r) throws T {
- this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public T performActionWithFormatterDisabled(Computable r) {
- return this.delegate.performActionWithFormatterDisabled(r);
- }
-
- @Override
- public int adjustLineIndent(Document document, int offset, FormattingMode mode) {
- if (this.delegate instanceof FormattingModeAwareIndentAdjuster) {
- return ((FormattingModeAwareIndentAdjuster) this.delegate).adjustLineIndent(document, offset, mode);
- }
- return offset;
- }
-
- @Override
- public FormattingMode getCurrentFormattingMode() {
- if (this.delegate instanceof FormattingModeAwareIndentAdjuster) {
- return ((FormattingModeAwareIndentAdjuster) this.delegate).getCurrentFormattingMode();
- }
- return FormattingMode.REFORMAT;
- }
-
- @Override
- public void scheduleIndentAdjustment(Document document, int offset) {
- this.delegate.scheduleIndentAdjustment(document, offset);
- }
-
- @Override
- public void scheduleReformatWhenSettingsComputed(PsiFile file) {
- this.delegate.scheduleReformatWhenSettingsComputed(file);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java
deleted file mode 100644
index 56b94ab5..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.function.Supplier;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.IncorrectOperationException;
-
-/**
- * {@link CodeStyleManager} to apply Spring Formatting conventions.
- *
- * @author Phillip Webb
- */
-public class SpringCodeStyleManager extends DelegatingCodeStyleManager {
-
- private final SpringReformatter springReformatter;
-
- public SpringCodeStyleManager(CodeStyleManager delegate) {
- super(delegate);
- this.springReformatter = new SpringReformatter(() -> getProject());
- }
-
- SpringCodeStyleManager(CodeStyleManager delegate, SpringReformatter springReformatter) {
- super(delegate);
- this.springReformatter = springReformatter;
- }
-
- @Override
- public void reformatText(PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException {
- reformat(file, () -> Collections.singleton(new TextRange(startOffset, endOffset)),
- () -> super.reformatText(file, startOffset, endOffset));
- }
-
- @Override
- public void reformatText(PsiFile file, Collection extends TextRange> ranges) throws IncorrectOperationException {
- reformat(file, () -> ranges, () -> super.reformatText(file, ranges));
- }
-
- @Override
- public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) throws IncorrectOperationException {
- reformat(file, () -> info.allChangedRanges, () -> super.reformatTextWithContext(file, info));
- }
-
- private void reformat(PsiFile file, Supplier> ranges, Runnable delegate) {
- if (this.springReformatter.canReformat(file)) {
- this.springReformatter.reformat(file, ranges.get());
- }
- else {
- delegate.run();
- }
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java
deleted file mode 100644
index be1ceed0..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/SpringReformatter.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.function.Supplier;
-
-import com.intellij.core.CoreBundle;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.IncorrectOperationException;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.text.edits.TextEdit;
-
-import io.spring.javaformat.config.JavaFormatConfig;
-import io.spring.javaformat.formatter.Formatter;
-
-/**
- * Reformatter used by {@link SpringCodeStyleManager} to determine when formatting can
- * apply and to perform the actual formatting.
- *
- * @author Phillip Webb
- */
-class SpringReformatter {
-
- private static final String NORMALIZED_LINE_SEPARATOR = "\n";
-
- private static final FileType JAVA_FILE_TYPE = FileTypeManager.getInstance().getStdFileType("JAVA");
-
- private final Supplier project;
-
- private final Supplier application;
-
- private final Supplier documentManager;
-
- SpringReformatter(Supplier project) {
- this.project = project;
- this.application = () -> ApplicationManager.getApplication();
- this.documentManager = () -> PsiDocumentManager.getInstance(project.get());
- }
-
- SpringReformatter(Supplier project, Supplier application,
- Supplier documentManager) {
- this.project = project;
- this.application = application;
- this.documentManager = documentManager;
- }
-
- public boolean canReformat(PsiFile file) {
- return JAVA_FILE_TYPE.equals(file.getFileType());
- }
-
- public void reformat(PsiFile file, Collection extends TextRange> ranges) {
- this.application.get().assertWriteAccessAllowed();
- this.documentManager.get().commitAllDocuments();
- if (!file.isWritable()) {
- throwNotWritableException(file);
- }
- reformat(file, ranges, this.documentManager.get().getDocument(file));
- }
-
- private void throwNotWritableException(PsiElement element) throws IncorrectOperationException {
- if (element instanceof PsiDirectory) {
- String url = ((PsiDirectory) element).getVirtualFile().getPresentableUrl();
- throw new IncorrectOperationException(CoreBundle.message("cannot.modify.a.read.only.directory", url));
- }
- PsiFile file = element.getContainingFile();
- if (file == null) {
- throw new IncorrectOperationException();
- }
- VirtualFile virtualFile = file.getVirtualFile();
- if (virtualFile == null) {
- throw new IncorrectOperationException();
- }
- throw new IncorrectOperationException(
- CoreBundle.message("cannot.modify.a.read.only.file", virtualFile.getPresentableUrl()));
- }
-
- private void reformat(PsiFile file, Collection extends TextRange> ranges, Document document) {
- if (document != null && file.getVirtualFile() != null) {
- JavaFormatConfig javaFormatConfig = JavaFormatConfig.findFrom(file.getVirtualFile().toNioPath());
- Formatter formatter = new Formatter(javaFormatConfig);
- String source = document.getText();
- IRegion[] regions = EclipseRegionAdapter.asArray(ranges);
- TextEdit edit = formatter.format(source, regions, NORMALIZED_LINE_SEPARATOR);
- applyEdit(document, edit);
- }
- }
-
- private void applyEdit(Document document, TextEdit textEdit) {
- runWriteCommandAction(() -> {
- try {
- EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(document);
- textEdit.apply(adapter);
- this.documentManager.get().commitDocument(document);
- }
- catch (Exception ex) {
- throw new IllegalStateException(ex);
- }
- });
- }
-
- protected void runWriteCommandAction(Runnable runnable) {
- WriteCommandAction.runWriteCommandAction(this.project.get(), runnable);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
similarity index 92%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
index 99dadda0..8d874234 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapter.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
similarity index 79%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
index 59169754..20888b55 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapter.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import com.intellij.openapi.util.TextRange;
@@ -29,15 +28,15 @@
*
* @author Phillip Webb
*/
-public class EclipseRegionAdapter extends Region {
+class EclipseRegionAdapter extends Region {
private static final IRegion[] NO_REGIONS = {};
- public EclipseRegionAdapter(TextRange range) {
+ EclipseRegionAdapter(TextRange range) {
super(range.getStartOffset(), range.getLength());
}
- public static IRegion[] asArray(Collection extends TextRange> ranges) {
+ static IRegion[] asArray(List ranges) {
if (ranges == null) {
return NO_REGIONS;
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java
new file mode 100644
index 00000000..a457072f
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingService.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2017-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.format.formatter.intellij.formatting;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiConsumer;
+
+import com.intellij.formatting.FormattingContext;
+import com.intellij.formatting.service.AbstractDocumentFormattingService;
+import com.intellij.formatting.service.FormattingService;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.text.edits.TextEdit;
+import org.jetbrains.annotations.NotNull;
+
+import io.spring.format.formatter.intellij.state.State;
+import io.spring.javaformat.config.JavaFormatConfig;
+import io.spring.javaformat.formatter.Formatter;
+
+/**
+ * {@link FormattingService} to apply Spring formatting conventions.
+ *
+ * @author Phillip Webb
+ */
+public class SpringJavaFormatFormattingService extends AbstractDocumentFormattingService {
+
+ private static final String NORMALIZED_LINE_SEPARATOR = "\n";
+
+ private static final Set FEATURES = Set.of(Feature.FORMAT_FRAGMENTS);
+
+ private static final FileType JAVA_FILE_TYPE = FileTypeManager.getInstance().getStdFileType("JAVA");
+
+ private final BiConsumer runAction;
+
+ public SpringJavaFormatFormattingService() {
+ this(WriteCommandAction::runWriteCommandAction);
+ }
+
+ SpringJavaFormatFormattingService(BiConsumer runAction) {
+ this.runAction = runAction;
+ }
+
+ @Override
+ public @NotNull Set getFeatures() {
+ return FEATURES;
+ }
+
+ @Override
+ public boolean canFormat(@NotNull PsiFile file) {
+ return JAVA_FILE_TYPE.equals(file.getFileType()) && State.get(file.getProject()) == State.ACTIVE;
+ }
+
+ @Override
+ public void formatDocument(@NotNull Document document, @NotNull List formattingRanges,
+ @NotNull FormattingContext formattingContext, boolean canChangeWhiteSpaceOnly, boolean quickFormat) {
+ VirtualFile file = formattingContext.getVirtualFile();
+ Path path = (file != null) ? file.toNioPath() : null;
+ JavaFormatConfig config = JavaFormatConfig.findFrom(path);
+ Formatter formatter = new Formatter(config);
+ String source = document.getText();
+ formattingRanges = (!formattingRanges.isEmpty()) ? formattingRanges : List.of(TextRange.allOf(source));
+ IRegion[] regions = EclipseRegionAdapter.asArray(formattingRanges);
+ TextEdit edit = formatter.format(source, regions, NORMALIZED_LINE_SEPARATOR);
+ applyEdit(formattingContext.getProject(), document, edit);
+ }
+
+ private void applyEdit(Project project, Document document, TextEdit textEdit) {
+ this.runAction.accept(project, () -> {
+ try {
+ IDocument adapted = new EclipseDocumentAdapter(document);
+ textEdit.apply(adapted);
+ }
+ catch (Exception ex) {
+ throw new IllegalStateException(ex);
+ }
+ });
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
similarity index 88%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
index cc93579c..ac930e50 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/FileMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/FileMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -24,16 +24,16 @@
import com.intellij.openapi.vfs.VirtualFileMoveEvent;
import com.intellij.openapi.vfs.VirtualFilePropertyEvent;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
- * {@link Monitor} that looks for a {@literal .springformat} file.
+ * {@link Monitor} that looks for a {@literal .springjavaformatconfig} file.
*
* @author Phillip Webb
*/
public class FileMonitor extends Monitor {
- private static final String TRIGGER_FILE = ".springformat";
+ private static final String TRIGGER_FILE = ".springjavaformatconfig";
private final VirtualFileManager fileManager;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
similarity index 83%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
index a90c9ce6..6ad8d657 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/GradleMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/GradleMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.Collection;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ExternalProjectInfo;
@@ -27,13 +26,14 @@
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener;
import com.intellij.openapi.project.Project;
import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
- * {@link Monitor} that looks for a {@code spring-javaformat-gradle-plugin} declaration in
- * the build.gradle file.
+ * {@link Monitor} that looks for a {@code spring-javaformat-gradle-plugin}
+ * declaration in the build.gradle file.
*
* @author Phillip Webb
*/
@@ -46,12 +46,19 @@ public class GradleMonitor extends Monitor {
public GradleMonitor(Project project, Trigger trigger) {
super(project, trigger);
MessageBusConnection messageBus = project.getMessageBus().connect();
- messageBus.subscribe(ProjectDataImportListener.TOPIC, (path) -> check());
+ messageBus.subscribe(ProjectDataImportListener.TOPIC, new ProjectDataImportListener() {
+
+ @Override
+ public void onImportFinished(@Nullable String projectPath) {
+ check();
+ }
+
+ });
}
private void check() {
logger.info("Checking " + getProject().getName() + " for use of Spring Java Format");
- ProjectDataManager projectDataManager = ServiceManager.getService(ProjectDataManager.class);
+ ProjectDataManager projectDataManager = getProject().getService(ProjectDataManager.class);
boolean hasFormatPlugin = hasFormatPlugin(
projectDataManager.getExternalProjectsData(getProject(), GradleConstants.SYSTEM_ID));
getTrigger().updateState(hasFormatPlugin ? State.ACTIVE : State.NOT_ACTIVE);
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
similarity index 93%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
index c0cab821..5af1f808 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/MavenMonitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/MavenMonitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.List;
@@ -26,7 +26,7 @@
import org.jetbrains.idea.maven.project.MavenProjectsTree.Listener;
import org.jetbrains.idea.maven.server.NativeMavenProjectHolder;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* {@link Monitor} that looks for a {@code spring-javaformat-maven-plugin} declaration in
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
similarity index 93%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
index 81710cd5..ec69d85e 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitor.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import com.intellij.openapi.project.Project;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
similarity index 94%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
index 33d1b7e1..5af61007 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Monitors.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Monitors.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
import java.util.ArrayList;
import java.util.Arrays;
@@ -24,7 +24,7 @@
import com.intellij.openapi.project.Project;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* Utility class used to manage a collection of {@link Monitors}. Creates and manages
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
similarity index 73%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
index 10bbc5ba..8bab9300 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/codestyle/monitor/Trigger.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/monitor/Trigger.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle.monitor;
+package io.spring.format.formatter.intellij.monitor;
+
+import io.spring.format.formatter.intellij.state.State;
/**
* Trigger used to to update the state for this monitor. Triggers are thread safe and can
@@ -30,21 +32,4 @@ public interface Trigger {
*/
void updateState(State state);
- /**
- * The desired state of the plugin for this monitor.
- */
- enum State {
-
- /**
- * The plugin should be active.
- */
- ACTIVE,
-
- /**
- * The plugin need not be active.
- */
- NOT_ACTIVE
-
- }
-
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java
new file mode 100644
index 00000000..043de49c
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/ManagedSpringJavaFormatProject.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.format.formatter.intellij.startup;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+
+import io.spring.format.formatter.intellij.monitor.FileMonitor;
+import io.spring.format.formatter.intellij.monitor.GradleMonitor;
+import io.spring.format.formatter.intellij.monitor.MavenMonitor;
+import io.spring.format.formatter.intellij.monitor.Monitors;
+import io.spring.format.formatter.intellij.state.State;
+import io.spring.format.formatter.intellij.ui.StatusIndicator;
+
+/**
+ * Spring Java Format IntelliJ support added to a {@link Project}.
+ *
+ * @author Phillip Webb
+ */
+class ManagedSpringJavaFormatProject {
+
+ private static final String ACTIVE_PROPERTY = ManagedSpringJavaFormatProject.class.getName() + ".ACTIVE";
+
+ private static final Logger logger = Logger.getInstance(ManagedSpringJavaFormatProject.class);
+
+ private final Project project;
+
+ private final StatusIndicator statusIndicator;
+
+ private final Lock lock = new ReentrantLock();
+
+ private Monitors monitors;
+
+ private PropertiesComponent properties;
+
+ protected ManagedSpringJavaFormatProject(Project project) {
+ logger.info("Initializing Spring Format for project " + project.getName());
+ this.project = project;
+ this.statusIndicator = new StatusIndicator(project);
+ this.properties = PropertiesComponent.getInstance(project);
+ if (this.properties.getBoolean(ACTIVE_PROPERTY, false)) {
+ update(State.ACTIVE);
+ }
+ this.monitors = new Monitors(this.project, this::update, FileMonitor.factory(), MavenMonitor.factory(),
+ GradleMonitor.factory());
+ Disposer.register(project, this::dispose);
+ }
+
+ private void dispose() {
+ if (this.monitors != null) {
+ logger.info("Stopping monitors for " + this.project.getName());
+ this.monitors.stop();
+ this.monitors = null;
+ }
+ }
+
+ private void update(State state) {
+ logger.info("Updating state of " + this.project.getName() + " to " + state);
+ this.lock.lock();
+ try {
+ state.put(this.project);
+ ApplicationManager.getApplication().invokeLater(() -> this.statusIndicator.update(state));
+ }
+ finally {
+ this.lock.unlock();
+ }
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
similarity index 71%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
index 8005c961..4d9c4a98 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/SpringFormatStartupActivity.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/startup/SpringJavaFormatStartupActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2020 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,21 +14,21 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij;
+package io.spring.format.formatter.intellij.startup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
/**
- * {@link StartupActivity} hook for {@link SpringFormat}.
+ * {@link StartupActivity} hook for {@link ManagedSpringJavaFormatProject}.
*
* @author Phillip Webb
*/
-public class SpringFormatStartupActivity implements StartupActivity {
+public class SpringJavaFormatStartupActivity implements StartupActivity {
@Override
public void runActivity(Project project) {
- new SpringFormat(project);
+ new ManagedSpringJavaFormatProject(project);
}
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java
new file mode 100644
index 00000000..c093671b
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/state/State.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.format.formatter.intellij.state;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+
+/**
+ * The state of the plugin.
+ *
+ * @author Phillip Webb
+ */
+public enum State {
+
+ /**
+ * The plugin is active.
+ */
+ ACTIVE,
+
+ /**
+ * The plugin is not active.
+ */
+ NOT_ACTIVE;
+
+ private static final Key KEY = Key.create(State.class.getName());
+
+ /**
+ * Put this state to the given project.
+ * @param project the project that should save the state
+ */
+ public void put(Project project) {
+ project.putUserData(KEY, this);
+ }
+
+ /**
+ * Return the state from the given project.
+ * @param project the project to check
+ * @return the state of the project
+ */
+ public static State get(Project project) {
+ State state = (project != null) ? project.getUserData(KEY) : null;
+ return (state != null) ? state : NOT_ACTIVE;
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
similarity index 89%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
index e7a2ee89..85287af9 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/StatusIndicator.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/java/io/spring/format/formatter/intellij/ui/StatusIndicator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij;
+package io.spring.format.formatter.intellij.ui;
import java.awt.event.MouseEvent;
import java.util.concurrent.TimeUnit;
@@ -30,26 +30,26 @@
import com.intellij.util.Consumer;
import com.intellij.util.concurrency.AppExecutorUtil;
-import io.spring.format.formatter.intellij.codestyle.monitor.Trigger.State;
+import io.spring.format.formatter.intellij.state.State;
/**
* Indicator used to show when Spring Formatting is active.
*
* @author Phillip Webb
*/
-class StatusIndicator {
+public class StatusIndicator {
private final Project project;
private Widget widget;
- StatusIndicator(Project project) {
+ public StatusIndicator(Project project) {
this.project = project;
}
public void update(State state) {
WindowManager windowManager = WindowManager.getInstance();
- final StatusBar statusBar = windowManager.getStatusBar(this.project);
+ StatusBar statusBar = windowManager.getStatusBar(this.project);
if (statusBar == null) {
AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> retryUpdate(state), 1, TimeUnit.SECONDS);
return;
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
index ccbca400..21c74b0f 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/main/resources/META-INF/plugin.xml
@@ -9,6 +9,7 @@
org.jetbrains.idea.maven
org.jetbrains.plugins.gradle
-
+
+
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java
deleted file mode 100644
index b8ab5809..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/DelegatingCodeStyleManagerTests.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import com.intellij.util.ThrowableRunnable;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link DelegatingCodeStyleManager}.
- *
- * @author Phillip Webb
- */
-public class DelegatingCodeStyleManagerTests {
-
- @Mock
- private CodeStyleManager delegate;
-
- private DelegatingCodeStyleManager delegating;
-
- @Mock
- private PsiElement element;
-
- @Mock
- private PsiFile file;
-
- @Mock
- private TextRange range;
-
- private Collection ranges;
-
- @Mock
- private Document document;
-
- @Mock
- private FileType fileType;
-
- @Mock
- private ASTNode block;
-
- @Mock
- private ASTNode node;
-
- @Mock
- private ChangedRangesInfo changedRangesInfo;
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- this.delegating = new DelegatingCodeStyleManager(this.delegate);
- this.ranges = Collections.singleton(mock(TextRange.class));
- }
-
- @Test
- public void getDelegateShouldGetDelegate() throws Exception {
- assertThat(this.delegating.getDelegate()).isEqualTo(this.delegate);
- }
-
- @Test
- public void getProjectShouldCallDelegate() throws Exception {
- this.delegating.getProject();
- verify(this.delegate).getProject();
- }
-
- @Test
- public void reformatShouldCallDelegate() throws Exception {
- this.delegating.reformat(this.element);
- verify(this.delegate).reformat(this.element);
- }
-
- @Test
- public void reformatWithCanChangeWhiteSpacesOnlyShouldCallDelegate() throws Exception {
- this.delegating.reformat(this.element, true);
- verify(this.delegate).reformat(this.element, true);
- }
-
- @Test
- public void reformatRangeShouldCallDelegate() throws Exception {
- this.delegating.reformatRange(this.element, 12, 34);
- verify(this.delegate).reformatRange(this.element, 12, 34);
- }
-
- @Test
- public void reformatRangeWithCanChangeWhiteSpacesOnlyShouldCallDelegate() throws Exception {
- this.delegating.reformatRange(this.element, 12, 34, true);
- verify(this.delegate).reformatRange(this.element, 12, 34, true);
- }
-
- @Test
- public void reformatTextShouldCallDelegate() throws Exception {
- this.delegating.reformatText(this.file, 12, 34);
- verify(this.delegate).reformatText(this.file, 12, 34);
- }
-
- @Test
- public void reformatTextWithRangeCollectionShouldCallDelegate() throws Exception {
- this.delegating.reformatText(this.file, this.ranges);
- verify(this.delegate).reformatText(this.file, this.ranges);
- }
-
- @Test
- public void reformatTextWithContextShouldCallDelegate() throws Exception {
- this.delegating.reformatTextWithContext(this.file, this.ranges);
- ArgumentCaptor changedRanges = ArgumentCaptor.forClass(ChangedRangesInfo.class);
- verify(this.delegate).reformatTextWithContext(eq(this.file), changedRanges.capture());
- assertThat(changedRanges.getValue().allChangedRanges).containsExactlyElementsOf(this.ranges);
- }
-
- @Test
- public void reformatTextWithContextInfoShouldCallDelegate() throws Exception {
- this.delegating.reformatTextWithContext(this.file, this.changedRangesInfo);
- verify(this.delegate).reformatTextWithContext(this.file, this.changedRangesInfo);
- }
-
- @Test
- public void adjustLineIndentForFileWithRangeShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.file, this.range);
- verify(this.delegate).adjustLineIndent(this.file, this.range);
- }
-
- @Test
- public void adjustLineIndentForFileShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.file, 123);
- verify(this.delegate).adjustLineIndent(this.file, 123);
- }
-
- @Test
- public void adjustLineIndentForDocumentShouldCallDelegate() throws Exception {
- this.delegating.adjustLineIndent(this.document, 123);
- verify(this.delegate).adjustLineIndent(this.document, 123);
- }
-
- @Test
- @Deprecated
- public void isLineToBeIndentedShouldCallDelegate() throws Exception {
- this.delegating.isLineToBeIndented(this.file, 123);
- verify(this.delegate).isLineToBeIndented(this.file, 123);
- }
-
- @Test
- public void getLineIndentForFileShouldCallDelegate() throws Exception {
- this.delegating.getLineIndent(this.file, 123);
- verify(this.delegate).getLineIndent(this.file, 123);
- }
-
- @Test
- public void getLineIndentForDocumentShouldCallDelegate() throws Exception {
- this.delegating.getLineIndent(this.document, 123);
- verify(this.delegate).getLineIndent(this.document, 123);
- }
-
- @Test
- @Deprecated
- public void getIndentShouldCallDelegate() throws Exception {
- this.delegating.getIndent("hello", this.fileType);
- verify(this.delegate).getIndent("hello", this.fileType);
- }
-
- @Test
- @Deprecated
- public void fillIndentShouldCallDelegate() throws Exception {
- com.intellij.psi.codeStyle.Indent indent = mock(com.intellij.psi.codeStyle.Indent.class);
- this.delegating.fillIndent(indent, this.fileType);
- verify(this.delegate).fillIndent(indent, this.fileType);
- }
-
- @Test
- @Deprecated
- public void zeroIndentShouldCallDelegate() throws Exception {
- this.delegating.zeroIndent();
- verify(this.delegate).zeroIndent();
- }
-
- @Test
- public void reformatNewlyAddedElementShouldCallDelegate() throws Exception {
- this.delegating.reformatNewlyAddedElement(this.block, this.node);
- verify(this.delegate).reformatNewlyAddedElement(this.block, this.node);
- }
-
- @Test
- public void isSequentialProcessingAllowedShouldCallDelegate() throws Exception {
- this.delegating.isSequentialProcessingAllowed();
- verify(this.delegate).isSequentialProcessingAllowed();
- }
-
- @Test
- public void performActionWithFormatterDisabledWithRunnableShouldCallDelegate() throws Exception {
- Runnable runnable = mock(Runnable.class);
- this.delegating.performActionWithFormatterDisabled(runnable);
- verify(this.delegate).performActionWithFormatterDisabled(runnable);
- }
-
- @Test
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void performActionWithFormatterDisabledWithThrowableRunnableShouldCallDelegate() throws Throwable {
- ThrowableRunnable runnable = mock(ThrowableRunnable.class);
- this.delegating.performActionWithFormatterDisabled(runnable);
- verify(this.delegate).performActionWithFormatterDisabled(runnable);
- }
-
- @Test
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void performActionWithFormatterDisabledWithComputableShouldCallDelegate() throws Exception {
- Computable computable = mock(Computable.class);
- this.delegating.performActionWithFormatterDisabled(computable);
- verify(this.delegate).performActionWithFormatterDisabled(computable);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java
deleted file mode 100644
index cfe25a39..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringCodeStyleManagerTests.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.codeStyle.ChangedRangesInfo;
-import com.intellij.psi.codeStyle.CodeStyleManager;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-/**
- * Tests for {@link SpringCodeStyleManager}.
- *
- * @author Phillip Webb
- */
-public class SpringCodeStyleManagerTests {
-
- @Mock
- private CodeStyleManager delegate;
-
- @Mock
- private SpringReformatter springReformatter;
-
- private SpringCodeStyleManager styleManager;
-
- @Mock
- private PsiFile file;
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- this.styleManager = new SpringCodeStyleManager(this.delegate, this.springReformatter);
- }
-
- @Test
- public void reformatTextWithOffsetWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- this.styleManager.reformatText(this.file, 10, 20);
- verify(this.delegate).reformatText(this.file, 10, 20);
- }
-
- @Test
- public void reformatTextWithOffsetWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Set ranges = new HashSet<>(Arrays.asList(new TextRange(10, 20)));
- this.styleManager.reformatText(this.file, 10, 20);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
- @Test
- public void reformatTextWithRangeWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatText(this.file, ranges);
- verify(this.delegate).reformatText(this.file, ranges);
- }
-
- @Test
- public void reformatTextWithRangeWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatText(this.file, ranges);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
- @Test
- public void reformatTextWithContextWhenCantFormatShouldCallDelegate() {
- given(this.springReformatter.canReformat(any())).willReturn(false);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatTextWithContext(this.file, ranges);
- ArgumentCaptor changedRanges = ArgumentCaptor.forClass(ChangedRangesInfo.class);
- verify(this.delegate).reformatTextWithContext(eq(this.file), changedRanges.capture());
- assertThat(changedRanges.getValue().allChangedRanges).containsExactlyElementsOf(ranges);
- }
-
- @Test
- public void reformatTextWithContextWhenCanFormatShouldCallFormatter() {
- given(this.springReformatter.canReformat(any())).willReturn(true);
- Collection ranges = Arrays.asList(new TextRange(10, 20));
- this.styleManager.reformatTextWithContext(this.file, ranges);
- verify(this.springReformatter).reformat(this.file, ranges);
- verifyZeroInteractions(this.delegate);
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java
deleted file mode 100644
index a37ddce7..00000000
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/SpringReformatterTests.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2017-2021 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.format.formatter.intellij.codestyle;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.function.Supplier;
-
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.util.IncorrectOperationException;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-/**
- * Tests for {@link SpringReformatter}.
- *
- * @author Phillip Webb
- */
-public class SpringReformatterTests {
-
- @Mock
- private Project project;
-
- @Mock
- private Application application;
-
- @Mock
- private PsiDocumentManager documentManager;
-
- private SpringReformatter reformatter;
-
- @Mock
- private PsiFile file;
-
- @Mock
- VirtualFile virtualFile;
-
- private Collection ranges = Arrays.asList(new TextRange(10, 20));
-
- @BeforeEach
- public void setup() {
- MockitoAnnotations.initMocks(this);
- given(this.file.getVirtualFile()).willReturn(this.virtualFile);
- this.reformatter = new TestSpringReformatter(() -> this.project, () -> this.application,
- () -> this.documentManager);
- }
-
- @Test
- public void reformatShouldAssertWriteAccess() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- this.reformatter.reformat(this.file, this.ranges);
- verify(this.application).assertWriteAccessAllowed();
- }
-
- @Test
- public void reformatShouldCommitAllDocuments() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- this.reformatter.reformat(this.file, this.ranges);
- verify(this.documentManager).commitAllDocuments();
- }
-
- @Test
- public void reformatWhenFileIsNotWriteableShouldThrow() throws Exception {
- assertThatExceptionOfType(IncorrectOperationException.class)
- .isThrownBy(() -> this.reformatter.reformat(this.file, this.ranges));
- }
-
- @Test
- public void reformatShouldReformatDocument() throws Exception {
- given(this.file.isWritable()).willReturn(true);
- Document document = mock(Document.class);
- String text = "public class Hello {}";
- given(document.getText()).willReturn(text);
- given(this.documentManager.getDocument(this.file)).willReturn(document);
- this.reformatter.reformat(this.file, Arrays.asList(new TextRange(0, text.length())));
- verify(document).replaceString(20, 20, "\n\n");
- verify(this.documentManager).commitDocument(document);
- }
-
- static class TestSpringReformatter extends SpringReformatter {
-
- TestSpringReformatter(Supplier project, Supplier application,
- Supplier documentManager) {
- super(project, application, documentManager);
- }
-
- @Override
- protected void runWriteCommandAction(Runnable runnable) {
- runnable.run();
- }
-
- }
-
-}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
similarity index 83%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
index 4d9b4b4d..09a8a0d9 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseDocumentAdapterTests.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseDocumentAdapterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import com.intellij.openapi.editor.Document;
import org.junit.jupiter.api.Test;
@@ -29,10 +29,10 @@
*
* @author Phillip Webb
*/
-public class EclipseDocumentAdapterTests {
+class EclipseDocumentAdapterTests {
@Test
- public void createShouldUseDocumentText() throws Exception {
+ void createUsesDocumentText() throws Exception {
Document intellijDocument = mock(Document.class);
given(intellijDocument.getText()).willReturn("hello");
EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(intellijDocument);
@@ -40,7 +40,7 @@ public void createShouldUseDocumentText() throws Exception {
}
@Test
- public void replaceShouldApplyToIntellijDocument() throws Exception {
+ void replaceAppliesToIntellijDocument() throws Exception {
Document intellijDocument = mock(Document.class);
given(intellijDocument.getText()).willReturn("hello");
EclipseDocumentAdapter adapter = new EclipseDocumentAdapter(intellijDocument);
@@ -48,5 +48,4 @@ public void replaceShouldApplyToIntellijDocument() throws Exception {
assertThat(adapter.get()).isEqualTo("help");
verify(intellijDocument).replaceString(3, 5, "p");
}
-
}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
similarity index 81%
rename from spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java
rename to spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
index b281ad5c..873d7fec 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/codestyle/EclipseRegionAdapterTests.java
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/EclipseRegionAdapterTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2021 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.format.formatter.intellij.codestyle;
+package io.spring.format.formatter.intellij.formatting;
import java.util.Arrays;
import java.util.List;
@@ -33,25 +33,25 @@
public class EclipseRegionAdapterTests {
@Test
- public void getOffsetShouldReturnStartOffset() throws Exception {
+ void getOffsetReturnsStartOffset() throws Exception {
IRegion region = new EclipseRegionAdapter(new TextRange(10, 20));
assertThat(region.getOffset()).isEqualTo(10);
}
@Test
- public void getLengthShouldReturnLength() throws Exception {
+ void getLengthReturnsLength() throws Exception {
IRegion region = new EclipseRegionAdapter(new TextRange(10, 20));
assertThat(region.getLength()).isEqualTo(10);
}
@Test
- public void asArrayWhenCollectionIsNullShouldReturnEmptyArray() throws Exception {
+ void asArrayWhenCollectionIsNullReturnsEmptyArray() throws Exception {
IRegion[] regions = EclipseRegionAdapter.asArray(null);
assertThat(regions).isNotNull().isEmpty();
}
@Test
- public void asArrayShouldReturnArray() throws Exception {
+ void asArrayReturnsArray() throws Exception {
List ranges = Arrays.asList(new TextRange(10, 20), new TextRange(30, 35));
IRegion[] regions = EclipseRegionAdapter.asArray(ranges);
assertThat(regions).hasSize(2);
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java
new file mode 100644
index 00000000..c49bae99
--- /dev/null
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-plugin/src/test/java/io/spring/format/formatter/intellij/formatting/SpringJavaFormatFormattingServiceTests.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2017-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.format.formatter.intellij.formatting;
+
+import java.util.Collections;
+
+import com.intellij.formatting.FormattingContext;
+import com.intellij.formatting.service.FormattingService.Feature;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.PlainTextFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import org.junit.jupiter.api.Test;
+
+import io.spring.format.formatter.intellij.state.State;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Tests for {@link SpringJavaFormatFormattingService}.
+ *
+ * @author Phillip Webb
+ */
+class SpringJavaFormatFormattingServiceTests {
+
+ private SpringJavaFormatFormattingService service = new SpringJavaFormatFormattingService(
+ (project, runnable) -> runnable.run());
+
+ @Test
+ void getFeaturesReturnsFormatFragments() {
+ assertThat(this.service.getFeatures()).containsExactly(Feature.FORMAT_FRAGMENTS);
+ }
+
+ @Test
+ void canFormatWhenNotJavaReturnsFalse() {
+ FileType fileType = PlainTextFileType.INSTANCE;
+ PsiFile file = mockFile(fileType, State.ACTIVE);
+ assertThat(this.service.canFormat(file)).isFalse();
+ }
+
+ @Test
+ void canFormatWhenJavaFileAndNotActiveReturnsFalse() {
+ FileType fileType = FileTypeManager.getInstance().getStdFileType("JAVA");
+ PsiFile file = mockFile(fileType, State.NOT_ACTIVE);
+ assertThat(this.service.canFormat(file)).isFalse();
+ }
+
+ @Test
+ void canFormatWhenJavaFileAndActiveReturnsTrue() {
+ FileType fileType = FileTypeManager.getInstance().getStdFileType("JAVA");
+ PsiFile file = mockFile(fileType, State.ACTIVE);
+ assertThat(this.service.canFormat(file)).isTrue();
+ }
+
+ @Test
+ void formatDocumentAppliesFormatting() {
+ Document document = mock(Document.class);
+ String text = "public class Hello {}";
+ given(document.getText()).willReturn(text);
+ FormattingContext formattingContext = mock(FormattingContext.class);
+ this.service.formatDocument(document, Collections.emptyList(), formattingContext, false, false);
+ verify(document).replaceString(20, 20, "\n\n");
+ }
+
+ private PsiFile mockFile(FileType fileType, State state) {
+ PsiFile file = mock(PsiFile.class);
+ given(file.getFileType()).willReturn(fileType);
+ Project project = mock(Project.class);
+ given(project.getUserData(any())).willReturn(state);
+ given(file.getProject()).willReturn(project);
+ return file;
+ }
+
+}
diff --git a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
index 2d474eb4..d49d6851 100644
--- a/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
+++ b/spring-javaformat-intellij-idea/spring-javaformat-intellij-idea-runtime/pom.xml
@@ -13,9 +13,10 @@
Spring JavaFormat IntelliJ IDEA Runtime
${basedir}/../..
- https://download.jetbrains.com/idea/ideaIC-2021.2.tar.gz
- https://github.com/JetBrains/intellij-community/archive/idea/212.4746.92.zip
- idea-IC-212.4746.92
+ https://download.jetbrains.com/idea/ideaIC-2022.3.2.tar.gz
+ https://github.com/JetBrains/intellij-community/archive/idea/223.8617.56.zip
+ ${project.build.directory}/intellij-source
+ idea-IC-223.8617.56
@@ -66,64 +67,71 @@
-
+
+ dest="${project.build.directory}/intellij">
+
+ src="${intellij.source.directory}.zip"
+ dest="${intellij.source.directory}">
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -134,150 +142,136 @@
maven-install-plugin
- install-intellij-annotations
- install
- false
-
- install-file
-
-
- ${project.build.directory}/intellij/annotations.jar
- io.spring.javaformat.intellij.idea
- annotations
- ${project.version}
- jar
- true
-
-
-
- install-intellij-platform-api
+ install-intellij-util
install
false
install-file
- ${project.build.directory}/intellij/platform-api.jar
- ${project.build.directory}/intellij-source/platform-api-sources.zip
+ ${project.build.directory}/intellij/util.jar
+ ${intellij.source.directory}/util-sources.zip
io.spring.javaformat.intellij.idea
- platform-api
+ util
${project.version}
jar
true
- install-intellij-platform-impl
+ install-intellij-util_rt
install
false
install-file
- ${project.build.directory}/intellij/platform-impl.jar
- ${project.build.directory}/intellij-source/platform-impl-sources.zip
+ ${project.build.directory}/intellij/util_rt.jar
+ ${intellij.source.directory}/util_rt-sources.zip
io.spring.javaformat.intellij.idea
- platform-impl
+ util_rt
${project.version}
jar
true
- install-intellij-util
+ install-intellij-app
install
false
install-file
- ${project.build.directory}/intellij/util.jar
- ${project.build.directory}/intellij-source/util-sources.zip
+ ${project.build.directory}/intellij/app.jar
+ ${intellij.source.directory}/app-sources.zip
io.spring.javaformat.intellij.idea
- util
+ app
${project.version}
jar
true
- install-intellij-idea
+ install-intellij-maven
install
false
install-file
- ${project.build.directory}/intellij/idea.jar
+ ${project.build.directory}/intellij/maven.jar
+ ${intellij.source.directory}/maven-sources.zip
io.spring.javaformat.intellij.idea
- idea
+ maven
${project.version}
jar
true
- install-intellij-maven
+ install-intellij-maven-server
install
false
install-file
- ${project.build.directory}/intellij/maven.jar
- ${project.build.directory}/intellij-source/maven-sources.zip
+ ${project.build.directory}/intellij/maven-server.jar
+ ${intellij.source.directory}/maven-server-sources.zip
io.spring.javaformat.intellij.idea
- maven
+ maven-server
${project.version}
jar
true
- install-intellij-maven-server-api
+ install-intellij-gradle
install
false
install-file
- ${project.build.directory}/intellij/maven-server-api.jar
+ ${project.build.directory}/intellij/gradle.jar
+ ${intellij.source.directory}/gradle-sources.zip
io.spring.javaformat.intellij.idea
- maven-server-api
+ gradle
${project.version}
jar
true
- install-intellij-gradle
+ install-intellij-gradle-tooling-extension-api
install
false
install-file
- ${project.build.directory}/intellij/gradle.jar
- ${project.build.directory}/intellij-source/gradle-sources.zip
+ ${project.build.directory}/intellij/gradle-tooling-extension-api.jar
+ ${intellij.source.directory}/gradle-tooling-extension-api-sources.zip
io.spring.javaformat.intellij.idea
- gradle
+ gradle-tooling-extension-api
${project.version}
jar
true
- install-intellij-gradle-tooling-extension-api
+ install-intellij-jps-model
install
false
install-file
- ${project.build.directory}/intellij/gradle-tooling-extension-api.jar
- ${project.build.directory}/intellij-source/gradle-tooling-extension-api-sources.zip
+ ${project.build.directory}/intellij/jps-model.jar
+ ${intellij.source.directory}/jps-model-sources.zip
io.spring.javaformat.intellij.idea
- gradle-tooling-extension-api
+ jps-model
${project.version}
jar
true
@@ -292,7 +286,7 @@
${project.build.directory}/intellij/gradle-tooling-extension-impl.jar
- ${project.build.directory}/intellij-source/gradle-tooling-extension-impl-sources.zip
+ ${intellij.source.directory}/gradle-tooling-extension-impl-sources.zip
io.spring.javaformat.intellij.idea
gradle-tooling-extension-impl
${project.version}