[Gradle] on mvn dependency paste into build.gradle it is converted to gradle one
authorYaroslav Lepenkin <yaroslav.lepenkin@jetbrains.com>
Fri, 12 Aug 2016 12:25:33 +0000 (15:25 +0300)
committerYaroslav Lepenkin <yaroslav.lepenkin@jetbrains.com>
Fri, 12 Aug 2016 12:28:39 +0000 (15:28 +0300)
plugins/gradle/src/META-INF/plugin.xml
plugins/gradle/src/org/jetbrains/plugins/gradle/action/PasteMvnDependencyPreProcessor.java [new file with mode: 0644]
plugins/gradle/testSources/org/jetbrains/plugins/gradle/codeInsight/actions/MvnDependencyPasteTest.java [new file with mode: 0644]

index 2cbd6db04acd3aea2f71ff70d2a76504bf41b38a..0cf2e69aaf86b77d7fc860da2f70d5e003f4bda1 100644 (file)
                      key="multiple.repository.urls" groupKey="group.names.probable.bugs" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
                      implementationClass="org.jetbrains.plugins.gradle.codeInspection.MultipleRepositoryUrlsInspection"/>
 
+    <copyPastePreProcessor implementation="org.jetbrains.plugins.gradle.action.PasteMvnDependencyPreProcessor"/>
+    
   </extensions>
 
   <extensions defaultExtensionNs="org.intellij.groovy">
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 (file)
index 0000000..22ad491
--- /dev/null
@@ -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("<dependency>") && trimmed.endsWith("</dependency>")) {
+      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 (file)
index 0000000..f5609e3
--- /dev/null
@@ -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" +
+                      "    <dependency>\n" +
+                      "    <groupId>group</groupId>\n" +
+                      "  <version>1.0</version>\n" +
+                      "    <scope>runtime</scope>\n" +
+                      "</dependency>\n" +
+                      "}");
+  }
+  
+
+  @NotNull
+  private static String getDependency(@Nullable String groupId,
+                                      @Nullable String artifactId,
+                                      @Nullable String version,
+                                      @Nullable String scope,
+                                      @Nullable String type) {
+    
+    String dependency = "<dependency>\n";
+    if (groupId != null) {
+      dependency +=     "  <groupId>" + groupId + "</groupId>\n";
+    }
+    if (artifactId != null) {
+      dependency +=     "  <artifactId>" + artifactId + "</artifactId>\n";
+    }
+    if (version != null) {
+      dependency +=     "  <version>" + version + "</version>\n";     
+    }
+    if (scope != null) {
+      dependency +=     "  <scope>" + scope + "</scope>\n";
+    }
+    if (type != null) {
+      dependency +=     "  <type>" + type + "</type>\n";
+    }
+    dependency += "</dependency>";
+    return dependency;
+  }
+
+  private static void configureGradleFile() {
+    configureFromFileText("build.gradle",
+                          "dependencies {\n" +
+                          "    <caret>\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());
+  }
+}