From 830875a43b74bb44c1c12b09e09f30abb1bf06ae Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Fri, 12 Aug 2016 15:25:33 +0300 Subject: [PATCH] [Gradle] on mvn dependency paste into build.gradle it is converted to gradle one --- plugins/gradle/src/META-INF/plugin.xml | 2 + .../PasteMvnDependencyPreProcessor.java | 127 ++++++++++++++++++ .../actions/MvnDependencyPasteTest.java | 111 +++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/action/PasteMvnDependencyPreProcessor.java create mode 100644 plugins/gradle/testSources/org/jetbrains/plugins/gradle/codeInsight/actions/MvnDependencyPasteTest.java diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 2cbd6db04acd..0cf2e69aaf86 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -155,6 +155,8 @@ key="multiple.repository.urls" groupKey="group.names.probable.bugs" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.plugins.gradle.codeInspection.MultipleRepositoryUrlsInspection"/> + + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/PasteMvnDependencyPreProcessor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/PasteMvnDependencyPreProcessor.java new file mode 100644 index 000000000000..22ad4915bc70 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/PasteMvnDependencyPreProcessor.java @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * 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 + * + * http://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 org.jetbrains.plugins.gradle.action; + +import com.intellij.codeInsight.editorActions.CopyPastePreProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RawText; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.apache.tools.ant.filters.StringInputStream; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; + +public class PasteMvnDependencyPreProcessor implements CopyPastePreProcessor { + + @Nullable + @Override + public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) { + return null; + } + + @NotNull + @Override + public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) { + if ("build.gradle".equals(file.getName()) && isMvnDependency(text)) { + return toGradleDependency(text); + } + return text; + } + + private static String toGradleDependency(final String mavenDependency) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); + + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + try { + Document document = builder.parse(new StringInputStream(mavenDependency)); + String gradleDependency = extractGradleDependency(document); + return gradleDependency != null ? gradleDependency : mavenDependency; + } + catch (SAXException | IOException e) { + } + } + catch (ParserConfigurationException e) { + } + + return mavenDependency; + } + + @Nullable + private static String extractGradleDependency(Document document) { + String groupId = getGroupId(document); + String artifactId = getArtifactId(document); + String version = getVersion(document); + String scope = getScope(document); + + if (groupId.isEmpty() || artifactId.isEmpty() || version.isEmpty()) { + return null; + } + + return scope + "'" + groupId + ":" + artifactId + ":" + version + "'"; + } + + private static String getScope(@NotNull Document document) { + String scope = firstOrEmpty(document.getElementsByTagName("scope")); + switch (scope) { + case "test": + scope = "testCompile "; + break; + case "compile": + case "runtime": + scope += " "; + break; + default: + scope = ""; + } + return scope; + } + + private static String getVersion(@NotNull Document document) { + return firstOrEmpty(document.getElementsByTagName("version")); + } + + private static String getArtifactId(@NotNull Document document) { + return firstOrEmpty(document.getElementsByTagName("artifactId")); + } + + private static String getGroupId(@NotNull Document document) { + return firstOrEmpty(document.getElementsByTagName("groupId")); + } + + private static String firstOrEmpty(@NotNull NodeList list) { + Node first = list.item(0); + return first != null ? first.getTextContent() : ""; + } + + private static boolean isMvnDependency(String text) { + String trimmed = text.trim(); + if (trimmed.startsWith("") && trimmed.endsWith("")) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/codeInsight/actions/MvnDependencyPasteTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/codeInsight/actions/MvnDependencyPasteTest.java new file mode 100644 index 000000000000..f5609e32b743 --- /dev/null +++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/codeInsight/actions/MvnDependencyPasteTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * 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 + * + * http://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 org.jetbrains.plugins.gradle.codeInsight.actions; + +import com.intellij.ide.DataManager; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class MvnDependencyPasteTest extends LightCodeInsightTestCase { + + public void testPastedGradleDependency() throws Exception { + configureFromFileText("pom.xml", getDependency("group", "artifact", "1.0", "runtime", null)); + selectWholeFile(); + performCut(); + + configureGradleFile(); + performPaste(); + checkResultByText("dependencies {\n" + + " runtime 'group:artifact:1.0'\n" + + "}"); + } + + public void test_DoNotConvertIfCoordinatesNotClear() throws Exception { + String noArtifact = getDependency("group", null, "1.0", "runtime", null); + configureFromFileText("pom.xml", noArtifact); + + selectWholeFile(); + + performCut(); + + configureGradleFile(); + performPaste(); + checkResultByText("dependencies {\n" + + " \n" + + " group\n" + + " 1.0\n" + + " runtime\n" + + "\n" + + "}"); + } + + + @NotNull + private static String getDependency(@Nullable String groupId, + @Nullable String artifactId, + @Nullable String version, + @Nullable String scope, + @Nullable String type) { + + String dependency = "\n"; + if (groupId != null) { + dependency += " " + groupId + "\n"; + } + if (artifactId != null) { + dependency += " " + artifactId + "\n"; + } + if (version != null) { + dependency += " " + version + "\n"; + } + if (scope != null) { + dependency += " " + scope + "\n"; + } + if (type != null) { + dependency += " " + type + "\n"; + } + dependency += ""; + return dependency; + } + + private static void configureGradleFile() { + configureFromFileText("build.gradle", + "dependencies {\n" + + " \n" + + "}"); + } + + private static void selectWholeFile() { + Document document = getEditor().getDocument(); + getEditor().getSelectionModel().setSelection(0, document.getTextLength()); + } + + private static void performCut() { + EditorActionManager actionManager = EditorActionManager.getInstance(); + EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_CUT); + actionHandler.execute(getEditor(), null, DataManager.getInstance().getDataContextFromFocus().getResultSync()); + } + + private static void performPaste() { + EditorActionManager actionManager = EditorActionManager.getInstance(); + EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_PASTE); + actionHandler.execute(getEditor(), null, DataManager.getInstance().getDataContextFromFocus().getResultSync()); + } +}